@zeroexcore/trader 1.1.4 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. package/dist/cli.js +4 -0
  2. package/dist/cli.js.map +1 -1
  3. package/dist/commands/dca/cancel.d.ts +3 -0
  4. package/dist/commands/dca/cancel.d.ts.map +1 -0
  5. package/dist/commands/dca/cancel.js +44 -0
  6. package/dist/commands/dca/cancel.js.map +1 -0
  7. package/dist/commands/dca/create.d.ts +3 -0
  8. package/dist/commands/dca/create.d.ts.map +1 -0
  9. package/dist/commands/dca/create.js +88 -0
  10. package/dist/commands/dca/create.js.map +1 -0
  11. package/dist/commands/dca/index.d.ts +3 -0
  12. package/dist/commands/dca/index.d.ts.map +1 -0
  13. package/dist/commands/dca/index.js +10 -0
  14. package/dist/commands/dca/index.js.map +1 -0
  15. package/dist/commands/dca/list.d.ts +3 -0
  16. package/dist/commands/dca/list.d.ts.map +1 -0
  17. package/dist/commands/dca/list.js +48 -0
  18. package/dist/commands/dca/list.js.map +1 -0
  19. package/dist/commands/limit/cancel.d.ts +3 -0
  20. package/dist/commands/limit/cancel.d.ts.map +1 -0
  21. package/dist/commands/limit/cancel.js +45 -0
  22. package/dist/commands/limit/cancel.js.map +1 -0
  23. package/dist/commands/limit/create.d.ts +3 -0
  24. package/dist/commands/limit/create.d.ts.map +1 -0
  25. package/dist/commands/limit/create.js +68 -0
  26. package/dist/commands/limit/create.js.map +1 -0
  27. package/dist/commands/limit/index.d.ts +3 -0
  28. package/dist/commands/limit/index.d.ts.map +1 -0
  29. package/dist/commands/limit/index.js +10 -0
  30. package/dist/commands/limit/index.js.map +1 -0
  31. package/dist/commands/limit/list.d.ts +3 -0
  32. package/dist/commands/limit/list.d.ts.map +1 -0
  33. package/dist/commands/limit/list.js +40 -0
  34. package/dist/commands/limit/list.js.map +1 -0
  35. package/dist/commands/perps/close.d.ts +3 -0
  36. package/dist/commands/perps/close.d.ts.map +1 -0
  37. package/dist/commands/perps/close.js +48 -0
  38. package/dist/commands/perps/close.js.map +1 -0
  39. package/dist/commands/perps/decrease.d.ts +3 -0
  40. package/dist/commands/perps/decrease.d.ts.map +1 -0
  41. package/dist/commands/perps/decrease.js +55 -0
  42. package/dist/commands/perps/decrease.js.map +1 -0
  43. package/dist/commands/perps/increase.d.ts +3 -0
  44. package/dist/commands/perps/increase.d.ts.map +1 -0
  45. package/dist/commands/perps/increase.js +60 -0
  46. package/dist/commands/perps/increase.js.map +1 -0
  47. package/dist/commands/perps/index.d.ts.map +1 -1
  48. package/dist/commands/perps/index.js +8 -0
  49. package/dist/commands/perps/index.js.map +1 -1
  50. package/dist/commands/perps/open.d.ts +3 -0
  51. package/dist/commands/perps/open.d.ts.map +1 -0
  52. package/dist/commands/perps/open.js +60 -0
  53. package/dist/commands/perps/open.js.map +1 -0
  54. package/dist/commands/perps/pool.d.ts.map +1 -1
  55. package/dist/commands/perps/pool.js +37 -29
  56. package/dist/commands/perps/pool.js.map +1 -1
  57. package/dist/commands/perps/positions.d.ts.map +1 -1
  58. package/dist/commands/perps/positions.js +56 -61
  59. package/dist/commands/perps/positions.js.map +1 -1
  60. package/dist/commands/perps/show.d.ts.map +1 -1
  61. package/dist/commands/perps/show.js +45 -25
  62. package/dist/commands/perps/show.js.map +1 -1
  63. package/dist/commands/portfolio.d.ts.map +1 -1
  64. package/dist/commands/portfolio.js +65 -18
  65. package/dist/commands/portfolio.js.map +1 -1
  66. package/dist/commands/predict/buy.d.ts.map +1 -1
  67. package/dist/commands/predict/buy.js +3 -0
  68. package/dist/commands/predict/buy.js.map +1 -1
  69. package/dist/commands/predict/sell.d.ts.map +1 -1
  70. package/dist/commands/predict/sell.js +3 -0
  71. package/dist/commands/predict/sell.js.map +1 -1
  72. package/dist/commands/tokens/quote.d.ts.map +1 -1
  73. package/dist/commands/tokens/quote.js +4 -1
  74. package/dist/commands/tokens/quote.js.map +1 -1
  75. package/dist/commands/tokens/swap.d.ts.map +1 -1
  76. package/dist/commands/tokens/swap.js +6 -3
  77. package/dist/commands/tokens/swap.js.map +1 -1
  78. package/dist/config.d.ts +4 -1
  79. package/dist/config.d.ts.map +1 -1
  80. package/dist/config.js +5 -1
  81. package/dist/config.js.map +1 -1
  82. package/dist/utils/amounts.d.ts +0 -16
  83. package/dist/utils/amounts.d.ts.map +1 -1
  84. package/dist/utils/amounts.js +4 -36
  85. package/dist/utils/amounts.js.map +1 -1
  86. package/dist/utils/helius.d.ts +3 -23
  87. package/dist/utils/helius.d.ts.map +1 -1
  88. package/dist/utils/helius.js +0 -123
  89. package/dist/utils/helius.js.map +1 -1
  90. package/dist/utils/jupiter.d.ts +4 -8
  91. package/dist/utils/jupiter.d.ts.map +1 -1
  92. package/dist/utils/jupiter.js +1 -7
  93. package/dist/utils/jupiter.js.map +1 -1
  94. package/dist/utils/nft.d.ts +3 -37
  95. package/dist/utils/nft.d.ts.map +1 -1
  96. package/dist/utils/nft.js +0 -71
  97. package/dist/utils/nft.js.map +1 -1
  98. package/dist/utils/perps/index.d.ts +51 -10
  99. package/dist/utils/perps/index.d.ts.map +1 -1
  100. package/dist/utils/perps/index.js +249 -34
  101. package/dist/utils/perps/index.js.map +1 -1
  102. package/dist/utils/perps-api.d.ts +110 -0
  103. package/dist/utils/perps-api.d.ts.map +1 -0
  104. package/dist/utils/perps-api.js +260 -0
  105. package/dist/utils/perps-api.js.map +1 -0
  106. package/dist/utils/positions.d.ts +3 -77
  107. package/dist/utils/positions.d.ts.map +1 -1
  108. package/dist/utils/positions.js +3 -330
  109. package/dist/utils/positions.js.map +1 -1
  110. package/dist/utils/prediction.d.ts +6 -28
  111. package/dist/utils/prediction.d.ts.map +1 -1
  112. package/dist/utils/prediction.js +0 -37
  113. package/dist/utils/prediction.js.map +1 -1
  114. package/dist/utils/recurring.d.ts +79 -0
  115. package/dist/utils/recurring.d.ts.map +1 -0
  116. package/dist/utils/recurring.js +73 -0
  117. package/dist/utils/recurring.js.map +1 -0
  118. package/dist/utils/token-book.d.ts.map +1 -1
  119. package/dist/utils/token-book.js +10 -1
  120. package/dist/utils/token-book.js.map +1 -1
  121. package/dist/utils/token-info.d.ts +2 -1
  122. package/dist/utils/token-info.d.ts.map +1 -1
  123. package/dist/utils/token-info.js +5 -2
  124. package/dist/utils/token-info.js.map +1 -1
  125. package/dist/utils/trigger.d.ts +88 -0
  126. package/dist/utils/trigger.d.ts.map +1 -0
  127. package/dist/utils/trigger.js +114 -0
  128. package/dist/utils/trigger.js.map +1 -0
  129. package/dist/utils/wallet.d.ts +0 -9
  130. package/dist/utils/wallet.d.ts.map +1 -1
  131. package/dist/utils/wallet.js +14 -4
  132. package/dist/utils/wallet.js.map +1 -1
  133. package/package.json +8 -2
  134. package/dist/utils/perps/doves-idl.d.ts +0 -380
  135. package/dist/utils/perps/doves-idl.d.ts.map +0 -1
  136. package/dist/utils/perps/doves-idl.js +0 -379
  137. package/dist/utils/perps/doves-idl.js.map +0 -1
  138. package/dist/utils/perps/jupiter-perpetuals-idl.d.ts +0 -7243
  139. package/dist/utils/perps/jupiter-perpetuals-idl.d.ts.map +0 -1
  140. package/dist/utils/perps/jupiter-perpetuals-idl.js +0 -7242
  141. package/dist/utils/perps/jupiter-perpetuals-idl.js.map +0 -1
