mcpField
O
orderly-sdk-trading-workflows

orderly-sdk-trading-workflows

github.com/orderlynetwork开发250 次安装4 天前更新
代码仓库

关于 orderly-sdk-trading-workflows

这项技能说明如何使用 Orderly SDK 完成从账户连接、存款到下单、监控仓位、平仓和提现的交易流程。它面向构建交易界面的开发者,涵盖 SDK hooks 自定义 UI,并介绍推荐的 TradingPage 组件。

主要功能

  1. 01账户连接与身份验证
  2. 02存款和余额流程
  3. 03下单与订单监控
  4. 04仓位监控与平仓
  5. 05提现和杠杆控制
  6. 06保证金与风险监控

适用场景

  1. 01构建完整交易界面
  2. 02实现存款到提现流程
  3. 03创建自定义订单和仓位 UI
  4. 04监控订单、仓位与保证金

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/orderlynetwork/skills --skill orderly-sdk-trading-workflows

安装后在 Claude Code 中输入/orderly-sdk-trading-workflows确认已加载。

详细介绍

Orderly Network:SDK 交易工作流

端到端交易工作流:连接 → 存款 → 交易 → 监控 → 平仓 → 提现。

适用场景

  • 构建完整的交易界面
  • 实现存款 → 交易 → 提现流程
  • 基于 SDK 钩子构建自定义订单/仓位 UI

前提条件

  • 已安装 Orderly SDK 软件包(参见 orderly-sdk-install-dependency)
  • 已配置钱包连接(参见 orderly-sdk-wallet-connection)
  • 使用 OrderlyAppProvider 包装应用

概述

Connect → Deposit → Trade → Monitor → Close → Withdraw

推荐方式:参考 DEX 不会手动编写交易流程,而是渲染 <TradingPage>(来自 @orderly.network/trading)。它已包含图表、订单簿、下单界面、仓位和订单管理。下面基于钩子的代码适用于自定义交易 UI,即替换 TradingPage 的部分内容。

1. 连接并验证身份

AccountStatusEnum 从 @orderly.network/types 导出(而非 hooks)。完整状态机的说明参见 orderly-sdk-wallet-connection。

import { useAccount } from '@orderly.network/hooks';
import { AccountStatusEnum } from '@orderly.network/types';

function TradingGuard({ children }: { children: React.ReactNode }) {
  const { state, createAccount, createOrderlyKey } = useAccount();

  switch (state.status) {
    case AccountStatusEnum.NotConnected:
      return <ConnectWalletPrompt />;
    case AccountStatusEnum.Connected:
      return <button onClick={() => createAccount()}>Create Orderly Account</button>;
    case AccountStatusEnum.NotSignedIn:
      return <button onClick={() => createOrderlyKey()}>Enable Trading</button>;
    default:
      return <>{children}</>;
  }
}
AuthGuard

对于自定义 UI,可使用 AuthGuard(来自 @orderly.network/ui-connector)控制内容的访问权限。注意:TradingPage 会自行管理身份验证提示,因此不要使用 AuthGuard 包装它。

import { AuthGuard } from '@orderly.network/ui-connector';

<AuthGuard>{/* protected custom UI */}</AuthGuard>;

2. 存款

useDeposit

deposit() 不接受任何参数——它会提交通过 setQuantity 设置的金额。如果代币不是原生代币,请先批准 ERC-20 授权额度。

import { useDeposit } from '@orderly.network/hooks';
import { toast } from '@orderly.network/ui';

function DepositForm() {
  const { balance, allowance, approve, deposit, quantity, setQuantity, depositFee, isNativeToken } =
    useDeposit({
      srcChainId: 42161,
      srcToken: 'USDC',
      address: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',
      decimals: 6,
    });

  const handleDeposit = async () => {
    setQuantity('100');
    try {
      // Approve if allowance is insufficient (allowance is a wei string)
      if (!isNativeToken) await approve();
      await deposit();
      toast.success('Deposit submitted');
    } catch (e) {
      toast.error((e as Error).message);
    }
  };

  return (
    <div>
      <input value={quantity} onChange={(e) => setQuantity(e.target.value)} placeholder="Amount" />
      <p>Wallet balance: {balance}</p>
      <p>Deposit fee (wei): {depositFee?.toString()}</p>
      <button onClick={handleDeposit}>Deposit</button>
    </div>
  );
}

