Api

Orderbook API

Market data and order management

The Orderbook API provides decentralized trading functionality with support for limit orders, market orders, liquidity provision, and multi-hop swaps.

Endpoints

Market Management

Orderbook Data

Order Operations

Trade History

Streaming


Get Markets Info

Get information about all available markets.

Method: GetMarketsInfo

Parameters: None

Response:

FieldTypeDescription
marketsMarketInfo[]Array of market information

MarketInfo Object:

FieldTypeDescription
baseCurrencyInfoBase currency info
quoteCurrencyInfoQuote currency info
taker_base_feeDecimalStringTaker fee in base currency
taker_quote_feeDecimalStringTaker fee in quote currency
maker_base_feeDecimalStringMaker fee in base currency
maker_quote_feeDecimalStringMaker fee in quote currency
base_precisionuint32Decimal precision for base
quote_precisionuint32Decimal precision for quote
min_base_amountDecimalStringMinimum base amount
min_quote_amountDecimalStringMinimum quote amount

Example Request:

TypeScript
import { OrderbookServiceClient } from './proto/OrderbookServiceClientPb'
import { GetMarketsInfoRequest } from './proto/orderbook_pb'

const client = new OrderbookServiceClient('http://localhost:5001')

const request = new GetMarketsInfoRequest()
const response = await client.getMarketsInfo(request, {})
const markets = response.getMarketsList()
Go
import (
    "context"
    pb "your-package/proto"
)

client := pb.NewOrderbookServiceClient(conn)
request := &pb.GetMarketsInfoRequest{}

response, err := client.GetMarketsInfo(context.Background(), request)
if err != nil {
    log.Fatalf("Error: %v", err)
}
markets := response.GetMarkets()
Rust
use tonic::Request;
use your_package::orderbook_service_client::OrderbookServiceClient;
use your_package::GetMarketsInfoRequest;

let mut client = OrderbookServiceClient::connect("http://localhost:5001").await?;
let request = Request::new(GetMarketsInfoRequest {});

let response = client.get_markets_info(request).await?.into_inner();
let markets = response.markets;

Example Response:

{
  "markets": [
    {
      "base": {
        "protocol": 0,
        "network_id": "0",
        "asset_id": "BTC",
        "decimals": 8
      },
      "quote": {
        "protocol": 1,
        "network_id": "1",
        "asset_id": "0x0000000000000000000000000000000000000000",
        "decimals": 18
      },
      "taker_base_fee": "0.001",
      "taker_quote_fee": "0.001",
      "maker_base_fee": "0.0005",
      "maker_quote_fee": "0.0005",
      "base_precision": 8,
      "quote_precision": 18,
      "min_base_amount": "10000",
      "min_quote_amount": "1000000000000000"
    }
  ]
}

Get Market Info

Get information about a specific market.

Method: GetMarketInfo

Parameters:

NameTypeRequiredDescription
first_currencyOrderbookCurrencyYESFirst currency of the pair
other_currencyOrderbookCurrencyYESOther currency of the pair

Response:

