Skip to content

feat: add --tx-version option to build legacy transactions - #109

Merged
lorisleiva merged 3 commits into
solana-program:mainfrom
bangyro:feat/legacy_tx
Aug 29, 2026
Merged

feat: add --tx-version option to build legacy transactions#109
lorisleiva merged 3 commits into
solana-program:mainfrom
bangyro:feat/legacy_tx

Conversation

@bangyro

@bangyro bangyro commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a global --tx-version <version> option to the CLI so users can build legacy transactions instead of version 0 transactions. Squads v3 only accepts legacy transactions when importing a base58 encoded transaction, so exports for a v3 multisig failed to import.

Usage

npx @solana-program/program-metadata@latest write idl <program-address> \
  --buffer <buffer-address> \
  --export <multisig-address> \
  --export-encoding base58 \
  --close-buffer <your-address> \
  --tx-version legacy

@lorisleiva

Copy link
Copy Markdown
Member

@trevor-cortex

@trevor-cortex trevor-cortex left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Summary

Adds a global --tx-version <version> CLI option (legacy | 0, default 0) so exported transactions can be built as legacy transactions — needed because Squads v3 only accepts legacy transactions when importing base58-encoded transactions. The option is threaded into the transaction planner via a new getTransactionConfig helper, and the README documents both the flag and the Squads v3 workflow.

The implementation looks solid:

  • TransactionPlannerConfig in @solana/kit-plugin-rpc accepts version: 0 | 'legacy' (defaulting to 0), so passing the parsed value through is correct, and the explicit version: 0 default preserves the previous behavior.
  • The .choices() + .default() + .argParser() pattern matches the existing house style in options.ts (compressionOption, encodingOption, etc.). Nice touch using the parsed representation (0 as a number) for the default value, since Commander doesn't run argParser on defaults — an easy trap to fall into.
  • The custom InvalidArgumentError message mirrors Commander's own choices-validation wording, which matters since .argParser() replaces the validator that .choices() installs.

Notes for reviewers

  • One non-blocking inline suggestion on getTransactionConfig: the exhaustive switch is a nice future-proofing pattern, but since this tsconfig doesn't enable noImplicitReturns, the compiler won't actually catch the missing case when a version 1 is added later — see inline comment.
  • Out of scope for this PR, but adjacent to the new code path: priorityFeesOption uses .default('100000') with a string default, and since Commander doesn't run argParser on defaults, microLamportsPerComputeUnit receives the string '100000' (not a MicroLamports bigint) whenever the flag isn't passed. Pre-existing behavior, just worth a follow-up look.

Comment thread clients/js/src/cli/utils.ts

@lorisleiva lorisleiva left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

That's a great improvement and it'll make it easier for us to add tx v1 support so thank you!

@lorisleiva
lorisleiva merged commit a100cb2 into solana-program:main Aug 29, 2026
21 checks passed
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.

3 participants