NVDAon → QQQon) — not selling to USDC and rebuying. In the BYOW model it is
self-custody — the user’s wallet signs every transaction and Cesto never holds the key;
in the managed model Cesto signs server-side.
- Managed (recommended)
- BYOW (client-signed)
For Cesto-managed wallets (provisioned via There is no
users.create),
Cesto signs server-side — one call, then poll:done flag to check and no batch to sign — the managed call enqueues the
migration directly. If the position is already on the latest version there is nothing
to migrate. The read-only previews below (getAvailability, getHistory) accept any
Solana address, including a managed wallet’s solanaAddress, so you can still show
users what a rebalance would do before calling it.Full managed reference: Managed Wallets.Existing Cesto users
When the wallet belongs to a Cesto account holder, the user approves once by signing a message and Cesto runs the rebalance with their Cesto wallet — no per-transaction signing. Samerebalance.start as the managed flow, plus a consent field:
What the user approves here is different in one way that matters. The message says
“migrate my position in this basket to whatever its latest version is.” The target
version is deliberately not part of the approval, because the backend resolves it when
the job is enqueued. A user approving a rebalance is approving the move, not a specific
destination version.
prepare, it is not
limited to swap-only baskets — this path runs the same machinery as the Cesto app, so
prediction and perps baskets rebalance here too.
Previewing a rebalance
rebalance.getAvailability is a read (works with a read-only key, and accepts any
Solana address — BYOW or managed). Use it to show the user what a rebalance would do before
they commit — the target version, the token diffs, and whether they’re eligible.
available is false, reason explains why (e.g. no_positions, no_newer_version,
rebalance_in_progress). When eligible is false, eligibilityErrors lists the blockers
(and ineligibleReason is populated when the invested amount is below the new version’s
minimum).
rebalance.getAvailability(params)
string
required
Solana address of the wallet whose position would be rebalanced.
string
required
Basket to rebalance — product id or slug.
{ available, reason?, currentVersionId?, targetVersionId?, currentVersionLabel?, targetVersionLabel?, tokensToSell, tokensToBuy, tokensUnchanged, positions, totalInvested, estimatedPlatformFee, eligible, eligibilityErrors?, ineligibleReason? }.
Rebalance history
rebalance.getHistory lists the wallet’s past rebalances of the basket — each version move,
the swaps, fees, and on-chain signatures.
getHistory takes the same { wallet, product } params as getAvailability and returns
{ history }.
Execution results
Terminal statuses areCOMPLETED, PARTIALLY_COMPLETED, and FAILED — exactly as for an
open, in both models.
To read the resulting position, use
positions.getHoldings — SDK positions are
self-custody and do not appear in positions.list.
Constraints
- Swap-only baskets. No prediction markets, lending, or perps.
- Needs a position on an older version and a newer version published for the basket —
otherwise
getAvailabilityreturnsavailable: falseand (BYOW)preparereturnsdone: true. - One in-flight execution per wallet + product.
- Gas sponsored — Cesto pays network gas + ATA rent; the wallet needs no SOL (unless the deployment runs without a sponsor).
Related
- Managed Wallets — the recommended server-signed flow.
- Open a Position — the client-signed model, gas, and
signWithKeypair. - Close a Position — sell the wallet’s full basket holding.
- Positions — read a wallet’s live per-basket holdings.