# Welcome

Welcome to the official Spacecoin documentation.

Spacecoin is building an open connectivity infrastructure designed to expand internet access through a combination of satellite infrastructure, ground participation, and developer-accessible products. These docs are for developers, partners, node operators, and ecosystem participants who want to understand the network and build on top of it.

Today, the most immediate way to interact with the Spacecoin ecosystem is through SpaceRouter, a product designed to give developers and partners programmable access to connectivity infrastructure. Over time, Spacecoin expands toward a broader open network model that combines greater blockchain and satellite participation.

Use these docs to:

* understand what Spacecoin is building
* learn how SpaceRouter fits into the ecosystem
* explore the network model and verification layers
* understand the role of SPACE in the network
* find the right starting point for integrations and partnerships

#### Jump right in:

<table><thead><tr><th width="93.453125">Card</th><th width="206.9921875">Title</th><th>Description</th></tr></thead><tbody><tr><td>⚡</td><td><a href="/pages/eCZza3CYxcgunIuhRLcI">What is Spacecoin</a></td><td>Learn about the project overview and core concepts</td></tr><tr><td>🛰️</td><td><a href="/pages/MpZbneU94IQDMhCMoDlw">How It Works</a></td><td>Understand the satellite network architecture</td></tr><tr><td>🪙</td><td><a href="/pages/8Q2x75ma17l3hsQAfXcS">$SPACE Token</a></td><td>Explore token utility and tokenomics</td></tr><tr><td><span data-gb-custom-inline data-tag="emoji" data-code="1f3e0">🏠</span></td><td><a href="/pages/HqgcjFjMzpL62LhepcFD">SpaceRouter</a></td><td>Get started with SpaceRouter</td></tr></tbody></table>


# What is Spacecoin

Spacecoin is a DePIN (Decentralized Physical Infrastructure Network) project that combines three complex technologies: blockchain, satellites, and telecommunications.

A constellation of small satellites operating in Low Earth Orbit (LEO) provides internet connectivity worldwide, while the Creditcoin blockchain transparently manages network operations, payments, and verification. The $SPACE token serves as the coordination and payment layer for this network.

**Core Features**

**Physically Decentralized** The network uses a LEO satellite constellation that operates independently of terrestrial infrastructure such as cell towers and fiber optic cables. This space-based approach ensures reliable access even during natural disasters, government restrictions, and in remote regions where traditional internet fails. "No Kill Switch" — no single entity can control or shut down the entire network.

**Transparent & Trustless** Transaction hashes for all data transmissions are recorded on the Creditcoin blockchain. Anyone can independently verify the network's operational status, eliminating the need to trust centralized intermediaries.

**Borderlessly Accessible** Cryptocurrency payments remove financial and geographical barriers, enabling access even in regions with limited banking infrastructure. Regular users can also pay in fiat currency through local telecom providers.

**Open Network** Spacecoin operates as an Open Constellation model, where anyone meeting protocol standards can contribute their own satellites to the network without any application review process.

Spacecoin is building infrastructure for the emerging space economy. Just as the open internet created trillions of dollars in economic value by allowing anyone to build on it, Spacecoin is building the open infrastructure layer for space-based connectivity that anyone can participate in and build upon.

**Quick Stats**

| Item                | Detail                                                                     |
| ------------------- | -------------------------------------------------------------------------- |
| Blockchain          | Creditcoin                                                                 |
| Token               | $SPACE                                                                     |
| Satellites in Orbit | 4 total. CTC-0 mission has 1 satellite and CTC-1 mission has 3 satellites. |

***


# Why Spacecoin

Internet connectivity is critical infrastructure, but it is still vulnerable to centralization, physical disruption, and uneven access.

Traditional internet infrastructure depends heavily on physical assets such as fibre cables, landing stations, towers, and regional hubs. These systems are essential, but they can also become chokepoints. When critical infrastructure is damaged, filtered, or otherwise disrupted, connectivity can degrade at scale.

Spacecoin exists because connectivity needs a more resilient long-term model.

### Why this matters <a href="#why-this-matters" id="why-this-matters"></a>

**Connectivity is still fragile**

Even in highly connected markets, internet access still depends on concentrated physical infrastructure and institutional dependencies that are difficult to route around quickly.

**Access is still uneven**

Large populations remain underserved or unconnected because traditional deployment models are expensive and often difficult to extend into remote or economically challenging areas.

**Developers need programmable infrastructure**

Modern developers increasingly need connectivity infrastructure that can be integrated programmatically rather than accessed only through closed systems and manual workflows.

**Open participation matters**

A more open infrastructure model can support broader participation across the network over time, including operators, developers, and ecosystem partners.

Spacecoin is being built around the idea that connectivity should become more resilient, more open, and more usable as programmable infrastructure.


# Mission & Vision

**Mission**

> Make internet connectivity a universal right, not a privilege.

Spacecoin's founder "Captain Tae" shared this in the first message transmitted from the CTC-0 satellite:

> "I created Spacecoin because I believed that billions of people deserved better. The future is decentralized."

**Vision**

Build the standard open protocol for decentralized connectivity infrastructure — connecting everyone, everywhere.

**Core Values**

* **Decentralization**: Infrastructure that is decentralized both physically and operationally
* **Accessibility**: Available to everyone without economic or geographic barriers
* **Transparency**: Network operations verifiable on-chain
* **Openness**: An open network where anyone can participate and contribute
* **Resilience**: Service that never goes down due to any single point of failure


# How It Works

Spacecoin is being built as a connectivity ecosystem that combines infrastructure, verification, participation, and incentives.

At a high level, the system can be understood in four layers:

### 1. Product layer <a href="#id-1-product-layer" id="id-1-product-layer"></a>

This is where developers and partners interact with the ecosystem through products such as SpaceRouter.

### 2. Network layer <a href="#id-2-network-layer" id="id-2-network-layer"></a>

This is the broader connectivity layer that connects infrastructure, participation, and routing across the system.

**Architecture**

The network's foundation consists of blockchain-enabled small satellites operating in Low Earth Orbit (LEO). This space-based infrastructure operates independently of terrestrial systems (cell towers, fiber optics, etc.), providing censorship-resistant and regionally fault-tolerant "lifeline connectivity."

**No Kill Switch**: No single entity can control or disable the entire network. Even if individual satellite operators or ground stations go offline, the rest of the network continues to operate.

**Open Constellation**: Anyone meeting protocol standards can add their own satellites without any review process. $SPACE staking serves as the trust mechanism.

**Blockchain Integration**

The Creditcoin blockchain serves as the primary ledger for network operations.

* Transaction hashes for satellite data transmissions are recorded on the Creditcoin blockchain
* This creates immutable, publicly accessible records
* Anyone can independently verify the network's operational status and data transmissions

**Payment Flow**

Payments are processed through a blockchain-based escrow mechanism:

1. Users lock $SPACE in a smart contract before requesting service (prepaid guarantee)
2. Operators deliver the service and submit cryptographic proof
3. The smart contract automatically verifies the proof and releases payment

This enables real-time settlement, cross-border transactions without currency conversion, and viable micropayments.

### 3. Verification layer <a href="#id-3-verification-layer" id="id-3-verification-layer"></a>

Spacecoin includes verification concepts intended to help establish trust in network activity and participation, such as our patented Proof of Location technology.

### 4. Incentive layer <a href="#id-4-incentive-layer" id="id-4-incentive-layer"></a>

The SPACE token helps align participation, usage, and network growth across the ecosystem.

### How the pieces fit together <a href="#how-the-pieces-fit-together" id="how-the-pieces-fit-together"></a>

A developer or partner may begin by integrating a product such as SpaceRouter. That product sits within a broader network model that is supported by infrastructure, verification, and incentives. Over time, as the network expands, these layers work together to support a more open and resilient connectivity model.


# Orbiting Satellites

### **CTC-0 Mission — First Satellite**

