Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: hyperliquid #71

Merged
merged 4 commits into from
Jan 29, 2025
Merged

Conversation

caillef
Copy link
Contributor

@caillef caillef commented Jan 29, 2025

fixes #44

Summary by CodeRabbit

Release Notes

  • New Features

    • Added Hyperliquid trading bot with comprehensive trading functionalities.
    • Introduced support for placing limit and market orders.
    • Implemented account balance and position tracking.
    • Added interactive console interface for manual trading.
    • Introduced a new character, "Trading Sage," to enhance user interaction.
  • Configuration

    • Added new environment variables for Hyperliquid integration.
  • Development

    • Added new script for running Hyperliquid example.
    • Installed Hyperliquid dependency.
    • Reinstated Express dependency.

Copy link

vercel bot commented Jan 29, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
daydreams ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jan 29, 2025 3:15pm

Copy link
Contributor

coderabbitai bot commented Jan 29, 2025

Walkthrough

The pull request introduces a comprehensive implementation of a Hyperliquid trading bot, adding support for Hyperliquid trading functionality across multiple files. The changes include creating a new Hyperliquid client, adding environment variables for Hyperliquid credentials, implementing a trading example script, and defining a new trading character. The implementation provides capabilities for placing limit and market orders, retrieving account balances, and managing trading operations through an interactive console interface.

Changes

File Change Summary
.env.example Added 3 new Hyperliquid-related environment variables
examples/example-hyperliquid.ts Created a full Hyperliquid trading bot example with multiple handlers for trading operations
package.json Added hyperliquid script and new dependency; re-added express
packages/core/src/core/character_trading_sage.ts Introduced defaultCharacter for a trading-focused persona
packages/core/src/core/env.ts Added Hyperliquid-related environment variable schemas
packages/core/src/core/io/hyperliquid.ts Created HyperliquidClient with comprehensive trading methods

Assessment against linked issues

Objective Addressed Explanation
Build provider (44) HyperliquidClient implemented in hyperliquid.ts
Build example (44) example-hyperliquid.ts created with comprehensive trading functionality

Poem

🐰 A trading sage hops on the scene,
With Hyperliquid's flow, sharp and keen,
Orders placed with digital might,
Market moves dancing left and right,
A rabbit's trade, a techno-dream! 🚀

✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@caillef caillef changed the title Hyperliquid feat: hyperliquid Jan 29, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (7)
packages/core/src/core/io/hyperliquid.ts (3)

35-41: Good initialization sequence, but consider environment-based defaults for testnet.

Currently, testnet defaults to false. If you regularly work in a test/staging environment, you may want to derive this from an environment variable or a configuration setting to prevent accidental production orders.


272-299: Consider making reduce_only configurable.

The reduce_only: false parameter is hard-coded for all orders. If you need partial closing of positions (especially for risk management or exit strategies), exposing a reduce_only option to your placeOrder method may offer more flexibility.


141-158: Potential partial-failure handling for concurrent sells.

When calling marketSellPositions with multiple tickers, a single failure will throw an error and halt the entire Promise.all() operation. If partial success is acceptable, consider adding a structured approach to handle partial failures (e.g., continuing to process remaining tickers even if one fails).

packages/core/src/core/env.ts (1)

15-17: Be mindful of storing private keys in environment variables.

Storing private keys in plain text env variables might pose a security risk if logs or stack traces leak. Consider using a secure vault or key management service. If environment variables are the only option, ensure that logs and error messages never expose them.

packages/core/src/core/character_trading_sage.ts (2)

110-110: Fix capitalization in contextRules.

The word "emphasize" should be capitalized for consistency with other rules.

-            "emphasize risk management in volatile markets",
+            "Emphasize risk management in volatile markets",

115-130: Enhance tweet template with market risk disclaimers.

