exonum-client-cis
Version:
Light Client for Exonum CIS Blockchain
255 lines (215 loc) • 7.56 kB
JavaScript
"use strict";
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.chainIdToBytes = chainIdToBytes;
exports.isTransaction = isTransaction;
exports.Transaction = exports.Verified = 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 crypto = _interopRequireWildcard(require("../crypto"));
var _helpers = require("../helpers");
var protobuf = _interopRequireWildcard(require("../../proto/protocol.js"));
var _convert = require("./convert");
var _protobuf$exonum$cons = protobuf.exonum.consensus,
CoreMessage = _protobuf$exonum$cons.CoreMessage,
SignedMessage = _protobuf$exonum$cons.SignedMessage;
function chainIdToBytes(chainId) {
var bigChainId = global.BigInt(chainId);
var chainIdBytes = new Uint8Array(8);
for (var x = 0; x < 8; x++) {
chainIdBytes.set([Number(bigChainId >> global.BigInt(8) * global.BigInt(x) & global.BigInt(255))], x);
}
return chainIdBytes;
}
var Verified =
/*#__PURE__*/
function () {
function Verified(schema, chainId, payload, author, signature) {
(0, _classCallCheck2["default"])(this, Verified);
if (chainId.length === 8) {
this.chainIdBytes = chainId;
} else {
this.chainIdBytes = chainIdToBytes(chainId);
}
this.schema = schema;
this.payload = payload;
this.author = author;
this.signature = signature;
this.bytes = SignedMessage.encode({
chain_id_bytes: this.chainIdBytes,
payload: schema.encode(payload).finish(),
author: {
data: (0, _convert.hexadecimalToUint8Array)(author)
},
signature: {
data: (0, _convert.hexadecimalToUint8Array)(signature)
}
}).finish();
}
(0, _createClass2["default"])(Verified, [{
key: "serialize",
value: function serialize() {
return this.bytes;
}
/**
* Gets the SHA-256 digest of the message.
* @returns {string}
*/
}, {
key: "hash",
value: function hash() {
var payloadBuffer = this.schema.encode(this.payload).finish();
var chainIdBytesBuffer = this.chainIdBytes;
var authorBuffer = (0, _convert.hexadecimalToUint8Array)(this.author);
var buffer = Buffer.concat([chainIdBytesBuffer, payloadBuffer, authorBuffer]);
return crypto.hash(buffer);
}
}], [{
key: "sign",
value: function () {
var _sign = (0, _asyncToGenerator2["default"])(
/*#__PURE__*/
_regenerator["default"].mark(function _callee(schema, chainId, payload, _ref) {
var publicKey, secretKey, signingKey, chainIdBytes, payloadBuf, signature;
return _regenerator["default"].wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
publicKey = _ref.publicKey, secretKey = _ref.secretKey;
signingKey = secretKey;
chainIdBytes = chainIdToBytes(chainId);
payloadBuf = schema.encode(payload).finish();
_context.next = 6;
return crypto.sign(signingKey, Buffer.concat([chainIdBytes, payloadBuf]));
case 6:
signature = _context.sent;
return _context.abrupt("return", new this(schema, chainId, payload, publicKey, signature));
case 8:
case "end":
return _context.stop();
}
}
}, _callee, this);
}));
function sign(_x, _x2, _x3, _x4) {
return _sign.apply(this, arguments);
}
return sign;
}()
}, {
key: "deserialize",
value: function deserialize(schema, bytes) {
var _SignedMessage$decode = SignedMessage.decode(bytes),
payload = _SignedMessage$decode.payload,
rawAuthor = _SignedMessage$decode.author,
rawSignature = _SignedMessage$decode.signature,
chainIdBytes = _SignedMessage$decode.chain_id_bytes;
if (!crypto.verifySignature((0, _convert.uint8ArrayToHexadecimal)(rawSignature.data), (0, _convert.uint8ArrayToHexadecimal)(rawAuthor.data), payload)) {
return null;
} else {
var decoded = schema.decode(payload);
var author = (0, _convert.uint8ArrayToHexadecimal)(rawAuthor.data);
var signature = (0, _convert.uint8ArrayToHexadecimal)(rawSignature.data);
return new this(schema, chainIdBytes, decoded, author, signature);
}
}
}]);
return Verified;
}();
/**
* @constructor
* @param {Object} type
*/
exports.Verified = Verified;
var Transaction =
/*#__PURE__*/
function () {
function Transaction(_ref2) {
var schema = _ref2.schema,
serviceId = _ref2.serviceId,
methodId = _ref2.methodId,
chainId = _ref2.chainId;
(0, _classCallCheck2["default"])(this, Transaction);
this.serviceId = serviceId;
this.methodId = methodId;
this.schema = schema;
this.chainId = chainId || 0;
}
/**
* Creates a signature transaction.
*
* @param {bigint} chainId
* chain identifier
* @param {Object} payload
* transaction payload
* @param {Uint8Array | {publicKey: string, secretKey: string}} authorOrKeypair
* author or keypair
* @param {Uint8Array?} signature
* transaction signature
* @returns {Verified}
* signature transaction message
*/
(0, _createClass2["default"])(Transaction, [{
key: "create",
value: function create(payload, authorOrKeypair, signature) {
var fullPayload = this._serializePayload(payload);
if (signature === undefined) {
return Verified.sign(CoreMessage, this.chainId, fullPayload, authorOrKeypair);
} else {
return new Verified(CoreMessage, this.chainId, fullPayload, authorOrKeypair, signature);
}
}
}, {
key: "_serializePayload",
value: function _serializePayload(payload) {
var args = this.schema.encode((0, _helpers.cleanZeroValuedFields)(payload, {})).finish();
var transaction = {
call_info: {
instance_id: this.serviceId,
method_id: this.methodId
},
arguments: args
};
return {
any_tx: transaction
};
}
}, {
key: "serialize",
value: function serialize(payload) {
return CoreMessage.encode(this._serializePayload(payload)).finish();
}
}, {
key: "deserialize",
value: function deserialize(bytes) {
var verified = Verified.deserialize(CoreMessage, bytes);
if (!verified) {
return null;
}
var payload = verified.payload.any_tx;
if (!payload) {
return null;
}
if (payload.call_info.instance_id !== this.serviceId || payload.call_info.method_id !== this.methodId) {
return null;
}
verified.payload = this.schema.decode(payload.arguments);
return verified;
}
}]);
return Transaction;
}();
/**
* Check if passed object is of type Transaction
* @param type
* @returns {boolean}
*/
exports.Transaction = Transaction;
function isTransaction(type) {
return type instanceof Transaction;
}