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

# An actor's wallet

> How an actor gets money, what it pays for, and how its code pays someone else

Every actor has its own balance, in CBY, separate from your wallet. This page covers what that balance pays for, how money gets in, and how an actor's code pays someone else.

## Who pays for what

Whoever calls a handler pays for that call. The actor pays for everything it starts itself: scheduled runs, runner jobs, off-chain functions, stored state and its own payments.

People who hire your actor pay what the listing charges ([Billing](https://docs.cowboy.inc/hire/billing.md)), but that money doesn't flow into the actor's balance by itself. It's up to you to keep the actor funded for the work it does.

## Get money into the actor

An actor's first money comes at deploy, which asks how much to move from your wallet to the new actor, 1 CBY by default, or takes `--fund`. After that, anyone can add to its balance:

```bash theme={"system"}
cowboy actor fund <actor> --amount 5
```

```text Output theme={"system"}
Funding actor 0x2858…c20c with 5000000000 wei
  Signer: 0x2858…423C
   Tx hash: 0xb2f6…c909
✓ FundActor submitted: {"added":1,"skipped":0,"hashes":["0xb2f6…c909"]}
✓ FundActor committed at block 82368
```

`cowboy actor inspect <actor>` shows the balance, and `cowboy actor auto-topup` refills the actor from your wallet automatically ([Deploy and operate](https://docs.cowboy.inc/build/deploy.md#keep-it-funded)).

A payment into the actor runs none of its code, and actor code can't read its own balance. To act on a payment, have the payer call a handler as well, and keep your own record in `self.storage`.

## Pay someone from the actor

`runtime.transfer_balance(to, amount)` moves CBY from the actor's balance to any address. The amount is in base units: 1 CBY is 1,000,000,000.

This actor pays out only when you, its owner, tell it to. Create a project:

```bash theme={"system"}
cowboy init payouts --dir payouts
cd payouts
```

```text Output theme={"system"}
✓ Project initialized.
→ Preparing Python environment
✓ Python environment ready · .venv (0.1s)

Yeehaw! Project ready: /path/to/payouts
```

Replace `actors/payouts/main.py` with:

```python theme={"system"}
from cowboy_sdk import OWNER, Actor, Address, callable_by, deferred, public, runtime

CBY = 1_000_000_000  # one CBY in base units


class PayoutsActor(Actor):
    @public
    def init(self, payload: bytes | None = None) -> None:
        self.storage["paid"] = []

    @callable_by(OWNER)
    @deferred
    def pay(self, order: object) -> int:
        if not isinstance(order, dict):
            raise ValueError('send {"to": address, "cby": amount}')
        to = Address(order["to"])
        amount = int(order["cby"]) * CBY
        if amount <= 0:
            raise ValueError("pay a positive amount")
        runtime.transfer_balance(to, amount)
        paid = self.storage["paid"]
        paid.append({"to": to.to_hex(), "amount": amount})
        self.storage["paid"] = paid
        return amount
```

`@callable_by(OWNER)` means only you can make the actor pay, and a handler that moves money must say who may call it. It also needs `@deferred`: a handler that pays or sends a message must be marked that way, or it raises `PurityViolationError`.

A payment is all or nothing. If the actor's balance is short, the transfer raises and the handler changes nothing. If the handler raises after the transfer, the transfer is undone too.

### Test it

Replace `tests/test_payouts.py` with:

```python theme={"system"}
import pytest
from cowboy_sdk import PermissionDeniedError, codec, mock_host
from cowboy_sdk.testing import SimulatedChain

from actors.payouts import main

SELLER = "0x4444444444444444444444444444444444444444"
STRANGER = b"\x33" * 20


def deploy() -> tuple[main.PayoutsActor, SimulatedChain]:
    actor = main.PayoutsActor()
    chain = SimulatedChain(actor)
    mock_host.seed_actor_owner(mock_host.context()["sender"])
    chain.call(actor.init)
    return actor, chain


def test_the_owner_pays_a_seller() -> None:
    actor, chain = deploy()
    paid = chain.call(actor.pay, codec.encode({"to": SELLER, "cby": 2}))
    assert codec.decode(paid) == 2 * main.CBY
    transfer = mock_host.get_transfer_log()[-1]
    assert transfer == {"to": bytes.fromhex(SELLER[2:]), "amount": 2 * main.CBY}


def test_a_stranger_cannot_pay() -> None:
    actor, chain = deploy()
    chain.set_sender(STRANGER)
    with pytest.raises(PermissionDeniedError):
        chain.call(actor.pay, codec.encode({"to": SELLER, "cby": 2}))
```

```bash theme={"system"}
cowboy test
```

```text Output theme={"system"}
tests/test_payouts.py ..                                                 [100%]
============================== 2 passed in 0.05s ===============================
```

Tests don't hold real balances, so a transfer always succeeds there, and `mock_host.get_transfer_log()` lists each one. Test payments with `cowboy test`, not `cowboy run`.

## A spending budget

To stop an actor overspending, it can cap its own spending per period; `runtime.budget_left()` reports what's left ([reference](https://docs.cowboy.inc/developers/sdk-reference.md#budget_left)).

## Tokens

Besides CBY, an actor can hold and move tokens ([Working with tokens](https://docs.cowboy.inc/developers/working-with-tokens.md)).

## Next

* [An actor's schedule](https://docs.cowboy.inc/build/sdk/schedule.md)
* [SDK reference: `transfer_balance`](https://docs.cowboy.inc/developers/sdk-reference#transfer_balance)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.