Passer au contenu principal

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.

Cette page est traduite automatiquement par IA. La version anglaise fait foi.Voir la version anglaise →
Raydium Perps est un déploiement white-label sur Orderly Network. Le carnet d’ordres, le moteur d’appariement et l’état du compte résident tous sur Orderly. Le SDK Raydium v2 (@raydium-io/raydium-sdk-v2) ne couvre pas les perps — pour l’accès programmatique, utilisez directement l’API REST + WebSocket d’Orderly. Les extraits ci-dessous montrent les flux les plus courants ; la référence canonique se trouve à orderly.network/docs.
Banneau de version.
  • Backend : API REST + WebSocket d’Orderly Network
  • Schéma des extraits vérifié par rapport à l’API d’Orderly à partir d’avril 2026
  • Cluster Solana pour les dépôts en chaîne : mainnet-beta
  • Signature : Ed25519 Solana sur la charge utile de style EIP-712 d’Orderly (Orderly utilise un schéma EIP-712 même pour les chaînes non-EVM ; consultez la documentation d’Orderly pour la liste des champs la plus récente)
La surface de l’API d’Orderly évolue ; consultez orderly.network/docs avant de copier ces extraits dans la production.

Ce que contient cette page

Les flux ci-dessous couvrent le cycle de vie pertinent pour l’intégrateur :
  1. Configuration du compte — déposer l’USDC et enregistrer le compte auprès d’Orderly.
  2. Appels REST authentifiés — demander la signature pour le placement, l’annulation et les requêtes de compte.
  3. Trading — placement d’ordres au marché / limités, annulation, récupération des positions et des remplissages.
  4. Données de marché — abonnement au carnet d’ordres et au WebSocket des transactions.
  5. Retrait — lancer un retrait vers le portefeuille.
Ces extraits ciblent Node.js + TypeScript avec @solana/web3.js et tweetnacl pour la signature Ed25519. Ce sont des points de départ — la surface de l’API d’Orderly est large et change plus vite que cette page ; consultez toujours la documentation en direct d’Orderly avant de déployer du code en production.

Configuration

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

// 1. Solana wallet — owns USDC, signs deposit/withdrawal transactions.
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. Orderly trading key — separate Ed25519 keypair used to sign API requests.
//    NOT the Solana wallet. Generate once, keep secret, reuse across sessions.
const orderlyKey = nacl.sign.keyPair();   // ed25519
const orderlyPubB58 = "ed25519:" + bs58.encode(orderlyKey.publicKey);

// 3. Orderly base URL. Raydium uses Orderly's mainnet host.
const ORDERLY_BASE = "https://api.orderly.org";
const BROKER_ID    = "raydium";   // Raydium's broker namespace on Orderly
const CHAIN_ID     = "solana";    // for cross-chain account registration
La clé de trading Orderly n’est pas votre clé de portefeuille. C’est une clé de signature de requête que vous enregistrez par rapport à votre portefeuille à la première utilisation ; vous pouvez la faire tourner sans toucher aux fonds. Traitez-la comme une credential de session.

Enregistrement du compte

Avant de placer un quelconque ordre, enregistrez le portefeuille auprès d’Orderly :
import { encodeUserSettlement } from "./eip712-helpers"; // see Orderly docs for the exact payload

// 1. Request a registration nonce from Orderly.
const nonceResp = await fetch(`${ORDERLY_BASE}/v1/registration_nonce`).then(r => r.json());
const registrationNonce = nonceResp.data.registration_nonce;

// 2. Sign a registration payload with the Solana wallet (EIP-712-style on Solana
//    is implemented as a structured message; Orderly's SDK provides the encoder).
const payload = encodeUserSettlement({
  brokerId: BROKER_ID,
  chainId: CHAIN_ID,
  registrationNonce,
  timestamp: Date.now(),
});
const walletSig = nacl.sign.detached(Buffer.from(payload), owner.secretKey);

// 3. Register, including the Orderly Ed25519 trading key.
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);
Les identifiants de compte sont déterministes par paire (broker_id, wallet_address) — l’enregistrement est idempotent. Si un portefeuille a déjà été enregistré auprès du broker de Raydium, l’appel retourne le même identifiant de compte sans en créer un nouveau.

Déposer l’USDC

Les dépôts déplacent l’USDC du wallet ATA au coffre-fort de règlement d’Orderly. Ce sont des transactions Solana en chaîne :
// Build the deposit ix using Orderly's Solana program (vault program ID is
// published in their docs; pull it dynamically rather than hard-coding).
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 decimals)
});

const tx = new Transaction().add(depositIx);
const sig = await connection.sendTransaction(tx, [owner]);
await connection.confirmTransaction(sig, "confirmed");
console.log("Deposit tx:", sig);
Après environ 30 secondes, le relayeur d’Orderly indexe le dépôt et le solde apparaît sous la marge libre du compte. Interrogez /v1/client/holding pour confirmer :
const holdingResp = await orderlyAuthGet("/v1/client/holding");
console.log("Balances:", holdingResp.data.holding);
(orderlyAuthGet est défini ci-dessous — chaque appel authentifié passe par lui.)