depositFee 是 bigint(单位为 wei)。如需完整的样式化体验,请使用预构建表单(来自 @orderly.network/ui-transfer 的 DepositForm/DepositFormWidget)。

3. 查看账户余额

import { useCollateral } from '@orderly.network/hooks';

function AccountSummary() {
  const { totalValue, freeCollateral, availableBalance, unsettledPnL } = useCollateral({ dp: 2 });
  // totalValue: number | null — total portfolio value
  // freeCollateral: available for new positions
  // availableBalance: withdrawable
  // unsettledPnL: unrealized PnL across positions
}

4. 下单

推荐方式:TradingPage
import { TradingPage } from '@orderly.network/trading';
<TradingPage symbol="PERP_BTC_USDC" tradingViewConfig={config.tradingPage.tradingViewConfig} />;
自定义 UI:useOrderEntry

使用 setValue/setValues 设置订单字段(键:side、order_type、order_price、order_quantity、reduce_only、tp_trigger_price、sl_price),进行验证,然后调用 submit()。验证状态位于 metaState 中(而非顶层的 errors)。

import { useOrderEntry } from '@orderly.network/hooks';
import { OrderSide, OrderType } from '@orderly.network/types';

function OrderForm({ symbol }: { symbol: string }) {
  const { submit, setValues, setValue, helper, isMutating, metaState, formattedOrder } =
    useOrderEntry(symbol);

  useEffect(() => {
    setValues({ side: OrderSide.BUY, order_type: OrderType.LIMIT });
  }, [symbol]);

  const handleSubmit = async () => {
    const result = await helper.validate();
    if (result) return; // validation issues are in metaState.errors
    try {
      await submit({ resetOnSuccess: true });
      toast.success('Order submitted');
    } catch (e) {
      toast.error((e as Error).message);
    }
  };

  return (
    <form
      onSubmit={(e) => {
        e.preventDefault();
        handleSubmit();
      }}
    >
      <input
        placeholder="Price"
        value={formattedOrder.order_price ?? ''}
        onChange={(e) => setValue('order_price', e.target.value)}
      />
      <input
        placeholder="Quantity"
        value={formattedOrder.order_quantity ?? ''}
        onChange={(e) => setValue('order_quantity', e.target.value)}
      />
      <button type="submit" disabled={isMutating}>
        {isMutating ? 'Placing…' : 'Buy'}
      </button>
    </form>
  );
}
底层方式:useMutation

对于非 Orderly 下单流程(例如机器人),可直接提交。这不是 DEX 模板使用的方式。

import { useMutation } from '@orderly.network/hooks';
import { OrderType, OrderSide } from '@orderly.network/types';

const [submitOrder] = useMutation('/v1/order');
await submitOrder({
  symbol,
  side,
  order_type: OrderType.MARKET,
  order_quantity: quantity,
});

5. 监控并取消订单

useOrderStream 返回 [orders, actions]。请使用 OrderStatus 枚举,而不要使用字符串 'OPEN'(未完成订单的状态为 OrderStatus.INCOMPLETE)。

import { useOrderStream } from '@orderly.network/hooks';
import { OrderStatus } from '@orderly.network/types';

function OpenOrders({ symbol }: { symbol?: string }) {
  const [orders, { cancelOrder, cancelAllPendingOrders }] = useOrderStream({
    status: OrderStatus.INCOMPLETE,
    symbol,
  });
  return (
    <div>
      <button onClick={() => cancelAllPendingOrders(symbol)}>Cancel All</button>
      {(orders ?? []).map((o) => (
        <div key={o.order_id}>
          {o.symbol} {o.side} {o.order_quantity} @ {o.order_price}
          <button onClick={() => cancelOrder(o.order_id, o.symbol)}>✕</button>
        </div>
      ))}
    </div>
  );
}

6. 监控仓位

usePositionStream 返回一个包含 3 个元素的元组 [positions, calc, status]。第三个元素提供 isLoading(而非 loading)。

import { usePositionStream } from '@orderly.network/hooks';

