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

# Wallet Operations in the Walley Python SDK

> Balances, holdings, transfers, two-step accept/reject flows, transfer preapprovals, and merge delegations — the wallet surface of walley-sdk.

Everything the Walley app shows in its dashboard is available programmatically.

## Balances and holdings

```python theme={null}
for b in w.balances:                  # every instrument the party holds
    print(b.instrument_id, b.total_balance, b.usd_value)

w.balances["Amulet"]                  # one instrument (KeyError if not held)
w.balances.get("Amulet")              # ...or None if not held
```

A balance aggregates one instrument: `total_balance`, `unlocked_balance`, `locked_balance`, `holding_count`, and `usd_value` where the registry prices it. Behind each balance are on-ledger holding contracts, you can fetch them when your dApp needs contract ids:

```python theme={null}
for h in w.holdings.list(instrument_id="Amulet"):
    print(h.contract_id, h.amount, h.is_locked, h.lock_context)
```

The token registry lists every instrument the wallet can hold; the SDK also uses it to resolve a token's admin party so you can name tokens by id alone:

```python theme={null}
for token in w.tokens:
    print(token.id, token.symbol, token.decimals)
```

## Sending

```python theme={null}
result = w.transfers.send(
    receiver="walley-bob::1220...",
    amount="2.5",
    instrument_id="Amulet",     # default; admin id resolved from the registry
    reason="lunch",             # optional note, max 256 chars
)
result.update_id, result.fee
```

If the receiver has a [transfer preapproval](/guides/automation-approvals), the transfer settles instantly. Otherwise it becomes a pending two-step transfer they must act on. Every flow helper has a `prepare_*` twin that stops at the fee quote, and takes `wait=False` for fire-and-forget submission.

## Incoming transfers

```python theme={null}
for t in w.transfers:                 # pending, both directions
    if t.receiver == w.party_id and not t.is_expired:
        w.transfers.accept(t.contract_id)

w.transfers.reject(contract_id)       # as receiver
w.transfers.withdraw(contract_id)     # as sender, before accept
```

## Preapprovals and merge delegation

Opt in to instant receives, or let the operator consolidate fragmented holdings:

```python theme={null}
w.preapprovals.status()               # ENABLED / PENDING / NOT_ENABLED / EXPIRED
w.preapprovals.enable()

w.merge_delegations.status()
w.merge_delegations.enable()
```

Both are ordinary transactions under the hood — prepared, signed with your key, and submitted — so they return the same result objects with fee information.

## Party lookups

```python theme={null}
w.party.get()                         # the client's own party (is_local, ...)
w.party.get("walley-bob::1220...")    # any party on the ledger
```
