update: migrate quasar programs to latest API#8
update: migrate quasar programs to latest API#8mikemaccana merged 13 commits intoquiknode-labs:mainfrom
Conversation
mikemaccana
left a comment
There was a problem hiding this comment.
Awesome work and thanks - just remove the impl and let the instruction handlers and account constraints be seperate and we can get this in!
…all quasar programs
Every per-project Quasar.toml in old format failed CI with:
✘ Quasar.toml uses an outdated format.
Run quasar config reset and re-init your project.
The PR migrated program code to the new Quasar API but did not
regenerate the per-project manifests. The current Quasar CLI expects
the new structured form:
[testing]
language = "rust"
[testing.rust]
framework = "quasar-svm"
[testing.rust.test]
program = "cargo"
args = ["test", "tests::"]
[clients]
languages = ["rust"]
instead of the old single-line:
[testing]
framework = "quasarsvm-rust"
This commit converts all 25 remaining old-format Quasar.toml files in
place. The 18 manifests that were already migrated (most token-extension
projects) are left untouched.
Verified locally with quasar build + cargo test on representative
projects across each category: basics/create-account, basics/hello-solana,
compression/cnft-burn, tokens/transfer-tokens, and a token-extensions
sample.
d7c229b to
70c45d2
Compare
| quasar-lang = "0.0" | ||
| quasar-spl = "0.0" | ||
| quasar-lang = { git = "https://github.com/blueshift-gg/quasar", branch = "master" } | ||
| quasar-spl = { git = "https://github.com/blueshift-gg/quasar", branch = "master" } |
There was a problem hiding this comment.
Token-extension crates missing quasar-svm git migration
Medium Severity
All token-extension crates update quasar-lang and quasar-spl from crates.io to git dependencies but leave quasar-svm at version = "0.1" on crates.io. Every other program in the repo (basics/*, compression/*, oracles/*, non-extension tokens/*) migrates quasar-svm to { git = "https://github.com/blueshift-gg/quasar-svm" }. This mismatch across at least 7 crates will likely cause version conflicts or test failures since quasar-svm 0.1 from crates.io may be incompatible with the latest git quasar-lang.
Additional Locations (2)
Reviewed by Cursor Bugbot for commit 70c45d2. Configure here.
The Quasar master branch (commit 37a531dc) replaced the registry version of `solana-account-view`, changing `AccountView::try_borrow_mut` from `&self` to `&mut self`. It also dropped the `alloc` Cargo feature on `quasar-lang`, renamed `BufCpiCall` to `DynCpiCall`, and rejects all-zero multi-byte instruction discriminators at compile time. This commit migrates all 7 broken transfer-hook examples to compile and run against the current API: - hello-world, counter, transfer-cost, transfer-switch: replaced the invalid `account as *const UncheckedAccount as *mut UncheckedAccount` cast (which tried to cast a value, not a reference) with `&mut account as *mut UncheckedAccount`. - whitelist, account-data-as-seed: converted account structs from `&'info mut UncheckedAccount` field syntax (which the Quasar derive macro no longer accepts) to owned `UncheckedAccount` fields, updated handler signatures from `&Foo` to `&mut Foo`, and applied the same pointer-cast fix. - allow-block-list-token: same `&'info` -> owned conversion across all instruction modules; removed the `alloc` feature dependency from Cargo.toml (upstream `quasar-lang` master no longer exposes it); rewrote two `BufCpiCall` call sites to use `DynCpiCall` (the new variable-length CPI builder); changed the all-zero `init_mint` instruction discriminator to a non-zero value. All 7 projects now pass `quasar build` and `cargo test`.
The Quasar `#[account]` and `#[instruction]` derive macros use a single "compact" wire layout: a header containing all fixed-size fields and length prefixes grouped together, followed by a tail with all dynamic byte payloads grouped together. The previous tests assumed an interleaved field-by-field layout with u32 length prefixes, which never matched the program code that was already migrated to the compact format. Two consequences flowed from that mismatch: 1. Length prefixes for `String<MAX>` default to a single byte (the second `String` generic argument is the prefix type and its default is `u8`). The tests were using u32 prefixes, so the program rejected the instruction data or wrote wildly wrong account contents. 2. The compact format groups all length prefixes ahead of the data bytes; the tests expected each prefix to immediately precede its own bytes. This commit rewrites the failing test fixtures so they encode and decode the same compact format the programs already produce. The program code itself is not changed — programs are canonical, tests follow. Also removes a stray `rent` sysvar account from the `tokens/pda-mint-authority` `create_mint` test: the program's `CreateMint` accounts struct no longer takes a rent sysvar, so the extra entry was shifting `token_program` and `system_program` to the wrong slots. Projects fixed: basics/account-data basics/close-account basics/favorites basics/realloc basics/rent basics/repository-layout tokens/pda-mint-authority
|
@jim4067 I can have my agent here fix the tests if you need. |
@mikemaccana, yes that would be awesome. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
There are 3 total unresolved issues (including 1 from previous review).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 6c2bef3. Configure here.
| } | ||
|
|
||
| /// Build update instruction data. | ||
| /// Wire format: [disc=1] [message: u32 prefix + bytes] |
There was a problem hiding this comment.
String<1024> likely needs u16 prefix, not u8
High Severity
The test assumes String<1024> uses a u8 length prefix, but other files' comments say String<50> uses u8 "because MAX (50) fits in a byte" — implying the prefix type depends on MAX. Since 1024 exceeds u8's max of 255, String<1024> likely uses a u16 prefix. The build_initialize, build_update, and on-disk verification all use a single-byte length, which would produce incorrect wire format and fail data assertions if the framework uses u16.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 6c2bef3. Configure here.
|
|
||
| [dependencies] | ||
| quasar-lang = "0.0" | ||
| quasar-lang = { git = "https://github.com/blueshift-gg/quasar" } |
There was a problem hiding this comment.
Lever program not migrated to new API
Medium Severity
The lever program's quasar-lang dependency was updated to the latest git version, but its source files (e.g., switch_power.rs) still use the old API with lifetime parameters (SwitchPower<'info>, &'info mut Account<PowerStatus>) and plain String without a size bound. Every other quasar program in this PR was migrated to the new lifetimeless API. This oversight means the lever either fails to compile or silently uses a different wire format than intended.
Reviewed by Cursor Bugbot for commit 6c2bef3. Configure here.
|
Hey @jim4067 - I pushed three fixes on top of your branch (with maintainer-edit access enabled) to get CI green. Thanks for the original API migration; this just finishes off the bits the new Quasar CLI was strict about. The three commits:
CI is green across all 7 workflows on the latest commit: Should be ready to merge. Shout if anything needs adjusting. |
|
Followup PR opened to address the cursor[bot] review on this one: #9. Summary of the 8 cursor[bot] comments verified against
Full details and the verification matrix are in the PR description: #9 |
|
Thanks. I had installed the CLI using cargo but hadn't updated it to the latest version. |


Note
Medium Risk
Broad mechanical migration across many Solana example programs to new Quasar APIs (account types, CPI helpers, rent handling, instruction encoding), which could break builds/tests or change on-chain serialization if any of these examples are deployed.
Overview
Migrates the Quasar-based examples to the latest Quasar/Quasar-SVM APIs. Dependencies switch from placeholder crate versions to git sources, and most
#[derive(Accounts)]contexts are updated to the new owned account types (dropping'infolifetimes and&mut/&fields).Instruction/state handling is updated to match new codegen: accounts add
#[seeds(...)]/set_innersupport with generated*Innerstructs, string args move to boundedString<N>(changing wire-format assumptions), and account init/set_innercalls now pass explicit rent parameters (Rent::get(),lamports_per_byte,exemption_threshold_raw) or manualcreate_accountwith computed rent-exempt lamports.CPI and remaining-accounts flows are refreshed (e.g.,
DynCpiCall,RemainingAccounts), and tests that manually build instruction data are rewritten to the new compact “header then tail” encoding. Misc:.gitignorenow ignores.claude.Reviewed by Cursor Bugbot for commit 6c2bef3. Bugbot is set up for automated code reviews on this repo. Configure here.