diodejs 0.0.3

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/connection.js ADDED
@@ -0,0 +1,552 @@
1
+ // connection.js
2
+ const tls = require('tls');
3
+ const fs = require('fs');
4
+ const { RLP } = require('@ethereumjs/rlp');
5
+ const EventEmitter = require('events');
6
+ const { makeReadable, parseRequestId, parseResponseType, parseReason } = require('./utils');
7
+ const { Buffer } = require('buffer'); // Import Buffer
8
+ const asn1 = require('asn1.js');
9
+ const secp256k1 = require('secp256k1');
10
+ const ethUtil = require('ethereumjs-util');
11
+ const crypto = require('crypto');
12
+ const DiodeRPC = require('./rpc');
13
+ const abi = require('ethereumjs-abi');
14
+ class DiodeConnection extends EventEmitter {
15
+ constructor(host, port, certPath) {
16
+ super();
17
+ this.host = host;
18
+ this.port = port;
19
+ this.certPath = certPath;
20
+ this.socket = null;
21
+ this.requestId = 0; // Initialize request ID counter
22
+ this.pendingRequests = new Map(); // Map to store pending requests
23
+ this.totalConnections = 0;
24
+ this.totalBytes = 128000; // start with 128KB
25
+ // Add buffer to handle partial data
26
+ this.receiveBuffer = Buffer.alloc(0);
27
+ this.RPC = new DiodeRPC(this);
28
+ }
29
+
30
+ connect() {
31
+ return new Promise((resolve, reject) => {
32
+ const options = {
33
+ cert: fs.readFileSync(this.certPath),
34
+ key: fs.readFileSync(this.certPath),
35
+ rejectUnauthorized: false,
36
+ ciphers: 'ECDHE-ECDSA-AES256-GCM-SHA384',
37
+ ecdhCurve: 'secp256k1',
38
+ minVersion: 'TLSv1.2',
39
+ maxVersion: 'TLSv1.2',
40
+ };
41
+
42
+ this.socket = tls.connect(this.port, this.host, options, async () => {
43
+ console.log('Connected to Diode.io server');
44
+ // Set keep-alive to prevent connection timeout forever
45
+ this.socket.setKeepAlive(true, 0);
46
+
47
+ // Send the ticketv2 command
48
+ try {
49
+ const ticketCommand = await this.createTicketCommand();
50
+ const response = await this.sendCommand(ticketCommand);
51
+ console.log('Ticket accepted:', response);
52
+ resolve();
53
+ } catch (error) {
54
+ console.error('Error sending ticket:', error);
55
+ reject(error);
56
+ }
57
+ });
58
+
59
+ this.socket.on('data', (data) => {
60
+ try {
61
+ this._handleData(data);
62
+ } catch (error) {
63
+ console.error('Error handling data:', error);
64
+ }
65
+ });
66
+ this.socket.on('error', (err) => {
67
+ console.error('Connection error:', err);
68
+ reject(err);
69
+ });
70
+ this.socket.on('end', () => console.log('Disconnected from server'));
71
+ });
72
+ }
73
+
74
+ _handleData(data) {
75
+ // Append new data to the receive buffer
76
+ this.receiveBuffer = Buffer.concat([this.receiveBuffer, data]);
77
+ console.log('Received data:', data.toString('hex'));
78
+
79
+ let offset = 0;
80
+ while (offset + 2 <= this.receiveBuffer.length) {
81
+ // Read the length of the message (2 bytes)
82
+ const lengthBuffer = this.receiveBuffer.slice(offset, offset + 2);
83
+ const length = lengthBuffer.readUInt16BE(0);
84
+
85
+ if (offset + 2 + length > this.receiveBuffer.length) {
86
+ // Not enough data received yet, wait for more
87
+ break;
88
+ }
89
+
90
+ const messageBuffer = this.receiveBuffer.slice(offset + 2, offset + 2 + length);
91
+ offset += 2 + length;
92
+
93
+ try {
94
+ const decodedMessage = RLP.decode(Uint8Array.from(messageBuffer));
95
+ console.log('Decoded message:', makeReadable(decodedMessage));
96
+
97
+ if (Array.isArray(decodedMessage) && decodedMessage.length > 1) {
98
+ const requestIdRaw = decodedMessage[0];
99
+ const responseArray = decodedMessage[1];
100
+
101
+ // Parse requestId
102
+ const requestId = parseRequestId(requestIdRaw);
103
+
104
+ // Debug statements
105
+ console.log('requestIdRaw:', requestIdRaw);
106
+ console.log('Parsed requestId:', requestId);
107
+
108
+ if (requestId !== null && this.pendingRequests.has(requestId)) {
109
+ // This is a response to a pending request
110
+ const [responseTypeRaw, ...responseData] = responseArray;
111
+ const responseRaw = responseData[0];
112
+
113
+ // Debug statements
114
+ console.log('responseTypeRaw:', responseTypeRaw);
115
+ console.log('Type of responseTypeRaw:', typeof responseTypeRaw);
116
+ console.log('Instance of responseTypeRaw:', responseTypeRaw instanceof Uint8Array);
117
+ console.log('Is Array:', Array.isArray(responseTypeRaw));
118
+
119
+ // Parse responseType
120
+ const responseType = parseResponseType(responseTypeRaw);
121
+
122
+ console.log(`Received response for requestId: ${requestId}`);
123
+ console.log(`Response Type: '${responseType}'`);
124
+
125
+ const { resolve, reject } = this.pendingRequests.get(requestId);
126
+ try{
127
+ if (responseType === 'response') {
128
+ if (!Array.isArray(responseRaw) && makeReadable(responseRaw) === 'too_low') {
129
+ this.fixResponse(responseData);
130
+ // Re-send the ticket command
131
+ this.createTicketCommand().then((ticketCommand) => {
132
+ this.sendCommand(ticketCommand).then(resolve).catch(reject);
133
+ }).catch(reject);
134
+ resolve(responseData);
135
+ }
136
+ resolve(responseData);
137
+ } else if (responseType === 'error') {
138
+ if (responseData.length > 1) {
139
+ const reason = parseReason(responseData[1]);
140
+ reject(new Error(reason));
141
+ } else {
142
+ const reason = parseReason(responseData[0]);
143
+ reject(new Error(reason));
144
+ }
145
+ } else {
146
+ resolve(responseData);
147
+ }
148
+ } catch (error) {
149
+ console.error('Error handling response:', error);
150
+ }
151
+ this.pendingRequests.delete(requestId);
152
+ } else {
153
+ // This is an unsolicited message
154
+ console.log('Received unsolicited message:', decodedMessage);
155
+ this.emit('unsolicited', decodedMessage);
156
+ }
157
+ } else {
158
+ // Invalid message format
159
+ console.error('Invalid message format:', decodedMessage);
160
+ }
161
+ } catch (error) {
162
+ console.error('Error decoding message:', error);
163
+ }
164
+ }
165
+
166
+
167
+ // Remove processed data from the buffer
168
+ this.receiveBuffer = this.receiveBuffer.slice(offset);
169
+ }
170
+
171
+ fixResponse(response) {
172
+ /* response is :
173
+ [
174
+ 'too_low',
175
+ 1284,
176
+ 666,
177
+ 11,
178
+ 135591,
179
+ 'test',
180
+ '0x01eb1726dd7286d2dab222ea5dfef7c820cd01c30936240f5780a6e468e731f3b55d4c963b3eb768663263b396555aa52be49d7d3ae2a9173732fa410ad46434f3'
181
+ ]
182
+ [3] is last totalConnections
183
+ [4] is last totalBytes
184
+ */
185
+ const totalConnectionsBuffer = Buffer.from(response[3]);
186
+ const totalBytesBuffer = Buffer.from(response[4]);
187
+ this.totalConnections = parseInt(totalConnectionsBuffer.readUIntBE(0, totalConnectionsBuffer.length), 10) +1;
188
+ this.totalBytes = parseInt(totalBytesBuffer.readUIntBE(0, totalBytesBuffer.length), 10) + 128000;
189
+ }
190
+
191
+ sendCommand(commandArray) {
192
+ return new Promise((resolve, reject) => {
193
+ //check if connection is alive
194
+ if (!this.socket || this.socket.destroyed) {
195
+ //reconnect
196
+ this.connect().then(() => {
197
+ this.sendCommand(commandArray).then(resolve).catch(reject);
198
+ }).catch(reject);
199
+ return;
200
+ }
201
+ const requestId = this._getNextRequestId();
202
+ // Build the message as [requestId, [commandArray]]
203
+ const commandWithId = [requestId, commandArray];
204
+
205
+ // Store the promise callbacks to resolve/reject later
206
+ this.pendingRequests.set(requestId, { resolve, reject });
207
+
208
+ const commandBuffer = RLP.encode(commandWithId);
209
+ const byteLength = Buffer.byteLength(commandBuffer);
210
+
211
+ // Create a 2-byte length buffer
212
+ const lengthBuffer = Buffer.alloc(2);
213
+ lengthBuffer.writeUInt16BE(byteLength, 0);
214
+
215
+ const message = Buffer.concat([lengthBuffer, commandBuffer]);
216
+
217
+ console.log(`Sending command with requestId ${requestId}:`, commandArray);
218
+ console.log('Command buffer:', message.toString('hex'));
219
+
220
+ this.socket.write(message);
221
+ });
222
+ }
223
+
224
+ sendCommandWithSessionId(commandArray, sessionId) {
225
+ return new Promise((resolve, reject) => {
226
+ //check if connection is alive
227
+ if (!this.socket || this.socket.destroyed) {
228
+ //reconnect
229
+ this.connect().then(() => {
230
+ this.sendCommand(commandArray).then(resolve).catch(reject);
231
+ }).catch(reject);
232
+ return;
233
+ }
234
+ const requestId = sessionId;
235
+ // Build the message as [requestId, [commandArray]]
236
+ const commandWithId = [requestId, commandArray];
237
+
238
+ // Store the promise callbacks to resolve/reject later
239
+ this.pendingRequests.set(requestId, { resolve, reject });
240
+
241
+ const commandBuffer = RLP.encode(commandWithId);
242
+ const byteLength = Buffer.byteLength(commandBuffer);
243
+
244
+ // Create a 2-byte length buffer
245
+ const lengthBuffer = Buffer.alloc(2);
246
+ lengthBuffer.writeUInt16BE(byteLength, 0);
247
+
248
+ const message = Buffer.concat([lengthBuffer, commandBuffer]);
249
+
250
+ console.log(`Sending command with requestId ${requestId}:`, commandArray);
251
+ console.log('Command buffer:', message.toString('hex'));
252
+
253
+ this.socket.write(message);
254
+ });
255
+ }
256
+
257
+ getEthereumAddress() {
258
+ try {
259
+ const pem = fs.readFileSync(this.certPath, 'utf8');
260
+ let privateKeyPem;
261
+ let privateKeyDer;
262
+ let privateKeyBytes;
263
+
264
+ if (pem.includes('-----BEGIN PRIVATE KEY-----')) {
265
+ // Handle PKCS#8 format
266
+ privateKeyPem = pem
267
+ .replace('-----BEGIN PRIVATE KEY-----', '')
268
+ .replace('-----END PRIVATE KEY-----', '')
269
+ .replace(/\r?\n|\r/g, '');
270
+
271
+ privateKeyDer = Buffer.from(privateKeyPem, 'base64');
272
+
273
+ // Define ASN.1 structure for PKCS#8 private key
274
+ const PrivateKeyInfoASN = asn1.define('PrivateKeyInfo', function () {
275
+ this.seq().obj(
276
+ this.key('version').int(),
277
+ this.key('privateKeyAlgorithm').seq().obj(
278
+ this.key('algorithm').objid(),
279
+ this.key('parameters').optional()
280
+ ),
281
+ this.key('privateKey').octstr(),
282
+ this.key('attributes').implicit(0).any().optional(),
283
+ this.key('publicKey').implicit(1).bitstr().optional()
284
+ );
285
+ });
286
+
287
+ // Decode the DER-encoded private key
288
+ const privateKeyInfo = PrivateKeyInfoASN.decode(privateKeyDer, 'der');
289
+ const privateKeyOctetString = privateKeyInfo.privateKey;
290
+
291
+ // Now parse the ECPrivateKey structure inside the octet string
292
+ const ECPrivateKeyASN = asn1.define('ECPrivateKey', function () {
293
+ this.seq().obj(
294
+ this.key('version').int(),
295
+ this.key('privateKey').octstr(),
296
+ this.key('parameters').explicit(0).objid().optional(),
297
+ this.key('publicKey').explicit(1).bitstr().optional()
298
+ );
299
+ });
300
+
301
+ const ecPrivateKey = ECPrivateKeyASN.decode(privateKeyOctetString, 'der');
302
+ privateKeyBytes = ecPrivateKey.privateKey;
303
+ console.log('Private key bytes:', privateKeyBytes.toString('hex'));
304
+ } else {
305
+ throw new Error('Unsupported key format. Expected EC PRIVATE KEY or PRIVATE KEY in PEM format.');
306
+ }
307
+
308
+ // Compute the public key
309
+ const publicKeyUint8Array = secp256k1.publicKeyCreate(privateKeyBytes, false); // uncompressed
310
+
311
+ // Convert publicKey to Buffer if necessary
312
+ const publicKeyBuffer = Buffer.isBuffer(publicKeyUint8Array)
313
+ ? publicKeyUint8Array
314
+ : Buffer.from(publicKeyUint8Array);
315
+
316
+ // Derive the Ethereum address
317
+ const addressBuffer = ethUtil.pubToAddress(publicKeyBuffer, true);
318
+ const address = '0x' + addressBuffer.toString('hex');
319
+
320
+ console.log('Ethereum address:', address);
321
+ return address;
322
+ } catch (error) {
323
+ console.error('Error extracting Ethereum address:', error);
324
+ throw error;
325
+ }
326
+ }
327
+
328
+ getServerEthereumAddress() {
329
+ try {
330
+ const serverCert = this.socket.getPeerCertificate(true);
331
+ if (!serverCert.raw) {
332
+ throw new Error('Failed to get server certificate.');
333
+ }
334
+
335
+ const publicKeyBuffer = Buffer.isBuffer(serverCert.pubkey)
336
+ ? serverCert.pubkey
337
+ : Buffer.from(serverCert.pubkey);
338
+
339
+ console.log('Public key Server:', publicKeyBuffer.toString('hex'));
340
+
341
+ const addressBuffer = ethUtil.pubToAddress(publicKeyBuffer, true);
342
+ const address = '0x' + addressBuffer.toString('hex');
343
+
344
+ console.log('Server Ethereum address:', address);
345
+ return address;
346
+ } catch (error) {
347
+ console.error('Error extracting server Ethereum address:', error);
348
+ throw error;
349
+ }
350
+ }
351
+
352
+ // getServerEthereumAddress() {
353
+ // try {
354
+ // const serverCert = this.socket.getPeerCertificate(true);
355
+ // if (!serverCert.raw) {
356
+ // throw new Error('Failed to get server certificate.');
357
+ // }
358
+
359
+ // // Extract public key from the certificate
360
+ // const publicKey = serverCert.pubkey; // May need to parse ASN.1 structure to get the public key
361
+ // // Assume you have a method to extract the public key buffer from the certificate
362
+
363
+ // // Compute Ethereum address from public key
364
+ // const publicKeyBuffer = Buffer.from(publicKey); // Ensure it's a Buffer
365
+ // const addressBuffer = ethUtil.pubToAddress(publicKeyBuffer, true);
366
+
367
+ // return addressBuffer; // Return as Buffer
368
+ // } catch (error) {
369
+ // console.error('Error extracting server Ethereum address:', error);
370
+ // throw error;
371
+ // }
372
+ // }
373
+
374
+ // Method to extract private key bytes from certPath
375
+ getPrivateKey() {
376
+ // Similar to getEthereumAddress(), but return privateKeyBytes
377
+ // Ensure to handle different key formats (EC PRIVATE KEY and PRIVATE KEY)
378
+ try {
379
+ const pem = fs.readFileSync(this.certPath, 'utf8');
380
+ let privateKeyPem;
381
+ let privateKeyDer;
382
+ let privateKeyBytes;
383
+
384
+ if (pem.includes('-----BEGIN PRIVATE KEY-----')) {
385
+ // Handle PKCS#8 format
386
+ privateKeyPem = pem
387
+ .replace('-----BEGIN PRIVATE KEY-----', '')
388
+ .replace('-----END PRIVATE KEY-----', '')
389
+ .replace(/\r?\n|\r/g, '');
390
+
391
+ privateKeyDer = Buffer.from(privateKeyPem, 'base64');
392
+
393
+ // Define ASN.1 structure for PKCS#8 private key
394
+ const PrivateKeyInfoASN = asn1.define('PrivateKeyInfo', function () {
395
+ this.seq().obj(
396
+ this.key('version').int(),
397
+ this.key('privateKeyAlgorithm').seq().obj(
398
+ this.key('algorithm').objid(),
399
+ this.key('parameters').optional()
400
+ ),
401
+ this.key('privateKey').octstr(),
402
+ this.key('attributes').implicit(0).any().optional(),
403
+ this.key('publicKey').implicit(1).bitstr().optional()
404
+ );
405
+ });
406
+
407
+ // Decode the DER-encoded private key
408
+ const privateKeyInfo = PrivateKeyInfoASN.decode(privateKeyDer, 'der');
409
+ const privateKeyOctetString = privateKeyInfo.privateKey;
410
+
411
+ // Now parse the ECPrivateKey structure inside the octet string
412
+ const ECPrivateKeyASN = asn1.define('ECPrivateKey', function () {
413
+ this.seq().obj(
414
+ this.key('version').int(),
415
+ this.key('privateKey').octstr(),
416
+ this.key('parameters').explicit(0).objid().optional(),
417
+ this.key('publicKey').explicit(1).bitstr().optional()
418
+ );
419
+ });
420
+
421
+ const ecPrivateKey = ECPrivateKeyASN.decode(privateKeyOctetString, 'der');
422
+ privateKeyBytes = ecPrivateKey.privateKey;
423
+ } else if (pem.includes('-----BEGIN EC PRIVATE KEY-----')) {
424
+ // Handle EC PRIVATE KEY format
425
+ privateKeyPem = pem
426
+ .replace('-----BEGIN EC PRIVATE KEY-----', '')
427
+ .replace('-----END EC PRIVATE KEY-----', '')
428
+ .replace(/\r?\n|\r/g, '');
429
+
430
+ privateKeyDer = Buffer.from(privateKeyPem, 'base64');
431
+
432
+ // Define ASN.1 structure for EC private key
433
+ const ECPrivateKeyASN = asn1.define('ECPrivateKey', function () {
434
+ this.seq().obj(
435
+ this.key('version').int(),
436
+ this.key('privateKey').octstr(),
437
+ this.key('parameters').explicit(0).objid().optional(),
438
+ this.key('publicKey').explicit(1).bitstr().optional()
439
+ );
440
+ });
441
+
442
+ // Decode the DER-encoded private key
443
+ const ecPrivateKey = ECPrivateKeyASN.decode(privateKeyDer, 'der');
444
+ privateKeyBytes = ecPrivateKey.privateKey;
445
+ } else {
446
+ throw new Error('Unsupported key format. Expected EC PRIVATE KEY or PRIVATE KEY in PEM format.');
447
+ }
448
+
449
+ return privateKeyBytes;
450
+ } catch (error) {
451
+ console.error('Error extracting Ethereum address:', error);
452
+ throw error;
453
+ }
454
+ }
455
+
456
+ async createTicketSignature(serverIdBuffer, totalConnections, totalBytes, localAddress, epoch) {
457
+ this.getEthereumAddress()
458
+ const chainId = 1284;
459
+ const fleetContractBuffer = ethUtil.toBuffer('0x6000000000000000000000000000000000000000'); // 20-byte Buffer
460
+
461
+ // Hash of localAddress (empty string)
462
+ const localAddressHash = crypto.createHash('sha256').update(Buffer.from(localAddress, 'utf8')).digest();
463
+
464
+ // Data to sign
465
+ const dataToSign = [
466
+ ethUtil.setLengthLeft(ethUtil.toBuffer(chainId), 32),
467
+ ethUtil.setLengthLeft(ethUtil.toBuffer(epoch), 32),
468
+ ethUtil.setLengthLeft(fleetContractBuffer, 32),
469
+ ethUtil.setLengthLeft(ethUtil.toBuffer(serverIdBuffer), 32),
470
+ ethUtil.setLengthLeft(ethUtil.toBuffer(totalConnections), 32),
471
+ ethUtil.setLengthLeft(ethUtil.toBuffer(totalBytes), 32),
472
+ ethUtil.setLengthLeft(localAddressHash, 32),
473
+ ];
474
+
475
+ // Convert each element in dataToSign to bytes32 and concatenate them
476
+ const encodedData = Buffer.concat(dataToSign.map(item => abi.rawEncode(['bytes32'], [item])));
477
+
478
+ console.log('Encoded data:', encodedData.toString('hex'));
479
+
480
+ console.log('Data to sign:', makeReadable(dataToSign));
481
+
482
+
483
+ // Sign the data
484
+ const privateKey = this.getPrivateKey();
485
+ const msgHash = ethUtil.keccak256(encodedData);
486
+ console.log('Message hash:', msgHash.toString('hex'));
487
+ const signature = secp256k1.ecdsaSign(msgHash, privateKey);
488
+ console.log('Signature:', signature);
489
+
490
+ const signatureBuffer = Buffer.concat([
491
+ ethUtil.toBuffer([signature.recid]),
492
+ signature.signature
493
+ ]);
494
+
495
+ return signatureBuffer;
496
+ }
497
+
498
+ async createTicketCommand() {
499
+ const chainId = 1284;
500
+ const fleetContract = ethUtil.toBuffer('0x6000000000000000000000000000000000000000')
501
+ const localAddress = 'test2'; // Always empty string
502
+
503
+ // Increment totalConnections
504
+ this.totalConnections += 1;
505
+ const totalConnections = this.totalConnections;
506
+
507
+ // Assume totalBytes is managed elsewhere
508
+ const totalBytes = this.totalBytes;
509
+
510
+ // Get server Ethereum address as Buffer
511
+ const serverIdBuffer = this.getServerEthereumAddress();
512
+
513
+ // Get epoch
514
+ const epoch = await this.RPC.getEpoch();
515
+ const signature = await this.createTicketSignature(
516
+ serverIdBuffer,
517
+ totalConnections,
518
+ totalBytes,
519
+ localAddress,
520
+ epoch
521
+ );
522
+ console.log('Signature hex:', signature.toString('hex'));
523
+
524
+
525
+ // Construct the ticket command
526
+ const ticketCommand = [
527
+ 'ticketv2',
528
+ chainId,
529
+ epoch,
530
+ fleetContract,
531
+ totalConnections,
532
+ totalBytes,
533
+ localAddress,
534
+ signature
535
+ ];
536
+
537
+ return ticketCommand;
538
+ }
539
+
540
+ _getNextRequestId() {
541
+ // Increment the request ID counter, wrap around if necessary
542
+ this.requestId = (this.requestId + 1) % Number.MAX_SAFE_INTEGER;
543
+ return this.requestId;
544
+ }
545
+
546
+ close() {
547
+ this.socket.end();
548
+ }
549
+ }
550
+
551
+
552
+ module.exports = DiodeConnection;
@@ -0,0 +1,29 @@
1
+ const { DiodeConnection, DiodeRPC } = require('../index');
2
+ const { makeReadable } = require('../utils');
3
+
4
+ async function main() {
5
+ const host = 'us2.prenet.diode.io';
6
+ const port = 41046;
7
+ const certPath = 'device_certificate.pem';
8
+
9
+ const connection = new DiodeConnection(host, port, certPath);
10
+ await connection.connect();
11
+ const rpc = connection.RPC;
12
+
13
+ try {
14
+ const address = connection.getEthereumAddress();
15
+ console.log('Address:', address);
16
+ const ping = await rpc.ping();
17
+ console.log('Ping:', ping);
18
+ const blockPeak = await rpc.getBlockPeak();
19
+ console.log('Current Block Peak:', blockPeak);
20
+ const blockHeader = await rpc.getBlockHeader(blockPeak);
21
+ console.log('Block Header:', makeReadable(blockHeader));
22
+ } catch (error) {
23
+ console.error('RPC Error:', error);
24
+ } finally {
25
+ connection.close();
26
+ }
27
+ }
28
+
29
+ main();
@@ -0,0 +1,16 @@
1
+ const { DiodeConnection, BindPort } = require('../index');
2
+
3
+ async function main() {
4
+ const host = 'us2.prenet.diode.io';
5
+ const port = 41046;
6
+ const certPath = 'device_certificate.pem';
7
+
8
+ const connection = new DiodeConnection(host, port, certPath);
9
+ await connection.connect();
10
+
11
+ const portForward = new BindPort(connection, 3002, 80, "5365baf29cb7ab58de588dfc448913cb609283e2");
12
+ portForward.bind();
13
+
14
+ }
15
+
16
+ main();
@@ -0,0 +1,19 @@
1
+ // example.js
2
+
3
+ const DiodeConnection = require('../connection')
4
+ const PublishPort = require('../publishPort')
5
+
6
+ async function startPublishing() {
7
+ const host = 'us2.prenet.diode.io';
8
+ const port = 41046;
9
+ const certPath = 'device_certificate.pem';
10
+
11
+ const connection = new DiodeConnection(host, port, certPath);
12
+ await connection.connect();
13
+
14
+ const publishedPorts = [8080]; // Ports you want to publish
15
+ const publishPort = new PublishPort(connection, publishedPorts, certPath);
16
+
17
+ }
18
+
19
+ startPublishing();
package/index.js ADDED
@@ -0,0 +1,7 @@
1
+ // index.js
2
+ const DiodeConnection = require('./connection');
3
+ const DiodeRPC = require('./rpc');
4
+ const BindPort = require('./bindPort');
5
+ const PublishPort = require('./publishPort');
6
+ const makeReadable = require('./utils').makeReadable;
7
+ module.exports = { DiodeConnection, DiodeRPC, BindPort , PublishPort, makeReadable };
package/package.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "diodejs",
3
+ "version": "0.0.3",
4
+ "description": "A JavaScript client for interacting with the Diode network. It provides functionalities to bind and publish ports, send RPC commands, and handle responses.",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "test": "echo \"Error: no test specified\" && exit 1"
8
+ },
9
+ "author": "",
10
+ "license": "ISC",
11
+ "dependencies": {
12
+ "@ethereumjs/rlp": "^5.0.2",
13
+ "asn1.js": "^5.4.1",
14
+ "axios": "^1.6.8",
15
+ "buffer": "^6.0.3",
16
+ "crypto": "^1.0.1",
17
+ "dgram": "^1.0.1",
18
+ "ethereumjs-abi": "^0.6.8",
19
+ "ethereumjs-util": "^7.1.5",
20
+ "ethers": "^6.13.2",
21
+ "fs": "^0.0.1-security",
22
+ "net": "^1.0.2",
23
+ "node-fetch": "^2.7.0",
24
+ "rlp": "^3.0.0",
25
+ "secp256k1": "^5.0.0",
26
+ "tls": "^0.0.1"
27
+ }
28
+ }