Perpetual Trading

Updated

The SDK provides seven perpetual trading primitives for protocols like Hyperliquid, GMX, Drift, Jupiter, and others.

ConstantType StringPurpose
PRIMITIVE_PERP_OPEN"perp_open"Open a new position
PRIMITIVE_PERP_CLOSE"perp_close"Close an existing position
PRIMITIVE_PERP_INCREASE"perp_increase"Increase position size
PRIMITIVE_PERP_DECREASE"perp_decrease"Decrease position size
PRIMITIVE_PERP_DEPOSIT"perp_deposit"Deposit margin collateral
PRIMITIVE_PERP_WITHDRAW"perp_withdraw"Withdraw margin collateral
PRIMITIVE_PERP_SET_LEVERAGE"perp_set_leverage"Adjust leverage multiplier

Each primitive has typed params including chain, protocol, market, side, size, leverage, collateral, stop_loss, take_profit, and more.

Open a Long Position

perp-open-long.ts
import {
  Chaos,
  WALLET_MODEL,
  extractPrimitives,
  isPerpOpenPrimitive,
  PRIMITIVE_PERP_OPEN,
} from '@chaoslabs/ai-sdk';
 
const chaos = new Chaos({ apiKey: process.env.CHAOS_API_KEY! });
 
const response = await chaos.chat.responses.create({
  model: WALLET_MODEL,
  input: [
    {
      type: 'message',
      role: 'user',
      content: 'Open a 5x long ETH-PERP position with $1000 on Hyperliquid',
    },
  ],
  metadata: {
    user_id: 'user-1',
    session_id: 'session-1',
    wallets: [{ address: '0xYourWallet', chain: 'ethereum' }],
  },
});
 
// Extract and type-narrow perp_open primitives
const primitives = extractPrimitives(response);
 
for (const primitive of primitives) {
  if (isPerpOpenPrimitive(primitive)) {
    // TypeScript knows this is PerpOpenPrimitive
    console.log('Open position:');
    console.log('  Protocol:', primitive.params.protocol);
    console.log('  Market:', primitive.params.market);
    console.log('  Side:', primitive.params.side);
    console.log('  Size:', primitive.params.size);
    console.log('  Leverage:', primitive.params.leverage);
    console.log('  Chain:', primitive.params.chain);
  }
}

Close a Position

perp-close.ts
import {
  Chaos,
  WALLET_MODEL,
  extractPrimitives,
  isPerpClosePrimitive,
} from '@chaoslabs/ai-sdk';
 
const chaos = new Chaos({ apiKey: process.env.CHAOS_API_KEY! });
 
const response = await chaos.chat.responses.create({
  model: WALLET_MODEL,
  input: [
    {
      type: 'message',
      role: 'user',
      content: 'Close my ETH-PERP position on Hyperliquid',
    },
  ],
  metadata: {
    user_id: 'user-1',
    session_id: 'session-1',
    wallets: [{ address: '0xYourWallet', chain: 'ethereum' }],
  },
});
 
const primitives = extractPrimitives(response);
 
for (const primitive of primitives) {
  if (isPerpClosePrimitive(primitive)) {
    console.log('Close position:');
    console.log('  Protocol:', primitive.params.protocol);
    console.log('  Market:', primitive.params.market);
    console.log('  Percentage:', primitive.params.percentage ?? '100%');
  }
}

Increase / Decrease Position Size

perp-adjust-size.ts
import {
  Chaos,
  WALLET_MODEL,
  extractPrimitives,
  isPerpIncreasePrimitive,
  isPerpDecreasePrimitive,
} from '@chaoslabs/ai-sdk';
 
const chaos = new Chaos({ apiKey: process.env.CHAOS_API_KEY! });
 
const response = await chaos.chat.responses.create({
  model: WALLET_MODEL,
  input: [
    {
      type: 'message',
      role: 'user',
      content: 'Increase my BTC-PERP long by $500 on Hyperliquid',
    },
  ],
  metadata: {
    user_id: 'user-1',
    session_id: 'session-1',
    wallets: [{ address: '0xYourWallet', chain: 'ethereum' }],
  },
});
 
for (const primitive of extractPrimitives(response)) {
  if (isPerpIncreasePrimitive(primitive)) {
    console.log('Increase position:');
    console.log('  Market:', primitive.params.market);
    console.log('  Additional size:', primitive.params.size);
    console.log('  Collateral:', primitive.params.collateral);
  }
 
  if (isPerpDecreasePrimitive(primitive)) {
    console.log('Decrease position:');
    console.log('  Market:', primitive.params.market);
    console.log('  Percentage:', primitive.params.percentage);
  }
}

