import { hex } from '@scure/base'; import { getBitcoinNetwork, toXOnly } from '@saturnbtcio/psbt'; import { getScriptPubkeyFromAddress } from '../../util/address'; import { SaturnSdkConfig } from '../../saturn-sdk'; import { UtxoMetaData } from '@saturnbtcio/arch-sdk'; import { collectProtocolFeesMessage, IdentifiableLiquidityPool, } from '@saturnbtcio/pool-serde-sdk'; import { validatePoolSdkData } from '../../util/validation'; import { createProtocolPda } from '../../account/pda-finder'; export interface CollectProtocolFeesMessageRequest { runePublicKey: string; feePayerPubkey: string; poolId: string; withdrawAddressToken0: string; withdrawAddressToken1: string; recentBlockhash: string; feesUtxo?: UtxoMetaData; } export class CollectProtocolFees { constructor(private readonly config: SaturnSdkConfig) {} async collectProtocolFeesMessage(request: CollectProtocolFeesMessageRequest) { const scureNetwork = getBitcoinNetwork(this.config.network); validatePoolSdkData( request, scureNetwork, ); const pool: IdentifiableLiquidityPool | undefined = await this.config.indexerProvider.getPoolById(request.poolId); if (!pool) { throw new Error(`Pool ${request.poolId} not found`); } const withdraw_script_pubkey_token_0 = getScriptPubkeyFromAddress( request.withdrawAddressToken0, scureNetwork, ); const withdraw_script_pubkey_token_1 = getScriptPubkeyFromAddress( request.withdrawAddressToken1, scureNetwork, ); const [protocolPda, _bump] = createProtocolPda( hex.decode(this.config.programAccount), ); return collectProtocolFeesMessage( this.config.programAccount, hex.encode(toXOnly(hex.decode(request.runePublicKey))), hex.encode(toXOnly(hex.decode(request.feePayerPubkey))), this.config.mempoolInfoOracleAccount, this.config.feeRateOracleAccount, request.poolId, pool.shards.map((s: { pubkey: string }) => s.pubkey), { params: { withdraw_script_pubkey_token_0, withdraw_script_pubkey_token_1, fees_utxo: request.feesUtxo ?? null, }, }, request.recentBlockhash, hex.encode(protocolPda), ); } }