Note: This guide uses the Circle sandbox environment to test StableFX. The
base URL is https://api-sandbox.circle.com/v1/exchange/stablefx. When you
are ready to launch in production, you should update the base URL to the
production URL.
This tutorial walks you through the steps to test your StableFX integration as a maker.
Before you begin, ensure that you have:
This guide provides API requests in cURL format, along with example responses.
Note: This guide uses the Circle sandbox environment to test StableFX. The
base URL is https://api-sandbox.circle.com/v1/exchange/stablefx. When you
are ready to launch in production, you should update the base URL to the
production URL.
Query for trades with the confirmed status using the
get all trades endpoint. The
following is an example request:
curl --request GET \
--url https://api-sandbox.circle.com/v1/exchange/stablefx/trades?type=maker&status=confirmed \
--header 'Accept: application/json' \
--header 'Authorization: Bearer ${YOUR_API_KEY}' \
Response
{
"data": [
{
"id": "c2558cd1-98b5-4ccd-90b8-96891512af20",
"contractTradeId": 42,
"status": "confirmed",
"rate": 0.915,
"from": {
"currency": "USDC",
"amount": "10"
},
"to": {
"currency": "EURC",
"amount": "9.15"
},
"createDate": "2023-01-01T12:04:05Z",
"updateDate": "2023-01-01T12:04:05Z",
"quoteId": "c4d1da72-111e-4d52-bdbf-2e74a2d803d5"
}
],
"pagination": {
"next": "",
"previous": ""
}
}
Decide which trades to take from the maker side, and register your signature for those trades.
Using the id field from the response in the previous step, get the typed data
for the trade using the
generate trade presign data
endpoint. The following is an example request:
curl --request GET \
--url https://api-sandbox.circle.com/v1/exchange/stablefx/signatures/presign/maker/c2558cd1-98b5-4ccd-90b8-96891512af20 \
--header 'Accept: application/json' \
--header 'Authorization: Bearer ${YOUR_API_KEY}'
Response
{
"consideration": {
"quoteId": "c4d1da72-111e-4d52-bdbf-2e74a2d803d5",
"base": "0x...",
"quote": "0x...",
"baseAmount": "10",
"quoteAmount": "9.15",
"maturity": 1752148800
},
"deadline": 1752149700,
"fee": "100000"
}
Using your wallet, sign the typed data returned from the previous step.
Submit the signed data to the submit a trade signature endpoint. The following is an example request for the signed data:
curl --request POST \
--url https://api-sandbox.circle.com/v1/exchange/stablefx/signatures \
--header 'Accept: application/json' \
--header 'Authorization: Bearer ${YOUR_API_KEY}' \
--header 'Content-Type: application/json' \
--data '
{
"tradeId": "c2558cd1-98b5-4ccd-90b8-96891512af20",
"type": "maker",
"address": "0xabc123...",
"details": {
"consideration": {
"quoteId": "c4d1da72-111e-4d52-bdbf-2e74a2d803d5",
"base": "0x...",
"quote": "0x...",
"baseAmount": "10",
"quoteAmount": "9.15",
"maturity": 1752148800
},
"deadline": 1752149700,
"fee": "100000"
},
"signature": "0xsignature"
}
'
Use the following steps to fund the trade onchain.
Before you send funds onchain, you should confirm that the trade is ready for
funding. To do this, call the
get all trades endpoint. You should
filter the response by the taker_funded status.
To use the StableFX API to deliver the funds onchain, you must first sign the funding typed data with an EIP-712 signature. To get the data to sign, call the generate funding presign data endpoint. Your request must include the contract ID of the trade and the side of the trade that you are taking. The following an example request:
curl --request POST \
--url https://api-sandbox.circle.com/v1/exchange/stablefx/signatures/funding/presign \
--header 'Accept: application/json' \
--header 'Authorization: Bearer ${YOUR_API_KEY}' \
--header 'Content-Type: application/json' \
--data '
{
"contractTradeIds": ["${stablefx_contract_trade_id}"],
"type": "maker"
}
'
Response
{
"typedData": {
"domain": {
"name": "Permit2",
"chainId": 11155111,
"verifyingContract": "0xffd21ca8F0876DaFAD7de09404E0c1f868bbf1AE"
},
"types": {
"EIP712Domain": [
{
"name": "name",
"type": "string"
},
{
"name": "chainId",
"type": "uint256"
},
{
"name": "verifyingContract",
"type": "address"
}
],
"TokenPermissions": [
{
"name": "token",
"type": "address"
},
{
"name": "amount",
"type": "uint256"
}
],
"SingleTradeWitness": [
{
"name": "id",
"type": "uint256"
}
],
"PermitWitnessTransferFrom": [
{
"name": "permitted",
"type": "TokenPermissions"
},
{
"name": "spender",
"type": "address"
},
{
"name": "nonce",
"type": "uint256"
},
{
"name": "deadline",
"type": "uint256"
},
{
"name": "witness",
"type": "SingleTradeWitness"
}
]
},
"primaryType": "PermitWitnessTransferFrom",
"message": {
"permitted": {
"token": "0xTOKEN",
"amount": "1000"
},
"spender": "0xffd21ca8F0876DaFAD7de09404E0c1f868bbf1AE",
"nonce": "42",
"deadline": "1735689600",
"witness": {
"id": "10"
}
}
}
}
The StableFX API can handle the onchain transaction for you through the fund trades endpoint. You must submit the maker-specific funding data along with your signature.
curl --request POST \
--url https://api-sandbox.circle.com/v1/exchange/stablefx/fund \
--header 'Accept: application/json' \
--header 'Authorization: Bearer ${YOUR_API_KEY}' \
--header 'Content-Type: application/json' \
--data '
{
"type": "maker",
"signature": "0xsignature",
"permit2": {
"permitted": {
"token": "0xTOKEN1",
"amount": "9.15"
},
"spender": "0xTOKEN1",
"nonce": "123456",
"deadline": 1752149700,
"witness": {
"id": "123456"
}
}
}
'
If the signed data is accepted, the API returns a blank 200 response.
Note: It's not required to submit the funding transaction through the StableFX API. You can submit the transaction onchain using your own web3 provider or wallet by calling the appropriate maker contract methods directly.
Note that the sandbox query for trades endpoint returns multiple trades. This
can be useful for testing a batch integration. If you are testing batching, you
need to get the contractTradeId for each trade that you'd like to fund. You
should complete part 2 for each trade that
you'd like to fund.
Once you have the array of IDs, and your signature is submitted for each trade, you can use the same fund trades endpoint to fund multiple trades by submitting the permit2 data for each trade along with the appropriate signatures.