madeline-ton
Version:
Pure JS client-side implementation of the Telegram TON blockchain protocol
228 lines (184 loc) • 7.77 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _stream = _interopRequireDefault(require("./stream"));
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
/**
* Custom TL parser based on an unreleased project of mine (madeline.py).
* Could've based it on my MadelineProto, but madeline.py's parser is way cleaner.
*/
var Objects =
/*#__PURE__*/
function () {
/**
* Init TLObjects
* @param {Object} schemes JSON scheme object
*/
function Objects(schemes) {
(0, _classCallCheck2["default"])(this, Objects);
(0, _defineProperty2["default"])(this, "byId", {});
(0, _defineProperty2["default"])(this, "byPredicateAndLayer", {});
(0, _defineProperty2["default"])(this, "layers", []);
(0, _defineProperty2["default"])(this, "basicSizes", {
'string': 1,
'bytes': 1,
'int': 1,
'#': 1,
'long': 2,
'int128': 4,
'int256': 8,
'double': 2
});
console.log("Parsing TL schemes");
var data = [];
for (var _i = 0, _Object$entries = Object.entries(schemes); _i < _Object$entries.length; _i++) {
var _Object$entries$_i = (0, _slicedToArray2["default"])(_Object$entries[_i], 2),
layer = _Object$entries$_i[0],
scheme = _Object$entries$_i[1];
layer = parseInt(layer); // Parse constructors
for (var key in scheme['constructors']) {
var _constructor = scheme['constructors'][key];
if (typeof _constructor['layer'] === 'undefined') {
_constructor['layer'] = layer;
}
data.push(_constructor);
} // Parse functional constructors (still constructors, store in same array)
for (var _key in scheme['methods']) {
var method = scheme['methods'][_key];
if (typeof method['layer'] === 'undefined') {
method['layer'] = layer;
}
method['predicate'] = method['method'];
delete method['method'];
data.push(method);
}
}
for (var _i2 = 0, _data = data; _i2 < _data.length; _i2++) {
var _constructor2 = _data[_i2];
var minSize = _constructor2['type'] === 'Vector t' ? 1 : 0;
var newParams = {};
for (var _key2 in _constructor2['params']) {
var param = _constructor2['params'][_key2];
param['layer'] = _constructor2['layer'];
var match = param['type'].match(/^([\w_]+)\.(\d+)\?(.+)/);
if (match) {
param['flag'] = match[1];
param['pow'] = Math.pow(2, match[2]);
param['type'] = match[3];
}
if (param['layer'] === 1 && param['type'] === 'string') {
param['type'] = 'bytes';
}
if (param['type'] === '!X') {
param['type'] = 'bytes';
}
if (param['type'][0] === '%') {
param = _objectSpread({}, param, {}, this.findByType(param['type'].substring(1), _constructor2['layer']));
} else {
try {
param = _objectSpread({}, param, {}, this.findByPredicateAndLayer(param['type'], _constructor2['layer']));
} catch (e) {}
}
match = param['type'].match(/^(vector)<(.*)>$/i);
if (match) {
param['type'] = 'Vector t';
param['subtype'] = {
type: match[2],
layer: param['layer']
}; // If bare vector type
if (match[1] === 'vector') {
param = _objectSpread({}, param, {}, this.findByPredicateAndLayer(match[1], _constructor2['layer']));
}
if (param['subtype'][0] === '%') {
param = _objectSpread({}, param, {}, this.findByType(param['subtype'].substring(1), _constructor2['layer']));
} else {
try {
param['subtype'] = _objectSpread({}, param['subtype'], {}, this.findByPredicateAndLayer(param['subtype']['type'], _constructor2['layer']));
} catch (e) {}
}
}
if (this.basicSizes[param['type']] && !param['pow']) {
minSize += this.basicSizes[param['type']];
}
var name = param['name'];
delete param['name'];
newParams[name] = param;
}
_constructor2['params'] = newParams;
_constructor2['minSize'] = minSize;
this.byId[_constructor2['id']] = _constructor2;
this.byPredicateAndLayer[_constructor2['predicate'] + _constructor2['layer']] = _constructor2['id'];
if (!this.layers.includes(_constructor2['layer'])) {
this.layers.push(_constructor2['layer']);
}
}
this.layers.sort(function (a, b) {
return a < b;
});
}
(0, _createClass2["default"])(Objects, [{
key: "findById",
value: function findById(id) {
if (!this.byId[id]) {
throw Error("Could not find object by ID " + id);
}
return this.byId[id];
}
}, {
key: "findByPredicateAndLayer",
value: function findByPredicateAndLayer(predicate, layer) {
var id;
if (layer && (id = this.byPredicateAndLayer[predicate + layer])) {
return this.byId[id];
}
for (var k in this.layers) {
var myLayer = this.layers[k];
if (id = this.byPredicateAndLayer[predicate + myLayer]) {
return this.byId[id];
}
}
throw Error("Could not find object by predicate " + predicate + " and layer " + layer);
}
}, {
key: "findByType",
value: function findByType(type, layer) {
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = this.byId[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var object = _step.value;
object = this.byId[object];
if (object['type'] === type && object['layer'] === layer) {
return object;
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator["return"] != null) {
_iterator["return"]();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
throw Error('Could not find object by type ' + type);
}
}]);
return Objects;
}();
var _default = Objects;
exports["default"] = _default;