@@ -0,0 +1,55 @@
1
+ import { Connection } from '@solana/web3.js';
2
+ import { Command } from 'commander';
3
+ import { toSmallestUnit } from '../../utils/amounts.js';
4
+ import { getPerpsPositions, buildDecreasePositionTransaction, signAndSendPerps, formatUsd, assetToMint, DEFAULT_SLIPPAGE_BPS, } from '../../utils/perps-api.js';
5
+ import { loadKeypairForSigning, getWalletAddress } from '../../utils/wallet.js';
6
+ import { output, action, requirePassword, getRpcUrl } from '../shared.js';
7
+ export const decreaseCommand = new Command('decrease')
8
+ .argument('<market>', 'Market: SOL, ETH, BTC')
9
+ .argument('<side>', 'Side: long, short')
10
+ .argument('<amount-usd>', 'Size to reduce in USD')
11
+ .option('--receive <token>', 'Token to receive (default: asset for longs, USDC for shorts)')
12
+ .option('--slippage <bps>', `Price slippage in bps (default: ${DEFAULT_SLIPPAGE_BPS})`)
13
+ .option('-n, --note <note>', 'Trading journal note')
14
+ .description('Decrease a perps position (e.g. perps decrease BTC short 5)')
15
+ .action(action(async (market, side, amountUsd, options) => {
16
+ const password = requirePassword();
17
+ const asset = market.toUpperCase();
18
+ const sideNorm = side.toLowerCase();
19
+ const usdAmount = parseFloat(amountUsd);
20
+ const slippageBps = options.slippage ? parseInt(options.slippage, 10) : DEFAULT_SLIPPAGE_BPS;
21
+ if (!['long', 'short'].includes(sideNorm))
22
+ throw new Error('Side must be "long" or "short"');
23
+ if (isNaN(usdAmount) || usdAmount <= 0)
24
+ throw new Error(`Invalid amount: "${amountUsd}"`);
25
+ assetToMint(asset);
26
+ const rpcUrl = getRpcUrl();
27
+ const connection = new Connection(rpcUrl, 'confirmed');
28
+ const walletAddress = getWalletAddress(password);
29
+ const { dataList } = await getPerpsPositions(walletAddress, connection);
30
+ const pos = dataList.find(p => p.asset.toUpperCase() === asset && p.side === sideNorm);
31
+ if (!pos)
32
+ throw new Error(`No open ${asset} ${sideNorm} position found`);
33
+ const defaultReceive = sideNorm === 'long' ? asset : 'USDC';
34
+ const receiveToken = (options.receive || defaultReceive).toUpperCase();
35
+ const sizeUsdDelta = toSmallestUnit(usdAmount, 6);
36
+ console.log(`\nDecreasing ${asset} ${sideNorm} by $${usdAmount} — current size ${formatUsd(pos.sizeUsd)}`);
37
+ console.log(` Receive: ${receiveToken}, slippage: ${slippageBps} bps`);
38
+ const { tx } = await buildDecreasePositionTransaction(connection, { positionPubkey: pos.positionPubkey, receiveToken, sizeUsdDelta, slippageBps }, { side: sideNorm, asset });
39
+ console.log('Signing and submitting...');
40
+ const keypair = loadKeypairForSigning(password);
41
+ const txid = await signAndSendPerps(connection, keypair, tx);
42
+ console.log(`\nDecrease request submitted — keeper will execute shortly.`);
43
+ console.log(`https://solscan.io/tx/${txid}`);
44
+ output({
45
+ txid,
46
+ positionPubkey: pos.positionPubkey,
47
+ asset,
48
+ side: sideNorm,
49
+ sizeUsdDelta: usdAmount,
50
+ receive: receiveToken,
51
+ slippageBps,
52
+ note: options.note,
53
+ });
54
+ }));
55
+ //# sourceMappingURL=decrease.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decrease.js","sourceRoot":"","sources":["../../../src/commands/perps/decrease.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const increaseCommand: Command;
3
+ //# sourceMappingURL=increase.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"increase.d.ts","sourceRoot":"","sources":["../../../src/commands/perps/increase.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAepC,eAAO,MAAM,eAAe,SAyDvB,CAAC"}
@@ -0,0 +1,60 @@
1
+ import { Connection } from '@solana/web3.js';
2
+ import { Command } from 'commander';
3
+ import { toSmallestUnit } from '../../utils/amounts.js';
4
+ import { buildIncreasePositionTransaction, signAndSendPerps, assetToMint, perpsTokenDecimals, DEFAULT_SLIPPAGE_BPS, } from '../../utils/perps-api.js';
5
+ import { loadKeypairForSigning, getWalletAddress } from '../../utils/wallet.js';
6
+ import { output, action, requirePassword, getRpcUrl } from '../shared.js';
7
+ export const increaseCommand = new Command('increase')
8
+ .argument('<market>', 'Market: SOL, ETH, BTC')
9
+ .argument('<side>', 'Side: long, short')
10
+ .argument('<token>', 'Payment token: SOL, ETH, BTC, USDC')
11
+ .argument('<amount>', 'Amount of payment token to add')
12
+ .option('--leverage <leverage>', 'Leverage multiplier (e.g. 5 for 5x)')
13
+ .option('--slippage <bps>', `Price slippage in bps (default: ${DEFAULT_SLIPPAGE_BPS})`)
14
+ .option('-n, --note <note>', 'Trading journal note')
15
+ .description('Increase a perps position (e.g. perps increase BTC short USDC 5 --leverage 2)')
16
+ .action(action(async (market, side, token, amount, options) => {
17
+ const password = requirePassword();
18
+ const asset = market.toUpperCase();
19
+ const sideNorm = side.toLowerCase();
20
+ const inputToken = token.toUpperCase();
21
+ const amountNum = parseFloat(amount);
22
+ const slippageBps = options.slippage ? parseInt(options.slippage, 10) : DEFAULT_SLIPPAGE_BPS;
23
+ if (!['long', 'short'].includes(sideNorm))
24
+ throw new Error('Side must be "long" or "short"');
25
+ if (isNaN(amountNum) || amountNum <= 0)
26
+ throw new Error(`Invalid amount: "${amount}"`);
27
+ assetToMint(asset);
28
+ const rpcUrl = getRpcUrl();
29
+ const connection = new Connection(rpcUrl, 'confirmed');
30
+ const walletAddress = getWalletAddress(password);
31
+ const decimals = perpsTokenDecimals(inputToken);
32
+ const inputTokenAmount = toSmallestUnit(amountNum, decimals);
33
+ console.log(`\nIncrease ${asset} ${sideNorm} — adding ${amountNum} ${inputToken}, ${options.leverage || 'auto'}x leverage`);
34
+ const { tx, positionPubkey } = await buildIncreasePositionTransaction(connection, {
35
+ asset,
36
+ inputToken,
37
+ inputTokenAmount,
38
+ leverage: options.leverage,
39
+ side: sideNorm,
40
+ slippageBps,
41
+ walletAddress,
42
+ });
43
+ console.log('Signing and submitting...');
44
+ const keypair = loadKeypairForSigning(password);
45
+ const txid = await signAndSendPerps(connection, keypair, tx);
46
+ console.log(`\nIncrease request submitted — keeper will execute shortly.`);
47
+ console.log(`https://solscan.io/tx/${txid}`);
48
+ output({
49
+ txid,
50
+ positionPubkey,
51
+ asset,
52
+ side: sideNorm,
53
+ inputToken,
54
+ amount: amountNum,
55
+ leverage: options.leverage || 'auto',
56
+ slippageBps,
57
+ note: options.note,
58
+ });
59
+ }));
60
+ //# sourceMappingURL=increase.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"increase.js","sourceRoot":"","sources":["../../../src/commands/perps/increase.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/perps/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,eAAO,MAAM,YAAY,SACyB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/perps/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASpC,eAAO,MAAM,YAAY,SACyB,CAAC"}
@@ -2,9 +2,17 @@ import { Command } from 'commander';
2
2
  import { showCommand } from './show.js';
