delegate-framework
Version:
A TypeScript framework for building robust, production-ready blockchain workflows with comprehensive error handling, logging, and testing. Maintained by delegate.fun
101 lines • 4.27 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.SplClient = void 0;
const error_handling_1 = require("../../utils/error-handling");
class SplClient {
constructor(config) {
this.requestId = 0;
this.config = {
timeout: SplClient.DEFAULT_TIMEOUT,
retries: SplClient.DEFAULT_RETRIES,
...config,
};
this.connection = this.config.connection;
this.logger = this.config.logger;
}
/**
* Get priority fee based on recent network activity
* @param options - Optional configuration for fee calculation
* @param options.percentile - Percentile to use for fee calculation (0-1, default: 0.9999999)
* @param options.defaultCuPrice - Default fee when no data is available (default: 0.1)
* @returns Priority fee in microLamports per compute unit
*/
async getPriorityFee(options = {}) {
const { percentile = SplClient.DEFAULT_PERCENTILE, defaultCuPrice = SplClient.DEFAULT_CU_PRICE, } = options;
return this.makeRequest(async () => {
const recentFees = await this.connection.getRecentPrioritizationFees();
if (recentFees.length === 0) {
this.logger?.warn('No recent prioritization fees found, using default');
return defaultCuPrice;
}
const sortedFees = recentFees
.map((f) => f.prioritizationFee)
.sort((a, b) => b - a);
const topPercentileIndex = Math.floor(sortedFees.length * (1 - percentile));
const calculatedFee = sortedFees[topPercentileIndex] || defaultCuPrice;
const finalFee = Math.max(calculatedFee, defaultCuPrice);
this.logger?.debug('Priority fee calculation', {
recentFeesCount: recentFees.length,
percentile,
calculatedFee,
finalFee,
});
return finalFee;
}, 'getPriorityFee');
}
/**
* Make a request with retry logic and error handling
* @param operation - The operation to perform
* @param operationName - Name of the operation for logging
* @returns Result of the operation
*/
async makeRequest(operation, operationName) {
const requestId = ++this.requestId;
this.logger?.debug(`Request ${requestId} started: ${operationName}`);
let lastError;
for (let attempt = 1; attempt <= this.config.retries; attempt++) {
try {
const result = await Promise.race([
operation(),
new Promise((_, reject) => {
setTimeout(() => {
reject(new Error(`Operation timed out after ${this.config.timeout}ms`));
}, this.config.timeout);
}),
]);
this.logger?.debug(`Request ${requestId} completed: ${operationName}`, { result });
return result;
}
catch (error) {
lastError = error instanceof Error ? error : new Error(String(error));
this.logger?.warn(`Request ${requestId} attempt ${attempt} failed: ${operationName}`, lastError);
if (attempt === this.config.retries) {
this.logger?.error(`Request ${requestId} failed after ${attempt} attempts: ${operationName}`, lastError);
(0, error_handling_1.throwError)(lastError, `SPL Client Request Failed (${operationName})`);
}
await this.delay(Math.pow(2, attempt - 1) * 1000);
}
}
throw lastError;
}
/**
* Utility method for delays
* @param ms - Milliseconds to delay
*/
delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
/**
* Get the current configuration
* @returns Current client configuration
*/
getConfig() {
return this.config;
}
}
exports.SplClient = SplClient;
SplClient.DEFAULT_TIMEOUT = 30000;
SplClient.DEFAULT_RETRIES = 3;
SplClient.DEFAULT_PERCENTILE = 0.9999999; // 99.99999th percentile
SplClient.DEFAULT_CU_PRICE = 0.1;
//# sourceMappingURL=spl.js.map