> For the complete documentation index, see [llms.txt](https://docs.nexus.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.nexus.xyz/api-reference/ko/guides/networks.md).

# 네트워크

모든 Nexus Exchange 인터페이스가 테스트넷, 메인넷, 로컬, 또는 직접 기술하는 사용자 지정 대상 중에서 네트워크를 선택하는 방식을 설명합니다.

모든 Nexus Exchange 인터페이스는 클라이언트를 생성할 때 선택한 정확히 하나의 **네트워크**와 통신합니다. 네트워크는 릴리스 채널이 아닙니다. 네트워크는 누구의 돈이 걸려 있는지를 결정합니다. **테스트넷**은 합성 플레이 자금을, **메인넷**은 실제 자금을 다루게 되며, **로컬**은 개발용입니다. 네트워크를 하나 선택하면 네트워크마다 다른 모든 것이 한꺼번에 정해집니다. REST 및 WebSocket 대상, 포셋 존재 여부, 요청이 속하는 서명 도메인이 그것입니다. URL을 조합하는 것이 아니라 네트워크를 선택하는 방식입니다. 현재 기본 URL은 [API 및 요청 한도](https://docs.nexus.xyz/exchange/apis-and-rates)를 참조하십시오.

이 세 가지가 공개된 네트워크입니다. 직접 운영하는 배포는 [`Custom` 네트워크](#the-custom-network)입니다. 같은 구성 묶음을 가지지만, 클라이언트가 이를 해석하는 대신 사용자가 직접 기술합니다.

### 공개된 세 가지 네트워크

| 네트워크      | 자금                                     | 포셋 | 이용 가능 여부                                 |
| --------- | -------------------------------------- | -- | ---------------------------------------- |
| `testnet` | 실제 가치가 없는 합성 USDX                      | 있음 | 현재 운영 중. 모든 인터페이스의 기본값.                  |
| `mainnet` | Ethereum Mainnet에서 브리징한 USDX 형태의 실제 자금 | 없음 | 실제 자금 거래소와 함께 출시 예정. 아직 연결할 수 없음. 아래 참조. |
| `local`   | 합성 자금, 직접 운영하는 인덱서 대상                  | 있음 | 로컬 개발용. 공개 네트워크가 아님.                     |

실제 자금을 기본값으로 삼는 것은 안전하지 않으므로, 테스트넷이 의도적으로 모든 곳의 기본값입니다.

**메인넷은 아직 연결할 수 없습니다.** 공개 호스트가 아직 운영되지 않으므로, 어떤 인터페이스도 사용자를 대신해 메인넷 대상을 해석하지 않습니다. 요청을 그럴듯하지만 잘못된 곳으로 보내는 대신, 각 인터페이스는 실패 시 차단(fail closed) 방식으로 동작합니다. Python 및 TypeScript 클라이언트는 생성 시점에 예외를 발생시키고, MCP 서버는 시작을 거부합니다. Rust 클라이언트(따라서 CLI도)는 정상적으로 빌드되지만, 어떤 바이트도 프로세스를 벗어나기 전에 모든 요청을 로컬에서 거부합니다. 통과하는 유일한 방법은 대상을 직접 지정하는 것입니다. Python, TypeScript, MCP 서버는 명시적인 기본 URL과 함께 주어지면 `mainnet`을 받아들이며([기술하지 않고 호스트 지정하기](#pointing-at-a-host-without-describing-it) 참조), 이것이 영구 호스트가 운영되기 전에 실제 자금 배포에 연결하는 방법입니다. Rust에서는 이 재정의가 네트워크를 전혀 담지 않는 별도의 생성자이므로, 메인넷이 아니라 URL을 대상으로 합니다. 그 실패는 미리 연습해 볼 수 없으므로, 어떤 인터페이스도 실제 자금 대상을 대신 추측하지 않습니다. 메인넷이 출시되면 이 페이지와 각 인터페이스의 릴리스 노트에서 알려 드립니다.

### 네트워크 선택

| 인터페이스      | 네트워크 선택                                                         | 기본값       |
| ---------- | --------------------------------------------------------------- | --------- |
| Python     | `Client(network=Network.TESTNET)`                               | `testnet` |
| TypeScript | `new Client({ network: Network.Testnet })`                      | `testnet` |
| Rust       | `Config::new(Network::Testnet)`                                 | `testnet` |
| CLI        | `--network <mainnet\|testnet\|local\|LABEL>` 또는 `NEXUS_NETWORK` | `testnet` |
| MCP 서버     | `NEXUS_EXCHANGE_NETWORK`                                        | `testnet` |

CLI의 `--network`는 설정 파일에 선언한 사용자 지정 대상의 레이블도 받으며, MCP 서버는 기술된 구성 묶음과 함께 `NEXUS_EXCHANGE_NETWORK=custom`을 받습니다. [사용자 지정 대상 기술하기](#describing-a-custom-target)를 참조하십시오.

인식되지 않는 네트워크 이름은 항상 오류입니다. 어떤 인터페이스도 기본값으로 대체하지 않으며, `local`로 대체하지도 않습니다. 인터페이스는 알 수 없는 식별자를 그렇지 않다고 입증될 때까지 실제 자금으로 취급하므로, 사용자가 직접 바로잡아야 합니다. 폐기된 릴리스 채널 이름은 대체 이름을 안내하며 거부됩니다. `stable`은 테스트넷을 제공하는 호스트를 가리켰으므로, `testnet`이 직접적인 대응 값입니다.

### 예시

```python
from nexus_exchange import Client, Network

client = Client(network=Network.TESTNET, api_key=..., api_secret=...)
```

```typescript
import { Client, Network } from "@nexus-xyz/exchange-ts";

const client = new Client({ network: Network.Testnet, apiKey: "…", apiSecret: "…" });
```

```rust
use nexus_exchange::{Config, Network};

let config = Config::new(Network::Testnet);
```

```bash
nexus --network local markets
```

### `Custom` 네트워크

위의 세 네트워크는 공개된 네트워크입니다. 비공개 스테이지, 프리뷰 환경, 자체 인프라의 인덱서처럼 직접 운영하는 배포는 **`Custom` 네트워크**입니다. 이는 세 네트워크 중 하나에 URL을 붙인 것이 아니라, 사용자가 직접 기술하는 네 번째 종류의 대상입니다.

주소가 아니라 네트워크인 이유는 비공개 배포에도 이름 있는 네트워크가 묶어 두는 모든 것이 여전히 필요하고, URL은 그중 어느 것도 제공하지 않기 때문입니다. `Custom`은 같은 구성 묶음을 사용자가 제공하는 형태로 가집니다.

| 구성 요소                   | 제공 주체                                                                                                                                                                           |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **REST 기본 URL**         | 사용자. 필수.                                                                                                                                                                        |
| **직접 `/api/v1` 기본 URL** | 배포가 REST 기본 URL과 분리해 둔 경우 사용자. 기본값은 REST 기본 URL이며, 단일 호스트 배포는 그곳에서 제공합니다.                                                                                                       |
| **WebSocket 오리진**       | 배포가 이를 분리할 수 있게 하는 인터페이스에서는 사용자. Rust SDK와 CLI는 이를 절대 유도하지 않습니다. 유도하면 스트림 토큰을 그 토큰을 발급하지 않은 오리진과 짝짓게 되기 때문입니다. [필드 집합에 관한 참고](#the-two-field-sets-differ-deliberately)를 참조하십시오. |
| **자금(Funds)**           | 사용자. 필수, 기본값 없음. 아래 참조.                                                                                                                                                         |
| **포셋**                  | 사용자. 선언하기 전까지는 **없는** 것으로 간주되므로, 자금 충전 호출이 존재하지 않는 포셋으로 라우팅될 수 없습니다.                                                                                                            |
| **서명 도메인**              | 해당 배포의 `GET /metadata`에서 읽거나 사용자가 제공. 절대 추측하지 않음.                                                                                                                               |
| **레이블**                 | 사용자. 자격 증명 네임스페이스이므로 필수.                                                                                                                                                        |

#### 자금은 필수인 3값 상태입니다

`funds`는 `real`, `play`, `unknown` 중 하나이며, **기본값이 없습니다**. 두 불리언 답 중 어느 것도 가정하기에 안전하지 않습니다. 실제 자금 거래소의 스테이징 배포는 실제 자금처럼 동작하며, 뒤에 프로덕션 데이터가 있는 프리뷰 환경은 공개 호스트가 아니라는 이유만으로 플레이 머니가 되지 않습니다. 오직 운영자만이 알 수 있습니다.

`unknown`은 **실패 시 차단으로 처리됩니다**. 모를 수도 있으므로 이는 정당한 답이며, 추측하기보다 모른다고 말하는 편이 낫습니다. 그러면 인터페이스는 실제 자금으로 보호되는 작업을 통과시키지 않고 거부합니다. 가치를 이동하는 명령이나 도구가 사용자 지정 대상에서 거부된다면, 선언되지 않은 `funds`를 가장 먼저 확인하십시오.

#### 레이블은 필수이며 자격 증명 네임스페이스입니다

모든 `Custom` 대상에는 호출자가 정한 레이블이 있으며, `[A-Za-z0-9._-]` 문자로 최대 64자까지 허용됩니다. `.`와 `..`는 무조건 거부됩니다. 내장 네트워크가 이미 사용하는 이름(`mainnet`, `testnet`, `local`, 그리고 `custom` 자체)도 거부됩니다. 이 이름들은 해당 문자 집합에서는 유효하지만, 그 이름을 쓰면 다른 대상의 자격 증명을 가리키게 됩니다.

레이블은 저장된 자격 증명의 네임스페이스 키이므로, 설정을 저장하는 클라이언트에서는 파일 시스템까지 전달됩니다. `/`나 `..`를 포함한 검증되지 않은 레이블은 경로 탐색(path traversal)이며, 그 레이블이 가리키는 자격 증명은 다른 대상의 것입니다. 문자 집합과 길이 상한은 모든 인터페이스에 적용되며, 각 인터페이스는 이를 물려받지 않고 스스로 강제합니다. MCP 서버는 Rust SDK 기반이 아니며 이 규칙의 자체 사본을 가지고 있습니다. 예약된 이름은 아직 통일되지 않은 유일한 부분입니다. Rust SDK와 CLI는 내장 네트워크의 이름을 거부하지만, MCP 서버는 거부하지 않습니다. 거부에 의존해 충돌을 잡으려 하지 말고, 어느 이름과도 겹치지 않는 레이블을 고르십시오.

레이블은 자신의 설정에서 직접 정합니다. `dev`, `preview`, `example` 모두 괜찮습니다.

#### 서명 도메인은 절대 추측하지 않습니다

`Custom` 대상은 어디에서도 서명 도메인을 물려받지 않습니다. 클라이언트는 배포 자체의 `GET /metadata`에서 EIP-712 체인 ID를 읽거나, 사용자가 제공한 값을 사용합니다. 둘 다 없으면 다른 네트워크의 값을 재사용하는 대신 **서명을 거부합니다**.

반대 방향의 실패는 조용히 일어나므로, 이 규칙에 부딪히기 전에 이해해 두십시오. 잘못된 도메인으로 만든 서명은 *다른 네트워크에서 유효할* 수 있습니다. 거부만이 유일하게 안전한 답입니다.

### 기술하지 않고 호스트 지정하기

모든 인터페이스는 여전히 기본 URL만 단독으로 받습니다.

| 인터페이스      | 단독 기본 URL                                                  |
| ---------- | ---------------------------------------------------------- |
| Python     | `base_url=`, 직접 기본 URL에는 `direct_base_url=` 추가             |
| TypeScript | `baseUrl`                                                  |
| Rust       | `Config::with_base_url(…)`, 추가로 `.with_direct_base_url(…)` |
| CLI        | `--base-url <URL>` 또는 `NEXUS_BASE_URL`                     |
| MCP 서버     | `NEXUS_EXCHANGE_API_URL`                                   |

이는 지름길이지 문서화된 경로가 아닙니다. MCP 서버에서는 공식적으로 지원 중단(deprecated)되었습니다. 여전히 변함없이 작동하지만, 구성 묶음을 안내하는 알림을 출력합니다. 단독 URL은 **자금이 선언되지 않고** **서명 도메인이 없는** `Custom` 대상을 만들므로, 실제 자금으로 보호되는 작업은 거부되고 클라이언트는 서명하지 않습니다. 호스트를 읽기 전용으로 살펴보기에는 충분하지만, 거래하기에는 의도적으로 부족하게 되어 있습니다.

읽기 이상의 작업을 하려면 주소를 지정하는 대신 대상을 기술하십시오.

### 사용자 지정 대상 기술하기

두 인터페이스는 생성자 인수가 아니라 설정에서 전체 구성 묶음을 받습니다.

**MCP 서버.** `NEXUS_EXCHANGE_NETWORK=custom`을 설정한 다음:

| 변수                             | 의미                                                             |
| ------------------------------ | -------------------------------------------------------------- |
| `NEXUS_EXCHANGE_API_URL`       | REST 기본 URL. 필수.                                               |
| `NEXUS_EXCHANGE_NETWORK_LABEL` | 레이블. 필수.                                                       |
| `NEXUS_EXCHANGE_FUNDS`         | `real`, `play` 또는 `unknown`. 필수.                               |
| `NEXUS_EXCHANGE_FAUCET`        | 이곳에 포셋이 있는지 여부. 설정하지 않으면 없음으로 간주.                              |
| `NEXUS_EXCHANGE_GATEWAY_PATH`  | 오리진 아래에서 게이트웨이 경로의 위치: `/api/exchange`(기본값) 또는 단독 인덱서의 경우 `/`. |

`NEXUS_EXCHANGE_NETWORK=custom` **없이** 이 중 하나라도 설정하면 조용히 무시되는 것이 아니라 오류가 됩니다. 구성 묶음의 절반만 조용히 적용되면, 실제로는 적용되지 않은 안전 속성을 설정했다고 믿게 됩니다.

**CLI.** 설정 파일(`$XDG_CONFIG_HOME/nexus/config.json`, 없으면 `~/.config/nexus/config.json`)의 `custom_networks` 아래에 대상을 선언하고 레이블로 선택하십시오.

```json
{
  "custom_networks": {
    "dev": {
      "base_url": "https://exchange.example.com/api/exchange",
      "direct_base_url": "https://api.example.com",
      "funds": "play",
      "ws_url": "wss://stream.example.com",
      "faucet": true
    }
  }
}
```

```bash
nexus --network dev markets
```

해당 배포 자체의 `GET /metadata`에서 읽어 온 뒤에는 `chain_id`도 그 항목에 넣어야 합니다. 예시는 플레이스홀더 값을 보여 주는 대신 의도적으로 이를 생략했습니다. *알 수 없음*을 뜻하는 센티널 값은 없습니다. CLI는 입력한 어떤 숫자든 EIP-712 도메인으로 받아들이므로, 지어낸 값은 잘못된 도메인으로 서명을 만들고, 생략하면 거부가 발생합니다.

선언되지 않은 레이블은 오류입니다. CLI는 선언된 레이블을 파일을 읽을 때가 아니라 선택할 때 검증하므로, 사용하지 않는 스테이지의 실수가 다른 모든 명령을 망가뜨리지 않습니다.

#### 두 필드 집합은 의도적으로 다릅니다

어느 목록도 다른 목록의 부분 집합이 아닙니다. 차이는 세 가지입니다.

* **`chain_id`는 CLI 전용입니다.** MCP 서버는 EIP-712 서명을 만들지 않으므로(HMAC으로 인증) 서명 도메인이 필요 없으며, 이를 담으면 값이 오래될 수 있는 곳이 하나 더 생깁니다.
* **`gateway_path`는 MCP 전용입니다.** CLI의 `direct_base_url`과 같은 설정을 반대쪽에서 접근한 것입니다. MCP 서버는 경로를 받아 직접 기본 URL을 유도하고, CLI는 직접 기본 URL을 받으므로 경로가 필요 없습니다.
* **`ws_url`은 CLI 전용입니다.** MCP 서버는 게이트웨이 기본 URL에서 WebSocket 오리진을 유도하며, 스트림 경로에 별도의 호스트가 없으므로 API 계약이 이를 지원합니다. CLI는 배포가 스트림을 다른 호스트에 둘 수 있으므로 명시적인 값을 받습니다. 따라서 별도의 WebSocket 오리진을 가진 사용자 지정 대상은 CLI에는 기술할 수 있지만, MCP 서버에는 아직 기술할 수 없습니다.

### 네트워크에 담기는 것

네트워크를 선택하면 다음이 모두 함께 결정되며, 그래서 여러 선택이 아니라 하나의 선택입니다.

* 거래 및 계정 엔드포인트를 위한 **REST 기본 URL**.
* 인터페이스가 스트리밍을 지원하는 경우, 공개 시장 데이터와 인증된 스트림을 위한 **WebSocket 기본 URL**. Python SDK에는 WebSocket 클라이언트가 없습니다. Rust SDK는 스트림 토큰을 그 토큰을 발급하지 않은 오리진과 짝짓지 않기 위해, 공개 스트림 호스트가 운영되기 전까지 테스트넷에서 연결을 거부하므로, 그곳에서는 명시적인 WebSocket URL을 제공하십시오.
* **포셋 존재 여부.** 공개된 네트워크 중 합성 자금 충전은 테스트넷과 로컬 전용이며, 메인넷에는 없습니다. 사용자 지정 대상은 자체적으로 선언하며, 선언하기 전까지는 없는 것으로 간주됩니다.
* **잔액이 실제 돈인지 여부.** 호스트 이름을 패턴 매칭하는 대신, 되돌릴 수 없는 작업 전에 분기할 수 있는 단일 플래그입니다.
* 에이전트 등록 범위를 이 네트워크로 한정하는 **EIP-712 서명 도메인**. 체인 ID의 기준은 서버이므로, 연결된 네트워크의 `GET /metadata`에서 읽으십시오. 체인 ID를 얻을 수 없는 클라이언트는 다른 곳의 값을 재사용하는 대신 서명을 거부합니다.

### 자격 증명과 네트워크 격리

세션 토큰, HMAC API 키, 에이전트 등록은 **네트워크별로** 발급되며 다른 모든 네트워크에서는 무효입니다. 한 네트워크용으로 설정된 키는 다른 네트워크에서 인증되지 않으므로, 테스트넷에서 노출된 자격 증명으로 실제 자금에 대해 서명할 수 없습니다.

클라이언트는 수명 전체 동안 자신의 네트워크에 묶이며, 변경하는 설정자(setter)는 없습니다. 네트워크를 바꾸려면 해당 네트워크의 자격 증명으로 새 클라이언트를 생성해야 하며, 서명, 논스, 에이전트 등록을 절대 다른 네트워크로 가져가서는 안 됩니다.

CLI는 자격 증명을 네트워크 이름을 키로 하여 **네트워크별로** 저장합니다. 사용자 지정 대상의 경우 URL이 아니라 레이블을 키로 삼으므로, 같은 호스트의 두 스테이지도 별도의 자격 증명을 가집니다. 따라서 `--network`는 대상*과* 자격 증명 집합을 함께 선택합니다. 이 옵션으로 자격 증명을 발급할 수는 없습니다. 아직 설정하지 않은 네트워크로 전환하면 저장된 키가 없으므로, 해당 네트워크에 대해 `nexus setup`을 실행하거나 명령줄에서 `--network`와 함께 자격 증명을 전달하십시오.

#### 무엇이 키를 네트워크에 묶는가

**키를 발급한 호스트입니다.** 키 생성에는 네트워크 파라미터가 없습니다. `POST /keys`는 요청을 처리한 인스턴스의 네트워크를 기록하며, 그 이후 키는 그곳에서만 유효합니다. 따라서 키를 생성할 때 가리키는 기본 URL이 *곧* 바인딩 결정입니다. 설정할 것도, 확인할 것도 없습니다.

다음 두 가지 결과를 고려해 계획하십시오.

* 한 네트워크를 가리킨 상태에서 키를 생성한 뒤 다른 네트워크에서 거래하는 것은, 이후 클라이언트를 어떻게 설정하든 작동하지 않습니다.
* 사용하려는 네트워크마다 별도의 키가 필요하며, 각 네트워크에 대해 따로 발급해야 합니다.

#### 잘못된 네트워크의 키는 어떻게 보이는가

존재하지 않는 키와 정확히 똑같이 보입니다. 다음 본문과 함께 **HTTP 401 Unauthorized**가 반환됩니다.

```json
{
  "code": "unauthorized"
}
```

이 응답은 잘못된 서명, 알 수 없는 키 ID, 누락된 헤더와 **의도적으로 구분되지 않습니다**. 거부된 키가 "실재하지만 다른 곳에 등록된" 키로 식별되어서는 안 됩니다. 그렇게 되면 누군가 추측한 키 ID가 다른 네트워크에서 유효한지 확인할 수 있기 때문입니다. 따라서 API는 "이 요청은 인증되지 않았다"는 것 외에는 아무것도 알려 주지 않습니다.

**대상 네트워크를 바꾼 뒤에 인증이 실패한다면, 키가 폐기되었을 가능성보다 네트워크 문제일 가능성이 훨씬 높습니다.** 키가 삭제되었거나 시크릿을 잃어버렸다고 가정하기 전에 어느 호스트가 키를 발급했는지 확인하십시오. 응답에는 이를 알려 주는 단서가 전혀 없습니다.

#### 네트워크별 바인딩 이전에 발급된 키

네트워크 바인딩이 생기기 전에 생성된 키에는 자체 네트워크 정보가 없습니다. 이런 키는 테스트넷과 로컬에서 계속 작동하며, 두 네트워크는 이러한 키를 자신의 것으로 받아들이고 네트워크를 기록합니다. 표시가 없는 키는 출처에 대해 아무것도 증명하지 못하므로, 메인넷은 출시 시 이러한 키를 받아들이지 **않습니다**. 기존 키가 이어질 것으로 기대하지 말고 메인넷에 대해 새 키를 발급하십시오.

지갑 로그인부터 서명된 요청까지 전체 인증 과정은 [빠른 시작](https://docs.nexus.xyz/exchange/trading/quickstart)을 참조하십시오.

### 관련 문서

* [API 및 요청 한도](https://docs.nexus.xyz/exchange/apis-and-rates): 현재 기본 URL과 요청 한도
* [인터페이스 개요](/api-reference/ko/readme.md)
* [포트폴리오 및 계정 상태](/api-reference/ko/guides/portfolio.md)
* [빠른 시작](https://docs.nexus.xyz/exchange/trading/quickstart)

> **상태:** 테스트넷의 개발 프리뷰입니다. 메인넷은 출시되지 않았으며 아직 연결할 수 없습니다. 네트워크 선택기는 이전의 `{stable, beta, local}` 릴리스 채널 선택기를 대체했습니다. 프로덕션에서는 릴리스된 버전에 고정하고, 업그레이드하기 전에 각 인터페이스의 릴리스 노트를 확인하십시오. 테스트넷 자격 증명과 잔액에는 실제 가치가 없습니다.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.nexus.xyz/api-reference/ko/guides/networks.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
