-
Notifications
You must be signed in to change notification settings - Fork 163
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
[example project] LP Repositioning Bot #558
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about adding README.md
- to explain what this bot does.
- to explain how to invoke (1 example
lp-bot --position-mint-address xxxxx ...
- to explain what preparation is required (need to have 1 position, wallet.json file)
How about putting RPC URL in main (reader will notice that it is defined as constant)
How about add "rust-sdk" / "ts-sdk" directory in examples ? (/examples/rust-sdk/lp-bod)
How about executing close and open in atomic because once open position fails, user need to open position manually
I think utility should have the following 2 functions:
- add priority fee (jito tip may be overkill as an example, so ComputeBudget program is sufficient)
- client-side retry
client-side retry is not scope of SDK, but dev often faces "transaction expired" error.
https://github.com/orca-so/whirlpools/blob/main/legacy-sdk/cli/src/utils/transaction_sender.ts#L110
How about displaying wallet balance for tokenA and tokenB (The balance will be rebalanced without swaps, so there may be a shortfall.)
…dk. Make atomic transaction for close and open position instructions. Add utility functions for priority fee and client-side retry. Work in progress: dislapying wallet balances.
…ces. Update args.
examples/rust-sdk/lp-bot/Cargo.toml
Outdated
@@ -0,0 +1,16 @@ | |||
[package] | |||
name = "lp-bot" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe something like:orca_whirlpools_repositioning_cli_example?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also same goes for the folder examples/lp-bot is not very descriptive.
examples/rust-sdk/lp-bot/Cargo.toml
Outdated
|
||
[dependencies] | ||
clap = { version = "4.5.21", features = ["derive"] } | ||
colored = "2.0" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: format these to all use expanded object with explicit caret (^)
@@ -6,5 +6,6 @@ members = [ | |||
exclude = [ | |||
"rust-sdk", | |||
"ts-sdk", | |||
"docs" | |||
"docs", | |||
"examples" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Useful to add a readme to the examples folder with a little more description on each example?
examples/rust-sdk/lp-bot/README.md
Outdated
The bot connects to Solana Mainnet Beta by default using: | ||
|
||
```rust | ||
const RPC_URL: &str = "https://api.mainnet-beta.solana.com"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mainnet beta rpc url doesnt work for most things
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I noticed it barely worked with this project. I will add a recommendation to update the URL.
examples/rust-sdk/lp-bot/README.md
Outdated
- `--position-mint-address` (required): The mint address of the position to monitor and rebalance. | ||
- `--threshold` (optional): The percentage deviation from the center price at which rebalancing is triggered. Default: 1.0. | ||
- `--interval` (optional): The time interval (in seconds) between checks. Default: 60. | ||
- `--priority-fee-tier` (optional): The priority fee tier for transaction processing. Options: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not just let the user specify the percentile instead of these arbitrary levels?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I copied this from Helius' documentation on their priority fee API: https://docs.helius.dev/solana-apis/priority-fee-api
I feel it's more user friendly this way and abstracts away how priority fees are calculated, but I don't have a very strong opinion about it. Happy to adjust.
max_priority_fee_lamports: u64, | ||
) -> Result<Option<solana_sdk::instruction::Instruction>, Box<dyn std::error::Error>> { | ||
if let Some(priority_fee_micro_lamports) = calculate_priority_fee(rpc, tier).await? { | ||
let recent_blockhash = rpc.get_latest_blockhash().await?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can ask sim_tx to give you a recent blockhash (saved one rpc call)
if non_zero_fees.is_empty() { | ||
return Ok(Some(0)); | ||
} | ||
non_zero_fees.sort_unstable(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why sort unstable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fromt the docs I understand that sort_unstable()
is usually faster than sort()
, because it doesn't try to preserve the order of equal elements. Since we're dealing with u64s, I think that's fine. Also, it requires less memory and performs the sort in-place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair enough. I believe normal sort
is also in-place tho
let mut non_zero_fees: Vec<u64> = prioritization_fees | ||
.iter() | ||
.map(|fee| fee.prioritization_fee) | ||
.filter(|&fee| fee > 0) // Keep only non-zero fees |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why only non-zero?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I remember implementing this myself a while back and used an article from Chainstack as reference: https://docs.chainstack.com/docs/solana-estimate-priority-fees-getrecentprioritizationfees#add-the-code
If this doesn't make a lot of sense, I'll remove this part.
} | ||
|
||
fn create_priority_fee_instruction(unit_price: u64) -> solana_sdk::instruction::Instruction { | ||
ComputeBudgetInstruction::set_compute_unit_price(unit_price) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You also need to set compute budget units instruction
ComputeBudgetInstruction::set_compute_unit_price(unit_price) | ||
} | ||
|
||
async fn retry_async<'a, F, Fut, T, E>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't there a package we can use for this?
calculations regarding price
…for sqrt_prices. Remove unnecessary retries.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚢🚢🚢
"scripts": { | ||
"build": "cargo build", | ||
"format": "cargo clippy --fix --allow-dirty --allow-staged && cargo fmt", | ||
"lint": "cargo clippy", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed this command in #522 so you might want to do that here too
Title
[example project] LP Repositioning Bot
Details
This pull request introduces a Rust-based CLI bot designed to monitor and rebalance liquidity positions on Orca Whirlpools. The bot automates the process of tracking price deviations, closing out-of-range positions, and reopening new ones at adjusted ranges. It also includes prioritization fee management and customizable options to meet various user needs.
The bot calculates the center price of a position, checks its deviation against the whirlpool price and a user-defined threshold, and adjusts liquidity around the current price using the same width as the initial range. Users can configure parameters such as slippage tolerance, time intervals, and prioritization fees to optimize rebalancing according to their preferences.
Key features:
For a full explanation of the program's functionality and configuration options, please refer to README.