Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 123 additions & 0 deletions docs/api/ERROR_REFERENCE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# API Error Code Reference

This document serves as the developer reference for all categories of errors thrown or handled by the **Stellar Dev Dashboard** API layers and modules (primarily `src/lib/errorHandling.ts`, `stellar.ts`, and `contractInvoker.js`).

---

## 1. Error Categories and HTTP Mappings

The application maps all integration failures into a unified set of categories defined by the `ErrorCategory` enum. Below is the mapping table showing how HTTP status codes from Horizon, Soroban RPC, CoinGecko, and local validation map to these categories:

| HTTP Status | Category | Code / Identifier | User Message / Scenario | Retryable |
|-------------|----------|-------------------|-------------------------|-----------|
| `400` | `VALIDATION` | `bad_request` | Invalid parameters or malformed transaction XDR. | No |
| `401` | `AUTHENTICATION` | `unauthorized` | Freighter or Ledger wallet is not connected or approved. | No |
| `403` | `AUTHORIZATION` | `forbidden` | Access to the requested resource is denied. | No |
| `404` | `NOT_FOUND` | `not_found` | Stellar account or transaction hash does not exist on-chain. | No |
| `409` | `CONFLICT` | `conflict` | State conflict (e.g. transaction sequence gap). | No |
| `429` | `RATE_LIMIT` | `rate_limit_exceeded` | Horizon or CoinGecko rate limit has been exceeded. | **Yes** |
| `500` | `SERVER_ERROR` | `internal_server_error` | The remote server encountered an unexpected error. | **Yes** |
| `502` | `SERVER_ERROR` | `bad_gateway` | Horizon gateway failed to communicate with the core node. | **Yes** |
| `503` | `SERVER_ERROR` | `service_unavailable` | Service is down for maintenance or overloaded. | **Yes** |
| `504` | `TIMEOUT` | `gateway_timeout` | The request took too long to resolve. | **Yes** |
| — | `NETWORK` | `network_failed` | Client has lost internet connectivity or CORS blocked the call. | **Yes** |
| — | `TIMEOUT` | `client_timeout` | The local request timed out (default limit reached). | **Yes** |

---

## 2. Stellar Horizon Operation Result Codes

When submitting a transaction via `POST /transactions` or simulating via `simulateTransaction`, Horizon/Soroban returns specific result codes in the `result_codes` block inside `extras`.

Here are the most common result codes you must handle in integrations:

### Transaction-Level Codes (`result_codes.transaction`)

| Code | Meaning | Root Cause / Resolution |
|------|---------|-------------------------|
| `tx_success` | Success | The transaction was included in a ledger block. |
| `tx_failed` | Failed | One or more operations failed. Inspect `result_codes.operations`. |
| `tx_too_early` | Too Early | Ledger time is before the transaction's `time_bounds.min_time`. |
| `tx_too_late` | Too Late | Ledger time is after the transaction's `time_bounds.max_time`. |
| `tx_bad_seq` | Bad Sequence | The source account's sequence number does not match. Increment sequence by 1. |
| `tx_bad_auth` | Bad Auth | Invalid signatures, or signature weight is below threshold. |
| `tx_insufficient_balance` | Insufficient Balance | The source account cannot pay the fee in XLM. |
| `tx_insufficient_fee` | Insufficient Fee | The fee bid is below the current base fee multiplier for high-activity blocks. |

### Operation-Level Codes (`result_codes.operations`)

| Operation Code | Scenario | Recommended Action |
|----------------|----------|--------------------|
| `op_success` | Operation succeeded. | None. |
| `op_no_destination` | The destination account does not exist. | Create the account first using `createAccount`, or check key. |
| `op_no_trust` | The destination does not have a trustline for the asset. | Recipient must execute a `changeTrust` operation first. |
| `op_underfunded` | The source account has insufficient balance for the amount. | Fund the account or reduce transfer quantity. |
| `op_low_reserve` | The transfer would drop the account below the minimum base reserve. | Account must maintain `(2 + subentries) * 0.5 XLM`. |
| `op_src_not_authorized` | The source account is not authorized to hold this asset. | Issuer has auth_required enabled and has not approved the account. |

---

## 3. Soroban Smart Contract RPC Error Codes