FieldTypeDescription
market_infoMarketInfoMarket information (optional - null if market doesn't exist)

Example Request:

TypeScript
const request = new GetMarketInfoRequest()
request.setFirstCurrency({
  network: { protocol: 0, chainId: '0', name: 'Bitcoin' },
  assetId: 'BTC'
})
request.setOtherCurrency({
  network: { protocol: 1, chainId: '1', name: 'Ethereum' },
  assetId: '0x0000000000000000000000000000000000000000'
})

const response = await client.getMarketInfo(request, {})
const marketInfo = response.getMarketInfo()
Go
request := &pb.GetMarketInfoRequest{
    FirstCurrency: &pb.OrderbookCurrency{
        Network: &pb.Network{Protocol: 0, ChainId: "0", Name: "Bitcoin"},
        AssetId: "BTC",
    },
    OtherCurrency: &pb.OrderbookCurrency{
        Network: &pb.Network{Protocol: 1, ChainId: "1", Name: "Ethereum"},
        AssetId: "0x0000000000000000000000000000000000000000",
    },
}

response, err := client.GetMarketInfo(context.Background(), request)
if err != nil {
    log.Fatalf("Error: %v", err)
}
marketInfo := response.GetMarketInfo()
Rust
let request = Request::new(GetMarketInfoRequest {
    first_currency: Some(OrderbookCurrency {
        network: Some(Network {
            protocol: 0,
            chain_id: "0".to_string(),
            name: "Bitcoin".to_string(),
        }),
        asset_id: "BTC".to_string(),
    }),
    other_currency: Some(OrderbookCurrency {
        network: Some(Network {
            protocol: 1,
            chain_id: "1".to_string(),
            name: "Ethereum".to_string(),
        }),
        asset_id: "0x0000000000000000000000000000000000000000".to_string(),
    }),
});

let response = client.get_market_info(request).await?.into_inner();
let market_info = response.market_info;

Initialize Market

Initialize a new market for a currency pair.

Method: InitMarket

Parameters:

NameTypeRequiredDescription
first_currencyOrderbookCurrencyYESFirst currency
other_currencyOrderbookCurrencyYESOther currency

Response:

FieldTypeDescription
market_infoMarketInfoMarket info (null if pair is invalid)

Example Request:

TypeScript
const request = new InitMarketRequest()
request.setFirstCurrency({
  network: { protocol: 0, chainId: '0', name: 'Bitcoin' },
  assetId: 'BTC'
})
request.setOtherCurrency({
  network: { protocol: 1, chainId: '1', name: 'Ethereum' },
  assetId: '0x0000000000000000000000000000000000000000'
})

const response = await client.initMarket(request, {})
Go
request := &pb.InitMarketRequest{
    FirstCurrency: &pb.OrderbookCurrency{
        Network: &pb.Network{Protocol: 0, ChainId: "0", Name: "Bitcoin"},
        AssetId: "BTC",
    },
    OtherCurrency: &pb.OrderbookCurrency{
        Network: &pb.Network{Protocol: 1, ChainId: "1", Name: "Ethereum"},
        AssetId: "0x0000000000000000000000000000000000000000",
    },
}

response, err := client.InitMarket(context.Background(), request)
if err != nil {
    log.Fatalf("Error: %v", err)
}
Rust
let request = Request::new(InitMarketRequest {
    first_currency: Some(OrderbookCurrency {
        network: Some(Network {
            protocol: 0,
            chain_id: "0".to_string(),
            name: "Bitcoin".to_string(),
        }),
        asset_id: "BTC".to_string(),
    }),
    other_currency: Some(OrderbookCurrency {
        network: Some(Network {
            protocol: 1,
            chain_id: "1".to_string(),
            name: "Ethereum".to_string(),
        }),
        asset_id: "0x0000000000000000000000000000000000000000".to_string(),
    }),
});

let response = client.init_market(request).await?.into_inner();

Get Initialized Markets

Get all initialized markets.

Method: GetInitializedMarkets

Parameters: None

Response:

FieldTypeDescription
marketsCurrencyInfoPair[]Array of currency pairs

Example Request:

TypeScript
const request = new GetInitializedMarketsRequest()
const response = await client.getInitializedMarkets(request, {})
const markets = response.getMarketsList()
Go
request := &pb.GetInitializedMarketsRequest{}

response, err := client.GetInitializedMarkets(context.Background(), request)
if err != nil {
    log.Fatalf("Error: %v", err)
}
markets := response.GetMarkets()
Rust
let request = Request::new(GetInitializedMarketsRequest {});

let response = client.get_initialized_markets(request).await?.into_inner();
let markets = response.markets;

Get Orderbook

Get the current orderbook state for a market.

Method: GetOrderbook

Parameters:

NameTypeRequiredDescription
baseOrderbookCurrencyYESBase currency
quoteOrderbookCurrencyYESQuote currency

Response:

FieldTypeDescription
orderbookOrderbookOrderbook data (optional)

Orderbook Object:

FieldTypeDescription
infoMarketInfoMarket information
ordersmap<string, LiquidityPosition>Active liquidity orders (order_id → position)

LiquidityPosition Object:

FieldTypeDescription
client_pubkeybytesOrder owner's public key
min_buy_priceDecimalStringMinimum buy price
max_buy_priceDecimalStringMaximum buy price
min_sell_priceDecimalStringMinimum sell price
max_sell_priceDecimalStringMaximum sell price
quote_amountDecimalStringActive quote amount
base_amountDecimalStringActive base amount
inactive_quote_amountDecimalStringInactive quote amount
inactive_base_amountDecimalStringInactive base amount
highest_buy_priceDecimalStringHighest buy price
lowest_sell_priceDecimalStringLowest sell price
remove_on_fillboolRemove order after any fill

Example Request:

TypeScript
const request = new GetOrderbookRequest()
request.setBase({
  network: { protocol: 0, chainId: '0', name: 'Bitcoin' },
  assetId: 'BTC'
})
request.setQuote({
  network: { protocol: 1, chainId: '1', name: 'Ethereum' },
  assetId: '0x0000000000000000000000000000000000000000'
})

const response = await client.getOrderbook(request, {})
const orderbook = response.getOrderbook()
Go
request := &pb.GetOrderbookRequest{
    Base: &pb.OrderbookCurrency{
        Network: &pb.Network{Protocol: 0, ChainId: "0", Name: "Bitcoin"},
        AssetId: "BTC",
    },
    Quote: &pb.OrderbookCurrency{
        Network: &pb.Network{Protocol: 1, ChainId: "1", Name: "Ethereum"},
        AssetId: "0x0000000000000000000000000000000000000000",
    },
}

response, err := client.GetOrderbook(context.Background(), request)
if err != nil {
    log.Fatalf("Error: %v", err)
}
orderbook := response.GetOrderbook()
Rust
let request = Request::new(GetOrderbookRequest {
    base: Some(OrderbookCurrency {
        network: Some(Network {
            protocol: 0,
            chain_id: "0".to_string(),
            name: "Bitcoin".to_string(),
        }),
        asset_id: "BTC".to_string(),
    }),
    quote: Some(OrderbookCurrency {
        network: Some(Network {
            protocol: 1,
            chain_id: "1".to_string(),
            name: "Ethereum".to_string(),
        }),
        asset_id: "0x0000000000000000000000000000000000000000".to_string(),
    }),
});

let response = client.get_orderbook(request).await?.into_inner();
let orderbook = response.orderbook;

Example Response:

{
  "orderbook": {
    "info": { ... },
    "orders": {
      "order_abc123": {
        "client_pubkey": "02abc...",
        "min_buy_price": "27.5",
        "max_buy_price": "28.0",
        "min_sell_price": "28.5",
        "max_sell_price": "29.0",
        "quote_amount": "50000000000000000000",
        "base_amount": "100000000",
        "inactive_quote_amount": "0",
        "inactive_base_amount": "0",
        "highest_buy_price": "28.0",
        "lowest_sell_price": "28.5",
        "remove_on_fill": false
      }
    }
  }
}

Get Orderbook Balances

Get your orderbook balances across all currencies.

Method: GetOrderbookBalances

Parameters: None

Response:

FieldTypeDescription
balancesOrderbookBalance[]Array of balances by currency

OrderbookBalance Object:

FieldTypeDescription
currencyOrderbookCurrencyCurrency identifier
balanceCurrencyBalanceBalance breakdown

CurrencyBalance Object:

FieldTypeDescription
sendingDecimalStringAvailable to send
receivingDecimalStringAvailable to receive
pending_sendingDecimalStringPending sends
pending_receivingDecimalStringPending receives
unavailable_sendingDecimalStringUnavailable for sending
unavailable_receivingDecimalStringUnavailable for receiving
in_use_sendingDecimalStringLocked in active orders (sending)
in_use_receivingDecimalStringLocked in active orders (receiving)

Example Request:

TypeScript
const request = new GetOrderbookBalancesRequest()
const response = await client.getOrderbookBalances(request, {})
const balances = response.getBalancesList()
Go
request := &pb.GetOrderbookBalancesRequest{}

response, err := client.GetOrderbookBalances(context.Background(), request)
if err != nil {
    log.Fatalf("Error: %v", err)
}
balances := response.GetBalances()
Rust
let request = Request::new(GetOrderbookBalancesRequest {});

let response = client.get_orderbook_balances(request).await?.into_inner();
let balances = response.balances;

Estimate Order

Estimate order execution before placing it.

Method: EstimateOrder

Parameters:

NameTypeRequiredDescription
order_variantOrderVariantYESOrder details (one of: AddLiquidity, MarketOrder, SwapOrder)

OrderVariant Types:

AddLiquidity

FieldTypeDescription
baseOrderbookCurrencyBase currency
quoteOrderbookCurrencyQuote currency
min_buy_priceDecimalStringMinimum buy price
mid_priceDecimalStringMiddle price
max_sell_priceDecimalStringMaximum sell price
amountOrderAmountAmount (base or quote)
remove_on_fillboolRemove on any fill

MarketOrder

FieldTypeDescription
baseOrderbookCurrencyBase currency
quoteOrderbookCurrencyQuote currency
amountOrderAmountAmount (base or quote)
sideOrderSideBUY (0) or SELL (1)

SwapOrder

FieldTypeDescription
from_currencyOrderbookCurrencyStarting currency
currency_pathOrderbookCurrency[]Intermediate currencies
to_currencyOrderbookCurrencyDestination currency
amountSwapAmountAmount (sending or receiving)

Response:

FieldTypeDescription
order_matchOrderMatchEstimated execution (optional)

Example Request (Market Order):

TypeScript
const request = new EstimateOrderRequest()
request.setOrderVariant({
  marketOrder: {
    base: {
      network: { protocol: 0, chainId: '0', name: 'Bitcoin' },
      assetId: 'BTC'
    },
    quote: {
      network: { protocol: 1, chainId: '1', name: 'Ethereum' },
      assetId: '0x0000000000000000000000000000000000000000'
    },
    amount: { base: { amount: '1000000' } }, // 0.01 BTC
    side: OrderSide.BUY
  }
})

const response = await client.estimateOrder(request, {})
const match = response.getOrderMatch()
Go
request := &pb.EstimateOrderRequest{
    OrderVariant: &pb.OrderVariant{
        Variant: &pb.OrderVariant_MarketOrder{
            MarketOrder: &pb.MarketOrder{
                Base: &pb.OrderbookCurrency{
                    Network: &pb.Network{Protocol: 0, ChainId: "0", Name: "Bitcoin"},
                    AssetId: "BTC",
                },
                Quote: &pb.OrderbookCurrency{
                    Network: &pb.Network{Protocol: 1, ChainId: "1", Name: "Ethereum"},
                    AssetId: "0x0000000000000000000000000000000000000000",
                },
                Amount: &pb.OrderAmount{
                    Amount: &pb.OrderAmount_Base{
                        Base: &pb.BaseAmount{Amount: "1000000"},
                    },
                },
                Side: pb.OrderSide_BUY,
            },
        },
    },
}

response, err := client.EstimateOrder(context.Background(), request)
if err != nil {
    log.Fatalf("Error: %v", err)
}
match := response.GetOrderMatch()
Rust
use your_package::order_variant::Variant;

let request = Request::new(EstimateOrderRequest {
    order_variant: Some(OrderVariant {
        variant: Some(Variant::MarketOrder(MarketOrder {
            base: Some(OrderbookCurrency {
                network: Some(Network {
                    protocol: 0,
                    chain_id: "0".to_string(),
                    name: "Bitcoin".to_string(),
                }),
                asset_id: "BTC".to_string(),
            }),
            quote: Some(OrderbookCurrency {
                network: Some(Network {
                    protocol: 1,
                    chain_id: "1".to_string(),
                    name: "Ethereum".to_string(),
                }),
                asset_id: "0x0000000000000000000000000000000000000000".to_string(),
            }),
            amount: Some(order_amount::Amount::Base(BaseAmount {
                amount: "1000000".to_string(),
            })),
            side: OrderSide::Buy as i32,
        })),
    }),
});

let response = client.estimate_order(request).await?.into_inner();
let match_result = response.order_match;

Example Request (Add Liquidity):

TypeScript
const request = new EstimateOrderRequest()
request.setOrderVariant({
  addLiquidity: {
    base: { ... },
    quote: { ... },
    minBuyPrice: '27.5',
    midPrice: '28.0',
    maxSellPrice: '28.5',
    amount: { quote: { amount: '50000000000000000000' } }, // 50 ETH
    removeOnFill: false
  }
})

const response = await client.estimateOrder(request, {})
Go
request := &pb.EstimateOrderRequest{
    OrderVariant: &pb.OrderVariant{
        Variant: &pb.OrderVariant_AddLiquidity{
            AddLiquidity: &pb.AddLiquidity{
                Base:         &pb.OrderbookCurrency{...},
                Quote:        &pb.OrderbookCurrency{...},
                MinBuyPrice:  "27.5",
                MidPrice:     "28.0",
                MaxSellPrice: "28.5",
                Amount: &pb.OrderAmount{
                    Amount: &pb.OrderAmount_Quote{
                        Quote: &pb.QuoteAmount{Amount: "50000000000000000000"},
                    },
                },
                RemoveOnFill: false,
            },
        },
    },
}

response, err := client.EstimateOrder(context.Background(), request)
if err != nil {
    log.Fatalf("Error: %v", err)
}
Rust
let request = Request::new(EstimateOrderRequest {
    order_variant: Some(OrderVariant {
        variant: Some(Variant::AddLiquidity(AddLiquidity {
            base: Some(OrderbookCurrency {...}),
            quote: Some(OrderbookCurrency {...}),
            min_buy_price: "27.5".to_string(),
            mid_price: "28.0".to_string(),
            max_sell_price: "28.5".to_string(),
            amount: Some(order_amount::Amount::Quote(QuoteAmount {
                amount: "50000000000000000000".to_string(),
            })),
            remove_on_fill: false,
        })),
    }),
});

let response = client.estimate_order(request).await?.into_inner();

Create Order

Place a new order in the orderbook.

Method: CreateOrder

Parameters:

NameTypeRequiredDescription
order_variantOrderVariantYESOrder details

Response:

FieldTypeDescription
order_idstringUnique order identifier

Example Request:

TypeScript
const request = new CreateOrderRequest()
request.setOrderVariant({
  marketOrder: {
    base: {
      network: { protocol: 0, chainId: '0', name: 'Bitcoin' },
      assetId: 'BTC'
    },
    quote: {
      network: { protocol: 1, chainId: '1', name: 'Ethereum' },
      assetId: '0x0000000000000000000000000000000000000000'
    },
    amount: { base: { amount: '1000000' } },
    side: OrderSide.SELL
  }
})

const response = await client.createOrder(request, {})
const orderId = response.getOrderId()
console.log('Order created:', orderId)
Go
request := &pb.CreateOrderRequest{
    OrderVariant: &pb.OrderVariant{
        Variant: &pb.OrderVariant_MarketOrder{
            MarketOrder: &pb.MarketOrder{
                Base: &pb.OrderbookCurrency{
                    Network: &pb.Network{Protocol: 0, ChainId: "0", Name: "Bitcoin"},
                    AssetId: "BTC",
                },
                Quote: &pb.OrderbookCurrency{
                    Network: &pb.Network{Protocol: 1, ChainId: "1", Name: "Ethereum"},
                    AssetId: "0x0000000000000000000000000000000000000000",
                },
                Amount: &pb.OrderAmount{
                    Amount: &pb.OrderAmount_Base{
                        Base: &pb.BaseAmount{Amount: "1000000"},
                    },
                },
                Side: pb.OrderSide_SELL,
            },
        },
    },
}

response, err := client.CreateOrder(context.Background(), request)
if err != nil {
    log.Fatalf("Error: %v", err)
}
orderId := response.GetOrderId()
fmt.Printf("Order created: %s\n", orderId)
Rust
let request = Request::new(CreateOrderRequest {
    order_variant: Some(OrderVariant {
        variant: Some(Variant::MarketOrder(MarketOrder {
            base: Some(OrderbookCurrency {
                network: Some(Network {
                    protocol: 0,
                    chain_id: "0".to_string(),
                    name: "Bitcoin".to_string(),
                }),
                asset_id: "BTC".to_string(),
            }),
            quote: Some(OrderbookCurrency {
                network: Some(Network {
                    protocol: 1,
                    chain_id: "1".to_string(),
                    name: "Ethereum".to_string(),
                }),
                asset_id: "0x0000000000000000000000000000000000000000".to_string(),
            }),
            amount: Some(order_amount::Amount::Base(BaseAmount {
                amount: "1000000".to_string(),
            })),
            side: OrderSide::Sell as i32,
        })),
    }),
});

let response = client.create_order(request).await?.into_inner();
let order_id = response.order_id;
println!("Order created: {}", order_id);

Cancel Order

Cancel an existing order.

Method: CancelOrder

Parameters:

NameTypeRequiredDescription
order_idstringYESOrder ID to cancel

Response:

FieldTypeDescription
removedboolWhether order was removed

Example Request:

TypeScript
const request = new CancelOrderRequest()
request.setOrderId('order_abc123')

const response = await client.cancelOrder(request, {})
if (response.getRemoved()) {
  console.log('Order cancelled successfully')
}
Go
request := &pb.CancelOrderRequest{
    OrderId: "order_abc123",
}

response, err := client.CancelOrder(context.Background(), request)
if err != nil {
    log.Fatalf("Error: %v", err)
}
if response.GetRemoved() {
    fmt.Println("Order cancelled successfully")
}
Rust
let request = Request::new(CancelOrderRequest {
    order_id: "order_abc123".to_string(),
});

let response = client.cancel_order(request).await?.into_inner();
if response.removed {
    println!("Order cancelled successfully");
}

Cancel All Orders

Cancel all your active orders.

Method: CancelAllOrders

Parameters: None

Response: Empty (success confirmation)

Example Request:

TypeScript
const request = new CancelAllOrdersRequest()
await client.cancelAllOrders(request, {})
console.log('All orders cancelled')
Go
request := &pb.CancelAllOrdersRequest{}

_, err := client.CancelAllOrders(context.Background(), request)
if err != nil {
    log.Fatalf("Error: %v", err)
}
fmt.Println("All orders cancelled")
Rust
let request = Request::new(CancelAllOrdersRequest {});

client.cancel_all_orders(request).await?;
println!("All orders cancelled");

Get Order

Get details of a specific order.

Method: GetOrder

Parameters:

NameTypeRequiredDescription
order_idstringYESOrder ID

Response:

FieldTypeDescription
orderOrderOrder details

Order Object (one of):

PairOrder (LiquidityOrder or MarketOrder)

LiquidityOrder:

FieldTypeDescription
baseOrderbookCurrencyBase currency
quoteOrderbookCurrencyQuote currency
created_atTimestampCreation time
min_buy_priceDecimalStringMin buy price
max_buy_priceDecimalStringMax buy price
min_sell_priceDecimalStringMin sell price
max_sell_priceDecimalStringMax sell price
remaining_base_amountDecimalStringRemaining base
remaining_quote_amountDecimalStringRemaining quote
paid_base_feeDecimalStringFees paid in base
paid_quote_feeDecimalStringFees paid in quote
filledFilledFill details (optional)

MarketOrder:

FieldTypeDescription
baseOrderbookCurrencyBase currency
quoteOrderbookCurrencyQuote currency
created_atTimestampCreation time
remaining_amountOrderAmountRemaining amount
unmatched_amountOrderAmountUnmatched amount
buy or sellBuy or SellExecution details

SwapOrder

FieldTypeDescription
from_currencyOrderbookCurrencySource currency
currency_pathOrderbookCurrency[]Route
to_currencyOrderbookCurrencyDestination currency
created_atTimestampCreation time
remaining_amountSwapAmountRemaining
unmatched_amountSwapAmountUnmatched
sold_from_currency_amountDecimalStringSold amount
bought_to_currency_amountDecimalStringBought amount
paid_to_currency_feeDecimalStringFee paid

Example Request:

TypeScript
const request = new GetOrderRequest()
request.setOrderId('order_abc123')

const response = await client.getOrder(request, {})
const order = response.getOrder()
Go
request := &pb.GetOrderRequest{
    OrderId: "order_abc123",
}

response, err := client.GetOrder(context.Background(), request)
if err != nil {
    log.Fatalf("Error: %v", err)
}
order := response.GetOrder()
Rust
let request = Request::new(GetOrderRequest {
    order_id: "order_abc123".to_string(),
});

let response = client.get_order(request).await?.into_inner();
let order = response.order;

Get Own Orders

Get your orders for a specific market.

Method: GetOwnOrders

Parameters:

NameTypeRequiredDescription
baseOrderbookCurrencyYESBase currency
quoteOrderbookCurrencyYESQuote currency

Response:

FieldTypeDescription
ordersmap<string, Order>Map of order_id → Order

Example Request:

TypeScript
const request = new GetOwnOrdersRequest()
request.setBase({
  network: { protocol: 0, chainId: '0', name: 'Bitcoin' },
  assetId: 'BTC'
})
request.setQuote({
  network: { protocol: 1, chainId: '1', name: 'Ethereum' },
  assetId: '0x0000000000000000000000000000000000000000'
})

const response = await client.getOwnOrders(request, {})
const orders = response.getOrdersMap()
Go
request := &pb.GetOwnOrdersRequest{
    Base: &pb.OrderbookCurrency{
        Network: &pb.Network{Protocol: 0, ChainId: "0", Name: "Bitcoin"},
        AssetId: "BTC",
    },
    Quote: &pb.OrderbookCurrency{
        Network: &pb.Network{Protocol: 1, ChainId: "1", Name: "Ethereum"},
        AssetId: "0x0000000000000000000000000000000000000000",
    },
}

response, err := client.GetOwnOrders(context.Background(), request)
if err != nil {
    log.Fatalf("Error: %v", err)
}
orders := response.GetOrders()
Rust
let request = Request::new(GetOwnOrdersRequest {
    base: Some(OrderbookCurrency {
        network: Some(Network {
            protocol: 0,
            chain_id: "0".to_string(),
            name: "Bitcoin".to_string(),
        }),
        asset_id: "BTC".to_string(),
    }),
    quote: Some(OrderbookCurrency {
        network: Some(Network {
            protocol: 1,
            chain_id: "1".to_string(),
            name: "Ethereum".to_string(),
        }),
        asset_id: "0x0000000000000000000000000000000000000000".to_string(),
    }),
});

let response = client.get_own_orders(request).await?.into_inner();
let orders = response.orders;

Get All Own Orders

Get all your orders across all markets.

Method: GetAllOwnOrders

Parameters: None

Response:

FieldTypeDescription
ordersmap<string, Order>Map of order_id → Order

Example Request:

TypeScript
const request = new GetAllOwnOrdersRequest()
const response = await client.getAllOwnOrders(request, {})
const allOrders = response.getOrdersMap()
Go
request := &pb.GetAllOwnOrdersRequest{}

response, err := client.GetAllOwnOrders(context.Background(), request)
if err != nil {
    log.Fatalf("Error: %v", err)
}
allOrders := response.GetOrders()
Rust
let request = Request::new(GetAllOwnOrdersRequest {});

let response = client.get_all_own_orders(request).await?.into_inner();
let all_orders = response.orders;

Get Trade History

Get public trade history for a market.

Method: GetTradeHistory

Parameters:

NameTypeRequiredDescription
baseOrderbookCurrencyYESBase currency
quoteOrderbookCurrencyYESQuote currency

Response:

FieldTypeDescription
trade_historyTrade[]Trades (sorted newest first)

Trade Object:

FieldTypeDescription
taker_order_idstringTaker's order ID
base_amountDecimalStringBase amount traded
quote_amountDecimalStringQuote amount traded
priceDecimalStringExecution price
final_priceDecimalStringFinal price after fees
timestampTimestampTrade time
maker_order_sideOrderSideMaker side (BUY/SELL)

Example Request:

TypeScript
const request = new GetTradeHistoryRequest()
request.setBase({ ... })
request.setQuote({ ... })

const response = await client.getTradeHistory(request, {})
const trades = response.getTradeHistoryList()
Go
request := &pb.GetTradeHistoryRequest{
    Base:  &pb.OrderbookCurrency{...},
    Quote: &pb.OrderbookCurrency{...},
}

response, err := client.GetTradeHistory(context.Background(), request)
if err != nil {
    log.Fatalf("Error: %v", err)
}
trades := response.GetTradeHistory()
Rust
let request = Request::new(GetTradeHistoryRequest {
    base: Some(OrderbookCurrency {...}),
    quote: Some(OrderbookCurrency {...}),
});

let response = client.get_trade_history(request).await?.into_inner();
let trades = response.trade_history;

Get Pair Market Trades

Get your market trades for a specific pair.

Method: GetPairMarketTrades

Parameters:

NameTypeRequiredDescription
baseOrderbookCurrencyYESBase currency
quoteOrderbookCurrencyYESQuote currency

Response:

FieldTypeDescription
tradesClientMarketTrade[]Your trades (newest first)

ClientMarketTrade Object:

FieldTypeDescription
swap_idstringSwap identifier
order_idstringOrder identifier
base_amountDecimalStringBase amount
quote_amountDecimalStringQuote amount
base_feeDecimalStringFee in base
quote_feeDecimalStringFee in quote
priceDecimalStringPrice
final_priceDecimalStringFinal price
timestampTimestampTrade time
order_sideOrderSideBUY/SELL
order_typeOrderTypeLIMIT/MARKET/LIQUIDITY/SWAP

Example Request:

TypeScript
const request = new GetPairMarketTradesRequest()
request.setBase({ ... })
request.setQuote({ ... })

const response = await client.getPairMarketTrades(request, {})
const trades = response.getTradesList()
Go
request := &pb.GetPairMarketTradesRequest{
    Base:  &pb.OrderbookCurrency{...},
    Quote: &pb.OrderbookCurrency{...},
}

response, err := client.GetPairMarketTrades(context.Background(), request)
if err != nil {
    log.Fatalf("Error: %v", err)
}
trades := response.GetTrades()
Rust
let request = Request::new(GetPairMarketTradesRequest {
    base: Some(OrderbookCurrency {...}),
    quote: Some(OrderbookCurrency {...}),
});

let response = client.get_pair_market_trades(request).await?.into_inner();
let trades = response.trades;

Get All Market Trades

Get all your market trades across all pairs.

Method: GetAllMarketTrades

Parameters: None

Response:

FieldTypeDescription
pair_market_tradesPairMarketTrades[]Trades grouped by pair

Example Request:

TypeScript
const request = new GetAllMarketTradesRequest()
const response = await client.getAllMarketTrades(request, {})
const trades = response.getPairMarketTradesList()
Go
request := &pb.GetAllMarketTradesRequest{}

response, err := client.GetAllMarketTrades(context.Background(), request)
if err != nil {
    log.Fatalf("Error: %v", err)
}
trades := response.GetPairMarketTrades()
Rust
let request = Request::new(GetAllMarketTradesRequest {});

let response = client.get_all_market_trades(request).await?.into_inner();
let trades = response.pair_market_trades;

Get Pair Swap Trades

Get your swap trades for a specific currency pair.

Method: GetPairSwapTrades

Parameters:

NameTypeRequiredDescription
from_currencyOrderbookCurrencyYESSource currency
to_currencyOrderbookCurrencyYESDestination currency

Response:

FieldTypeDescription
tradesClientSwapTrade[]Swap trades (newest first)

ClientSwapTrade Object:

FieldTypeDescription
swap_idstringSwap identifier
order_idstringOrder identifier
from_currency_amountDecimalStringAmount sent
to_currency_amountDecimalStringAmount received
to_currency_feeDecimalStringFee paid
timestampTimestampTrade time

Example Request:

TypeScript
const request = new GetPairSwapTradesRequest()
request.setFromCurrency({ ... })
request.setToCurrency({ ... })

const response = await client.getPairSwapTrades(request, {})
const swapTrades = response.getTradesList()
Go
request := &pb.GetPairSwapTradesRequest{
    FromCurrency: &pb.OrderbookCurrency{...},
    ToCurrency:   &pb.OrderbookCurrency{...},
}

response, err := client.GetPairSwapTrades(context.Background(), request)
if err != nil {
    log.Fatalf("Error: %v", err)
}
swapTrades := response.GetTrades()
Rust
let request = Request::new(GetPairSwapTradesRequest {
    from_currency: Some(OrderbookCurrency {...}),
    to_currency: Some(OrderbookCurrency {...}),
});

let response = client.get_pair_swap_trades(request).await?.into_inner();
let swap_trades = response.trades;

Get All Swap Trades

Get all your swap trades.

Method: GetAllSwapTrades

Parameters: None

Response:

FieldTypeDescription
pair_swap_tradesPairSwapTrades[]Swaps grouped by currency pair

Example Request:

TypeScript
const request = new GetAllSwapTradesRequest()
const response = await client.getAllSwapTrades(request, {})
const allSwaps = response.getPairSwapTradesList()
Go
request := &pb.GetAllSwapTradesRequest{}

response, err := client.GetAllSwapTrades(context.Background(), request)
if err != nil {
    log.Fatalf("Error: %v", err)
}
allSwaps := response.GetPairSwapTrades()
Rust
let request = Request::new(GetAllSwapTradesRequest {});

let response = client.get_all_swap_trades(request).await?.into_inner();
let all_swaps = response.pair_swap_trades;

Subscribe Market Events

Stream real-time market updates.

Method: SubscribeMarketEvents

Parameters:

NameTypeRequiredDescription
baseOrderbookCurrencyYESBase currency
quoteOrderbookCurrencyYESQuote currency

Response: Stream of MarketEvent

MarketEvent Types:

EventDescription
is_syncedInitial sync complete
orderbook_updateOrderbook changed
trade_updateTrade executed
daily_stats_update24h stats updated
candlestick_updateNew candlestick data

Example:

TypeScript
const request = new SubscribeMarketEventsRequest()
request.setBase({ ... })
request.setQuote({ ... })

const stream = client.subscribeMarketEvents(request, {})

stream.on('data', (event) => {
  if (event.hasIsSynced()) {
    console.log('Market synced')
  }
  if (event.hasOrderbookUpdate()) {
    const update = event.getOrderbookUpdate()
    console.log('Orderbook updated:', update)
  }
  if (event.hasTradeUpdate()) {
    const trade = event.getTradeUpdate()
    console.log('Trade:', trade.getBaseAmount(), '@', trade.getPrice())
  }
  if (event.hasDailyStatsUpdate()) {
    const stats = event.getDailyStatsUpdate()
    console.log('24h volume:', stats.getVolatility()?.getBaseVolume())
  }
  if (event.hasCandlestickUpdate()) {
    const candle = event.getCandlestickUpdate()
    console.log('Candle:', candle.getInterval(), candle.getCandlestick())
  }
})

stream.on('error', (err) => console.error('Stream error:', err))
stream.on('end', () => console.log('Stream ended'))
Go
request := &pb.SubscribeMarketEventsRequest{
    Base:  &pb.OrderbookCurrency{...},
    Quote: &pb.OrderbookCurrency{...},
}

stream, err := client.SubscribeMarketEvents(context.Background(), request)
if err != nil {
    log.Fatalf("Error: %v", err)
}

for {
    event, err := stream.Recv()
    if err != nil {
        log.Printf("Stream error: %v", err)
        break
    }

    if event.GetIsSynced() {
        fmt.Println("Market synced")
    }
    if update := event.GetOrderbookUpdate(); update != nil {
        fmt.Printf("Orderbook updated: %v\n", update)
    }
    if trade := event.GetTradeUpdate(); trade != nil {
        fmt.Printf("Trade: %s @ %s\n", trade.GetBaseAmount(), trade.GetPrice())
    }
    if stats := event.GetDailyStatsUpdate(); stats != nil {
        fmt.Printf("24h volume: %s\n", stats.GetVolatility().GetBaseVolume())
    }
    if candle := event.GetCandlestickUpdate(); candle != nil {
        fmt.Printf("Candle: %v %v\n", candle.GetInterval(), candle.GetCandlestick())
    }
}
Rust
use tokio_stream::StreamExt;

let request = Request::new(SubscribeMarketEventsRequest {
    base: Some(OrderbookCurrency {...}),
    quote: Some(OrderbookCurrency {...}),
});

let mut stream = client.subscribe_market_events(request).await?.into_inner();

while let Some(event) = stream.next().await {
    let event = event?;

    if event.is_synced {
        println!("Market synced");
    }
    if let Some(update) = event.orderbook_update {
        println!("Orderbook updated: {:?}", update);
    }
    if let Some(trade) = event.trade_update {
        println!("Trade: {} @ {}", trade.base_amount, trade.price);
    }
    if let Some(stats) = event.daily_stats_update {
        if let Some(vol) = stats.volatility {
            println!("24h volume: {}", vol.base_volume);
        }
    }
    if let Some(candle) = event.candlestick_update {
        println!("Candle: {:?} {:?}", candle.interval, candle.candlestick);
    }
}

Subscribe DEX Events

Stream all your DEX activity (orders, balances, swaps).

Method: SubscribeDexEvents

Parameters: None

Response: Stream of DexEvent

DexEvent Types:

EventDescription
is_syncedInitial sync complete
balance_updateBalance changed
order_updateOrder created/updated/completed/cancelled
order_matchedYour order matched
swap_updateSwap progress update
market_trade_updateMarket trade completed
swap_trade_updateSwap trade completed

Example:

TypeScript
const request = new SubscribeDexEventsRequest()
const stream = client.subscribeDexEvents(request, {})

stream.on('data', (event) => {
  const timestamp = event.getTimestamp()

  if (event.hasBalanceUpdate()) {
    const balance = event.getBalanceUpdate()
    console.log('Balance updated:', balance.getCurrency(), balance.getBalance())
  }

  if (event.hasOrderUpdate()) {
    const update = event.getOrderUpdate()
    if (update.hasOrderCreated()) {
      console.log('Order created:', update.getOrderCreated().getOrderId())
    }
    if (update.hasOrderCompleted()) {
      console.log('Order completed:', update.getOrderCompleted().getOrderId())
    }
  }

  if (event.hasOrderMatched()) {
    const matched = event.getOrderMatched()
    console.log('Order matched:', matched.getOwnOrderId())
    console.log('Is taker:', matched.getIsTaker())
  }

  if (event.hasSwapUpdate()) {
    const swap = event.getSwapUpdate()
    const progress = swap.getProgress()
    console.log('Swap status:', progress.getStatus())
    if (progress.hasError()) {
      console.error('Swap error:', progress.getError())
    }
  }
})
Go
request := &pb.SubscribeDexEventsRequest{}

stream, err := client.SubscribeDexEvents(context.Background(), request)
if err != nil {
    log.Fatalf("Error: %v", err)
}

for {
    event, err := stream.Recv()
    if err != nil {
        log.Printf("Stream error: %v", err)
        break
    }

    timestamp := event.GetTimestamp()

    if balance := event.GetBalanceUpdate(); balance != nil {
        fmt.Printf("Balance updated: %v %v\n",
            balance.GetCurrency(), balance.GetBalance())
    }

    if update := event.GetOrderUpdate(); update != nil {
        if created := update.GetOrderCreated(); created != nil {
            fmt.Printf("Order created: %s\n", created.GetOrderId())
        }
        if completed := update.GetOrderCompleted(); completed != nil {
            fmt.Printf("Order completed: %s\n", completed.GetOrderId())
        }
    }

    if matched := event.GetOrderMatched(); matched != nil {
        fmt.Printf("Order matched: %s\n", matched.GetOwnOrderId())
        fmt.Printf("Is taker: %v\n", matched.GetIsTaker())
    }

    if swap := event.GetSwapUpdate(); swap != nil {
        progress := swap.GetProgress()
        fmt.Printf("Swap status: %v\n", progress.GetStatus())
        if errMsg := progress.GetError(); errMsg != "" {
            fmt.Printf("Swap error: %s\n", errMsg)
        }
    }
}
Rust
use tokio_stream::StreamExt;

let request = Request::new(SubscribeDexEventsRequest {});

let mut stream = client.subscribe_dex_events(request).await?.into_inner();

while let Some(event) = stream.next().await {
    let event = event?;
    let timestamp = event.timestamp;

    if let Some(balance) = event.balance_update {
        println!("Balance updated: {:?} {:?}",
            balance.currency, balance.balance);
    }

    if let Some(update) = event.order_update {
        if let Some(created) = update.order_created {
            println!("Order created: {}", created.order_id);
        }
        if let Some(completed) = update.order_completed {
            println!("Order completed: {}", completed.order_id);
        }
    }

    if let Some(matched) = event.order_matched {
        println!("Order matched: {}", matched.own_order_id);
        println!("Is taker: {}", matched.is_taker);
    }

    if let Some(swap) = event.swap_update {
        if let Some(progress) = swap.progress {
            println!("Swap status: {:?}", progress.status);
            if let Some(error) = progress.error {
                eprintln!("Swap error: {}", error);
            }
        }
    }
}

Enums Reference

OrderSide

ValueDescription
BUY (0)Buy base with quote
SELL (1)Sell base for quote

OrderType

ValueDescription
LIMIT (0)Limit order
LIQUIDITY (1)Liquidity provision order
MARKET (2)Market order
SWAP (3)Multi-hop swap order

SwapStatus

ValueDescription
ORDER_MATCHED (0)Order matched with counterparty
RECEIVING_INVOICE_CREATED (1)Invoice created for receiving
PAYING_INVOICE_RECEIVED (2)Payment invoice received
PAYMENT_SENT (3)Payment sent
PAYMENT_RECEIVED (4)Payment received
PAYMENT_CLAIMED (5)Payment claimed by you
PAYMENT_CLAIMED_BY_COUNTERPARTY (6)Counterparty claimed
SWAP_COMPLETED (7)Swap successful
SWAP_FAILED (8)Swap failed

CandlestickInterval

ValueDescription
ONE_MINUTE (0)1m candles
THREE_MINUTES (1)3m candles
FIVE_MINUTES (2)5m candles
FIFTEEN_MINUTES (3)15m candles
THIRTY_MINUTES (4)30m candles
ONE_HOUR (5)1h candles
TWO_HOURS (6)2h candles
FOUR_HOURS (7)4h candles
SIX_HOURS (8)6h candles
EIGHT_HOURS (9)8h candles
TWELVE_HOURS (10)12h candles
ONE_DAY (11)1d candles
THREE_DAYS (12)3d candles
ONE_WEEK (13)1w candles
ONE_MONTH (14)1M candles

Common Workflows

Place a limit order (liquidity provision)

TypeScript
async function placeLimitOrder(
  client: OrderbookServiceClient,
  base: OrderbookCurrency,
  quote: OrderbookCurrency,
  midPrice: string,
  spreadPercent: number,
  quoteAmount: string
) {
  const spread = parseFloat(midPrice) * (spreadPercent / 100)
  const minBuyPrice = (parseFloat(midPrice) - spread).toString()
  const maxSellPrice = (parseFloat(midPrice) + spread).toString()

  // Estimate first
  const estimateReq = new EstimateOrderRequest()
  estimateReq.setOrderVariant({
    addLiquidity: {
      base,
      quote,
      minBuyPrice,
      midPrice,
      maxSellPrice,
      amount: { quote: { amount: quoteAmount } },
      removeOnFill: false
    }
  })

  const estimate = await client.estimateOrder(estimateReq, {})
  console.log('Estimated match:', estimate.getOrderMatch())

  // Create order
  const createReq = new CreateOrderRequest()
  createReq.setOrderVariant({
    addLiquidity: {
      base,
      quote,
      minBuyPrice,
      midPrice,
      maxSellPrice,
      amount: { quote: { amount: quoteAmount } },
      removeOnFill: false
    }
  })

  const response = await client.createOrder(createReq, {})
  return response.getOrderId()
}

// Example: Provide liquidity at 28 ETH/BTC with 1% spread
const orderId = await placeLimitOrder(
  client,
  btcCurrency,
  ethCurrency,
  '28.0',      // mid price
  1.0,         // 1% spread
  '50000000000000000000' // 50 ETH
)
Go
func placeLimitOrder(
    client pb.OrderbookServiceClient,
    base *pb.OrderbookCurrency,
    quote *pb.OrderbookCurrency,
    midPrice string,
    spreadPercent float64,
    quoteAmount string,
) (string, error) {
    midPriceFloat, _ := strconv.ParseFloat(midPrice, 64)
    spread := midPriceFloat * (spreadPercent / 100)
    minBuyPrice := fmt.Sprintf("%f", midPriceFloat-spread)
    maxSellPrice := fmt.Sprintf("%f", midPriceFloat+spread)

    // Estimate first
    estimateReq := &pb.EstimateOrderRequest{
        OrderVariant: &pb.OrderVariant{
            Variant: &pb.OrderVariant_AddLiquidity{
                AddLiquidity: &pb.AddLiquidity{
                    Base:         base,
                    Quote:        quote,
                    MinBuyPrice:  minBuyPrice,
                    MidPrice:     midPrice,
                    MaxSellPrice: maxSellPrice,
                    Amount: &pb.OrderAmount{
                        Amount: &pb.OrderAmount_Quote{
                            Quote: &pb.QuoteAmount{Amount: quoteAmount},
                        },
                    },
                    RemoveOnFill: false,
                },
            },
        },
    }

    estimate, err := client.EstimateOrder(context.Background(), estimateReq)
    if err != nil {
        return "", err
    }
    fmt.Printf("Estimated match: %v\n", estimate.GetOrderMatch())

    // Create order
    createReq := &pb.CreateOrderRequest{
        OrderVariant: estimateReq.OrderVariant,
    }

    response, err := client.CreateOrder(context.Background(), createReq)
    if err != nil {
        return "", err
    }
    return response.GetOrderId(), nil
}

// Example: Provide liquidity at 28 ETH/BTC with 1% spread
orderId, err := placeLimitOrder(
    client,
    btcCurrency,
    ethCurrency,
    "28.0",                    // mid price
    1.0,                       // 1% spread
    "50000000000000000000",    // 50 ETH
)
Rust
async fn place_limit_order(
    client: &mut OrderbookServiceClient<Channel>,
    base: OrderbookCurrency,
    quote: OrderbookCurrency,
    mid_price: &str,
    spread_percent: f64,
    quote_amount: &str,
) -> Result<String, Box<dyn std::error::Error>> {
    let mid_price_float: f64 = mid_price.parse()?;
    let spread = mid_price_float * (spread_percent / 100.0);
    let min_buy_price = (mid_price_float - spread).to_string();
    let max_sell_price = (mid_price_float + spread).to_string();

    // Estimate first
    let estimate_req = Request::new(EstimateOrderRequest {
        order_variant: Some(OrderVariant {
            variant: Some(Variant::AddLiquidity(AddLiquidity {
                base: Some(base.clone()),
                quote: Some(quote.clone()),
                min_buy_price: min_buy_price.clone(),
                mid_price: mid_price.to_string(),
                max_sell_price: max_sell_price.clone(),
                amount: Some(order_amount::Amount::Quote(QuoteAmount {
                    amount: quote_amount.to_string(),
                })),
                remove_on_fill: false,
            })),
        }),
    });

    let estimate = client.estimate_order(estimate_req).await?.into_inner();
    println!("Estimated match: {:?}", estimate.order_match);

    // Create order
    let create_req = Request::new(CreateOrderRequest {
        order_variant: Some(OrderVariant {
            variant: Some(Variant::AddLiquidity(AddLiquidity {
                base: Some(base),
                quote: Some(quote),
                min_buy_price,
                mid_price: mid_price.to_string(),
                max_sell_price,
                amount: Some(order_amount::Amount::Quote(QuoteAmount {
                    amount: quote_amount.to_string(),
                })),
                remove_on_fill: false,
            })),
        }),
    });

    let response = client.create_order(create_req).await?.into_inner();
    Ok(response.order_id)
}

// Example: Provide liquidity at 28 ETH/BTC with 1% spread
let order_id = place_limit_order(
    &mut client,
    btc_currency,
    eth_currency,
    "28.0",                    // mid price
    1.0,                       // 1% spread
    "50000000000000000000",    // 50 ETH
).await?;

Execute market order

TypeScript
async function buyMarket(
  client: OrderbookServiceClient,
  base: OrderbookCurrency,
  quote: OrderbookCurrency,
  baseAmount: string
) {
  const request = new CreateOrderRequest()
  request.setOrderVariant({
    marketOrder: {
      base,
      quote,
      amount: { base: { amount: baseAmount } },
      side: OrderSide.BUY
    }
  })

  const response = await client.createOrder(request, {})
  return response.getOrderId()
}
Go
func buyMarket(
    client pb.OrderbookServiceClient,
    base *pb.OrderbookCurrency,
    quote *pb.OrderbookCurrency,
    baseAmount string,
) (string, error) {
    request := &pb.CreateOrderRequest{
        OrderVariant: &pb.OrderVariant{
            Variant: &pb.OrderVariant_MarketOrder{
                MarketOrder: &pb.MarketOrder{
                    Base:  base,
                    Quote: quote,
                    Amount: &pb.OrderAmount{
                        Amount: &pb.OrderAmount_Base{
                            Base: &pb.BaseAmount{Amount: baseAmount},
                        },
                    },
                    Side: pb.OrderSide_BUY,
                },
            },
        },
    }

    response, err := client.CreateOrder(context.Background(), request)
    if err != nil {
        return "", err
    }
    return response.GetOrderId(), nil
}
Rust
async fn buy_market(
    client: &mut OrderbookServiceClient<Channel>,
    base: OrderbookCurrency,
    quote: OrderbookCurrency,
    base_amount: &str,
) -> Result<String, Box<dyn std::error::Error>> {
    let request = Request::new(CreateOrderRequest {
        order_variant: Some(OrderVariant {
            variant: Some(Variant::MarketOrder(MarketOrder {
                base: Some(base),
                quote: Some(quote),
                amount: Some(order_amount::Amount::Base(BaseAmount {
                    amount: base_amount.to_string(),
                })),
                side: OrderSide::Buy as i32,
            })),
        }),
    });

    let response = client.create_order(request).await?.into_inner();
    Ok(response.order_id)
}

Multi-hop swap

TypeScript
async function swapBTCtoUSDT(
  client: OrderbookServiceClient,
  amount: string
) {
  // BTC → ETH → USDT
  const request = new CreateOrderRequest()
  request.setOrderVariant({
    swapOrder: {
      fromCurrency: btcCurrency,
      currencyPath: [ethCurrency],
      toCurrency: usdtCurrency,
      amount: { sending: { value: amount } }
    }
  })

  const response = await client.createOrder(request, {})
  return response.getOrderId()
}
Go
func swapBTCtoUSDT(
    client pb.OrderbookServiceClient,
    amount string,
) (string, error) {
    // BTC → ETH → USDT
    request := &pb.CreateOrderRequest{
        OrderVariant: &pb.OrderVariant{
            Variant: &pb.OrderVariant_SwapOrder{
                SwapOrder: &pb.SwapOrder{
                    FromCurrency: btcCurrency,
                    CurrencyPath: []*pb.OrderbookCurrency{ethCurrency},
                    ToCurrency:   usdtCurrency,
                    Amount: &pb.SwapAmount{
                        Amount: &pb.SwapAmount_Sending{
                            Sending: &pb.SendingAmount{Value: amount},
                        },
                    },
                },
            },
        },
    }

    response, err := client.CreateOrder(context.Background(), request)
    if err != nil {
        return "", err
    }
    return response.GetOrderId(), nil
}
Rust
async fn swap_btc_to_usdt(
    client: &mut OrderbookServiceClient<Channel>,
    amount: &str,
) -> Result<String, Box<dyn std::error::Error>> {
    // BTC → ETH → USDT
    let request = Request::new(CreateOrderRequest {
        order_variant: Some(OrderVariant {
            variant: Some(Variant::SwapOrder(SwapOrder {
                from_currency: Some(btc_currency),
                currency_path: vec![eth_currency],
                to_currency: Some(usdt_currency),
                amount: Some(swap_amount::Amount::Sending(SendingAmount {
                    value: amount.to_string(),
                })),
            })),
        }),
    });

    let response = client.create_order(request).await?.into_inner();
    Ok(response.order_id)
}

Best Practices

  1. Always estimate before creating - Use EstimateOrder to verify liquidity
  2. Subscribe to DEX events - Monitor your orders in real-time
  3. Check orderbook balances - Ensure sufficient balance before placing orders
  4. Use liquidity orders for market making - Better fees than market orders
  5. Handle swap failures - Monitor SwapStatus for errors
  6. Cancel stale orders - Remove unfilled orders to free up balance
  7. Use appropriate precision - Respect base_precision and quote_precision

← Back to API Reference | Next: Swap API →


Copyright © 2025