Chuyển đến nội dung chính

Documentation Index

Fetch the complete documentation index at: https://docs.raydium.io/llms.txt

Use this file to discover all available pages before exploring further.

Trang này được dịch tự động bằng AI. Phiên bản tiếng Anh là bản chính thức.Xem bản tiếng Anh →
Raydium Perps là một triển khai có nhãn hiệu trên Orderly Network. Sổ lệnh, công cụ khớp lệnh và trạng thái tài khoản đều nằm trên Orderly. SDK Raydium v2 (@raydium-io/raydium-sdk-v2) không hỗ trợ perps — để truy cập lập trình, hãy dùng REST + WebSocket API của Orderly trực tiếp. Các đoạn mã dưới đây thể hiện những luồng phổ biến nhất; tài liệu chính thức nằm tại orderly.network/docs.
Banner phiên bản.
  • Backend: Orderly Network REST + WebSocket API
  • Schema đoạn mã được xác minh với API của Orderly tính đến tháng 04/2026
  • Cụm Solana để gửi trên chuỗi: mainnet-beta
  • Ký: Ed25519 của Solana trên payload theo kiểu EIP-712 của Orderly (Orderly sử dụng schema EIP-712 ngay cả với các chuỗi không phải EVM; xem tài liệu Orderly để có danh sách trường mới nhất)
API của Orderly liên tục phát triển; hãy kiểm tra orderly.network/docs trước khi sao chép những đoạn mã này vào sản xuất.

Nội dung của trang này

Các luồng dưới đây bao gồm vòng đời liên quan đến nhà tích hợp:
  1. Thiết lập tài khoản — gửi USDC và đăng ký tài khoản với Orderly.
  2. Các lệnh REST được xác thực — yêu cầu ký để đặt lệnh, hủy lệnh và truy vấn tài khoản.
  3. Giao dịch — đặt lệnh thị trường/giới hạn, hủy lệnh, lấy vị thế và lịch sử lệnh.
  4. Dữ liệu thị trường — đăng ký kênh WebSocket của sổ lệnh và giao dịch.
  5. Rút tiền — bắt đầu rút tiền về ví.
Những đoạn mã này nhắm tới Node.js + TypeScript với @solana/web3.jstweetnacl để ký Ed25519. Chúng là điểm khởi đầu — API của Orderly rất rộng và thay đổi nhanh hơn trang này; luôn kiểm tra tài liệu trực tiếp của Orderly trước khi triển khai mã sản xuất.

Thiết lập

import { Connection, Keypair, PublicKey, clusterApiUrl } from "@solana/web3.js";
import nacl from "tweetnacl";
import bs58 from "bs58";
import fs from "node:fs";

// 1. Ví Solana — sở hữu USDC, ký các giao dịch gửi/rút.
const connection = new Connection(process.env.RPC_URL ?? clusterApiUrl("mainnet-beta"));
const owner = Keypair.fromSecretKey(
  new Uint8Array(JSON.parse(fs.readFileSync(process.env.KEYPAIR!, "utf8"))),
);

// 2. Khóa giao dịch Orderly — cặp khóa Ed25519 riêng biệt dùng để ký các yêu cầu API.
//    KHÔNG phải khóa ví Solana. Tạo một lần, giữ kín, tái sử dụng qua các phiên.
const orderlyKey = nacl.sign.keyPair();   // ed25519
const orderlyPubB58 = "ed25519:" + bs58.encode(orderlyKey.publicKey);

// 3. URL cơ sở Orderly. Raydium sử dụng máy chủ mainnet của Orderly.
const ORDERLY_BASE = "https://api.orderly.org";
const BROKER_ID    = "raydium";   // không gian broker của Raydium trên Orderly
const CHAIN_ID     = "solana";    // cho đăng ký tài khoản xuyên chuỗi
Khóa giao dịch Orderly không phải khóa ví của bạn. Đó là khóa ký yêu cầu mà bạn đăng ký với ví của mình khi sử dụng lần đầu; bạn có thể xoay vòng khóa mà không cần chạm vào quỹ. Coi đó là thông tin xác thực phiên.

