UNPKG

sui-direct

Version:

Decentralized version control system on SUI blockchain

244 lines (243 loc) 9.4 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); /* Communication with Node */ const path_1 = require("path"); const fs_1 = require("fs"); const to_string_1 = require("uint8arrays/to-string"); const from_string_1 = require("uint8arrays/from-string"); const json_1 = __importDefault(require("../utils/json")); const colors_1 = require("../utils/colors"); const helpers_1 = require("../utils/helpers"); async function imports() { const [{ createLibp2p }, { tcp }, // { ping }, // { kadDHT }, { identify }, { noise }, { yamux }, { multiaddr }, { createFromJSON, createEd25519PeerId }, { privateKeyFromProtobuf },] = await (0, helpers_1.initDynamicImports)([ "libp2p", "@libp2p/tcp", // "@libp2p/ping", // "@libp2p/kad-dht", "@libp2p/identify", "@chainsafe/libp2p-noise", "@chainsafe/libp2p-yamux", "@multiformats/multiaddr", "@libp2p/peer-id-factory", "@libp2p/crypto/keys", ]); return { createLibp2p, tcp, // ping, // kadDHT, identify, noise, yamux, multiaddr, createFromJSON, createEd25519PeerId, privateKeyFromProtobuf, }; } class P2P { constructor() { this.nodePeerID = ""; this.peerID = null; this.peerPrivKey = null; this.libp2p = null; this.connection = null; // Protocols this.HANDSHAKE_PROTOCOL = "/handshake/1.0.0"; this.NONCE_PROTOCOL = "/nonce/1.0.0"; this.SIGNATURE_PROTOCOL = "/signature/1.0.0"; this.VALIDATE_PROTOCOL = "/validate/1.0.0"; this.PUSH_PROTOCOL = "/push/1.0.0"; this.PULL_PROTOCOL = "/pull/1.0.0"; this.RENAME_PROTOCOL = "/rename/1.0.0"; this.config = json_1.default.getConfig(); } async sink(stream, data) { await stream.sink((async function* () { yield (0, from_string_1.fromString)(data); })()); } async parseChunk(stream) { let data = ""; for await (const chunk of stream.source) { data += (0, to_string_1.toString)(chunk.subarray()); } try { return JSON.parse(data); } catch (e) { return data; } } async generatePeerID() { if (this.peerID) return; const config = json_1.default.getConfig(); const { createFromJSON, privateKeyFromProtobuf, createEd25519PeerId } = await imports(); if (config === null || config === void 0 ? void 0 : config.peerID) { this.peerID = await createFromJSON(config.peerID); this.peerPrivKey = await privateKeyFromProtobuf(Buffer.from(config.peerID.privKey, "base64")); } else { this.peerID = (await createEd25519PeerId()); this.peerPrivKey = await privateKeyFromProtobuf(this.peerID.privateKey); json_1.default.setConfig({ ...config, peerID: { id: this.peerID.toString(), privKey: Buffer.from(this.peerID.privateKey).toString("base64"), pubKey: Buffer.from(this.peerID.publicKey).toString("base64"), }, }); } } async getNodePeerID() { var _a; const req = await fetch(`${this.config.nodehttp}/peer-id`); this.nodePeerID = (_a = (await req.json())) === null || _a === void 0 ? void 0 : _a.id; if (!this.nodePeerID) return null; return this.nodePeerID; } async init() { if (this.libp2p && this.connection) return { peerID: this.peerID.toString(), nodePeerID: this.nodePeerID, connection: this.connection, }; return new Promise(async (resolve, reject) => { const { createLibp2p, tcp, identify, noise, yamux, multiaddr } = await imports(); await this.generatePeerID(); const nodePeerID = this.nodePeerID || (await this.getNodePeerID()); if (!nodePeerID) { console.log(colors_1.colorize.errorIcon("Node is offline or not reachable.")); return reject(); } this.libp2p = (await createLibp2p({ privateKey: this.peerPrivKey, addresses: { listen: [], }, transports: [tcp()], connectionEncrypters: [noise()], streamMuxers: [yamux()], services: { identify: identify(), }, })); await this.libp2p.start(); // Node address const ip = this.config.node.split("//")[1].split(":")[0]; const port = this.config.node.split("//")[1].split(":")[1]; const remoteAddr = multiaddr(`/ip4/${ip}/tcp/${port}/p2p/${nodePeerID}`); this.connection = await this.libp2p.dial(remoteAddr); // Handshake const stream = await this.connection.newStream(this.HANDSHAKE_PROTOCOL); await this.sink(stream, JSON.stringify({ peerID: this.peerID.toString() })); // Listen for incoming messages const response = await this.parseChunk(stream); if ((response === null || response === void 0 ? void 0 : response.status) !== "ok") { console.error(colors_1.colorize.errorIcon("Failed to connect to node.")); return reject(); } return resolve({ peerID: this.peerID.toString(), nodePeerID: this.nodePeerID, connection: this.connection, }); }); } // Helper method to receive streamed content async receiveStreamedContent(stream) { const chunks = []; let totalSize = 0; for await (const chunk of stream.source) { console.log(totalSize); let buffer; // Handle different chunk types if (chunk.constructor.name === "Uint8ArrayList") { if (chunk.bufs && chunk.bufs.length > 0) { buffer = Buffer.concat(chunk.bufs); } else { buffer = Buffer.from(chunk.slice()); } } else if (chunk instanceof Buffer) { buffer = chunk; } else if (chunk instanceof Uint8Array) { buffer = Buffer.from(chunk); } else { buffer = Buffer.from(chunk); } totalSize += buffer.length; chunks.push(buffer); } return Buffer.concat(chunks); } // Helper method to process cloned content async processClonedContent(id, zipBuffer) { const [{ writeFileSync }, { extractZipToFolder }] = await Promise.all([ Promise.resolve().then(() => __importStar(require("fs"))).then(fs => ({ writeFileSync: fs.writeFileSync })), Promise.resolve().then(() => __importStar(require("../utils/zip"))).then(zipModule => ({ extractZipToFolder: zipModule.extractZipToFolder, })), ]); // Create temporary zip file const tempZipPath = (0, path_1.join)(process.cwd(), `${id}-temp.zip`); writeFileSync(tempZipPath, zipBuffer); // Extract to target directory const extractPath = (0, path_1.join)(process.cwd(), id); await extractZipToFolder(tempZipPath, extractPath); try { (0, fs_1.rmSync)(tempZipPath, { force: true }); } catch (e) { console.log(colors_1.colorize.warning("Failed to clean up temporary zip file")); console.error(e); } } } exports.default = P2P;