# Pay with SPACE v1.5

### How it works (in plain language)

You pay with SPACE the same way a metro card works:

1. You **load up** your card — depositing SPACE into the on-chain escrow contract.
2. You **tap to ride** — your SDK signs a small receipt for every proxy request, charging a tiny amount.
3. The network **cashes the receipts** — the gateway batches them and settles on-chain. The Provider that served you gets paid automatically.
4. When you're done, you can **cash out** your remaining balance with a 5-day delay.

You don't need to subscribe to a plan, you don't need a card on file, and you only pay for what you use.

### Before you start

You'll need:

* An Ethereum-compatible wallet you control (private key).
* A small amount of **SPACE** to spend on traffic.
* A small amount of **CTC** (Creditcoin's gas token) for the deposit transaction. \~0.01 CTC per transaction is plenty.
* The Python SDK, version 1.5 or later.

{% hint style="info" %}
**Where to get SPACE and CTC**

SPACE is listed on several major exchanges; see the Staking guide for the current list. CTC is the native gas token of Creditcoin and is available on the same exchanges. Move both to your wallet on the Creditcoin mainnet.
{% endhint %}

### Step 1 — Install the SDK and CLI

```bash
pip install spacerouter
```

The package ships both the Python library and the `spacerouter` command-line tool.

### Step 2 — Configure your environment

Set these environment variables once (or place them in a `.env` file):

```bash
export SR_GATEWAY_URL=https://gateway.spacerouter.org
export SR_ESCROW_CHAIN_RPC=https://mainnet3.creditcoin.network
export SR_ESCROW_CONTRACT_ADDRESS=0x...   # see Reference page for current value
export SR_ESCROW_PRIVATE_KEY=0xYOUR_PRIVATE_KEY
```

{% hint style="warning" %}
**Keep this private key safe**

The private key controls both your SPACE and your deposited balance. Never commit it, never paste it into a chat. Use a dedicated wallet for SpaceRouter rather than your main one.
{% endhint %}

### Step 3 — Deposit SPACE into escrow

The deposit is a single CLI call. Amounts are in **wei** (1 SPACE = 1018 wei).

```
spacerouter escrow deposit 100000000000000000000   # 100 SPACE
```

Expected output:

```
{
  "action": "deposit",
  "amount_wei": 100000000000000000000,
  "tx_hash": "0xabc…",
  "from": "0xYourAddress"
}
```

Behind the scenes the CLI auto-approves the SPACE token to the escrow contract on first use, then calls `deposit()`. Both transactions burn a small amount of CTC for gas.

Check your balance any time:

```
spacerouter escrow balance 0xYourAddress
```

### Step 4 — Send a paid request

The recommended pattern is to pass your `SpaceRouterSPACE` instance to `SpaceRouter` via `payment=`. The proxy client takes care of the per-request challenge, header injection on the CONNECT, and (with `auto_settle=True`) settlement after each call.

```bash
from spacerouter import SpaceRouter
from spacerouter.payment import SpaceRouterSPACE

consumer = SpaceRouterSPACE(
    gateway_url="https://gateway.spacerouter.org",
    proxy_url="http://gateway.spacerouter.org:8080",
    private_key="0xYOUR_PRIVATE_KEY",
)

with SpaceRouter(
    consumer.address.lower(),
    gateway_url="http://gateway.spacerouter.org:8080",
    payment=consumer,
    auto_settle=True,
) as cli:
    response = cli.get("https://httpbin.org/ip")
    print(response.status_code, response.json())
```

The SDK does three things automatically per call:

1. Asks the gateway for a fresh challenge string.
2. Signs the challenge with your wallet (EIP-712).
3. Stamps the four `X-SpaceRouter-…` headers on the proxy `CONNECT` handshake — they MUST land on the CONNECT, not on the inner request, because the gateway can't read inside a TLS tunnel.

{% hint style="info" %}
**Async variant**

Replace `SpaceRouter` with `AsyncSpaceRouter`, wrap the call in `async def main(): … asyncio.run(main())`, and use `await cli.get(...)`. Same constructor signature.
{% endhint %}

{% hint style="warning" %}
**Don't bypass SpaceRouter**

If you build an `httpx.Proxy(url, headers={…})` manually, all four `X-SpaceRouter-*` headers must land on the **CONNECT**, not on the inner request — the gateway can't read inside a TLS tunnel. Using `SpaceRouter(consumer.address.lower(), payment=consumer, …)` handles this for you.
{% endhint %}

### Step 5 — Sync your receipts

The gateway holds unsigned receipts for the bandwidth it served you. Periodically — at the end of a session, or once a day — sync them so they can settle on-chain:

```
result = await consumer.sync_receipts()
print(result)
# {
#   "accepted":      ["uuid-1", "uuid-2", ...],
#   "rejected":      [],
#   "pending_count": 0
# }
```

The same operation is available from the CLI:

```
spacerouter receipts sync
```

Each accepted receipt debits a small amount of SPACE from your escrow balance.

### Step 6 — Withdraw your balance (when ready)

Withdrawals are protected by a **5-day timelock** to give the network time to claim outstanding Provider receipts.

#### Initiate the withdrawal

```
spacerouter escrow initiate-withdrawal 50000000000000000000   # 50 SPACE
```

#### Wait 5 days

Check status any time:

```
spacerouter escrow withdrawal-request 0xYourAddress
```

#### Execute the withdrawal

```
spacerouter escrow execute-withdrawal
```

You can **cancel** a pending withdrawal at any point during the 5-day window:

```
spacerouter escrow cancel-withdrawal
```

### What happens behind the scenes

```
Consumer wallet
       │
       │  signs EIP-712 receipt
       ▼
┌─────────────┐  CONNECT + payment headers   ┌──────────┐
│   SDK       │ ───────────────────────────▶ │  Gateway │
│  (your app) │                              └────┬─────┘
└─────────────┘                                   │
       ▲                                          │ relay traffic
       │ sync_receipts()                          ▼
       │                                  ┌──────────────┐
       │                                  │   Provider   │
       │                                  └──────────────┘
       │
       └────────── escrow.claim_batch() on-chain ◀──── Gateway batches
                                                       Leg-1 receipts
```

### Cost & pricing

The gateway publishes a maximum rate per gigabyte. By default the SDK accepts any rate up to that cap, but you can tighten it client-side:

```
consumer = SpaceRouterSPACE(
    ...,
    max_rate_per_gb=1_000_000_000_000_000_000,  # 1 SPACE per GB
)
```

If a receipt arrives with a higher rate, the SDK refuses to sign it and the request is dropped before any SPACE is committed.

### Errors specific to SPACE payment

| Symptom                                               | Likely cause                                                     | Fix                                                          |
| ----------------------------------------------------- | ---------------------------------------------------------------- | ------------------------------------------------------------ |
| HTTP 407 on every request                             | Payment headers are on the inner request, not the proxy CONNECT. | Use the SDK's helpers — they put headers in the right place. |
| HTTP 402                                              | Escrow balance below the request's price.                        | Run `spacerouter escrow deposit` with more SPACE.            |
| Deposit reverts with "ERC-20: insufficient allowance" | Token approval missing.                                          | Re-run the deposit; the CLI will re-approve.                 |
| Deposit fails with "insufficient funds for gas"       | Wallet has SPACE but no CTC.                                     | Send a small amount of CTC to the wallet.                    |
| Withdrawal won't execute                              | 5-day delay hasn't elapsed yet.                                  | Check `withdrawal-request` for `unlock_at_epoch_seconds`.    |

### Frequently asked

#### Do I need to register an account first?

No. Your wallet address is your identity. Deposit SPACE into the escrow contract and you can send paid requests immediately — no signup, no API key.

#### What chain is the escrow contract on?

Creditcoin mainnet, chain ID `102030`. See Reference for the canonical address.

#### Are receipts replayable?

No. Each receipt has a unique `requestUUID`; the contract enforces it can be claimed at most once per consumer.


---

# Agent Instructions: 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.spacecoin.org/spacerouter-proxy/service-user-guide/pay-with-space-v1.5.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.
