# Spell schema

A spell is a small JSON document with **relative values only** (percentages and shares), so the same spell works for any token and any size. The Machine view of a spell is exactly this JSON.

## Schema v1
```json
{
  "name": "Cautious entry",
  "description": "Buy, protect with a stop, and sell the position at your target.",
  "visibility": "public",
  "steps": [
    { "type": "cast", "params": { "side": "buy" } },
    { "type": "guard", "params": { "dropPct": 10, "sizePct": 100 } },
    { "type": "target", "params": { "risePct": 30, "sizePct": 100 } }
  ]
}
```

| Field       | Type                   | Rules                             |
| ----------- | ---------------------- | --------------------------------- |
| name        | string                 | 1 to 60 characters                |
| description | string                 | up to 280 characters              |
| visibility  | "public" or "unlisted" | unlisted spells open only by link |
| steps       | array                  | 1 to 8 steps                      |

Unknown fields are rejected everywhere. Absolute prices and amounts are not allowed.

Percentages are measured from the price when you cast the spell. After an Entry, Guard and Target are measured from the entry price.

## Cast
`{ "type": "cast", "params": { "side": "buy" | "sell" } }`

Swaps now, through the best available route, with the amount you choose at cast time. At most one Cast per spell. A sell Cast closes the position, so it cannot be followed by exits.

## Entry
`{ "type": "entry", "params": { "offsetPct": number } }`

Buys when the price moves `offsetPct` away from the current price: negative means below, positive means above. The range is −90 to 500, and the entry must be at least 0.5% away. An Entry cannot be combined with a Cast. After an Entry, use exactly one Guard and one Target of the same size; they are placed together with the entry.

## Guard
`{ "type": "guard", "params": { "dropPct": number, "sizePct": number, "trailing"?: boolean } }`

Sells `sizePct` (1 to 100) of the position if the price falls `dropPct` (0.5 to 90) below the reference price. With `trailing: true`, the level follows the highest price since the order was placed and never moves down. Use one Guard per spell.

A Guard is a stop order. It may not fill in a fast market, or may fill below its level. See [Risks](/docs/risks).

## Target
`{ "type": "target", "params": { "risePct": number, "sizePct": number } }`

Sells `sizePct` of the position when the price rises `risePct` (0.5 to 1000) above the reference price. A spell can have several Targets, for example 50% at +15% and 50% at +40%.

## Ladder
`{ "type": "ladder", "params": { "side": "buy" | "sell", "levels": [{ "offsetPct": number, "sizePct": number }] } }`

Splits one order across 2 to 10 price levels. Shares must add up to exactly 100%. Sell levels must be above the price and buy levels below it, and no two levels may share a price.

## How spells become orders
| Spell steps                                              | Orders placed                                                     | Wallet requests     |
| -------------------------------------------------------- | ----------------------------------------------------------------- | ------------------- |
| Cast                                                     | one swap                                                          | 1                   |
| Guard + Target of the same size                          | one one-cancels-other order                                       | 1 deposit           |
| Entry + Guard + Target                                   | one order that buys at the entry and then places Guard and Target | 1 deposit           |
| Guard or Target on their own, Targets of different sizes | one price order each                                              | 1 deposit each      |
| Trailing Guard                                           | one trailing stop order                                           | 1 deposit           |
| Ladder                                                   | one price order per level                                         | 1 deposit per level |
| Cast + exits                                             | the swap first, then exits sized on the amount actually received  | 1 + exits           |

When a spell needs several deposits and your wallet supports it, they are signed in a single wallet prompt.

## Validation rules
- Exits cannot sell more than the whole position, unless one Guard and one Target of equal size pair into a one-cancels-other order.
- Every order must be worth at least 10 USD at cast time (an order-engine rule).
- This release allows up to 250 USD per spell.

## Sharing
Publishing a spell stores its name, description and steps. Your wallet address is kept only so you can list and delete your own spells; it is never shown on the spell page, in its Markdown, in the API or in share images. Copying someone's spell copies the steps into your builder; it never mirrors their trades.