3
3
  import { positionsCommand } from './positions.js';
4
4
  import { poolCommand } from './pool.js';
5
+ import { openCommand } from './open.js';
6
+ import { closeCommand } from './close.js';
7
+ import { increaseCommand } from './increase.js';
8
+ import { decreaseCommand } from './decrease.js';
5
9
  export const perpsCommand = new Command('perps')
6
10
  .description('Perpetual futures on SOL/ETH/BTC');
7
11
  perpsCommand.addCommand(showCommand);
8
12
  perpsCommand.addCommand(positionsCommand);
9
13
  perpsCommand.addCommand(poolCommand);
14
+ perpsCommand.addCommand(openCommand);
15
+ perpsCommand.addCommand(closeCommand);
16
+ perpsCommand.addCommand(increaseCommand);
17
+ perpsCommand.addCommand(decreaseCommand);
10
18
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/perps/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC;KAC7C,WAAW,CAAC,kCAAkC,CAAC,CAAC;AAEnD,YAAY,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AACrC,YAAY,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;AAC1C,YAAY,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/perps/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC;KAC7C,WAAW,CAAC,kCAAkC,CAAC,CAAC;AAEnD,YAAY,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AACrC,YAAY,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;AAC1C,YAAY,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AACrC,YAAY,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AACrC,YAAY,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AACtC,YAAY,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;AACzC,YAAY,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const openCommand: Command;
3
+ //# sourceMappingURL=open.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"open.d.ts","sourceRoot":"","sources":["../../../src/commands/perps/open.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAepC,eAAO,MAAM,WAAW,SAyDnB,CAAC"}
@@ -0,0 +1,60 @@
1
+ import { Connection } from '@solana/web3.js';
2
+ import { Command } from 'commander';
3
+ import { toSmallestUnit } from '../../utils/amounts.js';
4
+ import { buildIncreasePositionTransaction, signAndSendPerps, assetToMint, perpsTokenDecimals, DEFAULT_SLIPPAGE_BPS, } from '../../utils/perps-api.js';
5
+ import { loadKeypairForSigning, getWalletAddress } from '../../utils/wallet.js';
6
+ import { output, action, requirePassword, getRpcUrl } from '../shared.js';
7
+ export const openCommand = new Command('open')
8
+ .argument('<market>', 'Market: SOL, ETH, BTC')
9
+ .argument('<side>', 'Side: long, short')
10
+ .argument('<token>', 'Payment token: SOL, ETH, BTC, USDC')
11
+ .argument('<amount>', 'Amount of payment token')
12
+ .option('--leverage <leverage>', 'Leverage multiplier (e.g. 5 for 5x)')
13
+ .option('--slippage <bps>', `Price slippage tolerance in bps (default: ${DEFAULT_SLIPPAGE_BPS})`)
14
+ .option('-n, --note <note>', 'Trading journal note')
15
+ .description('Open a new perps position (e.g. perps open SOL long SOL 0.06 --leverage 2)')
16
+ .action(action(async (market, side, token, amount, options) => {
17
+ const password = requirePassword();
18
+ const asset = market.toUpperCase();
19
+ const sideNorm = side.toLowerCase();
20
+ const inputToken = token.toUpperCase();
21
+ const amountNum = parseFloat(amount);
22
+ const slippageBps = options.slippage ? parseInt(options.slippage, 10) : DEFAULT_SLIPPAGE_BPS;
23
+ if (!['long', 'short'].includes(sideNorm))
24
+ throw new Error('Side must be "long" or "short"');
25
+ if (isNaN(amountNum) || amountNum <= 0)
26
+ throw new Error(`Invalid amount: "${amount}"`);
27
+ assetToMint(asset);
28
+ const rpcUrl = getRpcUrl();
29
+ const connection = new Connection(rpcUrl, 'confirmed');
30
+ const walletAddress = getWalletAddress(password);
31
+ const decimals = perpsTokenDecimals(inputToken);
32
+ const inputTokenAmount = toSmallestUnit(amountNum, decimals);
33
+ console.log(`\n${asset} ${sideNorm} — ${amountNum} ${inputToken}, ${options.leverage || 'auto'}x leverage, ${slippageBps} bps slippage`);
34
+ const { tx, positionPubkey } = await buildIncreasePositionTransaction(connection, {
35
+ asset,
36
+ inputToken,
37
+ inputTokenAmount,
38
+ leverage: options.leverage,
39
+ side: sideNorm,
40
+ slippageBps,
41
+ walletAddress,
42
+ });
43
+ console.log('Signing and submitting...');
44
+ const keypair = loadKeypairForSigning(password);
45
+ const txid = await signAndSendPerps(connection, keypair, tx);
46
+ console.log(`\nPosition request submitted — keeper will execute shortly.`);
47
+ console.log(`https://solscan.io/tx/${txid}`);
48
+ output({
49
+ txid,
50
+ positionPubkey,
51
+ asset,
52
+ side: sideNorm,
53
+ inputToken,
54
+ amount: amountNum,
55
+ leverage: options.leverage || 'auto',
56
+ slippageBps,
57
+ note: options.note,
58
+ });
59
+ }));
60
+ //# sourceMappingURL=open.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"open.js","sourceRoot":"","sources":["../../../src/commands/perps/open.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"pool.d.ts","sourceRoot":"","sources":["../../../src/commands/perps/pool.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,eAAO,MAAM,WAAW,SA+BpB,CAAC"}
1
+ {"version":3,"file":"pool.d.ts","sourceRoot":"","sources":["../../../src/commands/perps/pool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASpC,eAAO,MAAM,WAAW,SA0CnB,CAAC"}
@@ -1,33 +1,41 @@
1
- import { Connection } from '@solana/web3.js';
2
1
  import { Command } from 'commander';
3
- import { getPoolStats } from '../../utils/perps/index.js';
4
- import { output, error } from '../shared.js';
5
- import { getRpcUrl } from '../../config.js';
2
+ import { getPoolInfo, assetToMint, PERPS_ASSETS, } from '../../utils/perps-api.js';
3
+ import { output, action } from '../shared.js';
6
4
  export const poolCommand = new Command('pool')
7
- .description('View JLP pool stats and AUM')
8
- .action(async () => {
9
- try {
10
- const rpcUrl = getRpcUrl();
11
- const connection = new Connection(rpcUrl);
12
- const stats = await getPoolStats(connection);
13
- output({
14
- aumUsd: stats.aumUsd.toFixed(2),
15
- aumFormatted: `$${stats.aumUsd.toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ',')}`,
16
- markets: ['SOL-PERP', 'ETH-PERP', 'BTC-PERP'],
17
- maxLeverage: '100x',
18
- fees: '0.06%',
19
- }, () => [
20
- 'Jupiter Perpetuals Pool Stats',
5
+ .description('View JLP pool stats and liquidity')
6
+ .action(action(async () => {
7
+ const results = await Promise.all(PERPS_ASSETS.map(async (asset) => {
8
+ const pool = await getPoolInfo(assetToMint(asset));
9
+ return { asset, pool };
10
+ }));
11
+ const poolData = results.map(({ asset, pool }) => ({
12
+ market: asset,
13
+ longAvailableLiquidity: pool.longAvailableLiquidity,
14
+ longBorrowRatePercent: pool.longBorrowRatePercent,
15
+ longUtilizationPercent: pool.longUtilizationPercent,
16
+ shortAvailableLiquidity: pool.shortAvailableLiquidity,
17
+ shortBorrowRatePercent: pool.shortBorrowRatePercent,
18
+ shortUtilizationPercent: pool.shortUtilizationPercent,
19
+ openFeePercent: pool.openFeePercent,
20
+ }));
21
+ output({ pool: poolData }, () => {
22
+ const lines = [
23
+ 'Jupiter Perpetuals Pool',
21
24
  '',
22
- `Pool AUM: $${stats.aumUsd.toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ',')}`,
23
- '',
24
- 'Available Markets: SOL-PERP, ETH-PERP, BTC-PERP',
25
- 'Max Leverage: Up to 100x',
26
- 'Fees: 0.06% open/close',
27
- ].join('\n'));
28
- }
29
- catch (e) {
30
- error('Failed to fetch pool stats', e.message);
31
- }
32
- });
25
+ 'Market Long Liq Borrow Util Short Liq Borrow Util Open Fee',
26
+ '------- ------------------ -------- ------- ------------------ -------- ------- --------',
27
+ ];
28
+ for (const { asset, pool } of results) {
29
+ lines.push(`${asset.padEnd(7)} ` +
30
+ `${pool.longAvailableLiquidity.padEnd(18)} ` +
31
+ `${(pool.longBorrowRatePercent + '%').padEnd(8)} ` +
32
+ `${(pool.longUtilizationPercent + '%').padEnd(7)} ` +
33
+ `${pool.shortAvailableLiquidity.padEnd(18)} ` +
34
+ `${(pool.shortBorrowRatePercent + '%').padEnd(8)} ` +
35
+ `${(pool.shortUtilizationPercent + '%').padEnd(7)} ` +
36
+ `${pool.openFeePercent}%`);
37
+ }
38
+ return lines.join('\n');
39
+ });
40
+ }));
33
41
  //# sourceMappingURL=pool.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pool.js","sourceRoot":"","sources":["../../../src/commands/perps/pool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;KAC3C,WAAW,CAAC,6BAA6B,CAAC;KAC1C,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;QAC3B,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;QAE1C,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,UAAU,CAAC,CAAC;QAE7C,MAAM,CACJ;YACE,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;YAC/B,YAAY,EAAE,IAAI,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,uBAAuB,EAAE,GAAG,CAAC,EAAE;YACjF,OAAO,EAAE,CAAC,UAAU,EAAE,UAAU,EAAE,UAAU,CAAC;YAC7C,WAAW,EAAE,MAAM;YACnB,IAAI,EAAE,OAAO;SACd,EACD,GAAG,EAAE,CACH;YACE,+BAA+B;YAC/B,EAAE;YACF,cAAc,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,uBAAuB,EAAE,GAAG,CAAC,EAAE;YAC7E,EAAE;YACF,iDAAiD;YACjD,0BAA0B;YAC1B,wBAAwB;SACzB,CAAC,IAAI,CAAC,IAAI,CAAC,CACf,CAAC;IACJ,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QAChB,KAAK,CAAC,4BAA4B,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;IACjD,CAAC;AACH,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"pool.js","sourceRoot":"","sources":["../../../src/commands/perps/pool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EACL,WAAW,EACX,WAAW,EACX,YAAY,GAEb,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;KAC3C,WAAW,CAAC,mCAAmC,CAAC;KAChD,MAAM,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE;IACxB,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAC/B,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,KAAiB,EAAE,EAAE;QAC3C,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;QACnD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACzB,CAAC,CAAC,CACH,CAAC;IAEF,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;QACjD,MAAM,EAAE,KAAK;QACb,sBAAsB,EAAE,IAAI,CAAC,sBAAsB;QACnD,qBAAqB,EAAE,IAAI,CAAC,qBAAqB;QACjD,sBAAsB,EAAE,IAAI,CAAC,sBAAsB;QACnD,uBAAuB,EAAE,IAAI,CAAC,uBAAuB;QACrD,sBAAsB,EAAE,IAAI,CAAC,sBAAsB;QACnD,uBAAuB,EAAE,IAAI,CAAC,uBAAuB;QACrD,cAAc,EAAE,IAAI,CAAC,cAAc;KACpC,CAAC,CAAC,CAAC;IAEJ,MAAM,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,GAAG,EAAE;QAC9B,MAAM,KAAK,GAAG;YACZ,yBAAyB;YACzB,EAAE;YACF,0FAA0F;YAC1F,0FAA0F;SAC3F,CAAC;QACF,KAAK,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,OAAO,EAAE,CAAC;YACtC,KAAK,CAAC,IAAI,CACR,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG;gBACrB,GAAG,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;gBAC5C,GAAG,CAAC,IAAI,CAAC,qBAAqB,GAAG,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG;gBAClD,GAAG,CAAC,IAAI,CAAC,sBAAsB,GAAG,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG;gBACnD,GAAG,IAAI,CAAC,uBAAuB,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;gBAC7C,GAAG,CAAC,IAAI,CAAC,sBAAsB,GAAG,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG;gBACnD,GAAG,CAAC,IAAI,CAAC,uBAAuB,GAAG,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG;gBACpD,GAAG,IAAI,CAAC,cAAc,GAAG,CAC1B,CAAC;QACJ,CAAC;QACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"positions.d.ts","sourceRoot":"","sources":["../../../src/commands/perps/positions.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,eAAO,MAAM,gBAAgB,SAwEzB,CAAC"}
1
+ {"version":3,"file":"positions.d.ts","sourceRoot":"","sources":["../../../src/commands/perps/positions.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASpC,eAAO,MAAM,gBAAgB,SAkExB,CAAC"}
@@ -1,68 +1,63 @@
1
- import { Connection, PublicKey } from '@solana/web3.js';
1
+ import { Connection } from '@solana/web3.js';
2
2
  import { Command } from 'commander';
3
- import { getOpenPositions } from '../../utils/perps/index.js';
4
- import { output, error, requirePassword, getRpcUrl } from '../shared.js';
3
+ import { getPerpsPositions, rawToUsd, formatUsd, } from '../../utils/perps-api.js';
5
4
  import { getWalletAddress } from '../../utils/wallet.js';
5
+ import { output, action, requirePassword, getRpcUrl } from '../shared.js';
6
6
  export const positionsCommand = new Command('positions')
7
- .description('View your open perps positions')
7
+ .description('View your open perps positions with PnL')
8
8
  .option('-w, --wallet <address>', 'Wallet address (defaults to configured wallet)')
9
- .action(async (options) => {
10
- try {
11
- const rpcUrl = getRpcUrl();
12
- const connection = new Connection(rpcUrl);
13
- let walletAddress = options.wallet;
14
- if (!walletAddress) {
15
- const password = requirePassword();
16
- walletAddress = getWalletAddress(password);
17
- }
18
- const positions = await getOpenPositions(connection, new PublicKey(walletAddress));
19
- if (positions.length === 0) {
20
- output({
21
- wallet: walletAddress,
22
- positions: [],
23
- message: 'No open perps positions found',
24
- tradeUrl: 'https://jup.ag/perps',
25
- }, () => [
26
- `Perps Positions for ${walletAddress.slice(0, 8)}...`,
27
- '',
28
- 'No open perps positions found',
29
- '',
30
- 'Open a position at: https://jup.ag/perps',
31
- ].join('\n'));
32
- return;
33
- }
34
- const positionsData = positions.map((pos) => ({
35
- market: pos.custody,
36
- side: pos.side,
37
- sizeUsd: pos.sizeUsd.toFixed(2),
38
- collateralUsd: pos.collateralUsd.toFixed(2),
39
- leverage: pos.leverage.toFixed(1),
40
- entryPrice: pos.entryPrice.toFixed(2),
41
- publicKey: pos.publicKey,
42
- }));
43
- output({
44
- wallet: walletAddress,
45
- positions: positionsData,
46
- }, () => {
47
- const lines = [
48
- `Perps Positions for ${walletAddress.slice(0, 8)}...`,
49
- '',
50
- 'Market Side Size Collateral Leverage Entry',
51
- '------- ------ ------------ ------------ --------- ----------',
52
- ];
53
- for (const pos of positions) {
54
- const side = pos.side.toUpperCase().padEnd(6);
55
- const size = `$${pos.sizeUsd.toFixed(2)}`.padEnd(12);
56
- const collateral = `$${pos.collateralUsd.toFixed(2)}`.padEnd(12);
57
- const leverage = `${pos.leverage.toFixed(1)}x`.padEnd(9);
58
- const entry = `$${pos.entryPrice.toFixed(2)}`;
59
- lines.push(`${pos.custody.padEnd(7)} ${side} ${size} ${collateral} ${leverage} ${entry}`);
60
- }
61
- return lines.join('\n');
62
- });
9
+ .action(action(async (options) => {
10
+ let walletAddress = options.wallet;
11
+ if (!walletAddress) {
12
+ const password = requirePassword();
13
+ walletAddress = getWalletAddress(password);
63
14
  }
64
- catch (e) {
65
- error('Failed to fetch positions', e.message);
15
+ const rpcUrl = getRpcUrl();
16
+ const connection = new Connection(rpcUrl, 'confirmed');
17
+ const { dataList: positions, count } = await getPerpsPositions(walletAddress, connection);
18
+ if (positions.length === 0) {
19
+ output({ wallet: walletAddress, positions: [], message: 'No open perps positions found' }, () => [
20
+ `Perps Positions for ${walletAddress.slice(0, 8)}...`,
21
+ '',
22
+ 'No open perps positions found',
23
+ '',
24
+ 'Open a position: trader perps open SOL long 100 --leverage 5',
25
+ ].join('\n'));
26
+ return;
66
27
  }
67
- });
28
+ const positionsData = positions.map(p => ({
29
+ asset: p.asset,
30
+ side: p.side,
31
+ sizeUsd: rawToUsd(p.sizeUsd),
32
+ collateralUsd: rawToUsd(p.collateralUsd),
33
+ leverage: p.leverage,
34
+ entryPriceUsd: rawToUsd(p.entryPriceUsd),
35
+ markPriceUsd: rawToUsd(p.markPriceUsd),
36
+ liquidationPriceUsd: rawToUsd(p.liquidationPriceUsd),
37
+ pnlAfterFeesUsd: rawToUsd(p.pnlAfterFeesUsd),
38
+ pnlAfterFeesPct: p.pnlAfterFeesPct,
39
+ positionPubkey: p.positionPubkey,
40
+ }));
41
+ output({ wallet: walletAddress, positions: positionsData, count }, () => {
42
+ const lines = [
43
+ `Perps Positions for ${walletAddress.slice(0, 8)}...`,
44
+ '',
45
+ 'Market Side Size Entry Mark Liq PnL Lev',
46
+ '------- ------ ------------ ------------ ------------ ------------ ---------------- ------',
47
+ ];
48
+ for (const p of positions) {
49
+ const pnl = rawToUsd(p.pnlAfterFeesUsd);
50
+ const pnlStr = `${pnl >= 0 ? '+' : ''}${formatUsd(p.pnlAfterFeesUsd)} (${p.pnlAfterFeesPct}%)`;
51
+ lines.push(`${p.asset.padEnd(7)} ` +
52
+ `${p.side.toUpperCase().padEnd(6)} ` +
53
+ `${formatUsd(p.sizeUsd).padEnd(12)} ` +
54
+ `${formatUsd(p.entryPriceUsd).padEnd(12)} ` +
55
+ `${formatUsd(p.markPriceUsd).padEnd(12)} ` +
56
+ `${formatUsd(p.liquidationPriceUsd).padEnd(12)} ` +
57
+ `${pnlStr.padEnd(16)} ` +
58
+ `${p.leverage}x`);
59
+ }
60
+ return lines.join('\n');
61
+ });
62
+ }));
68
63
  //# sourceMappingURL=positions.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"positions.js","sourceRoot":"","sources":["../../../src/commands/perps/positions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"positions.js","sourceRoot":"","sources":["../../../src/commands/perps/positions.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"show.d.ts","sourceRoot":"","sources":["../../../src/commands/perps/show.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,eAAO,MAAM,WAAW,SAmCnB,CAAC"}
1
+ {"version":3,"file":"show.d.ts","sourceRoot":"","sources":["../../../src/commands/perps/show.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,eAAO,MAAM,WAAW,SAyDnB,CAAC"}
@@ -1,36 +1,56 @@
1
- import { Connection } from '@solana/web3.js';
2
1
  import { Command } from 'commander';
3
- import { getAllCustodyInfo } from '../../utils/perps/index.js';
2
+ import { getMarketStats, getPoolInfo, assetToMint, PERPS_ASSETS, } from '../../utils/perps-api.js';
4
3
  import { output, action } from '../shared.js';
5
- import { getRpcUrl } from '../../config.js';
6
4
  export const showCommand = new Command('show')
7
5
  .argument('[market]', 'Market symbol (SOL, ETH, BTC) — omit for all')
8
- .description('View market info, prices, and fees')
6
+ .description('View market prices, stats, and pool info')
9
7
  .action(action(async (market) => {
10
- const connection = new Connection(getRpcUrl());
11
- const custodies = await getAllCustodyInfo(connection);
12
- const filtered = market
13
- ? custodies.filter(c => c.name.toUpperCase().startsWith(market.toUpperCase()))
14
- : custodies;
15
- if (filtered.length === 0)
16
- throw new Error(`Market "${market}" not found. Available: SOL, ETH, BTC`);
17
- const marketsData = filtered.map(c => ({
18
- market: c.name,
19
- maxLeverage: `${c.maxLeverage}x`,
20
- openFeePct: (c.openFeeBps / 100).toFixed(2),
21
- closeFeePct: (c.closeFeeBps / 100).toFixed(2),
8
+ const assets = market
9
+ ? [market.toUpperCase()]
10
+ : [...PERPS_ASSETS];
11
+ // Validate
12
+ for (const a of assets)
13
+ assetToMint(a);
14
+ // Fetch market stats and pool info in parallel
15
+ const results = await Promise.all(assets.map(async (asset) => {
16
+ const mint = assetToMint(asset);
17
+ const [stats, pool] = await Promise.all([
18
+ getMarketStats(mint),
19
+ getPoolInfo(mint),
20
+ ]);
21
+ return { asset, stats, pool };
22
+ }));
23
+ const marketsData = results.map(({ asset, stats, pool }) => ({
24
+ market: asset,
25
+ price: stats.price,
26
+ priceChange24H: stats.priceChange24H,
27
+ priceHigh24H: stats.priceHigh24H,
28
+ priceLow24H: stats.priceLow24H,
29
+ volume: stats.volume,
30
+ longLiquidity: pool.longAvailableLiquidity,
31
+ longBorrowRate: pool.longBorrowRatePercent,
32
+ longUtilization: pool.longUtilizationPercent,
33
+ shortLiquidity: pool.shortAvailableLiquidity,
34
+ shortBorrowRate: pool.shortBorrowRatePercent,
35
+ shortUtilization: pool.shortUtilizationPercent,
36
+ openFee: pool.openFeePercent,
22
37
  }));
23
38
  output({ markets: marketsData, tradeUrl: 'https://jup.ag/perps' }, () => {
24
- const lines = [
25
- 'Jupiter Perpetuals',
26
- '',
27
- 'Market Max Lev Open Fee Close Fee',
28
- '----------- -------- ---------- ----------',
29
- ];
30
- for (const c of filtered) {
31
- lines.push(`${c.name.padEnd(11)} ${(c.maxLeverage + 'x').padEnd(8)} ${((c.openFeeBps / 100).toFixed(2) + '%').padEnd(10)} ${(c.closeFeeBps / 100).toFixed(2)}%`);
39
+ const lines = ['Jupiter Perpetuals', ''];
40
+ for (const { asset, stats, pool } of results) {
41
+ const price = parseFloat(String(stats.price));
42
+ const change = parseFloat(String(stats.priceChange24H));
43
+ const high = parseFloat(String(stats.priceHigh24H));
44
+ const low = parseFloat(String(stats.priceLow24H));
45
+ const chg = change >= 0 ? `+${change.toFixed(2)}%` : `${change.toFixed(2)}%`;
46
+ lines.push(`${asset}-PERP`);
47
+ lines.push(` Price: $${price.toLocaleString()} 24h: ${chg} H: $${high.toLocaleString()} L: $${low.toLocaleString()}`);
48
+ lines.push(` Long: Liquidity ${pool.longAvailableLiquidity} Borrow ${pool.longBorrowRatePercent}% Util ${pool.longUtilizationPercent}%`);
49
+ lines.push(` Short: Liquidity ${pool.shortAvailableLiquidity} Borrow ${pool.shortBorrowRatePercent}% Util ${pool.shortUtilizationPercent}%`);
50
+ lines.push(` Open Fee: ${pool.openFeePercent}%`);
51
+ lines.push('');
32
52
  }
33
- lines.push('', 'Trade at: https://jup.ag/perps');
53
+ lines.push('Trade at: https://jup.ag/perps');
34
54
  return lines.join('\n');
35
55
  });
36
56
  }));
@@ -1 +1 @@
1
- {"version":3,"file":"show.js","sourceRoot":"","sources":["../../../src/commands/perps/show.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;KAC3C,QAAQ,CAAC,UAAU,EAAE,8CAA8C,CAAC;KACpE,WAAW,CAAC,oCAAoC,CAAC;KACjD,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;IAC9B,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,SAAS,EAAE,CAAC,CAAC;IAC/C,MAAM,SAAS,GAAG,MAAM,iBAAiB,CAAC,UAAU,CAAC,CAAC;IAEtD,MAAM,QAAQ,GAAG,MAAM;QACrB,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;QAC9E,CAAC,CAAC,SAAS,CAAC;IAEd,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,WAAW,MAAM,uCAAuC,CAAC,CAAC;IAErG,MAAM,WAAW,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACrC,MAAM,EAAE,CAAC,CAAC,IAAI;QACd,WAAW,EAAE,GAAG,CAAC,CAAC,WAAW,GAAG;QAChC,UAAU,EAAE,CAAC,CAAC,CAAC,UAAU,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;QAC3C,WAAW,EAAE,CAAC,CAAC,CAAC,WAAW,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;KAC9C,CAAC,CAAC,CAAC;IAEJ,MAAM,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,sBAAsB,EAAE,EAAE,GAAG,EAAE;QACtE,MAAM,KAAK,GAAG;YACZ,oBAAoB;YACpB,EAAE;YACF,4CAA4C;YAC5C,4CAA4C;SAC7C,CAAC;QACF,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;YACzB,KAAK,CAAC,IAAI,CACR,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,GAAG,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CACrJ,CAAC;QACJ,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,gCAAgC,CAAC,CAAC;QACjD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"show.js","sourceRoot":"","sources":["../../../src/commands/perps/show.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"portfolio.d.ts","sourceRoot":"","sources":["../../src/commands/portfolio.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,eAAO,MAAM,gBAAgB,SA2FxB,CAAC"}
1
+ {"version":3,"file":"portfolio.d.ts","sourceRoot":"","sources":["../../src/commands/portfolio.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAYpC,eAAO,MAAM,gBAAgB,SA6IxB,CAAC"}