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

# Banking and inventory

> Bank actions, deposit box, bank-inventory slots, use-item combines, looting bag, drop patterns, and inventory plans.

This playbook covers the read and write surfaces for the bank, the deposit box, the inventory, and item-on-target combines. All writes return `InteractionResult` and route through the shared pacer. For loadout-driven restocking state machines, see [workflow builders](/guides/workflow-builders).

## Bank actions

`BankActions` is the result-aware bank API. Item and mode operations require the bank interface to stay open.

### Opening and reading

* `isOpen()` reports whether the bank interface is open and visible.
* `openNearestAccessible()` opens the nearest path-reachable bank object from the active Shortest Path bank destination catalog. The object must expose the exact `Bank` action and a reachable interaction tile; `nearestByPath()` ranks candidates by path distance. When no eligible object matches, it falls back to the nearest path-reachable bank NPC. With no active catalog, object discovery fails closed and the NPC fallback remains.
* `openNearest()` remains as a compatibility delegate to `openNearestAccessible()`.
* `count(itemId)`, `count(name)`, `contains(itemId, quantity)`, and `contains(ids, quantity)` read bank contents.

```java theme={null}
InteractionResult open = BankActions.openNearestAccessible();
if (open.failed()) {
    return;
}

if (BankActions.isOpen() && BankActions.count(561) >= 100) {
    BankActions.ensureWithdrawMode(BankWithdrawMode.NOTE);
    BankActions.withdrawNoted(561, 100);
}
```

### Deposits and withdrawals

| Method                                               | Behavior                                                  |
| ---------------------------------------------------- | --------------------------------------------------------- |
| `withdraw(itemId, amount)`, `withdraw(name, amount)` | Withdraw the quantity                                     |
| `withdrawNoted(itemId, amount)`                      | Withdraw in noted form                                    |
| `withdrawAll(itemId)`, `withdrawAll(name)`           | Queue `Withdraw-All`                                      |
| `depositInventory()`                                 | Deposit the whole inventory                               |
| `depositEquipment()`                                 | Deposit all equipped items                                |
| `deposit(itemId, quantity)`                          | Deposit a selective quantity from the bank inventory pane |
| `depositAll()`                                       | Alias for `depositInventory()`                            |

Quantities `1`, `5`, `10`, and the bank's configured X quantity dispatch as direct menu actions. Any other positive quantity opens the client-owned X prompt; wait until the prompt is visible, then submit with `ensureWithdrawQuantity(amount)`, which routes through `DialogActions` and does not mutate the bank quantity varbit. `ensureWithdrawMode(...)` toggles noted or item mode with typed and legacy overloads.

`close()` succeeds when the bank is already closed. Otherwise it waits for the pacer, queues a click, and dispatches the client-local close operation through the revision-cached menu dispatcher. Reflection failure returns `PACKET_NOT_QUEUED`.

## Deposit box

`DepositBoxActions` works with the deposit box interface (widget group 192) for bulk or selective deposits without a full bank interface:

* `isOpen()` checks the container.
* `depositAll()` and `depositEquipment()` click the deposit-all buttons.
* `deposit(itemId, quantity)`, `deposit(name, quantity)`, and `deposit(predicate, quantity)` deposit selectively.
* `close()` closes the box.

Quantity mapping: `1`, `5`, and `10` map to `Deposit-1/5/10`; any other value maps to `Deposit-All`.

## Inventory actions

`InventoryActions` covers inventory item interactions:

* `use(name | id | Set<Integer> | predicate, actions...)` and `useIndex(index, actions...)` dispatch menu actions on inventory items.
* `useSelectedSpell(id)` clicks an item while a spell stays selected.
* `moveSlot(fromSlot, toSlot)` moves an item between exact 0-based slots with the paced, fail-closed widget-drag packet. Invalid indices, a hidden inventory, an empty source, pacing, or an unhealthy packet mapping fail or pace without confirming the move. Observe the container on a later tick before advancing a multi-move workflow.

### Drop patterns

`InventoryDropActions` drops at most one item per call. Call it once from a tick or workflow step, inspect the result, and re-evaluate on the next tick. It never bulk-clicks an entire inventory:

```java theme={null}
InteractionResult result = InventoryDropActions.dropNext(
        InventoryDropPattern.columnMajor(),
        widget -> widget.getItemId() == ItemID.OAK_LOGS);

if (result.getStatus() == InteractionStatus.PACED) {
    return; // try again next tick
}
```

