> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cesto.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Integration Models

> Pick the wallet model that fits your users — managed wallets (Cesto-managed Privy, recommended), your own Privy, browser EOAs, or cross-chain EVM funding.

Every SDK open, close, and rebalance lands a **Solana transaction from a Solana wallet** —
that never changes. What differs between partners is two things:

1. **Who provisions and controls the Solana wallet** that signs.
2. **How the user's funds arrive** on that wallet.

This page maps the common partner setups onto the SDK flows — [Managed
Wallets](/sdk/managed-wallets) for the recommended server-signed path, and [Open a
Position](/sdk/open-position) / [Close a Position](/sdk/close-position) for the
client-signed (BYOW) flows — so you can tell which path is yours before you write any code.

<Info>
  Whatever the model, the wallet needs the basket's **input token (USDC)** to open. Cesto
  **sponsors the network gas and ATA rent** — the wallet needs **no SOL**.
</Info>

## The models at a glance

<CardGroup cols={2}>
  <Card title="Managed wallets (recommended)" icon="wand-magic-sparkles" href="/sdk/managed-wallets">
    Cesto provisions a Solana wallet per user via Privy and signs server-side. You call
    open/close by user — no key handling on your side.
  </Card>

  <Card title="Your own Privy (BYOW)" icon="server">
    You provision embedded / server wallets in your own Privy app and sign inside the
    one-call flow's `signTransactions` callback.
  </Card>

  <Card title="Browser EOA (BYOW)" icon="wallet">
    The user connects Phantom / Solflare and signs in the browser. Your backend runs the
    split `prepare → sign → submit → poll` flow.
  </Card>

  <Card title="Cross-chain (EVM → Solana)" icon="right-left">
    Users hold USDC on Base. Bridge it in with the SDK's native CCTP bridging — naturally
    paired with a managed wallet as the destination.
  </Card>
</CardGroup>

