stellar-plus
Version:
beta version of stellar-plus, an all-in-one sdk for the Stellar blockchain
330 lines (329 loc) • 14.3 kB
JavaScript
"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;