API Access
Direct access for any of the ~5,000 token pairs with Uniswap V3 liquidity on Ethereum & Polygon
Overview
To facilitate smart contract interaction, our API server offers three helpful API calls: choose pool, calculate trade parameters, and review all trades. For direct smart contract interactions, three main solidity functions: create, ping, and close. Deployment addresses: Addresses
Typical flow
To execute a new Limit trade:
API call: Choose pool
API call: Calculate trade parameters: ticks, liquidity
Smart Contract: Create position
Example
Trade 1.3 ETH for CIV @ price of 29146 CIV/ETH on Ethereum (chainId = 1):
API call: getPool(WETH/CIV) → returns poolContract 0x2b1b8052eed6467967d047b58b71f8e9ffa057b5
API call: evaluateLimitTrade(pool and prices above) → returns tickLower:-102840, tickUpper:-102780, liquidity: 73998408845592650000000
Smart Contract: createPos(true [ETH=native token], true [address of WETH>CIV], false [not relayed], <poolContract>, <tickLower>, <tickUpper>, <liquidity>) → opens the position
Javascript example code
Simple example using axios for API calls, Defender Relayers, and ethers JS to submit the transaction. Set as you please the variables tokenGiven, tokenWanted, sendNative, targetAmount, targetPrice:
exports.handler = async function(credentials) {
const provider = new DefenderRelayProvider(credentials);
const network = await provider.getNetwork();
const chainId = network.chainId;
const signer = new DefenderRelaySigner(credentials, provider, { speed: 'fast' });
const civposmgr = new ethers.Contract(getCivPosMgrAddress(chainId), civPosMgrAbi, signer);
let response, linkTarget
let sentTokenTwo = tokenGiven > tokenWanted
try {
linkTarget = 'https://api.civfund.org/getPool/' + tokenGiven + '/' + tokenWanted + '?chainId=' + chainId
response = await fetch(linkTarget, { method: 'GET', headers: { 'Content-Type': 'application/json' }, });
response = await response.json();
} catch (err) { console.log("fetch error", err); }
let targetPool = response.poolContract
try {
linkTarget = 'https://api.civfund.org/evaluateLimitTrade/' + targetPool + '/' + tokenGiven + '/' + tokenWanted + '/' + targetAmount + '/' + targetPrice + '?chainId=' + chainId
response = await fetch(linkTarget, { method: 'GET', headers: { 'Content-Type': 'application/json' }, });
response = await response.json();
} catch (err) { console.log("fetch error", err); }
let amountSent = Math.round( Math.max(response.amount0, response.amount1) ) + 1; //only sending one of the two tokens
let txValue = sendNative ? amountSent : 0
let tx = await civposmgr.createPos(true, sentTokenTwo, false, targetPool, tickLower, tickUpper, liquidity, { value: txValue })
return 'Transaction hash: ' + tx.hash;
}
API calls
Choose pool
The ASR (Auto-Smart-Router) selects the best pool to trade a given token pair based on the volume, liquidity, and fee tier of all the pools available for that pair. Errors if no pool available. For more info, click here.
Average latency: ~500ms. The poolContract output of this API call can be used as direct input to the smart contract createPos function, and also as input to the API call evaluateLimitTrade as detailed below.
NOTE: All API calls require specifying the chainId for the target blockchain as query parameter, 1 for Ethereum and 137 for Polygon. Refer to https://chainlist.org/ for details on chainId settings.
GET /getPool/:tokenGiven/:tokenWanted
Input
tokenGiven, contract address of the input token
tokenWanted, contract address of the output token
chainId, query parameter, 1 for Ethereum and 137 for Polygon
Returns
poolContract, contract address of the chosen pool
rate, current pool rate of tokenWanted per tokenGiven
feeTier, pool fee tier expressed in 10000 x %, for example 0.3% = 3000
decimalsFrom, number of contract decimals of the Given token
decimalsTo, number of contract decimals of the Wanted token
tickCurrent, current pool tick
Usage example
https://api.civfund.org/getPool/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2/0x37fe0f067fa808ffbdd12891c0858532cfe7361d?chainId=1
Result
{"poolContract":"0x2b1b8052eed6467967d047b58b71f8e9ffa057b5","rate":27758.25199344553,"feeTier":"3000","decimalsFrom":"18","decimalsTo":"18","tickCurrent":"-102318","result":"OK"}
Calculate trade parameters
Helps determine the smart contract input. Average latency: ~220ms. The tickLower, tickUpper, liquidity output can be used as direct input to the smart contract createPos function.
GET /evaluateLimitTrade/:pool/:tokenGiven/:tokenWanted/:amountGiven/:targetPrice
Input
pool, pool to be traded - for example, from the previous getPool call
tokenGiven, contract address of the input token
tokenWanted, contract address of the output token
amountGiven, amount of tokenGiven traded, expressed in token number
targetPrice, target price in tokenWanted per 1 tokenGiven
chainId, query parameter, 1 for Ethereum and 137 for Polygon
Returns
amount0, number of the first token in the pool (in the correct alphabetical order by contract ID) including all Solidity decimals
amount1, number of the second token in the pool
tickTarget, target tick based on the specified targetPrice
tickLower, lower end of the concentrated tick range
tickUpper, upper end of the concentrated tick range
liquidity, the amount of liquidity to provide
tickCurrent, current tick of the target pool
Usage example
https://api.civfund.org/evaluateLimitTrade/0x2b1b8052eed6467967d047b58b71f8e9ffa057b5/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2/0x37fe0f067fa808ffbdd12891c0858532cfe7361d/1.3/29146.16459265?chai
Result
{"amount0":"0","amount1":"1300000000000000000","tickTarget":"-102806","tickLower":-102840,"tickUpper":-102780,"liquidity":"73998408845592650000000","tickCurrent":-102318,"check":true,"result":"OK"}
Review trades
Status of all trades for a given wallet. Average latency: depends on how many trades the wallet has opened historically. Note: similar information is also available online in easy-to-read format at https://app.civfund.org/your-trades
GET /trades/:wallet
Input
wallet, wallet address to be queried
chainId, query parameter, 1 for Ethereum and 137 for Polygon
Returns
Array containing, for each trade:
token0, contract address of the input token in the trade
tokenSymbol0, symbol of the input token in the trade
tokenName0, name of the input token in the trade
amount0, number of input tokens
token1, contract address of the output token in the trade
tokenSymbol1, symbol of the output token in the trade
tokenName1, name of the output token in the trade
amount1, number of output tokens
dateOpened, readable date/time of the opening transaction in UTC time
dateOpenedRaw, machine date/time of the opening transaction in UTC time
dateOpenedDay, readable date of the opening transaction in UTC time
dateOpenedTime, readable time of the opening transaction in UTC time
dateClosed, readable date/time of the closing transaction in UTC time
elapsed, readable time elapsed since opening (if open) or until closing time (if closed)
currentAmount0, number of input tokens currently in the position,
currentAmount1, number of output tokens currently in the position,
status, text describing the current trade status,
orderId, ID of the trade,
token0Decimals, number of Solidity contract decimals for the input token,
token1Decimals, number of Solidity contract decimals for the output token,
percentFilled, % of input token already traded - note, this can also go down, read https://docs.civfund.org/civilization/civtrade/building-the-binance-of-defi/your-questions#filled-decreased for more information,
targetPrice, target number of output token per input token,
invertedPrice, target number of input token per output token,
actualPrice, current number of output token per input token,
actualInverted, current number of input token per output token,
initialPrice, initial number of output token per input token at the time of open,
initialInverted, initial number of input token per output token at the time of open,
pairName, text describing the pair traded,
pairInverted, text describing the pair traded in the inverted direction,
openTxn, block explorer link of the opening transaction,
closeTxn, block explorer link of the closing transaction (if closed),
version, version of CivTrade (1 = legacy or 2 = current),
tradeType, type of trade (Faster or Cheaper)
feePercent, pool fee tier expressed in 10000 x %, for example 0.3% = 3000
Usage example
https://api.civfund.org/trades/0x46DaD8f630736C7265849422F943efD77CB8714f?chainId=1
Result
[{"token0":"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2","tokenSymbol0":"ETH","tokenName0":"Ether","amount0":"1.2","token1":"0x37fe0f067fa808ffbdd12891c0858532cfe7361d","tokenSymbol1":"CIV","tokenName1":"Civilization","amount1":"29,845.162","dateOpened":"3 Feb 2022, 13:25:11 UTC","dateOpenedRaw":"2022-02-03T13:25:11.000Z","dateOpenedDay":"3 Feb 2022","dateOpenedTime":"13:25:11 UTC","dateClosed":"6 Feb 2022, 3:10:40 UTC","elapsed":"22 days, 23h:57m,15s","currentAmount0":"1.2","currentAmount1":"0","status":"Closed","orderId":"2","token0Decimals":18,"token1Decimals":18,"percentFilled":"","targetPrice":"25,578.119","invertedPrice":"-","initialPrice":"20,733.438","initialInverted":"-","pairName":"CIV per ETH","pairInverted":"ETH per CIV","openTxn":"https://etherscan.io/tx/0x804f87aaadb56e79172bdf5af538683d4ba7c5931499816e784e3b0d8abe9841","closeTxn":"https://etherscan.io/tx/0xb83dae1ec492db9ddf8a94e7abd9939ef5ad3f32769c3b668aab6007388968ef","version":2,"tradeType":"Cheaper","feePercent":"1%"}, (...) ]
Smart Contract calls
Create
Open a new position. Interface specs:
function createPos(
bool _nativeETH,
bool userSentTokenTwo,
bool relayed,
IUniswapV3Pool _pool,
int24 _tickLower,
int24 _tickUpper,
uint128 _liquidity
)
Input
Parameters, in order:
bool _nativeETH, must be true if any of the two tokens is ETH (on Ethereum) or MATIC (on Polygon); false in any other case including WETH or WMATIC. CivTrade Limit does not support ETH<->WETH wrap/unwrap: not a Limit trade, since their ratio is fixed 1:1 - (use CivTrade Market to wrap/unwrap). Maybe useful to know that with DeFi it is always gas-cheaper to trade in/out of WETH rather than ETH, so to trade frequently, consider using WETH. Usage examples:
ETH -> CIV: true
CIV -> ETH: true
WETH -> CIV: false
CIV -> WETH: false
ETH -> WETH: not allowed
bool userSentTokenTwo, must be true if the contract ID of the input token is alphabetically higher than the contract ID of the output token, false otherwise. For example, the Ethereum contract ID of CIV is 0x37fe0f067fa808ffbdd12891c0858532cfe7361d and of WETH is 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 there usage examples:
WETH -> CIV: true (sending WETH which is 0xc02 alphabetically higher than CIV 0x37)
CIV -> WETH: false (the other way around)
bool relayed, used only for “Cheaper” trades. Always set to false otherwise. Usage examples:
WETH -> CIV: false
CIV -> WETH: false
IUniswapV3Pool _pool, target pool address, for example 0x2b1b8052eed6467967d047b58b71f8e9ffa057b5 is the CIV/WETH 0.3% pool. The contract will fail if the pool does not exist, but will not make any assessment to the quality or volume of the target pool. Can be calculated for any token pair using the API call getPool. Usage examples:
WETH -> CIV: 0x2b1b8052eed6467967d047b58b71f8e9ffa057b5
CIV -> WETH: 0x2b1b8052eed6467967d047b58b71f8e9ffa057b5
int24 _tickLower, the lower-end of the tick range. This must be an initialised tick in the pool, at least “tickSpacing” away from the tickUpper. The contract will accept any valid range, error otherwise. Can be calculated for any token pair using the API call evaluateLimitTrade. Usage examples:
WETH -> CIV @ 29146: -102840
CIV -> WETH @ 29146: 102780
int24 _tickUpper, the higher-end of the tick range. Can be calculated for any token pair using the API call evaluateLimitTrade. Usage examples:
WETH -> CIV @ 29146: -102780
CIV -> WETH @ 29146: 102840
uint128 _liquidity, the amount of liquidity to create. The contract will then calculate the correct amounts to debit the wallet with; due to their peculiar behaviour, tax-on-transfer tokens are supported only for purchase (e.g. ETH -> Token) but not sale (e.g. Token -> ETH) unless manually adjusting the liquidity calculation, not recommended. Can be calculated for any token pair using the API call evaluateLimitTrade. Usage examples:
1.3 WETH -> CIV @ 29146: 73998408845592650000000
1000 CIV -> WETH @ 29146: 56921852958152060000000000
This function emits the event:
event OpenedCivTrade(
uint256 orderId,
address user,
address pool,
bool nativeETH,
bool relayed,
uint256 initialAmount0,
uint256 initialAmount1,
int24 tickLower,
int24 tickUpper,
uint128 liquidity
)
The uint256 orderId is used in all other function calls.
The initialAmount0 / initialAmount1 are the amounts of input tokens debited, including all Solidity decimals. So 2 WETH will show as 2 * 10^18 in the initialAmount, as WETH is a token with 18 decimals.
Note: the amount of input token is calculated, not an explicit input; the transaction will fail if the wallet does not have sufficient funds to create the target liquidity, for example, if the market price moves across the tickLower-tickUpper range before execution - keep at least 0.1% away from the current price to limit this risk.
Ping
Ping an existing position while open.
Interface
function civTrade(uint256 orderId)
returns (
bool nativeETH,
bool userSentTokenTwo,
int24 tickLower,
int24 tickUpper,
uint128 liquidity,
address user,
IUniswapV3Pool pool
)
Errors if the orderId is closed or does not exist.
Close
Close an open position manually. The position will auto-close when filled, no need to call this function except to return funds when not yet filled.
Interface
function closePos(uint256 _orderId)
This function emits the event:
event ClosedCivTrade(
uint256 orderId,
bool autoClosed,
uint256 amountReturned0,
uint256 amountReturned1,
uint256 feesPaid0,
uint256 feesPaid1,
bool zeroFee
)
The bool autoClosed is false for manually closed positions.
Last updated
Was this helpful?