quote:* WebSocket events (quote:accepted, quote:confirmed, quote:executed, quote:expired,
quote:rejected, quote:withdrawn) go to the market maker whose quote they concern, on their private
mm:quotes:{mm_id} channel. The bettor’s own authenticated connections also receive
quote:confirmed and quote:executed for their trade. rfq:* and position:* events go to rfq:{rfq_id}, the channel a
user or anyone tracking a specific trade subscribes to. vault:deposited and vault:withdrawn go to
the account’s own connections and are not in the table.The two families are not interchangeable. Some rows have a WebSocket event for the maker and none
for the user, or the reverse.One trade, across every channel
The acquisition gap
An early cashout resolves one of two ways. Only one of them notifies you live.A closing exit is well covered
position:bought_back carries rfq_id, position_pda, amount, mm_pays_user, tx_signature,
and quote_id. It fans out to four places at once:
The last two arrive on identity alone. If you also hold the
rfq:{rfq_id} subscription, you may
see the same event twice. Dedupe on tx_signature.
The position.bought_back webhook carries the same moment.
An acquiring bid notifies the buyer of nothing
Polling the RFQ status does not help either. A transfer leaves itexecuted, so polling for
bought_back never fires.

