stellar-plus
Version:
beta version of stellar-plus, an all-in-one sdk for the Stellar blockchain
65 lines (64 loc) • 3.75 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.SorobanGetTransactionPipeline = void 0;
const tslib_1 = require("tslib");
const stellar_sdk_1 = require("@stellar/stellar-sdk");
const conveyor_belt_1 = require("../../../../stellar-plus/error/helpers/conveyor-belt");
const conveyor_belts_1 = require("../../../../stellar-plus/utils/pipeline/conveyor-belts");
const errors_1 = require("./errors");
const types_1 = require("./types");
class SorobanGetTransactionPipeline extends conveyor_belts_1.ConveyorBelt {
constructor({ plugins, options } = {}) {
super({
type: types_1.SorobanGetTransactionPipelineType.id,
plugins: plugins || [],
});
this.options = options || { defaultSecondsToWait: 30, useEnvelopeTimeout: true };
}
// Waits for the given transaction to be processed by the Soroban server.
// Soroban transactions are processed asynchronously, so this method will wait for the transaction to be processed.
// If the transaction is not processed within the given timeout, it will throw an error.
// If the transaction is processed, it will return the response from the Soroban server.
// If the transaction fails, it will throw an error.
process(item, itemId) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
const { sorobanSubmission, transactionEnvelope, rpcHandler } = item;
const { hash } = sorobanSubmission;
const secondsToWait = this.getSecondsToWait(transactionEnvelope);
const waitUntil = Date.now() + secondsToWait * 1000;
const initialWaitTime = 1000; //1 second
let currentWaitTime = initialWaitTime;
let updatedTransaction = yield rpcHandler.getTransaction(hash);
while (Date.now() < waitUntil && updatedTransaction.status === stellar_sdk_1.rpc.Api.GetTransactionStatus.NOT_FOUND) {
yield new Promise((resolve) => setTimeout(resolve, currentWaitTime));
updatedTransaction = yield rpcHandler.getTransaction(hash);
currentWaitTime *= 2; // Exponential backoff
}
if (updatedTransaction.status === stellar_sdk_1.rpc.Api.GetTransactionStatus.SUCCESS) {
return { response: updatedTransaction };
}
if (updatedTransaction.status === stellar_sdk_1.rpc.Api.GetTransactionStatus.FAILED) {
throw errors_1.SGTError.transactionFailed((0, conveyor_belt_1.extractConveyorBeltErrorMeta)(item, this.getMeta(itemId)), updatedTransaction);
}
throw errors_1.SGTError.transactionNotFound((0, conveyor_belt_1.extractConveyorBeltErrorMeta)(item, this.getMeta(itemId)), secondsToWait, hash);
});
}
getSecondsToWait(transactionEnvelope) {
let secondsToWait = this.options.defaultSecondsToWait;
if (this.options.useEnvelopeTimeout && transactionEnvelope) {
const txTimeout = transactionEnvelope.innerTransaction
? this.getTransactionTimeoutInSeconds(transactionEnvelope.innerTransaction)
: this.getTransactionTimeoutInSeconds(transactionEnvelope);
if (txTimeout > 0) {
secondsToWait = txTimeout;
}
}
return secondsToWait;
}
getTransactionTimeoutInSeconds(transactionEnvelope) {
var _a, _b;
const txTimeout = (_b = Number((_a = transactionEnvelope.timeBounds) === null || _a === void 0 ? void 0 : _a.maxTime)) !== null && _b !== void 0 ? _b : 0;
return txTimeout > 0 ? txTimeout - Math.floor(Date.now() / 1000) : 0;
}
}
exports.SorobanGetTransactionPipeline = SorobanGetTransactionPipeline;