Aide à la signature des requêtes

Chaque appel REST authentifié à Orderly porte une signature Ed25519 sur (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":  /* the registered account_id */ "",
      "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);
Protection contre la relecture : les requêtes avec un timestamp déphasé de plus de 5 secondes par rapport à l’horloge du serveur sont rejetées. Synchronisez votre horloge (NTP) et évitez de signer les requêtes à l’avance.

Placer un ordre au marché

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

if (marketResp.success) {
  console.log("Order ID:", marketResp.data.order_id);
} else {
  console.error("Reject:", marketResp.message);
}
Les ordres au marché s’exécutent immédiatement. La réponse retourne l’order_id résultant plus un statut. Les remplissages arrivent via le WebSocket (voir ci-dessous) ; la réponse REST elle-même ne bloque pas jusqu’à ce qu’elle soit complètement remplie.

Placer un ordre limité avec 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,
  // flag combinations:
  // post_only: true makes this a maker-only order — cancels if it would cross.
  // reduce_only / time_in_force are independently settable.
  post_only:      true,
});
console.log(limitResp);
Pour IOC / FOK, définissez time_in_force: "IOC" ou "FOK". Voir /fr/products/perps/order-types pour la sémantique de chaque drapeau.

Annuler un ordre

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

// Cancel ALL orders on a symbol
await orderlyAuthDel(`/v1/orders?symbol=PERP_SOL_USDC`);
Une annulation est reconnue de manière synchrone, mais l’annulation réelle peut être en concurrence avec un remplissage. Réconciliez toujours en interrogeant /v1/orders ou en observant le WebSocket — supposer qu’une annulation a réussi sans confirmation peut entraîner des positions dupliquées ou involontaires.

Récupérer les positions ouvertes

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,
  );
}
Une position_qty négative est un short, positive est un long. position_qty == 0 signifie que la position est fermée mais la ligne peut toujours être présente jusqu’au prochain nettoyage.

Récupérer l’historique des remplissages

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);
}
Les arguments de temps sont des timestamps Unix en millisecondes. La taille de page par défaut est 25 lignes ; utilisez les paramètres de requête page et size pour paginer.

WebSocket : données de marché

import WebSocket from "ws";

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

ws.on("open", () => {
  // Public market data: orderbook deltas + trades for one symbol
  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@")) {
    // depth diff: { bids: [[price, qty], ...], asks: [[price, qty], ...] }
    applyOrderbookDelta(msg.data);
  } else if (msg.topic?.startsWith("trade@")) {
    console.log("trade:", msg.data);
  }
});
Pour le flux privé (vos remplissages, mises à jour de position, changements de solde), le WebSocket doit être authentifié. Envoyez une charge utile subscribe signée de la même manière que les requêtes REST, délimitée à votre identifiant de compte. La documentation d’Orderly contient la forme exacte de la charge utile ; elle change occasionnellement, donc ne codez pas en dur un schéma particulier ici.

Retirer l’USDC

// 1. Request a withdrawal.
const wRes = await orderlyAuthPost("/v1/withdraw_request", {
  token:  "USDC",
  chain_id: CHAIN_ID,
  amount: 50.0,                          // human units
  receiver: owner.publicKey.toBase58(),
});

console.log("Withdrawal request id:", wRes.data.withdraw_id);
Orderly relaie le retrait en chaîne vers l’adresse du destinataire. Il y a un frais de retrait forfaitaire de 1 USDC (voir /fr/products/perps/fees). Le transfert en chaîne se produit dans 1–2 minutes dans les conditions normales ; attendez-vous à plus long pendant la congestion.

Pièges

  • Ne réutilisez pas la clé de trading dans les environnements. Une seule clé de trading Orderly enregistrée auprès de votre portefeuille est associée à un compte Solana mainnet. Si vous avez également besoin de devnet ou de staging, générez une clé séparée pour chacun.
  • Synchronisation de l’horloge. La tolérance de déphasage horaire d’Orderly est serrée (±5s). Sur les services longue durée, la dérive NTP finira par casser la signature. Resynchronisez périodiquement.
  • Reconnexions WebSocket. Le WS public abandonne occasionnellement les connexions pendant les mises à jour d’Orderly. Implémentez un backoff exponentiel et réabonnez-vous à la réouverture.
  • Limites de débit. Les appels REST sont limités par taux par compte. Annulez en masse via cancel_all plutôt que de boucler cancel-par-id quand vous avez plus de 5 ordres à annuler.
  • La direction de la position est implicite. Un ordre BUY sur PERP_SOL_USDC ouvre ou prolonge un long ; un SELL ouvre ou prolonge un short — mais si vous êtes déjà long, un SELL réduit (et peut retourner) la position car Raydium Perps est en mode à sens unique. Vérifiez toujours la position actuelle avant de placer un ordre si la direction compte.
  • Le financement et les liquidations sont séparés du flux d’ordres. Les paiements de financement et les liquidations apparaissent comme des flux d’événements séparés ; ce ne sont pas des « ordres ». Abonnez-vous aux rubriques privées WS pertinentes si vous avez besoin de les observer.

Où aller ensuite

Sources :