UNPKG

madeline-ton

Version:

Pure JS client-side implementation of the Telegram TON blockchain protocol

204 lines (166 loc) 6.47 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _random = require("../crypto-sync/random"); var _constants = require("../TL/constants"); var _stream = _interopRequireDefault(require("../TL/stream")); var _tools = require("../tools"); var Websocket = /*#__PURE__*/ function () { function Websocket() { (0, _classCallCheck2["default"])(this, Websocket); } (0, _createClass2["default"])(Websocket, [{ key: "connect", /** * * @param {Context} ctx Connection context */ value: function () { var _connect = (0, _asyncToGenerator2["default"])( /*#__PURE__*/ _regenerator["default"].mark(function _callee2(ctx) { var _this = this; var random, byteView, reverse, key, keyRev, iv, ivRev; return _regenerator["default"].wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: this.crypto = ctx.getCrypto(); random = new Uint32Array(16); byteView = new Uint8Array(random.buffer); do { (0, _random.fastRandom)(random); } while (byteView[0] === 0xEF || _constants.obf2.includes(random[0]) || random[1] === 0); random[14] = 0xefefefef; reverse = new Uint32Array(byteView.slice().reverse().buffer); key = random.slice(2, 10); keyRev = reverse.slice(2, 10); iv = random.slice(10, 14); ivRev = reverse.slice(10, 14); _context2.next = 12; return this.crypto.getCtr(key, iv); case 12: this.encrypt = _context2.sent; _context2.next = 15; return this.crypto.getCtr(keyRev, ivRev); case 15: this.decrypt = _context2.sent; _context2.t0 = random; _context2.t1 = Uint32Array; _context2.next = 20; return this.encrypt.process(random); case 20: _context2.t2 = _context2.sent; _context2.t3 = new _context2.t1(_context2.t2).slice(14, 16); _context2.t0.set.call(_context2.t0, _context2.t3, 14); _context2.next = 25; return new Promise(function (resolve, reject) { _this.socket = new WebSocket(ctx.getUri('ws')); _this.socket.binaryType = "arraybuffer"; _this.socket.onmessage = /*#__PURE__*/ function () { var _ref = (0, _asyncToGenerator2["default"])( /*#__PURE__*/ _regenerator["default"].mark(function _callee(message) { var length; return _regenerator["default"].wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: _context.t0 = Uint8Array; _context.next = 3; return _this.decrypt.process(new Uint8Array(message.data)); case 3: _context.t1 = _context.sent; message = new _context.t0(_context.t1); length = message[0]; length = (length >= 0x7f ? message[1] | message[2] << 8 | message[3] << 16 : length) << 2; //console.log(message.length - 1, length) _this.onMessage(new _stream["default"](message.slice(-length).buffer)); case 8: case "end": return _context.stop(); } } }, _callee); })); return function (_x2) { return _ref.apply(this, arguments); }; }(); _this.socket.onopen = resolve; _this.socket.onerror = reject; _this.socket.onclose = _this.close.bind(_this); }); case 25: this.socket.onerror = function (e) { console.log("Websocket error: ", e); _this.close(); }; return _context2.abrupt("return", this.socket.send(random)); case 27: case "end": return _context2.stop(); } } }, _callee2, this); })); function connect(_x) { return _connect.apply(this, arguments); } return connect; }() }, { key: "write", value: function write(payload) { var _this2 = this; var length = payload.uBuf.length - 1; if (length >= 0x7f) { payload.pos = 0; payload.writeUnsignedInt(length << 8 & 0x7F); payload = payload.bBuf; } else { payload = payload.bBuf.slice(3); payload[0] = length; } return this.encrypt.process(payload).then(function (payload) { return _this2.socket.send(payload); }); } }, { key: "getBuffer", value: function getBuffer(length) { var s = new _stream["default"](new Uint32Array(6 + (length || 0))); s.pos += 6; s.initPos = 1; return s; } }, { key: "close", value: function close() { console.log("Closing socket!"); if (this.socket) { this.socket.close(); this.socket = undefined; this.onClose(); } } }, { key: "isHttp", value: function isHttp() { return false; } }]); return Websocket; }(); var _default = Websocket; exports["default"] = _default;