Skip to main content

Polygon

DFlow supports token swaps and indicative quotes on Polygon.

Supported token pairs and order sizes

To access best-execution market maker liquidity, you must create order flow auctions (OFAs) for each token pair you want to support. Additionally, your OFAs for a token pair must cover all order sizes that you want to support for that token pair. See Create Auction to learn how to create an auction.

If you choose to use an alternative liquidity source (e.g. AMM or aggregator) for certain token pairs or order sizes, you may set up a backup liquidity provider (LP) without creating an auction. Refer to Backup Liquidity Provider (LP).

Token Swaps

Step 1: Request an Endorsement

First, request an endorsement from your endorsement server.

// Use your endorsement server's URL
const endorsementServerURL = "https://endorsements.dflow.net";
const walletAddress = "0x838A9B9992052AB55b5239c74d41671d03A5c31A";
const endorsementURL = endorsementServerURL + "?retailTrader=" + walletAddress;
const endorsement = await(await fetch(endorsementURL)).json();

Step 2: Request a Firm Quote

Once your request is endorsed, you can request a firm quote. A firm quote includes a Polygon transaction that contains the instructions needed to perform the token swap.

import {
FirmQuoteResponseCode,
getFirmQuote,
} from "@dflow-protocol/signatory-client-lib/evm";

const signatoryServerURL = "https://signatory-1.dflow.net";
const walletAddress = "0x838A9B9992052AB55b5239c74d41671d03A5c31A";
const firmQuote = await getFirmQuote(signatoryServerURL, {
chainId: 137,
sendToken: "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174",
receiveToken: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
sendQty: "5",
orderFlowSource: "dflow1ejsafz9xy3ymkp6fmw8t299ag0wfl7drydj68n",
endorsement: endorsement,
retailTrader: walletAddress,
});
if (firmQuote.code !== FirmQuoteResponseCode.Ok) {
// Quote request failed.
}

This is the response:

{
"code": 0, // A successful firm quote fetched from the market maker
"tx": {
"chainId": 137,
"from": "0x838A9B9992052AB55b5239c74d41671d03A5c31A",
"to": "0x...",
"data": "0x...",
"value": "...",
},
"minGasLimit": "500000",
"allowanceTarget": "0x...",
"lastValidBlockTimestamp": 1682214813,
"lastAllowedBlockTimestamp": 1682214803,
"receiveQty": "4923819115647293875", // 4.923819115647293875 MATIC
"requestId": {...},
}

Firm Quote Request Fields

FieldTypeDescription
chainIdnumberThe chain ID of the EVM chain.
sendTokenstringThe address of the ERC-20 token sent by the retail trader. For native MATIC, this is 0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee.
receiveTokenstringThe address of the ERC-20 token received by the retail trader. For native MATIC, this is 0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee.
sendQtystringThe quantity of sendToken that the retail trader will send.
orderFlowSourcestringThe order flow source's DFlow address. This is the address on the DFlow Chain of the wallet that you use to create your auctions.
endorsementobject(Optional) The endorsement received from the endorsement server. Only required if the request is routed via an auction.
retailTraderstringAddress of the retail trader's Polygon wallet.

Firm Quote Response Fields

The response for a successful request contains the following fields:

FieldTypeDescription
codenumberThe status code for the quote request. The available response codes are 0, 1, and 2. 0 indicates a successful request for market maker quote. 1 indicates a successful request for backup liquidity quote when the quote request is routed via an auction. For both 0 and 1, you must send the transaction using the DFlow sendTransaction endpoint. 2 indicates a successful request for backup liquidity when the quote request is not routed via an auction. In this case, the transaction must be sent directly to Polygon.
txobjectThe transaction. The client is responsible for populating the transaction's nonce and gas parameters. The client must not modify the specified transaction parameters.
minGasLimitstringMinimum allowed gas limit for the transaction. If the client specifies a lower gas limit, the transaction will be rejected.
allowanceTargetstringThe contract address for which the retail trader needs to have an allowance for the send token for the transaction to be processed.
lastValidBlockTimestampnumberThe last Polygon block timestamp at which the transaction can be processed.
lastAllowedBlockTimestampstringThe last Polygon block timestamp at which the swap transaction may be sent to the DFlow node. If the transaction is sent to the DFlow node after this Polygon block timestamp, the DFlow node rejects the transaction, and you must request another quote.
receiveQtystringThe quantity of receiveToken that the retail trader will receive. Note that the receiveQty is specified with the fixed number of decimals used for the receive mint. For example, if the receiveToken is USDC, which has 6 decimals, and the receiveQty is 1500000, then the retail trader will receive 1.5 USDC.
requestIdobjectRequest information used by the DFlow node when processing a sendTransaction request.

