> For the complete documentation index, see [llms.txt](https://docs.northstar.sonicsvm.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.northstar.sonicsvm.org/concepts/delegation.md).

# Account Delegation

Delegation is what makes a Solana account writable inside a NorthStar session. Without it, the ER can read the account (inherited from L1) but cannot mutate it. With it, the ER has exclusive write authority for the session's lifespan, and L1 cannot modify the account until the session closes.

## The two-sided rule

Every delegated account has the same two properties for the session's duration:

|           | On L1                     | On ER |
| --------- | ------------------------- | ----- |
| **Read**  | Yes                       | Yes   |
| **Write** | **No — locked by Portal** | Yes   |

This is the core property the Portal program enforces. No L1 transaction signed by anyone — including the original owner — can mutate a delegated account. The ER is the single source of writes.

## What can be delegated

| Account type                      | Delegated? | Notes                                                                                                                 |
| --------------------------------- | ---------- | --------------------------------------------------------------------------------------------------------------------- |
| **PDAs your program owns**        | Yes        | Pool PDA, vault PDA, custom state. Requires a `delegate_to_portal` hook in the owning program.                        |
| **Keypair-owned signer accounts** | Yes        | E.g. an agent keypair that signs `place_intent` ixs inside the ER. Delegated via the Portal's `Delegate` instruction. |
| **SPL token accounts**            | Yes        | Each token account gets its own delegation.                                                                           |
| **SPL token mints**               | No         | Mints are not delegated — inherited as read-only into the ER on first reference.                                      |
| **The owner keypair itself**      | No         | Owner stays system-owned on L1 so it can sign close/undelegate ixs.                                                   |

## How delegation lands on chain

Three coordinated state changes per delegation:

1. **Account ownership** — the account's `owner` field is reassigned from the original program (or `SystemProgram`) to the Portal program. This is what locks it on L1.
2. **A delegation record** — a Portal-owned PDA at `delegationRecordPda(portal, account)` is created with `(grid_id, owner_program, bump)`. This is the on-chain proof of delegation.
3. **A buffer account** — a transient account holding rent for the buffer-dance pattern that survives the ownership transfer.

## Undelegation

When the session closes (explicit `CloseSession` or TTL expiry), each delegated account undergoes the reverse:

1. Final state from the ER is committed to the L1 account.
2. Ownership is restored to the original program.
3. The delegation record is closed; rent goes back to the owner.

If the session expires without explicit close, the Portal allows **forced undelegation** by the owner — see [security model](/architecture/security.md) for the formal guarantees.

## Common patterns

* **Pool + vault delegation** — for an AMM running inside a session, both the pool PDA and the vault PDA delegate to the same `grid_id`. The agent keypair that signs `place_intent` also delegates so it can sign on the ER.
* **Token account delegation** — every SPL token account that holds delegated funds also delegates. The mints stay on L1.
* **Per-user delegation** (Phase 5) — a per-user session opens and delegates only that user's accounts; isolation between users is enforced at the session boundary.

## Constraints

* **Programs need a `delegate_to_portal` hook.** Portal's `Delegate` instruction only accepts accounts owned by the calling program. Third-party programs (Jupiter, Raydium) without this hook can't be delegated. Workaround: separate agent reasoning (in the ER) from external execution (on L1) — see the [Mach Sandbox architecture](https://github.com/mirrorworld-universe/mach-amm).
* **Re-delegation requires undelegate first.** An account already delegated to grid 1 cannot be re-delegated to grid 2 directly; close + reopen.

## See also

* [Sessions](https://github.com/mirrorworld-universe/northstar-docs/blob/main/concepts/sessions/README.md)
* [Settle-back guarantees](https://github.com/mirrorworld-universe/northstar-docs/blob/main/concepts/settle-back/README.md)
* [Portal program reference](https://github.com/mirrorworld-universe/northstar-docs/blob/main/reference/portal-program/README.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.northstar.sonicsvm.org/concepts/delegation.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
