Skip to content
This repository was archived by the owner on Sep 8, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion crates/solana-cli/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

- `shreds pay`: remove the command. `shreds withdraw`, `list`, `payments`, and `price` stay (malbeclabs/infra#2410)
- `shreds`: collapse `pay`'s `SLOT_DURATION_SECS` and `prepare-offchain-message`'s `SLOT_DURATION_MS` into one `NOMINAL_SLOT_DURATION` at 350ms, matching mainnet-beta from epoch 1020 (2026-08-21). Deliberately cluster-independent, because a `~` prefixed estimate and a deadline slot the CLI and operator must both compute want reproducibility over accuracy. `--valid-for 1h` now resolves to 10,285 slots rather than 9,000, and the epoch-remaining estimates shrink by an eighth. Testnet runs at 200ms, so its estimates stay wrong in the other direction, and SIMD-0525 will need one more bump here (malbeclabs/infra#2317)
- `shreds validator-client-rewards`: read the `ValidatorClientRewards` account through the SDK's zero-copy mirror instead of the hand-written byte-offset parser. Every subcommand now requires at least 184 bytes of account data rather than 116
- `shreds pay`: print the fastshreds.com transition notice, and require a y/N confirmation when the operator can actually answer it. The notice fires before the wallet is built and before the first RPC call, so declining needs neither a loadable keypair nor a reachable cluster and signs nothing. The prompt requires *both* stdin and stdout to be a terminal: the prompt is written to stdout, so under a redirect (`> pay.log`, `| tee`) the question would land in the file while `read_line` blocked on a terminal showing nothing. Dry runs print the notice without prompting, matching the epoch-remaining prompt, because a simulation signs and sends nothing. A non-terminal stdin also prints without prompting — `read_line` there returns EOF, which the helper reads as "no", and keypair-from-stdin requires a non-terminal stdin, so a prompt would consume the keypair bytes. `--accept-deprecation-notice` skips the prompt for interactive batch and multi-seat workflows; the notice still prints. Declining exits non-zero, matching the epoch-remaining prompt, so a `shreds pay ... && ...` chain does not treat a decline as a completed payment (malbeclabs/infra#2164)
- `shreds pay`: check the `--amount` floor against the price the program actually charges. A new instant seat allocation is priced from the metro/device ring entries at the execution controller's `last_settled_epoch` (the seat covers the remainder of the epoch currently being served), not from the newest entries — those two agree only while prices are static, so the epoch a metro repriced the preflight passed an underfunded amount through to an opaque `invalid account data for instruction`. A pure escrow top-up for an already-active seat submits no `RequestInstantSeatAllocation` and keeps its floor at the newest entry's price. When either ring has no entry for `last_settled_epoch` the command refuses to submit instead of falling back to the newest entry, mirroring the program's own error. The rejection message now names both prices and both epochs (#405)
- `shreds price`: new `Instant Price (USDC)` column (`instant_allocation_price` in `--json`) with the amount `shreds pay` charges right now, alongside the existing `Epoch Price` (unchanged: what the next settlement charges). The two differ for one epoch after a metro reprices. Empty when the execution controller or a ring entry for that epoch is missing; the rest of the listing still prints (#405)
- `shreds price`: new `Instant Price (USDC)` column (`instant_allocation_price` in `--json`) with the remainder-of-epoch price, alongside the existing `Epoch Price` (unchanged: what the next settlement charges). The two differ for one epoch after a metro reprices. Empty when the execution controller or a ring entry for that epoch is missing; the rest of the listing still prints (#405)
- RFC-20 verb contract: all CLI verbs now follow `execute(self, ctx: &CliContext, out: &mut impl Write)`. New global flags (`--env`, `--solana-url`/`--url`, `--dz-ledger-url`, `--keypair`) construct a `CliContext` at startup. Output uses `writeln!(out, ...)` for testability. Unblocks mounting into unified `doublezero` binary (#1517). Backwards compatible: invocations without the new global flags behave exactly as before — per-verb `--url`/`-u`, `--keypair`/`-k`, `--dz-env`, and `shreds --dz-ledger-url` keep their positions and their meaning, including everything the per-verb moniker implies (network environment, token mints, oracle key, serviceability program id, DZ Ledger URL), resolved per-verb from the moniker or the connection's genesis hash as before. The global flags only supply defaults; per-verb flags win.
- `--env` uses the DoubleZero environment taxonomy (`mainnet-beta`, `testnet`, `devnet`, `local`), matching the `doublezero` CLI: `--env devnet` selects the DZ devnet environment (Solana L1 = testnet). To target the Solana devnet cluster (e.g. the testnet shred-subscription program), keep using `-u devnet` after the subcommand.
- `shreds`: remove the testnet shred-subscription special-case that routed reads/writes to the DZ Ledger. The testnet shred-subscription program now lives on Solana devnet, so the `-u`/`--url` option resolves to the network's Solana RPC URL for all monikers; reach the testnet program with `-u devnet`. Write subcommands now build their `Wallet` directly from `-u`/`--url` (`Wallet::try_new(opts, None)`) and read subcommands from `SolanaConnection::from(connection_options)`, collapsing the redundant second connection that the special-case required. Device codes still resolve against the DZ Ledger via `--dz-ledger-url`. Mainnet behavior is unchanged (#1763)
Expand Down
20 changes: 0 additions & 20 deletions crates/solana-cli/src/command/shreds/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
pub mod list;
pub mod pay;
pub mod payments;
pub mod price;
pub mod publisher_rewards;
Expand Down Expand Up @@ -55,8 +54,6 @@ impl ShredsCommand {

#[derive(Debug, Subcommand)]
pub enum ShredsSubcommand {
/// Initialize a client seat (if needed) and fund a payment escrow with USDC.
Pay(pay::PayCommand),
/// Close a payment escrow and withdraw any remaining USDC.
Withdraw(withdraw::WithdrawCommand),
/// List client seats.
Expand All @@ -79,7 +76,6 @@ impl ShredsSubcommand {
out: &mut impl Write,
) -> Result<()> {
match self {
Self::Pay(command) => command.execute(dz_ledger_url, ctx, out).await,
Self::Withdraw(command) => command.execute(dz_ledger_url, ctx, out).await,
Self::List(command) => command.execute(dz_ledger_url, ctx, out).await,
Self::Payments(command) => command.execute(dz_ledger_url, ctx, out).await,
Expand Down Expand Up @@ -137,22 +133,6 @@ pub(in crate::command::shreds) fn make_dz_connection(
}
}

/// Known shred oracle pubkey per environment. Returns `None` on localnet
/// (the multicast-user guard is already skipped there because
/// `serviceability_program_id` returns `Err`).
pub(in crate::command::shreds) fn shred_oracle_key(env: NetworkEnvironment) -> Option<Pubkey> {
match env {
NetworkEnvironment::MainnetBeta => Some(solana_sdk::pubkey!(
"3b2Ze7VYUvhwQBfx5oCMCmsc2xvyZ74s2Lata5vmQeeN"
)),
NetworkEnvironment::Testnet => Some(solana_sdk::pubkey!(
"BUtAWK4GaUV42YRp7jSHZhchspsshabn67HnBHnKxzsY"
)),
NetworkEnvironment::Devnet => None,
NetworkEnvironment::Localnet => None,
}
}

/// Parse the CLI's build version into (major, minor, patch).
///
/// Handles version strings like "0.5.0" or "0.5.0-rc1" by only considering
Expand Down
Loading
Loading