Step 3: Send the Swap Transaction

Now that you have a swap transaction, you can sign it and then execute it by sending it via the DFlow network. Firm quote requests with a response code of 0 or 1 must do this step. If you fetched a firm quote from a backup LP without routing via an auction (response code 3), you can send the transaction directly to Polygon.

import {
sendTransaction,
SendTransactionResponseCode,
} from "@dflow-protocol/signatory-client-lib/evm";
import { ethers } from "ethers";

const signatoryServerURL = "https://signatory-1.dflow.net";
const [nonce, feeData] = await Promise.all([
ethers.provider.getTransactionCount(walletAddress),
ethers.provider.getFeeData(),
]);
const signedTx = await wallet.signTransaction({
...firmQuote.tx,
nonce,
gasLimit: firmQuote.minGasLimit,
maxFeePerGas: feeData.maxFeePerGas,
});
const result = await sendTransaction(signatoryServerURL, {
tx: signedTx,
lastAllowedBlockTimestamp: firmQuote.lastAllowedBlockTimestamp,
endorsement: endorsement,
requestId: firmQuote.requestId,
});
if (result.code !== SendTransactionResponseCode.Sent) {
// Transaction wasn't sent. Request another quote and retry.
}

This is the response:

{
"code": 0,
"txHash": "0x..."
}

Send Transaction Request Fields

FieldTypeDescription
txstringThe hex-encoded transaction, signed by the retail trader.
lastAllowedBlockTimestampnumber(Optional) Taken from the firmQuote response. Only specified if the firm quote response included a lastAllowedBlockTimestamp.
endorsementobjectThe endorsement received from the endorsement server.
requestIdobjectTaken from the firmQuote response.

Send Transaction Response Fields

If the transaction was sent to Polygon, the response will contain the following fields:

FieldTypeDescription
codenumber0 if transaction was sent to the network and 1 if transaction was not sent to the network.
txHashstringPolygon transaction hash. You can use this to check for transaction confirmation using the Polygon JSON RPC API.

Indicative Quotes

An indicative quote contains pricing information from the market maker, but unlike a firm quote, it cannot be used to swap tokens at a set price. You should use indicative quotes to show pricing information when you don't have a wallet connected or don't intend to send an order.

Step 1: Request an Endorsement

First, request an endorsement from your endorsement server. Note that if your application allows your users to see indicative prices before connecting their wallets, your endorsements for indicative quotes can be generic and omit the retailTrader.

// Use your endorsement server's URL
const endorsementServerURL = "https://endorsements.dflow.net";
const walletAddress = "0x838A9B9992052AB55b5239c74d41671d03A5c31A";
const endorsementURL = endorsementServerURL + "?retailTrader=" + walletAddress;
const endorsement = await(await fetch(endorsementURL)).json();

Step 2: Request an Indicative Quote

Once your request is endorsed, you can request an indicative quote.

import { getIndicativeQuote } from "@dflow-protocol/signatory-client-lib/evm";

const signatoryServerURL = "https://signatory-1.dflow.net";
const walletAddress = "0x838A9B9992052AB55b5239c74d41671d03A5c31A";
const indicativeQuote = await getIndicativeQuote(signatoryServerURL, {
chainId: 137,
sendToken: "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174",
receiveToken: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
sendQty: "5",
orderFlowSource: "dflow1ejsafz9xy3ymkp6fmw8t299ag0wfl7drydj68n",
endorsement: endorsement, // Required when routing via auction
retailTrader: walletAddress, // Required when routing via auction
});

This is the response:

{
"fillPrice": "984763823125212342" // 0.984763823125212342 MATIC per USDC
}

Indicative Quote Request Fields

FieldTypeDescription
chainIdnumberThe chain ID of the EVM chain.
sendTokenstringThe address of the ERC-20 token sent by the retail trader. For native MATIC, this is 0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee.
receiveTokenstringThe address of the ERC-20 token received by the retail trader. For native MATIC, this is 0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee.
sendQtystringThe quantity of sendToken that the retail trader will send.
orderFlowSourcestringThe order flow source's DFlow address. This is the address on the DFlow Chain of the wallet that you use to create your auctions.
endorsementobject(Optional) The endorsement received from the endorsement server. Only required if the request is routed via an auction.
retailTraderstring(Optional) Address of the retail trader's Polygon wallet. Only required if the request is routed via an auction.

Indicative Quote Response Fields

The response for a successful request contains the following fields:

FieldTypeDescription
fillPricestringThe number of token units that the retail trader would receive per token sent. Note that the fillPrice is specified with the fixed number of decimals used for the receive token. For example, if the receiveToken is USDC, which has 6 decimals, and the fillPrice is 1500000, then the retail trader would receive 1.5 USDC per sendToken token.