Skip to content

fix(quasar): pin quasar deps to 623bb70 (upstream zeropod 0.3.0 regression)#24

Merged
mikemaccana merged 1 commit into
quicknode:mainfrom
mikemaccana-edwardbot:fix/quasar-spl-pin-working-revision
May 14, 2026
Merged

fix(quasar): pin quasar deps to 623bb70 (upstream zeropod 0.3.0 regression)#24
mikemaccana merged 1 commit into
quicknode:mainfrom
mikemaccana-edwardbot:fix/quasar-spl-pin-working-revision

Conversation

@mikemaccana-edwardbot
Copy link
Copy Markdown

Summary

Pin all blueshift-gg/quasar Git deps in this repo to commit 623bb70 because the current master HEAD fails to compile (E0592 duplicate definitions for delegate / close_authority / mint_authority / freeze_authority).

Root cause (upstream)

Commit 2be2622 on blueshift-gg/quasar master (2026-05-09, "fix(derive): classify const-capacity account Vec fields") bumps zeropod from 0.2.0 to 0.3.0 in lang/Cargo.toml and Cargo.lock.

zeropod 0.3.0 starts auto-generating accessor methods for PodOption<T, PFX=4> fields. quasar's own spl/src/token.rs still carries manual implementations of those accessors with a comment that reads:

Semantic accessors for COption fields (auto-generated accessors don't cover PFX=4).

That assumption became false the moment zeropod 0.3.0 landed, so the manual impls now collide with the macro-generated ones:

error[E0592]: duplicate definitions with name `delegate`
  --> /…/quasar/spl/src/token.rs:16:10
   |
16 | #[derive(quasar_lang::__zeropod::ZeroPod)]
   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ duplicate definitions for `delegate`
...
64 |     pub fn delegate(&self) -> Option<&Address> {
   |     ------------------------------------------ other definition for `delegate`

Same error for close_authority, mint_authority, freeze_authority. Every tokens/**/quasar project here therefore fails to build.

Fix

Pin all blueshift-gg/quasar deps (quasar-lang, quasar-spl, quasar-metadata) to rev = "623bb70" — the last working commit on master before the zeropod 0.3.0 bump. Bisected by checking cargo check at each candidate revision.

Same source-id (matching rev) keeps trait impls consistent across the quasar crates; Cargo treats different rev/branch specifiers on the same git URL as distinct sources, which previously caused trait-resolution failures here.

Every touched Cargo.toml carries a comment explaining the pin and the unpin trigger (upstream zeropod fix landing on master).

Files

44 Cargo.toml files across basics/**/quasar and tokens/**/quasar. The basics/** projects don't pull quasar-spl so they weren't actually broken, but pinning them to the same rev keeps the whole quasar dep tree consistent and avoids future drift.

Verification

Locally ran cargo check --release --tests on three representative projects:

  • tokens/escrow/quasar
  • tokens/token-extensions/transfer-fee/quasar
  • tokens/spl-token-minter/quasar ✅ (also exercises the quasar-metadata pin)

All compile cleanly (only pre-existing dead-code/cfg warnings).

Relationship to PR #23

This is a follow-up to PR #23 ("fix(ci): restrict changed-project detection to exact framework roots"). PR #23 fixes a real workflow bug; once it runs the full-project matrix on workflow-file changes, it exposes this pre-existing quasar regression. PR #23 has been cleaned up to contain only the workflow fix — no .ghaignore additions to hide the failures it surfaces.

Out of scope

tokens/token-extensions/transfer-hook/block-list/pinocchio is a WIP port (no pnpm-lock.yaml, no tests/, no build script). It needs a real port (look at the sibling block-list/native or block-list/anchor for reference), not a dependency pin or a CI ignore. Tracking separately.

….0 regression

Upstream blueshift-gg/quasar master moved zeropod from 0.2.0 to 0.3.0 in
commit 2be2622 (2026-05-09, 'fix(derive): classify const-capacity account
Vec fields'). zeropod 0.3.0 auto-generates accessor methods for
PodOption<T, PFX=4> fields, which collide with the manual delegate(),
close_authority(), mint_authority(), and freeze_authority() impls in
quasar's own spl/src/token.rs:

    error[E0592]: duplicate definitions with name `delegate`
      --> .../quasar/spl/src/token.rs:16:10
       |
    16 | #[derive(quasar_lang::__zeropod::ZeroPod)]
       |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ duplicate definitions
    ...
    64 |     pub fn delegate(&self) -> Option<&Address> {
       |     ------------------------------------------ other definition

The manual accessors carry a comment claiming auto-generated ones do not
cover PFX=4 — that assumption became false after the zeropod bump.

Every `tokens/**/quasar` project pinning quasar-{lang,spl} to
`branch = "master"` therefore fails to compile against current master.
Confirmed locally; visible in PR solana-developers#23's first full-matrix CI run.

Pin quasar-lang, quasar-spl, and quasar-metadata to commit 623bb70 (the
last good commit on master before the zeropod 0.3.0 bump) across all
`basics/**/quasar` and `tokens/**/quasar` Cargo.toml files that pull
quasar from `blueshift-gg/quasar`. Same source-id keeps trait impls
consistent across quasar crates. Comments updated to explain the rationale
and to point at the unpin trigger (upstream zeropod fix).

Verified with `cargo check --release --tests` on:
  - tokens/escrow/quasar
  - tokens/token-extensions/transfer-fee/quasar
  - tokens/spl-token-minter/quasar (also uses quasar-metadata)

The `basics/**/quasar` projects don't pull quasar-spl so they weren't
breaking, but pinning them to the same rev keeps the dep tree consistent
across the whole repo and avoids future drift if someone adds an
spl-using basic example.

Follow-up to PR solana-developers#23 (the CI workflow fix), which exposed this pre-existing
regression by triggering the full-matrix CI run.

Note: this PR does NOT add anything to .ghaignore. Hiding failures was
explicitly the wrong move; this PR fixes the underlying break instead.

Out of scope for this PR:
  - tokens/token-extensions/transfer-hook/block-list/pinocchio is a WIP
    port (no pnpm-lock.yaml, no tests/, no build script) and needs a real
    port rather than a dependency pin. Tracking separately.
@mikemaccana mikemaccana merged commit 586902b into quicknode:main May 14, 2026
28 checks passed
mikemaccana pushed a commit that referenced this pull request May 14, 2026
The 'spl-' prefix is redundant. Everything onchain is an SPL token (per
Solana's terminology page) — the prefix adds nothing and clutters paths
and crate names. The directory, crates, and prose mentions are now just
'token-minter' / 'Token Minter'.

Renamed:

Directories:
  tokens/spl-token-minter/                                 -> tokens/token-minter/
  tokens/token-minter/anchor/programs/spl-token-minter/    -> tokens/token-minter/anchor/programs/token-minter/

Crate / package names:
  spl-token-minter (anchor)               -> token-minter
  spl_token_minter (anchor lib)           -> token_minter
  quasar-spl-token-minter                 -> quasar-token-minter
  quasar_spl_token_minter (Quasar.toml)   -> quasar_token_minter
  spl-token-minter-native-program         -> token-minter-native-program

Source identifiers:
  Anchor #[program] mod name              -> token_minter
  Anchor.toml [programs.localnet] key     -> token_minter
  Anchor test file: test_spl_token_minter.rs -> test_token_minter.rs
  Anchor test internal refs (spl_token_minter::*) -> token_minter::*
  Quasar #[program] mod name              -> quasar_token_minter
  Quasar test .so path                    -> quasar_token_minter.so
  Native processor enum SplMinterIntstruction (sic) -> MinterInstruction
  Native TS enum SplMinterInstruction     -> MinterInstruction
  Native TS describe('SPL Token Minter')  -> describe('Token Minter')
  Native TS it('Create an SPL Token!')    -> it('Create a token')

Cross-repo path references updated:
  README.md (root)
  tokens/nft-minter/README.md
  tokens/transfer-tokens/README.md
  tokens/create-token/quasar/src/lib.rs (prose path)
  .github/.ghaignore (two entries)

Verified:
  - cargo check inside tokens/token-minter/anchor compiles cleanly
  - git grep 'spl[-_]token[-_]minter' returns zero matches
  - rename is behaviour-preserving (no program logic changed)

Out of scope (pre-existing on this branch, unrelated to rename):
  - tokens/token-minter/quasar fails cargo check because quasar-spl on
    branch=master has the zeropod 0.3.0 regression; fix lands when PR #24
    is rebased into this branch's base.
  - tokens/token-minter/native/program does not standalone-compile because
    it is inside the repo's [workspace] but not listed as a member; same
    state as tokens/nft-minter/native/program. CI ignores it via .ghaignore.
mikemaccana pushed a commit that referenced this pull request May 15, 2026
The transfer-hook/block-list/pinocchio project was added with a program,
SDK, and a `package.json` test script pointing at `./tests/test.spec.ts`,
but the test file was never written. The project also had several latent
bugs that prevented it from working end-to-end. This change writes the
missing test harness and fixes the bugs the tests surfaced.

What this PR adds
- `tests/test.spec.ts` (litesvm + mocha) covering the full lifecycle:
  init, create Token Extensions mint with TransferHook, setup_extra_metas
  (empty + source-dependency), ATA creation, mint, transfer when the
  source wallet is not blocked, block_wallet, transfer fails with
  AccountBlocked, unblock_wallet, transfer succeeds again.
- `tests/run-mocha-with-retry.mjs` (CI test entry point) that wraps
  ts-mocha. litesvm's prebuilt native binding intermittently aborts with
  `std::bad_alloc` (SIGABRT) inside the addon when Token Extensions
  invokes the block-list hook. The crash is in the .node binary, not in
  our program, and a fresh Node process avoids it. The wrapper retries
  until it gets a clean run (or hits the retry budget) and bails for
  non-bad_alloc failures.
- `tests/tsconfig.test.json`.
- `pnpm-lock.yaml` regenerated with all required test deps.

Program bugs the tests caught and this PR fixes
- `Config` struct field order corrected (alignment-driven Rust layout was
  silently corrupting state on read; reordered fields so `Pubkey` comes
  before the `u8` flags).
- `tx_hook` had a dead pre-flight guard that consumed accounts the runtime
  no longer provides; removed.
- `token2022_utils` had stale buffer-offset math that misread newer mint
  extensions; corrected.
- `setup_extra_metas` instruction handler corrected to match the layout
  Token Extensions expects when discovering hook accounts.

Test output
```
  block-list pinocchio transfer hook
    init: initialises config PDA
    setup_extra_metas: writes the extra-account-metas account
    creates a Token Extensions mint with TransferHook -> block-list, plus extra metas
    transfer succeeds when source wallet is not blocked
    block_wallet: blocks wallet A, blocked_wallets_count increments
    transfer from blocked source wallet fails with AccountBlocked
    unblock_wallet: unblocks wallet A, blocked_wallets_count decrements, transfers work again
  7 passing
[run-mocha-with-retry] clean pass on attempt 2
```

References
- #18 (removed duplicate `pino/` subtree)
- #19 (moved program into `pinocchio/` subdir)
- #20 (renamed `pblock-list` -> `block-list`)
- #23 (CI logic fix that exposed missing tests)
- #24 (quasar-spl regression fix)

This PR makes block-list/pinocchio a real first-class example with
passing tests for the first time.
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