RFQ
AirSwap Request-for-Quote (RFQ) is used by market makers to provide orders with expirations. Takers will request an order periodically and have the option to fill it.
Protocol Features
  • Taker has the option to fill an order.
  • Taker is guaranteed the price until expiry.
Protocol Summary
RFQ is available over HTTP or WebSocket. In RFQ, servers are signers and clients are senders.
  1. 1.
    Client sends the server a JSON-RPC over HTTP request.
  2. 2.
    Server responds with a signed order.
  3. 3.
    Client may send the signed order to Ethereum for settlement.
For information on finding counter-parties, see Discovery.

Methods

initialize

To support RFQ via WebSocket, the server must call initialize upon connection by the client and indicate request-for-quote among its list of supported protocols.
1
initialize([
2
{
3
name: 'request-for-quote',
4
version: '1.0.0'
5
}, ...
6
})
Copied!

getSignerSideOrder

Given a senderAmount the server returns a signed order with a signerAmount. The client is selling to the server.
1
getSignerSideOrder(
2
senderAmount: string, // Amount the sender would transfer
3
signerToken: string, // Token the signer would transfer
4
senderToken: string, // Token the sender would transfer
5
senderWallet: string, // Wallet of the sender
6
swapContract: string, // Swap contract intended for use (Light)
7
proxyingFor: string, // Ultimate counterparty of the swap (Optional)
8
)
Copied!

getSenderSideOrder

Given a signerAmount the server returns a signed order with a senderAmount. The client is buying from the server.
1
getSenderSideOrder(
2
signerAmount: string, // Amount the signer would transfer
3
signerToken: string, // Token the signer would transfer
4
senderToken: string, // Token the sender would transfer
5
senderWallet: string, // Wallet of the sender
6
swapContract: string, // Swap contract intended for use (Light)
7
proxyingFor: string, // Ultimate counterparty of the swap (Optional)
8
)
Copied!

Server

A successful result containing a LightOrder has the following properties:
Property
Type
Description
nonce
uint256
Unique per signer and should be sequential.
expiry
uint256
Expiry in seconds since 1 January 1970.
signerWallet
address
Wallet that sets and signs terms.
signerToken
address
Token that the signer will transfer.
signerAmount
uint256
Amount that the signer will transfer.
senderToken
address
Token that the sender will transfer.
senderAmount
uint256
Amount that the sender will transfer.
v
uint8
v value of the ECDSA signature.
r
bytes32
r value of the ECDSA signature.
s
bytes32
s value of the ECDSA signature.

Example

1
HTTP/1.1 200 OK
2
Access-Control-Allow-Origin: *
3
Access-Control-Allow-Headers: *
4
Access-Control-Allow-Methods: POST, OPTIONS
5
Content-Length: ...
6
Content-Type: application/json
7
8
{
9
"jsonrpc": "2.0",
10
"id": 123,
11
"result": {
12
"nonce": "99",
13
"expiry": "1566941284",
14
"signerWallet": "0x73BCEb1Cd57C711feaC4224D062b0F6ff338501f",
15
"signerToken": "0xdac17f958d2ee523a2206206994597c13d831ec7",
16
"signerAmount": "100000000",
17
"senderToken": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
18
"senderAmount": "1000000000000000000",
19
"v": "28",
20
"r": "0x67e0723b0afd357d4f28523bf633dfee16e0eab2f3cbcf8ce1afd32a035d2764",
21
"s": "0x1b71e6e633b3334fc88faf4ec0ca1b7611883bc0de4df7024abec07af78b97c3"
22
}
23
}
Copied!

Protocol

For information on finding counterparties, see the Discovery protocol. With server URLs in hand, clients call getSignerSideOrder or getSenderSideOrder as JSON-RPC over HTTP requests.
1
POST / HTTP/1.1
2
Content-Length: ...
3
Content-Type: application/json
4
5
{
6
"jsonrpc": "2.0",
7
"id": 123,
8
"method": "getSignerSideOrder",
9
"params": {
10
"signerToken": "0xdac17f958d2ee523a2206206994597c13d831ec7",
11
"senderWallet": "0x1FF808E34E4DF60326a3fc4c2b0F80748A3D60c2",
12
"senderToken": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
13
"senderAmount": "1000000000000000000",
14
"swapContract": "0xc549a5c701cb6e6cbc091007a80c089c49595468"
15
}
16
}
Copied!
A response looks like the example above. Requests can be made using curl for testing.
1
curl -H 'Content-Type: application/json' \
2
-d '{"jsonrpc":"2.0","id":"123","method":"getSignerSideOrder","params":{"signerToken":"0xdac17f958d2ee523a2206206994597c13d831ec7","senderWallet":"0x1FF808E34E4DF60326a3fc4c2b0F80748A3D60c2","senderToken":"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2","senderAmount":"1000000000000000000","swapContract":"0xc549a5c701cb6e6cbc091007a80c089c49595468"}}' \
3
http://localhost:3000/
Copied!
After requesting an order, parameters are submitted as an Ethereum transaction to the swap function on the Light contract, which emits a Swap event on success.
1
function swap(
2
uint256 nonce,
3
uint256 expiry,
4
address signerWallet,
5
IERC20 signerToken,
6
uint256 signerAmount,
7
IERC20 senderToken,
8
uint256 senderAmount,
9
uint8 v,
10
bytes32 r,
11
bytes32 s
12
) external;
Copied!
1
event Swap(
2
uint256 indexed nonce,
3
uint256 timestamp,
4
address indexed signerWallet,
5
IERC20 signerToken,
6
uint256 signerAmount,
7
uint256 signerFee,
8
address indexed senderWallet,
9
IERC20 senderToken,
10
uint256 senderAmount
11
);
Copied!
The server may subscribe to a filter for a Swap event with the nonce they provided to the client.
Last modified 1mo ago