UNPKG

stellar-plus

Version:

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

119 lines (118 loc) 4.69 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SorobanChannelAccountsPlugin = exports.BaseChannelAccountsPlugin = void 0; const tslib_1 = require("tslib"); const types_1 = require("../../../../../../stellar-plus/core/pipelines/soroban-transaction/types"); class BaseChannelAccountsPlugin { constructor(typeId, channels) { this.name = 'ChannelAccountsPlugin'; this.type = typeId; this.freeChannels = []; this.lockedChannels = []; if (channels) { this.registerChannels(channels); } } //=========================================== // belt process modifiers //=========================================== preProcess(item, meta) { return tslib_1.__awaiter(this, void 0, void 0, function* () { const allocatedChannel = yield this.allocateChannel(meta.itemId); const updatedItem = this.injectChannel(item, allocatedChannel); return updatedItem; }); } postProcess(item, meta) { return tslib_1.__awaiter(this, void 0, void 0, function* () { this.releaseChannel(meta.itemId); return item; }); } processError(error, meta) { return tslib_1.__awaiter(this, void 0, void 0, function* () { this.releaseChannel(meta.itemId); return error; }); } //=========================================== // public methods //=========================================== /** * * @description - Returns the list of channels registered to the pool. * * @returns {AccountHandler[]} The list of channels registered to the pool. */ getChannels() { const lockedChannels = this.lockedChannels.map((c) => c.channel); return [...this.freeChannels, ...lockedChannels]; } /** * * @param {AccountHandler[]} channels - The channel accounts to register. * * @description - Registers the provided channel accounts to the pool. * * @see ChannelAccountsHandler for a helper class for managing channel accounts. */ registerChannels(channels) { this.freeChannels = [...this.freeChannels, ...channels]; } //=========================================== // Internal methods //=========================================== allocateChannel(id) { return tslib_1.__awaiter(this, void 0, void 0, function* () { if (this.freeChannels.length === 0) { return yield this.noChannelPipeline(id); } else { const channel = this.freeChannels.pop(); this.lockedChannels.push({ id, channel, }); return channel; } }); } releaseChannel(id) { var _a; const channel = (_a = this.lockedChannels.find((c) => c.id === id)) === null || _a === void 0 ? void 0 : _a.channel; if (!channel) { throw new Error(`locked channel not found for item ${id}`); } this.lockedChannels = this.lockedChannels.filter((c) => c.id !== id); this.freeChannels.push(channel); } /** * * @description - Waits for a channel to be available and then allocates it. This step will wait for 1 second before trying again. * This function can be overriden to implement a custom waiting logic. * * @returns {Promise<AccountHandler>} The allocated channel account. */ noChannelPipeline(id) { return new Promise((resolve) => { setTimeout(() => { resolve(this.allocateChannel(id)); }, 1000); }); } injectChannel(item, channel) { var _a; const { header } = item.txInvocation; const itemSigners = (_a = item.txInvocation.signers) !== null && _a !== void 0 ? _a : []; // pure simulations may not carry signers const updatedTxInvocation = Object.assign(Object.assign(Object.assign({}, item.txInvocation), { header: Object.assign(Object.assign({}, header), { source: channel.getPublicKey() }) }), { signers: [...itemSigners, channel] }); const updatedItem = Object.assign(Object.assign({}, item), { txInvocation: updatedTxInvocation }); return updatedItem; } } exports.BaseChannelAccountsPlugin = BaseChannelAccountsPlugin; class SorobanChannelAccountsPlugin extends BaseChannelAccountsPlugin { constructor(args) { super(types_1.SorobanTransactionPipelineType.id, args.channels); } } exports.SorobanChannelAccountsPlugin = SorobanChannelAccountsPlugin;