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