Đăng ký tài khoản

Trước khi đặt lệnh nào, hãy đăng ký ví với Orderly:
import { encodeUserSettlement } from "./eip712-helpers"; // xem tài liệu Orderly để có payload chính xác

// 1. Yêu cầu nonce đăng ký từ Orderly.
const nonceResp = await fetch(`${ORDERLY_BASE}/v1/registration_nonce`).then(r => r.json());
const registrationNonce = nonceResp.data.registration_nonce;

// 2. Ký payload đăng ký bằng ví Solana (EIP-712 theo kiểu Solana
//    được triển khai như một tin nhắn có cấu trúc; SDK của Orderly cung cấp bộ mã hóa).
const payload = encodeUserSettlement({
  brokerId: BROKER_ID,
  chainId: CHAIN_ID,
  registrationNonce,
  timestamp: Date.now(),
});
const walletSig = nacl.sign.detached(Buffer.from(payload), owner.secretKey);

// 3. Đăng ký, bao gồm khóa giao dịch Ed25519 của Orderly.
const reg = await fetch(`${ORDERLY_BASE}/v1/register_account`, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    message: payload,
    signature: bs58.encode(walletSig),
    userAddress: owner.publicKey.toBase58(),
    orderlyKey: orderlyPubB58,
  }),
}).then(r => r.json());

console.log("Account ID:", reg.data.account_id);
ID tài khoản là xác định cho mỗi cặp (broker_id, wallet_address) — đăng ký là idempotent. Nếu ví đã đăng ký với broker của Raydium, lệnh gọi sẽ trả về cùng một ID tài khoản mà không tạo ID mới.

Gửi USDC

Các lần gửi di chuyển USDC từ ATA ví đến kho bảo quản kế toán của Orderly. Chúng là các giao dịch Solana trên chuỗi:
// Xây dựng ix gửi bằng chương trình Solana của Orderly (ID chương trình kho được
// công bố trong tài liệu; lấy nó động thay vì hard-code).
const vaultProgramId = new PublicKey("<orderly_solana_vault_program_id>");

const depositIx = await buildOrderlyDepositIx({
  vaultProgramId,
  user: owner.publicKey,
  brokerId: BROKER_ID,
  amountUsdc: BigInt(100_000_000),    // 100 USDC (6 chữ số thập phân)
});

const tx = new Transaction().add(depositIx);
const sig = await connection.sendTransaction(tx, [owner]);
await connection.confirmTransaction(sig, "confirmed");
console.log("Deposit tx:", sig);
Sau khoảng ~30 giây, relayer của Orderly sẽ lập chỉ mục lần gửi và số dư sẽ hiển thị dưới lợi nhuận ròng miễn phí của tài khoản. Truy vấn /v1/client/holding để xác nhận:
const holdingResp = await orderlyAuthGet("/v1/client/holding");
console.log("Balances:", holdingResp.data.holding);
(orderlyAuthGet được định nghĩa dưới đây — mọi lệnh gọi được xác thực đều đi qua nó.)

Trợ giúp ký yêu cầu

Mọi lệnh gọi REST được xác thực tới Orderly đều mang chữ ký Ed25519 trên (timestamp + method + path + body):
async function orderlyAuthRequest(
  method: "GET" | "POST" | "PUT" | "DELETE",
  path: string,
  body?: unknown,
): Promise<any> {
  const ts   = Date.now().toString();
  const json = body ? JSON.stringify(body) : "";
  const msg  = `${ts}${method}${path}${json}`;
  const sig  = nacl.sign.detached(Buffer.from(msg), orderlyKey.secretKey);

  const resp = await fetch(ORDERLY_BASE + path, {
    method,
    headers: {
      "Content-Type": "application/json",
      "orderly-account-id":  /* account_id đã đăng ký */ "",
      "orderly-key":         orderlyPubB58,
      "orderly-signature":   bs58.encode(sig),
      "orderly-timestamp":   ts,
    },
    body: json || undefined,
  });
  return resp.json();
}

