> For the complete documentation index, see [llms.txt](https://docs.evefrontier.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.evefrontier.com/smart-assemblies/storage-unit/build.md).

# Build

Step-by-step instructions for building a custom Storage Unit extension. For concepts and design, see the [Storage Unit README](/smart-assemblies/storage-unit.md).

## Prerequisites

* Follow [environment-setup](/quickstart/environment-setup.md)
* For typed-witness and publish flow, see the [Gate build guide](/smart-assemblies/gate/build.md) and [builder-scaffold](https://github.com/evefrontier/builder-scaffold) — use them as the source of truth for setup and build steps.

## High-level steps

1. **Define a witness struct** (e.g. `public struct VendingAuth has drop {}`) in your Move package.
2. **Implement your logic** so it calls the [world storage unit module](https://github.com/evefrontier/world-contracts/blob/main/contracts/world/sources/assemblies/storage_unit.move) to deposit or withdraw items using your `Auth` witness (e.g. after checking payment, tribe, or other rules).
3. **Publish** the package and **authorize** it on the storage unit: borrow the storage unit’s `OwnerCap` and call `storage_unit::authorize_extension<YourAuth>`.

After authorization, only your extension’s logic can perform deposits/withdrawals for non-owner characters; the world module checks the `Auth` type.

## Storage Unit API

Custom contracts use the **typed witness pattern**: define a witness struct (`Auth`) and register it on the storage unit.

**Authorize an extension:**

```move
public fun authorize_extension<Auth: drop>(
    storage_unit: &mut StorageUnit,
    owner_cap: &OwnerCap<StorageUnit>,
)
```

**Extension: deposit / withdraw** (main inventory; your extension calls these with your `Auth` witness):

```move
public fun deposit_item<Auth: drop>(
    storage_unit: &mut StorageUnit,
    character: &Character,
    item: Item,
    _: Auth,
    _: &mut TxContext,
)

public fun withdraw_item<Auth: drop>(
    storage_unit: &mut StorageUnit,
    character: &Character,
    _: Auth,
    type_id: u64,
    quantity: u32,
    ctx: &mut TxContext,
): Item
```

**Extension: deposit into a player’s owned inventory** Lets the extension push items into a specific character’s owned inventory; the recipient does not need to be the transaction sender. Use for async delivery, guild hangars, rewards:

```move
public fun deposit_to_owned<Auth: drop>(
    storage_unit: &mut StorageUnit,
    character: &Character,
    item: Item,
    _: Auth,
    _: &mut TxContext,
)
```

**Owner deposit / withdraw** (no extension; owner uses `OwnerCap`; sender must be the character).

```move
public fun deposit_by_owner<T: key>(
    storage_unit: &mut StorageUnit,
    item: Item,
    character: &Character,
    owner_cap: &OwnerCap<T>,
    ctx: &mut TxContext,
)

public fun withdraw_by_owner<T: key>(
    storage_unit: &mut StorageUnit,
    character: &Character,
    owner_cap: &OwnerCap<T>,
    type_id: u64,
    quantity: u32,
    ctx: &mut TxContext,
): Item
```

Example use cases: vending machine (pay then withdraw), trade hub, gated access. See [builder-scaffold storage unit extension](https://github.com/evefrontier/builder-scaffold/tree/main/move-contracts/storage_unit_extension) for a working example.

## Reference

* [world-contracts](https://github.com/evefrontier/world-contracts) — EVE Frontier Sui Move contracts
* [storage\_unit.move](https://github.com/evefrontier/world-contracts/blob/main/contracts/world/sources/assemblies/storage_unit.move) — core storage unit module
* [inventory.move](https://github.com/evefrontier/world-contracts/blob/main/contracts/world/sources/primitives/inventory.move) — inventory primitives
* [builder-scaffold storage\_unit\_extension](https://github.com/evefrontier/builder-scaffold/tree/main/move-contracts/storage_unit_extension) — example extension
* [contracts/world](https://github.com/evefrontier/world-contracts/tree/main/contracts/world) — world contract package


---

# 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:

```
GET https://docs.evefrontier.com/smart-assemblies/storage-unit/build.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