Deposit and Withdraw Margin

perp-margin.ts
import {
  Chaos,
  WALLET_MODEL,
  extractPrimitives,
  isPerpDepositPrimitive,
  isPerpWithdrawPrimitive,
} from '@chaoslabs/ai-sdk';
 
const chaos = new Chaos({ apiKey: process.env.CHAOS_API_KEY! });
 
// Deposit margin
const depositResponse = await chaos.chat.responses.create({
  model: WALLET_MODEL,
  input: [
    {
      type: 'message',
      role: 'user',
      content: 'Deposit $2000 USDC margin to Hyperliquid',
    },
  ],
  metadata: {
    user_id: 'user-1',
    session_id: 'session-1',
    wallets: [{ address: '0xYourWallet', chain: 'ethereum' }],
  },
});
 
for (const primitive of extractPrimitives(depositResponse)) {
  if (isPerpDepositPrimitive(primitive)) {
    console.log('Deposit margin:');
    console.log('  Amount:', primitive.params.amount);
    console.log('  Chain:', primitive.params.chain);
  }
}
 
// Withdraw margin
const withdrawResponse = await chaos.chat.responses.create({
  model: WALLET_MODEL,
  input: [
    {
      type: 'message',
      role: 'user',
      content: 'Withdraw $500 from my Hyperliquid margin',
    },
  ],
  metadata: {
    user_id: 'user-1',
    session_id: 'session-2',
    wallets: [{ address: '0xYourWallet', chain: 'ethereum' }],
  },
});
 
for (const primitive of extractPrimitives(withdrawResponse)) {
  if (isPerpWithdrawPrimitive(primitive)) {
    console.log('Withdraw margin:');
    console.log('  Amount:', primitive.params.amount);
  }
}

Set Leverage

perp-leverage.ts
import {
  Chaos,
  WALLET_MODEL,
  extractPrimitives,
  isPerpSetLeveragePrimitive,
} from '@chaoslabs/ai-sdk';
 
const chaos = new Chaos({ apiKey: process.env.CHAOS_API_KEY! });
 
const response = await chaos.chat.responses.create({
  model: WALLET_MODEL,
  input: [
    {
      type: 'message',
      role: 'user',
      content: 'Set my ETH-PERP leverage to 10x on Hyperliquid',
    },
  ],
  metadata: {
    user_id: 'user-1',
    session_id: 'session-1',
    wallets: [{ address: '0xYourWallet', chain: 'ethereum' }],
  },
});
 
for (const primitive of extractPrimitives(response)) {
  if (isPerpSetLeveragePrimitive(primitive)) {
    console.log('Set leverage:');
    console.log('  Market:', primitive.params.market);
    console.log('  Leverage:', primitive.params.leverage);
  }
}

Filter All Perp Primitives

Use the category-level helpers when you want to handle all perp operations at once.

perp-filter-all.ts
import {
  Chaos,
  WALLET_MODEL,
  extractPrimitives,
  isPerpPrimitive,
  PERP_PRIMITIVES,
} from '@chaoslabs/ai-sdk';
 
const chaos = new Chaos({ apiKey: process.env.CHAOS_API_KEY! });
 
const response = await chaos.chat.responses.create({
  model: WALLET_MODEL,
  input: [
    {
      type: 'message',
      role: 'user',
      content: 'Open a 3x long ETH position and deposit $5000 margin on Hyperliquid',
    },
  ],
  metadata: {
    user_id: 'user-1',
    session_id: 'session-1',
    wallets: [{ address: '0xYourWallet', chain: 'ethereum' }],
  },
});
 
// Category check: is this any perp primitive?
const allPrimitives = extractPrimitives(response);
const perpPrimitives = allPrimitives.filter(p => isPerpPrimitive(p.type));
 
console.log(`Found ${perpPrimitives.length} perp primitives:`);
for (const p of perpPrimitives) {
  console.log(`  ${p.type} on ${p.params.protocol}`);
}
 
// Available perp primitive types for reference
console.log('\nAll perp primitive types:', PERP_PRIMITIVES);
// => ['perp_open', 'perp_close', 'perp_increase', 'perp_decrease',
//     'perp_deposit', 'perp_withdraw', 'perp_set_leverage']
[@portabletext/react] Unknown block type "callout", specify a component for it in the `components.types` prop
Was this helpful?