Следующие методы используются для расширения возможностей вашего сервиса с помощью функций обмена Swapgate.io.
Параметр наценки в расчёте курса
Алгоритм
Swapgate использует систему алгоритмов курсов для прогнозирования обменных курсов на основе анализа ликвидности рынка поставщиков. Алгоритм анализирует рынок и возвращает реалистичный расчёт по умолчанию, а параметры наценки могут применяться к курсу, возвращённому алгоритмом прогнозирования.
Параметр наценки влияет на предварительно рассчитанный курс следующим образом:
| Обозначение | Описание |
|---|---|
Afinal |
Окончательная итоговая сумма, прогнозируемая для обмена. |
Aestimated |
Первоначальная расчётная сумма прогноза по обмену. |
Kmarkup |
Значение параметра наценки. |
Исходя из представленной формулы, величина наценки 0.3, предусмотренная для обмена 1 BTC → USDT, даёт следующий результат:
API
Данные о тарифах можно получить с помощью API v1, обратившись к endpoint /api/v1/rates/public/one.
| Параметр | Описание | Пример |
|---|---|---|
instrumentFromCurrencyTitle |
Название валюты, подлежащей обмену. | BTC |
instrumentFromNetworkTitle |
Сеть валюты, подлежащей обмену. | BTC |
instrumentToCurrencyTitle |
Название валюты, которую необходимо получить. | USDT |
instrumentToNetworkTitle |
Сеть валюты, которую необходимо получить. | TRC20 |
rateMode |
Режим обменного курса: FLOATING или FIXED. |
FLOATING |
claimedDepositAmount |
Заявленная клиентом сумма депозита. | 1 |
markup |
Параметр наценки. | 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 Swapgate применяет следующую формулу:
| Обозначение | Описание |
|---|---|
Withdrawal |
Сумма валюты, отправленная клиенту как результат обмена. |
Exchange |
Количество валюты, доступное Swapgate после выполнения торговой стратегии. |
Platform C (%) |
Текущий процент комиссии Swapgate. |
Kmarkup |
Значение параметра наценки. |
Исходя из приведённой формулы, значение наценки 0.3, указанное при оформлении заказа, увеличивает процент комиссии Swapgate на 0.3. В следующем примере комиссия Swapgate установлена на 1%:
Используя предыдущий пример, обмен 1 BTC на USDT на основе рыночной цены 50243.798064469251204 BTC:USDT приводит к следующему итоговому результату средств клиента:
После того как обмен с параметром наценки перейдёт в состояние COMPLETED, параметр markup будет использован в формуле расчёта партнёрской маржи:
| Обозначение | Описание |
|---|---|
Caffiliate |
Количество валюты, отправленное на кошелёк партнёра за обмен: партнёрская маржа. |
Cplatform |
Сумма валюты, которую Swapgate получил от обмена: маржа платформы. |
Caffiliate (%) |
Процент комиссии, определённый для партнёра. |
Kmarkup |
Значение параметра markup. |
Передача параметра markup
При создании заказа Swapgate API принимает параметр markup наряду с другими параметрами создания заказа:
{
"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"
}
Значение параметра markup передаётся вместе с другими параметрами.
Использование API v2
Использование endpoint API v2 требует дополнительной настройки авторизации. Без необходимых параметров авторизации endpoint API v2 будет возвращать ошибку 403 Forbidden.
Интеграция состоит из двух шагов: создания API-ключа и его дальнейшего использования в API-запросах. После создания API-ключа b2b-клиенты получают пару ключей для подписи запросов, а также список IP-адресов, которым разрешён доступ к endpoint API.
/api/v1/users/* необходим активный cookie авторизации.Создание API-ключа
При создании API-ключа необходимо передать массив IP-адресов для белого списка:
POST /api/v1/users/generate-api-key
{
"name": "test",
"whiteListIp": ["127.0.0.1"],
"isActive": true
}
{
"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"
}
В ответе будет содержаться пара ключей, которую необходимо использовать для авторизации API v2.
secretKey отображается только один раз — во время создания API-ключа. Рекомендуется сохранить его сразу после создания ключа.Список API-ключей
Если ваша интеграция требует использования более одного API-ключа, вы можете получить их список с помощью 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"
}
]
Управление API-ключами
Управление существующими API-ключами может выполняться через службу поддержки b2b-клиентов. Это включает:
- удаление API-ключей;
- добавление новых IP-адресов в белый список существующего API-ключа;
- обновление и добавление настроек для API-ключа, например минимальных и максимальных значений для
markup; - деактивацию API-ключей.
Использование API-ключа
API v2 требует установки трёх заголовков при каждом запросе:
| Заголовок | Значение |
|---|---|
x-api-public-key |
Открытый ключ, полученный при создании API-ключа. |
x-api-timestamp |
Временная метка UNIX. |
x-api-signature |
Подпись запроса. |
Значение подписи создаётся с помощью HMAC SHA-256. Контрольные данные формируются через строковую конкатенацию временной метки, строкового представления тела запроса и открытого ключа. Закрытый ключ используется как ключ функции HMAC.
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" });
Пример кода инициализации
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();