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

# Wrap SOL into the Pot's WSOL on Solana

> A Solana cook that moves SOL from the owner into the Pot's WSOL account with two program calls and checks that the WSOL balance rose by the amount.

The program transfers `lamports` of SOL from the owner to the Pot's WSOL account and has SPL Token count them as WSOL. The cook reverts when the owner holds less than `lamports` or the Pot's WSOL balance does not rise by exactly `lamports`.

**Target chains:** Solana. Use `--chain solana`; the recorded simulation is described below.

## Prerequisites

You need the `sauce` command (`npm install -g @eco-incorp/sauce`), a Solana key holding the SOL to wrap (a keypair file, or `sauce wallet new <name> --solana`). See [Installation](https://docs.eco.com/sauce-sdk/installation.md).

## Program

```ts solana-wrap-sol.sauce.ts theme={null}
// Wraps `lamports` of the owner's SOL into the Pot's WSOL account: the System Program's transfer,
// which the owner signs, then SPL Token's SyncNative, which counts the account's new lamports as
// WSOL. Each account is written where it is used, and compiling adds it to main with how it is
// derived, so the command is given none. The cook reverts, and nothing moves, when the owner holds
// less than `lamports` or the Pot's WSOL balance does not rise by exactly `lamports`.
//
//   sauce simulate solana-wrap-sol.sauce.ts --chain solana --owner <pubkey> \
//     --assume-balance WSOL:0 --args <lamports>
//   sauce run solana-wrap-sol.sauce.ts --chain solana --keypair <keypair> --args <lamports>
//
//   --assume-balance WSOL:0 lets the simulation run before the Pot's WSOL account exists, as it
//   is before a first run: `sauce run` creates that account before the cook.
//
//   lamports: Uint256   the SOL to wrap, in lamports (9 decimals): 10000000 is 0.01 SOL
//
// Wrap 0.01 SOL:
//
//   sauce run solana-wrap-sol.sauce.ts --chain solana --keypair <keypair> --args 10000000
function main(lamports: Uint256): { wrapped: Uint256; balance: Uint256 } {
  const potWsol = WSOL.accountOf(pot).writable();
  const before = pot.WSOL;

  // The System Program's transfer: instruction 2 (4 bytes), then the lamports (8 bytes).
  let transfer = hex`02000000`;
  svm.call(
    Account.systemProgram,
    [pot.owner.writable().signer(), potWsol],
    transfer.concat(lamports.toBytesLe(8)),
  );
  // SPL Token's SyncNative: instruction 17.
  svm.call(Account.tokenProgram, [potWsol], hex`11`);

  const balance = pot.WSOL;
  require(balance - before == lamports, "WSOL balance did not rise by lamports");
  return { wrapped: balance - before, balance };
}
```

## How it works

* No token method wraps SOL, so the program makes the two calls itself with `svm.call`: the System Program's transfer (instruction 2 as 4 bytes, then the lamports as 8 little-endian bytes), signed by the owner, then SPL Token's SyncNative (instruction 17, `` hex`11` ``).
* Each account is written where it is used: `WSOL.accountOf(pot).writable()`, `pot.owner.writable().signer()`, `Account.systemProgram`, `Account.tokenProgram`. Compiling adds five accounts to `main`, each derived, so the command is given none.
* `accountOf` names an account that exists: its check reads the Pot's WSOL account when the program starts, and `sauce run` creates a missing one before the cook.
* The program reads `pot.WSOL` once after the calls and returns both values from that read. That keeps the cook at 1,173 of 1,232 bytes, small enough that one transaction also creates a new Pot ahead of the cook.

## Run the example

**1. Compile**

```bash theme={null}
sauce compile solana-wrap-sol.sauce.ts --chain solana
sauce compile solana-wrap-sol.sauce.ts --chain solana --json --args 10000000 \
  --account potWSOL=pot:WSOL --account owner=owner
```

The `--json` output gives the program's size, the payload with the argument, and the cook against Solana's transaction limit:

```text theme={null}
  "size": 665,
  "payload": {
    "size": 697,
    "argumentsSize": 32
  },
  "cook": {
    "via": "kitchen",
    "size": 1173,
    "limit": 1232,
    "fits": true,
    "assumed": [],
    "remaining": false
  },
```

**2. Simulate**

```bash theme={null}
sauce simulate solana-wrap-sol.sauce.ts --chain solana --owner <your-pubkey> \
  --assume-balance WSOL:0 --args 10000000
```

`--assume-balance WSOL:0` runs the cook in a local LiteSVM copy of the cook's accounts, read from the cluster, with the Pot's WSOL account made empty where it does not exist, as `sauce run` creates it before the cook. The owner must hold the lamports.

**3. Send**

```bash theme={null}
sauce run solana-wrap-sol.sauce.ts --chain solana --keypair <keypair> --args 10000000
```

`--wallet <name>` signs with a Solana wallet instead. `sauce tx` with `--owner <your-pubkey>` in place of `--keypair <keypair>` planned two steps for a new Pot: a setup transaction that creates the Pot's WSOL account, then one transaction that creates the Pot and runs the cook.

## Simulation result

Simulated on Solana at slot 462066340 with the command above, in a local LiteSVM copy. Nothing was signed or sent; values change with the slot. Lines that name the owner are left out.

```text theme={null}
...
main returns { wrapped: Uint256, balance: Uint256 }: { wrapped: 10000000, balance: 10000000 }
Left in the Pot, not in the owner's wallet:
  0.01 WSOL, in 84T6jwW8KWo6avpkoN4e3TckfyQVsobBKyoondoWjYcX
  Only another cook moves it out. To end in a wallet, the program must send it there, or name the wallet as the recipient of the call that produces it.
Simulated in a local copy (LiteSVM) of the 5 accounts the cook names, read from solana at slot 462066340, with the released engine and Kitchen: a cluster's simulation takes no balance to assume. Nothing was signed or sent:
  Kitchen create_pot: Pot BjFSkVpfmbX19SuADFxTsfzWdTErjdELMyd4Nd4iXo9T is not created on solana yet, so the copy creates it first
  the 697-byte program staged into a code buffer in 3 transactions, as `sauce run` stages it
...
Token balance changes:
  84T6jwW8KWo6avpkoN4e3TckfyQVsobBKyoondoWjYcX (potWSOL, the Pot's WSOL account), owned by BjFSkVpfmbX19SuADFxTsfzWdTErjdELMyd4Nd4iXo9T (the Pot): +0.01 WSOL
...
```

The Pot's WSOL account rose by exactly 10000000 lamports, 0.01 SOL. The full output's lamport changes show the owner paying that plus the Kitchen's 85672-lamport execution fee and the 5000-lamport transaction fee. The local copy ran the program from a code buffer; `sauce tx` plans the sent cook without one, as above.

Asking to wrap 100,000 SOL (`100000000000000`), more than the owner holds, at slot 462066347:

```text theme={null}
The cook reverts: program 11111111111111111111111111111111 failed with custom program error 1 (0x1); the logs say why
...
  Program 11111111111111111111111111111111 invoke [3]
  Transfer: insufficient lamports 14209759940, need 100000000000000
  Program 11111111111111111111111111111111 failed: custom program error: 0x1
...
```

The System Program refuses the transfer, and the whole cook reverts with it.

## Next steps

* [Solana swap](https://docs.eco.com/quickstarts/sauce/solana-swap.md): spend the Pot's tokens at an Orca whirlpool
* [Solana payment](https://docs.eco.com/quickstarts/sauce/solana-payment.md): pay tokens from the Pot with token methods
* [Builtins](https://docs.eco.com/sauce/builtins.md), [Pot](https://docs.eco.com/sauce/pot.md), [`sauce simulate`](https://docs.eco.com/sauce-sdk/cli/simulate)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.