require(`../../../_virtual/_rolldown/runtime.cjs`);const e=require(`../../../functions/utils/serialize.utils.cjs`),t=require(`../../../error-handling/logger.cjs`),n=require(`../../../functions/utils/resolve-sync.utils.cjs`),r=require(`../../BlockchainEvent/BlockchainEvent.cjs`);let i=require(`@coral-xyz/anchor`);var a=1e3,o=20,s=class{_chainId;connection;programId;_latestSlot;_initialSlot;onEventsProcessed;eventProcessors=new Set;maxPageSize;_isReady=!1;isServer;inProgress;anchorParser;anchorCoder;eventsFetchingMutex;constructor(e,t,n,r,i,a,o){this._chainId=e,this.connection=t,this.programId=n,this._initialSlot=r,this.maxPageSize=o,this.isServer=i,this.inProgress=!1,this.eventsFetchingMutex=a}get chainId(){return this._chainId}get latestBlockNumber(){return this._latestSlot??this._initialSlot}get isReady(){return this._isReady}setIdl(e){try{let t=new i.BorshCoder(e);this.anchorCoder=t,this.anchorParser=new i.EventParser(this.programId,t)}catch(e){t.Logger.error(`Failed to initialize Anchor EventParser:`,e),this.anchorParser=void 0,this.anchorCoder=void 0}}syncFromAtMost(e){(this._latestSlot===void 0||e<this._latestSlot)&&(this._latestSlot=e)}advanceLatestBlockNumber(e){e>(this._latestSlot??this._initialSlot)&&(this._latestSlot=e)}intervalClear(){this._isReady=!1,this.eventProcessors=new Set,this.clear()}async init(){if(this._isReady)throw Error(`Already initialized`);this._isReady=!0,await this.retrieveEvents(this.latestBlockNumber+1,!1,!0),this.startUpdateListener()}requireReady(){if(!this._isReady)throw Error(`Not ready`)}addEventProcessorFunction(e){if(this._isReady)throw Error(`Can't add event processor after event emitter initialized`);this.eventProcessors.add(e)}async getEventsInRange(e,t){return(await this.getProgramEvents(e,t)).map(e=>r.BlockchainEvent.fromSolanaEvent(e))}async getLastBlockNumberForEventRequest(){let e=await this.connection.getSlot();return this.isServer?Math.max(this.latestBlockNumber,e-32+1):e}async retrieveEvents(e,i=!1,a=!1){let o=e;return this.requireReady(),await this.eventsFetchingMutex.runExclusive(async()=>{try{if(this.inProgress&&!i)return!1;this.inProgress=!0;let e=await this.getLastBlockNumberForEventRequest();if(e<o)return this.inProgress=!1,!1;let t=n.getSequence(o,e,this.maxPageSize),s=[];await n.resolveSync(t.map(({from:e,to:t})=>async()=>{let n=await this.getProgramEvents(e,t,a);s.push(...n)})),s.sort((e,t)=>e.slot-t.slot);let c=s.map(e=>r.BlockchainEvent.fromSolanaEvent(e));return await this.processEvents(c,e),this._latestSlot=e,this.inProgress=!1,!0}catch(e){return t.Logger.error(`retrieveEvents error:`,e),this.inProgress=!1,!1}})}async getProgramEvents(e,n,r=!1){let i=[],s=r?a:o;try{let r=await this.connection.getSignaturesForAddress(this.programId,{limit:s,before:void 0}),a=r.length;for(;a>=s&&r[r.length-1].slot>=e;){let e=r[r.length-1],t=await this.connection.getSignaturesForAddress(this.programId,{limit:s,before:e.signature});if(t.length===0)break;r.push(...t),a=t.length}let o=r.filter(t=>t.slot>=e&&t.slot<=n).map(async e=>{try{let t=await this.connection.getTransaction(e.signature,{commitment:`confirmed`,maxSupportedTransactionVersion:0});return t&&t.meta&&!t.meta.err?this.parseTransactionForEvents(t,e.signature,e.slot,t.blockTime||null):[]}catch(n){return t.Logger.error(`Failed to get transaction ${e.signature}:`,n),[]}}),c=await Promise.all(o);i.push(...c.flat())}catch(e){t.Logger.error(`Error getting program events:`,e)}return i}parseTransactionForEvents(t,n,r,i){let a=this.parseLogsForEvents(t?.meta?.logMessages??[],n,r,i),o=this.parseCpiForEvents(t,n,r,i),s=[...a,...o];if(s.length===0)return[];let c=new Set;return s.filter(t=>{let n=`${t.signature}:${t.eventName}:${e.safeJsonStringify(t.data)}`;return c.has(n)?!1:(c.add(n),!0)})}parseLogsForEvents(e,n,r,i){if(!this.anchorParser)return[];try{return Array.from(this.anchorParser.parseLogs(e)).map(({name:e,data:t})=>({signature:n,slot:r,blockTime:i||0,programId:this.programId,data:t,eventName:e}))}catch(e){return t.Logger.error(`Anchor EventParser failed; falling back to generic parsing:`,e),[]}}parseCpiForEvents(e,n,r,a){if(!e||!this.anchorCoder)return[];let o=e.meta?.innerInstructions??[];if(o.length===0)return[];try{return o.flatMap(e=>e.instructions??[]).map(e=>{try{if(!e?.data)return null;let t=i.utils.bytes.bs58.decode(e.data);if(t.length<=8)return null;let o=i.utils.bytes.base64.encode(t.subarray(8)),s=this.anchorCoder?.events.decode(o);return s?{signature:n,slot:r,blockTime:a||0,programId:this.programId,data:s.data,eventName:s.name}:null}catch{return null}}).filter(e=>e!==null)}catch(e){return t.Logger.error(`Failed to parse emit_cpi events:`,e),[]}}async processEvents(e,t){let n=(await Promise.all([...this.eventProcessors].map(n=>n(e,t)))).reduce((e,t)=>e+t,0);this.onEventsProcessed?.(n)}};exports.SolanaBlockchainEventEmitter=s;