Skip to main content

Integration guide

Use this page when you want exact steps instead of a function-by-function reference. The Getting Started page explains the SDK surface area, and the Exports pages document individual helpers. This page focuses on common workflows and the operational details that matter in production.

What SDK v1 covers today

SDK v1 (GmxSdk) is the full client. It reads markets, tokens, positions, orders, trades, and account delegates, and it submits or cancels orders through a connected wallet.

WorkflowStatusNotes
Read market, token, position, order, and trade dataAvailable through markets, tokens, positions, orders, trades, and accounts
Submit and cancel ordersAvailable through orders.long, orders.short, orders.swap, create*Order, and cancelOrders
Built-in transaction receipt pollingOrder methods return a transaction hash; your app must wait for receipts and refetch state
Built-in idempotency keys or client order IDsPrevent duplicate submits in your app layer
Automatic retry and backoff for RPC reads⚠️Default viem HTTP clients are created with retryCount: 0

Read account state for one wallet

Use one market and token snapshot across the whole read flow. This avoids mixing data from different polls when you render positions, active orders, and recent trades together.

import { GmxSdk } from "@gmx-io/sdk";

const sdk = new GmxSdk({
chainId: 42161,
rpcUrl: "https://arb1.arbitrum.io/rpc",
oracleUrl: "https://arbitrum-api.gmxinfra.io",
subsquidUrl: "https://gmx.squids.live/gmx-synthetics-arbitrum:prod/api/graphql",
});

sdk.setAccount("0x9f7198eb1b9Ccc0Eb7A07eD228d8FbC12963ea33");

const { marketsInfoData, tokensData } = await sdk.markets.getMarketsInfo();

if (!marketsInfoData || !tokensData) {
throw new Error("Failed to load market snapshot");
}

const [{ positionsData }, { ordersInfoData }, trades] = await Promise.all([
sdk.positions.getPositions({
marketsData: marketsInfoData,
tokensData,
}),
sdk.orders.getOrders({
marketsInfoData,
tokensData,
}),
sdk.trades.getTradeHistory({
pageSize: 25,
pageIndex: 0,
marketsInfoData,
tokensData,
}),
]);

console.log({
positions: Object.values(positionsData ?? {}),
orders: Object.values(ordersInfoData ?? {}),
recentTrades: trades,
});

Open a Market Increase order

If you want the SDK to calculate swap paths, fees, and order amounts for you, start with the quick helper methods. The helper returns a transaction hash after submission. After that, you still need to wait for the receipt and refetch positions or orders.

import { GmxSdk } from "@gmx-io/sdk";
import { createWalletClient, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { arbitrum } from "viem/chains";

const account = privateKeyToAccount("0x...your-private-key");

const walletClient = createWalletClient({
account,
chain: arbitrum,
transport: http("https://arb1.arbitrum.io/rpc"),
});

const sdk = new GmxSdk({
chainId: 42161,
rpcUrl: "https://arb1.arbitrum.io/rpc",
oracleUrl: "https://arbitrum-api.gmxinfra.io",
subsquidUrl: "https://gmx.squids.live/gmx-synthetics-arbitrum:prod/api/graphql",
walletClient,
account: account.address,
});

const txHash = await sdk.orders.long({
payAmount: 100031302n,
marketAddress: "0x70d95587d40A2caf56bd97485aB3Eec10Bee6336",
payTokenAddress: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
collateralTokenAddress: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
allowedSlippageBps: 125,
leverage: 50000n,
});

const receipt = await sdk.publicClient.waitForTransactionReceipt({ hash: txHash });

if (receipt.status !== "success") {
throw new Error("Order transaction reverted");
}

const { marketsInfoData, tokensData } = await sdk.markets.getMarketsInfo();
const { ordersInfoData } = await sdk.orders.getOrders({
marketsInfoData: marketsInfoData!,
tokensData: tokensData!,
});

console.log("Submitted tx:", txHash);
console.log("Active orders:", Object.keys(ordersInfoData));

Cancel active orders

Fetch the latest active orders first, then cancel by on-chain order key. This matters if your UI lets the user cancel and replace orders quickly.

const { marketsInfoData, tokensData } = await sdk.markets.getMarketsInfo();

if (!marketsInfoData || !tokensData) {
throw new Error("Failed to load market snapshot");
}

const { ordersInfoData } = await sdk.orders.getOrders({
marketsInfoData,
tokensData,
});

const orderKeys = Object.keys(ordersInfoData);

if (orderKeys.length === 0) {
throw new Error("No active orders to cancel");
}

const txHash = await sdk.orders.cancelOrders(orderKeys);
await sdk.publicClient.waitForTransactionReceipt({ hash: txHash });

const refreshed = await sdk.orders.getOrders({
marketsInfoData,
tokensData,
});

console.log("Remaining orders:", Object.keys(refreshed.ordersInfoData));

Operational notes

Data freshness and consistency

  • Quick helpers fetch marketsInfoData and tokensData for you when you do not pass them in.
  • If your app already has a fresh snapshot, pass the same marketsInfoData and tokensData through the whole flow. This gives you a more consistent view than mixing independent reads.
  • After a write, treat reads as eventually consistent. Transaction submission, order creation, keeper execution, and indexed reads do not complete at the same time.

Simulation behavior

  • Market increases simulate before submit unless you pass skipSimulation: true.
  • Limit increases skip simulation in the current implementation.
  • Market swaps simulate before submit. Limit Swap orders do not.
  • createDecreaseOrder() currently sets skipSimulation: true. If you expose that flow, validate inputs before submit and handle chain-level failures explicitly.

Retries and timeouts

  • The default viem HTTP clients created by GmxSdk disable transport retries with retryCount: 0.
  • SDK multicalls use a 40000 ms timeout.
  • Add your own retry and backoff policy around read paths that can be repeated safely. Persist transaction hashes from write paths so you can recover after client restarts.

Idempotency and race conditions

  • SDK v1 order methods do not take idempotency keys or client-generated order IDs.
  • Disable duplicate submit actions in your UI while a transaction is pending.
  • When you cancel or replace orders, refetch active orders just before choosing orderKeys.

Next steps

  • Go back to Getting Started for constructor options and module reference.
  • See Examples for smaller focused snippets.
  • Use Exports when you need lower-level helpers such as fee estimation, price impact, or custom trade amount calculation.