Patterns: `rowMajor()`, `reverseRowMajor()`, `columnMajor()`, `reverseColumnMajor()`, and `of(comparator)` for custom orders.

<Tip>
  When dropping by rule, match against an explicit allowlist of junk items. Inverted checks such as "drop anything not protected" risk discarding unrecognized valuables.
</Tip>

## Inventory plans

`InventoryPlan` asserts inventory requirements before a step runs. It reads live state or a test snapshot:

```java theme={null}
InventoryPlan plan = InventoryPlan.create()
    .require(561, 100)
    .requireFreeSlots(2);

if (!plan.satisfied()) {
    log.debug(plan.describeMissing());
}
```

Use it as a gate before actions that would fail noisily without supplies:

```java theme={null}
InventoryPlan runesForTeleport = InventoryPlan.create()
    .require(563, 1)   // law rune
    .require(556, 3)   // air runes
    .requireFreeSlots(1);

if (!runesForTeleport.satisfied()) {
    return StepResult.waitTicks(1, "Waiting for teleport supplies");
}
```

The planner clamps required amounts to zero or above, keeps the highest requested free-slot value, and `describeMissing()` reports item and slot deficits. Snapshots let unit tests exercise the logic without a client.

## Use-item combines

`UseItemActions` covers "use this on that" combinations:

| Method                                          | Combines                              |
| ----------------------------------------------- | ------------------------------------- |
| `itemOnItem(sourceName, targetName)`            | Two inventory items by name           |
| `itemOnItem(sourceItemId, targetItemId)`        | Two inventory items by ID             |
| `itemOnNpc(sourceItemId, npcName)`              | Item on the nearest matching NPC      |
| `itemOnNpc(sourceItemId, NPC npc)`              | Item on an exact NPC instance         |
| `itemOnObject(sourceItemId, objectName)`        | Item on the nearest matching object   |
| `itemOnObject(sourceItemId, TileObject object)` | Item on an exact object instance      |
| `itemOnTileItem(sourceItemId, tileItemId)`      | Item on a ground item                 |
| `itemOnPlayer(itemId, playerName or Player)`    | Item on a player                      |
| `widgetOnWidget(source, target)`                | One widget on another                 |
| `dragAndDrop(src, dest)`                        | Drag a widget onto a destination slot |

```java theme={null}
UseItemActions.itemOnItem("Pestle and mortar", "Blue dragon scale");
UseItemActions.itemOnObject("Raw shrimps", "Fire");
UseItemActions.itemOnNpc(ItemID.BUCKET_OF_MILK, "Cow");
```

The exact `NPC` and `TileObject` overloads skip a second name-based lookup when you already resolved the target. A direct combine never opens a production interface; for make-X flows (fletching, smelting, crafting) use the [production workflow builder](/guides/workflow-builders).

## Bank-inventory slots

While the bank is open, the inventory renders in a separate bank-side container. `BankInventoryActions` interacts with those slots:

```java theme={null}
BankInventoryActions.use("Lobster", "Deposit-1");
BankInventoryActions.use(ItemID.LOBSTER, "Deposit-all");
BankInventoryActions.useIndex(0, "Deposit-all");
```

Overloads accept a name, an ID, a predicate, a raw 1-based index, or a slot widget.

## Looting bag

`LootingBagActions` queries and fills the looting bag. Open the bag before querying contents; the read methods never open it implicitly:

```java theme={null}
if (!LootingBagActions.isOpen()) {
    InteractionResult open = LootingBagActions.open();
    if (open.failed()) {
        return;
    }
}

int natureRunes = LootingBagActions.count(561);

InteractionResult result = LootingBagActions.deposit(561, 10);
```

Deposits accept an item ID or a widget predicate plus an amount, validate the request, and return `InteractionResult`. The API operates at the widget and action level and does not manage Wilderness-specific rules.

## Tab prerequisites

Every inventory interaction, drop, slot move, item-on-target operation, and widget-on-widget operation requires the Inventory tab to be visible. A closed tab returns `WIDGET_HIDDEN` targeting `tab/INVENTORY` before anything is queued. Call `TabActions.open(Tab.INVENTORY)` explicitly and observe `TabActions.isOpen(...)` before retrying. See [equipment and loadouts](/guides/equipment-loadouts) for the full tab contract.