* **Launch Date**: December 21, 2024
* **Launch Vehicle**: SpaceX Bandwagon-2 rideshare mission
* **Orbital Period**: Approximately 90 minutes per orbit
* **Purpose:** Proof of concept for end-to-end blockchain transaction, from Earth to space and back. [Successfully completed](https://www.reuters.com/business/media-telecom/satellite-startup-spacecoin-sends-data-through-space-bid-rival-starlink-2025-10-01/) November 13, 2025

Orbital transmitted message:

> "I created Spacecoin because I believed that billions of people deserved better. The future is decentralized. — Captain Tae"

### **CTC-1 Mission — First Constellation**

* **Composition**: 3 satellites
* **Launch Date**: November 28, 2025
* **Launch Vehicle**: SpaceX Transporter-15 rideshare mission
* **Purpose**: Test intersatellite linking and signal handoff to prepare for pilot testing with partners in Africa and Southeast Asia.

**Live Satellites Tracking**: spacecoin.org → [Satellite Tracker](https://spacecoin.org/satellite-tracker)


# Proof of Orbit

A verification mechanism unique to Spacecoin that confirms satellites are actually operating in space.

**Verification Methods**

**1. Satellite Observation (SatNOGS)** Through the open-source SatNOGS network, anyone can independently track and observe Spacecoin's satellites. No need to trust the Spacecoin project itself — a third-party network confirms the existence and operation of the satellites.

* [CTC-0](https://db.satnogs.org/satellite/VWXG-4101-0824-5480-8078)
* [CTC-1A](https://db.satnogs.org/satellite/OTUO-9494-3471-7180-4596)
* [CTC-1B](https://db.satnogs.org/satellite/CDDD-0280-4973-5946-8664)
* [CTC-1C](https://db.satnogs.org/satellite/IJQV-1195-2515-8742-0084)

**2. On-Chain Records (Creditcoin)** Transaction hashes of messages transmitted from space are published on the Creditcoin block explorer. Anyone can [audit these records on the blockchain](https://x.com/spacecoin/status/1989062848434348174?s=20), ensuring transparency of satellite operations.


# Proof of Location

Proof of Location is part of Spacecoin’s broader verification framework and a mechanism that combines blockchain and satellite technology to verify physical locations in a secure, decentralized, and trustworthy manner.

At a high level, Proof of Location is intended to help verify that network participation or infrastructure presence corresponds to real-world geographic claims. This matters because location is often an important part of how connectivity infrastructure is trusted, coordinated, and allocated.

### Why it matters <a href="#why-it-matters" id="why-it-matters"></a>

A network that depends on infrastructure distributed across locations needs reliable ways to verify where participation is actually happening. Proof of Location supports that trust layer.

* **U.S. Patent Granted**: [US 12335739 B2 (Proof of Location & Velocity)](https://patents.google.com/patent/US12335739B2)
* Solves centralization issues of existing location verification systems such as GPS
* Provides spoofing resistance through satellite-based independent location verification


# Token Overview & Utility

**Basic Information**

<table><thead><tr><th width="186.98046875">Item</th><th>Detail</th></tr></thead><tbody><tr><td>Official Name</td><td>Spacecoin</td></tr><tr><td>Ticker</td><td>SPACE</td></tr><tr><td>Token Standard</td><td>ERC-20</td></tr><tr><td>Blockchain</td><td>Creditcoin</td></tr><tr><td>Contract Address</td><td><code>0x7ab7C6A935Ab2D1437398790C9C0660af62A80b9</code></td></tr><tr><td>Total Supply</td><td>21,000,000,000 SPACE (fixed)</td></tr><tr><td>Initial Circulating Supply at TGE</td><td>2,150,000,000 SPACE (10.25%)</td></tr><tr><td>TGE Date</td><td>January 23, 2026</td></tr><tr><td>Explorer</td><td><a href="https://creditcoin.blockscout.com/token/0x7ab7C6A935Ab2D1437398790C9C0660af62A80b9">https://creditcoin.blockscout.com/token/0x7ab7C6A935Ab2D1437398790C9C0660af62A80b9</a></td></tr></tbody></table>

$SPACE is the native utility token of the Spacecoin ecosystem, responsible for coordinating and settling payments across the satellite network. It has a fixed supply with no additional issuance.

***

The $SPACE token has four core utilities.

**1. Tokenizing Network Infrastructure**

Tokenizes idle satellite capacity for satellite operators. LEO satellites maintain connection with any given location for only about 5–15 minutes per orbit (roughly 5% of total capacity). The remaining \~95% is idle. By joining the Spacecoin Network, satellite operators can monetize this idle capacity through $SPACE, turning regional connectivity into a global revenue stream.

**2. Staking**

To filter out malicious operators in the Open Constellation, node operators must stake $SPACE to register. This stake acts as a deposit that is slashed in cases of misbehavior. As more operators join, the buy-and-lock mechanism reduces circulating supply.

**3. Payment**

A blockchain-based escrow mechanism enables real-time settlement, cross-border transactions without currency conversion, and viable micropayments. Users lock $SPACE in a smart contract, operators submit cryptographic proof of service delivery, and the smart contract automatically verifies and releases payment.

**4. Governance**

Grants all holders a voice in important network decisions including protocol upgrades, policy updates, and dispute resolution. This utility will be activated once the network reaches full functionality.

**Self-Reinforcing Economy**

Network expansion → increased operator staking (supply decrease) + increased user payments (demand increase) → a virtuous cycle of growing $SPACE value.


# Tokenomics

**Allocation Breakdown**

**Growth & Rewards — 46% (9.66B SPACE)**

<table><thead><tr><th width="142.7578125">Category</th><th width="65.82421875">%</th><th width="101.44140625">Amount</th><th width="197.83984375">Vesting</th><th>Purpose</th></tr></thead><tbody><tr><td>Ecosystem</td><td>20%</td><td>4.2B</td><td>48-month linear (87.5M/month)</td><td>Developer grants, partnership incentives, strategic reserves</td></tr><tr><td>Airdrop S1</td><td>5%</td><td>1.05B</td><td>3-month linear (25% at TGE + monthly)</td><td>Early Cadets &#x26; CTC holder rewards</td></tr><tr><td>Airdrop S2</td><td>6%</td><td>1.26B</td><td>Starts TGE+1 month, 33.3%/month over 3 months</td><td>Season 2 Cadets rewards</td></tr><tr><td>Satellite Node Rewards</td><td>10%</td><td>2.1B</td><td>12-month cliff + 48-month linear</td><td>Satellite operator incentives (proportional to data relayed)</td></tr><tr><td>VPN Rewards</td><td>5%</td><td>1.05B</td><td>48-month linear (21.875M/month)</td><td>Starmesh usage incentives</td></tr></tbody></table>

**Foundation & Operations — 30% (6.3B SPACE)**

<table><thead><tr><th width="119.078125">Category</th><th width="60.87890625">%</th><th width="103.84375">Amount</th><th width="154.83984375">Vesting</th><th>Purpose</th></tr></thead><tbody><tr><td>Foundation</td><td>15%</td><td>3.15B</td><td>12-month cliff + 24-month linear</td><td>Protocol development, regulatory compliance, network stewardship</td></tr><tr><td>Operations</td><td>5%</td><td>1.05B</td><td>36-month linear</td><td>Ground station hosting, satellite insurance, bandwidth</td></tr><tr><td>Marketing</td><td>5%</td><td>1.05B</td><td>12-month linear</td><td>User acquisition, community events, partnership marketing</td></tr><tr><td>Dev</td><td>5%</td><td>1.05B</td><td>36-month linear</td><td>Engineer recruitment, security audits, bug bounties</td></tr></tbody></table>

**Team & Contributors — 24% (5.04B SPACE)**

<table><thead><tr><th width="121.54296875">Category</th><th width="59.80859375">%</th><th width="102.48046875">Amount</th><th width="197.53515625">Vesting</th><th>Purpose</th></tr></thead><tbody><tr><td>Partner Support</td><td>9%</td><td>1.89B</td><td>Fully unlocked at TGE</td><td>CEX listings, market maker liquidity, initial trading support</td></tr><tr><td>Investors</td><td>10%</td><td>2.1B</td><td>12-month cliff + 24-month linear</td><td>Investor allocation</td></tr><tr><td>Advisors &#x26; Contributors</td><td>5%</td><td>1.05B</td><td>12-month cliff + 24-month linear</td><td>Advisors, partners, contributors</td></tr></tbody></table>


# Staking

How to stake SPACE tokens and earn rewards.

## Staking Guide

How to stake SPACE tokens and earn rewards.

### Before You Start

* **SPACE tokens** on the Creditcoin network
* **CTC** for gas fees (small amount needed per transaction)
* **Wallet**: MetaMask or Credit Wallet

Current APR is shown on the [staking dashboard](https://penguinbase.com/dapp/spacestaking).

> To earn SpaceRouter rewards, you need both staking and node operation. → [Node Operator Guide](/spacerouter-proxy/proxy-provider-guide)

### Step 1 — Buy SPACE

Purchase on any exchange below.

| Exchange      | Pair       | Link                                                                                     |
| ------------- | ---------- | ---------------------------------------------------------------------------------------- |
| Binance Alpha | SPACE/USDT | [Trade](https://www.binance.com/en/alpha/bsc/0x87acfa3fd7a6e0d48677d070644d76905c2bdc00) |
| OKX           | SPACE/USDT | [Trade](https://www.okx.com/trade-spot/space-usdt)                                       |
| Bitget        | SPACE/USDT | [Trade](https://www.bitget.com/spot/SPACEUSDT)                                           |
| KuCoin        | SPACE/USDT | [Trade](https://www.kucoin.com/trade/SPACE-USDT)                                         |
| MEXC          | SPACE/USDT | [Trade](https://www.mexc.com/exchange/SPACE_USDT)                                        |
| Kraken        | SPACE/USD  | [Trade](https://pro.kraken.com/app/trade/space-usd)                                      |
| Coinone       | SPACE/KRW  | [Trade](https://coinone.co.kr/exchange/trade/space/)                                     |
| Gopax         | SPACE/KRW  | [Trade](https://www.gopax.co.kr/exchange/space-krw)                                      |
| Aster DEX     | SPACE/USD1 | [Trade](https://www.asterdex.com/en/spot/SPACEUSD1)                                      |

### Step 2 — Bridge to Creditcoin

If you withdrew SPACE to the **Ethereum network**, bridge it to the Creditcoin network before staking.

→ [Bridge SPACE: Ethereum → Creditcoin](https://portalbridge.com/?toChain=CreditCoin\&toToken=SPACE\&fromChain=Ethereum\&fromToken=SPACE)

> **Note:** Staking only works with SPACE on the Creditcoin network. SPACE on Ethereum cannot be staked directly.

### Step 3 — Stake

1. Go to the [staking dashboard](https://penguinbase.com/dapp/spacestaking)
2. Connect your wallet
3. **Stake** tab → enter amount → **Stake** → confirm transaction

> To earn rewards by running a node, you must stake at least 1 $SPACE.

### Step 4 — Run a Node

To earn rewards, you must also run a SpaceRouter Home Node. Staking alone does not qualify.

1. Download the Home Node from the [Node Operator Guide](/spacerouter-proxy/proxy-provider-guide)
2. Install and launch the app
3. Enter your staking wallet address during setup

> **Note:** Your node must remain online to earn rewards.

### Claim Rewards

1. Go to the **Claim Rewards** tab
2. Click **Claim** → confirm transaction

Claimed SPACE goes directly to your wallet. You can claim at any time.

### Unstake

1. Go to the **Unstake** tab
2. Enter amount → **Unstake** → confirm transaction

> Unstaking has a **14-day unbonding period**. No rewards are earned during this period. Tokens return to your wallet after 14 days.

### FAQ

#### What chain is SPACE on?

The official SPACE token used for staking and rewards lives on Creditcoin mainnet. The version on Ethereum is a wrapped representation, so you'll want to [bridge](https://docs.creditcoin.org/what-is-creditcoin/acquiring-creditcoin-assets#bonus-bridge-to-the-creditcoin-network) it over to Creditcoin mainnet before staking.

#### Can I stake without running a Provider?

You'll need to run a node to earn rewards. Staking alone won't earn you any rewards, so please keep that in mind.

#### What's the minimum stake?

You can start staking with as little as 1 SPACE. Just keep in mind that you'll also need to run a node in order to earn rewards.

#### Are stake amounts visible on chain?

Yes, everything is publicly visible! The staking contract is open for anyone to read, and you can check the total staked SPACE, the list of stakers, and recent transactions directly on Blockscout.


# Overview

## SpaceRouter Proxy

A decentralized residential proxy network powered by the Spacecoin community.

SpaceRouter Proxy routes web traffic through residential connections contributed by people around the world. Consumers send proxy requests to a single gateway and reach websites with real, geo-targeted residential IPs. Providers run a small app at home, earn SPACE for the bandwidth they share, and stake SPACE to qualify.

### How it works

```
┌──────────────┐         ┌────────────────────┐         ┌────────────┐         ┌──────────┐
│   Proxy      │  HTTP   │SpaceRouter  Proxy  │  TLS    │   Proxy    │  HTTPS  │ Internet │
│   Consumer   │ ──────▶ │  Gateway + Coord.  │ ──────▶ │  Provider  │ ──────▶ │  target  │
│   (your app) │         │       API          │         │  (at home) │         │          │
└──────────────┘         └────────────────────┘         └────────────┘         └──────────┘
                                  │
                                  ▼
                         ┌────────────────────┐
                         │  TokenPaymentEscrow│   ← on-chain settlement
                         │   (Creditcoin)     │
                         └────────────────────┘
```

The Gateway picks a healthy Provider that matches your routing preferences (region, IP type), opens a tunnel, and relays traffic. Payment for the bandwidth is settled by signed on-chain receipt automatically.

### Two ways to participate

**I want to use the proxy** — Send requests through SpaceRouter Proxy from your app, script, or browser. Pay with SPACE on-chain — deposit once, pay per request.

**I want to run a Provider** — Share your home connection, stake SPACE, and earn rewards for serving traffic.

### What's in v1.5.0

* **Pay with SPACE** — Consumers deposit SPACE into the on-chain escrow and pay per request, with no subscription.
* **Earnings dashboard** — Providers see every receipt, claim history, and lifetime earnings inside the app.
* **Auto-claim** — Providers can opt in to automatic on-chain settlement when earnings cross a threshold.
* **Unified config path** — All platforms now use `~/.spacerouter/` for keys, settings, and receipts.

### Resources

<table data-header-hidden><thead><tr><th width="264.50390625"></th><th></th></tr></thead><tbody><tr><td>Website</td><td><a href="https://spacerouter.org">spacerouter.org</a></td></tr><tr><td>Provider download</td><td><a href="https://github.com/space-labs/space-router-node/releases/latest">github.com/space-labs/space-router-node/releases/latest</a></td></tr><tr><td>Python SDK</td><td><code>pip install spacerouter</code></td></tr><tr><td>JavaScript SDK</td><td><code>npm install @spacenetwork/spacerouter</code></td></tr><tr><td>Staking dApp</td><td><a href="https://penguinbase.com/dapp/spacestaking">penguinbase.com/dapp/spacestaking</a></td></tr><tr><td>Support</td><td><a href="mailto:router.support@spacenetwork.com">router.support@spacenetwork.com</a></td></tr><tr><td>Operator</td><td>Space Labs Ltd.</td></tr></tbody></table>


# Concepts

Plain-language definitions for the parts of SpaceRouter Proxy you'll see across these docs.

### The four roles

**Proxy Consumer** Anyone who sends traffic through SpaceRouter Proxy — a developer running an SDK, a script using curl, or an app calling the gateway. Consumers pay for the bandwidth they use.

**Proxy Provider** Anyone running the SpaceRouter Proxy app on a computer at home (or a server) to share their internet connection. Providers stake SPACE to qualify, serve traffic, and earn SPACE in return.

**Gateway** The single entry point for all consumer traffic. The gateway authenticates the consumer, picks a Provider that matches the request's region and IP type, and relays the traffic. You can think of it as the network's switchboard.

**Coordination API** The brain that registers Providers, runs health checks, calculates rewards, and pays Providers on-chain. Consumers don't interact with it directly.

### Status states for a Provider

The app on a Provider's machine and the staking dashboard show one of four status states. They tell you whether you are earning right now, and what to do if you are not.

<table><thead><tr><th width="118.421875">State</th><th>What it means</th><th>What to do</th></tr></thead><tbody><tr><td><strong>earning</strong></td><td>Your node is online, your stake is approved, and you are earning SPACE on every request routed through you.</td><td>Nothing — keep the node online.</td></tr><tr><td><strong>qualifying</strong></td><td>Your node is online and staked, but the network is still verifying your reliability for the current period. New nodes spend their first review window here.</td><td>Wait. Reviews run every 4 hours at fixed UTC times; full approval typically lands within one or two review cycles.</td></tr><tr><td><strong>unstaked</strong></td><td>Your node is online, but your stake is below the minimum required to earn.</td><td>Open the staking dApp and stake more SPACE.</td></tr><tr><td><strong>inactive</strong></td><td>Your node is offline, your wallet is draining, or no staking address is set.</td><td>Restart the app and check your network mode in Troubleshooting.</td></tr></tbody></table>

### Periods and review windows

SpaceRouter Proxy scores Provider reliability in fixed windows called **periods**. At the end of each period, the Coordination API decides which Providers earned during the window and approves new ones. Periods are measured in minutes, not blocks — they have nothing to do with Substrate eras.

### Tokens you'll see

<table><thead><tr><th width="102.3359375">Symbol</th><th>What it is</th><th>Where it's used</th></tr></thead><tbody><tr><td><strong>SPACE</strong></td><td>The Spacecoin token. ERC-20 on Creditcoin mainnet.</td><td>Stake to qualify as a Provider; deposit to escrow to pay for proxy traffic; receive as Provider rewards.</td></tr><tr><td><strong>CTC</strong></td><td>Creditcoin's native gas token.</td><td>Pays the gas fee on every on-chain transaction (deposit, claim, withdraw). You only need a small amount.</td></tr><tr><td><strong>SPC</strong></td><td>The testnet-only equivalent of SPACE.</td><td>Used on the Creditcoin CC3 testnet for development. <strong>Never used in production.</strong></td></tr></tbody></table>

### How you pay for traffic

You hold SPACE in your wallet, deposit some into the on-chain escrow contract, and your SDK signs a tiny receipt for every request. The gateway settles those receipts on-chain in batches. No subscription, no card, no per-month commitment. See the Pay with SPACE guide.

### The two-leg payment model

Behind the scenes, every paid proxy request produces two receipts:

* **Leg 1 — Consumer → Gateway.** The consumer's SDK signs this receipt with their wallet. It pays the network.
* **Leg 2 — Gateway → Provider.** The gateway pays the Provider for serving the traffic. The Provider claims these receipts on-chain when they're ready.

Consumers only ever sign Leg 1. Providers only ever claim Leg 2. The gateway keeps a small margin between the two — that funds operations.

### Wallets a Provider needs

A Provider has up to three Ethereum-style addresses. Most users keep them all the same; they only diverge if you deliberately separate custody.

<table><thead><tr><th width="114.16015625">Wallet</th><th>What it does</th><th>Funds it needs</th></tr></thead><tbody><tr><td><strong>Staking</strong></td><td>Holds your staked SPACE. You picked this when you staked.</td><td>SPACE (your stake)</td></tr><tr><td><strong>Collection</strong></td><td>Where your SPACE earnings land when you claim. Defaults to your Staking wallet.</td><td>None — it just receives</td></tr><tr><td><strong>Identity</strong></td><td>Created automatically by the app on first launch. Signs API requests <em>and</em> broadcasts your on-chain claim transactions.</td><td><strong>A small amount of CTC</strong> for gas. Without CTC here, claims fail.</td></tr></tbody></table>

{% hint style="warning" %}
**Most common provider mistake**

Forgetting that the Identity wallet needs CTC. You stake from your Staking wallet, but the app claims earnings from the Identity wallet. Top up the Identity wallet with \~1 CTC before your first claim.
{% endhint %}

### Glossary

**Receipt** — A small signed message that says "this many bytes were served at this price for this request." Used as on-chain proof of bandwidth.

**Escrow** — The on-chain contract that holds Consumer SPACE deposits and pays Providers when receipts are claimed.

**Claim** — A Provider's on-chain transaction that submits a batch of signed receipts and transfers earned SPACE into the Collection wallet.

**Identity key** — The private key the app generates on first launch. Stored at `~/.spacerouter/certs/node-identity.key`. Back this up.

**Region / IP type** — Routing preferences a Consumer can attach to a request: a 2-letter country code (e.g. `US`, `KR`) and one of `residential`, `mobile`, `business`, or `hosting`.

**Period — A fixed-length review window (currently 240 minutes /** 4 hours) used to aggregate Provider health-probe results. The Coordination API runs a review every 4 hours (at 00:00, 04:00, 08:00, 12:00, 16:00, 20:00 UTC) to approve or disapprove Providers based on their pass rate over the window.


# Reference

Endpoints, contract addresses, package versions — single source of truth.

### Latest release v1.5.0

All Provider apps and SDK packages are aligned on version **v1.5.0**.

<table><thead><tr><th width="252.2265625">Component</th><th>Version</th><th>Where</th></tr></thead><tbody><tr><td>Provider app (GUI &#x26; CLI)</td><td>v1.5.0</td><td><a href="https://github.com/space-labs/space-router-node/releases/">GitHub releases</a></td></tr><tr><td>Python SDK (<code>spacerouter</code>)</td><td>v1.5.0</td><td><a href="https://pypi.org/project/spacerouter/">PyPI</a></td></tr><tr><td>JavaScript SDK (<code>@spacenetwork/spacerouter</code>)</td><td>v1.5.0</td><td><a href="https://www.npmjs.com/package/@spacenetwork/spacerouter">npm</a></td></tr></tbody></table>

### Network endpoints

| Service               | URL                                         | Purpose                                      |
| --------------------- | ------------------------------------------- | -------------------------------------------- |
| Proxy gateway (HTTPS) | `https://gateway.spacerouter.org`           | Single entry point for all consumer traffic. |
| Proxy gateway (HTTP)  | `gateway.spacerouter.org:8080`              | HTTP proxy port.                             |
| Staking dApp          | `https://penguinbase.com/dapp/spacestaking` | Stake SPACE, view rewards, unstake.          |

### Tokens

| Symbol            | What it is                             | Where used                              |
| ----------------- | -------------------------------------- | --------------------------------------- |
| **SPACE** mainnet | Spacecoin token (ERC-20 on Creditcoin) | Staking, on-chain payment, rewards      |
| **CTC** mainnet   | Creditcoin native gas token            | Pays gas for every on-chain transaction |

### Creditcoin mainnet

| Setting          | Value                                                           |
| ---------------- | --------------------------------------------------------------- |
| Chain ID         | `102030`                                                        |
| RPC URL          | `https://mainnet3.creditcoin.network`                           |
| Block explorer   | [creditcoin.blockscout.com](https://creditcoin.blockscout.com/) |
| Native gas token | CTC                                                             |

### Smart contracts

Production contracts on Creditcoin mainnet:

<table><thead><tr><th width="308.8203125">Contract</th><th>Address</th></tr></thead><tbody><tr><td>SPACE token</td><td><code>0x7ab7C6A935Ab2D1437398790C9C0660af62A80b9</code></td></tr><tr><td>StakingV2</td><td><code>0x5d07fEd750F77C2DB8e7D1c031c05E3A5d2bc9fA</code></td></tr><tr><td>TokenPaymentEscrow</td><td><code>0xC130F5D76f0b4Ce8FE2ceA0D2C2b8f53A39a5cd0</code></td></tr></tbody></table>

{% hint style="warning" %}
**Why aren't the addresses fixed in this doc?**

Contracts may be redeployed or upgraded across releases. The Provider app and SDK ship with the canonical addresses for the matching version. The release notes for v1.5.0 list the deployed addresses; treat those as authoritative.
{% endhint %}

### Routing parameters

#### Country codes

Any 2-letter ISO 3166-1 alpha-2 code, e.g. `US`, `KR`, `JP`, `BR`, `DE`, `GB`.

#### IP types

| Value         | Description                                         |
| ------------- | --------------------------------------------------- |
| `residential` | Home internet connections (most demand).            |
| `mobile`      | Cellular / mobile broadband.                        |
| `business`    | Business / enterprise ISPs.                         |
| `hosting`     | Datacenter / VPS IPs (cheapest, easiest to detect). |

### HTTP status codes

The full table is in [Consumer Errors & Troubleshooting](/spacerouter-proxy/service-user-guide/errors-and-troubleshooting). Common codes:

* **200** — Success.
* **402** — Payment required (escrow empty or below request price).
* **407** — Payment headers missing or challenge signature failed.
* **429** — Rate limited.
* **502** — Provider couldn't reach target.
* **503** — No matching Provider.
* **504** — Provider didn't respond in time.

### File & data layout

Provider data directory (all platforms):

```
~/.spacerouter/
├── certs/
│   ├── node-identity.key
│   ├── node.crt
│   ├── node.key
│   └── gateway-ca.crt
├── settings.json
├── receipts.db          (SQLite)
├── incidents.json
└── logs/
    └── spacerouter-node.log
```

Linux package install (`.deb`, `.rpm`) places these under `/opt/spacerouter/` instead.

### Useful environment variables

#### Consumer SDK / CLI

| Variable                     | Purpose                                        |
| ---------------------------- | ---------------------------------------------- |
| `SR_GATEWAY_URL`             | Override gateway.                              |
| `SR_GATEWAY_MANAGEMENT_URL`  | Management API (`/auth/challenge`, `/leg1/*`). |
| `SR_ESCROW_CHAIN_RPC`        | Creditcoin RPC for on-chain calls.             |
| `SR_ESCROW_CONTRACT_ADDRESS` | TokenPaymentEscrow contract address.           |
| `SR_ESCROW_PRIVATE_KEY`      | Wallet key for deposit/withdraw.               |

#### Provider

| Variable                             | Purpose                             |
| ------------------------------------ | ----------------------------------- |
| `SR_IDENTITY_PASSPHRASE`             | Decrypt identity key.               |
| `SR_RECEIPT_MAX_SIGN_ATTEMPTS`       | Sign retry cap (default 2).         |
| `SR_RECEIPT_MAX_CLAIM_ATTEMPTS`      | Claim retry cap (default 2).        |
| `SR_RECEIPT_REAPER_INTERVAL_SECONDS` | Reaper tick interval (default 300). |

### Repositories

* **Provider app:** [github.com/space-labs/space-router-node](https://github.com/space-labs/space-router-node)
* **SDK (Python & JS):** [github.com/space-labs/space-router-sdk](https://github.com/space-labs/space-router-sdk)

### Support

Email: <router.support@spacenetwork.com> Bug reports: open an issue on the relevant GitHub repo.


# Service User Guide

Audience: Developers, businesses, and AI agents that want to use the SpaceRouter proxy network

## Quick Start

Send your first request through SpaceRouter Proxy in under five minutes.

You'll need a wallet with a small amount of SPACE (and a little CTC for gas). If you don't have one yet, see [Pay with SPACE](/spacerouter-proxy/service-user-guide/pay-with-space-v1.5) for the full setup walkthrough.

### Try it with the CLI

Install the CLI, deposit some SPACE, and make a paid request:

```bash
pip install spacerouter

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

# One-time: deposit SPACE into the escrow contract for your wallet.
spacerouter escrow deposit 10000000000000000000   # 10 SPACE

# Send a paid request.
spacerouter request get https://httpbin.org/ip --pay
```

You should see a JSON response with the IP of the residential node that served your request.

### Geo targeting

Add `--region` and `--ip-type` flags to target a country and IP type:

```bash
spacerouter request get https://httpbin.org/ip --pay --region KR --ip-type residential
```

* **Region** — any 2-letter ISO country code (e.g. `US`, `KR`, `BR`).
* **IP type** — one of `residential`, `mobile`, `business`, or `hosting`.

{% hint style="info" %}
**No nodes match?**

If no Provider currently matches your region/type combination, the gateway returns **HTTP 503**. Drop the type filter or pick a more popular region and try again.
{% endhint %}

### Use an SDK

* **Python SDK** — `pip install spacerouter` — sync & async clients, EIP-712 receipts, escrow client.
* **JavaScript SDK** — `npm install @spacenetwork/spacerouter` — Node.js (Undici-based), TypeScript types included.

### Where to next

* Read the full [Pay with SPACE](/spacerouter-proxy/service-user-guide/pay-with-space-v1.5) walkthrough.
* Read about the [core concepts](/spacerouter-proxy/concepts).
* If something fails, check [Errors & Troubleshooting](/spacerouter-proxy/service-user-guide/errors-and-troubleshooting).


# Pay with SPACE v1.5

Use your wallet to pay for proxy traffic on-chain. Deposit SPACE once, then send requests as long as your balance lasts.

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


# JavaScript SDK

The official Node.js client for SpaceRouter Proxy. Promise-based API, TypeScript types included.

### Install

```bash
npm install @spacenetwork/spacerouter
```

Requires Node.js 18 or later. Browser and Bun support are on the roadmap.

### SPACE-payment example

```ts
import { SpaceRouter, SpaceRouterSPACE } from "@spacenetwork/spacerouter";

const payment = new SpaceRouterSPACE({
  gatewayMgmtUrl: "https://gateway.spacerouter.org",
  wallet,                                          // your ClientPaymentWallet
});

const router = new SpaceRouter("0xYOUR_WALLET_ADDRESS", {
  gatewayUrl: "https://gateway.spacerouter.org",
  payment,
  region: "KR",
  ipType: "residential",
});

const response = await router.get("https://httpbin.org/ip");
console.log(await response.json());
router.close();
```

The first positional argument is the consumer's wallet address (lowercase 0x-hex). The `payment` helper signs the per-request EIP-191 challenge that the gateway requires.

### Constructor

```ts
new SpaceRouter(payerAddress: string, options: {
  gatewayUrl?: string;             // default: "https://gateway.spacerouter.org"
  payment: SpaceRouterSPACE;       // required — signs per-request challenges
  protocol?: "http";               // "http" only — socks5 not supported in v1.5+
  region?: string;                 // 2-letter ISO country code
  ipType?: "residential" | "mobile" | "business" | "hosting";
  timeout?: number;                // default: 30000 (ms)
})
```

### Methods

```ts
await router.request(method, url, options?)
await router.get(url, options?)
await router.post(url, options?)
await router.put(url, options?)
await router.patch(url, options?)
await router.delete(url, options?)
await router.head(url, options?)

// Per-request routing override
const krRouter = router.withRouting({ region: "KR", ipType: "residential" });

// Always close when done
router.close();
```

`options` accepts `headers`, `body`, and an `AbortSignal`:

```ts
const ctrl = new AbortController();
setTimeout(() => ctrl.abort(), 5000);

const r = await router.post("https://api.example.com/v1/items", {
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ name: "widget" }),
  signal: ctrl.signal,
});
```

### The response object

```ts
interface ProxyResponse {
  status: number;
  headers: Record<string, string>;
  body: ReadableStream;
  text(): Promise<string>;
  json(): Promise<unknown>;
  nodeId: string;  // ID of the Provider that served this request
}
```

### Errors

All errors extend `SpaceRouterError`:

| Class                   | HTTP | Raised when                                                                                                            |
| ----------------------- | ---- | ---------------------------------------------------------------------------------------------------------------------- |
| `AuthenticationError`   | 407  | Payment headers missing or challenge signature rejected.                                                               |
| `QuotaExceededError`    | 402  | Escrow balance below the request's price, or legacy `Proxy-Authorization: Basic` detected (`api_key_auth_deprecated`). |
| `RateLimitError`        | 429  | Rate limited. Has `retryAfter`.                                                                                        |
| `NoNodesAvailableError` | 503  | No Provider matches your region/type filter.                                                                           |
| `UpstreamError`         | 502  | Provider couldn't reach the target site.                                                                               |

```ts
import { NoNodesAvailableError } from "@spacenetwork/spacerouter";

try {
  await router.get("https://httpbin.org/ip");
} catch (err) {
  if (err instanceof NoNodesAvailableError) {
    console.log("No matching nodes — try another region");
  } else {
    throw err;
  }
}
```

### Pay with SPACE

The JavaScript SDK uses on-chain SPACE payment as its only auth mechanism — every request constructed via `SpaceRouter` is paid per byte from the consumer's escrow balance. See the [Pay with SPACE guide](/spacerouter-proxy/service-user-guide/pay-with-space-v1.5) for the wallet/escrow setup, the protocol details, and the matching Python reference implementation.


# Python SDK

The official Python client for SpaceRouter Proxy. Sync, async, and on-chain payment in one package.

### Install

```bash
pip install spacerouter
```

Requires Python 3.10 or later.

### Synchronous client

```python
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(),                  # wallet address as first positional arg
    gateway_url="http://gateway.spacerouter.org:8080",
    payment=consumer,
    auto_settle=True,
    region="KR",
    ip_type="residential",
) as router:
    response = router.get("https://httpbin.org/ip")
    print(response.json())
```

### Constructor

```python
SpaceRouter(
    payer_address: str,                       # consumer wallet (lowercase 0x-hex)
    *,
    gateway_url: str = "https://gateway.spacerouter.org",
    payment: SpaceRouterSPACE,                # required — signs per-request challenges
    auto_settle: bool = False,                # sync receipts after each request
    protocol: Literal["http"] = "http",       # "http" only — socks5 not supported in v1.5+
    region: str | None = None,
    ip_type: str | None = None,
    timeout: float = 30.0,
)
```

### HTTP methods

Each method takes a URL and forwards keyword arguments to `httpx`:

```python
router.get(url, **kwargs)
router.post(url, json=..., **kwargs)
router.put(url, **kwargs)
router.patch(url, **kwargs)
router.delete(url, **kwargs)
router.head(url, **kwargs)
router.request(method, url, **kwargs)
```

### Per-request routing override

```python
kr_router = router.with_routing(region="KR", ip_type="residential")
us_router = router.with_routing(region="US")

kr_router.get("https://httpbin.org/ip")
```

### Async client

```python
import asyncio
from spacerouter import AsyncSpaceRouter
from spacerouter.payment import SpaceRouterSPACE

async def main():
    consumer = SpaceRouterSPACE(
        gateway_url="https://gateway.spacerouter.org",
        proxy_url="http://gateway.spacerouter.org:8080",
        private_key="0xYOUR_PRIVATE_KEY",
    )
    async with AsyncSpaceRouter(
        consumer.address.lower(),
        gateway_url="http://gateway.spacerouter.org:8080",
        payment=consumer,
        auto_settle=True,
    ) as router:
        response = await router.get("https://httpbin.org/ip")
        print(await response.json())

asyncio.run(main())
```

### Manual signing (advanced)

If you can't use the bundled `SpaceRouter` / `AsyncSpaceRouter` clients, you can build the four `X-SpaceRouter-*` headers yourself and stamp them on the proxy CONNECT.

```python
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",
)

challenge = await consumer.request_challenge()
headers = consumer.build_auth_headers(challenge)
# … attach `headers` to the proxy CONNECT request

# Sync any pending Leg-1 receipts on chain
result = await consumer.sync_receipts()
print(result["accepted"], result["pending_count"])
```

See the full walk-through in [Pay with SPACE](https://claude.ai/local_sessions/pay-with-space-v1.5.md).

### Errors

Every SpaceRouter error subclasses `SpaceRouterError`:

<table><thead><tr><th width="225.328125">Class</th><th width="85.15234375">HTTP</th><th>Raised when</th></tr></thead><tbody><tr><td><code>AuthenticationError</code></td><td>407</td><td>Payment headers missing or challenge signature rejected.</td></tr><tr><td><code>QuotaExceededError</code></td><td>402</td><td>Escrow balance below the request's price, or legacy <code>Proxy-Authorization: Basic</code> detected (<code>api_key_auth_deprecated</code>).</td></tr><tr><td><code>RateLimitError</code></td><td>429</td><td>Too many requests. Has <code>retry_after</code>.</td></tr><tr><td><code>NoNodesAvailableError</code></td><td>503</td><td>No Provider matches your region/type filter.</td></tr><tr><td><code>UpstreamError</code></td><td>502</td><td>Provider couldn't reach the target site.</td></tr></tbody></table>

```python
from spacerouter import SpaceRouter, NoNodesAvailableError

try:
    router.get("https://httpbin.org/ip")
except NoNodesAvailableError:
    print("No matching nodes — try a different region")
```

### Configuration via environment

The CLI and SDK both read these:

<table><thead><tr><th width="265.38671875">Variable</th><th>Purpose</th></tr></thead><tbody><tr><td><code>SR_GATEWAY_URL</code></td><td>Override the gateway hostname (mostly for testing).</td></tr><tr><td><code>SR_GATEWAY_MANAGEMENT_URL</code></td><td>Management API endpoint (<code>/auth/challenge</code>, <code>/leg1/*</code>).</td></tr><tr><td><code>SR_ESCROW_PRIVATE_KEY</code></td><td>Wallet key for deposit/withdraw and per-request signing.</td></tr><tr><td><code>SR_ESCROW_CONTRACT_ADDRESS</code></td><td><code>TokenPaymentEscrow</code> contract address.</td></tr><tr><td><code>SR_ESCROW_CHAIN_RPC</code></td><td>Creditcoin RPC for on-chain calls.</td></tr></tbody></table>


# CLI

A command-line tool for sending requests, managing your escrow balance, and inspecting on-chain state.

### Install

```bash
pip install spacerouter
```

The Python package ships with the `spacerouter` command. Verify it's on your `PATH`:

```bash
spacerouter --version
```

### Environment

Most commands read defaults from these environment variables:

| Variable                     | Used by                                  |
| ---------------------------- | ---------------------------------------- |
| `SR_GATEWAY_URL`             | `request` commands                       |
| `SR_GATEWAY_MANAGEMENT_URL`  | `request` commands (challenge endpoint)  |
| `SR_ESCROW_CHAIN_RPC`        | `escrow`, `receipts`                     |
| `SR_ESCROW_CONTRACT_ADDRESS` | `escrow`, `receipts`                     |
| `SR_ESCROW_PRIVATE_KEY`      | `escrow` write commands, `request --pay` |

### `request` — send proxy requests

```bash
spacerouter request get https://httpbin.org/ip --pay --region US --ip-type residential

spacerouter request post https://api.example.com/v1/items --pay \
    -H "Content-Type: application/json" \
    --data '{"name":"widget"}'
```

Sub-commands: `get`, `post`, `put`, `patch`, `delete`, `head`.

#### Common flags

| Flag                 | Purpose                                                                    |
| -------------------- | -------------------------------------------------------------------------- |
| `--pay`              | Sign the request with the SPACE-payment flow (required for paid requests). |
| `--auto-settle`      | After `--pay`, sign and submit the parked Leg 1 receipt in the same step.  |
| `--gateway-url URL`  | Gateway endpoint (overrides `SR_GATEWAY_URL`).                             |
| `--region XX`        | 2-letter ISO country code.                                                 |
| `--ip-type TYPE`     | `residential`, `mobile`, `business`, `hosting`.                            |
| `-H, --header`       | Add a request header (repeat for multiple).                                |
| `-d, --data`         | Request body (string, file, or `@filename`).                               |
| `--timeout SEC`      | Request timeout in seconds.                                                |
| `--output FORMAT`    | `json` (default) or `raw`.                                                 |
| `--follow-redirects` | Follow HTTP redirects.                                                     |

### `escrow` — manage your on-chain balance

#### Read commands

```bash
spacerouter escrow balance <address>
spacerouter escrow token-balance <address>
spacerouter escrow withdrawal-request <address>
spacerouter escrow withdrawal-delay
```

Example output for `balance`:

```json
{
  "address": "0xAbc…",
  "escrow_balance_wei": 50000000000000000000,
  "escrow_balance_space": "50.0"
}
```

#### Write commands (need `--private-key` or `SR_ESCROW_PRIVATE_KEY`)

```bash
spacerouter escrow approve <amount_wei>            # one-shot ERC-20 allowance
spacerouter escrow deposit <amount_wei>
spacerouter escrow initiate-withdrawal <amount_wei>
spacerouter escrow execute-withdrawal
spacerouter escrow cancel-withdrawal
```

All amounts are in wei. 1 SPACE = 10¹⁸ wei. The 5-day withdrawal delay is enforced by the contract — see [Pay with SPACE](/spacerouter-proxy/service-user-guide/pay-with-space-v1.5).

### `receipts` — inspect on-chain receipt state

```bash
spacerouter receipts pending     # list unsigned receipts the gateway has for you
spacerouter receipts sync        # fetch, sign, and submit all pending receipts
spacerouter receipts is-settled <client_address> <request_uuid>
spacerouter receipts show <client_address> <request_uuid>
```

Use `sync` after a session to make sure the gateway can claim its bandwidth fees on-chain. `is-settled` lets you double-check that a specific request was claimed.

### Examples

#### Top up and use SPACE for a session

```bash
export SR_ESCROW_PRIVATE_KEY=0x...

spacerouter escrow deposit 50000000000000000000   # 50 SPACE

# … run your scripts …
spacerouter request get https://httpbin.org/ip --pay --region KR

spacerouter receipts sync
spacerouter escrow balance 0xYourAddress
```


# Errors & Troubleshooting

Every HTTP code the gateway can return, what it means, and how to fix it.

### HTTP status codes

<table><thead><tr><th width="83.484375">Code</th><th width="160.7734375">Name</th><th>Meaning</th><th>Fix</th></tr></thead><tbody><tr><td><strong>402</strong></td><td>Payment Required</td><td>Escrow balance is below the request price (SPACE).</td><td>Run <code>spacerouter escrow deposit</code>.</td></tr><tr><td><strong>407</strong></td><td>Proxy Authentication Required</td><td>Payment headers landed on the inner request instead of the CONNECT, or the challenge signature was rejected.</td><td>Use the SDK helper — it puts headers on CONNECT and signs each fresh challenge.</td></tr><tr><td><strong>429</strong></td><td>Too Many Requests</td><td>You're hitting the rate limit (60 RPM per wallet by default).</td><td>Honor the <code>Retry-After</code> header and back off.</td></tr><tr><td><strong>502</strong></td><td>Bad Gateway / Upstream Error</td><td>The Provider reached your target site but got an error from it (e.g. site rejected the IP).</td><td>Try a different region or IP type.</td></tr><tr><td><strong>503</strong></td><td>Service Unavailable</td><td>No Provider currently matches your region/IP-type filter.</td><td>Drop the type filter or pick a more popular region.</td></tr></tbody></table>

### Common scenarios

#### "It worked yesterday, today every request is 402"

Almost always: your escrow balance has run out. Check it with `spacerouter escrow balance 0xYourAddress`, then top up with `spacerouter escrow deposit <amount_wei>`.

If the balance is fine but the gateway still returns `402 api_key_auth_deprecated`, your client is on the legacy `Proxy-Authorization: Basic sr_live_…` flow. Upgrade to the v1.5 SDK and switch to the wallet + `payment` constructor.

#### Some target sites block me

The IP type matters. Hosting IPs are commonly blocked by anti-bot systems. Try `type=residential` or `type=mobile`.

#### "503 No nodes available" for every request

Your region/type combination has no live Providers right now. Pick a more popular region (e.g. `US`, `KR`, `JP`) or drop the type filter and let the gateway pick.

#### SPACE deposit transaction reverts

Most likely: your wallet has SPACE but no CTC for gas, or the escrow allowance was never granted. The CLI handles approval automatically; if you're calling the contract directly, run `token.approve(escrow, amount)` first.

#### SDK calls hang forever

You're behind a corporate firewall that blocks port 8080. Use the HTTPS gateway URL (`https://gateway.spacerouter.org`) — it tunnels over 443.

### Get help

If you've checked the above and you're still stuck:

* Email [**router.support@spacenetwork.com**](mailto:router.support@spacenetwork.com) with the request ID from the response headers (`X-Request-Id`).
* For SDK bugs, file an issue on the public repos.


# Proxy Provider Guide

From zero to earning SPACE in roughly 10 minutes — once your stake is in place.

You'll do six things, in order. Each links to a more detailed guide if you need it.

1. **Check prerequisites** — supported OS, open port 9090 (or a tunnel), staked SPACE, \~1 CTC for gas.
2. **Download & install** — pick the GUI installer for your operating system, or the CLI binary for headless servers.
3. **Run first-time setup** — generate or import your identity key, set your staking address, choose a network mode.
4. **Click Start** — your node enters **qualifying**, then moves to **earning** after the first review period.
5. **Watch your earnings** — the Earnings screen tallies SPACE owed for every request you serve.
6. **Claim** — once you have a few receipts, hit *Claim All Outstanding* to settle them on-chain. Your SPACE arrives in your collection wallet.

### What you'll see

#### The status badge

* **qualifying** — first 1–2 review periods after install. The network is verifying your reliability.
* **earning** — you're approved and earning SPACE on every request routed through you.
* **unstaked** — your stake is below the minimum. Add SPACE in the staking dApp.
* **inactive** — your node is offline or the wallet is draining.

#### The Earnings screen

Every request you serve produces a small **receipt**. The Earnings screen shows them grouped:

* **Claimable** — receipts ready to settle on-chain.
* **Pending signing** — receipts the gateway hasn't yet acknowledged.
* **Needs attention** — receipts that hit a transient error and will be retried.
* **Locked** — receipts that failed permanently and won't be retried.
* **History** — receipts already claimed.

### The single most important thing

{% hint style="warning" %}
**Top up your Identity wallet with CTC**

The app generates an **Identity wallet** on first launch. That wallet — not your staking wallet — submits your claim transactions to Creditcoin. It needs **\~1 CTC** for gas. Without CTC there, every claim will fail with `insufficient funds`. The Earnings screen shows the Identity wallet address with a copy button. Send a small amount of CTC to it before your first claim.
{% endhint %}

### Where to go next

**Prerequisites** — System requirements, network setup, wallets you'll need.

**Install** — Desktop installer or headless CLI binary.

**First-Time Setup** — Identity key, staking address, network mode.

**Claim Your Earnings** — How payments work and how to settle on-chain.


# Prerequisites

What you need before installing the Provider app.

### System

<table><thead><tr><th width="198.37890625">Requirement</th><th>Detail</th></tr></thead><tbody><tr><td>Operating system</td><td>Windows 10/11 (x64), macOS 12+ (Apple Silicon or Intel), or Linux x64</td></tr><tr><td>RAM</td><td>2 GB free</td></tr><tr><td>Disk</td><td>500 MB free</td></tr><tr><td>Always-on connection</td><td>Wired or Wi-Fi; the longer your node is online the more it earns</td></tr><tr><td>Bandwidth</td><td>No fixed minimum, but unmetered or generous quota strongly recommended</td></tr></tbody></table>

### Network

The gateway connects to your node on port **9090** (TCP, encrypted with TLS). You have three options:

1. **UPnP (recommended for home routers)** — the app opens the port automatically. No router config needed.
2. **Manual port forwarding** — open port 9090 (or any port you choose) in your router and point it at the machine running the node.
3. **Tunnel (CGNAT, double NAT, restrictive ISP)** — use a reverse-tunnel service like [bore](https://github.com/ekzhang/bore) or [ngrok](https://ngrok.com/). Many ISPs (especially mobile/4G/5G) put you behind CGNAT — UPnP can't help there.

{% hint style="info" %}
**Not sure if you're behind CGNAT?**

Check the WAN/Internet IP shown on your router's admin page. If it begins with `100.64.` through `100.127.`, you're behind CGNAT and need a tunnel. If it begins with `10.`, `192.168.`, or `172.16-31.`, you may be behind double NAT.
{% endhint %}

### Staking

To *earn*, your node must be backed by staked SPACE. To *install and run*, no stake is required (your node will sit in **unstaked** state).

* Minimum stake: **1 SPACE**.
* Stake from any Creditcoin-compatible wallet via the [staking dApp](https://penguinbase.com/dapp/spacestaking).
* Detailed walk-through: Staking Guide.

### Wallets you'll use

A Provider has up to three Ethereum-style addresses. Many providers reuse the same address for all three; only separate them if you have a specific custody reason.

<table><thead><tr><th width="116.4296875">Wallet</th><th>What it does</th><th>What it needs</th></tr></thead><tbody><tr><td><strong>Staking</strong></td><td>Holds your staked SPACE. Picked when you staked.</td><td>Your stake (≥ 1 SPACE).</td></tr><tr><td><strong>Collection</strong></td><td>Where your earned SPACE lands when you claim. Defaults to the staking wallet.</td><td>Nothing — it just receives.</td></tr><tr><td><strong>Identity</strong></td><td>Generated automatically by the app on first launch. Signs API requests <em>and</em> broadcasts your claim transactions.</td><td><strong>~1 CTC</strong> for gas. Top this up before your first claim.</td></tr></tbody></table>

{% hint style="warning" %}
**The CTC trap**

Most "claim failed" support tickets trace back to the Identity wallet running out of CTC. The Earnings screen shows the Identity address with a copy button — fund it once, top up occasionally, and you're set.
{% endhint %}

### Pre-flight checklist

* ☐ Supported OS confirmed
* ☐ Port 9090 reachable (or a tunnel ready)
* ☐ Stake of ≥ 1 SPACE in your staking wallet
* ☐ A small amount of CTC (\~1) ready to send to the Identity wallet after install
* ☐ Time set correctly on your machine (NTP enabled — required for receipt signing)

Ready? On to Install.


# Install

Pick the desktop installer for your OS, or the headless CLI for servers.

### Download

All builds are published on GitHub:

[**github.com/space-labs/space-router-node/releases/latest**](https://github.com/space-labs/space-router-node/releases/latest)

<table><thead><tr><th width="154.16796875">Platform</th><th>GUI installer</th><th>Headless CLI</th></tr></thead><tbody><tr><td>Windows x64</td><td><code>spacerouter-gui-windows-x64-setup.exe</code></td><td><code>space-router-node-windows-x64.exe</code></td></tr><tr><td>macOS (Apple Silicon)</td><td><code>spacerouter-gui-macos-arm64.dmg</code></td><td><code>space-router-node-macos-arm64</code></td></tr><tr><td>Linux x64</td><td>—</td><td><code>space-router-node-linux-x64</code></td></tr><tr><td>Linux x64 (Debian/Ubuntu)</td><td>—</td><td><code>space-router-node-linux-x64.deb</code></td></tr><tr><td>Linux x64 (RHEL/Fedora)</td><td>—</td><td><code>space-router-node-linux-x64.rpm</code></td></tr></tbody></table>

### Desktop install

#### macOS

1. Open the downloaded `.dmg` file.
2. Drag **SpaceRouter Proxy** into your **Applications** folder.
3. Launch **SpaceRouter Proxy** from Launchpad or Spotlight.

#### Windows

1. Run the downloaded `spacerouter-gui-windows-x64-setup.exe`.
2. Follow the installer prompts. Windows SmartScreen may warn about an unrecognized publisher — click *More info* → *Run anyway*.
3. Launch **SpaceRouter Proxy** from the Start menu.

#### Linux

The AppImage is portable — no install step needed:

```
chmod +x spacerouter-gui-linux-x64.AppImage
./spacerouter-gui-linux-x64.AppImage
```

### Headless / server install

#### macOS / Linux (binary)

```bash
# macOS Apple Silicon
chmod +x space-router-node-macos-arm64
./space-router-node-macos-arm64

# Linux x64
chmod +x space-router-node-linux-x64
./space-router-node-linux-x64
```

#### Linux .deb (Debian, Ubuntu)

```
sudo dpkg -i space-router-node-linux-x64.deb
sudo systemctl enable --now spacerouter-node
```

#### Linux .rpm (RHEL, Fedora)

```
sudo rpm -i space-router-node-linux-x64.rpm
sudo systemctl enable --now spacerouter-node
```

#### Windows (binary)

```
.\space-router-node-windows-x64.exe
```

### What gets installed where

v1.5 unifies the data directory across all operating systems:

| Platform                           | Data directory                |
| ---------------------------------- | ----------------------------- |
| macOS (GUI & CLI)                  | `~/.spacerouter/`             |
| Linux (GUI & CLI)                  | `~/.spacerouter/`             |
| Windows (GUI & CLI)                | `%USERPROFILE%\.spacerouter\` |
| Linux (.deb / .rpm system service) | `/opt/spacerouter/`           |

#### What's in the data directory

```
~/.spacerouter/
├── certs/
│   ├── node-identity.key      # your private key — back this up
│   ├── node.crt               # TLS cert (auto-renewed)
│   └── node.key
├── settings.json              # canonical config
├── receipts.db                # local SQLite store of receipts
├── incidents.json             # auto-claim failure log
└── logs/                      # runtime logs
```

{% hint style="warning" %}
**Back up your identity key**

`node-identity.key` is the cryptographic identity of your node. Lose it and you lose your earnings history (though not your stake). Copy it to safe storage right after first run.
{% endhint %}

### Upgrading

To upgrade to a new release:

* **GUI:** Quit the app, install the new build over the old one, relaunch. Your `~/.spacerouter/` is preserved.
* **CLI binary:** Stop the running process, replace the binary, restart.
* **Linux .deb / .rpm:** `sudo dpkg -i` / `sudo rpm -U` the new package.

### Migrating from v1.4

On first launch of v1.5, the app automatically migrates your old config and identity key from the v1.4 location to `~/.spacerouter/`. The migration is one-way and idempotent. Your stake, earnings history, and identity are preserved.

Once installed, head to First-Time Setup.


# First-Time Setup

A single setup screen on first launch. Five fields, all but one optional.

### Identity Key

The identity key is your node's permanent cryptographic identity. The setup screen offers two options:

* **Generate a new key (recommended)** — the app creates a fresh key and stores it at `~/.spacerouter/certs/node-identity.key`.
* **Import an existing key** — paste a 64-character hex private key. Use this if you're moving a node to a new machine.

{% hint style="warning" %}
**Back up the file right after setup**

Copy `node-identity.key` to safe storage. If you lose it you'll have to re-onboard from scratch (the new node looks like a brand-new node to the network).
{% endhint %}

#### Optional: encrypt with a passphrase

You can protect the identity key with a passphrase. The app will prompt for it on every launch. Forget it and the file is unrecoverable, so use a password manager.

For headless installs, set `SR_IDENTITY_PASSPHRASE` in the environment so the daemon can decrypt without prompting.

### Staking Address

The Creditcoin wallet that holds your stake. Required to earn — leave it blank and the node runs in **unstaked** state.

The address is a standard EVM address: 42 characters starting with `0x`. You can paste it from the staking dApp.

If left blank, the staking address defaults to your identity address. Most providers prefer to keep these separate (cold-storage staking, hot identity).

### Collection Address (optional)

The wallet that *receives* your earnings when you claim. If you leave it blank, it defaults to the staking address.

Set this to a separate address if you want earnings to flow somewhere other than your staking wallet — for example, a hot wallet you actually transact from.

### Referral Code (optional)

If someone referred you, paste their code here. Codes are 3–50 characters, alphanumeric with hyphens or underscores.

### Network Mode

How the gateway reaches your node. Pick the one that matches your network:

| Mode                 | Pick this if…                                                                                | What you set                                                         |
| -------------------- | -------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
| **UPnP (Automatic)** | You're on a home router that supports UPnP/NAT-PMP. Default for most setups.                 | Nothing — the app discovers your public IP and opens port 9090.      |
| **Manual**           | You disabled UPnP and forwarded the port yourself, or you have a static public IP.           | Public IP / hostname and the port you forwarded.                     |
| **Tunnel**           | You're behind CGNAT, on mobile broadband, or in a restrictive network. UPnP can't help here. | The hostname and port your tunnel service (bore, ngrok, …) gave you. |

#### Tunnel mode example with bore

```
# In one terminal, run bore to expose your local port 9090
bore local 9090 --to bore.pub
# bore prints something like:
# listening at bore.pub:46213

# In SpaceRouter:
#   Network mode: Tunnel
#   Public hostname: bore.pub
#   Public port:     46213
```

### Click Start

Hit **Start**. The status badge transitions through:

1. **initializing** — a few seconds, while the app contacts the Coordination API.
2. **qualifying** — your node is registered and ready; the network is verifying your reliability for the current period.
3. **earning** — you're approved. SPACE is being credited as you serve traffic.

qualifying and earning are reported by the Coordination API based on its review cycle (every 4 hours, 240-minute lookback window). The first transition into earning typically takes one or two review cycles after your node is reliably online and your stake is on chain.

{% hint style="info" %}
**Already running a node? Reset to start fresh**

Click **Reset Node** on the main screen to clear the identity key and config and re-run setup. This deletes `~/.spacerouter/certs/node-identity.key` — back it up first if you might want to recover it.
{% endhint %}

### Headless / scripted setup

For server installs, all setup options have CLI flags:

```bash
./space-router-node-linux-x64 \
  --staking-address 0xYourStakingAddress \
  --collection-address 0xYourCollectionAddress \
  --no-upnp \
  --public-url myhost.example.com \
  --public-port 9090 \
  --label "node-eu-west-1"
```

See the CLI Reference for all flags.


# Daily Operation

What the app shows you, what each status means, and how to read your earnings.

### Status screen

The home screen of the app has a single status badge plus your wallet info.

#### Status states

<table><thead><tr><th width="115.93359375">Status</th><th width="114.62890625">Indicator</th><th>Meaning</th><th>What to do</th></tr></thead><tbody><tr><td><strong>earning</strong></td><td>green</td><td>Your node is online, your stake is approved, and you are earning SPACE on every routed request.</td><td>Nothing — keep the node online.</td></tr><tr><td><strong>qualifying</strong></td><td>yellow</td><td>Your node is online, but the network hasn't approved you yet. New nodes spend their first review period(s) here.</td><td>Wait. Reviews run every 4 hours.</td></tr><tr><td><strong>unstaked</strong></td><td>red</td><td>Your node is online, but your stake is below the 1,000 SPACE minimum.</td><td>Open the staking dApp and stake more SPACE.</td></tr><tr><td><strong>inactive</strong></td><td>dim</td><td>Your node is offline, draining, or has no staking address.</td><td>Click <em>Start</em>; if it stays inactive, see Troubleshooting.</td></tr></tbody></table>

#### What "qualifying" actually means

The Coordination API runs a continuous health check against every Provider. Every 4 hours (at 00:00, 04:00, 08:00, 12:00, 16:00, 20:00 UTC) it scores your reliability over the most recent 240-minute window. Once you cross the pass threshold, you move to earning. Brand-new nodes typically clear it within one or two review cycles.

If you bounce between **qualifying** and **inactive**, you have a connectivity problem. Check the network mode and see Troubleshooting.

### Wallet panel

The status screen shows three address chips:

* **Identity** — auto-generated. Click to copy. *This is the wallet that needs CTC for gas.*
* **Staking** — what you set during setup. Click to view it on the staking dApp.
* **Collection** — where claimed SPACE lands. Equal to staking unless you set it otherwise.

### Earnings screen

Click **Earnings** from the status screen to open the receipt dashboard.

#### Sections

<table><thead><tr><th width="159.94921875">Section</th><th>What's in it</th><th>Action</th></tr></thead><tbody><tr><td><strong>Claimable</strong></td><td>Receipts the gateway has signed for you. Ready to settle on chain.</td><td>"Claim All Outstanding" button.</td></tr><tr><td><strong>Pending signing</strong></td><td>Receipts waiting for the gateway's EIP-712 signature.</td><td>None — they sign themselves shortly.</td></tr><tr><td><strong>Needs attention</strong></td><td>Receipts that hit a transient failure (network, RPC). Will retry automatically.</td><td>Click "Retry now" to retry immediately.</td></tr><tr><td><strong>Locked</strong></td><td>Receipts that failed twice and are permanently rejected. They show why.</td><td>None — these can't be claimed.</td></tr><tr><td><strong>History</strong></td><td>Receipts already claimed on chain.</td><td>Click for a Blockscout link.</td></tr></tbody></table>

#### The Claim wallet card

Right above the Claimable section is a card that shows your **Identity wallet** address and its current CTC balance. If the balance is too low for the next claim, the card shows a yellow warning and an explanation. Read the Claim guide →

#### Receipt detail

Click any receipt to open its detail modal:

* Request UUID
* Bytes served and price
* Current state (pending\_sign / claimable / failed\_retryable / failed\_terminal / claimed)
* Error reason (if any) with a "What this means" explanation
* Blockscout link to the on-chain claim transaction (if claimed)

### Settings panel

The Settings gear opens a panel for runtime configuration:

* Network mode (UPnP / Manual / Tunnel) — change without re-onboarding.
* Auto-claim toggle and thresholds — see Auto-claim.
* Log level.
* Coordination API endpoint (advanced — only change if instructed).

Saving the settings panel restarts the daemon automatically. The status badge briefly returns to *initializing*.

### Reset Node

The bottom of the status screen has a **Reset Node** button. It deletes your identity key, settings, and receipt store, and re-runs first-time setup.

{% hint style="danger" %}
**Reset is destructive**

Resetting deletes your `node-identity.key`. If you don't have a backup, you can't restore the same node — the network will treat the new identity as a brand-new Provider and you'll re-enter **qualifying**. Your stake and any *unclaimed* earnings tied to the old identity may be unrecoverable.
{% endhint %}

### Logs

Logs are written to `~/.spacerouter/logs/spacerouter-node.log`. Rotate automatically; one line per event. The most useful filters:

```
tail -f ~/.spacerouter/logs/spacerouter-node.log
grep "Loaded node identity" ~/.spacerouter/logs/spacerouter-node.log    # find your identity address
grep -E "(claim|receipt)" ~/.spacerouter/logs/spacerouter-node.log      # payment events
```

If you need to share logs with support, redact your identity address and any private keys before sending.


# Claim Your Earnings

How traffic becomes SPACE in your collection wallet.

### How payment works

Every proxy request you serve produces a **receipt** — a tiny signed message that says "this many bytes were served at this price." The lifecycle is:

```
  ┌──────────────┐    you serve     ┌──────────────┐
  │   pending    │ ───────────────▶│  claimable   │
  │   _sign      │  gateway signs  │              │
  └──────────────┘                 └──────┬───────┘
        │                                  │ you submit
        │ sign error                       │ claimBatch()
        ▼                                  ▼
  ┌──────────────┐                  ┌──────────────┐
  │   failed     │                  │   claimed    │
  │  _retryable  │ ◀── claim error  │ (paid)       │
  └──────┬───────┘                  └──────────────┘
         │ second failure
         ▼
  ┌──────────────┐
  │   failed     │
  │  _terminal   │
  └──────────────┘
```

Three things you settle on chain:

1. The Provider app calls the on-chain `claimBatch()` function with your signed receipts.
2. The contract verifies each receipt against the network's signed approval and your wallet registration.
3. The SPACE for the entire batch is transferred to your **collection wallet** in a single transaction.

### Before your first claim

{% hint style="warning" %}
**Fund your Identity wallet with CTC**

Claims are broadcast from your **Identity** wallet (not your staking wallet). The Identity wallet pays the gas. Send **\~1 CTC** to it before clicking *Claim All Outstanding*. The Earnings screen shows the address with a copy button. Without CTC there, the claim transaction fails with `insufficient funds for gas`.
{% endhint %}

How much CTC is "enough"? Each claim transaction costs roughly 0.001–0.005 CTC depending on batch size. **1 CTC** is usually enough for hundreds of claim batches.

### Manual claim

#### From the GUI

1. Open **Earnings** from the status screen.
2. Confirm the Claim wallet card shows enough CTC.
3. Click **Claim All Outstanding**.
4. Wait — the button shows a progress indicator. The on-chain transaction usually confirms within \~15 seconds.
5. The claimed receipts move from **Claimable** to **History**. SPACE arrives in your collection wallet.

#### From the CLI

```bash
./space-router-node-linux-x64 --claim
./space-router-node-linux-x64 --claim --include-retryable      # also retry failed-retryable rows
./space-router-node-linux-x64 --claim --uuid abc-123…          # claim a specific receipt
```

The CLI prints a JSON summary:

```
{
  "submitted": 12,
  "claimed":   12,
  "skipped":   0,
  "tx_hash":   "0xabc…"
}
```

### Auto-claim

Auto-claim is an optional setting that submits a claim transaction automatically when your earnings cross a threshold. Enable it in **Settings**.

#### Thresholds (OR logic)

Auto-claim fires when **either**:

* Total claimable SPACE crosses your **amount threshold** (default **10 SPACE**), *or*
* Total claimable receipts crosses your **count threshold** (default **10 receipts**).

Lower the thresholds for more frequent (smaller) claims; raise them to amortize gas across larger batches.

{% hint style="info" %}
**Why opt in?**

Auto-claim is off by default because it spends CTC on its own schedule. Once you've fund your Identity wallet with enough CTC and seen claims succeed manually, turning on auto-claim is a "set and forget" option.
{% endhint %}

#### If auto-claim fails

The app sticks a banner on the status screen: *"Auto-claim failed: "* with three buttons:

* **Show log** — opens the relevant log file at the failing line.
* **Retry now** — re-attempts the claim.
* **Disable auto-claim** — turns off the feature so the banner stops returning.

The banner persists across restarts until you act on it.

### Receipt states & what to do

#### pending\_sign

The gateway hasn't returned a signature yet. Usually clears within a minute. No action.

#### claimable

Ready to settle. Click *Claim All Outstanding* or wait for auto-claim.

#### failed\_retryable

Sign or claim hit a transient error. The app will retry automatically; you can also click *Retry now*. Common causes:

| Error code                 | What it means                                                                               |
| -------------------------- | ------------------------------------------------------------------------------------------- |
| `SIGN_TIMEOUT`             | Gateway didn't respond in time. Retries don't count toward the cap.                         |
| `CLAIM_RPC_UNREACHABLE`    | Creditcoin RPC was down. Retries don't count toward the cap.                                |
| `CLAIM_TX_TIMEOUT`         | Submitted, but confirmation took too long. The reaper auto-checks if it actually succeeded. |
| `SIGN_REJECTED_CLOCK_SKEW` | Your machine's clock drifted. Enable NTP / time sync.                                       |

#### failed\_terminal

Failed twice and won't be retried. The receipt is permanently locked. Reasons:

| Error code                        | What it means                                                                      | Fix                                                          |
| --------------------------------- | ---------------------------------------------------------------------------------- | ------------------------------------------------------------ |
| `SIGN_REJECTED_UNREGISTERED_NODE` | Your wallet isn't registered in the escrow contract.                               | Wait for the next staking-approval cron, or contact support. |
| `SIGN_REJECTED_BYTE_MISMATCH`     | Gateway counted different bytes than your node reported.                           | Usually a one-off; if recurring, restart your node.          |
| `SIGN_REJECTED_PRICE_CAP`         | Receipt price exceeded the network cap.                                            | Should not happen in normal operation; report to support.    |
| `SIGN_REJECTED_BAD_SIGNATURE`     | Identity-key signature didn't verify.                                              | Check that `node-identity.key` hasn't been corrupted.        |
| `CLAIM_REVERTED`                  | On-chain claim reverted. Often "nonce already used" — receipt was already claimed. | Check Blockscout — usually no action needed.                 |
| `CLAIM_NONCE_ALREADY_USED`        | Receipt was settled in a prior batch.                                              | None — earnings already received.                            |

### The reaper

A background process called the reaper periodically reconciles stuck rows. If a claim transaction got submitted but the result is unclear (timeout, RPC blip), the reaper checks the on-chain state and marks the receipt as **claimed** if the contract recorded it. You can run a reaper tick on demand:

```bash
./space-router-node-linux-x64 --receipts --reap
```

### Tax & reporting

The Earnings screen's **History** section is your audit trail. Every claimed receipt has a Blockscout link with timestamp, batch size, and total SPACE transferred. Export the on-chain transactions of your collection wallet for accounting.


# CLI Reference

Every flag the Provider binary accepts.

### Synopsis

```
space-router-node [GLOBAL OPTIONS]
space-router-node --receipts [RECEIPT OPTIONS]
space-router-node --claim [CLAIM OPTIONS]
```

### Global options

<table><thead><tr><th width="249">Flag</th><th>Default</th><th>Purpose</th></tr></thead><tbody><tr><td><code>--version</code>, <code>-V</code></td><td>—</td><td>Print the version and exit.</td></tr><tr><td><code>--reset</code></td><td>—</td><td>Wipe config + identity key, then re-run setup.</td></tr><tr><td><code>--setup</code></td><td>—</td><td>Re-run setup interactively without wiping the identity key.</td></tr><tr><td><code>--port PORT</code></td><td>9090</td><td>Port the node listens on.</td></tr><tr><td><code>--public-url HOST</code></td><td>auto</td><td>Public hostname or IP advertised to the gateway (tunnel/manual mode).</td></tr><tr><td><code>--public-port PORT</code></td><td>auto</td><td>Public port advertised (tunnel/manual mode).</td></tr><tr><td><code>--no-upnp</code></td><td>false</td><td>Disable UPnP. You must set <code>--public-url</code> / <code>--public-port</code>.</td></tr><tr><td><code>--staking-address ADDR</code></td><td>identity</td><td>EVM address of your staking wallet.</td></tr><tr><td><code>--collection-address ADDR</code></td><td>staking</td><td>EVM address that receives claimed SPACE.</td></tr><tr><td><code>--password-file PATH</code></td><td>—</td><td>Read identity-key passphrase from this file (headless installs).</td></tr><tr><td><code>--log-level LEVEL</code></td><td>INFO</td><td>One of <code>DEBUG</code>, <code>INFO</code>, <code>WARNING</code>, <code>ERROR</code>.</td></tr><tr><td><code>--label NAME</code></td><td>—</td><td>Human-readable label shown in logs and dashboards.</td></tr></tbody></table>

### Receipt options

Use `--receipts` to inspect the local receipt store. The daemon does not need to be running.

| Flag         | Purpose                                                                                               |
| ------------ | ----------------------------------------------------------------------------------------------------- |
| `--receipts` | List outstanding receipts as a table.                                                                 |
| `--failed`   | Show only `failed_retryable` and `failed_terminal` rows.                                              |
| `--json`     | Emit a stable JSON payload instead of a table (suitable for scripts).                                 |
| `--reap`     | Run one reaper tick before listing — reconciles stuck `CLAIM_TX_TIMEOUT` rows against on-chain state. |

Example:

```
space-router-node --receipts
space-router-node --receipts --failed --json
space-router-node --receipts --reap
```

### Claim options

Use `--claim` to submit a claim transaction. The daemon does not need to be running, but you must have set the identity passphrase if your key is encrypted.

| Flag                  | Purpose                                                                      |
| --------------------- | ---------------------------------------------------------------------------- |
| `--claim`             | Submit all `claimable` receipts in one batch.                                |
| `--include-retryable` | Also retry `failed_retryable` receipts (respects attempt cap).               |
| `--uuid UUID`         | Claim only the receipt with this request UUID. Refuses on `failed_terminal`. |

Example:

```
space-router-node --claim
space-router-node --claim --include-retryable
space-router-node --claim --uuid 9f3c4d…
```

### Environment variables

| Variable                             | Purpose                                                                   |
| ------------------------------------ | ------------------------------------------------------------------------- |
| `SR_IDENTITY_PASSPHRASE`             | Decrypt the identity key without prompting.                               |
| `SR_RECEIPT_MAX_SIGN_ATTEMPTS`       | Cap on signing retries (default 2). Don't change unless instructed.       |
| `SR_RECEIPT_MAX_CLAIM_ATTEMPTS`      | Cap on claim retries (default 2).                                         |
| `SR_RECEIPT_REAPER_INTERVAL_SECONDS` | Reaper tick interval (default 300).                                       |
| `SR_RECEIPT_REAPER_GRACE_SECONDS`    | How long before a stuck row is eligible for reconciliation (default 300). |

### systemd unit (Linux .deb / .rpm)

The package installs the binary at /opt/spacerouter/space-router-node and a systemd unit named space-router-node.service. The service runs as the unprivileged spacerouter user, whose home is /var/lib/spacerouter:

```
# Status & control
sudo systemctl status space-router-node
sudo systemctl restart space-router-node
sudo systemctl stop space-router-node

# Logs
sudo journalctl -u space-router-node -f
```

Edit settings.json directly under /var/lib/spacerouter/.spacerouter/, then sudo systemctl restart space-router-node. Pass extra flags via the EnvironmentFile at /etc/spacerouter/spacerouter.env.


# Troubleshooting

If your status looks wrong or a claim fails, start here.

### My status is stuck on "qualifying"

Brand-new nodes typically clear qualifying in 1–2 review periods (10–20 minutes). If you're stuck longer:

1. Confirm the gateway can reach you. Open a terminal and check the log for `health probe ok` lines. If you only see `health probe failed`, the gateway can't connect.
2. Test your network mode: UPnP can silently fail on some routers. Try **Manual** with explicit port forwarding, or **Tunnel** via bore/ngrok.
3. Confirm your stake landed on chain. Open the staking dApp and check that your staked balance is at or above the minimum.

### My status flips between "qualifying" and "inactive"

You have intermittent connectivity. Common causes:

* UPnP lease expired and didn't renew (some consumer routers).
* ISP routes you through CGNAT — UPnP can't help. Switch to a tunnel.
* Your machine sleeps overnight. Disable sleep on the host.

### My status says "unstaked" but I staked

Check that the staking address shown in the app matches the wallet that holds the stake. The two must be the same. If they don't match, click **Reset Node** (back up your identity key first) and re-run setup with the right address.

### The status badge says "inactive" right after I clicked Start

Look at the log:

```
tail -f ~/.spacerouter/logs/spacerouter-node.log
```

Common log lines:

| Log line                       | Meaning                             | Fix                                                                               |
| ------------------------------ | ----------------------------------- | --------------------------------------------------------------------------------- |
| `port 9090 in use`             | Another process is already on 9090. | Pass `--port 9091` or stop the other process.                                     |
| `upnp failed`                  | Router doesn't support UPnP.        | Switch to Manual or Tunnel mode.                                                  |
| `identity-key decrypt failed`  | Wrong passphrase.                   | Re-enter, or set `SR_IDENTITY_PASSPHRASE`.                                        |
| `coordination api unreachable` | Outbound HTTPS blocked.             | Check firewall — the node makes outbound HTTPS to `coordination.spacerouter.org`. |

### Claim failed with "insufficient funds"

Your **Identity** wallet — not your staking wallet — pays gas for claims, and it's out of CTC. Find the address on the Earnings screen and send **\~1 CTC** to it. Detailed explanation: Before your first claim.

### Claim failed with "CLAIM\_REVERTED"

A revert almost always means the receipt was already settled in a previous batch (the contract refuses to double-claim). Check Blockscout — if the SPACE arrived in your collection wallet, no action is needed. The Earnings screen will show the receipt as **claimed** after the next reaper tick.

### "failed\_terminal" receipts I can't recover

Once a receipt is locked, the SPACE on it is unrecoverable from your side. The good news: each terminal failure shows you the reason, so you can prevent the next one:

* `SIGN_REJECTED_CLOCK_SKEW` → Enable NTP / time sync on the host.
* `SIGN_REJECTED_BAD_SIGNATURE` → Identity key file may be corrupt; restore from backup.
* `SIGN_REJECTED_UNREGISTERED_NODE` →Your wallet wasn't yet registered with the network when this receipt was created. Registration runs on the staking-approval review cycle (every 4 hours); future receipts will succeed once you're approved.

### I'm behind CGNAT — how do I tunnel?

Two common options:

#### bore (free, requires no signup)

```
# Install bore (Rust)
cargo install bore-cli

# Run it pointing to your local node port
bore local 9090 --to bore.pub

# bore prints:
# listening at bore.pub:46213
# Use that hostname/port in SpaceRouter Tunnel mode.
```

#### ngrok (paid for stable hostnames)

```
ngrok tcp 9090
# Forwarding tcp://0.tcp.ngrok.io:12345 -> localhost:9090
# Use the printed host:port in SpaceRouter Tunnel mode.
```

Either way, set Network mode to **Tunnel** and paste the hostname + port from the tunnel.

### The app crashes or won't open

1. Quit any running instance.
2. Move the data directory out of the way (don't delete): `mv ~/.spacerouter ~/.spacerouter.bak`.
3. Re-launch — you'll get a fresh setup screen.
4. If the app now starts, the issue is config-related. Restore the identity key from the backup: `cp ~/.spacerouter.bak/certs/node-identity.key ~/.spacerouter/certs/`.
5. If it still crashes, file a bug at [github.com/space-labs/space-router-node/issues](https://github.com/space-labs/space-router-node/issues) with the last 100 log lines.

### My identity key was lost / machine died

If you don't have a backup, you can't restore the same node identity. You'll need to:

1. Install fresh on the new machine.
2. Generate a new identity (or import any backup you might have).
3. Use the same staking address you were using before — your stake stays where it is.
4. Your status will start at **qualifying** again until the next review period approves the new identity.

Any unclaimed earnings tied to the old identity are unrecoverable. Going forward, back up `node-identity.key` the moment you set it up.

### Still stuck?

Email <router.support@spacenetwork.com>. Include:

* Your node identity address (in the Wallet panel).
* Your status state and how long you've been there.
* The last 100 log lines, with private keys redacted.
* Your OS and SpaceRouter version (`--version`).


# FAQ

### Running a Provider

#### Does running a Provider violate my ISP's terms of service?

The Provider sends and receives the same kind of TLS traffic any web app produces — it doesn't run a public-facing service that resells your connection. That said, ISP terms vary by region and plan. If your ISP explicitly forbids server-style traffic on residential plans, check before opting in. SpaceRouter is not liable for ISP disputes.

#### Do I need a static IP?

No. UPnP and tunnel mode both work with dynamic IPs. The Coordination API tracks your address and updates whenever it changes.

#### How much bandwidth will it use?

Variable. Reward and traffic depend on demand for your region and IP type. There's no hard floor or ceiling — your node serves what the gateway routes to it.

#### Can I run multiple Providers on one machine?

Not recommended. Each Provider needs its own port and identity key. The network treats them as separate nodes; running them on one IP doesn't give you any advantage and complicates support.

#### Can I run a Provider on a server / VPS?

Technically yes, but the Provider's value comes from **residential** IP addresses. A datacenter IP from a VPS will be classified as `hosting` and earn far less, since most consumer demand is for residential and mobile IPs.

### Wallets & tokens

#### Why does my Identity wallet need CTC if my earnings are in SPACE?

SPACE is your reward token; CTC is the gas token of Creditcoin (the chain that hosts the SPACE token contract). Every on-chain transaction — including the claim that pays you — burns a tiny amount of CTC. So the Identity wallet, which broadcasts your claims, needs CTC for gas. Think of it as postage on the envelope that carries your check.

#### Can I use the same wallet for staking, identity, and collection?

The Identity wallet is always auto-generated by the app on first launch — you don't pick it. The Staking and Collection addresses are the ones you can configure: leave both blank and they default to the Identity address; set only the Staking address and Collection defaults to it. Most providers stake from a single external wallet and let Collection default to the same address, while the Identity wallet stays separate (since it lives on the node and just signs claims). Use a fully separate Collection only if you have a specific custody reason.

#### Can I change my collection address later?

Yes — open Settings, change the Collection address, and save. Future claims will route to the new address. Already-claimed earnings stay where they were sent.

#### What happens if I unstake?

You enter a 14-day unbonding period (defined by the staking contract). During unbonding, your status is **inactive** and you stop earning. After unbonding, your stake returns to your wallet.

### Earnings & claims

#### How often should I claim?

There's no required cadence. Each claim costs gas, so:

* If you have only a few small receipts, wait until they accumulate — gas would dwarf the payout.
* If you have many receipts or large totals, claim more often so SPACE moves into a wallet you control.

Many providers turn on auto-claim with a threshold (e.g., 10 SPACE) and let it run.

#### What if a claim transaction is dropped or stuck?

The reaper checks on-chain state and reconciles automatically. If you're impatient, run `--receipts --reap` from the CLI.

#### Are claims taxable events?

This is jurisdiction-dependent. Most tax frameworks treat claimed proxy rewards similarly to mining or staking rewards (income at receipt, capital gains at sale). Talk to a tax professional. The Earnings History tab is your audit trail.

### Privacy & security

#### Can a Consumer see my IP?

Yes — the consumer's request exits to the internet from your IP. That's the whole point of a residential proxy. Your IP is not exposed to the consumer in any other way (no headers, no leak channels). The consumer pays for the right to use your egress.

#### Can I see what websites a Consumer is visiting?

The Provider relays traffic but doesn't decrypt it (HTTPS goes through end-to-end). You'll see only what hostnames are connected to (via the SNI header on TLS), and you can refuse to relay traffic by simply not running the Provider.

#### Is my identity key encrypted at rest?

Only if you set a passphrase during setup. Without one, the key is stored as plain JSON. If you're on a shared machine, set a passphrase or run the Provider on a dedicated user account.

### Updates & releases

#### Will the app update itself?

Not currently. We publish releases on GitHub; you upgrade by downloading the new build. The data directory at `~/.spacerouter/` is preserved.

#### Where do I see what changed in a release?

Each GitHub release page has a changelog. Subscribe to GitHub release notifications on [space-labs/space-router-node](https://github.com/space-labs/space-router-node) to be notified.


# Quickstart

This guide walks through installing the SpaceRouter Onion App, running the setup wizard, installing the browser extension, and verifying that traffic routes through the SpaceRouter Onion network. The entire process takes a few minutes.

***

### How it works

```
                          control (HTTP API)
  ┌────────────┐        ┌─────────────────────┐        ┌─────────────────────┐
  │  Browser   │ SOCKS5 │  SpaceRouter Onion  │ circuit│  SpaceRouter Onion  │
  │            ├───────►│   Client (local)    ├───────►│       Network       │
  │ + Extension│ :1080  │                     │        │ guard → mid → exit  ├──► Internet
  └────────────┘        └─────────────────────┘        └─────────────────────┘
        ▲                          ▲
        │                          │
   Browser extension        Desktop app
   starts/stops proxy       installs and manages
   from the toolbar         the proxy service
```

***

### Step 1: install the SpaceRouter Onion App

Download the installer

Available platforms:

| Platform | Architecture                                                                                     |
| -------- | ------------------------------------------------------------------------------------------------ |
| macOS    | [arm64](https://asset-api.spacerouter.org/api/assets/app/download/darwin-arm64?env=staging)      |
| macOS    | [x64](https://asset-api.spacerouter.org/api/assets/app/download/darwin-x64?env=staging)          |
| Windows  | [x64](https://asset-api.spacerouter.org/api/assets/app/download/windows-x64?env=staging)         |
| Linux    | [x64 (deb)](https://asset-api.spacerouter.org/api/assets/app/download/linux-x64-deb?env=staging) |
| Linux    | [x64 (rpm)](https://asset-api.spacerouter.org/api/assets/app/download/linux-x64-rpm?env=staging) |

Open the downloaded installer and follow the standard OS prompts to complete installation.

***

### Step 2: run the setup wizard

The first time the app launches, a setup wizard walks through initial configuration.

1. **Welcome.** Click "Get Started".
2. **Choose your client.** Select Go or Rust. Both connect to the same SpaceRouter Onion network.
3. **Download the binary.** The app downloads the selected proxy binary automatically. Wait for the progress bar to finish, then click "Next".
4. **Install service.** Click "Install Service". The OS prompts for a password on macOS, a UAC dialog on Windows, or installs without elevation on Linux (systemd user service). The proxy installs as a background service so it can run without a terminal window open.
5. **Select network.** Pick the network this proxy will join from the dropdown, then click "Save & Continue". If the list is empty, wait a few seconds for the proxy to populate it.
6. **Done.** The proxy service is now installed and running. Click "Open SpaceRouter Onion" to open the main app window.

***

### Step 3: install the SpaceRouter Onion extension

1. Open the [SpaceRouter Onion Proxy page on the Chrome Web Store](https://chromewebstore.google.com/detail/spacerouter-onion-extensi/dmofgbiaagkmblmpmjponfkinnnajfng).
2. Click "Add to Chrome".
3. The SpaceRouter Onion extension icon appears in the browser toolbar.

The extension also works in Chromium-based browsers (Edge, Brave, Arc).

***

### Step 4: start the proxy

1. Click the SpaceRouter Onion extension icon in the browser toolbar.
2. Click the Start button.
3. The extension builds a 3-hop circuit through the SpaceRouter Onion network and begins routing browser traffic through it.
4. The popup displays the active circuit: guard, middle, and exit nodes with their geographic locations.

***

### Step 5: verify

Open a new tab and visit a site that shows the public IP address, such as `https://httpbin.org/ip`. The IP displayed should differ from the normal public IP, confirming traffic is routed through the SpaceRouter Onion exit node.

Alternatively, test from the command line using the SOCKS5 proxy on the default port (1080):

```bash
curl -x socks5h://127.0.0.1:1080 https://httpbin.org/ip
```

The response contains the exit node's IP, not the local machine's IP.

***

### Next steps

* For desktop app features (circuit visualization, node browser, settings): [SpaceRouter Onion App](/spacerouter-onion/app)
* For extension features (configuration, node browser, WebRTC protection): [SpaceRouter Onion extension](/spacerouter-onion/browser-extension)
* If something is not working: [Troubleshooting](/spacerouter-onion/troubleshooting)


# App

SpaceRouter Onion is a desktop application that routes your internet traffic through a decentralized mesh network. Once installed, it acts as a local SOCKS5 proxy, sending your traffic through a multi-hop circuit of network nodes so that no single point in the network can see both who you are and what you are doing.

The app downloads the `proxy` binary, registers it as a background service, and provides a graphical interface for the proxy: starting and stopping it, viewing the active circuit, and browsing nodes on the network.

This page walks through the one-time setup wizard, the main interface, and all available settings.

***

### Supported platforms

| Platform | Architecture                                                                                     | Service mechanism                    | Binary      |
| -------- | ------------------------------------------------------------------------------------------------ | ------------------------------------ | ----------- |
| macOS    | [arm64](https://asset-api.spacerouter.org/api/assets/app/download/darwin-arm64?env=staging)      | launchd (`com.spacerouter.proxy`)    | `proxy`     |
| macOS    | [x64](https://asset-api.spacerouter.org/api/assets/app/download/darwin-x64?env=staging)          | launchd (`com.spacerouter.proxy`)    | `proxy`     |
| Windows  | [x64](https://asset-api.spacerouter.org/api/assets/app/download/windows-x64?env=staging)         | Windows Service (`SpaceRouterProxy`) | `proxy.exe` |
| Linux    | x64 ([deb](https://asset-api.spacerouter.org/api/assets/app/download/linux-x64-deb?env=staging)) | systemd user unit (`proxy`)          | `proxy`     |
| Linux    | x64 ([rpm](https://asset-api.spacerouter.org/api/assets/app/download/linux-x64-rpm?env=staging)) | systemd user unit (`proxy`)          | `proxy`     |

The screenshots in this page are from macOS. The Windows and Linux experiences follow the same flow with native installer prompts and elevation dialogs in place of the macOS password prompts (Linux installs the systemd user unit without elevation).

***

### Installation

Download the installer for your platform from the [supported platforms](#supported-platforms). Run the installer and follow the standard OS prompts (drag to Applications on macOS, run the `.exe` installer on Windows, install the `.deb` or `.rpm` on Linux). On first launch, the app opens the setup wizard.

***

### Setup wizard

The first time you launch SpaceRouter Onion, a setup wizard guides you through the installation. You only need to complete this once. If a previous proxy installation is detected, the wizard handles the upgrade automatically.

#### Step 1: Welcome

<figure><img src="/files/HfrQCRbpOm1QNEmcDN9q" alt=""><figcaption></figcaption></figure>

The welcome screen introduces SpaceRouter Onion and explains what it does. If a previous proxy installation is detected, a notice appears (for example: *Existing proxy detected. It will be uninstalled before proceeding.*).

Click **Get Started** to begin.

#### Step 2: Choose your client

<figure><img src="/files/KIPt0SLkZqEgkd0B2yR0" alt=""><figcaption></figcaption></figure>

Select which proxy binary to install:

* **SpaceRouter Onion — Go**: the Go-based implementation
* **SpaceRouter Onion — Rust**: the Rust-based implementation

Both implementations connect to the same network and provide the same privacy guarantees. Click your preferred option; the card highlights to confirm selection and the wizard advances automatically.

#### Step 3: Download Binary

<figure><img src="/files/AjVDUbdSsJK912Jj267x" alt=""><figcaption></figcaption></figure>

The wizard shows the version that will be downloaded for your chosen implementation. Click **Download** to begin. A progress bar tracks the download. Once complete, the wizard advances to the next step automatically.

#### Step 4: Install Service

<figure><img src="/files/OIJWzA6RdXNyLWNrfy1N" alt=""><figcaption></figcaption></figure>

SpaceRouter Onion installs itself as a background system service so it starts automatically:

* **macOS:** installs a `launchd` user agent (`com.spacerouter.proxy`)
* **Windows:** installs a Windows service (`SpaceRouterProxy`, requires administrator privileges)
* **Linux:** installs a `systemd --user` unit (`proxy`, no elevation required)

Click **Install Service** to proceed.

You may be prompted to enter your macOS password (or accept a Windows UAC dialog) to authorize the installation. This is expected; installing a system service requires administrator privileges. Linux user units install without elevation.

#### Step 5: Select Network

<figure><img src="/files/Zx3CWGmpAs3DjLVVPwfP" alt=""><figcaption></figcaption></figure>

Choose which network this proxy will connect to. The dropdown is populated from the discovery backend.

1. Click the **Network** dropdown.
2. Select your network.
3. Click **Save & Continue**.

If no networks appear yet, the proxy may still be initializing. Wait a few seconds and the list will populate. You can also click **Skip** and configure the network later from Settings.

#### Step 6: Done

<figure><img src="/files/Pf0xrSsOBKIulvfiigZb" alt=""><figcaption></figcaption></figure>

Setup is complete. SpaceRouter Onion is installed and running. The summary confirms your configuration:

* **Implementation:** Go or Rust
* **Version:** the installed `proxy` version
* **Discovery:** the configured backend
* **Network:** the selected network ID

Click **Open SpaceRouter Onion** to launch the main interface.

***

### Proxy tab

The **Proxy** tab is the home screen of the app.

#### Proxy off

<figure><img src="/files/mAwthaogs673VJqMwVKW" alt=""><figcaption></figcaption></figure>

When the proxy is inactive, the status reads **"No active circuit"**. The **Chrome Extension Required** notice is shown; the SpaceRouter Onion Chrome Extension is required to configure your browser proxy and control the connection. See [SpaceRouter Onion extension](/spacerouter-onion/browser-extension).

To start the proxy, click the **Start** link in the status bar at the bottom of the window.

#### Proxy on

<figure><img src="/files/Va2bHBrhEU3IryoNI877" alt=""><figcaption></figcaption></figure>

When the proxy is running, the status reads **"Active Circuit"** in teal. Your traffic is now being routed through the mesh.

The active circuit is displayed:

* **Circuit · 3 hops.** Traffic passes through three nodes before reaching the internet.
* **Protocol:** the transport protocol in use (for example, `quic`).

Each hop shows its role, country flag, IP address, port, and a truncated public key fingerprint:

| Role      | Description                                                 |
| --------- | ----------------------------------------------------------- |
| **Guard** | First hop. Your traffic enters the network here.            |
| **Mid**   | Intermediate relay node.                                    |
| **Exit**  | Last hop. Traffic leaves the mesh and reaches the internet. |

The flow is: **Extension → Guard → Mid → Exit → Internet**

To stop the proxy, click the **Stop** link in the status bar.

#### Selection modes

Selection mode controls how circuit nodes are picked. Set it from the Proxy tab or from Settings.

| Mode             | Behavior                                                         |
| ---------------- | ---------------------------------------------------------------- |
| Random (default) | Selects nodes at random from the discovery list                  |
| Fast             | Prefers geographically nearby nodes as a proxy for lower latency |
| Maximize privacy | Maximizes geographic diversity across hops                       |

Changing the selection mode takes effect on the next circuit build.

***

### Nodes tab

<figure><img src="/files/enzqQJSrHmaCxrH4IzM4" alt=""><figcaption></figcaption></figure>

The **Nodes** tab lists all known nodes in the connected SpaceRouter Onion network. Use it to understand the network topology and verify which nodes are in your circuit.

| Column         | Description                                                          |
| -------------- | -------------------------------------------------------------------- |
| **Country**    | Geographic location (flag icon)                                      |
| **IP**         | Node IP address                                                      |
| **TCP**        | TCP port                                                             |
| **QUIC**       | QUIC port                                                            |
| **Exit**       | Marked if the node can serve as an exit                              |
| **Public key** | Truncated key fingerprint                                            |
| **In circuit** | Role in your active circuit (Guard, Mid, Exit). Blank if not in use. |

A toggle filter at the top of the table restricts the view to nodes participating in the current active circuit.

***

### Console tab

<figure><img src="/files/roBeHDT2ZLyMGcbh0pCj" alt=""><figcaption></figcaption></figure>

The **Console** tab streams output from the `proxy` process. Useful for troubleshooting.

| Control      | Function                                |
| ------------ | --------------------------------------- |
| Level filter | Show All, Info, Warn, or Error messages |
| Auto-scroll  | Pin the view to the latest log line     |
| Refresh      | Reload the log stream                   |
| Clear        | Empty the log buffer in the viewer      |

***

### Settings tab

The **Settings** tab is scrollable and divided into sections.

<figure><img src="/files/UrEH9Zo6UH2TTv1FeRZj" alt=""><figcaption></figcaption></figure>

#### Binary and service

This panel is read-only and reflects the current installation state.

| Field          | Description                                                                                         |
| -------------- | --------------------------------------------------------------------------------------------------- |
| Implementation | Go or Rust                                                                                          |
| Version        | Installed `proxy` version                                                                           |
| Install path   | Binary location on disk                                                                             |
| Service status | Running, Stopped, Not installed, or Unknown                                                         |
| Service name   | `com.spacerouter.proxy` (macOS), `SpaceRouterProxy` (Windows), or `proxy` (Linux systemd user unit) |

Click **Refresh** to re-check the service status.

#### Discovery and network

| Field      | Requires service restart | Description                                    |
| ---------- | ------------------------ | ---------------------------------------------- |
| Network ID | No (applied via API)     | Network to connect to                          |
| Hops       | No (applied via API)     | Number of hops per circuit (default 3)         |
| SOCKS port | No (applied via API)     | Local port the proxy listens on (default 1080) |

Discovery itself is configured during installation and only re-exposed in developer mode. Fields marked "via API" are applied through the proxy's HTTP control API without restarting the service.

#### Actions

| Action                | Description                                                                                                                      |
| --------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| Restart Service       | Stop and restart the background service                                                                                          |
| Reset to Setup Wizard | Re-run the wizard without removing the binary or service; the wizard detects the existing installation and skips completed steps |
| Uninstall Proxy       | Remove the binary and service registration, then return to the setup wizard                                                      |

***

### Status bar

A persistent bar at the bottom of every screen shows the state of both status layers at a glance.

* **Service indicator (left side):** the OS-level service process. Click **Stop** to stop it, or **Start** when it is stopped.
* **Proxy indicator (right side):** the SOCKS5 proxy itself, toggled through the HTTP API. Click **Stop** to disable, or **Start** to enable.

Both indicators must be green for traffic to route through SpaceRouter Onion. A running service with a stopped proxy (or vice versa) does not forward traffic.

| Indicator       | Meaning                                                                              |
| --------------- | ------------------------------------------------------------------------------------ |
| Service running | Background service is active. Click **Stop** to stop it.                             |
| Service stopped | Background service is not running. The proxy cannot function without it.             |
| Proxy on        | Traffic is actively routed through the mesh. Click **Stop** to disable.              |
| Proxy off       | Proxy is inactive. Traffic goes directly to the internet. Click **Start** to enable. |

The version line shows the installed binary version, the implementation (Go or Rust), and the discovery method.

The *service* and the *proxy* are two separate things. The service is the background process that keeps the proxy available. The proxy is the active routing circuit. Both must be running for **Privacy enabled** to appear.

***

### Chrome Extension

The **Chrome Extension Required** notice on the Proxy tab is expected. The SpaceRouter Onion Chrome Extension is needed to configure your browser to route traffic through the local SOCKS proxy and to control the proxy connection from your browser. Install it from the [Chrome Web Store](https://chromewebstore.google.com/detail/spacerouter-onion-extensi/dmofgbiaagkmblmpmjponfkinnnajfng) to activate the full privacy workflow. See SpaceRouter Onion extension for the full reference.

***

### Appendix A: Service management

The app manages the `proxy` binary as a background service so the proxy can run independently of the desktop window. The service starts on user login and survives app restarts.

#### macOS

The app writes a launchd property list to:

```
~/Library/LaunchAgents/com.spacerouter.proxy.plist
```

The service label is `com.spacerouter.proxy`. The app uses `launchctl` to load, start, stop, and unload the service. Service status is checked with `launchctl list`. Installing and uninstalling the service triggers a macOS password prompt because `launchctl bootstrap` and `launchctl bootout` require authorization.

#### Windows

The app registers a Windows Service named `SpaceRouterProxy` using `sc.exe`. Service status is checked with `sc query SpaceRouterProxy`. Installing and uninstalling the service triggers a UAC elevation prompt.

#### Linux

The app installs a `systemd --user` unit named `proxy`. Service status is checked with `systemctl --user status proxy`. Installing and uninstalling the unit do not require elevation because the unit is scoped to the current user.

All other operations (starting and stopping the proxy, changing preferences, downloading binaries, checking status) run without elevation on every platform.

***

### Appendix B: Binary install paths

| Platform | Install path                                          |
| -------- | ----------------------------------------------------- |
| macOS    | `~/Library/Application Support/SpaceRouter/bin/proxy` |
| Windows  | `%APPDATA%\SpaceRouter\bin\proxy.exe`                 |
| Linux    | `~/.local/share/SpaceRouter/bin/proxy`                |

The setup wizard downloads the binary to these paths. The service configuration references the binary at its install path. Moving or renaming the binary breaks the service; use **Uninstall Proxy** in settings and re-run the wizard instead.


# Release Notes

Latest updates, improvements, bug fixes, and new features for the SpaceRouter Onion app.

### 0.4.26

* Added support for custom network configuration in the setup wizard when running in Dev Mode.
* Updated and fixed application icons and images across the setup flow, taskbar, dock, system tray, and menu bar.
* Removed the window frame on Windows.
* Removed step numbers from setup wizard eyebrow labels.
* Added application version information to the status bar.

### 0.4.23

* Added the ability to select the log level directly within the setup wizard when running in Dev Mode.

### 0.4.21

* Initial release


# Browser Extension

The SpaceRouter Onion browser extension provides a one-click interface for controlling the SpaceRouter Onion SOCKS5 proxy. It connects to the proxy's HTTP API, starts and stops circuits, displays the active relay path with country flags and IP addresses, and manages preferences such as hop count and node selection mode. The proxy must be running and reachable before the extension can do anything; see Prerequisites.

***

### Installation

Install from the [SpaceRouter Onion Proxy page on the Chrome Web Store](https://chromewebstore.google.com/detail/spacerouter-onion-extensi/dmofgbiaagkmblmpmjponfkinnnajfng). Click "Add to Chrome". The extension works in Chrome, Edge, Brave, Arc, and other Chromium-based browsers.

***

### Prerequisites

The extension controls a running `proxy` instance. The proxy must be running and its HTTP API must be reachable (default: `http://127.0.0.1:2080`). Install the proxy through the [SpaceRouter Onion App](/spacerouter-onion/app).

***

### Main view

<figure><img src="/files/ylFLZy8pP2tDEFBJEBbL" alt="" width="299"><figcaption></figcaption></figure>

The main view is the first screen you see when you open the extension popup. It contains a start/stop button, a status indicator showing whether the proxy is connected, a circuit visualization displaying the guard, middle, and exit nodes (each with a country flag and IP address), and a selection mode dropdown.

When you click **Start**, the extension:

1. Sends `POST /api/start` to the proxy.
2. Sets the browser's proxy to SOCKS5 on `127.0.0.1:<port>` (default `1080`).
3. On Chrome, disables non-proxied UDP to prevent WebRTC leaks.
4. Fetches the active circuit from `GET /api/status` and displays it.

When you click **Stop**, the extension:

1. Sends `POST /api/stop` to the proxy.
2. Clears the browser's proxy settings.
3. Restores default WebRTC behavior (Chrome only).

#### Selection modes

| Mode             | Behavior                                                         |
| ---------------- | ---------------------------------------------------------------- |
| Random (default) | Nodes chosen at random from the network                          |
| Fast             | Prefers geographically nearby nodes as a proxy for lower latency |
| Privacy          | Maximises geographic diversity across hops                       |

You can change the selection mode from the dropdown on the main view or from the configuration view.

***

### Configuration view

<figure><img src="/files/U4LF6k83abw4xAEYEDTR" alt="" width="301"><figcaption></figcaption></figure>

Open the configuration view by clicking the gear icon. All settings are listed below.

| Setting        | Default                 | Description                                      |
| -------------- | ----------------------- | ------------------------------------------------ |
| Network        | (from discovery)        | Network to connect to                            |
| Proxy API URL  | `http://127.0.0.1:2080` | Address of the proxy's HTTP API                  |
| SOCKS5 port    | `1080`                  | Port the proxy listens on for SOCKS5 connections |
| Hops           | `3`                     | Number of relay hops per circuit (1 to 5)        |
| Selection mode | Random                  | How nodes are selected for circuits              |

Changes to network, hops, or selection mode require the proxy to be stopped first. The extension stops the proxy automatically, applies changes via `POST /api/preferences`, then restarts it.

***

### Nodes view

<figure><img src="/files/lhBcPgUMETHWOu9P2Sav" alt="" width="301"><figcaption></figcaption></figure>

The nodes view lists every node in the selected network. Open it from the navigation bar.

| Column     | Description                                |
| ---------- | ------------------------------------------ |
| Country    | Geographic location (flag icon)            |
| IP         | Node IP address                            |
| TCP        | TCP listen port                            |
| QUIC       | QUIC listen port                           |
| Exit       | Whether the node accepts exit traffic      |
| Public key | Truncated Ed25519 identity key fingerprint |

***

### Background behavior

The extension runs a background service worker that polls `GET /api/status` every 30 seconds. If the proxy stops unexpectedly while the browser's SOCKS5 proxy settings are still active, the service worker clears those settings and shows a notification badge on the extension icon. If the proxy is running, the service worker keeps the browser proxy settings pointed at the configured SOCKS5 port.

***

### API endpoints

The extension communicates with the `proxy` binary through these HTTP endpoints:

| Method | Endpoint           | Description                                |
| ------ | ------------------ | ------------------------------------------ |
| GET    | `/api/status`      | Proxy state and active circuit             |
| POST   | `/api/start`       | Build circuit and start SOCKS5             |
| POST   | `/api/stop`        | Tear down circuit and stop SOCKS5          |
| GET    | `/api/preferences` | Current preferences and available networks |
| POST   | `/api/preferences` | Update preferences (proxy must be stopped) |
| GET    | `/api/nodes`       | Node list for the selected network         |

The proxy exposes additional endpoints for advanced tooling (`POST /api/guard` to pin a specific guard node, `POST /api/guard/rotate` to re-select guard/middle/exit). The extension does not use these; node selection is driven entirely through the `selectionMode` preference.

***

### Appendix: browser compatibility

| Browser | SOCKS5 proxy             | WebRTC protection              | Notes          |
| ------- | ------------------------ | ------------------------------ | -------------- |
| Chrome  | Yes (`chrome.proxy` API) | Yes (disables non-proxied UDP) | Primary target |
| Edge    | Yes (`chrome.proxy` API) | Yes                            | Same as Chrome |


# Release Notes

Latest updates, improvements, bug fixes, and new features for the SpaceRouter Onion Extension.

### 0.4.13

* Updated the application description.
* Improved icons and images in extension pop-up windows and the browser toolbar.
* Added a flag to enable or disable the pulse animation on the extension icon while the proxy is running.
* Fixed the default extension icon displayed while the browser loads the extension.
* Fixed a bug that caused a proxy error when the extension cleared the selected network settings.
* Fixed the polling preferences mechanism to allow users to make changes in the Settings page without losing data every 5 seconds.

### 0.4.9

* Initial release


# Troubleshooting

A short guide to the most common issues when running the SpaceRouter Onion proxy from the command line. If you are using the SpaceRouter Onion App or the browser extension, most of these conditions surface as a red indicator or a notification; the same root causes apply.

***

### Proxy won't start

Symptoms: the process exits immediately, or hangs at startup, or prints an error about listeners.

#### Port is already in use

The SOCKS5 and HTTP API listeners default to `127.0.0.1:1080` and `127.0.0.1:2080`. If either port is already bound, the proxy fails with an "address already in use" error.

Check what is using the ports:

{% tabs %}
{% tab title="macOS / Linux" %}

```bash
lsof -iTCP:1080 -sTCP:LISTEN -n -P
lsof -iTCP:2080 -sTCP:LISTEN -n -P
```

{% endtab %}

{% tab title="Windows (Powershell)" %}

```ps
Get-NetTCPConnection -LocalPort 1080
Get-NetTCPConnection -LocalPort 2080
```

{% endtab %}
{% endtabs %}

If the output shows another process, either stop that process or move the SpaceRouter Onion proxy onto different ports with `--listen` and `--api-listen`.

#### Data directory is not writable

The proxy persists `proxy-prefs.json` and `.guardstate` inside `--data-dir`. If the directory does not exist or the user running the proxy cannot write to it, startup fails.

{% tabs %}
{% tab title="macOS" %}

```bash
# Make sure the directory exists and is owned by the proxy user
sudo mkdir -p ~/Library/Application Support/SpaceRouter Onion/
sudo chown spacerouter:spacerouter ~/Library/Application Support/SpaceRouter Onion/
```

{% endtab %}

{% tab title="Linux" %}

```shellscript
# Make sure the directory exists and is owned by the proxy user
sudo mkdir -p ~/.local/share/SpaceRouter Onion/
sudo chown spacerouter:spacerouter ~/.local/share/SpaceRouter Onion/
```

{% endtab %}

{% tab title="Windows (Powershell)" %}

```powershell
# Make sure the directory exists and is owned by the current user
$dir = "$env:%APPDATA%\SpaceRouter Onion\"
New-Item -ItemType Directory -Force -Path $dir

$acl = Get-Acl $dir
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule(
    "spacerouter",
    "FullControl",
    "ContainerInherit,ObjectInherit",
    "None",
    "Allow"
)
$acl.SetAccessRule($rule)
Set-Acl -Path $dir -AclObject $acl
```

{% endtab %}
{% endtabs %}

#### Discovery source is unreachable at startup

With `--auto-start <network-id>` the proxy resolves discovery before it will accept traffic. If the discovery URL or contract returns nothing, times out, or the file path does not exist, the proxy logs the error and never enters the "enabled" state. Drop `--auto-start` to let the proxy start its listeners even when discovery is offline, then fix discovery and trigger `POST /api/start`.

***

### Can't reach `/api/status`

Symptoms: the extension shows "proxy unreachable", `curl http://127.0.0.1:2080/api/status` times out or returns a connection-refused error.

#### The proxy process isn't running

First, confirm the process is alive:

{% tabs %}
{% tab title="macOS / Linux" %}

```shell
pgrep -af proxy
```

{% endtab %}

{% tab title="Windows (Powershell)" %}

```powershell
Get-Process proxy
```

{% endtab %}
{% endtabs %}

If nothing is running, start it directly in a terminal (not as a service) and watch the output. Startup errors almost always explain themselves in the first few log lines.

#### The API is bound to a different address

The extension and the desktop app assume `http://127.0.0.1:2080`. If you launched the proxy with a different `--api-listen`, the clients will not reach it. Either restart the proxy with the default address, or update the "Proxy API URL" field in the extension's configuration view / the desktop app's settings.

#### Firewall is blocking localhost (rare but real)

Corporate machines sometimes ship with firewall profiles that block loopback connections to non-standard ports. Temporarily permit `127.0.0.1:2080` in the firewall or relocate the proxy to a port your environment allows.

#### The listener is bound to a specific interface

A `--api-listen 192.168.1.10:2080` bind will not accept connections on `127.0.0.1`. Use `--api-listen 0.0.0.0:2080` if you intentionally want to reach the proxy from another host on the LAN; otherwise keep the default loopback bind.

***

### Circuit build fails

Symptoms: `POST /api/start` returns a 500, logs mention "failed to build circuit", the extension popup spins on "Starting…" and then reports an error.

#### Discovery returned zero nodes

A circuit needs at least `--hops` distinct nodes, with at least one of them flagged as an exit. If discovery returns fewer than that (or returns an empty list), every build attempt fails.

{% tabs %}
{% tab title="macOS / Linux" %}

```shell
curl -s http://127.0.0.1:2080/api/nodes | jq '.nodes | length'
```

{% endtab %}

{% tab title="Windows (Powershell)" %}

```powershell
(Invoke-RestMethod -Uri "http://127.0.0.1:2080/api/nodes").nodes.Count
```

{% endtab %}
{% endtabs %}

#### No exit-capable nodes in the set

An exit node is any node whose `flags` field has the exit bit set. If no node in the returned list is exit-capable, the proxy cannot complete the circuit. Confirm the network you selected (`--network-id`) actually contains exit nodes and that you are not restricting the pool to an unusable subset.

#### Handshake timeout against the guard

Log lines like `session handshake timed out after 15s` usually mean one of:

* The guard node is offline or has been taken out of rotation but is still in the cached node list. Wait for the next discovery refresh (three minutes) or force a new guard with `curl -X POST http://127.0.0.1:2080/api/guard/rotate` while the proxy is stopped.
* A firewall is dropping the QUIC UDP handshake on the path.&#x20;

***

### Collecting logs for a bug report

If you can't fix the issue yourself and want to open an issue on GitHub, the most useful attachments are the proxy's own logs captured at a higher verbosity.

#### What to include in the report

{% tabs %}
{% tab title="macOS / Linux" %}

1. The exact command (or service configuration) you started the proxy with, redacting any private discovery URLs.
2. The output of `curl -s http://127.0.0.1:2080/api/status | jq .` captured immediately before the failure.
3. The last 200 to 500 lines of the log file, from the first error back through the handshake or circuit-build attempt that failed.
4. The version of the binary: `proxy version`.
5. Your platform (`uname -a` on macOS/Linux, `winver` on Windows).
   {% endtab %}

{% tab title="Windows (Powershell)" %}

1. The exact command (or service configuration) you started the proxy with, redacting any private discovery URLs.
2. The output of `Invoke-RestMethod -Uri "http://127.0.0.1:2080/api/status"` captured immediately before the failure.
3. The last 200 to 500 lines of the log file, from the first error back through the handshake or circuit-build attempt that failed.
4. The version of the binary: `proxy version`.
5. Your platform ( `winver` ).
   {% endtab %}
   {% endtabs %}

#### What not to include

The default logs do not contain packet payload. Avoid using `--sensitive-log`; it was built for protocol debugging on a single private machine and records cleartext traffic. Never attach a sensitive-log file to a public issue tracker.


# old - Staking

Stake SPACE to qualify as a Provider and earn yield while running a node.

### Before you start

* You'll need at least **1 SPACE** to stake.
* SPACE lives natively on Creditcoin mainnet. If you bought it on Ethereum, you'll bridge it first.
* You'll also need a small amount of CTC for gas.

### Step 1 — Buy SPACE

SPACE is listed on multiple exchanges. The most common venues:

* Binance Alpha
* OKX
* Bitget
* KuCoin
* MEXC
* Kraken
* Coinone
* Gopax
* Aster DEX

### Step 2 — Bridge to Creditcoin

If you bought SPACE on an Ethereum-network exchange, you'll need to bridge it to Creditcoin where the staking contract lives.

Use the official Portal Bridge:

[portalbridge.com → SPACE Ethereum → Creditcoin](https://portalbridge.com/?toChain=CreditCoin\&toToken=SPACE\&fromChain=Ethereum\&fromToken=SPACE)

If you bought SPACE on an exchange that already supports Creditcoin withdrawals, withdraw directly to your Creditcoin-compatible wallet — no bridge needed.

### Step 3 — Stake

1. Open the staking dApp: [penguinbase.com/dapp/spacestaking](https://penguinbase.com/dapp/spacestaking).
2. Connect your wallet (MetaMask, WalletConnect, etc.).
3. Make sure your wallet is on Creditcoin mainnet (chain ID `102030`). Add the network if it isn't there yet — the dApp will prompt you.
4. Enter the amount to stake (≥ 1 SPACE) and click *Stake*.
5. Approve the SPACE token to the staking contract (one-time, separate transaction).
6. Confirm the stake transaction.

Once your stake is confirmed on chain, your wallet is registered as a potential Provider. You can run a node from any machine using this wallet as your **staking address**.

### Step 4 — Run a Provider

Staking alone doesn't earn — you also need to operate a Provider that serves traffic. Head to Provider Quick Start.

Once your node is online and approved, the dApp will show your status as **earning** and the rewards counter starts ticking.

### Claim Rewards

Two distinct kinds of rewards exist:

* **Bandwidth rewards** — SPACE earned for traffic served. Claimed inside the Provider app's Earnings screen. See the Claim guide.
* **Staking rewards** — yield on your stake itself. Claimed inside the staking dApp.

Both go to your collection wallet (or staking wallet, if you didn't set a separate collection).

### Unstake

To withdraw your stake:

1. Open the staking dApp.
2. Click *Unstake* and enter the amount.
3. Wait through the **14-day unbonding period**. During unbonding, your stake earns nothing and your Provider's status becomes **inactive**.
4. After 14 days, click *Withdraw*. Your SPACE returns to your wallet.

{% hint style="info" %}
**You can stay online while unbonding**

Your node can keep running during the unbonding period — but it earns nothing. Most providers stop the app and only restart after re-staking.
{% endhint %}

### FAQ

#### What chain is SPACE on?

The official SPACE token used for staking and rewards lives on Creditcoin mainnet. The version on Ethereum is a wrapped representation, so you'll want to bridge it over to Creditcoin mainnet before staking.

#### Can I stake without running a Provider?

You'll need to run a node to earn rewards. If you stake without operating a Provider, unfortunately you won't earn staking yield or bandwidth rewards, so please keep that in mind.

#### What's the minimum stake?

You can start staking with as little as 1 SPACE.

#### Are stake amounts visible on chain?

Yes, everything is publicly visible! The staking contract is open for anyone to read, and you can check the total staked SPACE, the list of stakers, and recent transactions directly on Blockscout.


# API-Key Authentication

Pay with a card, get an sr\_live\_… key, and authenticate every request through the proxy gateway.

### Step 1 — Get an API key

1. Visit the [billing portal](https://coordination.spacerouter.org/billing).
2. Sign in with your email and pick a plan.
3. Copy the `sr_live_…` key shown on screen. Treat it like a password.

Lost your key? You can rotate it at any time at [/billing/reissue](https://coordination.spacerouter.org/billing/reissue). Your existing key stops working as soon as you reissue.

### Step 2 — Send a request

#### HTTP proxy (port 8080)

```bash
curl -x "http://gateway.spacerouter.org:8080" \
     -U "sr_live_YOUR_API_KEY:" \
     https://httpbin.org/ip
```

#### SOCKS5 proxy (port 1080)

```bash
curl -x "socks5://sr_live_YOUR_API_KEY:@gateway.spacerouter.org:1080" \
     https://httpbin.org/ip
```

### Geo targeting

Append routing parameters to the username segment of the URL. Order doesn't matter; pairs are separated by hyphens.

```
socks5://sr_live_YOUR_API_KEY-country-KR-type-residential:@gateway.spacerouter.org:1080
```

| Parameter | Values                                         | Example                    |
| --------- | ---------------------------------------------- | -------------------------- |
| `country` | 2-letter ISO country code                      | `country-US`, `country-KR` |
| `type`    | `residential`, `mobile`, `business`, `hosting` | `type-residential`         |

### Endpoints

| Protocol | Host                      | Port   |
| -------- | ------------------------- | ------ |
| HTTP     | `gateway.spacerouter.org` | `8080` |
| SOCKS5   | `gateway.spacerouter.org` | `1080` |

### Common errors

| HTTP code | Meaning                                      | What to do                                                                           |
| --------- | -------------------------------------------- | ------------------------------------------------------------------------------------ |
| **407**   | Bad or missing API key.                      | Double-check the key, especially the trailing colon in `sr_live_KEY:` for `curl -U`. |
| **402**   | Monthly data quota exceeded.                 | Upgrade your plan in the billing portal.                                             |
| **429**   | Rate limited.                                | Slow down. The response includes a `Retry-After` header.                             |
| **503**   | No Provider matches your region/type filter. | Drop the filter or pick another region.                                              |

For the full error catalogue, see Errors & Troubleshooting.

### Use it in your code

Most users will use the SDK rather than raw `curl`:

**Python SDK** — `SpaceRouter("sr_live_…")` — full HTTP method coverage, retries, async client.

**JavaScript SDK** — `new SpaceRouter("sr_live_…")` — fetch-style API, TypeScript types.


