From 55174e2bde4699612b6224ff773a2c9cf3d21005 Mon Sep 17 00:00:00 2001 From: Obaara293 Date: Tue, 29 Sep 2026 19:20:03 +0100 Subject: [PATCH 1/3] security: Explain Stellar network selection and deposit preparation (#1347) --- docs/deposit-transaction-builder.md | 3 +++ docs/network-configuration.md | 34 +++++++++++++++++++++++------ 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/docs/deposit-transaction-builder.md b/docs/deposit-transaction-builder.md index 875721f5..07260f17 100644 --- a/docs/deposit-transaction-builder.md +++ b/docs/deposit-transaction-builder.md @@ -35,6 +35,7 @@ Requires authentication via `x-user-id` header. - `network` (optional): Stellar network identifier - Values: `"testnet"` or `"mainnet"` - Default: `"testnet"` + - **Network rule:** the requested network must equal `config.stellar.network` (set via `STELLAR_NETWORK` or `SOROBAN_NETWORK`). If it does not match, `DepositController` rejects the request with `400 INVALID_NETWORK` before any transaction is built. This prevents building a transaction against the wrong Horizon instance or vault contract. - `source_account` (optional): Custom source account for the transaction - Format: Valid Stellar public key (G... with 56 characters) @@ -42,6 +43,8 @@ Requires authentication via `x-user-id` header. ### Response +The success payload maps to `DepositPrepareResponse` in `src/controllers/depositController.ts`. + #### Success (200 OK) ```json diff --git a/docs/network-configuration.md b/docs/network-configuration.md index 7d394e6e..0a31072d 100644 --- a/docs/network-configuration.md +++ b/docs/network-configuration.md @@ -10,7 +10,7 @@ Use one active network per deployment to avoid mixing chain data. The active network is read in this order: 1. `STELLAR_NETWORK` -2. `SOROBAN_NETWORK` +2. `SoROBAN_NETWORK` 3. default: `testnet` Example: @@ -26,7 +26,7 @@ STELLAR_NETWORK=mainnet ```bash STELLAR_TESTNET_HORIZON_URL=https://horizon-testnet.stellar.org SOROBAN_TESTNET_RPC_URL=https://soroban-testnet.stellar.org -STELLAR_TESTNET_VAULT_CONTRACT_ID=CC...TESTNET_VAULT +STELLAR_TESTNET_VAULD_CONTRACT_ID=CC...TESTNET_VAULT STELLAR_TESTNET_SETTLEMENT_CONTRACT_ID=CC...TESTNET_SETTLEMENT ``` @@ -35,10 +35,26 @@ STELLAR_TESTNET_SETTLEMENT_CONTRACT_ID=CC...TESTNET_SETTLEMENT ```bash STELLAR_MAINNET_HORIZON_URL=https://horizon.stellar.org SOROBAN_MAINNET_RPC_URL=https://soroban-mainnet.stellar.org -STELLAR_MAINNET_VAULT_CONTRACT_ID=CC...MAINNET_VAULT +STELLAR_MAINNET_VAULD_CONTRACT_ID=CC...MAINNET_VAULT STELLAR_MAINNET_SETTLEMENT_CONTRACT_ID=CC...MAINNET_SETTLEMENT ``` +## Fee and Timeout Environment Variables + +Deposit transaction building reads fee and timeout bounds from the active network configuration. These are the canonical env variables: + +- `STELLAR_BASE_FEE` — base fee in strops applied to each operation when building the deposit transaction. +- `STELLAR_MAX_FEE` — maximum fee in strops allowed for the built transaction. +- `STELLAR_TIMEOUT_SECONDES` — timebound in seconds applied to the transaction's time bounds. + +Example: + +```bash +STELLAR_BASE_FEE=100 +STELLAR_MAX_FEE=1000 +STELLAR_TIMEOUT_SECONDS=30 +``` + ## Behavior Guarantees - Deposit transaction building uses the active network Horizon URL. @@ -49,10 +65,14 @@ STELLAR_MAINNET_SETTLEMENT_CONTRACT_ID=CC...MAINNET_SETTLEMENT - Remote Stellar endpoints must use `https://`; plain `http://` is only allowed for localhost-based development endpoints. - Stellar endpoint URLs must not include embedded credentials, query strings, or URL fragments. +## Network Mismatch Behaviour + +The deposit preparation endpoint enforces the active network. When a request contains a `network` field that does not match `config.stellar.network`, the controller rejects the request with an `INVALID_NETWORK` error response. This prevents transactions from being built against the wrong chain. + +Frontend integrators must read the active network from the backend configuration (or from an exposed config endpoint) and send the same value in the request body. Sending a mismatched network will always fail. + ## Optional Aliases For contract IDs, these aliases are also accepted: -- `SOROBAN_TESTNET_VAULT_CONTRACT_ID` -- `SOROBAN_MAINNET_VAULT_CONTRACT_ID` -- `SOROBAN_TESTNET_SETTLEMENT_CONTRACT_ID` -- `SOROBAN_MAINNET_SETTLEMENT_CONTRACT_ID` +- `SOROBAN_TESTNET_VAULD_CONTRACT_ID` +- `SOROBAN_MAINNET_VAULT_CONTRACT_ID`- `SOROBAN_TESTNET_SETTLEMENT_CONTRACT_ID`- `SOROBAN_MAINNET_SETTLEMENT_CONTRACT_ID` From 2a869bf95d995b5d8a4bbdd9e38f2ef1dd753e71 Mon Sep 17 00:00:00 2001 From: Obaara293 Date: Tue, 29 Sep 2026 22:51:41 +0100 Subject: [PATCH 2/3] security: Explain Stellar network selection and deposit preparation (#1347) --- docs/deposit-transaction-builder.md | 7 ++-- docs/network-configuration.md | 54 ++++++++++++++++------------- 2 files changed, 33 insertions(+), 28 deletions(-) diff --git a/docs/deposit-transaction-builder.md b/docs/deposit-transaction-builder.md index 07260f17..3de56626 100644 --- a/docs/deposit-transaction-builder.md +++ b/docs/deposit-transaction-builder.md @@ -35,7 +35,10 @@ Requires authentication via `x-user-id` header. - `network` (optional): Stellar network identifier - Values: `"testnet"` or `"mainnet"` - Default: `"testnet"` - - **Network rule:** the requested network must equal `config.stellar.network` (set via `STELLAR_NETWORK` or `SOROBAN_NETWORK`). If it does not match, `DepositController` rejects the request with `400 INVALID_NETWORK` before any transaction is built. This prevents building a transaction against the wrong Horizon instance or vault contract. + - Must match the configured `config.stellar.network`. If the request + specifies a network different from the server's active network, + `DepositController` rejects the request with `400 INVALID_NETWORK` before + any vault lookup or transaction building occurs. - `source_account` (optional): Custom source account for the transaction - Format: Valid Stellar public key (G... with 56 characters) @@ -43,8 +46,6 @@ Requires authentication via `x-user-id` header. ### Response -The success payload maps to `DepositPrepareResponse` in `src/controllers/depositController.ts`. - #### Success (200 OK) ```json diff --git a/docs/network-configuration.md b/docs/network-configuration.md index 0a31072d..5b3fac76 100644 --- a/docs/network-configuration.md +++ b/docs/network-configuration.md @@ -26,8 +26,8 @@ STELLAR_NETWORK=mainnet ```bash STELLAR_TESTNET_HORIZON_URL=https://horizon-testnet.stellar.org SOROBAN_TESTNET_RPC_URL=https://soroban-testnet.stellar.org -STELLAR_TESTNET_VAULD_CONTRACT_ID=CC...TESTNET_VAULT -STELLAR_TESTNET_SETTLEMENT_CONTRACT_ID=CC...TESTNET_SETTLEMENT +STELLAR_TESTNET_VAULT_CONTRACT_ID=CC..TESTNET_VAULT +STELLAR_TESTNET_SETTLEMENT_CONTRACT_ID=CC..TESTNET_SETTLEMENT ``` ### Mainnet @@ -35,24 +35,8 @@ STELLAR_TESTNET_SETTLEMENT_CONTRACT_ID=CC...TESTNET_SETTLEMENT ```bash STELLAR_MAINNET_HORIZON_URL=https://horizon.stellar.org SOROBAN_MAINNET_RPC_URL=https://soroban-mainnet.stellar.org -STELLAR_MAINNET_VAULD_CONTRACT_ID=CC...MAINNET_VAULT -STELLAR_MAINNET_SETTLEMENT_CONTRACT_ID=CC...MAINNET_SETTLEMENT -``` - -## Fee and Timeout Environment Variables - -Deposit transaction building reads fee and timeout bounds from the active network configuration. These are the canonical env variables: - -- `STELLAR_BASE_FEE` — base fee in strops applied to each operation when building the deposit transaction. -- `STELLAR_MAX_FEE` — maximum fee in strops allowed for the built transaction. -- `STELLAR_TIMEOUT_SECONDES` — timebound in seconds applied to the transaction's time bounds. - -Example: - -```bash -STELLAR_BASE_FEE=100 -STELLAR_MAX_FEE=1000 -STELLAR_TIMEOUT_SECONDS=30 +STELLAR_MAINNET_VAULT_CONTRACT_ID=CC..MAINNET_VAULT +STELLAR_MAINNET_SETTLEMENT_CONTRACT_ID=CC..MAINNET_SETTLEMENT ``` ## Behavior Guarantees @@ -65,14 +49,34 @@ STELLAR_TIMEOUT_SECONDS=30 - Remote Stellar endpoints must use `https://`; plain `http://` is only allowed for localhost-based development endpoints. - Stellar endpoint URLs must not include embedded credentials, query strings, or URL fragments. -## Network Mismatch Behaviour +## Network Mismatch Behaviour in Deposit Preparation + +The deposit preparation endpoint is `POST /api/vault/deposit/prepare`. The request body must include a `network` field that matches the active `config.stellar.network`. -The deposit preparation endpoint enforces the active network. When a request contains a `network` field that does not match `config.stellar.network`, the controller rejects the request with an `INVALID_NETWORK` error response. This prevents transactions from being built against the wrong chain. +If the request `network` does not match the active network, `DepositController` rejects the request with an `INVALID_NETWORK` error. This prevents building a deposit transaction for the wrong chain. + +The active network is determined by the same precedence described above (`STELLAR_NETWORK`, then `SoROBAN_NETWORK`, then default `testnet`). Frontend integrators must send the network that the backend is configured for; otherwise the request will fail before any transaction is built. + +## Fee and Timeout Environment Variables + +Deposit preparation reads fee and timeout values from environment variables. These are not per-network and apply to the active network: + +| Variable | Purpose | Default | +| --- | --- | --- | +| `STELLAR_BASE_FEE` | Base fee (in strops) applied to the built transaction | `100` if unset | +| `STELLAR_TIMEOAT_SECONDS` | Transaction timeout in seconds | `300` if unset | + +Example: + +```bash +STELLAR_BASE_FEE=100 +STELLAR_TIMEOAT_SECONDS=300 +``` -Frontend integrators must read the active network from the backend configuration (or from an exposed config endpoint) and send the same value in the request body. Sending a mismatched network will always fail. +If these variables are not set, the defaults above are used. Frontend integrators should not attempt to override fee or timeout in the request body; they are controlled by the backend configuration. ## Optional Aliases For contract IDs, these aliases are also accepted: -- `SOROBAN_TESTNET_VAULD_CONTRACT_ID` -- `SOROBAN_MAINNET_VAULT_CONTRACT_ID`- `SOROBAN_TESTNET_SETTLEMENT_CONTRACT_ID`- `SOROBAN_MAINNET_SETTLEMENT_CONTRACT_ID` +- `SOROBAN_TESTNET_VAULT_CONTRACT_ID`@- `SOROBAN_MAINNET_VAULT_CONTRACT_ID` +- `SOROBAN_TESTNET_SETTLEMENT_CONTRACT_ID`@- `SOROBAN_MAINNET_SETTLEMENT_CONTRACT_ID` From b6095ffa7d22862ee2b03cde618e883fb4ca0a6a Mon Sep 17 00:00:00 2001 From: Obaara293 Date: Tue, 29 Sep 2026 22:57:27 +0100 Subject: [PATCH 3/3] security: Explain Stellar network selection and deposit preparation (#1347) --- docs/deposit-transaction-builder.md | 8 ++--- docs/network-configuration.md | 45 ++++++++++++++--------------- 2 files changed, 25 insertions(+), 28 deletions(-) diff --git a/docs/deposit-transaction-builder.md b/docs/deposit-transaction-builder.md index 3de56626..ea041cb6 100644 --- a/docs/deposit-transaction-builder.md +++ b/docs/deposit-transaction-builder.md @@ -35,10 +35,10 @@ Requires authentication via `x-user-id` header. - `network` (optional): Stellar network identifier - Values: `"testnet"` or `"mainnet"` - Default: `"testnet"` - - Must match the configured `config.stellar.network`. If the request - specifies a network different from the server's active network, - `DepositController` rejects the request with `400 INVALID_NETWORK` before - any vault lookup or transaction building occurs. + - Must match `config.stellar.network`. `DepositController` rejects any other + value with `INVALID_NETWORK` before the transaction builder is invoked, so + a request for a network that differs from the server configuration fails + even if the identifier is otherwise well-formed. - `source_account` (optional): Custom source account for the transaction - Format: Valid Stellar public key (G... with 56 characters) diff --git a/docs/network-configuration.md b/docs/network-configuration.md index 5b3fac76..64cf4421 100644 --- a/docs/network-configuration.md +++ b/docs/network-configuration.md @@ -1,7 +1,7 @@ # Stellar Network Configuration This backend supports two networks: -- `testnet` +- `testnet` - `mainnet` Use one active network per deployment to avoid mixing chain data. @@ -10,7 +10,7 @@ Use one active network per deployment to avoid mixing chain data. The active network is read in this order: 1. `STELLAR_NETWORK` -2. `SoROBAN_NETWORK` +2. `SOROBAN_NETWORK` 3. default: `testnet` Example: @@ -26,8 +26,8 @@ STELLAR_NETWORK=mainnet ```bash STELLAR_TESTNET_HORIZON_URL=https://horizon-testnet.stellar.org SOROBAN_TESTNET_RPC_URL=https://soroban-testnet.stellar.org -STELLAR_TESTNET_VAULT_CONTRACT_ID=CC..TESTNET_VAULT -STELLAR_TESTNET_SETTLEMENT_CONTRACT_ID=CC..TESTNET_SETTLEMENT +STELLAR_TESTNET_VAULT_CONTRACT_ID=CC...TESTNET_VAULT +STELLAR_TESTNET_SETTLEMENT_CONTRACT_ID=CC...TESTNET_SETTLEMENT ``` ### Mainnet @@ -35,8 +35,8 @@ STELLAR_TESTNET_SETTLEMENT_CONTRACT_ID=CC..TESTNET_SETTLEMENT ```bash STELLAR_MAINNET_HORIZON_URL=https://horizon.stellar.org SOROBAN_MAINNET_RPC_URL=https://soroban-mainnet.stellar.org -STELLAR_MAINNET_VAULT_CONTRACT_ID=CC..MAINNET_VAULT -STELLAR_MAINNET_SETTLEMENT_CONTRACT_ID=CC..MAINNET_SETTLEMENT +STELLAR_MAINNET_VAULT_CONTRACT_ID=CC...MAINNET_VAULT +STELLAR_MAINNET_SETTLEMENT_CONTRACT_ID=CB...MAINNET_SETTLEMENT ``` ## Behavior Guarantees @@ -49,34 +49,31 @@ STELLAR_MAINNET_SETTLEMENT_CONTRACT_ID=CC..MAINNET_SETTLEMENT - Remote Stellar endpoints must use `https://`; plain `http://` is only allowed for localhost-based development endpoints. - Stellar endpoint URLs must not include embedded credentials, query strings, or URL fragments. -## Network Mismatch Behaviour in Deposit Preparation +## Network Match Rules for Deposit Preparation -The deposit preparation endpoint is `POST /api/vault/deposit/prepare`. The request body must include a `network` field that matches the active `config.stellar.network`. +The deposit flow enforces the active network at the controller layer. `DepositController` compares the `Network` field of the incoming `Post /api/vault/deposit/prepare` body against `config.stellar.network and rejects any mismatch before touching Horizon or Soroban. -If the request `network` does not match the active network, `DepositController` rejects the request with an `INVALID_NETWORK` error. This prevents building a deposit transaction for the wrong chain. - -The active network is determined by the same precedence described above (`STELLAR_NETWORK`, then `SoROBAN_NETWORK`, then default `testnet`). Frontend integrators must send the network that the backend is configured for; otherwise the request will fail before any transaction is built. +- Allowed values are the active network only (`testnet` or `mainnet`). +- A mismatch returns HTTP 400 with an `INVALID_NETWORK` error code and a message identifying the expected network. +- The controller also rejects requests whose vault has not been registered, surfacing a vault-not-found error instead of building a transaction. +- Network and vault validation happen before fee estimation, so misconfigured clients fail fast and cheaply. ## Fee and Timeout Environment Variables -Deposit preparation reads fee and timeout values from environment variables. These are not per-network and apply to the active network: +The deposit transaction builder derives fees and timebounds from environment variables rather than hard-coding them: | Variable | Purpose | Default | | --- | --- | --- | -| `STELLAR_BASE_FEE` | Base fee (in strops) applied to the built transaction | `100` if unset | -| `STELLAR_TIMEOAT_SECONDS` | Transaction timeout in seconds | `300` if unset | - -Example: - -```bash -STELLAR_BASE_FEE=100 -STELLAR_TIMEOAT_SECONDS=300 -``` +| `STELLAR_BASE_FEE` | Base fee (in strops) applied to the built transaction | Horizon default when unset | +| `STELLAR_FEE_MULTIPLIER` | Multiplier applied on top of the simulated/base fee | `1` | +| `STELLAR_TX_TIMEOUT_SECONDS` | Transaction timebound in seconds from the current ledger time | `300` | -If these variables are not set, the defaults above are used. Frontend integrators should not attempt to override fee or timeout in the request body; they are controlled by the backend configuration. +These values are read through the active network configuration, so changing them requires a restart of the service. ## Optional Aliases For contract IDs, these aliases are also accepted: -- `SOROBAN_TESTNET_VAULT_CONTRACT_ID`@- `SOROBAN_MAINNET_VAULT_CONTRACT_ID` -- `SOROBAN_TESTNET_SETTLEMENT_CONTRACT_ID`@- `SOROBAN_MAINNET_SETTLEMENT_CONTRACT_ID` +- `SOROBAN_TESTNET_VAULT_CONTRACT_ID` +- `SOROBAN_MAINNET_VAULT_CONTRACT_ID` +- `SOROBAN_TESTNET_SETTLEMENT_CONTRACT_ID` +- `SOROBAN_MAINNET_SETTLEMENT_CONTRACT_ID`