Orderly Sdk Trading Workflows
by @tarnadas
Complete trading workflows for Orderly Network DEX applications, from wallet connection through order execution, position management, and withdrawal.
clawhub install orderly-sdk-trading-workflowsπ About This Skill
name: orderly-sdk-trading-workflows description: Complete trading workflows for Orderly Network DEX applications, from wallet connection through order execution, position management, and withdrawal.
Orderly Network: SDK Trading Workflows
A comprehensive guide to implementing complete trading workflows in Orderly Network DEX applications, from wallet connection through order execution and position management.
When to Use
Prerequisites
Overview
This skill covers end-to-end trading workflows:
1. Connect β Wallet connection and authentication 2. Deposit β Fund your Orderly account 3. Trade β Place and manage orders 4. Monitor β Track positions and PnL 5. Withdraw β Move funds back to wallet
Complete Trading Flow
ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ
β Connect ββββββΆβ Deposit ββββββΆβ Trade β
β Wallet β β Funds β β (Orders) β
ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ
β
βΌ
ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ
β Withdraw βββββββ Close βββββββ Monitor β
β Funds β β Positions β β Positions β
ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ
1. Connect & Authenticate
Check Account State
import { useAccount, AccountStatusEnum } from '@orderly.network/hooks';function TradingGuard({ children }) {
const { state, createAccount, createOrderlyKey } = useAccount();
switch (state.status) {
case AccountStatusEnum.NotConnected:
return ;
case AccountStatusEnum.Connected:
return (
Create your Orderly account to start trading
); case AccountStatusEnum.NotSignedIn:
return (
Enable trading by creating your trading key
); case AccountStatusEnum.SignedIn:
return children;
}
}
Using AuthGuard (Simpler)
import { AuthGuard } from '@orderly.network/ui-connector';function TradingPage() {
return (
);
}
2. Deposit Funds
Using useDeposit Hook
import { useDeposit } from '@orderly.network/hooks';function DepositForm() {
const { deposit, balance, allowance, approve, isNativeToken, quantity, setQuantity, depositFee } =
useDeposit({
address: '0xUSDC_ADDRESS',
decimals: 6,
srcChainId: 42161,
srcToken: 'USDC',
});
const handleDeposit = async () => {
try {
// Check and approve if needed
if (!isNativeToken && allowance < quantity) {
await approve();
}
// Execute deposit
const result = await deposit();
toast.success('Deposit successful!');
} catch (error) {
toast.error(error.message);
}
};
return (
setQuantity(e.target.value)} placeholder="Amount" />
Balance: {balance} USDC
Fee: {depositFee} USDC
);
}
Using DepositForm Component
import { DepositForm } from '@orderly.network/ui-transfer';function DepositPage() {
return (
{
toast.success('Deposited successfully!');
}}
/>
);
}
3. Check Account Balance
Using useCollateral
import { useCollateral } from '@orderly.network/hooks';function AccountBalance() {
const { totalCollateral, freeCollateral, totalValue, availableBalance, unsettledPnL } =
useCollateral({ dp: 2 });
return (
Total Value: ${totalValue}
Free Collateral: ${freeCollateral}
Unsettled PnL: ${unsettledPnL}
);
}
4. Place Orders
Market Order
import { useMutation } from '@orderly.network/hooks';
import { OrderType, OrderSide } from '@orderly.network/types';function MarketOrderButton({ symbol, side, quantity }) {
const [submitOrder] = useMutation('/v1/order');
const placeMarketOrder = async () => {
const order = {
symbol,
side,
order_type: OrderType.MARKET,
order_quantity: quantity,
};
try {
const result = await submitOrder(order);
if (result.success) {
toast.success(Order placed: ${result.data.order_id});
}
} catch (error) {
toast.error(error.message);
}
};
return (
);
}
Limit Order
function LimitOrderForm({ symbol }) {
const [submitOrder] = useMutation('/v1/order');
const [price, setPrice] = useState('');
const [quantity, setQuantity] = useState('');
const [side, setSide] = useState(OrderSide.BUY); const placeLimitOrder = async () => {
const order = {
symbol,
side,
order_type: OrderType.LIMIT,
order_price: parseFloat(price),
order_quantity: parseFloat(quantity),
};
const result = await submitOrder(order);
if (result.success) {
toast.success('Limit order placed!');
}
};
return (
setPrice(e.target.value)} />
setQuantity(e.target.value)} />
);
}
Using useOrderEntry (Recommended)
import { useOrderEntry } from '@orderly.network/hooks';
import { OrderSide, OrderType } from '@orderly.network/types';function OrderEntryForm({ symbol }) {
const { formattedOrder, submit, maxQty, freeCollateral, errors, setValues } =
useOrderEntry(symbol);
useEffect(() => {
setValues({
side: OrderSide.BUY,
order_type: OrderType.LIMIT,
});
}, []);
const handleSubmit = async () => {
if (Object.keys(errors).length > 0) {
toast.error('Please fix validation errors');
return;
}
try {
await submit();
toast.success('Order submitted!');
} catch (error) {
toast.error(error.message);
}
};
return (
setValues({ order_price: e.target.value })}
error={errors.order_price}
/>
setValues({ order_quantity: e.target.value })}
error={errors.order_quantity}
/>
Max: {maxQty}
Available: ${freeCollateral}
);
}
5. Monitor Orders
Active Orders
import { useOrderStream } from '@orderly.network/hooks';function ActiveOrders({ symbol }) {
const [orders, { refresh }] = useOrderStream({
symbol,
status: 'OPEN',
});
return (
,
},
]}
data={orders}
/>
);
}
Cancel Order
import { useMutation } from '@orderly.network/hooks';function useCancelOrder() {
const [cancel] = useMutation('/v1/order', 'DELETE');
return async (orderId: string, symbol: string) => {
const result = await cancel({
order_id: orderId,
symbol,
});
return result;
};
}
6. Monitor Positions
Real-time Position Stream
import { usePositionStream } from '@orderly.network/hooks';function PositionsTable({ symbol }) {
const [positions, positionInfo, { loading }] = usePositionStream(symbol);
return (
(
= 0 ? 'success' : 'danger'}>${getValue().toFixed(2)}
),
},
]}
data={positions}
/>
);
}
7. Close Positions
Close Specific Position
import { useMutation } from '@orderly.network/hooks';
import { OrderType, OrderSide } from '@orderly.network/types';function ClosePositionButton({ position }) {
const [submitOrder] = useMutation('/v1/order');
const closePosition = async () => {
const order = {
symbol: position.symbol,
side: position.position_qty > 0 ? OrderSide.SELL : OrderSide.BUY,
order_type: OrderType.MARKET,
order_quantity: Math.abs(position.position_qty),
reduce_only: true,
};
const result = await submitOrder(order);
if (result.success) {
toast.success('Position closed!');
}
};
return (
);
}
8. Withdraw Funds
Using useWithdraw Hook
import { useWithdraw } from '@orderly.network/hooks';function WithdrawForm() {
const { withdraw, maxAmount, availableWithdraw, unsettledPnL } = useWithdraw({
srcChainId: 42161,
token: 'USDC',
decimals: 6,
});
const [amount, setAmount] = useState('');
const handleWithdraw = async () => {
try {
await withdraw(parseFloat(amount));
toast.success('Withdrawal initiated!');
} catch (error) {
toast.error(error.message);
}
};
return (
setAmount(e.target.value)} placeholder="Amount" />
Available: {availableWithdraw} USDC
Max: {maxAmount} USDC
);
}
9. Leverage Management
Get/Set Leverage
import { useLeverage } from '@orderly.network/hooks';function LeverageControl() {
const { curLeverage, maxLeverage, leverageLevers, update, isLoading } = useLeverage();
const changeLeverage = async (newLeverage: number) => {
try {
await update({ leverage: newLeverage });
toast.success(Leverage set to ${newLeverage}x);
} catch (error) {
toast.error(error.message);
}
};
return (
Current: {curLeverage}x
changeLeverage(v)}
min={1}
max={maxLeverage}
/>
);
}
10. Risk Monitoring
Margin Ratio
import { useMarginRatio } from '@orderly.network/hooks';function RiskIndicator() {
const { marginRatio, mmr, currentLeverage } = useMarginRatio();
const isAtRisk = marginRatio < mmr * 1.5;
return (
Margin Ratio: {(marginRatio * 100).toFixed(2)}%
MMR: {(mmr * 100).toFixed(2)}%
{isAtRisk && Approaching Liquidation }
);
}
Complete Trading Page Example
import { useState } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import { TradingPage } from '@orderly.network/trading';
import { AuthGuard } from '@orderly.network/ui-connector';
import { API } from '@orderly.network/types';export default function Trading() {
const { symbol } = useParams();
const navigate = useNavigate();
const onSymbolChange = (data: API.Symbol) => {
navigate(/trade/${data.symbol});
};
return (
);
}
Error Handling Patterns
Order-Specific Errors
import { useOrderEntry } from '@orderly.network/hooks';function OrderForm() {
const { errors, submit } = useOrderEntry('PERP_ETH_USDC');
const handleSubmit = async () => {
if (errors.order_price) {
toast.error(Price: ${errors.order_price});
return;
}
try {
await submit();
} catch (error) {
if (error.code === 'INSUFFICIENT_BALANCE') {
toast.error('Insufficient balance. Please deposit more funds.');
} else if (error.code === 'RISK_TOO_HIGH') {
toast.error('Order rejected: would exceed risk limits.');
} else {
toast.error(error.message);
}
}
};
}
Best Practices
1. Always Check Auth Before Trading
const { state } = useAccount();
if (state.status !== AccountStatusEnum.SignedIn) {
return {children} ;
}
2. Validate Orders Before Submission
const { errors, validated } = metaState;
if (!validated || Object.keys(errors).length > 0) {
// Don't submit
}
3. Use Real-time Streams for Position Data
// Good - real-time updates
const [positions] = usePositionStream();
4. Handle Loading States
if (isLoading) return ;
if (error) return ;
5. Show Execution Feedback
toast.loading('Submitting order...');
try {
await submit();
toast.success('Order placed!');
} catch (e) {
toast.error(e.message);
}
Related Skills
β‘ When to Use
βοΈ Configuration
π Tips & Best Practices
1. Always Check Auth Before Trading
const { state } = useAccount();
if (state.status !== AccountStatusEnum.SignedIn) {
return {children} ;
}
2. Validate Orders Before Submission
const { errors, validated } = metaState;
if (!validated || Object.keys(errors).length > 0) {
// Don't submit
}
3. Use Real-time Streams for Position Data
// Good - real-time updates
const [positions] = usePositionStream();
4. Handle Loading States
if (isLoading) return ;
if (error) return ;
5. Show Execution Feedback
toast.loading('Submitting order...');
try {
await submit();
toast.success('Order placed!');
} catch (e) {
toast.error(e.message);
}