Build a Delta Order to Sign
Build a Delta Order to Sign
POST https://api.paraswap.io/delta/orders/build
This section explains how to construct a Delta Order, which is essential for executing trades using the Velora Delta API. The /orders/build endpoint retrieves a Delta price and allows fallback to market prices.
A successfully built order includes a structured object ready for signing.
Common errors include validation failures, unsupported assets, and signature mismatches.
Use this guide to generate a Delta Order and prepare it for signing before submission.
Request Body Parameters
chainId*
number
Chain ID. (Mainnet - 1, Optimism - 10, BSC - 56, Polygon - 137, Fantom - 250, zkEVM - 1101, Base - 8453, Arbitrum - 42161, Avalanche - 43114, Gnosis - 100).
owner*
string
Order owner address.
bridge
DeltaBridge
Required only for cross-chain orders. See below for details
beneficiary
string
Order beneficiary. Default: zero address, meaning owner address.
slippage
number
Slippage in base points (100 is 1%). Default: 100.
deadline
number
Order expiry time as UNIX timestamp. Default: 1 hour from order creation.
nonce
string
Arbitrary uint256 value to be used as order nonce. Default: value generated with internal algos. It is recommended to omit this param.
permit
string
Encoded permit to be used in order settlement. Supported permit types are described here. Default: 0x.
partiallyFillable
boolean
If true, order will be generated as partially fillable. Default: false.
partnerAddress
string
Address of the partner. Used to collect fees from the order. Default: zero address.
partnerFeeBps
number
Partner fee percent in base points (100 is 1%). Max value is 200. Default: 0.
partnerTakesSurplus
boolean
If true, partner will collect 50% of the order surplus instead of flat percent fee. Default: false.
DeltaBridge structure:
protocolSelector
string
Selector that indicates the bridge protocol used. Obtained from the price API
destinationChainId
number
Destination chain ID. (Mainnet - 1, Optimism - 10, BSC - 56, Polygon - 137, Fantom - 250, zkEVM - 1101, Base - 8453, Arbitrum - 42161, Avalanche - 43114, Gnosis - 100).
outputToken
string
Output token on the destination chain. List of supported output tokens can be obtained from /bridge-info endpoint. Output token can also be obtained from price.bridge.outputToken
scalingFactor
number
Specifies difference between the decimals in source bridge token and destination token
protocolData
string
Protocol-specific data, obtained from pricing API
{
"toSign": {
"domain": {
"name": "Portikus",
"version": "2.0.0",
"chainId": 1,
"verifyingContract": "0x0000000000bbf5c5fd284e657f01bd000933c96d"
},
"types": {
"Order": [
{
"name": "owner",
"type": "address"
},
{
"name": "beneficiary",
"type": "address"
},
{
"name": "srcToken",
"type": "address"
},
{
"name": "destToken",
"type": "address"
},
{
"name": "srcAmount",
"type": "uint256"
},
{
"name": "destAmount",
"type": "uint256"
},
{
"name": "expectedAmount",
"type": "uint256"
},
{
"name": "deadline",
"type": "uint256"
},
{
"name": "kind",
"type": "uint8"
},
{
"name": "nonce",
"type": "uint256"
},
{
"name": "partnerAndFee",
"type": "uint256"
},
{
"name": "permit",
"type": "bytes"
},
{
"name": "metadata",
"type": "bytes"
},
{
"name": "bridge",
"type": "Bridge"
}
],
"Bridge": [
{
"name": "protocolSelector",
"type": "bytes4"
},
{
"name": "destinationChainId",
"type": "uint256"
},
{
"name": "outputToken",
"type": "address"
},
{
"name": "scalingFactor",
"type": "int8"
},
{
"name": "protocolData",
"type": "bytes"
}
]
},
"value": {
"owner": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"beneficiary": "0x0000000000000000000000000000000000000000",
"srcToken": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"destToken": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"srcAmount": "10000000",
"destAmount": "9127760",
"expectedAmount": "9219960",
"deadline": 1757333024,
"kind": 0,
"nonce": "47551995136396664604384293391986507799897145387152361812735887931703330715323",
"permit": "0x",
"partnerAndFee": "0",
"metadata": "0x",
"bridge": {
"protocolSelector": "0x21eaa4cd",
"destinationChainId": 8453,
"outputToken": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
"scalingFactor": 0,
"protocolData": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
}
}
}
}{
"errorType": "InvalidHmac",
"details": "Invalid HMAC"
}Most common error types
ValidationError- validation for params failedUnsupportedChain- the chain ID is not supported by Delta.UnsupportedToken- the token is not supported by Delta.InvalidHmac-hmaccheck failed, meaningpriceobject returned from/quoteendpoint was mutated.
Supported Permits
Permit(ERC-2612)- expected to have 224 bytes length.Permit2TransferFromformat - expected length is 96 bytes (32 for permitNonce, 64 for compact signature), amount and deadline should be the same as inOrder.Allowanceformat - expected length is 192 bytes.
DAI Style Permit- expected length is 256 bytes.0x01- specialpermitvalue that signifies existingPermit2allowance.
Delta Contract should be specified as a spender is a permit.
Sign an Order
Once the Delta Order is built, it must be signed using the EIP-712 standard before submission. This section provides a working example using ethers.js and axios.
Example:
import { ethers, TypedDataEncoder } from "ethers"; // ethers V6
import axios from "axios";
const userWallet = new ethers.Wallet(ethers.id("alice"));
const userAddress = userWallet.address;
const chainId = 1;
// fetch price
const { data: quoteData } = await axios.get("https://api.paraswap.io/quote?mode=delta&...");
const price = quoteData.delta;
// prepare build order params
const buildOrderParams = {
price,
owner: userAddress,
chainId,
partnerAddress: "0x81037e7be71bce9591de0c54bb485ad3e048b8de",
partnerFeeBps: 100, // 1%
partnerTakesSurplus: false, // the default
};
// build the order to sign
const { data: buildOrderData } = await axios.post("https://api.paraswap.io/delta/orders/build", buildOrderParams);
const { domain, types, value: order } = buildOrderData.toSign;
// hash the order
const eip712Hash = TypedDataEncoder.hash(
domain,
types,
order,
);
// sign and compact
const signature = userWallet.signingKey.sign(typedHash).compactSerialized; // ERC-2098 representationSign an order (cross-chain)
The following snippet provides an example implementation of constructing the DeltaBridge structure for the cross-chain swap
import { ethers, TypedDataEncoder } from "ethers"; // ethers V6
import axios from "axios";
const ETH_ADDRESS = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"; // same across all chains
const USDC_ADDRESS_ETH = "0xA0b86991c6218b36c1d19D4a2e9EB0CE3606EB48"; // USDC on Ethereum
const WETH_ADDRESS_OP = "0x4200000000000000000000000000000000000006";
const userWallet = new ethers.Wallet(ethers.id("alice"));
const userAddress = userWallet.address;
const srcChainId = 1;
const destChainId = 10;
const buildAndSignOrder = async (
srcToken: string,
srcDecimals: number,
// dest token on destination chain
destToken: string,
destDecimals: number,
srcChainId: number,
destChainId: number,
amount: number,
) => {
const { data: quoteData } = await axios.get(`https://api.paraswap.io/quote`, {
params: {
mode: "delta",
srcToken,
srcDecimals,
destToken,
destDecimals,
chainId: srcChainId,
destChainId,
amount,
},
});
const price = quoteData.delta;
// prepare build order params
const buildOrderParams = {
price,
owner: userAddress,
chainId: srcChainId,
partnerAddress: "0x81037e7be71bce9591de0c54bb485ad3e048b8de",
partnerFeeBps: 100, // 1%
partnerTakesSurplus: false, // the default,
bridge: price.bridge,
};
// build the order to sign
const { data: buildOrderData } = await axios.post(
"https://api.paraswap.io/delta/orders/build",
buildOrderParams,
);
const { domain, types, value: order } = buildOrderData.toSign;
// hash the order
const eip712Hash = TypedDataEncoder.hash(domain, types, order);
// sign and compact
const signature = userWallet.signingKey.sign(eip712Hash).compactSerialized; // ERC-2098 representation
return { order, signature };
};
// swap 1 USDC on Mainnet to WETH on Optimism
const order = await buildAndSignOrder(
USDC_ADDRESS_ETH,
6,
WETH_ADDRESS_OP,
18,
srcChainId,
destChainId,
10 ** 18,
);
Partner Fees
The fees are enabled by encoding partnerAndFee param of the order, before its signed by a user.
The param includes three values:
partnerAddress- on-chain address which will be able to collect the fees.partnerFeeBps- flat fee percent which will be taken from the order. The value is in base points (100is1%), which the maximum allowed value of200.partnerTakeSurplus- a flag that, if set, allows the partner to collect50%of thesurplusas fees. It has no impact if passed together withpartnerFeeBps, sincepartnerFeeBpstakes precedence.
These are encoded into a single uint256 value, which then is used as partnerAndFee.
Last updated