function PositionsTable() {
  const [positions, , { isLoading }] = usePositionStream();
  return (
    <table>
      {(positions?.rows ?? []).map((p) => (
        <tr key={p.symbol}>
          <td>{p.symbol}</td>
          <td>{p.position_qty}</td>
          <td>{p.average_open_price}</td>
          <td>{p.mark_price}</td>
          <td className={p.unrealized_pnl >= 0 ? 'profit' : 'loss'}>
            {p.unrealized_pnl?.toFixed(2)}
          </td>
        </tr>
      ))}
    </table>
  );
}

7. 平仓

通过 useOrderEntry 提交一笔减少仓位的市价单(设置 reduce_only: true,并选择相反方向):

const { setValues, submit } = useOrderEntry(position.symbol);
await setValues({
  side: position.position_qty > 0 ? OrderSide.SELL : OrderSide.BUY,
  order_type: OrderType.MARKET,
  order_quantity: Math.abs(position.position_qty),
  reduce_only: true,
});
await submit();

也可以使用 usePositionClose 或仓位组件的平仓操作,一次性完成平仓。

8. 提现

useWithdraw 返回 withdraw(inputs)——传入完整的 inputs 对象(而非单独的金额)。请使用 maxAmount(不要使用已弃用的 availableWithdraw)。

import { useWithdraw } from '@orderly.network/hooks';

const { withdraw, maxAmount, unsettledPnL, availableBalance, dst } = useWithdraw({
  srcChainId: 42161,
  token: 'USDC',
  decimals: 6,
});

await withdraw({
  chainId: 42161,
  token: 'USDC',
  amount: '100',
  allowCrossChainWithdraw: false,
  receiver: '0x…', // optional
});

如需样式化 UI,请使用来自 @orderly.network/ui-transfer 的 WithdrawForm/WithdrawWidget。

9. 杠杆

账户级杠杆(useLeverage)不按交易品种区分。对于当前交易品种,请使用 useSymbolLeverage。

import { useLeverage, useSymbolLeverage } from '@orderly.network/hooks';

// Account-level
const { curLeverage, maxLeverage, update, isLoading } = useLeverage();
await update({ leverage: 5 });

// Symbol-level (preferred on the trading page)
const { maxLeverage, update: setSymbolLeverage } = useSymbolLeverage(symbol);
await setSymbolLeverage({ leverage: 5, symbol });

10. 风险监控

import { useMarginRatio } from '@orderly.network/hooks';
const { marginRatio, mmr, currentLeverage, maintenanceMargin } = useMarginRatio();

完整交易页面(推荐)

模板中的交易页面只需使用 useOrderlyConfig() 提供的配置来渲染 TradingPage——无需手动添加身份验证守卫,也无需手动连接下单逻辑:

// app/pages/perp/Symbol.tsx
import { TradingPage } from '@orderly.network/trading';
import { useOrderlyConfig } from '@/utils/config';

export default function PerpSymbol() {
  const params = useParams();
  const [symbol, setSymbol] = useState(params.symbol!);
  const config = useOrderlyConfig();
  return (
    <TradingPage
      symbol={symbol}
      onSymbolChange={(data) => {
        setSymbol(data.symbol);
        navigate(`/perp/${data.symbol}`);
      }}
      tradingViewConfig={config.tradingPage.tradingViewConfig}
      sharePnLConfig={config.tradingPage.sharePnLConfig}
    />
  );
}

路由为 /perp/:symbol(而非 /trade)。

最佳实践

  1. 除非需要深度自定义,否则优先使用 TradingPage,而不是手动编写订单/仓位 UI。
  2. 对于未完成订单流,使用 OrderStatus 枚举(INCOMPLETE),不要使用字符串 'OPEN'。
  3. 使用 useOrderEntry 时,从 metaState 读取验证状态(metaState.errors、metaState.validated)。
  4. 存入非原生 ERC-20 代币前先批准授权额度;检查 isNativeToken。
  5. 调用 withdraw() 时传入完整的 inputs 对象,并使用 maxAmount 作为可提现上限。

相关技能

  • orderly-sdk-wallet-connection - 钱包 + 账户状态机
  • orderly-sdk-react-hooks - 完整的 Hook 参考
  • orderly-sdk-page-components - TradingPage 和投资组合页面
  • orderly-trading-orders - 订单管理(REST API)
  • orderly-positions-tpsl - 仓位管理(REST API)
  • orderly-deposit-withdraw - 资金管理(REST API)

评论

支持 Markdown