users.create once per user, fund the wallet, and open /
close / rebalance by user reference.
This is the path to pick when your end users only have an EVM wallet (e.g. on Base) and
you don’t want to run Solana wallet infrastructure. It is also the recommended path in
every how-to on this site — the “Managed” tab comes first wherever both flows are shown.
Prerequisites
- A write-scoped API key. Every call on this page except
users.getis a write route — read-only keys get a403(PermissionDeniedError). Keys are created and scoped in the Cesto dashboard or by the Cesto team — see Authentication. - A provisioning quota. Each write key has a managed-user quota (contact the Cesto team
to set or raise it). When it’s full,
users.createfails with a403, codePROVISIONING_QUOTA_EXCEEDED. - Server-side execution. Managed calls run from your backend — the API key must
never ship to a browser or mobile client. Read it from the environment
(
process.env.CESTO_API_KEY), never hardcode it, and keep it out of version control. - USDC on Base in the user’s EVM wallet (or another supported funding route) — this is what gets bridged in and invested.
Provisioning users
users.create idempotently provisions a Cesto-managed Privy Solana wallet for a user,
keyed to their EVM wallet address:
- Idempotent — calling
createagain for the same EVM wallet returns the same record withcreated: false. It’s safe to call on every login. - One wallet per (partner, EVM wallet) — the mapping is fully isolated per API key: another partner provisioning the same EVM address gets a different, unrelated user.
- Quota — each write key has a provisioning quota. When it’s full,
createfails with a403(codePROVISIONING_QUOTA_EXCEEDED) — talk to the Cesto team to raise it. - Rate limit —
users.createis limited to 10 requests/minute per key.
users.get resolves by EVM wallet address:
users.get works with a read-scoped key. A 404 means this EVM wallet was never
provisioned under your key — even if another partner provisioned it, it isn’t yours.
Endpoint reference
Funding the wallet
Users fund their managed wallet by bridging USDC from their EVM wallet with the existing bridge flow (Base → Solana, Circle CCTP). Two things matter:recipientis the provisionedsolanaAddress.sourceAddressis the user’s EVM wallet — the user signs the burn on Base, as usual.
- Managed
- BYOW
Funding is the one step that looks the same in both models: the funds come from the
user’s EVM wallet, so the user always signs the EVM-side burn. The managed part is
only the destination — the provisioned When the transfer completes, invest what arrived —
solanaAddress.done.netOut — not the burn
amount (fast mode deducts its fee at mint).Opening, closing, rebalancing
Managed positions are custodial: Cesto signs for the provisioned wallet server-side, so no user signature,signTransactions callback, or split flow is needed. Each call returns
an { executionId } and the execution runs in the background. All three are write
routes.
- Managed
- BYOW
start is the single server-signed entry point, and it covers two kinds of user.
Managed users are the case with no consent field: Cesto holds their key, so
there is nothing for them to sign and your API key is the sole authority. A Cesto
account holder — someone with their own wallet — must instead approve each action by
signing a challenge, passed as consent. See
Existing Cesto users.user field accepts any of your user’s identifiers:- the
externalUserIdyou passed at provisioning, - the user’s EVM wallet address, or
- the provisioned Solana address.
amount, no partial close) and rebalance migrates the position to the basket’s
latest version. amount on open is a bigint in input-token base units.Full reference: Opening, closing, rebalancing on this
page — the rest of this section applies to the managed flow.Managed executions are scoped per API key — one partner never sees another’s users or
executions. A
user that doesn’t resolve to one of your provisioned users fails with
a 404 (code MANAGED_USER_NOT_FOUND).Waiting for the result
The*AndWait convenience variants kick off the operation and then poll the existing
execution-status endpoint until a terminal status — COMPLETED, PARTIALLY_COMPLETED, or
FAILED:
close.startAndWait and rebalance.startAndWait take the same params as their start
counterparts. To
poll an execution you kicked off with the plain variants, use the shared
positions.getExecution / positions.waitForExecution
with the returned executionId — polling is identical in both models.
Withdrawing
Withdrawal is the mirror image of funding — and needs no user signature at all in the managed model:1
Close the position
close.start (or close.startAndWait) sells the full holding back to USDC on the
managed wallet.2
Bridge back to EVM
Use
bridge with sourceChain: 'solana', destChain: 'base', the
managed wallet as sourceAddress, and the user’s EVM wallet as recipient.- Managed
- BYOW
For a managed Solana source wallet, Cesto signs and lands the burn itself (sponsor
pays gas and the CCTP message-account rent — managed wallets hold no SOL):
initiate
returns { status: 'BURN_SUBMITTED', burnTxHash, burn: null }, so skip submitBurn
and go straight to waitForTransfer.Errors
See Errors & Retries for the typed error hierarchy and retry behavior.
Rate limits
Per API key:
Exceeding a limit returns
429 (RateLimitError) with a retryAfter hint. Because
users.create is idempotent, call it on login rather than caching a lookup table of your
own — 10/minute is ample for user-driven provisioning.
Security notes
- Server-side only. Every managed call carries your API key; never expose it to a
browser, mobile app, or logs. Load it from the environment
(
process.env.CESTO_API_KEY), as in every example on this page. - Write scope gates every mutation. Provisioning, opening, closing, rebalancing, and bridging all require a write-scoped key. Keep a separate read-scoped key for status reads and dashboards if you want least-privilege separation.
- No keys to leak on your side. The managed wallet’s key material lives in Cesto’s Privy custody and never crosses your infrastructure — there is nothing in your stack to exfiltrate. Treat the API key itself as the sensitive secret.
- Per-key isolation. Users, executions, and bridge transfers are visible only to the API key that created them.
End-to-end example
Provision a user, bridge USDC in from their EVM wallet, open a position, then close it and bridge back out — no key handling anywhere on your side:Related
- Integration Models — how managed wallets compare to BYOW setups.
- Bridging (CCTP) — the funding and withdrawal rail.
- Open a Position — the client-signed (BYOW) flow, and the shared execution-status methods.
- Positions — read a user’s live per-basket holdings.