Sending Request for Quotes (RFQs)

Aori builds products and tooling for supporting high-frequency gas-efficient DeFi execution.

One of the more common flows is the RFQ flow. This flow is quick and useful for communication efficiency amongst takers and makers.

Taker Flows for Sending RFQs

A taker may interact with the RFQ service in 2 ways: with a partial request or a full request.

Tutorial

Approving the Contract

You will need to approve the Aori contract first to spend each token in your wallet.

We will soon add in signature-based approvals in the future via Permit2.

Formatting a Request

A RFQ request is formatted in a certain way to allow for split functionalities: to request a quote only, or to request a quote and execute a trade.

In all cases, you need to know the token's address (inputToken), the destination token address (outputToken), and the amount that you want to sell (inputAmount).

There are two types of RFQs that you can send: a partial request or a full request.

Partial Request

{
    "address": <address>,
    "inputToken": <address>,
    "outputToken": <address>,
    "inputAmount": <uint256>,
    "zone": <address (optional)>,
    "chainId": <uint256>,
    "deadline": <uint256 (optional)> // Deadline in seconds
}

Full Request

{
    "order": "<Limit Order>", // See Limit Order section
    "signature": "<string>"
}

Sending the Request

To send a request, you can use the aori_rfq JSON-RPC method.

You would then send the following payload body as a POST request to https://api.aori.io.

Typical Request Format

{
    "id": "1",
    "jsonrpc": "2.0",
    "method": "aori_rfq",
    "params": [
        <Partial Request> | <Full Request>
    ]
}

Example: Sending a Partial Request

POST https://api.aori.io
{
    "id": "1",
    "jsonrpc": "2.0",
    "method": "aori_rfq",
    "params": [
        {
            "address": "0x1234567890123456789012345678901234567890",
            "inputToken": "0x0987654321098765432109876543210987654321",
            "outputToken": "0x0987654321098765432109876543210987654321",
            "inputAmount": "1000000000000000000",
            "chainId": 1,
        }
    ]
}

Example: Sending a Full Request

POST https://api.aori.io
{
    "id": "1",
    "jsonrpc": "2.0",
    "method": "aori_rfq",
    "params": [
        {
            "order": "<Limit Order>",
            "signature": "0x12345678901234567890123456789..."
        }
    ]
}

API Response

After the RFQ is sent, the registered trade details recorded within the system will be returned.

{
    "id": 1,
    "result": {
        "tradeId": "aori-7qn8l",
        "event": "QuoteRequested",
        "data": {
            "orderType": "rfq",
            "takerOrder": {
                "offerer": "0x123...",
                "inputToken": "0x123...",
                "outputToken": "0x123...",
                "inputAmount": "1000000000000000000",
                // <-- Notice the missing `outputAmount`
                "recipient": "0x123...",
                "zone": "0x123...",
                "chainId": 1,
                "startTime": 1714285714,
                "endTime": 1714285714,
                "toWihdraw": true
            },
        },
        "timestamp": 1714285714
    }
}

For a full request, if the outputAmount is met by a market maker or solver, they'll then go on to execute the trade, as given by the TradeMatched event that they'll be responsible for handling.

Listening to Events

To connect to the websocket feed that broadcasts these events related to your RFQ, you first connect via websocket at wss://api.aori.io.

Upon connection, you can use the aori_subscribe JSON-RPC method to subscribe to all events by passing in the returned tradeId. You can pass in "ALL" as the value for tradeId if you would like to subscribe to all events globally.

{
    "id": "1",
    "jsonrpc": "2.0",
    "method": "aori_subscribe",
    "params": []
}

A number of events will be emitted from the websocket feed related to your RFQ.

QuoteRequested Event

The QuoteRequested event is emitted when a quote is requested (an RFQ), either from you or another user. An example of the format can be found below:

{
    "tradeId": "aori-1234567890",
    "event": "QuoteRequested",
    "data": {
        "orderType": "rfq",
        "takerOrder": {
            "offerer": "0x123...",
            "inputToken": "0x123...",
            "outputToken": "0x123...",
            "inputAmount": "1000000000000000000",
            // <--- Note the missing "outputAmount" field
            "recipient": "0x123...",
            "zone": "0x123...",
            "chainId": 1,
            "startTime": 1714285714,
            "endTime": 1714285714,
            "toWihdraw": true
        }
    },
    "timestamp": 1714285714
}

OrderCancelled Event

{
    "tradeId": "aori-1234567890",
    "event": "OrderCancelled",
    "data": {
        "orderType": "rfq",
        "takerOrder": {
            "offerer": "0x123...",
            "inputToken": "0x123...",
            "outputToken": "0x123...",
            "inputAmount": "1000000000000000000",
            // <--- Note the missing "outputAmount" field
            "recipient": "0x123...",
            "zone": "0x123...",
            "chainId": 1,
            "startTime": 1714285714,
            "endTime": 1714285714,
            "toWihdraw": true
        }
    },
    "timestamp": 1714285714
}

QuoteReceived Event

The QuoteReceived event is emitted when a market maker or solver has provided a quote for your RFQ. An example of the format can be found below:

{
    "tradeId": "aori-1234567890",
    "event": "QuoteReceived",
    "data": {
        "orderType": "rfq",
        "takerOrder": {
            "offerer": "0x123...",
            "inputToken": "0x123...",
            "outputToken": "0x123...",
            "inputAmount": "1000000000000000000",
            // <--- Note the missing "outputAmount" field
            "recipient": "0x123...",
            "zone": "0x123...",
            "chainId": 1,
            "startTime": 1714285714,
            "endTime": 1714285714,
            "toWihdraw": true
        },
        "makerOrder": { ... } // <AoriOrder>, see the `Limit Orders` section for more details
    },
    "timestamp": 1714285714
}

TradeMatched Event

The TradeMatched event is emitted when a match has occurred between a taker and a maker. You can find the market maker's address that has won the RFQ within the event data.

{
    "tradeId": "aori-1234567890",
    "event": "TradeMatched",
    "data": {
        "orderType": "limit", // can be "limit" or "rfq",
        "makerOrder": { ... }, // <AoriOrder>
        "takerOrder": { ... }, // <AoriOrder>
        "matching": {
            // These matching details are necessary to execute the trade on-chain.
            // Normally, the executor can just use the `to`, `value`, and `data` fields
            // for this, but in the case of a hook, the executor may need to use these
            // fields to construct new calldata.
            "makerSignature": "0x123...",
            "takerSignature": "0x123...",
            "feeTag": "aori",
            "feeRecipient": "0x123...",
        },
        "matchingSignature": "0x123...",
        "chainId": 42161,
        "zone": "0x123...",
        "to": "0x123",
        "value": 1000000000000000000,
        "data": "0x123",
    },
    "timestamp": 1714285714
}

TradeSettled Event

The TradeSettled event is emitted when a trade / RFQ has been settled for a full request. An example of the format can be found below:

{
    "tradeId": "aori-1234567890",
    "event": "TradeSettled",
    "data": {
        "orderType": "limit", // can be "limit" or "rfq",
        "makerOrder": { ... }, // <AoriOrder>
        "takerOrder": { ... }, // <AoriOrder>
        "transactionHash": "0x123...",
    },
    "timestamp": 1714285714
}

TradeFailed Event

A TradeFailed event is emitted when a trade / RFQ has failed to be settled on-chain within a given time period.

{
    "tradeId": "aori-1234567890",
    "event": "TradeFailed",
    "data": {
        "orderType": "limit", // can be "limit" or "rfq",
        "makerOrder": { ... }, // <AoriOrder>
        "takerOrder": { ... }, // <AoriOrder>
    },
    "timestamp": 1714285714
}