Soroban RPC returns standard JSON-RPC 2.0 error payloads when the request format or VM execution fails.

| Error Code | Error Type | Scenario |
|------------|------------|----------|
| `-32600` | Invalid Request | The JSON sent is not a valid Request object. |
| `-32601` | Method Not Found | The JSON-RPC method does not exist (e.g. spelling error). |
| `-32602` | Invalid Params | Invalid method parameters (e.g. wrong transaction XDR format). |
| `-32603` | Internal Error | Internal JSON-RPC error. |
| `-32001` | Action Failed | The requested action could not be completed. |
| `-32002` | Contract Code Malformed | The contract bytecode failed loading / verification. |

### Soroban VM Invocation Result Codes

If `simulateTransaction` succeeds but the transaction itself fails, the simulation `status` will be `error`, and it will contain `events` or `logs` with the following error structures:

```json
{
"jsonrpc": "2.0",
"id": "sim-fail",
"result": {
"latestLedger": 5493205,
"status": "error",
"error": "ContractError(102)",
"events": [
{
"type": "system",
"ledger": 5493205,
"contractId": "CBXG...",
"topics": ["error"],
"value": "AAAAAQAAAGY="
}
],
"logs": [
"VM Error: contract panicked with error code 102"
]
}
}
```

---

## 4. Developer Recovery Strategies (Code Reference)

In `src/lib/errorHandling.ts`, developers should utilize the `retryWithBackoff` wrapper to handle transient `RATE_LIMIT` (429) and `SERVER_ERROR` (5xx) codes safely:

```ts
import { retryWithBackoff } from '@/lib/errorHandling';

async function fetchWithRetry(publicKey: string) {
return await retryWithBackoff(
async () => {
const response = await fetch(`https://horizon-testnet.stellar.org/accounts/${publicKey}`);
if (!response.ok) {
throw new Error(`HTTP Error ${response.status}`);
}
return await response.json();
},
3, // Max retries
1000 // Base delay (1s, becomes 2s, 4s...)
);
}
```
107 changes: 107 additions & 0 deletions docs/api/RATE_LIMITING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# API Rate Limiting & Queue Management

All external API interactions from the **Stellar Dev Dashboard** (to Horizon, Soroban RPC, and CoinGecko) are gated and prioritized by an advanced client-side rate limiting and scheduling system. This prevents application actions from triggering HTTP `429 (Too Many Requests)` errors and keeps the interface active during heavy traffic.

This system is implemented in `src/lib/rateLimiter.js` and provides token bucket rate limiting, priority queuing, and request coalescing.

---

## 1. Core Architecture

The rate limiter acts as a middleware layer between the UI hooks (e.g. `usePersistedState`, data loaders) and the network. It uses a **Token Bucket** algorithm combined with **Priority Queues** to schedule outgoing requests.

```mermaid
graph TD
A[UI Hooks / Data Loaders] -->|Request + Priority| B{Rate Limiter}
B -->|Tokens Available| C[Immediate Execute]
B -->|Tokens Exceeded| D[Priority Queue]
D -->|High Priority| E[Queue Process]
D -->|Medium Priority| E
D -->|Low Priority| E
E -->|Refill Token| C
E -->|Timeout >30s| F[Reject Request]
```

---

## 2. Configured Rate Limits

Default and endpoint-specific limits are enforced per IP address/client identifier inside `src/lib/rateLimiter.js`. A single time window is set to **1 minute (60,000ms)**.

| Endpoint Target | Max Requests / Min | Priority Tier | Description / Scenario |
|-----------------|--------------------|---------------|------------------------|
| `/accounts` | `20` | `High` | Connected account details, balances, and signers. |
| `/transactions` | `15` | `Medium` | Paginated transaction lists, history, and records. |
| `/operations` | `25` | `Medium` | Paginated operation lists. |
| `/assets` | `10` | `Low` | Price feed mapping and assets search. |
| `/contracts` | `5` | `High` | Soroban simulations and get contract code. |
| `default` | `30` | `Medium` | Default fallback rate for unclassified requests. |

---

## 3. Queue Priority Scheduling

When outgoing requests exceed the maximum limit for a time window, the system automatically buffers them in three internal priority lists:

* **High Priority (`priority: 'high'`)**:
* *Triggers*: Contract simulations, transaction submissions, Friendbot faucets, and initial wallet connection.
* *Handling*: Processed immediately when a token becomes available.
* **Medium Priority (`priority: 'medium'`)**:
* *Triggers*: Tab switches, paginated "Load More" history, and DEX order book refreshes.
* *Handling*: Processed after the High priority queue is cleared.
* *Timeout*: Dropped and rejected if delayed for more than **30 seconds**.
* **Low Priority (`priority: 'low'`)**:
* *Triggers*: Live ticker price updates, portfolio value recalculations, and diagnostic logs.
* *Handling*: Only processed when both High and Medium queues are completely empty.

---

## 4. Throttle Modes

The rate limiter supports two performance modes that can be dynamically switched using `rateLimiter.setThrottleMode(mode)`:

### `aggressive` (Default)
Optimized for developer agility. Requests are executed immediately up to the absolute token capacity. Queued requests are processed every 50ms.

### `conservative`
Optimized for low-bandwidth networks or shared API keys.
* Outbound throughput is capped at **1/3** of normal capacity.
* Enforces a maximum queue size of **100 requests**. Any new requests beyond this size are rejected with `Request dropped: queue overflow in conservative mode` to prevent memory leaks.
* Reduces concurrent parallelism.

---

## 5. Developer Integration Example

All fetch calls to external resources should route through the rate limiter's `queueRequest` facade rather than calling raw `fetch` directly:

```ts
import { rateLimiter } from '@/lib/rateLimiter';

