UNPKG

diamante-base

Version:

Low-level support library for the Diamante network.

247 lines (236 loc) 8.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.TransactionBase = void 0; var _xdr = _interopRequireDefault(require("./xdr")); var _hashing = require("./hashing"); var _keypair = require("./keypair"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; } function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); } function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } } function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } /** * @ignore */ var TransactionBase = exports.TransactionBase = /*#__PURE__*/function () { function TransactionBase(tx, signatures, fee, networkPassphrase) { _classCallCheck(this, TransactionBase); if (typeof networkPassphrase !== 'string') { throw new Error("Invalid passphrase provided to Transaction: expected a string but got a ".concat(_typeof(networkPassphrase))); } this._networkPassphrase = networkPassphrase; this._tx = tx; this._signatures = signatures; this._fee = fee; } /** * @type {Array.<xdr.DecoratedSignature>} * @readonly */ return _createClass(TransactionBase, [{ key: "signatures", get: function get() { return this._signatures; }, set: function set(value) { throw new Error('Transaction is immutable'); } }, { key: "tx", get: function get() { return this._tx; }, set: function set(value) { throw new Error('Transaction is immutable'); } /** * @type {string} * @readonly */ }, { key: "fee", get: function get() { return this._fee; }, set: function set(value) { throw new Error('Transaction is immutable'); } /** * @type {string} * @readonly */ }, { key: "networkPassphrase", get: function get() { return this._networkPassphrase; }, set: function set(networkPassphrase) { this._networkPassphrase = networkPassphrase; } /** * Signs the transaction with the given {@link Keypair}. * @param {...Keypair} keypairs Keypairs of signers * @returns {void} */ }, { key: "sign", value: function sign() { var _this = this; var txHash = this.hash(); for (var _len = arguments.length, keypairs = new Array(_len), _key = 0; _key < _len; _key++) { keypairs[_key] = arguments[_key]; } keypairs.forEach(function (kp) { var sig = kp.signDecorated(txHash); _this.signatures.push(sig); }); } /** * Signs a transaction with the given {@link Keypair}. Useful if someone sends * you a transaction XDR for you to sign and return (see * [addSignature](#addSignature) for more information). * * When you get a transaction XDR to sign.... * - Instantiate a `Transaction` object with the XDR * - Use {@link Keypair} to generate a keypair object for your Diamante seed. * - Run `getKeypairSignature` with that keypair * - Send back the signature along with your publicKey (not your secret seed!) * * Example: * ```javascript * // `transactionXDR` is a string from the person generating the transaction * const transaction = new Transaction(transactionXDR, networkPassphrase); * const keypair = Keypair.fromSecret(myStellarSeed); * return transaction.getKeypairSignature(keypair); * ``` * * @param {Keypair} keypair Keypair of signer * @returns {string} Signature string */ }, { key: "getKeypairSignature", value: function getKeypairSignature(keypair) { return keypair.sign(this.hash()).toString('base64'); } /** * Add a signature to the transaction. Useful when a party wants to pre-sign * a transaction but doesn't want to give access to their secret keys. * This will also verify whether the signature is valid. * * Here's how you would use this feature to solicit multiple signatures. * - Use `TransactionBuilder` to build a new transaction. * - Make sure to set a long enough timeout on that transaction to give your * signers enough time to sign! * - Once you build the transaction, use `transaction.toXDR()` to get the * base64-encoded XDR string. * - _Warning!_ Once you've built this transaction, don't submit any other * transactions onto your account! Doing so will invalidate this pre-compiled * transaction! * - Send this XDR string to your other parties. They can use the instructions * for [getKeypairSignature](#getKeypairSignature) to sign the transaction. * - They should send you back their `publicKey` and the `signature` string * from [getKeypairSignature](#getKeypairSignature), both of which you pass to * this function. * * @param {string} publicKey The public key of the signer * @param {string} signature The base64 value of the signature XDR * @returns {void} */ }, { key: "addSignature", value: function addSignature() { var publicKey = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; var signature = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; if (!signature || typeof signature !== 'string') { throw new Error('Invalid signature'); } if (!publicKey || typeof publicKey !== 'string') { throw new Error('Invalid publicKey'); } var keypair; var hint; var signatureBuffer = Buffer.from(signature, 'base64'); try { keypair = _keypair.Keypair.fromPublicKey(publicKey); hint = keypair.signatureHint(); } catch (e) { throw new Error('Invalid publicKey'); } if (!keypair.verify(this.hash(), signatureBuffer)) { throw new Error('Invalid signature'); } this.signatures.push(new _xdr["default"].DecoratedSignature({ hint: hint, signature: signatureBuffer })); } /** * Add a decorated signature directly to the transaction envelope. * * @param {xdr.DecoratedSignature} signature raw signature to add * @returns {void} * * @see Keypair.signDecorated * @see Keypair.signPayloadDecorated */ }, { key: "addDecoratedSignature", value: function addDecoratedSignature(signature) { this.signatures.push(signature); } /** * Add `hashX` signer preimage as signature. * @param {Buffer|String} preimage Preimage of hash used as signer * @returns {void} */ }, { key: "signHashX", value: function signHashX(preimage) { if (typeof preimage === 'string') { preimage = Buffer.from(preimage, 'hex'); } if (preimage.length > 64) { throw new Error('preimage cannnot be longer than 64 bytes'); } var signature = preimage; var hashX = (0, _hashing.hash)(preimage); var hint = hashX.slice(hashX.length - 4); this.signatures.push(new _xdr["default"].DecoratedSignature({ hint: hint, signature: signature })); } /** * Returns a hash for this transaction, suitable for signing. * @returns {Buffer} */ }, { key: "hash", value: function hash() { return (0, _hashing.hash)(this.signatureBase()); } }, { key: "signatureBase", value: function signatureBase() { throw new Error('Implement in subclass'); } }, { key: "toEnvelope", value: function toEnvelope() { throw new Error('Implement in subclass'); } /** * Get the transaction envelope as a base64-encoded string * @returns {string} XDR string */ }, { key: "toXDR", value: function toXDR() { return this.toEnvelope().toXDR().toString('base64'); } }]); }();