const orderlyAuthGet  = (p: string)            => orderlyAuthRequest("GET",  p);
const orderlyAuthPost = (p: string, b: object) => orderlyAuthRequest("POST", p, b);
const orderlyAuthDel  = (p: string)            => orderlyAuthRequest("DELETE", p);
Bảo vệ chống phát lại: các yêu cầu có timestamp chênh lệch từ đồng hồ máy chủ hơn 5 giây sẽ bị từ chối. Đồng bộ đồng hồ của bạn (NTP) và tránh ký yêu cầu trước.

Đặt lệnh thị trường

const marketResp = await orderlyAuthPost("/v1/order", {
  symbol:        "PERP_SOL_USDC",
  order_type:    "MARKET",
  side:          "BUY",
  order_quantity: 1.0,        // 1 SOL vị thế
  reduce_only:    false,
});

if (marketResp.success) {
  console.log("Order ID:", marketResp.data.order_id);
} else {
  console.error("Reject:", marketResp.message);
}
Lệnh thị trường thực thi ngay lập tức. Phản hồi trả về order_id kết quả cùng với trạng thái. Các lệnh thực hiện đến qua WebSocket (xem bên dưới); phản hồi REST chính nó không chặn cho đến khi hoàn toàn lấp đầy.

Đặt lệnh giới hạn với Post-Only

const limitResp = await orderlyAuthPost("/v1/order", {
  symbol:         "PERP_SOL_USDC",
  order_type:     "LIMIT",
  side:           "SELL",
  order_quantity: 0.5,
  order_price:    140.50,
  // kết hợp cờ:
  // post_only: true làm cho đây là lệnh chỉ maker — hủy nếu nó sẽ giao nhau.
  // reduce_only / time_in_force có thể đặt độc lập.
  post_only:      true,
});
console.log(limitResp);
Để IOC / FOK, đặt time_in_force: "IOC" hoặc "FOK". Xem products/perps/order-types để hiểu ngữ nghĩa của mỗi cờ.

Hủy lệnh

// Theo ID lệnh
await orderlyAuthDel(`/v1/order?order_id=${orderId}&symbol=PERP_SOL_USDC`);

// Hủy TẤT CẢ lệnh trên một ký hiệu
await orderlyAuthDel(`/v1/orders?symbol=PERP_SOL_USDC`);
Một lệnh hủy được xác nhận đồng bộ nhưng việc hủy thực tế có thể xảy ra cùng lúc với một lần lấp đầy. Luôn đối chiếu bằng cách thăm dò /v1/orders hoặc xem WebSocket — giả định lệnh hủy thành công mà không xác nhận có thể dẫn đến vị thế trùng lặp hoặc không mong muốn.

Lấy vị thế mở

const posResp = await orderlyAuthGet("/v1/positions");
for (const p of posResp.data.rows) {
  console.log(
    p.symbol,
    "size:",  p.position_qty,
    "entry:", p.average_open_price,
    "unrealized:", p.unsettled_pnl,
  );
}
position_qty âm là short, dương là long. position_qty == 0 có nghĩa vị thế bị đóng nhưng hàng vẫn có thể xuất hiện cho đến lần dọn dẹp tiếp theo.

Lấy lịch sử lệnh thực hiện

const fills = await orderlyAuthGet(
  "/v1/trades?symbol=PERP_SOL_USDC&start_t=" + (Date.now() - 86_400_000)
);
for (const t of fills.data.rows) {
  console.log(t.executed_timestamp, t.side, t.executed_quantity, "@", t.executed_price);
}
Các đối số thời gian là dấu thời gian Unix tính bằng mili giây. Kích thước trang mặc định là 25 hàng; sử dụng các tham số truy vấn pagesize để phân trang.

WebSocket: dữ liệu thị trường

import WebSocket from "ws";

const ws = new WebSocket(`wss://ws.orderly.org/ws/stream/${accountId}`);

ws.on("open", () => {
  // Dữ liệu thị trường công khai: delta sổ lệnh + giao dịch cho một ký hiệu
  ws.send(JSON.stringify({ id: "ob1", topic: "orderbook@PERP_SOL_USDC" }));
  ws.send(JSON.stringify({ id: "tr1", topic: "trade@PERP_SOL_USDC" }));
});

