APIv2

Author profile photo
Swapgate team
September 11, 2024
~4 min read

The following methods are used to enhance the capabilities of your service using Swapgate.io’s exchange features.

Markup parameter in rate calculation

Algorithm

Swapgate uses a dynamic rate system to generate exchange rate predictions based on liquidity provider market depth analysis. While the default flow analyzes market depth and returns a realistically calculated result, the markup parameter can influence the rate returned by the rate prediction algorithm.

The markup parameter influences the rate pre-calculation returned by the system in the following way:

Afinal = Acalculated × (1 − Kmarkup / 100)
Variable Description
Afinal Final amount to receive, predicted for the exchange.
Acalculated Initial amount to receive, predicted for the exchange.
Kmarkup markup parameter value.

Based on the provided formula, a markup value of 0.3 for a 1 BTC → USDT exchange will yield the following result:

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 request
GET /api/v1/rates/public/one?instrumentFromCurrencyTitle=BTC&instrumentFromNetworkTitle=BTC&instrumentToCurrencyTitle=USDT&instrumentToNetworkTitle=TRC20&rateMode=FLOATING&claimedDepositAmount=1&markup=0.3
Response example
{
  "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 order creation to ensure valid order commission. With the markup parameter passed, Swapgate applies the following formula to the order commission algorithm:

Awithdrawal = Aexchange × (1 − (Cplatform(%) + Kmarkup) / 100)
Variable Description
Awithdrawal Amount of currency sent to the client as the exchange result.
Aexchange Amount of currency that Swapgate had available after performing the trading strategy.
Cplatform(%) Commission percent defined by Swapgate.
Kmarkup markup parameter value.

Based on the provided formula, a markup value of 0.3 during order creation increases the Swapgate commission percent by 0.3. In the following example, Swapgate commission is set to 1%:

Awithdrawal = Aexchange × (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

After an exchange with the markup parameter enters the COMPLETED state, the markup parameter is used in the partner margin calculation formula:

Caffiliate = Cplatform × (Caffiliate(%) / 100) + Cplatform × (Kmarkup / 100)
Variable Description
Caffiliate Amount of currency sent to the affiliate’s wallet per exchange, also known as the affiliate margin.
Cplatform Amount of currency that Swapgate gained from the exchange, also known as the platform margin.
Caffiliate(%) Commission percent defined for the affiliate.
Kmarkup markup parameter value.

Passing the markup parameter

During order creation, Swapgate API accepts the markup parameter alongside other order creation parameters:

Order creation payload
{
  "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"
}

The markup multiplier value is passed alongside the other parameters.

Using API v2

Using the v2 API endpoints requires additional authorization setup. Without the necessary authorization parameters, v2 endpoints return 403 Forbidden errors.

The integration consists of two steps: creating an API key and using it in API requests. After creating an API key, B2B customers receive a key pair to sign their requests, along with 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

When creating an API key, an array of whitelisted IP addresses must be passed:

Create API key
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 contains the key pair required for API v2 authorization.

Note: the secretKey field is displayed only once, during API key creation. Save it immediately after creating the API key.

Listing your API keys

If your integration requires more than one API key, you can list them through the list endpoint:

List API keys
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

Existing API keys can be managed through the B2B customer support line. This includes:

  • Deleting API keys.
  • Adding new whitelisted IP addresses to an existing API key.
  • Updating and adding settings for an API key, for example minimum and maximum values for the markup value.
  • Deactivating API keys.

Using the API key

API v2 requires three 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 SHA-256. The data is a string concatenation of the timestamp, the string representation of the request body, and the public key. The private key is used as the key for the HMAC function.

Request signature
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

Node.js integration example
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. Prepare 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();
Share this article: