Skip to content

update: migrate quasar programs to latest API#8

Merged
mikemaccana merged 13 commits intoquiknode-labs:mainfrom
jim4067:jimii/quasar-api-migration
Apr 29, 2026
Merged

update: migrate quasar programs to latest API#8
mikemaccana merged 13 commits intoquiknode-labs:mainfrom
jim4067:jimii/quasar-api-migration

Conversation

@jim4067
Copy link
Copy Markdown

@jim4067 jim4067 commented Apr 22, 2026

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 'info lifetimes and &mut/& fields).

Instruction/state handling is updated to match new codegen: accounts add #[seeds(...)]/set_inner support with generated *Inner structs, string args move to bounded String<N> (changing wire-format assumptions), and account init/set_inner calls now pass explicit rent parameters (Rent::get(), lamports_per_byte, exemption_threshold_raw) or manual create_account with 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: .gitignore now ignores .claude.

Reviewed by Cursor Bugbot for commit 6c2bef3. Bugbot is set up for automated code reviews on this repo. Configure here.

Copy link
Copy Markdown
Collaborator

@mikemaccana mikemaccana left a comment

Choose a reason for hiding this comment

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

Awesome work and thanks - just remove the impl and let the instruction handlers and account constraints be seperate and we can get this in!

Comment thread basics/account-data/quasar/src/instructions/create.rs Outdated
@jim4067 jim4067 marked this pull request as ready for review April 22, 2026 17:09
Comment thread tokens/escrow/quasar/src/lib.rs Outdated
Comment thread basics/account-data/quasar/src/lib.rs Outdated
Comment thread basics/counter/quasar/src/lib.rs Outdated
Comment thread .gitignore Outdated
Comment thread basics/cross-program-invocation/quasar/hand/src/lib.rs Outdated
@jim4067 jim4067 marked this pull request as draft April 24, 2026 18:03
@jim4067 jim4067 marked this pull request as ready for review April 25, 2026 14:02
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.
@mikemaccana mikemaccana force-pushed the jimii/quasar-api-migration branch from d7c229b to 70c45d2 Compare April 28, 2026 20:50
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" }
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 70c45d2. Configure here.

Edward (Mike's assistant) added 2 commits April 28, 2026 21:30
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
@mikemaccana
Copy link
Copy Markdown
Collaborator

@jim4067 I can have my agent here fix the tests if you need.

@jim4067
Copy link
Copy Markdown
Author

jim4067 commented Apr 28, 2026

@jim4067 I can have my agent here fix the tests if you need.

@mikemaccana, yes that would be awesome.
Thanks.

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

There are 3 total unresolved issues (including 1 from previous review).

Fix All in Cursor

❌ 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]
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 6c2bef3. Configure here.


[dependencies]
quasar-lang = "0.0"
quasar-lang = { git = "https://github.com/blueshift-gg/quasar" }
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 6c2bef3. Configure here.

@mikemaccana
Copy link
Copy Markdown
Collaborator

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:

  1. 70c45d2 - migrate Quasar.toml manifests to the new structured format. Every project was failing with Quasar.toml uses an outdated format. Updated all 39 in-scope manifests to the new [testing] / [testing.rust] / [testing.rust.test] / [clients] path = "target/client" shape.

  2. 8eff6b6a - update transfer-hook programs for the new UncheckedAccount API. 7 programs under tokens/token-extensions/transfer-hook/* were failing with cannot dereference UncheckedAccount and non-primitive cast. Replaced *account deref / account as Foo cast with explicit method calls.

  3. 6c2bef30 - align test fixtures with the new wire format. 7 tests had stale instruction-data encodings or account-data byte layouts relative to the rewritten programs. Updated each to match what its program now produces.

CI is green across all 7 workflows on the latest commit:

Should be ready to merge. Shout if anything needs adjusting.

@mikemaccana mikemaccana dismissed their stale review April 29, 2026 00:26

CI passing now

@mikemaccana mikemaccana merged commit 7ca968e into quiknode-labs:main Apr 29, 2026
28 checks passed
@mikemaccana
Copy link
Copy Markdown
Collaborator

Followup PR opened to address the cursor[bot] review on this one: #9.

Summary of the 8 cursor[bot] comments verified against main post-merge:

Full details and the verification matrix are in the PR description: #9

@jim4067
Copy link
Copy Markdown
Author

jim4067 commented Apr 29, 2026

Thanks. I had installed the CLI using cargo but hadn't updated it to the latest version.

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.

2 participants