async function fetchAccountSafely(publicKey: string) {
// Wrap your request details
const requestConfig = {
url: `https://horizon-testnet.stellar.org/accounts/${publicKey}`,
priority: 'high', // 'high' | 'medium' | 'low'
maxRetries: 3,
options: {
method: 'GET',
headers: {
'Accept': 'application/json'
}
}
};

try {
// Queue the request; returns a Promise that resolves once rate limits permit execution
const response = await rateLimiter.queueRequest(requestConfig, 'user-ip-address');
if (!response.ok) {
throw new Error(`HTTP Error ${response.status}`);
}
return await response.json();
} catch (error) {
console.error('Request failed or dropped:', error.message);
throw error;
}
}
```
15 changes: 9 additions & 6 deletions docs/api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,15 @@ This document collects all integration points for Stellar Horizon, Soroban RPC,

The API docs now include generated reference material and runnable examples.

- `docs/api/generated/API_REFERENCE.md` — auto-generated API reference from `src/lib` exports and JSDoc comments.
- `docs/api/SDK_EXAMPLES.md` — JavaScript and Python SDK examples with runnable sample scripts.
- `docs/api/REQUEST_RESPONSE_SAMPLES.md` — request/response payload examples for Horizon and Soroban RPC.
- `docs/api/CHANGELOG.md` — API documentation changelog.
- `docs/api/VERSION_HISTORY.md` — version history and release metadata.
- `docs/api/examples/` — runnable example scripts for JavaScript and Python.
- [docs/api/openapi.yaml](openapi.yaml) — complete OpenAPI 3.0 specification for all external dashboard integrations.
- [docs/api/generated/API_REFERENCE.md](generated/API_REFERENCE.md) — auto-generated API reference from `src/lib` exports and JSDoc comments.
- [docs/api/SDK_EXAMPLES.md](SDK_EXAMPLES.md) — JavaScript and Python SDK examples with runnable sample scripts.
- [docs/api/REQUEST_RESPONSE_SAMPLES.md](REQUEST_RESPONSE_SAMPLES.md) — request/response payload examples for Horizon, Soroban RPC, CoinGecko, and Friendbot.
- [docs/api/ERROR_REFERENCE.md](ERROR_REFERENCE.md) — developer reference for error categories, codes, and recovery strategies.
- [docs/api/RATE_LIMITING.md](RATE_LIMITING.md) — client-side rate limiting, priority queues, and throttle configurations.
- [docs/api/CHANGELOG.md](CHANGELOG.md) — API documentation changelog.
- [docs/api/VERSION_HISTORY.md](generated/VERSION_HISTORY.md) — version history and release metadata.
- [docs/api/examples/](examples/) — runnable example scripts for JavaScript and Python.

Regenerate the API docs with:

Expand Down
Loading