ws.on("message", (raw) => {
  const msg = JSON.parse(raw.toString());
  if (msg.topic?.startsWith("orderbook@")) {
    // delta độ sâu: { bids: [[price, qty], ...], asks: [[price, qty], ...] }
    applyOrderbookDelta(msg.data);
  } else if (msg.topic?.startsWith("trade@")) {
    console.log("trade:", msg.data);
  }
});
Đối với luồng riêng tư (các lệnh thực hiện, cập nhật vị thế và thay đổi số dư của bạn), WebSocket phải được xác thực. Gửi payload subscribe được ký theo cách tương tự như yêu cầu REST, có phạm vi cho ID tài khoản của bạn. Tài liệu của Orderly có hình dạng payload chính xác; nó thay đổi thỉnh thoảng, vì vậy đừng hard-code một schema cụ thể ở đây.

Rút USDC

// 1. Yêu cầu rút tiền.
const wRes = await orderlyAuthPost("/v1/withdraw_request", {
  token:  "USDC",
  chain_id: CHAIN_ID,
  amount: 50.0,                          // đơn vị con người
  receiver: owner.publicKey.toBase58(),
});

console.log("Withdrawal request id:", wRes.data.withdraw_id);
Orderly chuyển tiếp lệnh rút tiền trên chuỗi đến địa chỉ người nhận. Có phí rút tiền 1 USDC cố định (xem products/perps/fees). Chuyển tiền trên chuỗi xảy ra trong vòng 1–2 phút trong điều kiện bình thường; dự kiến sẽ lâu hơn trong thời gian tắc nghẽn.

Những cạm bẫy

  • Đừng tái sử dụng khóa giao dịch trên các môi trường. Một khóa giao dịch Orderly duy nhất được đăng ký với ví của bạn được liên kết với một tài khoản mainnet Solana. Nếu bạn cũng cần devnet hoặc staging, hãy tạo khóa riêng cho mỗi khóa.
  • Đồng bộ thời gian. Dung sai chênh lệch đồng hồ của Orderly rất chặt (±5 giây). Trên các dịch vụ chạy lâu dài, độ trôi NTP cuối cùng sẽ phá vỡ việc ký. Đồng bộ định kỳ.
  • Kết nối lại WebSocket. WebSocket công khai thỉnh thoảng đóng kết nối khi nâng cấp Orderly. Triển khai thoái lui theo cấp số nhân và tái đăng ký khi mở lại.
  • Giới hạn tỷ lệ. Các lệnh gọi REST bị giới hạn tỷ lệ phân tầng theo tài khoản. Hủy hàng loạt qua cancel_all thay vì vòng cancel-by-id khi bạn có >5 lệnh để hủy.
  • Hướng vị thế là ngầm. Lệnh BUY trên PERP_SOL_USDC mở hoặc mở rộng một long; lệnh SELL mở hoặc mở rộng một short — nhưng nếu bạn đã ở long, lệnh SELL sẽ giảm (và có thể lật) vị thế vì Raydium Perps ở chế độ một chiều. Luôn kiểm tra vị thế hiện tại trước khi đặt lệnh nếu hướng quan trọng.
  • Tài trợ và thanh lý tách biệt với luồng lệnh. Các khoản thanh toán tài trợ và thanh lý xuất hiện dưới dạng các luồng sự kiện riêng biệt; chúng không phải “lệnh”. Đăng ký các chủ đề WS riêng tư liên quan nếu bạn cần quan sát chúng.

Tiếp theo đi đâu

Nguồn:
  • Tài liệu nhà phát triển Orderly Network — tài liệu tham khảo chính thức cho API được sử dụng ở trên. Raydium Perps sử dụng trực tiếp.
  • SDK TypeScript Orderly — bao bọc cùng một lớp REST/WebSocket với các trợ giúp được nhập; hữu ích nếu bạn muốn bỏ qua việc viết lớp ký cho riêng mình.