UNPKG

stellar-plus

Version:

beta version of stellar-plus, an all-in-one sdk for the Stellar blockchain

330 lines (329 loc) 14.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ClassicAssetHandler = void 0; const tslib_1 = require("tslib"); const stellar_sdk_1 = require("@stellar/stellar-sdk"); const types_1 = require("../../../stellar-plus/asset/types"); const classic_transaction_1 = require("../../../stellar-plus/core/pipelines/classic-transaction"); const horizon_1 = require("../../../stellar-plus/horizon"); const errors_1 = require("./errors"); class ClassicAssetHandler { /** * * @param {string} code - The asset code. * @param {string | AccountHandler} issuerAccount - The issuer account. When an account handler is provided, it'll enable management functions and be used to sign transactions as the issuer. * @param {NetworkConfig} networkConfig - The network configuration to use. * @param {ClassicTransactionPipelineOptions} options - The options for the classic transaction pipeline. @param {ClassicTransactionPipelineOptions} options.classicTransactionPipeline - The options for the classic transaction pipeline. These allow for custom configurations for how the transaction pipeline will operate for this asset. * * @description - The Classic asset handler is used for handling classic assets with user-based and management functionalities. * * */ constructor(args) { var _a; this.code = args.code; this.type = args.code === 'XLM' && !args.issuerAccount ? types_1.AssetTypes.native : args.code.length <= 4 ? types_1.AssetTypes.credit_alphanum4 : types_1.AssetTypes.credit_alphanum12; // provided Public key for issuer if (args.issuerAccount && typeof args.issuerAccount === 'string') { this.issuerPublicKey = args.issuerAccount; } // provided Account Handler for issuer if (args.issuerAccount && typeof args.issuerAccount !== 'string') { this.issuerAccount = args.issuerAccount; this.issuerPublicKey = args.issuerAccount.getPublicKey(); } this.horizonHandler = new horizon_1.HorizonHandlerClient(args.networkConfig); this.asset = new stellar_sdk_1.Asset(args.code, this.issuerPublicKey); this.classicTransactionPipeline = new classic_transaction_1.ClassicTransactionPipeline(args.networkConfig, (_a = args.options) === null || _a === void 0 ? void 0 : _a.classicTransactionPipeline); } //========================================== // User Methods - Do not require Admin / Issuer //========================================== // // /** * * @returns {string} The asset code. */ symbol() { return tslib_1.__awaiter(this, void 0, void 0, function* () { return this.code; }); } /** * * @returns {number} The asset decimals. * @description - Default for classic assets = 7. * @todo Improve to get the actual value from the asset issuer's toml file. */ decimals() { return tslib_1.__awaiter(this, void 0, void 0, function* () { return 7; }); } /** * * @returns {string} The asset code. * @todo Improve to get the actual name from the asset issuer's toml file. */ name() { return tslib_1.__awaiter(this, void 0, void 0, function* () { return this.code; }); } /** * @description - Not implemented in the current version for pure classic assets. Only available for Soroban assets. */ approve() { return tslib_1.__awaiter(this, void 0, void 0, function* () { throw new Error('Method not implemented.'); }); } /** * * @param {string} id - The account id to check the balance for. * @returns {Promise<number>} The balance of the asset for the given account. */ balance(id) { return tslib_1.__awaiter(this, void 0, void 0, function* () { const sourceAccount = (yield this.horizonHandler.loadAccount(id)); const balanceLine = sourceAccount.balances.filter((balanceLine) => { if (balanceLine.asset_type === this.type && balanceLine.asset_type === types_1.AssetTypes.native) { return true; } if (balanceLine.asset_type === types_1.AssetTypes.credit_alphanum12 || balanceLine.asset_type === types_1.AssetTypes.credit_alphanum4) { if (balanceLine.asset_code === this.code && balanceLine.asset_issuer === this.issuerPublicKey) return true; } return false; }); return balanceLine[0] ? Number(balanceLine[0].balance) : 0; }); } /** * * @param {string} from - The account id to transfer the asset from. * @param {string} to - The account id to transfer the asset to. * @param {i128} amount - The amount of the asset to transfer. * @param {TransactionInvocation} txInvocation - The transaction invocation object. Must include the 'From' account as a signer to authorize this transaction. * * @requires - The 'from' account to be set as a signer in the transaction invocation. * * @returns {Promise<void>} * * @description - Transfers the given amount of the asset from the 'from' account to the 'to' account. */ transfer(args) { return tslib_1.__awaiter(this, void 0, void 0, function* () { const { from, to, amount } = args; const txInvocation = args; const transferOp = stellar_sdk_1.Operation.payment({ destination: to, asset: this.asset, amount: amount.toString(), source: from, }); const result = yield this.classicTransactionPipeline.execute({ txInvocation, operations: [transferOp], options: Object.assign({}, args.options), }); return result; }); } /** * * @param {string} from - The account id to burn the asset from. * @param {number} amount - The amount of the asset to burn. * @param {TransactionInvocation} txInvocation - The transaction invocation object. Must include the 'From' account as a signer to authorize this transaction. * * @requires - The 'from' account to be set as a signer in the transaction invocation. * * @returns {Promise<void>} * * @description - Burns the given amount of the asset from the 'from' account. */ burn(args) { return tslib_1.__awaiter(this, void 0, void 0, function* () { if (this.type === types_1.AssetTypes.native) { throw "You can't burn XLM"; } if (!this.issuerPublicKey) { throw "Missing issuer public key. Can't burn asset."; } return this.transfer(Object.assign(Object.assign({}, args), { to: this.issuerPublicKey })); }); } //========================================== // Management Methods - Require Admin / Issuer account //========================================== // These methods make use of this.requireIssuerAccount() // to enforce the issuer account to be set. The issue account // is then injected as a signer in the transaction invocation // when needed. // // // /** * @args * @param {string} to - The account id to mint the asset to. * @param {i128} amount - The amount of the asset to mint. * @param {TransactionInvocation} txInvocation - The transaction invocation object spread. The Issuer account will be automatically added as a signer. * * @description - Mints the given amount of the asset to the 'to' account. * @requires - The issuer account to be set in the asset. * * @returns {HorizonNamespace.SubmitTransactionResponse} The response from the Horizon server. */ mint(args) { return tslib_1.__awaiter(this, void 0, void 0, function* () { this.requireIssuerAccount(); // Enforces the issuer account to be set. const { to, amount } = args; const txInvocation = args; const updatedTxInvocation = Object.assign(Object.assign({}, txInvocation), { signers: [...txInvocation.signers, this.issuerAccount] }); const mintOp = stellar_sdk_1.Operation.payment({ destination: to, asset: this.asset, amount: amount.toString(), source: this.asset.getIssuer(), }); const result = yield this.classicTransactionPipeline.execute({ txInvocation: updatedTxInvocation, operations: [mintOp], options: Object.assign({}, args.options), }); return result; }); } /** * * @param {ControlFlags} controlFlags - The control flags to set for the asset. * @param {TransactionInvocation} txInvocation - The transaction invocation object spread. The Issuer account will be automatically added as a signer. * * @requires - The issuer account to be set in the asset. * * @returns {ClassicTransactionPipelineOutput} The response from the Horizon server. */ setFlags(args) { return tslib_1.__awaiter(this, void 0, void 0, function* () { this.requireIssuerAccount(); // Enforces the issuer account to be set. const { controlFlags } = args; const txInvocation = args; const updatedTxInvocation = Object.assign(Object.assign({}, txInvocation), { signers: [...txInvocation.signers, this.issuerAccount] }); let flags = 0; if (controlFlags.authorizationRequired) flags |= stellar_sdk_1.AuthRequiredFlag; if (controlFlags.authorizationRevocable) flags |= stellar_sdk_1.AuthRevocableFlag; if (controlFlags.authorizationImmutable) flags |= stellar_sdk_1.AuthImmutableFlag; if (controlFlags.clawbackEnabled) flags |= stellar_sdk_1.AuthClawbackEnabledFlag; const setFlags = stellar_sdk_1.Operation.setOptions({ setFlags: flags, source: this.asset.getIssuer(), }); const result = yield this.classicTransactionPipeline.execute({ txInvocation: updatedTxInvocation, operations: [setFlags], options: Object.assign({}, args.options), }); return result; }); } clawback() { return tslib_1.__awaiter(this, void 0, void 0, function* () { throw new Error('Method not implemented.'); }); } //========================================== // Util Methods //========================================== // // /** * * @param {string} to - The account id to mint the asset to. * @param {number} amount - The amount of the asset to mint. * @param {TransactionInvocation} txInvocation - The transaction invocation object spread. The Issuer account will be automatically added as a signer. * * @requires - The issuer account to be set in the asset. * @requires - The 'to' account to be set as a signer in the transaction invocation. * * @description - Mints the given amount of the asset to the 'to' account. The trustline is also set in process. * * @returns {HorizonNamespace.SubmitTransactionResponse} The response from the Horizon server. */ addTrustlineAndMint(args) { return tslib_1.__awaiter(this, void 0, void 0, function* () { this.requireIssuerAccount(); // Enforces the issuer account to be set. const { to, amount } = args; const txInvocation = args; const updatedTxInvocation = Object.assign(Object.assign({}, txInvocation), { signers: [...txInvocation.signers, this.issuerAccount] }); const addTrustlineOp = stellar_sdk_1.Operation.changeTrust({ source: to, asset: this.asset, }); const mintOp = stellar_sdk_1.Operation.payment({ destination: to, asset: this.asset, amount: amount.toString(), source: this.asset.getIssuer(), }); const result = yield this.classicTransactionPipeline.execute({ txInvocation: updatedTxInvocation, operations: [addTrustlineOp, mintOp], options: Object.assign({}, args.options), }); return result; }); } /** * * @param {string} to - The account id to add the trustline. * @param {TransactionInvocation} txInvocation - The transaction invocation object spread. * * @requires - The 'to' account to be set as a signer in the transaction invocation. * * @description - Adds the trustline for the asset to the 'to' account. * * @returns {HorizonNamespace.SubmitTransactionResponse} The response from the Horizon server. */ addTrustline(args) { return tslib_1.__awaiter(this, void 0, void 0, function* () { const { to } = args; const txInvocation = args; const addTrustlineOp = stellar_sdk_1.Operation.changeTrust({ source: to, asset: this.asset, }); const result = yield this.classicTransactionPipeline.execute({ txInvocation, operations: [addTrustlineOp], options: Object.assign({}, args.options), }); return result; }); } //========================================== // Internal Methods //========================================== // /** * * @description - Enforces the issuer account to be set. */ requireIssuerAccount() { if (!this.issuerAccount) { throw errors_1.CAHError.issuerAccountNotDefined(); } } } exports.ClassicAssetHandler = ClassicAssetHandler;