@electrum-cash/tcp-socket 1.0.0 → 1.1.0-development.12711670847

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,93 +1,3 @@
1
1
  # Electrum-Cash Tcp Socket
2
2
 
3
-
4
-
5
- ## Getting started
6
-
7
- To make it easy for you to get started with GitLab, here's a list of recommended next steps.
8
-
9
- Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)!
10
-
11
- ## Add your files
12
-
13
- - [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files
14
- - [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command:
15
-
16
- ```
17
- cd existing_repo
18
- git remote add origin https://gitlab.com/electrum-cash/tcp-socket.git
19
- git branch -M main
20
- git push -uf origin main
21
- ```
22
-
23
- ## Integrate with your tools
24
-
25
- - [ ] [Set up project integrations](https://gitlab.com/electrum-cash/tcp-socket/-/settings/integrations)
26
-
27
- ## Collaborate with your team
28
-
29
- - [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/)
30
- - [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html)
31
- - [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically)
32
- - [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/)
33
- - [ ] [Set auto-merge](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html)
34
-
35
- ## Test and Deploy
36
-
37
- Use the built-in continuous integration in GitLab.
38
-
39
- - [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html)
40
- - [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing (SAST)](https://docs.gitlab.com/ee/user/application_security/sast/)
41
- - [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html)
42
- - [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/)
43
- - [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html)
44
-
45
- ***
46
-
47
- # Editing this README
48
-
49
- When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thanks to [makeareadme.com](https://www.makeareadme.com/) for this template.
50
-
51
- ## Suggestions for a good README
52
-
53
- Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information.
54
-
55
- ## Name
56
- Choose a self-explaining name for your project.
57
-
58
- ## Description
59
- Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors.
60
-
61
- ## Badges
62
- On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge.
63
-
64
- ## Visuals
65
- Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method.
66
-
67
- ## Installation
68
- Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection.
69
-
70
- ## Usage
71
- Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README.
72
-
73
- ## Support
74
- Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc.
75
-
76
- ## Roadmap
77
- If you have ideas for releases in the future, it is a good idea to list them in the README.
78
-
79
- ## Contributing
80
- State if you are open to contributions and what your requirements are for accepting them.
81
-
82
- For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self.
83
-
84
- You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser.
85
-
86
- ## Authors and acknowledgment
87
- Show your appreciation to those who have contributed to the project.
88
-
89
- ## License
90
- For open source projects, say how it is licensed.
91
-
92
- ## Project status
93
- If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers.
3
+ This package provides an `ElectrumSocket` implementation using a tcp socket from the `net` node internal package.
@@ -0,0 +1,152 @@
1
+ import { EventEmitter } from "eventemitter3";
2
+
3
+ //#region node_modules/@electrum-cash/network/dist/index.d.ts
4
+ /**
5
+ * List of events emitted by the ElectrumSocket.
6
+ * @event
7
+ * @ignore
8
+ */
9
+ interface ElectrumSocketEvents {
10
+ /**
11
+ * Emitted when data has been received over the socket.
12
+ * @eventProperty
13
+ */
14
+ 'data': [string];
15
+ /**
16
+ * Emitted when a socket connects.
17
+ * @eventProperty
18
+ */
19
+ 'connected': [];
20
+ /**
21
+ * Emitted when a socket disconnects.
22
+ * @eventProperty
23
+ */
24
+ 'disconnected': [];
25
+ /**
26
+ * Emitted when the socket has failed in some way.
27
+ * @eventProperty
28
+ */
29
+ 'error': [Error];
30
+ }
31
+ /**
32
+ * Abstract socket used when communicating with Electrum servers.
33
+ */
34
+ interface ElectrumSocket extends EventEmitter<ElectrumSocketEvents>, ElectrumSocketEvents {
35
+ /**
36
+ * Utility function to provide a human accessible host identifier.
37
+ */
38
+ get hostIdentifier(): string;
39
+ /**
40
+ * Fully qualified domain name or IP address of the host
41
+ */
42
+ host: string;
43
+ /**
44
+ * Network port for the host to connect to, defaults to the standard TLS port
45
+ */
46
+ port: number;
47
+ /**
48
+ * If false, uses an unencrypted connection instead of the default on TLS
49
+ */
50
+ encrypted: boolean;
51
+ /**
52
+ * If no connection is established after `timeout` ms, the connection is terminated
53
+ */
54
+ timeout: number;
55
+ /**
56
+ * Connects to an Electrum server using the socket.
57
+ */
58
+ connect(): void;
59
+ /**
60
+ * Disconnects from the Electrum server from the socket.
61
+ */
62
+ disconnect(): void;
63
+ /**
64
+ * Write data to the Electrum server on the socket.
65
+ *
66
+ * @param data - Data to be written to the socket
67
+ * @param callback - Callback function to be called when the write has completed
68
+ */
69
+ write(data: Uint8Array | string, callback?: (err?: Error) => void): boolean;
70
+ }
71
+ //#endregion
72
+ //#region source/tcp.d.ts
73
+ /**
74
+ * TCP Socket used when communicating with Electrum servers.
75
+ */
76
+ declare class ElectrumTcpSocket extends EventEmitter<ElectrumSocketEvents> implements ElectrumSocket {
77
+ host: string;
78
+ port: number;
79
+ encrypted: boolean;
80
+ timeout: number;
81
+ private tcpSocket;
82
+ private disconnectTimer?;
83
+ private onConnectHasRun;
84
+ private eventForwarders;
85
+ /**
86
+ * Creates a socket configured with connection information for a given Electrum server.
87
+ *
88
+ * @param host Fully qualified domain name or IP address of the host
89
+ * @param port Network port for the host to connect to, defaults to the standard TLS port
90
+ * @param encrypted If false, uses an unencrypted connection instead of the default on TLS
91
+ * @param timeout If no connection is established after `timeout` ms, the connection is terminated
92
+ */
93
+ constructor(host: string, port?: number, encrypted?: boolean, timeout?: number);
94
+ /**
95
+ * Returns a string for the host identifier for usage in debug messages.
96
+ */
97
+ get hostIdentifier(): string;
98
+ /**
99
+ * Connect to host:port using the specified transport
100
+ */
101
+ connect(): void;
102
+ /**
103
+ * Internal error handler that helps provide context to some types of errors before passing them up through the stack.
104
+ */
105
+ private onError;
106
+ /**
107
+ * Sets up forwarding of events related to the connection.
108
+ */
109
+ private onConnect;
110
+ /**
111
+ * Clears the disconnect timer if it is still active.
112
+ */
113
+ private clearDisconnectTimerOnTimeout;
114
+ /**
115
+ * Forcibly terminate the connection.
116
+ *
117
+ * @throws {Error} if no connection was found
118
+ */
119
+ disconnect(): void;
120
+ /**
121
+ * Write data to the socket
122
+ *
123
+ * @param data Data to be written to the socket
124
+ * @param callback Callback function to be called when the write has completed
125
+ *
126
+ * @throws {Error} if no connection was found
127
+ * @returns true if the message was fully flushed to the socket, false if part of the message
128
+ * is queued in the user memory
129
+ */
130
+ write(data: Uint8Array | string, callback?: (err?: Error) => void): boolean;
131
+ /**
132
+ * Force a disconnection if no connection is established after `timeout` milliseconds.
133
+ */
134
+ private disconnectOnTimeout;
135
+ readonly connected: [];
136
+ readonly disconnected: [];
137
+ readonly data: [string];
138
+ readonly error: [Error];
139
+ }
140
+ //#endregion
141
+ //#region source/interfaces.d.ts
142
+ /**
143
+ * Connection options used with TLS connections.
144
+ * @ignore
145
+ */
146
+ interface ConnectionOptions {
147
+ rejectUnauthorized?: boolean;
148
+ serverName?: string;
149
+ }
150
+ //#endregion
151
+ export { ConnectionOptions, ElectrumTcpSocket };
152
+ //# sourceMappingURL=index.d.mts.map
package/dist/index.mjs CHANGED
@@ -1,221 +1,152 @@
1
- import {connect as $dvphU$connect, TLSSocket as $dvphU$TLSSocket} from "tls";
2
- import {isIP as $dvphU$isIP, connect as $dvphU$connect1} from "net";
3
- import $dvphU$electrumcashdebuglogs from "@electrum-cash/debug-logs";
4
- import {EventEmitter as $dvphU$EventEmitter} from "eventemitter3";
1
+ import * as tls from "tls";
2
+ import * as net from "net";
3
+ import debug from "@electrum-cash/debug-logs";
4
+ import { EventEmitter } from "eventemitter3";
5
5
 
6
+ //#region source/constants.ts
7
+ const defaultTimeout = 30 * 1e3;
6
8
 
7
- function $parcel$export(e, n, v, s) {
8
- Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
9
- }
10
- var $bcb32cbeddeae7b2$exports = {};
11
-
12
- $parcel$export($bcb32cbeddeae7b2$exports, "ElectrumTcpSocket", () => $bcb32cbeddeae7b2$export$22c0ca2c816c3e08);
13
-
14
-
15
-
16
- // Export a default timeout value of 30 seconds.
17
- const $d801b1f9b7fc3074$export$1bddf2b96e25d075 = 30000;
18
-
19
-
20
-
21
- class $bcb32cbeddeae7b2$export$22c0ca2c816c3e08 extends (0, $dvphU$EventEmitter) {
22
- host;
23
- port;
24
- encrypted;
25
- timeout;
26
- // Declare an empty TCP socket.
27
- tcpSocket;
28
- // Used to disconnect after some time if initial connection is too slow.
29
- disconnectTimer;
30
- // Initialize boolean that indicates whether the onConnect function has run (initialize to false).
31
- onConnectHasRun;
32
- // Initialize event forwarding functions.
33
- eventForwarders;
34
- /**
35
- * Creates a socket configured with connection information for a given Electrum server.
36
- *
37
- * @param host Fully qualified domain name or IP address of the host
38
- * @param port Network port for the host to connect to, defaults to the standard TLS port
39
- * @param encrypted If false, uses an unencrypted connection instead of the default on TLS
40
- * @param timeout If no connection is established after `timeout` ms, the connection is terminated
41
- */ constructor(host, port = 50002, encrypted = true, timeout = (0, $d801b1f9b7fc3074$export$1bddf2b96e25d075)){
42
- // Initialize the event emitter.
43
- super();
44
- this.host = host;
45
- this.port = port;
46
- this.encrypted = encrypted;
47
- this.timeout = timeout;
48
- this.onConnectHasRun = false;
49
- this.eventForwarders = {
50
- disconnect: ()=>this.emit("disconnected"),
51
- tcpData: (data)=>this.emit("data", data)
52
- };
53
- }
54
- /**
55
- * Returns a string for the host identifier for usage in debug messages.
56
- */ get hostIdentifier() {
57
- return `${this.host}:${this.port}`;
58
- }
59
- /**
60
- * Connect to host:port using the specified transport
61
- */ connect() {
62
- // Check that no existing socket exists before initiating a new connection.
63
- if (this.tcpSocket) throw new Error("Cannot initiate a new socket connection when an existing connection exists");
64
- // Set a timer to force disconnect after `timeout` seconds
65
- this.disconnectTimer = setTimeout(()=>this.disconnectOnTimeout(), this.timeout);
66
- // Remove the timer if a connection is successfully established
67
- this.once("connected", this.clearDisconnectTimerOnTimeout);
68
- // Set a named connection type for logging purposes.
69
- const connectionType = this.encrypted ? "an encrypted TCP Socket" : "a TCP Socket";
70
- // Log that we are trying to establish a connection.
71
- (0, $dvphU$electrumcashdebuglogs).network(`Initiating ${connectionType} connection to '${this.host}:${this.port}'.`);
72
- if (this.encrypted) {
73
- // Initialize connection options.
74
- const connectionOptions = {
75
- rejectUnauthorized: false
76
- };
77
- // If the hostname is not an IP address..
78
- if (!$dvphU$isIP(this.host)) // Set the servername option which enables support for SNI.
79
- // NOTE: SNI enables a server that hosts multiple domains to provide the appropriate TLS certificate.
80
- connectionOptions.serverName = this.host;
81
- // Initialize the socket (allowing self-signed certificates).
82
- this.tcpSocket = $dvphU$connect(this.port, this.host, connectionOptions);
83
- // Add a 'secureConnect' listener that checks the authorization status of
84
- // the socket, and logs a warning when it uses a self signed certificate.
85
- this.tcpSocket.once("secureConnect", ()=>{
86
- // Cannot happen, since this event callback *only* exists on TLSSocket
87
- if (!(this.tcpSocket instanceof $dvphU$TLSSocket)) return;
88
- // Force cast authorizationError from Error to string (through unknown)
89
- // because it is incorrectly typed as an Error
90
- const authorizationError = this.tcpSocket.authorizationError;
91
- if (authorizationError === "DEPTH_ZERO_SELF_SIGNED_CERT") (0, $dvphU$electrumcashdebuglogs).warning(`Connection to ${this.host}:${this.port} uses a self-signed certificate`);
92
- });
93
- // Trigger successful connection events.
94
- this.tcpSocket.on("secureConnect", this.onConnect.bind(this));
95
- } else {
96
- // Initialize the socket.
97
- this.tcpSocket = $dvphU$connect1({
98
- host: this.host,
99
- port: this.port
100
- });
101
- // Trigger successful connection events.
102
- this.tcpSocket.on("connect", this.onConnect.bind(this));
103
- }
104
- // Configure encoding.
105
- this.tcpSocket.setEncoding("utf8");
106
- // Enable persistent connections.
107
- // NOTE: This will send a non-data message 0.25 second after last activity.
108
- // After 10 consecutive such messages with no response, the connection will be cut.
109
- this.tcpSocket.setKeepAlive(true, 250);
110
- // Disable buffering of outgoing data.
111
- this.tcpSocket.setNoDelay(true);
112
- // Forward the encountered errors.
113
- this.tcpSocket.on("error", this.onError);
114
- }
115
- /**
116
- * Internal error handler that helps provide context to some types of errors before passing them up through the stack.
117
- */ onError(error) {
118
- switch(error.code){
119
- // If the DNS lookup failed.
120
- case "EAI_AGAIN":
121
- this.emit("error", new Error(`Failed to look up DNS records for '${this.host}'.`));
122
- break;
123
- // If the connection timed out..
124
- case "ETIMEDOUT":
125
- this.emit("error", error);
126
- break;
127
- // For unknown errors..
128
- default:
129
- this.emit("error", error);
130
- }
131
- }
132
- /**
133
- * Sets up forwarding of events related to the connection.
134
- */ onConnect() {
135
- // If the onConnect function has already run, do not execute it again.
136
- if (this.onConnectHasRun) return;
137
- // Set a named connection type for logging purposes.
138
- const connectionType = this.encrypted ? "an encrypted TCP Socket" : "a TCP Socket";
139
- // Log that the connection has been established.
140
- (0, $dvphU$electrumcashdebuglogs).network(`Established ${connectionType} connection with '${this.host}:${this.port}'.`);
141
- // Forward the socket events
142
- this.tcpSocket.addListener("close", this.eventForwarders.disconnect);
143
- this.tcpSocket.addListener("data", this.eventForwarders.tcpData);
144
- // Indicate that the onConnect function has run.
145
- this.onConnectHasRun = true;
146
- // Emit the connect event.
147
- this.emit("connected");
148
- }
149
- /**
150
- * Clears the disconnect timer if it is still active.
151
- */ clearDisconnectTimerOnTimeout() {
152
- // Clear the retry timer if it is still active.
153
- if (this.disconnectTimer) clearTimeout(this.disconnectTimer);
154
- }
155
- /**
156
- * Forcibly terminate the connection.
157
- *
158
- * @throws {Error} if no connection was found
159
- */ disconnect() {
160
- // Clear the disconnect timer so that the socket does not try to disconnect again later.
161
- this.clearDisconnectTimerOnTimeout();
162
- if (this.tcpSocket) {
163
- // Remove all event forwarders.
164
- this.tcpSocket.removeListener("close", this.eventForwarders.disconnect);
165
- this.tcpSocket.removeListener("data", this.eventForwarders.tcpData);
166
- // Also remove the error forwarder, to prevent the following destroy call from generating error messages.
167
- this.tcpSocket.removeListener("error", this.onError);
168
- // Terminate the connection.
169
- this.tcpSocket.destroy();
170
- // Remove the stored socket.
171
- this.tcpSocket = undefined;
172
- }
173
- // Indicate that the onConnect function has not run and it has to be run again.
174
- this.onConnectHasRun = false;
175
- // Emit a disconnect event
176
- this.emit("disconnected");
177
- }
178
- /**
179
- * Write data to the socket
180
- *
181
- * @param data Data to be written to the socket
182
- * @param callback Callback function to be called when the write has completed
183
- *
184
- * @throws {Error} if no connection was found
185
- * @returns true if the message was fully flushed to the socket, false if part of the message
186
- * is queued in the user memory
187
- */ write(data, callback) {
188
- // Throw an error if no active connection is found
189
- if (!this.tcpSocket) throw new Error("Cannot write to socket when there is no active connection");
190
- // Write data to the TLS Socket and return the status indicating
191
- // whether the full message was flushed to the socket
192
- return this.tcpSocket.write(data, callback);
193
- }
194
- /**
195
- * Force a disconnection if no connection is established after `timeout` milliseconds.
196
- */ disconnectOnTimeout() {
197
- // Remove the connect listener.
198
- this.removeListener("connected", this.clearDisconnectTimerOnTimeout);
199
- // Emit an error event so that connect is rejected upstream.
200
- this.emit("error", new Error(`Connection to '${this.host}:${this.port}' timed out after ${this.timeout} milliseconds`));
201
- // Forcibly disconnect to clean up the connection on timeout
202
- this.disconnect();
203
- }
204
- // Add magic glue that makes typedoc happy so that we can have the events listed on the class.
205
- connected;
206
- disconnected;
207
- data;
208
- error;
209
- }
210
-
211
-
212
- var $e83d2e7688025acd$exports = {};
9
+ //#endregion
10
+ //#region source/tcp.ts
213
11
  /**
214
- * Connection options used with TLS connections.
215
- * @ignore
216
- */
217
-
218
-
12
+ * TCP Socket used when communicating with Electrum servers.
13
+ */
14
+ var ElectrumTcpSocket = class extends EventEmitter {
15
+ tcpSocket;
16
+ disconnectTimer;
17
+ onConnectHasRun = false;
18
+ eventForwarders = {
19
+ disconnect: () => this.emit("disconnected"),
20
+ tcpData: (data) => this.emit("data", data)
21
+ };
22
+ /**
23
+ * Creates a socket configured with connection information for a given Electrum server.
24
+ *
25
+ * @param host Fully qualified domain name or IP address of the host
26
+ * @param port Network port for the host to connect to, defaults to the standard TLS port
27
+ * @param encrypted If false, uses an unencrypted connection instead of the default on TLS
28
+ * @param timeout If no connection is established after `timeout` ms, the connection is terminated
29
+ */
30
+ constructor(host, port = 50002, encrypted = true, timeout = defaultTimeout) {
31
+ super();
32
+ this.host = host;
33
+ this.port = port;
34
+ this.encrypted = encrypted;
35
+ this.timeout = timeout;
36
+ }
37
+ /**
38
+ * Returns a string for the host identifier for usage in debug messages.
39
+ */
40
+ get hostIdentifier() {
41
+ return `${this.host}:${this.port}`;
42
+ }
43
+ /**
44
+ * Connect to host:port using the specified transport
45
+ */
46
+ connect() {
47
+ if (this.tcpSocket) throw /* @__PURE__ */ new Error("Cannot initiate a new socket connection when an existing connection exists");
48
+ this.disconnectTimer = setTimeout(() => this.disconnectOnTimeout(), this.timeout);
49
+ this.once("connected", this.clearDisconnectTimerOnTimeout);
50
+ const connectionType = this.encrypted ? "an encrypted TCP Socket" : "a TCP Socket";
51
+ debug.network(`Initiating ${connectionType} connection to '${this.host}:${this.port}'.`);
52
+ if (this.encrypted) {
53
+ const connectionOptions = { rejectUnauthorized: false };
54
+ if (!net.isIP(this.host)) connectionOptions.serverName = this.host;
55
+ this.tcpSocket = tls.connect(this.port, this.host, connectionOptions);
56
+ this.tcpSocket.once("secureConnect", () => {
57
+ if (!(this.tcpSocket instanceof tls.TLSSocket)) return;
58
+ if (this.tcpSocket.authorizationError === "DEPTH_ZERO_SELF_SIGNED_CERT") debug.warning(`Connection to ${this.host}:${this.port} uses a self-signed certificate`);
59
+ });
60
+ this.tcpSocket.on("secureConnect", this.onConnect.bind(this));
61
+ } else {
62
+ this.tcpSocket = net.connect({
63
+ host: this.host,
64
+ port: this.port
65
+ });
66
+ this.tcpSocket.on("connect", this.onConnect.bind(this));
67
+ }
68
+ this.tcpSocket.setEncoding("utf8");
69
+ this.tcpSocket.setKeepAlive(true, 250);
70
+ this.tcpSocket.setNoDelay(true);
71
+ this.tcpSocket.on("error", this.onError);
72
+ }
73
+ /**
74
+ * Internal error handler that helps provide context to some types of errors before passing them up through the stack.
75
+ */
76
+ onError(error) {
77
+ switch (error.code) {
78
+ case "EAI_AGAIN":
79
+ this.emit("error", /* @__PURE__ */ new Error(`Failed to look up DNS records for '${this.host}'.`));
80
+ break;
81
+ case "ETIMEDOUT":
82
+ this.emit("error", error);
83
+ break;
84
+ default: this.emit("error", error);
85
+ }
86
+ }
87
+ /**
88
+ * Sets up forwarding of events related to the connection.
89
+ */
90
+ onConnect() {
91
+ if (this.onConnectHasRun) return;
92
+ const connectionType = this.encrypted ? "an encrypted TCP Socket" : "a TCP Socket";
93
+ debug.network(`Established ${connectionType} connection with '${this.host}:${this.port}'.`);
94
+ this.tcpSocket.addListener("close", this.eventForwarders.disconnect);
95
+ this.tcpSocket.addListener("data", this.eventForwarders.tcpData);
96
+ this.onConnectHasRun = true;
97
+ this.emit("connected");
98
+ }
99
+ /**
100
+ * Clears the disconnect timer if it is still active.
101
+ */
102
+ clearDisconnectTimerOnTimeout() {
103
+ if (this.disconnectTimer) clearTimeout(this.disconnectTimer);
104
+ }
105
+ /**
106
+ * Forcibly terminate the connection.
107
+ *
108
+ * @throws {Error} if no connection was found
109
+ */
110
+ disconnect() {
111
+ this.clearDisconnectTimerOnTimeout();
112
+ if (this.tcpSocket) {
113
+ this.tcpSocket.removeListener("close", this.eventForwarders.disconnect);
114
+ this.tcpSocket.removeListener("data", this.eventForwarders.tcpData);
115
+ this.tcpSocket.removeListener("error", this.onError);
116
+ this.tcpSocket.destroy();
117
+ this.tcpSocket = void 0;
118
+ }
119
+ this.onConnectHasRun = false;
120
+ this.emit("disconnected");
121
+ }
122
+ /**
123
+ * Write data to the socket
124
+ *
125
+ * @param data Data to be written to the socket
126
+ * @param callback Callback function to be called when the write has completed
127
+ *
128
+ * @throws {Error} if no connection was found
129
+ * @returns true if the message was fully flushed to the socket, false if part of the message
130
+ * is queued in the user memory
131
+ */
132
+ write(data, callback) {
133
+ if (!this.tcpSocket) throw /* @__PURE__ */ new Error("Cannot write to socket when there is no active connection");
134
+ return this.tcpSocket.write(data, callback);
135
+ }
136
+ /**
137
+ * Force a disconnection if no connection is established after `timeout` milliseconds.
138
+ */
139
+ disconnectOnTimeout() {
140
+ this.removeListener("connected", this.clearDisconnectTimerOnTimeout);
141
+ this.emit("error", /* @__PURE__ */ new Error(`Connection to '${this.host}:${this.port}' timed out after ${this.timeout} milliseconds`));
142
+ this.disconnect();
143
+ }
144
+ connected;
145
+ disconnected;
146
+ data;
147
+ error;
148
+ };
219
149
 
220
- export {$bcb32cbeddeae7b2$export$22c0ca2c816c3e08 as ElectrumTcpSocket};
221
- //# sourceMappingURL=index.mjs.map
150
+ //#endregion
151
+ export { ElectrumTcpSocket };
152
+ //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"mappings":"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","sources":["source/index.ts","source/tcp.ts","source/constants.ts","source/interfaces.ts"],"sourcesContent":["export * from './tcp.ts';\nexport * from './interfaces';\n","import * as tls from 'tls';\nimport * as net from 'net';\nimport debug from '@electrum-cash/debug-logs';\nimport { defaultTimeout } from './constants';\n\nimport { EventEmitter } from 'eventemitter3';\nimport type { ElectrumSocket, ElectrumSocketEvents } from '@electrum-cash/network';\n\n/**\n * Connection options used with TLS connections.\n * @ignore\n */\ninterface ConnectionOptions\n{\n\trejectUnauthorized?: boolean;\n\tserverName?: string;\n}\n\n/**\n * TCP Socket used when communicating with Electrum servers.\n */\nexport class ElectrumTcpSocket extends EventEmitter<ElectrumSocketEvents> implements ElectrumSocket\n{\n\t// Declare an empty TCP socket.\n\tprivate tcpSocket: net.Socket;\n\n\t// Used to disconnect after some time if initial connection is too slow.\n\tprivate disconnectTimer?: number;\n\n\t// Initialize boolean that indicates whether the onConnect function has run (initialize to false).\n\tprivate onConnectHasRun = false;\n\n\t// Initialize event forwarding functions.\n\tprivate eventForwarders =\n\t{\n\t\tdisconnect: () => this.emit('disconnected'),\n\t\ttcpData: (data: string) => this.emit('data', data),\n\t};\n\n\t/**\n\t * Creates a socket configured with connection information for a given Electrum server.\n\t *\n\t * @param host Fully qualified domain name or IP address of the host\n\t * @param port Network port for the host to connect to, defaults to the standard TLS port\n\t * @param encrypted If false, uses an unencrypted connection instead of the default on TLS\n\t * @param timeout If no connection is established after `timeout` ms, the connection is terminated\n\t */\n\tpublic constructor\n\t(\n\t\tpublic host: string,\n\t\tpublic port: number = 50002,\n\t\tpublic encrypted: boolean = true,\n\t\tpublic timeout: number = defaultTimeout,\n\t)\n\t{\n\t\t// Initialize the event emitter.\n\t\tsuper();\n\t}\n\n\t/**\n\t * Returns a string for the host identifier for usage in debug messages.\n\t */\n\tget hostIdentifier(): string\n\t{\n\t\treturn `${this.host}:${this.port}`;\n\t}\n\n\t/**\n\t * Connect to host:port using the specified transport\n\t */\n\tpublic connect(): void\n\t{\n\t\t// Check that no existing socket exists before initiating a new connection.\n\t\tif(this.tcpSocket)\n\t\t{\n\t\t\tthrow(new Error('Cannot initiate a new socket connection when an existing connection exists'));\n\t\t}\n\n\t\t// Set a timer to force disconnect after `timeout` seconds\n\t\tthis.disconnectTimer = setTimeout(() => this.disconnectOnTimeout(), this.timeout) as unknown as number;\n\n\t\t// Remove the timer if a connection is successfully established\n\t\tthis.once('connected', this.clearDisconnectTimerOnTimeout);\n\n\t\t// Set a named connection type for logging purposes.\n\t\tconst connectionType = (this.encrypted ? 'an encrypted TCP Socket' : 'a TCP Socket');\n\n\t\t// Log that we are trying to establish a connection.\n\t\tdebug.network(`Initiating ${connectionType} connection to '${this.host}:${this.port}'.`);\n\n\t\tif(this.encrypted)\n\t\t{\n\t\t\t// Initialize connection options.\n\t\t\tconst connectionOptions: ConnectionOptions = { rejectUnauthorized: false };\n\n\t\t\t// If the hostname is not an IP address..\n\t\t\tif(!net.isIP(this.host))\n\t\t\t{\n\t\t\t\t// Set the servername option which enables support for SNI.\n\t\t\t\t// NOTE: SNI enables a server that hosts multiple domains to provide the appropriate TLS certificate.\n\t\t\t\tconnectionOptions.serverName = this.host;\n\t\t\t}\n\n\t\t\t// Initialize the socket (allowing self-signed certificates).\n\t\t\tthis.tcpSocket = tls.connect(this.port, this.host, connectionOptions);\n\n\t\t\t// Add a 'secureConnect' listener that checks the authorization status of\n\t\t\t// the socket, and logs a warning when it uses a self signed certificate.\n\t\t\tthis.tcpSocket.once('secureConnect', () =>\n\t\t\t{\n\t\t\t\t// Cannot happen, since this event callback *only* exists on TLSSocket\n\t\t\t\tif(!(this.tcpSocket instanceof tls.TLSSocket)) return;\n\n\t\t\t\t// Force cast authorizationError from Error to string (through unknown)\n\t\t\t\t// because it is incorrectly typed as an Error\n\t\t\t\tconst authorizationError = (this.tcpSocket.authorizationError as unknown) as string;\n\t\t\t\tif(authorizationError === 'DEPTH_ZERO_SELF_SIGNED_CERT')\n\t\t\t\t{\n\t\t\t\t\tdebug.warning(`Connection to ${this.host}:${this.port} uses a self-signed certificate`);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Trigger successful connection events.\n\t\t\tthis.tcpSocket.on('secureConnect', this.onConnect.bind(this));\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// Initialize the socket.\n\t\t\tthis.tcpSocket = net.connect({ host: this.host, port: this.port });\n\n\t\t\t// Trigger successful connection events.\n\t\t\tthis.tcpSocket.on('connect', this.onConnect.bind(this));\n\t\t}\n\n\t\t// Configure encoding.\n\t\tthis.tcpSocket.setEncoding('utf8');\n\n\t\t// Enable persistent connections.\n\t\t// NOTE: This will send a non-data message 0.25 second after last activity.\n\t\t// After 10 consecutive such messages with no response, the connection will be cut.\n\t\tthis.tcpSocket.setKeepAlive(true, 250);\n\n\t\t// Disable buffering of outgoing data.\n\t\tthis.tcpSocket.setNoDelay(true);\n\n\t\t// Forward the encountered errors.\n\t\tthis.tcpSocket.on('error', this.onError);\n\t}\n\n\t/**\n\t * Internal error handler that helps provide context to some types of errors before passing them up through the stack.\n\t */\n\tprivate onError(error: NodeJS.ErrnoException): void\n\t{\n\t\tswitch(error.code)\n\t\t{\n\t\t\t// If the DNS lookup failed.\n\t\t\tcase 'EAI_AGAIN':\n\t\t\t\tthis.emit('error', new Error(`Failed to look up DNS records for '${this.host}'.`));\n\t\t\t\tbreak;\n\n\t\t\t// If the connection timed out..\n\t\t\tcase 'ETIMEDOUT':\n\t\t\t\tthis.emit('error', error);\n\t\t\t\tbreak;\n\n\t\t\t// For unknown errors..\n\t\t\tdefault:\n\t\t\t\tthis.emit('error', error);\n\t\t}\n\t}\n\n\t/**\n\t * Sets up forwarding of events related to the connection.\n\t */\n\tprivate onConnect(): void\n\t{\n\t\t// If the onConnect function has already run, do not execute it again.\n\t\tif(this.onConnectHasRun) return;\n\n\t\t// Set a named connection type for logging purposes.\n\t\tconst connectionType = (this.encrypted ? 'an encrypted TCP Socket' : 'a TCP Socket');\n\n\t\t// Log that the connection has been established.\n\t\tdebug.network(`Established ${connectionType} connection with '${this.host}:${this.port}'.`);\n\n\t\t// Forward the socket events\n\t\tthis.tcpSocket.addListener('close', this.eventForwarders.disconnect);\n\t\tthis.tcpSocket.addListener('data', this.eventForwarders.tcpData);\n\n\t\t// Indicate that the onConnect function has run.\n\t\tthis.onConnectHasRun = true;\n\n\t\t// Emit the connect event.\n\t\tthis.emit('connected');\n\t}\n\n\t/**\n\t * Clears the disconnect timer if it is still active.\n\t */\n\tprivate clearDisconnectTimerOnTimeout(): void\n\t{\n\t\t// Clear the retry timer if it is still active.\n\t\tif(this.disconnectTimer)\n\t\t{\n\t\t\tclearTimeout(this.disconnectTimer);\n\t\t}\n\t}\n\n\t/**\n\t * Forcibly terminate the connection.\n\t *\n\t * @throws {Error} if no connection was found\n\t */\n\tpublic disconnect(): void\n\t{\n\t\t// Clear the disconnect timer so that the socket does not try to disconnect again later.\n\t\tthis.clearDisconnectTimerOnTimeout();\n\n\t\tif(this.tcpSocket)\n\t\t{\n\t\t\t// Remove all event forwarders.\n\t\t\tthis.tcpSocket.removeListener('close', this.eventForwarders.disconnect);\n\t\t\tthis.tcpSocket.removeListener('data', this.eventForwarders.tcpData);\n\n\t\t\t// Also remove the error forwarder, to prevent the following destroy call from generating error messages.\n\t\t\tthis.tcpSocket.removeListener('error', this.onError);\n\n\t\t\t// Terminate the connection.\n\t\t\tthis.tcpSocket.destroy();\n\n\t\t\t// Remove the stored socket.\n\t\t\tthis.tcpSocket = undefined;\n\t\t}\n\n\t\t// Indicate that the onConnect function has not run and it has to be run again.\n\t\tthis.onConnectHasRun = false;\n\n\t\t// Emit a disconnect event\n\t\tthis.emit('disconnected');\n\t}\n\n\t/**\n\t * Write data to the socket\n\t *\n\t * @param data Data to be written to the socket\n\t * @param callback Callback function to be called when the write has completed\n\t *\n\t * @throws {Error} if no connection was found\n\t * @returns true if the message was fully flushed to the socket, false if part of the message\n\t * is queued in the user memory\n\t */\n\tpublic write(data: Uint8Array | string, callback?: (err?: Error) => void): boolean\n\t{\n\t\t// Throw an error if no active connection is found\n\t\tif(!this.tcpSocket)\n\t\t{\n\t\t\tthrow(new Error('Cannot write to socket when there is no active connection'));\n\t\t}\n\n\t\t// Write data to the TLS Socket and return the status indicating\n\t\t// whether the full message was flushed to the socket\n\t\treturn this.tcpSocket.write(data, callback);\n\t}\n\n\t/**\n\t * Force a disconnection if no connection is established after `timeout` milliseconds.\n\t */\n\tprivate disconnectOnTimeout(): void\n\t{\n\t\t// Remove the connect listener.\n\t\tthis.removeListener('connected', this.clearDisconnectTimerOnTimeout);\n\n\t\t// Emit an error event so that connect is rejected upstream.\n\t\tthis.emit('error', new Error(`Connection to '${this.host}:${this.port}' timed out after ${this.timeout} milliseconds`));\n\n\t\t// Forcibly disconnect to clean up the connection on timeout\n\t\tthis.disconnect();\n\t}\n\n\t// Add magic glue that makes typedoc happy so that we can have the events listed on the class.\n\tpublic readonly connected: [];\n\tpublic readonly disconnected: [];\n\tpublic readonly data: [ string ];\n\tpublic readonly error: [ Error ];\n}\n","// Export a default timeout value of 30 seconds.\nexport const defaultTimeout = 30 * 1000;\n","/**\n * Connection options used with TLS connections.\n * @ignore\n */\nexport interface ConnectionOptions\n{\n\trejectUnauthorized?: boolean;\n\tserverName?: string;\n}\n"],"names":[],"version":3,"file":"index.mjs.map"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../source/constants.ts","../source/tcp.ts"],"sourcesContent":["// Export a default timeout value of 30 seconds.\nexport const defaultTimeout = 30 * 1000;\n","import * as tls from 'tls';\nimport * as net from 'net';\nimport debug from '@electrum-cash/debug-logs';\nimport { defaultTimeout } from './constants.ts';\n\nimport { EventEmitter } from 'eventemitter3';\nimport type { ElectrumSocket, ElectrumSocketEvents } from '@electrum-cash/network';\n\n/**\n * Connection options used with TLS connections.\n * @ignore\n */\ninterface ConnectionOptions\n{\n\trejectUnauthorized?: boolean;\n\tserverName?: string;\n}\n\n/**\n * TCP Socket used when communicating with Electrum servers.\n */\nexport class ElectrumTcpSocket extends EventEmitter<ElectrumSocketEvents> implements ElectrumSocket\n{\n\t// Declare an empty TCP socket.\n\tprivate tcpSocket: net.Socket;\n\n\t// Used to disconnect after some time if initial connection is too slow.\n\tprivate disconnectTimer?: number;\n\n\t// Initialize boolean that indicates whether the onConnect function has run (initialize to false).\n\tprivate onConnectHasRun = false;\n\n\t// Initialize event forwarding functions.\n\tprivate eventForwarders =\n\t{\n\t\tdisconnect: () => this.emit('disconnected'),\n\t\ttcpData: (data: string) => this.emit('data', data),\n\t};\n\n\t/**\n\t * Creates a socket configured with connection information for a given Electrum server.\n\t *\n\t * @param host Fully qualified domain name or IP address of the host\n\t * @param port Network port for the host to connect to, defaults to the standard TLS port\n\t * @param encrypted If false, uses an unencrypted connection instead of the default on TLS\n\t * @param timeout If no connection is established after `timeout` ms, the connection is terminated\n\t */\n\tpublic constructor\n\t(\n\t\tpublic host: string,\n\t\tpublic port: number = 50002,\n\t\tpublic encrypted: boolean = true,\n\t\tpublic timeout: number = defaultTimeout,\n\t)\n\t{\n\t\t// Initialize the event emitter.\n\t\tsuper();\n\t}\n\n\t/**\n\t * Returns a string for the host identifier for usage in debug messages.\n\t */\n\tget hostIdentifier(): string\n\t{\n\t\treturn `${this.host}:${this.port}`;\n\t}\n\n\t/**\n\t * Connect to host:port using the specified transport\n\t */\n\tpublic connect(): void\n\t{\n\t\t// Check that no existing socket exists before initiating a new connection.\n\t\tif(this.tcpSocket)\n\t\t{\n\t\t\tthrow(new Error('Cannot initiate a new socket connection when an existing connection exists'));\n\t\t}\n\n\t\t// Set a timer to force disconnect after `timeout` seconds\n\t\tthis.disconnectTimer = setTimeout(() => this.disconnectOnTimeout(), this.timeout) as unknown as number;\n\n\t\t// Remove the timer if a connection is successfully established\n\t\tthis.once('connected', this.clearDisconnectTimerOnTimeout);\n\n\t\t// Set a named connection type for logging purposes.\n\t\tconst connectionType = (this.encrypted ? 'an encrypted TCP Socket' : 'a TCP Socket');\n\n\t\t// Log that we are trying to establish a connection.\n\t\tdebug.network(`Initiating ${connectionType} connection to '${this.host}:${this.port}'.`);\n\n\t\tif(this.encrypted)\n\t\t{\n\t\t\t// Initialize connection options.\n\t\t\tconst connectionOptions: ConnectionOptions = { rejectUnauthorized: false };\n\n\t\t\t// If the hostname is not an IP address..\n\t\t\tif(!net.isIP(this.host))\n\t\t\t{\n\t\t\t\t// Set the servername option which enables support for SNI.\n\t\t\t\t// NOTE: SNI enables a server that hosts multiple domains to provide the appropriate TLS certificate.\n\t\t\t\tconnectionOptions.serverName = this.host;\n\t\t\t}\n\n\t\t\t// Initialize the socket (allowing self-signed certificates).\n\t\t\tthis.tcpSocket = tls.connect(this.port, this.host, connectionOptions);\n\n\t\t\t// Add a 'secureConnect' listener that checks the authorization status of\n\t\t\t// the socket, and logs a warning when it uses a self signed certificate.\n\t\t\tthis.tcpSocket.once('secureConnect', () =>\n\t\t\t{\n\t\t\t\t// Cannot happen, since this event callback *only* exists on TLSSocket\n\t\t\t\tif(!(this.tcpSocket instanceof tls.TLSSocket)) return;\n\n\t\t\t\t// Force cast authorizationError from Error to string (through unknown)\n\t\t\t\t// because it is incorrectly typed as an Error\n\t\t\t\tconst authorizationError = (this.tcpSocket.authorizationError as unknown) as string;\n\t\t\t\tif(authorizationError === 'DEPTH_ZERO_SELF_SIGNED_CERT')\n\t\t\t\t{\n\t\t\t\t\tdebug.warning(`Connection to ${this.host}:${this.port} uses a self-signed certificate`);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Trigger successful connection events.\n\t\t\tthis.tcpSocket.on('secureConnect', this.onConnect.bind(this));\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// Initialize the socket.\n\t\t\tthis.tcpSocket = net.connect({ host: this.host, port: this.port });\n\n\t\t\t// Trigger successful connection events.\n\t\t\tthis.tcpSocket.on('connect', this.onConnect.bind(this));\n\t\t}\n\n\t\t// Configure encoding.\n\t\tthis.tcpSocket.setEncoding('utf8');\n\n\t\t// Enable persistent connections.\n\t\t// NOTE: This will send a non-data message 0.25 second after last activity.\n\t\t// After 10 consecutive such messages with no response, the connection will be cut.\n\t\tthis.tcpSocket.setKeepAlive(true, 250);\n\n\t\t// Disable buffering of outgoing data.\n\t\tthis.tcpSocket.setNoDelay(true);\n\n\t\t// Forward the encountered errors.\n\t\tthis.tcpSocket.on('error', this.onError);\n\t}\n\n\t/**\n\t * Internal error handler that helps provide context to some types of errors before passing them up through the stack.\n\t */\n\tprivate onError(error: NodeJS.ErrnoException): void\n\t{\n\t\tswitch(error.code)\n\t\t{\n\t\t\t// If the DNS lookup failed.\n\t\t\tcase 'EAI_AGAIN':\n\t\t\t\tthis.emit('error', new Error(`Failed to look up DNS records for '${this.host}'.`));\n\t\t\t\tbreak;\n\n\t\t\t// If the connection timed out..\n\t\t\tcase 'ETIMEDOUT':\n\t\t\t\tthis.emit('error', error);\n\t\t\t\tbreak;\n\n\t\t\t// For unknown errors..\n\t\t\tdefault:\n\t\t\t\tthis.emit('error', error);\n\t\t}\n\t}\n\n\t/**\n\t * Sets up forwarding of events related to the connection.\n\t */\n\tprivate onConnect(): void\n\t{\n\t\t// If the onConnect function has already run, do not execute it again.\n\t\tif(this.onConnectHasRun) return;\n\n\t\t// Set a named connection type for logging purposes.\n\t\tconst connectionType = (this.encrypted ? 'an encrypted TCP Socket' : 'a TCP Socket');\n\n\t\t// Log that the connection has been established.\n\t\tdebug.network(`Established ${connectionType} connection with '${this.host}:${this.port}'.`);\n\n\t\t// Forward the socket events\n\t\tthis.tcpSocket.addListener('close', this.eventForwarders.disconnect);\n\t\tthis.tcpSocket.addListener('data', this.eventForwarders.tcpData);\n\n\t\t// Indicate that the onConnect function has run.\n\t\tthis.onConnectHasRun = true;\n\n\t\t// Emit the connect event.\n\t\tthis.emit('connected');\n\t}\n\n\t/**\n\t * Clears the disconnect timer if it is still active.\n\t */\n\tprivate clearDisconnectTimerOnTimeout(): void\n\t{\n\t\t// Clear the retry timer if it is still active.\n\t\tif(this.disconnectTimer)\n\t\t{\n\t\t\tclearTimeout(this.disconnectTimer);\n\t\t}\n\t}\n\n\t/**\n\t * Forcibly terminate the connection.\n\t *\n\t * @throws {Error} if no connection was found\n\t */\n\tpublic disconnect(): void\n\t{\n\t\t// Clear the disconnect timer so that the socket does not try to disconnect again later.\n\t\tthis.clearDisconnectTimerOnTimeout();\n\n\t\tif(this.tcpSocket)\n\t\t{\n\t\t\t// Remove all event forwarders.\n\t\t\tthis.tcpSocket.removeListener('close', this.eventForwarders.disconnect);\n\t\t\tthis.tcpSocket.removeListener('data', this.eventForwarders.tcpData);\n\n\t\t\t// Also remove the error forwarder, to prevent the following destroy call from generating error messages.\n\t\t\tthis.tcpSocket.removeListener('error', this.onError);\n\n\t\t\t// Terminate the connection.\n\t\t\tthis.tcpSocket.destroy();\n\n\t\t\t// Remove the stored socket.\n\t\t\tthis.tcpSocket = undefined;\n\t\t}\n\n\t\t// Indicate that the onConnect function has not run and it has to be run again.\n\t\tthis.onConnectHasRun = false;\n\n\t\t// Emit a disconnect event\n\t\tthis.emit('disconnected');\n\t}\n\n\t/**\n\t * Write data to the socket\n\t *\n\t * @param data Data to be written to the socket\n\t * @param callback Callback function to be called when the write has completed\n\t *\n\t * @throws {Error} if no connection was found\n\t * @returns true if the message was fully flushed to the socket, false if part of the message\n\t * is queued in the user memory\n\t */\n\tpublic write(data: Uint8Array | string, callback?: (err?: Error) => void): boolean\n\t{\n\t\t// Throw an error if no active connection is found\n\t\tif(!this.tcpSocket)\n\t\t{\n\t\t\tthrow(new Error('Cannot write to socket when there is no active connection'));\n\t\t}\n\n\t\t// Write data to the TLS Socket and return the status indicating\n\t\t// whether the full message was flushed to the socket\n\t\treturn this.tcpSocket.write(data, callback);\n\t}\n\n\t/**\n\t * Force a disconnection if no connection is established after `timeout` milliseconds.\n\t */\n\tprivate disconnectOnTimeout(): void\n\t{\n\t\t// Remove the connect listener.\n\t\tthis.removeListener('connected', this.clearDisconnectTimerOnTimeout);\n\n\t\t// Emit an error event so that connect is rejected upstream.\n\t\tthis.emit('error', new Error(`Connection to '${this.host}:${this.port}' timed out after ${this.timeout} milliseconds`));\n\n\t\t// Forcibly disconnect to clean up the connection on timeout\n\t\tthis.disconnect();\n\t}\n\n\t// Add magic glue that makes typedoc happy so that we can have the events listed on the class.\n\tpublic readonly connected: [];\n\tpublic readonly disconnected: [];\n\tpublic readonly data: [ string ];\n\tpublic readonly error: [ Error ];\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@electrum-cash/tcp-socket",
3
- "version": "1.0.0",
3
+ "version": "1.1.0-development.12711670847",
4
4
  "description": "@electrum-cash/web-socket implements the ElectrumSocket interface using nodejs tcp sockets.",
5
5
  "keywords": [
6
6
  "electrum",
@@ -19,43 +19,42 @@
19
19
  "license": "MIT",
20
20
  "source": "./source/index.ts",
21
21
  "type": "module",
22
- "types": "./dist/index.d.ts",
22
+ "types": "./dist/index.d.mts",
23
23
  "module": "./dist/index.mjs",
24
24
  "exports": {
25
- "types": "./dist/index.d.ts",
25
+ "types": "./dist/index.d.mts",
26
26
  "default": "./dist/index.mjs"
27
27
  },
28
28
  "files": [
29
29
  "dist"
30
30
  ],
31
31
  "scripts": {
32
- "clean": "del ./dist",
33
- "build": "npm run clean && parcel build",
34
- "analyze": "parcel build --reporter @parcel/reporter-bundle-analyzer",
32
+ "build": "tsdown --clean --sourcemap source/index.ts",
33
+ "analyze": "tsdown --clean --no-fixed-extension --sourcemap source/index.ts && esbuild-analyzer dist/",
35
34
  "docs": "typedoc --hideGenerator --categorizeByGroup",
36
- "lint": "eslint . --ext .ts",
35
+ "lint": "eslint",
37
36
  "syntax": "tsc --noEmit",
38
37
  "spellcheck": "cspell 'source/**' 'test/**' 'examples/**'",
39
38
  "test": "vitest --dir test/ --test-timeout=15000 --passWithNoTests --run --coverage"
40
39
  },
41
40
  "devDependencies": {
42
- "@electrum-cash/network": "^4.0.2-development.8063220996",
43
- "@generalprotocols/cspell-dictionary": "git+https://gitlab.com/GeneralProtocols/cspell-dictionary.git",
44
- "@generalprotocols/eslint-config": "git+https://gitlab.com/GeneralProtocols/eslint-config.git",
45
- "@parcel/packager-ts": "^2.12.0",
46
- "@parcel/transformer-typescript-types": "^2.12.0",
41
+ "@chalp/eslint-airbnb": "^1.3.0",
42
+ "@electrum-cash/eslint-config": "^1.1.0",
43
+ "@electrum-cash/network": "^4.1.4",
44
+ "@stylistic/eslint-plugin": "^5.7.0",
47
45
  "@types/debug": "^4.1.6",
48
- "@typescript-eslint/eslint-plugin": "^6.8.0",
49
- "@vitest/coverage-v8": "^1.3.1",
46
+ "@typescript-eslint/eslint-plugin": "^8.53.0",
47
+ "@typescript-eslint/parser": "^8.53.0",
48
+ "@vitest/coverage-v8": "^3.2.4",
49
+ "@viz-kit/esbuild-analyzer": "^1.0.0",
50
50
  "cspell": "^8.6.0",
51
- "del-cli": "^5.0.0",
52
- "eslint": "^8.42.0",
53
- "eslint-plugin-import": "^2.23.4",
54
- "parcel": "^2.12.0",
51
+ "eslint": "^9.39.2",
52
+ "tsdown": "^0.20.0-beta.3",
55
53
  "typedoc": "^0.25.12",
56
54
  "typedoc-plugin-coverage": "^3.1.0",
57
55
  "typescript": "^5.1.3",
58
- "vitest": "^1.3.1"
56
+ "typescript-eslint": "^8.53.0",
57
+ "vitest": "^3.2.4"
59
58
  },
60
59
  "dependencies": {
61
60
  "@electrum-cash/debug-logs": "^1.0.0",
package/dist/index.d.ts DELETED
@@ -1,59 +0,0 @@
1
- import { EventEmitter } from "eventemitter3";
2
- import { ElectrumSocket, ElectrumSocketEvents } from "@electrum-cash/network";
3
- /**
4
- * TCP Socket used when communicating with Electrum servers.
5
- */
6
- export class ElectrumTcpSocket extends EventEmitter<ElectrumSocketEvents> implements ElectrumSocket {
7
- host: string;
8
- port: number;
9
- encrypted: boolean;
10
- timeout: number;
11
- /**
12
- * Creates a socket configured with connection information for a given Electrum server.
13
- *
14
- * @param host Fully qualified domain name or IP address of the host
15
- * @param port Network port for the host to connect to, defaults to the standard TLS port
16
- * @param encrypted If false, uses an unencrypted connection instead of the default on TLS
17
- * @param timeout If no connection is established after `timeout` ms, the connection is terminated
18
- */
19
- constructor(host: string, port?: number, encrypted?: boolean, timeout?: number);
20
- /**
21
- * Returns a string for the host identifier for usage in debug messages.
22
- */
23
- get hostIdentifier(): string;
24
- /**
25
- * Connect to host:port using the specified transport
26
- */
27
- connect(): void;
28
- /**
29
- * Forcibly terminate the connection.
30
- *
31
- * @throws {Error} if no connection was found
32
- */
33
- disconnect(): void;
34
- /**
35
- * Write data to the socket
36
- *
37
- * @param data Data to be written to the socket
38
- * @param callback Callback function to be called when the write has completed
39
- *
40
- * @throws {Error} if no connection was found
41
- * @returns true if the message was fully flushed to the socket, false if part of the message
42
- * is queued in the user memory
43
- */
44
- write(data: Uint8Array | string, callback?: (err?: Error) => void): boolean;
45
- readonly connected: [];
46
- readonly disconnected: [];
47
- readonly data: [string];
48
- readonly error: [Error];
49
- }
50
- /**
51
- * Connection options used with TLS connections.
52
- * @ignore
53
- */
54
- export interface ConnectionOptions {
55
- rejectUnauthorized?: boolean;
56
- serverName?: string;
57
- }
58
-
59
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"mappings":";;ACkBA;;GAEG;AACH,8BAA+B,SAAQ,aAAa,oBAAoB,CAAE,YAAW,cAAc;IA4B1F,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,MAAM;IACZ,SAAS,EAAE,OAAO;IAClB,OAAO,EAAE,MAAM;IAbvB;;;;;;;OAOG;gBAGK,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,MAAc,EACpB,SAAS,GAAE,OAAc,EACzB,OAAO,GAAE,MAAuB;IAOxC;;OAEG;IACH,IAAI,cAAc,IAAI,MAAM,CAG3B;IAED;;OAEG;IACI,OAAO,IAAI,IAAI;IA2ItB;;;;OAIG;IACI,UAAU,IAAI,IAAI;IA4BzB;;;;;;;;;OASG;IACI,KAAK,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,KAAK,IAAI,GAAG,OAAO;IA6BlF,SAAgB,SAAS,EAAE,EAAE,CAAC;IAC9B,SAAgB,YAAY,EAAE,EAAE,CAAC;IACjC,SAAgB,IAAI,EAAE,CAAE,MAAM,CAAE,CAAC;IACjC,SAAgB,KAAK,EAAE,CAAE,KAAK,CAAE,CAAC;CACjC;AC7RD;;;GAGG;AACH;IAEC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB","sources":["source/source/constants.ts","source/source/tcp.ts","source/source/interfaces.ts","source/source/index.ts","source/index.ts"],"sourcesContent":[null,null,null,null,"export * from './tcp.ts';\nexport * from './interfaces';\n"],"names":[],"version":3,"file":"index.d.ts.map"}