# RFQ Channel

The RFQ channel is where a user will either *<mark style="color:green;">publish/stream</mark>* a RFQ.  The user who is *<mark style="color:green;">publishing</mark>* a RFQ is the requester for a quote.  They are considered the "taker" in the transaction request.  The user who is *<mark style="color:green;">streaming</mark>* for RFQ's is the provider of the quote. They are considered the "maker" of the quote.&#x20;

{% hint style="success" %}
&#x20;It is important to note that the RFQ channel is <mark style="color:red;">not</mark> 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 *<mark style="color:green;">publish</mark>* on the RFQ Channel, you will need to *<mark style="color:green;">stream</mark>* on the [Quote Channel](/developer-center/apis/containerized-api/websockets-reference/quotes-channel.md) to see quotes that are returned to you.\
\
The quote provider who is *<mark style="color:green;">streaming</mark>* on the RFQ Channel will respond to request by [posting](/developer-center/apis/containerized-api/api-reference/orderbook/quotes.md#orderbook-quotes-1) the quotes via rest api.&#x20;
{% endhint %}

### <mark style="color:blue;">Responding to RFQ (RFQ Streamers Only)</mark>

If you are a *<mark style="color:green;">streamer</mark>* 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. &#x20;

{% tabs %}
{% tab title="Publish RFQ " %}

```javascript
/*
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))
```

{% endtab %}

{% tab title="Stream RFQ" %}

```typescript
/*
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))


const webSocketFilter: FilterMessage = {
  type: 'FILTER',
  channel: 'RFQ',
  body: {
    chainId: '42161',
    taker: '0x170f9e3eb81ed29491a2efdcfa2edd34fdd24a71' // fake address
  }
}

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 'RFQ': {
        // streamed requests will arrive here
        // business logic to POST quote via REST API HERE
      }  
      case 'ERROR': {
        // any error message will arrive here
        break
      }
      default: {
        throw `Unexpected message type ${message.type}`
      }
}

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

// send FilterMessage to start listening to RFQ stream
wsConnection.send(JSON.stringify(webSocketFilter))
```

{% endtab %}

{% tab title="Interface" %}

```typescript
interface AuthMessage {
  type: 'AUTH'
  apiKey: string
  body: null
}

// INFO message from Premia orderbook
interface InfoMessage {
  type: 'INFO'
  body: null
  message: string
}

// ERROR message from Premia orderbook
interface ErrorMessage {
  type: 'ERROR'
  body: null
  message: string
}

// human-readable format of a RFQ request
interface RFQMessage {
  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 message
interface WSUnsubscribeMessage {
    type: 'UNSUBSCRIBE'
    channel: 'QUOTES' | 'RFQ'
    body: null
}
```

{% endtab %}
{% endtabs %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.premia.blue/developer-center/apis/containerized-api/websockets-reference/rfq-channel.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
