@drift-labs/sdk
Version: 
SDK for Drift Protocol
93 lines (92 loc) • 5.24 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.TransactionParamProcessor = void 0;
const COMPUTE_UNIT_BUFFER_FACTOR = 1.2;
const MAX_COMPUTE_UNITS = 1400000;
const TEST_SIMS_ALWAYS_FAIL = false;
/**
 * This class is responsible for running through a "processing" pipeline for a base transaction, to adjust the standard transaction parameters based on a given configuration.
 */
class TransactionParamProcessor {
    static async getComputeUnitsFromSim(txSim) {
        var _a, _b;
        if ((_a = txSim === null || txSim === void 0 ? void 0 : txSim.value) === null || _a === void 0 ? void 0 : _a.unitsConsumed) {
            return (_b = txSim === null || txSim === void 0 ? void 0 : txSim.value) === null || _b === void 0 ? void 0 : _b.unitsConsumed;
        }
        return undefined;
    }
    static async getTxSimComputeUnits(tx, connection, bufferMultiplier, // Making this a mandatory param to force the user to remember that simulated CU's can be inaccurate and a buffer should be applied
    lowerBoundCu, simulatedTx) {
        var _a, _b;
        try {
            if (TEST_SIMS_ALWAYS_FAIL)
                throw new Error('Test Error::SIMS_ALWAYS_FAIL');
            const simTxResult = simulatedTx
                ? {
                    value: simulatedTx,
                }
                : await connection.simulateTransaction(tx, {
                    replaceRecentBlockhash: true, // This is important to ensure that the blockhash is not too new.. Otherwise we will very often receive a "blockHashNotFound" error
                });
            if ((_a = simTxResult === null || simTxResult === void 0 ? void 0 : simTxResult.value) === null || _a === void 0 ? void 0 : _a.err) {
                throw (_b = simTxResult === null || simTxResult === void 0 ? void 0 : simTxResult.value) === null || _b === void 0 ? void 0 : _b.err;
            }
            const computeUnits = await this.getComputeUnitsFromSim(simTxResult);
            // Apply the buffer, but round down to the MAX_COMPUTE_UNITS, and round up to the nearest whole number
            let bufferedComputeUnits = Math.ceil(Math.min(computeUnits * bufferMultiplier, MAX_COMPUTE_UNITS));
            // If a lower bound CU is passed then enforce it
            if (lowerBoundCu) {
                bufferedComputeUnits = Math.max(bufferedComputeUnits, Math.min(lowerBoundCu, MAX_COMPUTE_UNITS));
            }
            return {
                success: true,
                computeUnits: bufferedComputeUnits,
            };
        }
        catch (e) {
            console.warn(`Failed to get Simulated Compute Units for txParamProcessor`, e);
            return {
                success: false,
                computeUnits: undefined,
            };
        }
    }
    static async process(props) {
        var _a;
        // # Exit early if no process config is provided
        if (!props.processConfig || Object.keys(props.processConfig).length === 0) {
            return props.baseTxParams;
        }
        // # Setup
        const { txBuilder: txBuilder, processConfig, processParams: processProps, } = props;
        const finalTxParams = {
            ...props.baseTxParams,
        };
        // # Run Processes
        if (processConfig.useSimulatedComputeUnits) {
            const txToSim = await txBuilder({
                txParams: { ...finalTxParams, computeUnits: MAX_COMPUTE_UNITS },
            });
            const txSimComputeUnitsResult = await this.getTxSimComputeUnits(txToSim, processProps.connection, (_a = processConfig === null || processConfig === void 0 ? void 0 : processConfig.computeUnitsBufferMultiplier) !== null && _a !== void 0 ? _a : COMPUTE_UNIT_BUFFER_FACTOR, undefined, processProps.simulatedTx);
            if (txSimComputeUnitsResult.success) {
                // Adjust the transaction based on the simulated compute units
                finalTxParams.computeUnits = txSimComputeUnitsResult.computeUnits;
            }
        }
        if (processConfig === null || processConfig === void 0 ? void 0 : processConfig.useSimulatedComputeUnitsForCUPriceCalculation) {
            if (!(processConfig === null || processConfig === void 0 ? void 0 : processConfig.useSimulatedComputeUnits)) {
                throw new Error(`encountered useSimulatedComputeUnitsForFees=true, but useSimulatedComputeUnits is false`);
            }
            if (!(processConfig === null || processConfig === void 0 ? void 0 : processConfig.getCUPriceFromComputeUnits)) {
                throw new Error(`encountered useSimulatedComputeUnitsForFees=true, but getComputeUnitPriceFromUnitsToUse helper method is undefined`);
            }
            const simulatedComputeUnits = finalTxParams.computeUnits;
            const computeUnitPrice = processConfig.getCUPriceFromComputeUnits(simulatedComputeUnits);
            console.debug(`🔧:: Adjusting compute unit price for simulated compute unit budget :: ${finalTxParams.computeUnitsPrice}=>${computeUnitPrice}`);
            finalTxParams.computeUnitsPrice = computeUnitPrice;
        }
        // # Return Final Tx Params
        return finalTxParams;
    }
}
exports.TransactionParamProcessor = TransactionParamProcessor;