RFQ Channel

The RFQ channel is where a user will either publish/stream a 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 streaming for 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 Code
NOTE: since this is an API,  WS logic can be written in any language. This example
is in typescript, but the overall sequence will be the same for any language.
*/

import { RawData, WebSocket } from 'ws'

// Example for for local container runtime
const url = `ws://localhost:${process.env.HTTP_PORT}`
const wsConnection = new WebSocket(url)
const MOCK_API_KEY = '3423ee2bfd89491f82b351404'


const authMessage: AuthMessage = {
  type: 'AUTH',
  apiKey: MOCK_API_KEY,
  body: null
}

// send AuthMessage
wsConnection.send(JSON.stringify(authMsg))

// IMPORTANT!!! published RFQ messages must be in web3 format
const rfqRequest = {
  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'
  }
}

const wsCallback = (data: RawData) => {
  const message: InfoMessage | ErrorMessage | RFQMessage | PostQuoteMessage | FillQuoteMessage | DeleteQuoteMessage = JSON.parse(data.toString())
    switch (message.type) {
      case 'INFO': {
        // auth result message will arrive here
        break
      }  
      case 'ERROR': {
        // any error message will arrive here
        break
      }
      default: {
        throw `Unexpected message type ${message.type}`
      }
}

// subscribe to WS messages
wsConnection.on('message', wsCallback)

// publish RFQMessage to start getting quotes streamed on QUOTES channel
wsConnection.send(JSON.stringify(rfqRequest))


// unsubscribe to WS messages
// NOTE: unsubscribing does NOT close the ws connection
const unsubscribeMsg: WSUnsubscribeMessage = {
    type: 'UNSUBSCRIBE',
    channel: channel,
    body: null,
}

wsConnection.send(JSON.stringify(unsubscribeMsg))

Last updated

Terms and Disclaimers

Privacy Policy