| Model                                 | Solana wallet owner                  | Who signs                      | SDK flow                                                          |
| ------------------------------------- | ------------------------------------ | ------------------------------ | ----------------------------------------------------------------- |
| Managed wallets (Cesto-managed Privy) | Cesto (Privy)                        | Cesto, server-side             | [`*.start`, no `consent`](/sdk/managed-wallets)                   |
| Your own Privy                        | You (your Privy app)                 | Your backend, via Privy        | [One-call](/sdk/open-position#one-call-flow-you-hold-the-keypair) |
| Browser EOA                           | The end user                         | The user, in the browser       | [Split flow](/sdk/open-position#split-flow-browser-wallet-signs)  |
| Cross-chain (EVM)                     | Depends on the SVM wallet you map to | Owner of the mapped SVM wallet | Any of the above, after bridging                                  |

## Managed wallets (Cesto-managed Privy) — recommended

Cesto provisions a **Solana (Privy) wallet per user** and handles signing on its side. Your
integration only ever deals in **user references** — an external user id, the user's EVM
wallet, or the provisioned Solana address — you never touch a private key or run a signing
callback.

This is the lightest path to integrate, and the one to pick if your users only have EVM
wallets or you don't want to run wallet infrastructure yourself.

<Steps>
  <Step title="Provision a wallet for each user">
    Call [`cesto.users.create({ evmWalletAddress })`](/sdk/managed-wallets#provisioning-users)
    — idempotent, one wallet per (partner, EVM wallet). Store the returned `solanaAddress`
    against your user record.
  </Step>

  <Step title="Fund the wallet">
    The user bridges **USDC** from their EVM wallet into the provisioned address with the
    [bridge flow](/sdk/bridging) (see [Cross-chain](#cross-chain-users-evm-to-solana)).
    Cesto sponsors gas, so the wallet needs no SOL.
  </Step>

  <Step title="Open / close by user">
    Call [`open.start` / `close.start` / `rebalance.start`](/sdk/managed-wallets#opening-closing-rebalancing)
    with the user reference. Signing is handled on the Cesto side — no `signTransactions`
    callback, no split flow.
  </Step>
</Steps>

Full reference and an end-to-end example: [Managed Wallets](/sdk/managed-wallets).

## Bring your own wallet (BYOW)

You already have wallets for your users — either embedded/server wallets in your own Privy
app, or self-custody browser wallets — and want them to stay **self-custody**. Cesto builds
the unsigned transactions; **your side produces the signatures**.

### Your own Privy

You provision and control the Solana wallets in **your own Privy app** (embedded or server
wallets). Because your backend can sign on the user's behalf, use the **one-call flow** and
delegate signing to Privy inside the `signTransactions` callback:

```ts theme={null}
const result = await cesto.open.execute({
  wallet: userSolanaAddress,
  product: 'stable-genius',
  amount: 100_000_000n, // 100 USDC @ 6 decimals
  // Receive Cesto's prepared txs, sign each with your Privy wallet, return them base64.
  signTransactions: async (transactions) =>
    Promise.all(
      transactions.map(async ({ nodeId, transaction }) => ({
        nodeId,
        signedTransaction: await signWithPrivy(userSolanaAddress, transaction),
      })),
    ),
});
```

`signWithPrivy` is your own helper over Privy's server-side signing — the SDK never sees the
key. See the [one-call flow](/sdk/open-position#one-call-flow-you-hold-the-keypair) for the
full callback contract.

### Browser EOA (Phantom or Solflare)

The end user holds a self-custody wallet and signs in the **browser**. The SDK runs on your
backend and hops out to the wallet for signatures — this is the **split flow**:

```
prepare (backend) ─▶ sign (browser wallet) ─▶ submit (backend) ─▶ poll (backend)
```

Prepared transactions expire \~60s after `prepare`, and the wallet must sign them
**byte-for-byte** — any modification is rejected at submit. Walk through it in
[Open a Position → Split flow](/sdk/open-position#split-flow-browser-wallet-signs).

## Cross-chain users (EVM to Solana)

Some partners' users hold funds on **Base**, not Solana. The SDK's
[bridging resource](/sdk/bridging) moves their **USDC** onto Solana natively (Circle CCTP —
the user signs one burn on the EVM chain, Cesto attests and mints on Solana) — no
third-party bridge, no SOL needed on the destination.

Bridging pairs naturally with **managed wallets**: the user's EVM wallet is the provisioning
key *and* the funding source, so one identifier covers the whole lifecycle.

The pattern:

<Steps>
  <Step title="Provision a managed wallet from the EVM address">
    `cesto.users.create({ evmWalletAddress })` gives the user a Solana (Privy) wallet keyed
    to their EVM wallet — no Solana wallet infrastructure on your side. This SVM address is
    the **bridge destination**.

    ```text theme={null}
    end user  ──▶  EVM wallet (Base)  ──▶  Cesto-managed (Privy) Solana wallet
              provisioning key              bridge destination
    ```
  </Step>

  <Step title="Bridge USDC into the managed wallet">
    Use [`bridge`](/sdk/bridging): `quote → initiate` with `recipient` = the provisioned
    `solanaAddress` and `sourceAddress` = the user's EVM wallet → the user signs the burn on
    the EVM chain → `submitBurn → waitForTransfer`. Cesto's relayer pays the Solana-side gas
    and creates the USDC token account if it's the user's first transfer.
  </Step>

  <Step title="Open / close on Solana">
    Once USDC is on the managed wallet, call
    [`open.start` / `close.start`](/sdk/managed-wallets#opening-closing-rebalancing) with
    the user reference, investing the **arrived** amount (`netOut`). Read holdings any time
    with [`positions.getHoldings`](/sdk/positions#position-by-product-sdk-positions).
  </Step>
</Steps>

With a BYOW setup the bridge works the same way — `recipient` is the BYOW Solana wallet and
the arrived funds are invested via the client-signed [open flow](/sdk/open-position).

## Choosing a model

* **Don't want to run wallet infra, or users only have EVM wallets?** →
  [Managed wallets](#managed-wallets-cesto-managed-privy--recommended).
* **Already have Privy embedded/server wallets?** → [Your own Privy](#your-own-privy),
  one-call flow.
* **Users bring self-custody wallets (Phantom / Solflare)?** →
  [Browser EOA](#browser-eoa-phantom-or-solflare), split flow.
* **Users' money is on an EVM chain?** →
  [Cross-chain](#cross-chain-users-evm-to-solana): provision, bridge, then invest.

Whichever you pick, execution results and error handling are the same — see [Managed
Wallets](/sdk/managed-wallets), [Open a Position](/sdk/open-position), [Rebalance a
Position](/sdk/rebalance-position), and [Errors & Retries](/sdk/errors).
