"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildReserveFilters = buildReserveFilters;
exports.listenToReserveChanges = listenToReserveChanges;
/**
 * Listen to real-time reserve changes via WebSocket.
 *
 * Subscribes to all reserve accounts for a given market using
 * programNotifications with dataSize + market memcmp filters.
 *
 * Returns raw Reserve (not KaminoReserve) because constructing a
 * KaminoReserve requires oracle price data and an RPC connection
 * that are not available from the WS notification alone. The consumer
 * should hydrate into KaminoReserve using their market context.
 */
const kit_1 = require("@solana/kit");
const accounts_1 = require("../@codegen/klend/accounts");
const programId_1 = require("../@codegen/klend/programId");
const utils_1 = require("./utils");
/** Anchor accounts are prefixed with an 8-byte discriminator */
const ANCHOR_DISCRIMINATOR_BYTES = 8;
const RESERVE_ACCOUNT_SIZE = BigInt(accounts_1.Reserve.layout.span + ANCHOR_DISCRIMINATOR_BYTES);
const RESERVE_DISCRIMINATOR_BASE58 = (0, kit_1.getBase58Decoder)().decode(accounts_1.Reserve.discriminator);
function buildReserveFilters(marketAddress) {
    return [
        { dataSize: RESERVE_ACCOUNT_SIZE },
        { memcmp: { offset: 32n, bytes: marketAddress.toString(), encoding: 'base58' } },
        // Match Reserve's 8-byte Anchor discriminator at offset 0 so uninitialized
        // klend-owned accounts with the same 8624-byte layout (e.g. pre-allocated
        // placeholders awaiting init_reserve) don't trigger spurious WS decode errors.
        { memcmp: { offset: 0n, bytes: RESERVE_DISCRIMINATOR_BASE58, encoding: 'base58' } },
    ];
}
/**
 * Subscribe to all reserve account changes for a given market.
 * Returns an unsubscribe function.
 */
function listenToReserveChanges(params) {
    const programId = params.programId ?? programId_1.PROGRAM_ID;
    const filters = buildReserveFilters(params.marketAddress);
    const options = {
        // Reserves update every slot (~400ms) — use 'confirmed' to reduce noise
        commitment: params.commitment ?? 'confirmed',
        throttleMs: params.throttleMs,
    };
    return params.manager.subscribeProgramAccounts(programId, filters, (addr, buffer, slot) => {
        try {
            // Returns raw Reserve (not KaminoReserve) — see file header for rationale
            const reserve = accounts_1.Reserve.decode((0, utils_1.toBuffer)(buffer));
            params.onChange({ reserve, address: addr, slot });
        }
        catch (e) {
            params.onError?.(e);
        }
    }, options);
}
//# sourceMappingURL=reserveListener.js.map