The following methods are used to enhance the capabilities of your service using Swapgate.io’s exchange features.
Algorithm
Swapgate uses a dynamic rate system to generate exchange rate predictions, using liquidity provider market depth analysis. While the default flow will analyse the market depth and return a realistically-calculated result, the markup parameter can influence the rate returned by the rate prediction algorithm.
The markup parameter will influence the rate pre-calculation returned by our system on the following way:
A final=A calculated ∗ (1 − K markup / 100)
A final | Final amount to receive, predicted for the exchange |
A calculated | Initial amount to receive predicted for the exchange |
K markup | markup parameter value |
Based on the provided formula, a markup value of 0.3, provided for a 1 BTC → USDT exchange will yield the following results, making the final prediction price increased by 0.3%:
49549.728053855135 * (1 – 0.3 / 100) = 49401.07886969357
API
The rates data can be obtained through an API v1 call to the /api/v1/rates/public/one endpoint.
The API v1 does not require API key authorization or IP whitelisting.
Parameter | Description | Example |
---|---|---|
instrumentFromCurrencyTitle | The name of the currency to be exchanged | BTC |
instrumentFromNetworkTitle | The blockchain network of the currency to be exchanged | BTC |
instrumentToCurrencyTitle | The name of the currency to be obtained | USDT |
instrumentToNetworkTitle | The blockchain network of the currency to be obtained | TRC20 |
rateMode | The rate mode of the exchange, FLOATING or FIXED. | FLOATING |
claimedDepositAmount | The deposit amount claimed to be paid by the client | 1 |
markup | The markup parameter | 0.3 |
GET /api/v1/rates/public/one?instrumentFromCurrencyTitle=BTC&instrumentFromNetworkTitle=
BTC&instrumentToCurrencyTitle=
USDT&instrumentToNetworkTitle=TRC20&rateMode=FLOATING&claimedDepositAmount=
1&markup=0.3
{
"instrumentFrom": {
"currencyTitle": "BTC",
"networkTitle": "BTC",
"precisionDecimals": 11
},
"instrumentTo": {
"currencyTitle": "USDT",
"networkTitle": "TRC20",
"precisionDecimals": 1
},
"depositRules": {
"minAmount": "0.0010202831699481001984",
"maxAmount": "0"
},
"withdrawalRules": {
"minAmount": "51.324600057525118367",
"maxAmount": "0",
"withdrawalFeeRules": {
"maxAmount": "1",
"minAmount": "1"
}
},
"minConfirmationsToWithdraw": 2,
"minConfirmationsToTrade": 2,
"updatedAt": "2024-08-05T13:31:44.315Z",
"liquidityProviderPublicCode": "radio",
"amountToGet": "50201.90689595",
"amountToGive": "1",
"marketMinAmount": "0.1",
"enableFixedRate": true,
"amountToGiveCurrencyTitle": "BTC",
"rateMode": "FLOATING",
"finalNetworkFeeAmount": "0",
"platformFee_Absolute": null,
"liquidityProviderQuotes": {
"sellQuote": {
"baseValue": "1",
"quoteValue": "50304.27"
},
"buyQuote": {
"baseValue": "50294.99",
"quoteValue": "1"
}
},
"price": "50201.90689595",
"marketLeftPrice": "50304.27",
"marketRightPrice": "0.000019882696069727819809",
"marketAmountToGet": "50243.798064469251204",
"marketAmountToGetUSDT": "50243.798064469251204",
"quotesWithoutNetworkFee": {
"sellQuote": {
"baseValue": "1",
"quoteValue": "50202.90689595"
},
"buyQuote": {
"baseValue": "50294.99",
"quoteValue": "0.997985"
}
},
"quotes": {
"sellQuote": {
"baseValue": "1",
"quoteValue": "50201.90689595"
},
"buyQuote": {
"baseValue": "50294.99",
"quoteValue": "0.99796512097183797717"
}
},
"markup": "0.3"
}
Markup parameter in order flow
Algorithm
The markup parameter must also be passed during the order creation to ensure valid order commission. With the markup parameter passed, Swapgate will apply the following formula to the order commission algorithm:
A withdrawal = A exchange * (1 – (C platform(%) + K markup) / 100)
A withdrawal | Amount of currency sent to the client as the exchange result |
A exchange | Amount of currency that Swapgate had available after performing our trading strategy |
C platform(%) | Commission percent defined by Swapgate |
K markup | markup parameter value |
Based on the provided formula, a markup value of 0.3 provided during order creation, will increase Swapgate commission percent by 0.3.
In the following example Swapgate commission is set to 1 percent:
A withdrawal = A exchange * (1 – (1 + 0.3) / 100)
Using the previous example, an exchange of 1 BTC to USDT based on the market price of 50243.798064469251204 BTC:USDT will yield the following client withdrawal amount:
50243.798064469251204 * (1 – (1 + 0.3) / 100) = 49590.62868963115
Based on the provided formula, a markup value of 0.3 provided during order creation, will increase Swapgate commission percent by 0.3.
After an exchange with a markup parameter enters the COMPLETED state, the markup parameter will be used in the partner margin calculation formula:
C affiliate = C platform * (C affiliate(%) / 100) + C platform * (K markup / 100)
C affiliate | Amount of currency sent to the affiliate’s wallet per exchange (affiliate margin) |
C platform | Amount of currency that Swapgate gained from the exchange (platform margin) |
C affiliate(%) | Commission percent defined for the affiliate |
K markup | markup parameter value |
Passing the markup parameter
During order creation, Swapgate API accepts the markup parameter alongside other order creation parameters:
{
"rateMode": "FLOATING",
"instrumentFrom": {
"currencyTitle": "USDT",
"networkTitle": "TRC20"
},
"instrumentTo": {
"currencyTitle": "BTC",
"networkTitle": "BTC"
},
"destinationAddress": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
"destinationAddressMemo": null,
"refundAddress": null,
"refundAddressMemo": null,
"claimedNetworkFee": null,
"legacyOrderId": null,
"referrerId": "aff_616",
"claimedDepositAmount": "125000",
"utmData": [],
"browserFingerprint": "6b3add86bec11616427d069556a33548"
"markup": "0.2" // <-- here
}
The markup multiplier value is passed alongside other parameters.
Using API v2
Using the v2 API endpoints requires additional authorization setup. Without the necessary authorization parameters, v2 endpoints will throw 403 Forbidden errors.
The integration is composed of two steps – creating an API key and integrating its usage in the API requests. By creating an API key, our b2b customers will receive a key pair to sign their requests alongside a list of whitelisted IP addresses that can access the API endpoints.
Note: you must have an active authorization cookie to perform /api/v1/users/* requests.
Creating an API key
While creating the API key, an array of whitelisted IPs must be passed:
POST /api/v1/users/generate-api-key
Request:
{
"name": "test",
"whiteListIp": ["127.0.0.1"],
"isActive": true
}
Response:
{
"apiId": 40,
"name": "test",
"isActive": true,
"publicKey": "ZgzycV6Sf78BZKuyIAiz+0Bor002+0/rx1gLKsmYCsY=",
"secretKey": "a482a8e3a3ff9aeadefb11d3d8c11253e7e8412e05ef2b8599016cc87a64b7d6",
"whiteListIp": [
"127.0.0.1"
],
"createdAt": "2024-08-05T13:54:18.427Z"
}
The response will contain the key pair that is required to use during API v2 authorization.
Note: The secretKey field will be displayed only once, during API key creation. We advise to save it immediately after creating the API key.
Listing your API keys
If your integration requires more than one API key to be used, you can easily list them through the list endpoint:
GET /api/v1/users/list-api-key
[
{
"apiId": 40,
"name": "test",
"isActive": true,
"settings": {},
"publicKey": "ZgzycV6Sf78BZKuyIAiz+0Bor002+0/rx1gLKsmYCsY=",
"whiteListIp": [
"127.0.0.1"
],
"createdAt": "2024-08-05T13:54:18.427Z"
}
]
Managing your API keys
Managing existing API keys can be done through our b2b customer support line. This includes:
- Deleting API keys
- Adding new whitelisted IPs to an existing API key
- Updating and adding settings for an API key (ex.: min/max values for markup value)
- Deactivating API keys
Using the API key
API v2 requires 3 headers to be set on every request:
Header | Value |
---|---|
x-api-public-key | Your public key obtained during API key creation |
x-api-timestamp | UNIX timestamp |
x-api-signature | A signature of the request |
The signature value is generated using hmac sha256. The data passed is string concatenation of the timestamp, the string representation of the request body and the public key, while the private key is used as the key to the hmac function:
function signRequest(requestBody) {
const timestamp = new Date().getTime();
const publicKey = "ZgzycV6Sf78BZKuyIAiz+0Bor002+0/rx1gLKsmYCsY=";
const privateKey = "a482a8e3a3ff9aeadefb11d3d8c11253e7e8412e05ef2b8599016cc87a64b7d6";
const encoder = new TextEncoder();
const data = encoder.encode(
timestamp + JSON.stringify(requestBody) + publicKey,
);
const hmac = createHmac('sha256', privateKey);
const dataSign = hmac.update(data);
const signature = dataSign.digest('base64');
return signature;
}
signRequest({ myKey: "myValue" })
Sample integration code
const { createHmac } = require('crypto');
const API_PREFIX = 'https://swapgate.io/api/';
const PUBKEY = 'public_key'; // changeme
const PRIVKEY = 'private_key'; // changeme
function signRequest(requestBody, timestamp) {
const encoder = new TextEncoder();
const data = encoder.encode(timestamp + JSON.stringify(requestBody) + PUBKEY);
const hmac = createHmac('sha256', PRIVKEY);
const dataSign = hmac.update(data);
const signature = dataSign.digest('base64');
return signature;
}
async function createOrder() {
const clientBrowserFingerprint = '6b3add86bec11616427d069556a33548';
const orderRateMode = 'FLOATING';
const depositAmount = '1';
const clientDestinationAddress = 'TUhw6S1HyXDhycKvTec3x7HNGQfNn3Vhpc';
const clientDestinationAddressMemo = null;
const markup = '0.3';
const instrumentFromCurrencyTitle = 'BTC';
const instrumentFromNetworkTitle = 'BTC';
const instrumentToCurrencyTitle = 'USDT';
const instrumentToNetworkTitle = 'TRC20';
// Step 1. Prepate createOrder request body using obtained rate data
const createOrderRequestBody = {
rateMode: orderRateMode,
instrumentFrom: {
currencyTitle: instrumentFromCurrencyTitle,
networkTitle: instrumentFromNetworkTitle,
},
instrumentTo: {
currencyTitle: instrumentToCurrencyTitle,
networkTitle: instrumentToNetworkTitle,
},
destinationAddress: clientDestinationAddress,
destinationAddressMemo: clientDestinationAddressMemo,
refundAddress: null,
refundAddressMemo: null,
markup: markup,
claimedNetworkFee: null,
legacyOrderId: null,
referrerId: null,
claimedDepositAmount: depositAmount,
utmData: [],
browserFingerprint: clientBrowserFingerprint,
};
// Step 2. Prepare signature based on key pair and createOrder request data
const timestamp = new Date().getTime();
const signature = signRequest(createOrderRequestBody, timestamp);
// Step 3. Call API v2 create-order endpoint
const order = JSON.parse(
await (
await fetch(`${API_PREFIX}v2/orders/public/create`, {
method: 'POST',
headers: {
'x-api-public-key': PUBKEY,
'x-api-timestamp': timestamp,
'x-api-signature': signature,
'content-type': 'application/json; charset=utf-8',
},
body: JSON.stringify(createOrderRequestBody),
})
).text(),
);
console.log('order', order);
}
void createOrder();