The RFQ channel is where a user will either publish/streama RFQ. The user who is publishing a RFQ is the requester for a quote. They are considered the "taker" in the transaction request. The user who is streamingfor RFQ's is the provider of the quote. They are considered the "maker" of the quote.
It is important to note that the RFQ channel is not where RFQ quotes are actually generated or filled. It is only used to broadcast & listen to requests.
When an actual quote is generated by the quote provider, it can only be seen on the Quote channel. So if you intend to publish on the RFQ Channel, you will need to stream on the Quote Channel to see quotes that are returned to you.
The quote provider who is streaming on the RFQ Channel will respond to request by posting the quotes via rest api.
Responding to RFQ (RFQ Streamers Only)
If you are a streamer of RFQ's you will need to produce quote objects and post them via REST API. When doing so, the quotes must have the takerAddress populated with the requesters address. This is an optional param when posting quotes via REST API. If it is intentionally omitted when posting a quote, the order is considered PUBLIC and can be filled by anyone.
/*TypeScript Sample CodeNOTE: since this is an API, WS logic can be written in any language. This exampleis in typescript, but the overall sequence will be the same for any language.*/import { RawData, WebSocket } from'ws'// Example for for local container runtimeconsturl=`ws://localhost:${process.env.HTTP_PORT}`constwsConnection=newWebSocket(url)constMOCK_API_KEY='3423ee2bfd89491f82b351404'constauthMessage:AuthMessage= { type:'AUTH', apiKey:MOCK_API_KEY, body:null}// send AuthMessagewsConnection.send(JSON.stringify(authMsg))// IMPORTANT!!! published RFQ messages must be in web3 formatconstrfqRequest= { type:'RFQ', body: { poolKey: { base:'0x7F5bc2250ea57d8ca932898297b1FF9aE1a04999' quote: '0x53421DB1f41368E028A4239954feB5033C7B3729' oracleAdapter: string strike: parseEther('1700').toString() maturity: 1702022400 isCallPool: boolean }, side:'ask', chainId:'421613',// or '42161' for prod environment size:parseEther('1').toString(), taker:'0x3D1dcc44D65C08b39029cA8673D705D7e5c4cFF2' }}constwsCallback= (data:RawData) => {constmessage:InfoMessage|ErrorMessage|RFQMessage|PostQuoteMessage|FillQuoteMessage|DeleteQuoteMessage=JSON.parse(data.toString())switch (message.type) {case'INFO': {// auth result message will arrive herebreak } case'ERROR': {// any error message will arrive herebreak }default: {throw`Unexpected message type ${message.type}` }}// subscribe to WS messageswsConnection.on('message', wsCallback)// publish RFQMessage to start getting quotes streamed on QUOTES channelwsConnection.send(JSON.stringify(rfqRequest))// unsubscribe to WS messages// NOTE: unsubscribing does NOT close the ws connectionconstunsubscribeMsg:WSUnsubscribeMessage= { type:'UNSUBSCRIBE', channel: channel, body:null,}wsConnection.send(JSON.stringify(unsubscribeMsg))
/*TypeScript Sample CodeNOTE: since this is an API, WS logic can be written in any language. This exampleis in typescript, but the overall sequence will be the same for any language.*/import { RawData, WebSocket } from'ws'// Example for for local container runtimeconsturl=`ws://localhost:${process.env.HTTP_PORT}`constwsConnection=newWebSocket(url)constMOCK_API_KEY='3423ee2bfd89491f82b351404'constauthMessage:AuthMessage= { type:'AUTH', apiKey:MOCK_API_KEY, body:null}// send AuthMessagewsConnection.send(JSON.stringify(authMsg))constwebSocketFilter:FilterMessage= { type:'FILTER', channel:'RFQ', body: { chainId:'42161', taker:'0x170f9e3eb81ed29491a2efdcfa2edd34fdd24a71'// fake address }}constwsCallback= (data:RawData) => {constmessage:InfoMessage|ErrorMessage|RFQMessage|PostQuoteMessage|FillQuoteMessage|DeleteQuoteMessage=JSON.parse(data.toString())switch (message.type) {case'INFO': {// auth result message will arrive herebreak }case'RFQ': {// streamed requests will arrive here// business logic to POST quote via REST API HERE } case'ERROR': {// any error message will arrive herebreak }default: {throw`Unexpected message type ${message.type}` }}// subscribe to WS messageswsConnection.on('message', wsCallback)// send FilterMessage to start listening to RFQ streamwsConnection.send(JSON.stringify(webSocketFilter))
interfaceAuthMessage { type:'AUTH' apiKey:string body:null}// INFO message from Premia orderbookinterfaceInfoMessage { type:'INFO' body:null message:string}// ERROR message from Premia orderbookinterfaceErrorMessage { type:'ERROR' body:null message:string}// human-readable format of a RFQ requestinterfaceRFQMessage { type:'RFQ' body: { base:string// base token name i.e. WETH quote:string// base token name i.e. USDC expiration:string// i.e. 23NOV2023 strike:number type:'C'|'P' side:'bid'|'ask' size:number taker:string }}// Unsubscribe messageinterfaceWSUnsubscribeMessage { type:'UNSUBSCRIBE' channel:'QUOTES'|'RFQ' body:null}