The tweet template should include guidance for adding appropriate risk disclaimers.

     tweetTemplate: `
     <thinking id="tweet_template">
       As {{name}}, share a practical trading insight or reminder that promotes thoughtful trading.

       Rules:
       - Keep it actionable but not specific financial advice
       - Use at most one emoji
       - Focus on risk management or psychology
+      - Include appropriate risk disclaimers
+      - Avoid mentioning specific assets or trading pairs

       Context: {{context}}
       Market condition: {{market_context}}
       Key focus: {{trading_topic}}

       Aim to promote disciplined trading while maintaining a supportive tone.
     </thinking>
package.json (1)

10-10: Group related scripts together.

Consider grouping the hyperliquid script with other trading-related scripts for better organization.

     "scripts": {
         "goal": "bun run examples/example-goal.ts",
         "task": "bun run examples/example-basic.ts",
         "twitter": "bun run examples/example-twitter.ts",
         "server": "bun run examples/example-server.ts",
         "discord": "bun run examples/example-discord.ts",
-        "hyperliquid": "bun run examples/example-hyperliquid.ts",
         "api": "bun run examples/example-api.ts",
+        
+        "# Trading scripts"
+        "hyperliquid": "bun run examples/example-hyperliquid.ts",
+        
         "ui": "pnpm --dir clients/example-ui run dev",
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a7bb540 and f1eb65b.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (6)
  • .env.example (1 hunks)
  • examples/example-hyperliquid.ts (1 hunks)
  • package.json (2 hunks)
  • packages/core/src/core/character_trading_sage.ts (1 hunks)
  • packages/core/src/core/env.ts (1 hunks)
  • packages/core/src/core/io/hyperliquid.ts (1 hunks)
🔇 Additional comments (2)
packages/core/src/core/io/hyperliquid.ts (1)

215-217: Verify correct orderbook indexing for best bid/ask.

You're accessing orderbook.levels[1] for the ask price when is_buy is true and orderbook.levels[0] otherwise. Verify that the Hyperliquid orderbook data is ordered such that:

  • levels[0] is indeed the best price for one side (usually the best ask or bid),
  • levels[1] is the next best price, etc.

If the indexing is reversed or differs, this might lead to unexpected slippage or missed fills.

package.json (1)

27-27: Verify Hyperliquid package version compatibility.

The hyperliquid package version 1.5.8 should be verified for:

  1. Compatibility with the current Node.js version
  2. Known security vulnerabilities
  3. Latest available version
✅ Verification successful

Hyperliquid package version is optimal and secure

The package is using the latest available version (1.5.8) and has no known security vulnerabilities.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check hyperliquid package version and security advisories

# Check latest version
npm view hyperliquid versions --json | jq -r '.[-1]'

# Check for security advisories
gh api graphql -f query='
{
  securityVulnerabilities(first: 5, ecosystem: NPM, package: "hyperliquid") {
    nodes {
      advisory {
        summary
        severity
        publishedAt
      }
      vulnerableVersionRange
      firstPatchedVersion {
        identifier
      }
    }
  }
}'

Length of output: 405

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🧹 Nitpick comments (1)
examples/example-hyperliquid.ts (1)

112-114: Use decimal.js for price calculations.

Using regular floating-point arithmetic for price calculations can lead to precision issues. Consider using a decimal arithmetic library for accurate calculations.

+import { Decimal } from 'decimal.js';

// Example for one of the log messages:
chalk.blue(
    `🔍 ${message.is_buy ? "Buying" : "Selling"} ${message.sz}x${message.ticker} at ${message.limit_px} (total $${
+        new Decimal(message.limit_px).mul(message.sz).toFixed(2)
-        message.limit_px * message.sz
    })...`
)

Also applies to: 147-149, 221-224, 258-260

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f1eb65b and 76ac18a.

📒 Files selected for processing (3)
  • .env.example (1 hunks)
  • examples/example-hyperliquid.ts (1 hunks)
  • packages/core/src/core/character_trading_sage.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/core/src/core/character_trading_sage.ts
  • .env.example
🔇 Additional comments (1)
examples/example-hyperliquid.ts (1)

38-38: Review database purging strategy.

Purging databases on startup (vectorDb.purge() and scheduledTaskDb.deleteAll()) might lead to data loss in production. Consider making this behavior configurable based on the environment.

Would you like me to suggest an implementation that makes database purging configurable?

Also applies to: 65-65

Comment on lines +104 to +122
execute: async (data: unknown) => {
const message = data as {
ticker: string;
sz: number;
limit_px: number;
is_buy: boolean;
};
console.log(
chalk.blue(
`🔍 ${message.is_buy ? "Buying" : "Selling"} ${message.sz}x${message.ticker} at ${message.limit_px} (total $${message.limit_px * message.sz})...`
)
);
return await hyperliquid.placeLimitOrderInstantOrCancel(
message.ticker,
message.sz,
message.limit_px,
message.is_buy
);
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Standardize error handling across handlers.

Error handling is inconsistent across handlers. Some handlers have try-catch blocks (e.g., hyperliquid_place_market_order), while others don't (e.g., hyperliquid_place_limit_order_instantorcancel). Standardize error handling to ensure consistent behavior.

Here's an example implementation for one handler:

 execute: async (data: unknown) => {
     const message = data as {
         ticker: string;
         sz: number;
         limit_px: number;
         is_buy: boolean;
     };
     console.log(
         chalk.blue(
             `🔍 ${message.is_buy ? "Buying" : "Selling"} ${message.sz}x${message.ticker} at ${message.limit_px} (total $${message.limit_px * message.sz})...`
         )
     );
+    try {
         return await hyperliquid.placeLimitOrderInstantOrCancel(
             message.ticker,
             message.sz,
             message.limit_px,
             message.is_buy
         );
+    } catch (err) {
+        console.error(chalk.red("Error placing limit order:"), err);
+        throw err;
+    }
 }

Apply similar error handling to all handlers.

Also applies to: 139-157, 167-177, 185-189, 196-200, 215-235, 251-271, 286-293

Comment on lines +95 to +99
ticker: z
.string()
.describe(
"Ticker must be only the letter of the ticker in uppercase without the -PERP or -SPOT suffix"
),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Enhance ticker validation in schema.

The current schema only describes the ticker format but doesn't enforce it. Add pattern validation to ensure tickers follow the required format.

 ticker: z
     .string()
+    .regex(/^[A-Z]+$/, "Ticker must contain only uppercase letters")
     .describe(
         "Ticker must be only the letter of the ticker in uppercase without the -PERP or -SPOT suffix"
     )

Also applies to: 130-134, 207-211, 279-283

});

// Start the prompt loop
console.log(chalk.cyan("🤖 Bot is now running and monitoring Discord..."));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Update console message to remove Discord reference.

The console message mentions Discord monitoring, but this appears to be a standalone console application.

-console.log(chalk.cyan("🤖 Bot is now running and monitoring Discord..."));
+console.log(chalk.cyan("🤖 Bot is now running..."));
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
console.log(chalk.cyan("🤖 Bot is now running and monitoring Discord..."));
console.log(chalk.cyan("🤖 Bot is now running..."));

Comment on lines +81 to +88
const hyperliquid = new HyperliquidClient(
{
mainAddress: env.HYPERLIQUID_MAIN_ADDRESS,
walletAddress: env.HYPERLIQUID_WALLET_ADDRESS,
privateKey: env.HYPERLIQUID_PRIVATE_KEY,
},
loglevel
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add validation for required environment variables.

The Hyperliquid client initialization uses environment variables without validation. Add checks to ensure these required credentials are present before initialization.

+ // Validate required environment variables
+ if (!env.HYPERLIQUID_MAIN_ADDRESS || !env.HYPERLIQUID_WALLET_ADDRESS || !env.HYPERLIQUID_PRIVATE_KEY) {
+   throw new Error(
+     "Missing required environment variables: HYPERLIQUID_MAIN_ADDRESS, HYPERLIQUID_WALLET_ADDRESS, HYPERLIQUID_PRIVATE_KEY"
+   );
+ }

const hyperliquid = new HyperliquidClient(
    {
        mainAddress: env.HYPERLIQUID_MAIN_ADDRESS,
        walletAddress: env.HYPERLIQUID_WALLET_ADDRESS,
        privateKey: env.HYPERLIQUID_PRIVATE_KEY,
    },
    loglevel
);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const hyperliquid = new HyperliquidClient(
{
mainAddress: env.HYPERLIQUID_MAIN_ADDRESS,
walletAddress: env.HYPERLIQUID_WALLET_ADDRESS,
privateKey: env.HYPERLIQUID_PRIVATE_KEY,
},
loglevel
);
// Validate required environment variables
if (!env.HYPERLIQUID_MAIN_ADDRESS || !env.HYPERLIQUID_WALLET_ADDRESS || !env.HYPERLIQUID_PRIVATE_KEY) {
throw new Error(
"Missing required environment variables: HYPERLIQUID_MAIN_ADDRESS, HYPERLIQUID_WALLET_ADDRESS, HYPERLIQUID_PRIVATE_KEY"
);
}
const hyperliquid = new HyperliquidClient(
{
mainAddress: env.HYPERLIQUID_MAIN_ADDRESS,
walletAddress: env.HYPERLIQUID_WALLET_ADDRESS,
privateKey: env.HYPERLIQUID_PRIVATE_KEY,
},
loglevel
);

Comment on lines +56 to +60
const scheduledTaskDb = new MongoDb(
"mongodb://localhost:27017",
"myApp",
"scheduled_tasks"
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Move MongoDB connection URL to environment variables.

Hardcoding the MongoDB connection URL reduces configurability and poses security risks.

const scheduledTaskDb = new MongoDb(
-   "mongodb://localhost:27017",
+   env.MONGODB_URL || "mongodb://localhost:27017",
    "myApp",
    "scheduled_tasks"
);

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +298 to +300
execute: async (payload) => {
return payload;
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add input validation to chat handler.

The user_chat handler forwards the payload without validation. Add input validation to ensure message format consistency.

 execute: async (payload) => {
+    const schema = z.object({
+        content: z.string().min(1),
+        userId: z.string()
+    });
+    const validated = schema.parse(payload);
-    return payload;
+    return validated;
 }

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +380 to +383
main().catch((error) => {
console.error(chalk.red("Fatal error:"), error);
process.exit(1);
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Enhance error handling and cleanup in main function.

The error handling could be more informative and should include cleanup operations before exit.

main().catch(async (error) => {
    console.error(chalk.red("Fatal error:"), error);
+    // Attempt cleanup
+    try {
+        if (scheduledTaskDb) {
+            await scheduledTaskDb.disconnect();
+        }
+        // Add any other cleanup operations
+        console.log(chalk.yellow("Cleanup completed"));
+    } catch (cleanupError) {
+        console.error(chalk.red("Error during cleanup:"), cleanupError);
+    }
    process.exit(1);
});

Committable suggestion skipped: line range outside the PR's diff.

@ponderingdemocritus ponderingdemocritus merged commit 5b25421 into daydreamsai:main Jan 29, 2025
14 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Jan 30, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[feat] Create hyperliquid example
2 participants