> ## 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.

# Démos de code Perps

> Accès programmatique à Raydium Perps via l'API d'Orderly Network : déposer l'USDC, enregistrer le compte de trading, placer / annuler / modifier les ordres, récupérer les positions, s'abonner au WebSocket du marché et se retirer.

<Info>
  **Cette page est traduite automatiquement par IA. La version anglaise fait foi.**

  [Voir la version anglaise →](/products/perps/code-demos)
</Info>

<Info>
  **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](https://orderly.network/docs/build-on-omnichain/evm-api/introduction).
</Info>

<Info>
  **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](https://orderly.network/docs/build-on-omnichain/evm-api/introduction) avant de copier ces extraits dans la production.
</Info>

## 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

```ts theme={null}
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 :

```ts theme={null}
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 :

```ts theme={null}
// 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 :

```ts theme={null}
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)` :

```ts theme={null}
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é

```ts theme={null}
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

```ts theme={null}
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`](/fr/products/perps/order-types) pour la sémantique de chaque drapeau.

## Annuler un ordre

```ts theme={null}
// 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

```ts theme={null}
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

```ts theme={null}
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é

```ts theme={null}
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

```ts theme={null}
// 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`](/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

* [`/fr/products/perps/trading-basics`](/fr/products/perps/trading-basics) — l'amorce conceptuelle sur la mécanique des perpétuels.
* [`/fr/products/perps/order-types`](/fr/products/perps/order-types) — la sémantique de chaque type d'ordre et drapeau.
* [`/fr/products/perps/collateral`](/fr/products/perps/collateral) — les actifs de garantie supportés et les limites par chaîne.
* [`/fr/products/perps/fees`](/fr/products/perps/fees) — les calendriers maker/taker et les frais de retrait.

Sources :

* [Documentation du développeur Orderly Network](https://orderly.network/docs/build-on-omnichain/evm-api/introduction) — référence canonique pour la surface de l'API utilisée ci-dessus. Raydium Perps la consomme directement.
* [SDK TypeScript Orderly](https://github.com/OrderlyNetwork/orderly-sdk-js) — enveloppe la même couche REST/WebSocket avec des aides typées ; utile si vous voulez ignorer l'écriture de la couche de signature vous-même.
