Basic Market Making API

This page explains how market makers can interact with the Liquorice RFQ WebSocket API using their own inventory

1. Getting started

Connecting to maker API

  • Production: wss://api.liquorice.tech/v1/maker/ws

Include the following headers with the WebSocket request

  • maker - name of the Market Maker

  • authorization - authorization token

  • index (optional) - index of the connected client (between 0 and 9). Allows multiple connections with the same credentials.

The WebSocket server sends Ping message every 30 seconds.

2. Managing token approvals

Standard approvals

Token approval must be granted solely to the Liquorice Balance Manager smart contract address. Giving standard approval is the most gas efficient way to trade. Important note: providing approval to any other Liquorice address outside of Balance Manager may compromise the security of your funds, as it does not guarantee the same level of protection. Approvals should be given strictly to the Balance Manager address.

Permit2

Liquorice integrates with the Uniswap Permit2 contract.

To use Permit2, first grant standard token approval to address: 0x000000000022d473030f116ddee9f6b43ac78ba3

3. Receiving RFQ

When a trader or intent system requests a quote, Liquorice forwards the request to market makers using the following format:

  • The RFQ will include either baseTokenAmount or quoteTokenAmount, but not both.

    • When baseTokenAmount is specified, the trader (order initiator) is requesting the amount of quoteToken they would receive in exchange for a specific amount of baseToken.

    • When quoteTokenAmount is specified, the trader (order initiator) is requesting the amount of baseToken they need to provide to receive a specific amount of quoteToken.

  • intentMetadata - For the moment, only CoW Protocol is supported. If this parameter is absent, it means that the quote is requested for another intent system.

4. Providing Quote

Send the quote response through the same WebSocket connection using the following format:

Market makers can provide multiple quote levels with different amounts, but the quoted amounts must not exceed those specified in the RFQ.

Example For an RFQ where:

  • baseToken = ETH

  • quoteToken = USDT

  • baseTokenAmount = 1 ETH

The resulting quote may contain these levels:

Level 0: Exchange 1 ETH for 3,000 USDT

Level 1: Exchange 0.5 ETH for 1,502 USDT

Level 2: Exchange 0.1 ETH for 310 USDT

Quote level Lite

Use this type of quote level for simple and gas-efficient swaps.

Note: supports only Standard approvals

Signature schema

The following Solidity code demonstrates how to create an EIP-712 signature by hashing RFQ and quote level data.

To implement this in your preferred programming language, port the code below and populate values from the corresponding RFQ and quote level objects.

Sign the resulting hash with the signer's private key.

Check yourself

Use the following example to verify your hashing implementation. The RFQ and quote level payloads below should produce this hash:

0x2342c2e81befd9dda11c9e769d6d867e347d5b84a0137bf9fa31acbe7ee4f5ac

Quote level Extended

Use this quote level type for customizations that require hooks and interactions.

It supports both Standard and Permit2 approvals.

Signature schema

The following Solidity code demonstrates how to create an EIP-712 signature by hashing RFQ and quote level data.

To implement this in your preferred programming language, port the code below and populate values from the corresponding RFQ and quote level objects.

Sign the resulting hash with the signer's private key.

Check yourself

Use the following example to verify your hashing implementation. The RFQ and quote level payloads below should produce this hash:

0x7fedd067fe195b613ac92786b82aa93b076513c59da93becb052b54a36ccf41b

Using lending pools

Liquorice allows market makers to settle trades using borrowed funds, provided they have posted collateral equal to at least 25% of the quoted amount.

Consider the following example: a market maker receives an RFQ where a trader intends to exchange WETH for USDC. If the market maker does not have USDC in their inventory, they can borrow it from the lending pool—assuming they have supplied collateral (in any token) worth at least 25% of the quoted USDC amount.

For instance, if the quote is to exchange 0.3 WETH for 1,000 USDC, the market maker can post 250 USDT as collateral and borrow 1,000 USDC from the pool.

When the trade is settled, the 0.3 WETH will be added to the locked collateral alongside the market maker’s initially supplied 250 USDT. As a result, the market maker’s position in the pool will consist of 0.3 WETH and 250 USDT as locked collateral, with 1,000 USDC as outstanding debt.

To settle a trade using borrowed funds, the market maker must use the Extended Quote level and specify token amounts in the toSupply field of baseTokenData and the toBorrow field of quoteTokenData.

  • baseTokenData.toSupply: the amount (e.g., 0.3 WETH) that the trader will supply and which will be added to the locked collateral on behalf of the market maker.

  • quoteTokenData.toBorrow: the amount (e.g., 1,000 USDC) to be borrowed on behalf of the market maker and sent to the trader.

The system will automatically generate the transaction payload and forward it to the origin of the intent.

To withdraw the 0.3 WETH collateral, the market maker must first repay a sufficient portion of the 1,000 USDC debt.

Error handling

If the quote payload is not valid, WS API will send a message in the following format

5. Getting quote summary

Use the following endpoint to retrieve an extended information for the provided quote. Quote summary includes information such as originating solver RFQ and resulting solver quote with the competing quote levels from other market makers, and settlement result if the resulting solver quote was used to settle the trade on-chain.

URL: https://api.liquorice.tech/v1/maker/quote-summaries/{rfq-id}

Method: GET

Response
  • makerQuote.status can be one of live, settled, expired or missedDeadline

  • field settlementResult shows data on on final settlement which can be used, for example, to compare price provided by you with the winning price. If this field is "null", it normally means that settlement did not occur

  • field competing levels shows prices provided by other liquidity sources connected to Liquorice

6. Getting info on settled trades

When a trade executes on-chain, the Liquorice settlement contract emits a TraderOrder event containing information about transferred amounts. The event reflects actual token transfers, including cases of partial fills, and always shows the final amounts transferred on-chain.

Last updated