UNPKG

swapable

Version:
154 lines (153 loc) 6.36 kB
"use strict"; /** * This file is part of Swapable shared under AGPL-3.0 * Copyright (C) 2021 Using Blockchain Ltd, Reg No.: 12658136, United Kingdom * * @package Swapable * @author Grégory Saive for Using Blockchain Ltd <greg@ubc.digital> * @license AGPL-3.0 */ Object.defineProperty(exports, "__esModule", { value: true }); exports.Executable = void 0; const symbol_uri_scheme_1 = require("symbol-uri-scheme"); const symbol_sdk_1 = require("symbol-sdk"); // internal dependencies const index_1 = require("../../index"); const FailureEmptyContract_1 = require("../errors/FailureEmptyContract"); /** * @abstract * @class Swapable.Executable * @package Swapable * @subpackage Commands * @since v1.0.0 * @description Abstract class that describes a pool command * for assets compliant with the automated pool * standard as defined in this package. This is * the base layer for the execution of commands. */ class Executable extends index_1.BaseCommand { /** * Construct an executable command object around \a context * and an \a identifier of automated pool shares. * * @access public * @param {Context} context The execution context. * @param {AssetIdentifier} identifier The automated pool shares asset identifier. */ constructor( /** * @readonly * @access public * @description The execution context. */ context, /** * @readonly * @access public * @description The automated pool shares asset identifier. */ identifier) { super(context); this.context = context; this.identifier = identifier; /** * @access public * @description The list of **required** arguments to execute * an automated pool command. */ this.arguments = []; this.target = this.identifier.target; } // end-region abstract methods /** * Verifies **allowance** of \a actor to execute a command * with arguments \a argv. By default, this method returns * true *only* if the actor is the automated pool's target * account. * * This method asserts the presence of mandatory arguments. * * @access public * @param {PublicAccount} actor The actor is whom executes the command. * @param {Array<CommandOption>} argv The command options (arguments). * @return {AllowanceResult} Returns whether an actor is authorized to execute this command. * @throws {FailureMissingArgument} On missing mandatory argument(s). **/ canExecute(actor, argv) { // - Asserts the presence of mandatory inputs super.assertHasMandatoryArguments(argv, this.arguments); // - By default, only target can execute commands ("owner only") const isOperator = actor.address.equals(this.target.address); return new index_1.AllowanceResult(isOperator); } /** * Executes an automated pool command with \a actor given * \a argv command options. * * @access public * @param {PublicAccount} actor The actor is whom executes the command. * @param {Array<CommandOption>} argv The command options (arguments). * @return {TransactionURI<T>} Returns one transaction URI with all transactions. * @throws {FailureMissingArgument} On missing mandatory argument(s). * @throws {FailureOperationForbidden} On denial of authorization. **/ execute(actor, argv) { // - Verifies the authorization to execute super.assertExecutionAllowance(actor, argv); // - Creates a digital contract for this execution const contract = this.prepare(); // - Formats the result as a transaction URI return new symbol_uri_scheme_1.TransactionURI(contract.serialize(), symbol_sdk_1.TransactionMapping.createFromPayload); } /** * Wraps the resulting transactions inside an aggregate bonded * transaction. We will later refer to this transaction as the * **digital contract**. * * Prior to announcing this digital contract to a network, and * waiting for it to be included in a new block, you must also * announce a HashLockTransaction to allow the use of contracts. * * @link https://docs.symbolplatform.com/serialization/lock_hash.html#hash-lock-transaction * @link https://docs.symbolplatform.com/concepts/aggregate-transaction.html#id3 * * @access protected * @return {AggregateTransaction} Aggregate bonded transaction * @throws {FailureEmptyContract} Given a misconfigured digital contract which is empty. **/ prepare() { // - Sanity check if (!this.transactions.length) { throw new FailureEmptyContract_1.FailureEmptyContract('No transactions result from the execution of this contract.'); } // - Shortcut for network information const reader = this.context.reader; // - Creates a so-called digital contract return symbol_sdk_1.AggregateTransaction.createBonded(this.context.parameters.deadline, this.transactions, reader.networkType, [], // "unsigned" this.context.parameters.maxFee); } /** * Returns the available **reserve** of asset \a r. This method * is used internally to determine the available balance in the * automated pool and calculate the liquidity shares ratio. * * @access protected * @param {AssetIdentifier} r The asset identifier (i.e. for which to check reserves). * @return number The total balance (reserve) available. */ reserveOf(r) { var _a; // - Step out if we don't have the info if (this.reserveInfo === undefined) { return 0; //XXX FailureEmptyReserve } // - Reads reserve mosaic balance const reserve = (_a = this.reserveInfo) === null || _a === void 0 ? void 0 : _a.mosaics.filter((m) => m.id.id.equals(r.toMosaicId().id)); // - Step out if we don't have the info if (!reserve.length) { return 0; //XXX FailureEmptyReserve } return reserve[0].amount.compact(); } } exports.Executable = Executable;