diff --git a/docs/api/ERROR_REFERENCE.md b/docs/api/ERROR_REFERENCE.md new file mode 100644 index 00000000..1f042da2 --- /dev/null +++ b/docs/api/ERROR_REFERENCE.md @@ -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...) + ); +} +``` diff --git a/docs/api/RATE_LIMITING.md b/docs/api/RATE_LIMITING.md new file mode 100644 index 00000000..c6d1267e --- /dev/null +++ b/docs/api/RATE_LIMITING.md @@ -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; + } +} +``` diff --git a/docs/api/README.md b/docs/api/README.md index cf7f1c53..0be682e1 100644 --- a/docs/api/README.md +++ b/docs/api/README.md @@ -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: diff --git a/docs/api/REQUEST_RESPONSE_SAMPLES.md b/docs/api/REQUEST_RESPONSE_SAMPLES.md index 8ed092b5..67c37d3d 100644 --- a/docs/api/REQUEST_RESPONSE_SAMPLES.md +++ b/docs/api/REQUEST_RESPONSE_SAMPLES.md @@ -1,81 +1,239 @@ # API Request / Response Samples -This document provides direct HTTP request and sample response payloads for common Stellar Horizon and Soroban RPC operations. +This page provides exact, real-world examples of HTTP request payloads and corresponding server responses for the primary API integrations used by the **Stellar Dev Dashboard**. -## Horizon: Account Details +You can run the `curl` examples directly in your terminal to see live network responses. -Request: +--- +## 1. Horizon: Account Details + +Retrieve core account details, sequence numbers, thresholds, signers, and asset trustline balances. + +> [!NOTE] +> All balances are represented as strings to preserve decimal precision, avoiding IEEE-754 floating point inaccuracies. + +### Request (cURL) ```bash -curl -s "https://horizon-testnet.stellar.org/accounts/GDFE3..." | jq . +curl -s "https://horizon-testnet.stellar.org/accounts/GD3W47O7L6J22XCQNFSK3L2V3N45EPEHPEH4J46EPEH4J46EPEH4J46E" ``` -Response sample: - +### Response (200 OK) ```json { - "id": "GDFE3...", - "account_id": "GDFE3...", - "sequence": "1234567890123456", + "id": "GD3W47O7L6J22XCQNFSK3L2V3N45EPEHPEH4J46EPEH4J46EPEH4J46E", + "account_id": "GD3W47O7L6J22XCQNFSK3L2V3N45EPEHPEH4J46EPEH4J46EPEH4J46E", + "sequence": "125893021482", + "subentry_count": 2, + "last_modified_ledger": 5493201, + "last_modified_time": "2026-06-02T08:45:12Z", + "thresholds": { + "low_threshold": 0, + "med_threshold": 1, + "high_threshold": 2 + }, + "flags": { + "auth_required": false, + "auth_revocable": false, + "auth_immutable": false, + "auth_clawback_enabled": true + }, "balances": [ { - "balance": "100.0000000", + "balance": "1240.4019234", + "liquidity_pool_id": "", + "limit": "", + "buying_liabilities": "0.0000000", + "selling_liabilities": "0.0000000", "asset_type": "native" + }, + { + "balance": "500.0000000", + "limit": "922337203685.4775807", + "buying_liabilities": "0.0000000", + "selling_liabilities": "0.0000000", + "asset_type": "credit_alphanum4", + "asset_code": "USDC", + "asset_issuer": "GBBDQG4GBFFKFA65K7Z4C6EPEH4J46EPEH4J46EPEH4J46EPEH4J46E" } ], "signers": [ { - "key": "GDFE3...", "weight": 1, + "key": "GD3W47O7L6J22XCQNFSK3L2V3N45EPEHPEH4J46EPEH4J46EPEH4J46E", "type": "ed25519_public_key" } ] } ``` -## Horizon: Submit Transaction +--- + +## 2. Horizon: Submit Transaction -Request: +Submit a signed TransactionEnvelope XDR to Horizon to be included in a ledger block. +### Request (cURL) ```bash curl -X POST "https://horizon-testnet.stellar.org/transactions" \ -H 'Content-Type: application/x-www-form-urlencoded' \ - --data-urlencode 'tx=AAAA...' + --data-urlencode 'tx=AAAAAgAAAADcR+U8H9v...YOUR_SIGNED_XDR_HERE...' ``` -Sample response: +### Success Response (200 OK) +```json +{ + "id": "8c3bcf5273f7c469b61d4ff1ee8deabfe64e223d6a6234b3f86e92ab0310214a", + "hash": "8c3bcf5273f7c469b61d4ff1ee8deabfe64e223d6a6234b3f86e92ab0310214a", + "ledger": 5493205, + "envelope_xdr": "AAAAAgAAAADcR+U8H9v...", + "result_xdr": "AAAAAAAAAGQAAAAAAAAAAQAAAAAAAAAAAAAAAQ==", + "result_meta_xdr": "AAAAAQAAAAAAAAAA...", + "fee_charged": "100" +} +``` +### Error Response (400 Bad Request / Transaction Failed) ```json { - "hash": "abcdef123456...", - "ledger": 5601234, - "envelope_xdr": "AAAA...", - "result_xdr": "AAAAAAAA..." + "type": "https://stellar.org/horizon-errors/transaction_failed", + "title": "Transaction Failed", + "status": 400, + "detail": "The transaction execution failed on the ledger. Check the result_codes for details.", + "extras": { + "envelope_xdr": "AAAAAgAAAADcR...", + "result_xdr": "AAAAAAAAAHwAAAAAA...", + "result_codes": { + "transaction": "tx_failed", + "operations": [ + "op_no_destination" + ] + } + } } ``` -## Soroban RPC: simulateTransaction +--- + +## 3. Soroban RPC: simulateTransaction -Request: +Simulate contract invocation before committing it to the blockchain. Essential for estimating resource costs (CPU, memory, storage) and generating the footprint. +### Request (cURL) ```bash -curl -s "https://soroban-testnet.stellar.org/soroban/rpc" \ - -H 'Content-Type: application/json' \ - -d '{"id": "1", "method": "simulateTransaction", "params": [{"tx": "AAAA..."}]}' +curl -s -X POST "https://soroban-testnet.stellar.org" \ + -H "Content-Type: application/json" \ + -d '{ + "jsonrpc": "2.0", + "id": "sim-1", + "method": "simulateTransaction", + "params": { + "transaction": "AAAAAgAAAADcR+U8H9v...UNSIGNED_TX_ENVELOPE_XDR..." + } + }' ``` -Response sample: - +### Response (200 OK) ```json { - "id": "1", + "jsonrpc": "2.0", + "id": "sim-1", "result": { + "latestLedger": 5493220, "status": "success", - "results": [], + "results": [ + { + "xdr": "AAAAEAAAAAE=" + } + ], "cost": { - "cpu_insns": 12345, - "mem_bytes": 6789 + "cpuInsns": 182390, + "memBytes": 42091 + }, + "footprint": { + "readOnly": [ + { + "type": "ledgerKeyContractData", + "contractId": "CBXG...", + "key": "AAAAEAAAAAE=" + } + ], + "readWrite": [] } } } ``` + +--- + +## 4. Soroban RPC: sendTransaction + +Submit a signed transaction to a Soroban contract. This is an asynchronous process; the RPC server returns a submission status and transaction hash, which can then be polled using `getTransaction`. + +### Request (cURL) +```bash +curl -s -X POST "https://soroban-testnet.stellar.org" \ + -H "Content-Type: application/json" \ + -d '{ + "jsonrpc": "2.0", + "id": "send-1", + "method": "sendTransaction", + "params": { + "transaction": "AAAAAgAAAADcR+U8H9v...SIGNED_TX_ENVELOPE_XDR..." + } + }' +``` + +### Response (200 OK) +```json +{ + "jsonrpc": "2.0", + "id": "send-1", + "result": { + "hash": "4a737f...TRANSACTION_HASH...", + "status": "PENDING", + "latestLedger": 5493222, + "latestLedgerCloseTime": 1772491200 + } +} +``` + +--- + +## 5. CoinGecko: Simple Price + +Fetch live USD exchange rates and 24-hour fluctuations for XLM and mapped trustline tokens. + +### Request (cURL) +```bash +curl -s "https://api.coingecko.com/api/v3/simple/price?ids=stellar&vs_currencies=usd&include_24hr_change=true" +``` + +### Response (200 OK) +```json +{ + "stellar": { + "usd": 0.114532, + "usd_24h_change": 3.4561234901 + } +} +``` + +--- + +## 6. Friendbot: Faucet Funding + +Deposit 10,000 XLM into an account on the Testnet network. + +### Request (cURL) +```bash +curl -s "https://friendbot.stellar.org?addr=GD3W47O7L6J22XCQNFSK3L2V3N45EPEHPEH4J46EPEH4J46EPEH4J46E" +``` + +### Response (200 OK) +```json +{ + "hash": "a0fb4cfe3e...TRANSACTION_HASH...", + "ledger": 5493240 +} +``` diff --git a/docs/api/generated/API_REFERENCE.md b/docs/api/generated/API_REFERENCE.md index 3b1aca05..6a70d309 100644 --- a/docs/api/generated/API_REFERENCE.md +++ b/docs/api/generated/API_REFERENCE.md @@ -2,7 +2,57 @@ This API reference is auto-generated from the `src/lib` source files and JSDoc-style comments. -Generated on: 2026-06-02T09:17:29.375Z +Generated on: 2026-06-02T11:17:56.346Z + +--- + +## src/lib/accountWatchSystem.ts + +### `export function normalizeBalances(` + +Convert a Horizon balances array into our normalized shape. + +--- + +### `export function aggregateBalances(snapshots: AccountSnapshot[]): AggregatedInsights` + +Roll balances up across every (successful) snapshot. + +--- + +### `export function evaluateWatchRules(` + +Evaluate every enabled rule against the current snapshots. + +--- + +### `export function detectAnomalies(` + +Detect anomalous balance swings between the previous and current snapshots. + +--- + +### `export interface AccountWatchUpdate` + +Run async `worker` over `items` with at most `limit` running at once. + +--- + +### `export interface AccountWatchOptions` + +Run async `worker` over `items` with at most `limit` running at once. + +--- + +### `export class AccountWatchSystem` + +Run async `worker` over `items` with at most `limit` running at once. + +--- + +### `export const accountWatchSystem = new AccountWatchSystem()` + +Shared singleton used by the React hook. --- @@ -231,6 +281,27 @@ Evaluates an incoming streaming event against a collection of user-defined alert --- +## src/lib/alertsService.ts + +### `export interface AlertPayload` + +_No description available._ + +--- + +### `export async function dispatchAlert(alert: AlertPayload): Promise` + +Dispatch a single alert using the appropriate provider. +Returns true if the notification was sent successfully. + +--- + +### `export async function dispatchAlerts(alerts: AlertPayload[]): Promise` + +Dispatch multiple alerts in parallel, returning an array of results. + +--- + ## src/lib/analytics.js ### `export function summarizeBalances(accountData)` @@ -275,6 +346,32 @@ _No description available._ --- +## src/lib/biometricAuth.ts + +### `export interface BiometricOptions` + +_No description available._ + +--- + +### `export async function registerBiometric(options: BiometricOptions)` + +_No description available._ + +--- + +### `export async function loginBiometric()` + +_No description available._ + +--- + +### `export function isBiometricSupported(): boolean` + +_No description available._ + +--- + ## src/lib/cache.js ### `export const TTL =` @@ -1259,6 +1356,34 @@ _No description available._ --- +## src/lib/highRiskLogger.js + +### `export function getHighRiskLogs()` + +Retrieve the current log array from localStorage. + +**Returns**: {Array} Array of log objects. + +--- + +### `export function logApprovedHighRiskTransaction(entry)` + +Append a new log entry for an approved high‑risk transaction. + +**Parameters** + +| Name | Description | +| --- | --- | +| `{Object}` | entry - Information about the transaction. Expected fields: { transactionId, riskLevel, riskScore, timestamp, details } | + +--- + +### `export function clearHighRiskLogs()` + +Clear all high‑risk logs (e.g., for debugging or user reset). + +--- + ## src/lib/import.js ### `export function parseBackup(jsonString)` @@ -1716,6 +1841,50 @@ Calculates current network-wide TPS and OPS averages --- +## src/lib/notificationChannels.js + +### `export const NOTIFICATION_CHANNEL =` + +_No description available._ + +--- + +### `export async function sendEmail(payload)` + +Send an email notification. + +**Parameters** + +| Name | Description | +| --- | --- | +| `{object}` | payload - { to, subject, body } | + +--- + +### `export async function sendWebhook(payload)` + +Send a webhook POST request. + +**Parameters** + +| Name | Description | +| --- | --- | +| `{object}` | payload - { url, data } | + +--- + +### `export async function sendSMS(payload)` + +Send an SMS notification. + +**Parameters** + +| Name | Description | +| --- | --- | +| `{object}` | payload - { to, message } | + +--- + ## src/lib/notifications.js ### `export const NOTIFICATION_TYPES =` @@ -1736,6 +1905,20 @@ _No description available._ --- +### `export const playSound = (type)` + +_No description available._ + +--- + +## src/lib/performance.ts + +### `export function initPerformanceMonitoring(userConfig: PerfConfig =` + +_No description available._ + +--- + ## src/lib/performanceMonitoring.js ### `export const PERFORMANCE_BUDGETS =` @@ -2070,6 +2253,61 @@ Calculate portfolio value in USD from account balances and prices. --- +## src/lib/region.ts + +### `export type Region = 'global' | 'europe' | 'north_america' | 'asia' | 'custom'` + +_No description available._ + +--- + +### `export const REGION_NETWORK_MAP: Record rate. + +--- + +## src/lib/riskWhitelist.js + +### `export const whitelist = loadWhitelist()` + +_No description available._ + +--- + +### `export function isWhitelistedAddress(address)` + +Returns true if the address is in the whitelist. + +--- + +### `export function addWhitelistedAddress(address)` + +Adds an address to the whitelist and persists it. + +--- + +### `export function removeWhitelistedAddress(address)` + +Removes an address from the whitelist. + +--- + ## src/lib/searchEngine.ts ### `export class SearchEngine` @@ -2132,6 +2370,12 @@ Record a security-significant event. ## src/lib/stellar.ts +### `export function getSimulationFeeOptions(` + +_No description available._ + +--- + ### `export type NetworkName = 'mainnet' | 'testnet' | 'futurenet' | 'local' | 'custom'` _No description available._ @@ -2247,6 +2491,12 @@ Load profiles from storage and return them (Issue #188). --- +### `export async function fetchTransactionDetails(` + +Load profiles from storage and return them (Issue #188). + +--- + ### `export const OPERATION_LABELS: Record =` Load profiles from storage and return them (Issue #188). @@ -2513,7 +2763,7 @@ Calculate account reserves based on Stellar network base reserve --- -### `export async function invokeContract(` +### `export async function invokeContract(params: InvokeContractParams): Promise` Calculate account reserves based on Stellar network base reserve @@ -2547,7 +2797,7 @@ Check if address is a federated address (name*domain or name --- -### `export function parseMuxedAccount(muxedAddress: string):` +### `export function parseMuxedAccount(` Extract master account and muxed ID from a muxed address @@ -2641,7 +2891,7 @@ Human-readable summary of a claimant predicate. --- -### `export type BuilderOperation = PaymentOperation | CreateAccountOperation | InvokeHostFunctionOperation` +### `export type BuilderOperation =` Human-readable summary of a claimant predicate. @@ -2671,7 +2921,7 @@ Human-readable summary of a claimant predicate. --- -### `export async function simulateTransaction(` +### `export async function simulateTransaction(params: BuildTransactionParams): Promise` Human-readable summary of a claimant predicate. @@ -3060,6 +3310,24 @@ Clear the entire offline queue. --- +### `export async function addContractInteraction(record)` + +Clear the entire offline queue. + +--- + +### `export async function getContractInteractions(filters =` + +Clear the entire offline queue. + +--- + +### `export async function clearContractInteractions()` + +Clear the entire offline queue. + +--- + ### `export async function storageStats()` Estimate the number of entries in each store. @@ -3156,6 +3424,12 @@ _No description available._ --- +### `export const useStore = create((set, get)` + +_No description available._ + +--- + ## src/lib/streaming.js ### `export const ledgerStreamManager = new StreamManager()` @@ -3290,6 +3564,14 @@ Generate a one-click deployment config for a template. --- +## src/lib/thresholds.js + +### `export const THRESHOLDS =` + +_No description available._ + +--- + ## src/lib/transactionBuilder.js ### `export const OPERATION_TYPES = [` @@ -3350,6 +3632,56 @@ Build a fee-bump transaction wrapping a signed inner transaction. --- +## src/lib/transactionNotifications.ts + +### `export interface TransactionNotification` + +Transaction Real-Time Notification System (#295) + +Integrates with Stellar's streaming API to provide real-time notifications +for incoming transactions on monitored accounts. Supports mainnet and testnet +with automatic network switching. + +Features: +- Real-time updates via Stellar Horizon SSE API +- Toast notifications for new transactions +- Optional sound alerts +- Notification history panel (10+ notifications retained) +- Network-aware (mainnet/testnet) + +--- + +### `export const transactionNotificationStore = new TransactionNotificationStore()` + +Export notifications as CSV + +--- + +## src/lib/transactionSigningAuditLog.ts + +### `export interface SigningAuditEntry` + +Transaction Signing Audit Log (#310) + +Comprehensive audit log for all transaction signing operations. +Provides security/compliance tracking with timestamp, user tracking, +signing status, and export capabilities. + +Features: +- Log all signing operations (approved/rejected) +- Timestamp and user tracking +- Tamper-proof implementation using hashing +- Export to JSON/CSV formats +- Query and filtering capabilities + +--- + +### `export const transactionSigningAuditLog = new TransactionSigningAuditLog()` + +Get entry count + +--- + ## src/lib/transactionTemplateVault.ts ### `export interface TransactionTemplateOperation` diff --git a/docs/api/generated/VERSION_HISTORY.md b/docs/api/generated/VERSION_HISTORY.md index 21d783d7..343aff16 100644 --- a/docs/api/generated/VERSION_HISTORY.md +++ b/docs/api/generated/VERSION_HISTORY.md @@ -9,4 +9,4 @@ Generated from `package.json` version **0.1.0** on 2026-06-02. ## Current package version - version: **0.1.0** -- generated: 2026-06-02T09:17:29.565Z +- generated: 2026-06-02T11:17:56.438Z diff --git a/docs/api/openapi.yaml b/docs/api/openapi.yaml new file mode 100644 index 00000000..28f93c5d --- /dev/null +++ b/docs/api/openapi.yaml @@ -0,0 +1,899 @@ +openapi: 3.0.3 +info: + title: Stellar Dev Dashboard Integrations API + description: | + Comprehensive documentation and OpenAPI specification for the API integration points utilized by the Stellar Dev Dashboard. + + This specification covers: + - **Stellar Horizon REST API**: The primary gateway for ledger queries, account details, paginated transactions/operations lists, order books, and transaction submission. + - **Stellar Soroban RPC API**: The JSON-RPC service utilized for smart contract inspection, transaction simulations, transaction preparation, and contract-specific events. + - **CoinGecko API**: Utilized to fetch real-time USD asset price quotes and calculate portfolio valuation. + - **Stellar Friendbot Faucet**: The Testnet funding service that deposits 10,000 XLM into newly generated developer accounts. + version: 0.1.0 + contact: + name: Stellar Dev Dashboard Team + url: https://github.com/Nanle-code/stellar-dev-dashboard +servers: + - url: https://horizon-testnet.stellar.org + description: Horizon Testnet Server + - url: https://horizon.stellar.org + description: Horizon Mainnet Server + - url: https://soroban-testnet.stellar.org + description: Soroban RPC Testnet Server + - url: https://api.coingecko.com + description: CoinGecko Price API Server + - url: https://friendbot.stellar.org + description: Friendbot Faucet Server + +paths: + # ──────────────────────────────────────────────────────────────────────────── + # HORIZON ENDPOINTS + # ──────────────────────────────────────────────────────────────────────────── + /accounts/{accountId}: + get: + tags: + - Horizon (REST) + summary: Retrieve Account Details + description: Fetches account balances, thresholds, signers, sequence number, subentry counts, and flags for a given Stellar public key. + parameters: + - name: accountId + in: path + required: true + description: A valid G... Stellar public key (ED25519) + schema: + type: string + pattern: '^G[A-Z2-7]{55}$' + example: GD3W47O7L6J22XCQNFSK3L2V3N45EPEHPEH4J46EPEH4J46EPEH4J46E + responses: + '200': + description: Successful account retrieval + content: + application/json: + schema: + $ref: '#/components/schemas/AccountResponse' + '400': + description: Bad request (Invalid public key format) + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Account not found on the specified network + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '429': + description: Horizon API rate limit exceeded + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + + /accounts/{accountId}/transactions: + get: + tags: + - Horizon (REST) + summary: Retrieve Account Transactions + description: Fetches a paginated list of transactions involving the specified Stellar account. + parameters: + - name: accountId + in: path + required: true + description: The Stellar account ID + schema: + type: string + pattern: '^G[A-Z2-7]{55}$' + - name: limit + in: query + required: false + description: Number of records to return (1-200) + schema: + type: integer + default: 20 + minimum: 1 + maximum: 200 + - name: order + in: query + required: false + description: Ordering of results (ascending or descending) + schema: + type: string + enum: [asc, desc] + default: desc + - name: cursor + in: query + required: false + description: A paging token pointing to a specific transaction position + schema: + type: string + responses: + '200': + description: Paginated transaction list + content: + application/json: + schema: + $ref: '#/components/schemas/TransactionListResponse' + '400': + description: Invalid request parameters + '404': + description: Account not found + + /accounts/{accountId}/operations: + get: + tags: + - Horizon (REST) + summary: Retrieve Account Operations + description: Fetches a paginated list of operations executed under the specified Stellar account. + parameters: + - name: accountId + in: path + required: true + description: The Stellar account ID + schema: + type: string + pattern: '^G[A-Z2-7]{55}$' + - name: limit + in: query + required: false + description: Number of records to return (1-200) + schema: + type: integer + default: 20 + - name: order + in: query + required: false + description: Ordering of results + schema: + type: string + enum: [asc, desc] + default: desc + - name: cursor + in: query + required: false + description: Paging token + schema: + type: string + responses: + '200': + description: Paginated operations list + content: + application/json: + schema: + $ref: '#/components/schemas/OperationListResponse' + + /ledgers/{sequence}: + get: + tags: + - Horizon (REST) + summary: Retrieve Ledger Details + description: Fetches metadata for a single ledger block using its sequence number. + parameters: + - name: sequence + in: path + required: true + description: The ledger sequence number + schema: + type: integer + example: 54932011 + responses: + '200': + description: Ledger block details + content: + application/json: + schema: + $ref: '#/components/schemas/LedgerResponse' + '404': + description: Ledger block not found + + /ledgers: + get: + tags: + - Horizon (REST) + summary: List Latest Ledgers + description: Fetches a list of the latest ledgers on the network. Used by the network stats panel. + parameters: + - name: limit + in: query + required: false + schema: + type: integer + default: 10 + - name: order + in: query + required: false + schema: + type: string + enum: [asc, desc] + default: desc + responses: + '200': + description: List of recent ledgers + content: + application/json: + schema: + type: object + properties: + _embedded: + type: object + properties: + records: + type: array + items: + $ref: '#/components/schemas/LedgerResponse' + + /order_book: + get: + tags: + - Horizon (REST) + summary: Retrieve DEX Order Book + description: Fetches bids, asks, and midpoints for a trading pair on the Stellar Decentralized Exchange (SDEX). + parameters: + - name: selling_asset_type + in: query + required: true + schema: + type: string + enum: [native, credit_alphanum4, credit_alphanum12] + - name: selling_asset_code + in: query + required: false + description: Required if selling asset is not native (e.g. USDC) + schema: + type: string + - name: selling_asset_issuer + in: query + required: false + description: Required if selling asset is not native + schema: + type: string + - name: buying_asset_type + in: query + required: true + schema: + type: string + enum: [native, credit_alphanum4, credit_alphanum12] + - name: buying_asset_code + in: query + required: false + schema: + type: string + - name: buying_asset_issuer + in: query + required: false + schema: + type: string + - name: limit + in: query + required: false + schema: + type: integer + default: 20 + responses: + '200': + description: Order book depth details + content: + application/json: + schema: + $ref: '#/components/schemas/OrderBookResponse' + + /paths/strict-send: + get: + tags: + - Horizon (REST) + summary: Find Strict-Send Payment Paths + description: Finds valid payment paths for a strict amount of a selling asset, identifying target assets and conversion rates. + parameters: + - name: source_asset_type + in: query + required: true + schema: + type: string + - name: source_amount + in: query + required: true + schema: + type: string + - name: destination_assets + in: query + required: true + description: Comma separated list of target assets (e.g., native,USDC:G...) + schema: + type: string + responses: + '200': + description: Found strict-send payment paths + content: + application/json: + schema: + $ref: '#/components/schemas/PathsResponse' + + /paths/strict-receive: + get: + tags: + - Horizon (REST) + summary: Find Strict-Receive Payment Paths + description: Finds valid payment paths to deliver a strict amount of a buying asset. + parameters: + - name: destination_asset_type + in: query + required: true + schema: + type: string + - name: destination_amount + in: query + required: true + schema: + type: string + - name: source_assets + in: query + required: true + schema: + type: string + responses: + '200': + description: Found strict-receive payment paths + content: + application/json: + schema: + $ref: '#/components/schemas/PathsResponse' + + /transactions: + post: + tags: + - Horizon (REST) + summary: Submit Transaction to Network + description: Submits a fully formed, signed transaction envelope XDR string to the Stellar network via Horizon. + requestBody: + required: true + content: + application/x-www-form-urlencoded: + schema: + type: object + required: + - tx + properties: + tx: + type: string + description: Base64-encoded signed TransactionEnvelope XDR + example: AAAAAL56c9wJv68s... + responses: + '200': + description: Transaction successfully applied and included in a ledger block + content: + application/json: + schema: + $ref: '#/components/schemas/SubmitTransactionSuccess' + '400': + description: Transaction rejected (Failed validation, bad signature, or op errors) + content: + application/json: + schema: + $ref: '#/components/schemas/SubmitTransactionFailure' + + # ──────────────────────────────────────────────────────────────────────────── + # SOROBAN RPC ENDPOINTS + # ──────────────────────────────────────────────────────────────────────────── + /soroban/rpc: + post: + tags: + - Soroban (RPC) + summary: JSON-RPC Entry Point + description: General gateway for interacting with the Soroban smart contract virtual machine on Testnet and Mainnet. Supports custom JSON-RPC request methods. + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/SorobanRpcRequest' + examples: + getHealth: + summary: Health Check + value: + jsonrpc: "2.0" + id: "health-chk" + method: "getHealth" + getLatestLedger: + summary: Get Latest Ledger sequence + value: + jsonrpc: "2.0" + id: "ledg-chk" + method: "getLatestLedger" + simulateTransaction: + summary: Simulate Contract Invocation + value: + jsonrpc: "2.0" + id: "sim-1" + method: "simulateTransaction" + params: + transaction: "AAAAAgAAAADcR+U8..." + getEvents: + summary: Query Contract Events + value: + jsonrpc: "2.0" + id: "ev-1" + method: "getEvents" + params: + startLedger: 54930000 + filters: + - type: "contract" + contractIds: ["CBXG..."] + responses: + '200': + description: Standard JSON-RPC 2.0 Response payload + content: + application/json: + schema: + $ref: '#/components/schemas/SorobanRpcResponse' + + # ──────────────────────────────────────────────────────────────────────────── + # COINGECKO PRICE ENDPOINT + # ──────────────────────────────────────────────────────────────────────────── + /api/v3/simple/price: + get: + tags: + - External Services + summary: Fetch Asset Price Quotes + description: Fetches USD and price details for native and mapped credit assets from CoinGecko. Used for portfolio valuation. + parameters: + - name: ids + in: query + required: true + description: Comma separated CoinGecko coin identifiers (e.g. stellar) + schema: + type: string + example: stellar + - name: vs_currencies + in: query + required: true + description: target currencies (e.g. usd) + schema: + type: string + example: usd + - name: include_24hr_change + in: query + required: false + schema: + type: boolean + default: true + responses: + '200': + description: Asset price maps + content: + application/json: + schema: + type: object + additionalProperties: + type: object + properties: + usd: + type: number + example: 0.1145 + usd_24h_change: + type: number + example: 3.456 + + # ──────────────────────────────────────────────────────────────────────────── + # FRIENDBOT ENDPOINT + # ──────────────────────────────────────────────────────────────────────────── + /friendbot: + get: + tags: + - External Services + summary: Friendbot Faucet funding (Testnet Only) + description: Deposits 10,000 Testnet XLM to a valid, inactive or active Stellar public key. + parameters: + - name: addr + in: query + required: true + description: Public key (G...) to fund + schema: + type: string + pattern: '^G[A-Z2-7]{55}$' + responses: + '200': + description: Faucet deposit successfully executed + content: + application/json: + schema: + type: object + properties: + hash: + type: string + example: a0fb4cf... + ledger: + type: integer + example: 5493201 + +components: + schemas: + # ─── Horizon Schemas ────────────────────────────────────────────────────── + AccountResponse: + type: object + properties: + id: + type: string + example: GD3W47O7L6J22XCQNFSK3L2V3N45EPEHPEH4J46EPEH4J46EPEH4J46E + account_id: + type: string + example: GD3W47O7L6J22XCQNFSK3L2V3N45EPEHPEH4J46EPEH4J46EPEH4J46E + sequence: + type: string + example: "125893021482" + subentry_count: + type: integer + example: 4 + balances: + type: array + items: + type: object + properties: + balance: + type: string + example: "100.5402391" + limit: + type: string + example: "922337203685.4775807" + buying_liabilities: + type: string + example: "0.0000000" + selling_liabilities: + type: string + example: "0.0000000" + asset_type: + type: string + enum: [native, credit_alphanum4, credit_alphanum12, liquidity_pool_shares] + asset_code: + type: string + example: USDC + asset_issuer: + type: string + example: GBBDQ... + thresholds: + type: object + properties: + low_threshold: + type: integer + example: 0 + med_threshold: + type: integer + example: 1 + high_threshold: + type: integer + example: 2 + flags: + type: object + properties: + auth_required: + type: boolean + example: false + auth_revocable: + type: boolean + example: false + auth_immutable: + type: boolean + example: false + auth_clawback_enabled: + type: boolean + example: true + signers: + type: array + items: + type: object + properties: + key: + type: string + example: GD3W47O... + weight: + type: integer + example: 1 + type: + type: string + example: ed25519_public_key + + TransactionListResponse: + type: object + properties: + _embedded: + type: object + properties: + records: + type: array + items: + $ref: '#/components/schemas/TransactionRecord' + + TransactionRecord: + type: object + properties: + id: + type: string + example: 8c3bcf52... + hash: + type: string + example: 8c3bcf5273f7c469b61d4ff1ee8deabfe64e... + ledger: + type: integer + example: 5493201 + created_at: + type: string + format: date-time + example: 2026-06-01T15:20:00Z + source_account: + type: string + example: GD3W47O... + successful: + type: boolean + example: true + operation_count: + type: integer + example: 1 + envelope_xdr: + type: string + example: AAAAAL56c9wJv68s... + result_xdr: + type: string + example: AAAAAA... + fee_charged: + type: string + example: "100" + memo_type: + type: string + example: text + memo: + type: string + example: funding_tx + + OperationListResponse: + type: object + properties: + _embedded: + type: object + properties: + records: + type: array + items: + $ref: '#/components/schemas/OperationRecord' + + OperationRecord: + type: object + properties: + id: + type: string + example: "23594820934" + paging_token: + type: string + example: "23594820934-0" + type: + type: string + example: payment + type_i: + type: integer + example: 1 + source_account: + type: string + example: GD3W47O... + created_at: + type: string + format: date-time + amount: + type: string + example: "10.0000000" + asset_type: + type: string + example: native + + LedgerResponse: + type: object + properties: + id: + type: string + example: "7c5e2..." + sequence: + type: integer + example: 5493201 + hash: + type: string + example: 7c5e23924fbc... + prev_hash: + type: string + closed_at: + type: string + format: date-time + transaction_count: + type: integer + example: 12 + operation_count: + type: integer + example: 24 + base_fee_in_stroops: + type: integer + example: 100 + base_reserve_in_stroops: + type: integer + example: 5000000 + max_tx_set_size: + type: integer + example: 1000 + + OrderBookResponse: + type: object + properties: + bids: + type: array + items: + type: object + properties: + price: + type: string + example: "0.1143000" + amount: + type: string + example: "5000.0000000" + asks: + type: array + items: + type: object + properties: + price: + type: string + example: "0.1145000" + amount: + type: string + example: "12500.0000000" + base: + type: object + properties: + asset_type: + type: string + example: native + counter: + type: object + properties: + asset_type: + type: string + example: credit_alphanum4 + asset_code: + type: string + example: USDC + + PathsResponse: + type: object + properties: + _embedded: + type: object + properties: + records: + type: array + items: + type: object + properties: + source_asset_type: + type: string + source_amount: + type: string + destination_asset_type: + type: string + destination_amount: + type: string + path: + type: array + items: + type: object + properties: + asset_type: + type: string + + SubmitTransactionSuccess: + type: object + properties: + id: + type: string + example: 8c3bcf5273f7c469... + hash: + type: string + example: 8c3bcf5273f7c469b61d4ff1ee8deabfe64e... + ledger: + type: integer + example: 5493201 + envelope_xdr: + type: string + result_xdr: + type: string + example: AAAAAAAAAAG= + + SubmitTransactionFailure: + type: object + properties: + type: + type: string + example: https://stellar.org/horizon-errors/transaction_failed + title: + type: string + example: Transaction Failed + status: + type: integer + example: 400 + detail: + type: string + example: The transaction execution failed on the ledger. + extras: + type: object + properties: + envelope_xdr: + type: string + result_xdr: + type: string + example: AAAAAAAAAHwAAAAAA... + result_codes: + type: object + properties: + transaction: + type: string + example: tx_failed + operations: + type: array + items: + type: string + example: ["op_no_destination"] + + ErrorResponse: + type: object + properties: + type: + type: string + example: https://stellar.org/horizon-errors/not_found + title: + type: string + example: Resource Missing + status: + type: integer + example: 404 + detail: + type: string + example: The resource could not be found. + + # ─── Soroban Schemas ────────────────────────────────────────────────────── + SorobanRpcRequest: + type: object + required: + - jsonrpc + - id + - method + properties: + jsonrpc: + type: string + enum: ["2.0"] + example: "2.0" + id: + type: string + example: "req-1" + method: + type: string + enum: [getHealth, getLatestLedger, simulateTransaction, sendTransaction, getEvents] + example: simulateTransaction + params: + type: object + + SorobanRpcResponse: + type: object + required: + - jsonrpc + - id + properties: + jsonrpc: + type: string + example: "2.0" + id: + type: string + example: "req-1" + result: + type: object + error: + type: object + properties: + code: + type: integer + example: -32600 + message: + type: string + example: Invalid Request diff --git a/scripts/generate-api-docs.mjs b/scripts/generate-api-docs.mjs index 6ea87682..9287010f 100644 --- a/scripts/generate-api-docs.mjs +++ b/scripts/generate-api-docs.mjs @@ -203,6 +203,19 @@ async function generate() { await fs.mkdir(OUTPUT_DIR, { recursive: true }) const files = await collectSourceFiles(SOURCE_ROOT) + // Update openapi.yaml version in sync with package.json + const packageJson = JSON.parse(await fs.readFile(path.join(ROOT, 'package.json'), 'utf8')) + const version = packageJson.version || '0.1.0' + const openApiFilePath = path.join(ROOT, 'docs', 'api', 'openapi.yaml') + try { + let openApiContent = await fs.readFile(openApiFilePath, 'utf8') + openApiContent = openApiContent.replace(/(version:\s*['"]?)\d+\.\d+\.\d+(['"]?)/, `$1${version}$2`) + await fs.writeFile(openApiFilePath, openApiContent, 'utf8') + console.log('Updated OpenAPI spec version to:', version) + } catch (err) { + console.warn('Could not update OpenAPI spec version:', err.message) + } + const generatedSections = [] for (const filePath of files.sort()) { const content = await fs.readFile(filePath, 'utf8')