{"openapi":"3.1.0","info":{"title":"Nolus Protocol Webapp API","description":"Public REST API backing app.nolus.io. Read endpoints are cached and free to call; write endpoints return unsigned transaction payloads for client-side signing. Admin endpoints require API key auth and are intentionally omitted from this spec.","contact":{"name":"Nolus Protocol","url":"https://nolus.io/"},"license":{"name":"Apache-2.0"},"version":"1.0.0"},"servers":[{"url":"https://app.nolus.io","description":"Production"},{"url":"https://app-dev.nolus.io","description":"Staging"}],"paths":{"/api/assets":{"get":{"tags":["assets"],"summary":"List deduplicated assets","description":"Returns deduplicated assets with display prices from each primary protocol's\nOracle. Served from a background-refreshed cache (zero latency).","operationId":"get_assets","responses":{"200":{"description":"Asset catalog","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetsResponse"}}}},"503":{"description":"Cache not yet populated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/assets/{ticker}":{"get":{"tags":["assets"],"summary":"Get a single asset","description":"Returns a single asset with full details including per-protocol info and\nOracle prices.","operationId":"get_asset","parameters":[{"name":"ticker","in":"path","description":"Asset ticker (e.g., `ATOM`, `OSMO`)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Asset detail","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetDetailResponse"}}}},"404":{"description":"Asset not found or not configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Cache not yet populated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/balances":{"get":{"tags":["balances"],"summary":"Get wallet balances","description":"Returns visible balances (configured, non-ignored currencies) for a Nolus\nwallet address along with aggregated USD value. Requires a `nolus1`-prefixed\nbech32 address.","operationId":"get_balances","parameters":[{"name":"address","in":"query","description":"The wallet address (accepts \"address\", \"owner\", or \"delegator\")","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Wallet balances","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BalancesResponse"}}}},"400":{"description":"Invalid address","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Cache not yet populated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/campaigns/active":{"get":{"tags":["campaigns"],"summary":"Get active zero-interest campaigns","description":"Returns all currently active zero-interest campaigns. Used by the frontend\nto decide which lease/deposit actions to badge as zero-interest.","operationId":"get_active_campaigns","responses":{"200":{"description":"Active campaigns","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActiveCampaignsResponse"}}}},"502":{"description":"Upstream payments manager error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/campaigns/eligibility":{"get":{"tags":["campaigns"],"summary":"Check campaign eligibility","description":"Checks whether a wallet/protocol/currency combination is eligible for any\nzero-interest campaign and returns the matching campaigns.","operationId":"check_campaign_eligibility","parameters":[{"name":"wallet","in":"query","description":"Wallet address to check.","required":true,"schema":{"type":"string"}},{"name":"protocol","in":"query","description":"Optional protocol name (filters matching campaigns).","required":false,"schema":{"type":["string","null"]}},{"name":"currency","in":"query","description":"Optional currency ticker (filters matching campaigns).","required":false,"schema":{"type":["string","null"]}}],"responses":{"200":{"description":"Eligibility result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignEligibilityResponse"}}}},"502":{"description":"Upstream payments manager error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/config":{"get":{"tags":["config"],"summary":"Get full application configuration","description":"Returns protocols, networks, the native asset, and top-level contracts in a\nsingle payload. Served from a background-refreshed cache (zero latency).","operationId":"get_config","responses":{"200":{"description":"Application configuration","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppConfigResponse"}}}},"503":{"description":"Config cache not yet populated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/config/networks":{"get":{"tags":["config"],"summary":"Get configured networks","description":"Returns the networks section of the application configuration.","operationId":"get_networks","responses":{"200":{"description":"List of configured networks","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/NetworkInfo"}}}}},"503":{"description":"Config cache not yet populated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/config/protocols":{"get":{"tags":["config"],"summary":"Get configured protocols","description":"Returns the protocols section of the application configuration.","operationId":"get_protocols","responses":{"200":{"description":"Protocol map keyed by protocol name","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/ProtocolInfo"},"propertyNames":{"type":"string"}}}}},"503":{"description":"Config cache not yet populated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/currencies":{"get":{"tags":["currencies"],"summary":"List all currencies","description":"Returns supported currencies with metadata, LPNs, lease-able tickers, and\nalias map. Served from cache.","operationId":"get_currencies","responses":{"200":{"description":"Currencies catalog","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CurrenciesResponse"}}}},"503":{"description":"Cache not yet populated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/currencies/{key}":{"get":{"tags":["currencies"],"summary":"Get a single currency","description":"Looks up a currency by key (`TICKER@PROTOCOL`) or plain ticker.","operationId":"get_currency","parameters":[{"name":"key","in":"path","description":"Currency key (`TICKER@PROTOCOL`) or plain ticker","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Currency info","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CurrencyInfo"}}}},"404":{"description":"Currency not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/earn/deposit":{"post":{"tags":["earn"],"summary":"Build a deposit transaction","description":"Returns unsigned CosmWasm execute messages to deposit funds into an earn\npool. The client fills in the sender address and denom before signing.","operationId":"deposit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DepositRequest"}}},"required":true},"responses":{"200":{"description":"Unsigned deposit transaction","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EarnTransactionResponse"}}}},"404":{"description":"Protocol not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Cache not yet populated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/earn/pools":{"get":{"tags":["earn"],"summary":"List all earn pools","description":"Returns every configured earn pool with current APY, utilization, available\nliquidity, and remaining deposit capacity. Served from a background-refreshed\ncache and filtered by gated configuration.","operationId":"get_pools","responses":{"200":{"description":"List of earn pools","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EarnPool"}}}}},"503":{"description":"Cache not yet populated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/earn/pools/{pool_id}":{"get":{"tags":["earn"],"summary":"Get a single earn pool","description":"Returns details for a specific pool identified by protocol key. Returns 404\nif the protocol is not configured in gated config.","operationId":"get_pool","parameters":[{"name":"pool_id","in":"path","description":"Protocol key (e.g. `OSMOSIS-OSMOSIS-USDC_NOBLE`)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Earn pool details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EarnPool"}}}},"404":{"description":"Pool not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Cache not yet populated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/earn/positions":{"get":{"tags":["earn"],"summary":"Get earn positions for an owner","description":"Returns all earn positions across configured pools for the given address,\nplus aggregated total in USD. Unconfigured protocols are filtered out.","operationId":"get_positions","parameters":[{"name":"address","in":"query","description":"The wallet address (accepts \"address\", \"owner\", or \"delegator\")","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Earn positions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EarnPositionsResponse"}}}},"400":{"description":"Invalid address","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Cache not yet populated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/earn/stats":{"get":{"tags":["earn"],"summary":"Get overall earn statistics","description":"Returns aggregated earn metrics: total value locked, active pool count,\naverage APY, and the dispatcher rewards rate. TVL and pool data come from\nETL; the dispatcher rewards rate comes from on-chain (optional).","operationId":"get_earn_stats","responses":{"200":{"description":"Earn statistics","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EarnStats"}}}}}}},"/api/earn/withdraw":{"post":{"tags":["earn"],"summary":"Build a withdraw transaction","description":"Returns unsigned CosmWasm execute messages to burn nLPN receipt tokens and\nwithdraw the underlying LPN value from an earn pool.","operationId":"withdraw","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WithdrawRequest"}}},"required":true},"responses":{"200":{"description":"Unsigned withdraw transaction","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EarnTransactionResponse"}}}},"404":{"description":"Protocol not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Cache not yet populated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/etl/batch/loans-stats":{"get":{"tags":["etl"],"summary":"Loans stats batch","description":"Aggregates loan stats endpoints into one response, served from\nbackground-refreshed cache. Each field is an opaque ETL passthrough.","operationId":"batch_loans_stats","responses":{"200":{"description":"Batch of opaque ETL passthroughs","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoansStatsBatch"}}}},"503":{"description":"Cache not yet populated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/etl/batch/stats-overview":{"get":{"tags":["etl"],"summary":"Stats overview batch","description":"Aggregates several ETL stats endpoints into one response, served from\nbackground-refreshed cache. Each field is an opaque ETL passthrough.","operationId":"batch_stats_overview","responses":{"200":{"description":"Batch of opaque ETL passthroughs","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatsOverviewBatch"}}}},"503":{"description":"Cache not yet populated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/etl/batch/user-dashboard":{"get":{"tags":["etl"],"summary":"User dashboard batch","description":"Aggregates earnings, realized PnL, and position debt for an address in\nparallel. Each field is an opaque ETL passthrough.","operationId":"batch_user_dashboard","parameters":[{"name":"address","in":"query","description":"Nolus bech32 address","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Batch of opaque ETL passthroughs","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDashboardBatch"}}}},"502":{"description":"Upstream ETL call failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/etl/batch/user-history":{"get":{"tags":["etl"],"summary":"User history batch","description":"Aggregates history stats and realized PnL data for an address in parallel.\nEach field is an opaque ETL passthrough.","operationId":"batch_user_history","parameters":[{"name":"address","in":"query","description":"Nolus bech32 address","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Batch of opaque ETL passthroughs","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserHistoryBatch"}}}},"502":{"description":"Upstream ETL call failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/etl/subscribe":{"post":{"tags":["etl"],"summary":"Subscribe to push notifications","description":"Opaque passthrough to the ETL `/subscribe` endpoint. Request and response\nbodies are opaque JSON — shapes are not fixed in this spec.","operationId":"proxy_subscribe","requestBody":{"description":"Opaque ETL subscribe payload","content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Opaque ETL API passthrough","content":{"application/json":{"schema":{"type":"object"}}}},"502":{"description":"Upstream ETL call failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/etl/txs":{"get":{"tags":["transactions"],"summary":"Enriched transactions","description":"Fetches raw transactions from the ETL `/api/txs` endpoint, filters\nuser-initiated message types, and inserts a decoded `data` field per\ntransaction by decoding the protobuf `value`. Each entry is otherwise an\nopaque ETL passthrough — shape is not fixed in this spec.","operationId":"get_enriched_transactions","parameters":[{"name":"address","in":"query","description":"Wallet address to filter by","required":false,"schema":{"type":"string"}},{"name":"skip","in":"query","description":"Pagination offset","required":false,"schema":{"type":"integer","format":"int32","minimum":0}},{"name":"limit","in":"query","description":"Page size","required":false,"schema":{"type":"integer","format":"int32","minimum":0}},{"name":"filter","in":"query","description":"Free-form filter passed to ETL","required":false,"schema":{"type":"string"}},{"name":"to","in":"query","description":"Upper-bound timestamp","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"List of enriched transactions (opaque entries)","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"}}}}},"502":{"description":"Upstream ETL call failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/etl/{path}":{"get":{"tags":["etl"],"summary":"Generic ETL passthrough","description":"Forwards GET requests to the upstream ETL API for a fixed allowlist of\npaths. Query parameters are passed through verbatim. Response is an opaque\nETL API passthrough — shape is not fixed in this spec.","operationId":"etl_proxy_generic","parameters":[{"name":"path","in":"path","description":"Target ETL endpoint (allowlisted server-side)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Opaque ETL API passthrough","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"description":"ETL endpoint not in allowlist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"Upstream ETL call failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/fees/gas-config":{"get":{"tags":["fees"],"summary":"Get gas fee configuration","description":"Returns accepted fee denoms with their minimum gas prices plus the gas\nestimate multiplier used by the app.","operationId":"get_gas_fee_config","responses":{"200":{"description":"Gas fee configuration","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GasFeeConfigResponse"}}}},"503":{"description":"Cache not yet populated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/governance/accounts/{address}":{"get":{"tags":["governance"],"summary":"Get account info","description":"Returns the raw auth account object for an address, used to detect vesting\naccounts and derive spendable balances.","operationId":"get_account","parameters":[{"name":"address","in":"path","description":"Nolus bech32 address","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Account (shape depends on account type)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountResponse"}}}},"502":{"description":"Upstream chain RPC error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/governance/apr":{"get":{"tags":["governance"],"summary":"Get APR","description":"Combines annual inflation and staking-pool bonded tokens so the frontend can\nrender a staking APR figure.","operationId":"get_apr","responses":{"200":{"description":"APR inputs","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AprResponse"}}}},"503":{"description":"Cache not yet populated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/governance/denoms/{denom}":{"get":{"tags":["governance"],"summary":"Get denom metadata","description":"Returns bank-module metadata (units, display, description) for a denom, or\n`null` if the chain has no metadata registered for it.","operationId":"get_denom_metadata","parameters":[{"name":"denom","in":"path","description":"Bank denom (e.g. `unls`, `ibc/...`)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Denom metadata (nullable)","content":{"application/json":{"schema":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/DenomMetadata"}]}}}},"502":{"description":"Upstream chain RPC error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/governance/hidden-proposals":{"get":{"tags":["governance"],"summary":"Get hidden proposal IDs","description":"Returns proposal IDs that should be hidden in the UI (curated via gated config).","operationId":"get_hidden_proposals","responses":{"200":{"description":"List of hidden proposal IDs","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HiddenProposalsResponse"}}}},"503":{"description":"Gated config cache not yet populated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/governance/params/tallying":{"get":{"tags":["governance"],"summary":"Get governance tallying params","description":"Returns quorum / threshold / veto-threshold parameters used to decide proposals.","operationId":"get_tallying_params","responses":{"200":{"description":"Tallying parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TallyingParamsResponse"}}}},"502":{"description":"Upstream chain RPC error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/governance/proposals":{"get":{"tags":["governance"],"summary":"List governance proposals","description":"Returns governance proposals in reverse-chronological order from the\nbackground-refreshed cache. The response carries `Cache-Status: warm`\n(with a `Cache-Age` value in seconds) once the refresh task has populated\nthe cache, or `Cache-Status: cold` with an empty list before the first\nrefresh completes — never 503 — so the frontend's `Promise.allSettled`\nflow can render an empty state without a coordinated rollout.\n\nHidden proposals from the gated UI config are filtered at request time\nagainst the latest config; cached tallies are attached for voting-period\nproposals. The fresh tally for a single proposal is available on the\nper-id `/proposals/{id}/tally` endpoint, which still queries the chain\ndirectly. `?voter=` triggers a live `get_proposal_vote` fan-out across\nvoting-period proposals only — a chain failure on any of those calls\nsurfaces as 502.","operationId":"get_proposals","parameters":[{"name":"limit","in":"query","description":"Maximum number of proposals to return (defaults to 10).","required":false,"schema":{"type":["integer","null"],"format":"int32","minimum":0}},{"name":"voter","in":"query","description":"Voter address — when supplied, each voting-period proposal is annotated with `voted`.","required":false,"schema":{"type":["string","null"]}}],"responses":{"200":{"description":"Paginated list of proposals","headers":{"Cache-Age":{"schema":{"type":"string"},"description":"Age in seconds of the cached snapshot. Present on `warm` responses, omitted on `cold`."},"Cache-Status":{"schema":{"type":"string"},"description":"`warm` when served from the background-refreshed cache, `cold` before the first refresh has populated it (response body is then an empty list)."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProposalsListResponse"}}}},"502":{"description":"Upstream chain RPC error on live `?voter=` fan-out","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/governance/proposals/{proposal_id}/tally":{"get":{"tags":["governance"],"summary":"Get proposal tally","description":"Returns the current (live) tally for a proposal.","operationId":"get_proposal_tally","parameters":[{"name":"proposal_id","in":"path","description":"Governance proposal ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Tally for the given proposal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TallyResponse"}}}},"502":{"description":"Upstream chain RPC error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/governance/proposals/{proposal_id}/votes/{voter}":{"get":{"tags":["governance"],"summary":"Get a voter's vote for a proposal","description":"Returns the vote cast by `voter` on `proposal_id`, or `null` if the voter\nhas not voted on this proposal.","operationId":"get_proposal_vote","parameters":[{"name":"proposal_id","in":"path","description":"Governance proposal ID","required":true,"schema":{"type":"string"}},{"name":"voter","in":"path","description":"Voter bech32 address","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Vote (nullable if voter has not voted)","content":{"application/json":{"schema":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/VoteResponse"}]}}}},"502":{"description":"Upstream chain RPC error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/governance/staking-pool":{"get":{"tags":["governance"],"summary":"Get staking pool (bonded tokens)","description":"Returns the total bonded / not-bonded token supply — used to compute quorum and APR.","operationId":"get_staking_pool","responses":{"200":{"description":"Staking pool","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StakingPoolResponse"}}}},"503":{"description":"Cache not yet populated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/health":{"get":{"tags":["health"],"summary":"Basic health check","description":"Returns status, version and uptime. Fast, in-process — does not touch any\nexternal services.","operationId":"health_check","responses":{"200":{"description":"Service is up","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}}}}},"/api/health/detailed":{"get":{"tags":["health"],"summary":"Detailed health check","description":"Performs live connectivity checks to upstream services (ETL, Nolus RPC/REST,\nSkip, referral, zero-interest) in parallel and reports cache-warm status.\nSlower than `/api/health` — intended for monitoring rather than load\nbalancer probes.","operationId":"detailed_health_check","responses":{"200":{"description":"Detailed health snapshot","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DetailedHealthResponse"}}}}}}},"/api/intercom/hash":{"post":{"tags":["intercom"],"summary":"Generate Intercom JWT","description":"Generates an Intercom-compatible JWT for the given wallet address. All\nportfolio attributes (balance, leases, earn, staking, vesting) are fetched\nserver-side and embedded in the token — the client only supplies the\nwallet address and type.","operationId":"intercom_hash","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntercomTokenRequest"}}},"required":true},"responses":{"200":{"description":"Signed Intercom JWT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntercomTokenResponse"}}}},"400":{"description":"Invalid wallet address","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Cache not yet populated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/leases":{"get":{"tags":["leases"],"summary":"List leases for an owner","description":"Returns all leases for a given Nolus owner address, optionally filtered to a\nsingle protocol. Leases from non-configured protocols and assets blocked by\ngated restrictions (`ignore_all`, `ignore_long`, `ignore_short`) are omitted.","operationId":"get_leases","parameters":[{"name":"address","in":"query","description":"The wallet address (accepts \"address\" or \"owner\")","required":true,"schema":{"type":"string"}},{"name":"protocol","in":"query","description":"Filter by protocol name (optional)","required":false,"schema":{"type":["string","null"]}}],"responses":{"200":{"description":"Lease list with aggregated totals","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeasesResponse"}}}},"400":{"description":"Invalid address","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Cache not yet populated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/leases/close":{"post":{"tags":["leases"],"summary":"Build a close-lease transaction","description":"Returns unsigned `MsgExecuteContract` messages to fully close the specified\nlease position (full close of collateral).","operationId":"close_lease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CloseLeaseRequest"}}},"required":true},"responses":{"200":{"description":"Unsigned transaction messages","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeaseTransactionResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/leases/config/{protocol}":{"get":{"tags":["leases"],"summary":"Get lease configuration for a protocol","description":"Returns downpayment ranges and minimum asset/transaction amounts used to\nvalidate lease-open requests. Served from background-refreshed cache.","operationId":"get_lease_config","parameters":[{"name":"protocol","in":"path","description":"Protocol name (e.g. `osmosis-osmosis-usdc`)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Lease configuration for the protocol","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeaseConfigResponse"}}}},"404":{"description":"Protocol not configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Cache not yet populated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/leases/market-close":{"post":{"tags":["leases"],"summary":"Build a market-close transaction","description":"Returns unsigned `MsgExecuteContract` messages that market-close the lease\nby selling collateral to repay the outstanding debt.","operationId":"market_close_lease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketCloseRequest"}}},"required":true},"responses":{"200":{"description":"Unsigned transaction messages","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeaseTransactionResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/leases/open":{"post":{"tags":["leases"],"summary":"Build an open-lease transaction","description":"Returns unsigned `MsgExecuteContract` messages that the frontend wallet will\ncomplete (sender, IBC denom) and sign to open a new lease.","operationId":"open_lease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenLeaseRequest"}}},"required":true},"responses":{"200":{"description":"Unsigned transaction messages","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeaseTransactionResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Protocol not configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Cache not yet populated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/leases/quote":{"post":{"tags":["leases"],"summary":"Quote a prospective lease","description":"Queries the Leaser contract for the borrow amount and annual interest rate\nthat would result from opening a lease with the given downpayment.","operationId":"get_lease_quote","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeaseQuoteRequest"}}},"required":true},"responses":{"200":{"description":"Quote for the prospective lease","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeaseQuoteResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Protocol not configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Cache not yet populated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/leases/repay":{"post":{"tags":["leases"],"summary":"Build a repay-lease transaction","description":"Returns unsigned `MsgExecuteContract` messages to repay the specified amount\ntoward an existing lease.","operationId":"repay_lease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RepayLeaseRequest"}}},"required":true},"responses":{"200":{"description":"Unsigned transaction messages","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeaseTransactionResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/leases/{address}":{"get":{"tags":["leases"],"summary":"Get a single lease","description":"Returns full details for the specified lease. The `protocol` query parameter\nis required — the backend cannot infer it from the address alone and a wrong\ndefault would produce incorrect data for Short positions.","operationId":"get_lease","parameters":[{"name":"address","in":"path","description":"Lease contract address","required":true,"schema":{"type":"string"}},{"name":"protocol","in":"query","description":"Filter by protocol name (optional)","required":false,"schema":{"type":["string","null"]}}],"responses":{"200":{"description":"Lease details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeaseInfo"}}}},"400":{"description":"Missing or invalid protocol query parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Lease not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Cache not yet populated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/leases/{address}/history":{"get":{"tags":["leases"],"summary":"Get lease transaction history","description":"Returns the on-chain action history (open, repay, close, liquidation) for a\nlease, sourced from the ETL indexer. Returns an empty list if no history is\navailable.","operationId":"get_lease_history","parameters":[{"name":"address","in":"path","description":"Lease contract address","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Lease history entries","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LeaseHistoryEntry"}}}}}}}},"/api/locales/{lang}":{"get":{"tags":["locales"],"summary":"Get locale translations","description":"Returns the i18n translation blob for the requested language code. The\nresponse is an opaque JSON object keyed by translation keys — shape is not\nfixed in this spec.","operationId":"get_locale","parameters":[{"name":"lang","in":"path","description":"Language code (e.g. `en`, `de`, `es`). Max 5 chars, alphanumeric + hyphen.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Locale JSON blob (opaque object)","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Invalid language code","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Language not available","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/networks/gated":{"get":{"tags":["networks"],"summary":"List gated networks","description":"Returns all networks that pass the gated propagation filter (fully\nconfigured RPC/LCD/gas). Served from a background-refreshed cache.","operationId":"get_networks","responses":{"200":{"description":"Gated network list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NetworksResponse"}}}},"503":{"description":"Cache not yet populated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/networks/{network}/assets":{"get":{"tags":["networks"],"summary":"List assets on a network","description":"Returns assets available on a specific network, with prices taken from the\nnetwork's primary protocol when configured, else any available protocol.","operationId":"get_network_assets","parameters":[{"name":"network","in":"path","description":"Network key (e.g., `OSMOSIS`, `NEUTRON`)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Asset catalog for the network","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetsResponse"}}}},"404":{"description":"Network not found or not configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Cache not yet populated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/networks/{network}/info":{"get":{"tags":["networks"],"summary":"Get a single network","description":"Returns a single network's configuration (endpoints, prefix, gas,\nexplorer, primary protocol).","operationId":"get_network","parameters":[{"name":"network","in":"path","description":"Network key (e.g., `OSMOSIS`, `NEUTRON`)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Network configuration","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NetworkResponse"}}}},"404":{"description":"Network not found or not configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Cache not yet populated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/networks/{network}/pools":{"get":{"tags":["networks"],"summary":"List LPP pools on a network","description":"Returns LPP (Liquidity Pool) info for all configured protocols on the given\nnetwork, with APR, utilization, and supply/borrow totals from ETL.","operationId":"get_network_pools","parameters":[{"name":"network","in":"path","description":"Network key (e.g., `OSMOSIS`, `NEUTRON`)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Pool list for the network","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NetworkPoolsResponse"}}}},"404":{"description":"Network not found or not configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Cache not yet populated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/networks/{network}/protocols":{"get":{"tags":["networks"],"summary":"List protocols on a network","description":"Returns protocols filtered to a specific network and whose LPN currency is\nconfigured for display.","operationId":"get_network_protocols","parameters":[{"name":"network","in":"path","description":"Network key (e.g., `OSMOSIS`, `NEUTRON`)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Protocols on the network","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProtocolsResponse"}}}},"404":{"description":"Network not found or not configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Cache not yet populated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/node/info":{"get":{"tags":["node"],"summary":"Get node info","description":"Returns the chain software version and network identifier reported by the\nnode's ABCI info endpoint.","operationId":"get_node_info","responses":{"200":{"description":"Node info","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NodeInfoResponse"}}}},"502":{"description":"Upstream chain RPC error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/node/status":{"get":{"tags":["node"],"summary":"Get network status","description":"Returns latest block height/time and sync state for the Nolus RPC node.","operationId":"get_network_status","responses":{"200":{"description":"Network status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NetworkStatusResponse"}}}},"502":{"description":"Upstream chain RPC error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/prices":{"get":{"tags":["prices"],"summary":"Get current oracle prices","description":"Returns current USD prices for all supported currencies, aggregated from\non-chain Oracle contracts.","operationId":"get_prices","responses":{"200":{"description":"Oracle prices","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PricesResponse"}}}},"503":{"description":"Cache not yet populated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/protocols":{"get":{"tags":["protocols"],"summary":"List all protocols","description":"Returns the registry of Nolus DeFi sub-protocols (active and deprecated)\nwith contract addresses and lease/LPN metadata.","operationId":"get_protocols","responses":{"200":{"description":"Protocol registry with counts","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProtocolsResponse"}}}},"503":{"description":"Cache not yet populated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/protocols/active":{"get":{"tags":["protocols"],"summary":"List active protocols","description":"Returns only protocols where `is_active` is `true`.","operationId":"get_active_protocols","responses":{"200":{"description":"Map of active protocols keyed by name","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/Protocol"},"propertyNames":{"type":"string"}}}}},"503":{"description":"Cache not yet populated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/protocols/gated":{"get":{"tags":["protocols"],"summary":"List gated protocols","description":"Returns all protocols that pass the gated propagation filter (configured\nnetwork, LPN, and currencies). Served from a background-refreshed cache.","operationId":"get_protocols","responses":{"200":{"description":"Gated protocol list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProtocolsResponse"}}}},"503":{"description":"Cache not yet populated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/protocols/{protocol}/currencies":{"get":{"tags":["protocols"],"summary":"List protocol currencies","description":"Returns currencies available on a given protocol with protocol-specific\nOracle prices. Filtered by currency display config and lease-rules asset\nrestrictions (`ignore_all`, `ignore_long`, `ignore_short`).","operationId":"get_protocol_currencies","parameters":[{"name":"protocol","in":"path","description":"Protocol name (e.g., `OSMOSIS-OSMOSIS-USDC_NOBLE`)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Protocol currencies with prices","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProtocolCurrenciesResponse"}}}},"404":{"description":"Protocol not found or not configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Cache not yet populated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/referral/assign":{"post":{"tags":["referral"],"summary":"Assign a referral","description":"Links `referred_wallet` to the referrer that owns `referral_code`. Fails if\nthe wallet already has a referrer, the code is unknown, or the wallet is\ntrying to self-refer.","operationId":"assign","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssignRequest"}}},"required":true},"responses":{"201":{"description":"Referral assigned","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssignResponse"}}}},"404":{"description":"Referral code not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"Referral service error or not configured (including already-assigned / self-referral conflicts)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/referral/payouts/{address}":{"get":{"tags":["referral"],"summary":"Get referrer payouts","description":"Returns paginated payouts for the referrer, with optional status filter.","operationId":"get_payouts","parameters":[{"name":"address","in":"path","description":"Referrer wallet address","required":true,"schema":{"type":"string"}},{"name":"status","in":"query","description":"Optional status filter (`pending`, `submitted`, `confirmed`, `failed`).","required":false,"schema":{"type":["string","null"]}},{"name":"limit","in":"query","description":"Max number of records.","required":false,"schema":{"type":["integer","null"],"format":"int64","minimum":0}},{"name":"offset","in":"query","description":"Pagination offset.","required":false,"schema":{"type":["integer","null"],"format":"int64","minimum":0}}],"responses":{"200":{"description":"Paginated payouts","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayoutsListResponse"}}}},"502":{"description":"Referral service error or not configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/referral/referrals/{address}":{"get":{"tags":["referral"],"summary":"Get referrals for a referrer","description":"Returns paginated referrals (referred wallets) attached to this referrer.","operationId":"get_referrals","parameters":[{"name":"address","in":"path","description":"Referrer wallet address","required":true,"schema":{"type":"string"}},{"name":"status","in":"query","description":"Optional status filter (`active`, `inactive`).","required":false,"schema":{"type":["string","null"]}},{"name":"limit","in":"query","description":"Max number of records.","required":false,"schema":{"type":["integer","null"],"format":"int64","minimum":0}},{"name":"offset","in":"query","description":"Pagination offset.","required":false,"schema":{"type":["integer","null"],"format":"int64","minimum":0}}],"responses":{"200":{"description":"Paginated referrals","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReferralsListResponse"}}}},"502":{"description":"Referral service error or not configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/referral/register":{"post":{"tags":["referral"],"summary":"Register as a referrer","description":"Registers the supplied wallet as a referrer and returns its referral code.\nResponds with `201 Created` for new registrations and `200 OK` when the\nwallet is already registered (idempotent).","operationId":"register","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterRequest"}}},"required":true},"responses":{"200":{"description":"Already registered (idempotent)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterResponse"}}}},"201":{"description":"Referrer created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterResponse"}}}},"502":{"description":"Referral service error or not configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/referral/rewards/{address}":{"get":{"tags":["referral"],"summary":"Get referrer rewards","description":"Returns paginated rewards earned by the referrer, with optional status filter.","operationId":"get_rewards","parameters":[{"name":"address","in":"path","description":"Referrer wallet address","required":true,"schema":{"type":"string"}},{"name":"status","in":"query","description":"Optional status filter (`pending`, `included`, `paid`).","required":false,"schema":{"type":["string","null"]}},{"name":"limit","in":"query","description":"Max number of records.","required":false,"schema":{"type":["integer","null"],"format":"int64","minimum":0}},{"name":"offset","in":"query","description":"Pagination offset.","required":false,"schema":{"type":["integer","null"],"format":"int64","minimum":0}}],"responses":{"200":{"description":"Paginated rewards","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RewardsListResponse"}}}},"502":{"description":"Referral service error or not configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/referral/stats/{address}":{"get":{"tags":["referral"],"summary":"Get referrer statistics","description":"Returns aggregated stats (totals, pending rewards, bonuses) for the\nreferrer identified by `address`.","operationId":"get_stats","parameters":[{"name":"address","in":"path","description":"Referrer wallet address","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Referrer stats","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReferrerStatsResponse"}}}},"404":{"description":"Referrer not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"Referral service error or not configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/referral/validate/{code}":{"get":{"tags":["referral"],"summary":"Validate a referral code","description":"Public endpoint — checks whether `code` is a live referral code and returns\nthe owning referrer's wallet if so.","operationId":"validate_code","parameters":[{"name":"code","in":"path","description":"Referral code to validate","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Validation result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidateCodeResponse"}}}},"502":{"description":"Referral service error or not configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/staking/claim-rewards":{"post":{"tags":["staking"],"summary":"Build a claim-rewards transaction","description":"Returns unsigned `MsgWithdrawDelegatorReward` messages, one per validator\naddress supplied.","operationId":"claim_rewards","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimRewardsRequest"}}},"required":true},"responses":{"200":{"description":"Unsigned claim-rewards transaction","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StakingTransactionResponse"}}}}}}},"/api/staking/delegate":{"post":{"tags":["staking"],"summary":"Build a delegate transaction","description":"Returns an unsigned `MsgDelegate` for client-side signing. The delegator\naddress is filled in by the frontend before broadcast.","operationId":"delegate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DelegateRequest"}}},"required":true},"responses":{"200":{"description":"Unsigned delegate transaction","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StakingTransactionResponse"}}}}}}},"/api/staking/params":{"get":{"tags":["staking"],"summary":"Get staking parameters","description":"Returns the chain's staking module parameters (unbonding time, max\nvalidators, bond denom, etc.).","operationId":"get_staking_params","responses":{"200":{"description":"Staking parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StakingParams"}}}}}}},"/api/staking/positions":{"get":{"tags":["staking"],"summary":"Get staking positions for a delegator","description":"Returns all delegations, unbonding entries, and pending rewards for a\ndelegator address, with aggregated totals.","operationId":"get_positions","parameters":[{"name":"address","in":"query","description":"The wallet address (accepts \"address\", \"owner\", or \"delegator\")","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Staking positions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StakingPositionsResponse"}}}},"400":{"description":"Invalid address","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/staking/redelegate":{"post":{"tags":["staking"],"summary":"Build a redelegate transaction","description":"Returns an unsigned `MsgBeginRedelegate` for moving stake between validators.","operationId":"redelegate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedelegateRequest"}}},"required":true},"responses":{"200":{"description":"Unsigned redelegate transaction","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StakingTransactionResponse"}}}}}}},"/api/staking/undelegate":{"post":{"tags":["staking"],"summary":"Build an undelegate transaction","description":"Returns an unsigned `MsgUndelegate` for client-side signing.","operationId":"undelegate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UndelegateRequest"}}},"required":true},"responses":{"200":{"description":"Unsigned undelegate transaction","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StakingTransactionResponse"}}}}}}},"/api/staking/validators":{"get":{"tags":["staking"],"summary":"List all validators","description":"Returns the validator set (bonded and non-bonded), served from a\nbackground-refreshed cache for zero latency.","operationId":"get_validators","responses":{"200":{"description":"List of validators","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Validator"}}}}},"503":{"description":"Cache not yet populated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/staking/validators/{address}":{"get":{"tags":["staking"],"summary":"Get a single validator","description":"Looks up a validator by its operator address (`nolusvaloper1...`).","operationId":"get_validator","parameters":[{"name":"address","in":"path","description":"Validator operator address (`nolusvaloper1...`)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Validator details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Validator"}}}},"404":{"description":"Validator not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Cache not yet populated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/swap/chains":{"get":{"tags":["swap"],"summary":"List supported swap chains","description":"Proxies Skip `/v2/info/chains`. Response is an opaque Skip API\npassthrough — shape is not fixed in this spec.","operationId":"get_chains","parameters":[{"name":"include_evm","in":"query","description":"Include EVM chains in the response.","required":false,"schema":{"type":"boolean"}},{"name":"include_svm","in":"query","description":"Include SVM chains in the response.","required":false,"schema":{"type":"boolean"}}],"responses":{"200":{"description":"Opaque Skip API passthrough (list of chains)","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"}}}}},"502":{"description":"Skip API call failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/swap/config":{"get":{"tags":["swap"],"summary":"Get swap UI config","description":"Returns UI-only swap configuration (blacklist, defaults, transfers) from\nbackground-refreshed cache. Response is an opaque JSON object — shape is\nnot fixed in this spec.","operationId":"get_swap_config","responses":{"200":{"description":"Opaque swap UI config","content":{"application/json":{"schema":{"type":"object"}}}},"503":{"description":"Swap config not yet populated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/swap/messages":{"post":{"tags":["swap"],"summary":"Get Skip swap messages","description":"Enriches the slim request with slippage, timeout, and affiliates from\ngated config, then forwards to Skip API. Response is an opaque Skip API\npassthrough — shape is not fixed in this spec.","operationId":"get_messages","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessagesRequest"}}},"required":true},"responses":{"200":{"description":"Opaque Skip API passthrough","content":{"application/json":{"schema":{"type":"object"}}}},"502":{"description":"Skip API call failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Gated config not yet populated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/swap/route":{"post":{"tags":["swap"],"summary":"Get Skip swap route","description":"Enriches the slim request with gated swap config (affiliates, venues,\nbridges) and forwards to Skip API. Response is an opaque Skip API\npassthrough — shape is not fixed in this spec.","operationId":"get_route","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RouteRequest"}}},"required":true},"responses":{"200":{"description":"Opaque Skip API passthrough","content":{"application/json":{"schema":{"type":"object"}}}},"502":{"description":"Skip API call failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Gated config not yet populated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/swap/status/{tx_hash}":{"get":{"tags":["swap"],"summary":"Get swap status","description":"Forwards to Skip API `/v2/tx/status`. Response is an opaque Skip API\npassthrough — shape is not fixed in this spec.","operationId":"get_status","parameters":[{"name":"tx_hash","in":"path","description":"Transaction hash to query status for","required":true,"schema":{"type":"string"}},{"name":"chain_id","in":"query","description":"Chain ID the transaction lives on (e.g. `osmosis-1`)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Opaque Skip API passthrough","content":{"application/json":{"schema":{"type":"object"}}}},"502":{"description":"Skip API call failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/swap/track":{"post":{"tags":["swap"],"summary":"Track a swap transaction","description":"Registers a transaction with Skip for cross-chain status tracking.","operationId":"track_transaction","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrackRequest"}}},"required":true},"responses":{"200":{"description":"Tracking registered","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrackResponse"}}}},"502":{"description":"Skip API call failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/zero-interest/config":{"get":{"tags":["zero-interest"],"summary":"Get zero-interest configuration","description":"Returns whether the zero-interest feature is enabled, payment bounds, and supported denoms.","operationId":"get_config","responses":{"200":{"description":"Zero-interest configuration","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ZeroInterestConfigResponse"}}}},"502":{"description":"Upstream zero-interest service error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/zero-interest/eligibility":{"get":{"tags":["zero-interest"],"summary":"Check zero-interest eligibility","description":"Checks whether the given lease/owner pair is eligible for a zero-interest\npayment and returns the allowed maximum amount.","operationId":"check_eligibility","parameters":[{"name":"lease","in":"query","description":"Lease contract address being checked for zero-interest eligibility.","required":true,"schema":{"type":"string"}},{"name":"owner","in":"query","description":"Owner wallet address.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Eligibility result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EligibilityResponse"}}}},"400":{"description":"Invalid lease/owner input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"Upstream zero-interest service error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/zero-interest/lease/{lease_address}/payments":{"get":{"tags":["zero-interest"],"summary":"Get zero-interest payments for a lease","description":"Returns the zero-interest payments recorded against a specific lease.","operationId":"get_lease_payments","parameters":[{"name":"lease_address","in":"path","description":"Lease contract address","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Payments for lease","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PaymentResponse"}}}}},"502":{"description":"Upstream zero-interest service error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/zero-interest/payments":{"post":{"tags":["zero-interest"],"summary":"Create a zero-interest payment","description":"Creates a signed zero-interest payment and submits it for processing. The\nowner must sign the request; the backend forwards to the payments manager.","operationId":"create_payment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePaymentRequest"}}},"required":true},"responses":{"200":{"description":"Payment created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePaymentResponse"}}}},"400":{"description":"Invalid payment request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"Upstream zero-interest service error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/zero-interest/payments/by-owner/{owner}":{"get":{"tags":["zero-interest"],"summary":"Get zero-interest payments by owner","description":"Returns all zero-interest payments (pending or completed) owned by `owner`.","operationId":"get_payments","parameters":[{"name":"owner","in":"path","description":"Owner wallet address","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Payments owned by address","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PaymentResponse"}}}}},"502":{"description":"Upstream zero-interest service error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/zero-interest/payments/{payment_id}":{"delete":{"tags":["zero-interest"],"summary":"Cancel a zero-interest payment","description":"Cancels a pending zero-interest payment. The owner must sign the request.","operationId":"cancel_payment","parameters":[{"name":"payment_id","in":"path","description":"Zero-interest payment ID","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CancelPaymentRequest"}}},"required":true},"responses":{"200":{"description":"Payment cancelled"},"404":{"description":"Payment not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"Upstream zero-interest service error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}},"components":{"schemas":{"AccountResponse":{"type":"object","required":["account"],"properties":{"account":{"type":"object","description":"Raw account object returned by the chain (shape depends on account type: base, vesting, module)."}}},"ActiveCampaignsResponse":{"type":"object","description":"Response for active campaigns endpoint","required":["campaigns"],"properties":{"campaigns":{"type":"array","items":{"$ref":"#/components/schemas/ZeroInterestCampaign"},"description":"List of active campaigns"},"all_eligible_currencies":{"type":"array","items":{"type":"string"},"description":"All currencies eligible across any campaign"},"all_eligible_protocols":{"type":"array","items":{"type":"string"},"description":"All protocols eligible across any campaign"},"has_universal_campaign":{"type":"boolean","description":"True if any campaign has no restrictions"}}},"AmountSpec":{"type":"object","required":["amount","ticker"],"properties":{"amount":{"type":"string"},"ticker":{"type":"string"}}},"AppConfigResponse":{"type":"object","description":"Full application config response","required":["protocols","networks","native_asset","contracts"],"properties":{"protocols":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/ProtocolInfo"},"propertyNames":{"type":"string"}},"networks":{"type":"array","items":{"$ref":"#/components/schemas/NetworkInfo"}},"native_asset":{"$ref":"#/components/schemas/NativeAssetInfo"},"contracts":{"$ref":"#/components/schemas/ContractsInfo"}}},"AprResponse":{"type":"object","description":"APR response","required":["annual_inflation","bonded_tokens","apr"],"properties":{"annual_inflation":{"type":"string"},"bonded_tokens":{"type":"string"},"apr":{"type":"number","format":"double"}}},"AssetDetailResponse":{"type":"object","description":"Response for single asset with full details","required":["ticker","decimals","icon","displayName","shortName","networks","protocol_details"],"properties":{"ticker":{"type":"string"},"decimals":{"type":"integer","format":"int32","minimum":0},"icon":{"type":"string"},"displayName":{"type":"string"},"shortName":{"type":"string"},"color":{"type":["string","null"]},"coingeckoId":{"type":["string","null"]},"price":{"type":["string","null"],"description":"Price in USD (from primary protocol for display)"},"networks":{"type":"array","items":{"type":"string"},"description":"Networks where this asset is available"},"protocol_details":{"type":"array","items":{"$ref":"#/components/schemas/ProtocolAssetDetail"},"description":"Protocol-specific details with prices"}}},"AssetResponse":{"type":"object","description":"Single asset with display info and price","required":["ticker","decimals","icon","displayName","shortName","networks","protocols"],"properties":{"ticker":{"type":"string"},"decimals":{"type":"integer","format":"int32","minimum":0},"icon":{"type":"string"},"displayName":{"type":"string"},"shortName":{"type":"string"},"color":{"type":["string","null"]},"coingeckoId":{"type":["string","null"]},"price":{"type":["string","null"],"description":"Price in USD from primary protocol's Oracle"},"networks":{"type":"array","items":{"type":"string"},"description":"Networks where this asset is available"},"protocols":{"type":"array","items":{"type":"string"},"description":"Protocols where this asset can be traded"}}},"AssetsResponse":{"type":"object","description":"Response for all assets","required":["assets","count"],"properties":{"assets":{"type":"array","items":{"$ref":"#/components/schemas/AssetResponse"}},"count":{"type":"integer","minimum":0}}},"AssignRequest":{"type":"object","required":["referral_code","referred_wallet"],"properties":{"referral_code":{"type":"string"},"referred_wallet":{"type":"string"}}},"AssignResponse":{"type":"object","required":["id","referrer_wallet","referred_wallet","referral_code","assigned_at"],"properties":{"id":{"type":"integer","format":"int64"},"referrer_wallet":{"type":"string"},"referred_wallet":{"type":"string"},"referral_code":{"type":"string"},"assigned_at":{"type":"string"}}},"BalanceInfo":{"type":"object","required":["key","symbol","denom","amount","amount_usd","decimal_digits"],"properties":{"key":{"type":"string"},"symbol":{"type":"string"},"denom":{"type":"string"},"amount":{"type":"string"},"amount_usd":{"type":"string"},"decimal_digits":{"type":"integer","format":"int32","minimum":0}}},"BalancesResponse":{"type":"object","required":["balances","total_value_usd"],"properties":{"balances":{"type":"array","items":{"$ref":"#/components/schemas/BalanceInfo"}},"total_value_usd":{"type":"string"}}},"CacheHealth":{"type":"object","description":"Cache health information","required":["status","total_entries","hit_rate"],"properties":{"status":{"type":"string"},"total_entries":{"type":"integer","format":"int64","minimum":0},"hit_rate":{"type":"number","format":"double"}}},"CampaignEligibilityResponse":{"type":"object","description":"Response for eligibility check","required":["eligible"],"properties":{"eligible":{"type":"boolean"},"matching_campaigns":{"type":"array","items":{"$ref":"#/components/schemas/CampaignMatch"}},"reason":{"type":["string","null"]}}},"CampaignMatch":{"type":"object","required":["id","name"],"properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"}}},"CancelPaymentRequest":{"type":"object","required":["owner_address","signature"],"properties":{"owner_address":{"type":"string"},"signature":{"type":"string"}}},"ClaimRewardsRequest":{"type":"object","required":["validator_addresses"],"properties":{"validator_addresses":{"type":"array","items":{"type":"string"}}}},"CloseLeaseRequest":{"type":"object","required":["lease_address"],"properties":{"lease_address":{"type":"string"}}},"ContractsInfo":{"type":"object","required":["admin","dispatcher"],"properties":{"admin":{"type":"string"},"dispatcher":{"type":"string"}}},"CreatePaymentRequest":{"type":"object","required":["lease_address","amount","denom","owner_address","signature"],"properties":{"lease_address":{"type":"string"},"amount":{"type":"string"},"denom":{"type":"string"},"owner_address":{"type":"string"},"signature":{"type":"string"}}},"CreatePaymentResponse":{"type":"object","required":["payment"],"properties":{"payment":{"$ref":"#/components/schemas/PaymentResponse"},"tx_hash":{"type":["string","null"]}}},"CurrenciesResponse":{"type":"object","description":"Full currencies response for frontend","required":["currencies","lpn","lease_currencies","map"],"properties":{"currencies":{"type":"object","description":"All currencies indexed by key (TICKER@PROTOCOL)","additionalProperties":{"$ref":"#/components/schemas/CurrencyInfo"},"propertyNames":{"type":"string"}},"lpn":{"type":"array","items":{"$ref":"#/components/schemas/CurrencyInfo"},"description":"LPN currencies (one per protocol)"},"lease_currencies":{"type":"array","items":{"type":"string"},"description":"Lease-able currency tickers"},"map":{"type":"object","description":"Currency key mappings (aliases)","additionalProperties":{"type":"string"},"propertyNames":{"type":"string"}}}},"CurrencyDisplayInfo":{"type":"object","description":"Currency display information for API responses\n\nThis is the canonical type for currency display info across all handlers.\nThe `color` field is optional and will be omitted from JSON if None.","required":["ticker","icon","displayName","shortName"],"properties":{"ticker":{"type":"string"},"icon":{"type":"string"},"displayName":{"type":"string"},"shortName":{"type":"string"},"color":{"type":["string","null"]}}},"CurrencyInfo":{"type":"object","description":"Currency information with all details needed by frontend","required":["key","ticker","symbol","name","short_name","decimal_digits","bank_symbol","dex_symbol","icon","native","protocol","group","is_active"],"properties":{"key":{"type":"string"},"ticker":{"type":"string"},"symbol":{"type":"string"},"name":{"type":"string"},"short_name":{"type":"string"},"decimal_digits":{"type":"integer","format":"int32","minimum":0},"bank_symbol":{"type":"string","description":"IBC denom on Nolus chain"},"dex_symbol":{"type":"string","description":"IBC denom on DEX network"},"icon":{"type":"string"},"native":{"type":"boolean"},"coingecko_id":{"type":["string","null"]},"protocol":{"type":"string","description":"Protocol this currency belongs to"},"group":{"type":"string","description":"Currency group (lease, lpn, native, payment_only)"},"is_active":{"type":"boolean","description":"Whether currency is currently active"}}},"DelegateRequest":{"type":"object","required":["validator_address","amount","denom"],"properties":{"validator_address":{"type":"string"},"amount":{"type":"string"},"denom":{"type":"string"}}},"DenomMetadata":{"type":"object","required":["description","denom_units","base","display","name","symbol"],"properties":{"description":{"type":"string"},"denom_units":{"type":"array","items":{"$ref":"#/components/schemas/DenomUnit"}},"base":{"type":"string"},"display":{"type":"string"},"name":{"type":"string"},"symbol":{"type":"string"}}},"DenomUnit":{"type":"object","required":["denom","exponent"],"properties":{"denom":{"type":"string"},"exponent":{"type":"integer","format":"int32","minimum":0},"aliases":{"type":"array","items":{"type":"string"}}}},"DepositRequest":{"type":"object","required":["protocol","amount"],"properties":{"protocol":{"type":"string"},"amount":{"type":"string"}}},"DetailedHealthResponse":{"type":"object","description":"Detailed health response with service checks","required":["status","version","uptime_seconds","services","cache"],"properties":{"status":{"type":"string"},"version":{"type":"string"},"uptime_seconds":{"type":"integer","format":"int64","minimum":0},"services":{"$ref":"#/components/schemas/ServiceHealth"},"cache":{"$ref":"#/components/schemas/CacheHealth"}}},"DownpaymentRange":{"type":"object","description":"Downpayment range for an asset","required":["min","max"],"properties":{"min":{"type":"number","format":"double","description":"Minimum downpayment value in USD"},"max":{"type":"number","format":"double","description":"Maximum downpayment value in USD"}}},"EarnPool":{"type":"object","required":["protocol","lpp_address","currency","total_deposited","apy","utilization","available_liquidity"],"properties":{"protocol":{"type":"string","description":"Protocol name (e.g., \"OSMOSIS-OSMOSIS-USDC_NOBLE\")"},"lpp_address":{"type":"string","description":"LPP contract address"},"currency":{"type":"string","description":"LPN currency ticker"},"total_deposited":{"type":"string","description":"Total deposited amount (in base units)"},"total_deposited_usd":{"type":["string","null"],"description":"Total deposited in USD"},"apy":{"type":"number","format":"double","description":"Current APY as percentage"},"utilization":{"type":"number","format":"double","description":"Utilization ratio (0-100)"},"available_liquidity":{"type":"string","description":"Available liquidity for borrowing"},"deposit_capacity":{"type":["string","null"],"description":"Deposit capacity remaining"},"icon":{"type":["string","null"],"description":"Pool icon path"}}},"EarnPosition":{"type":"object","required":["protocol","lpp_address","currency","deposited_nlpn","deposited_lpn","lpp_price","current_apy"],"properties":{"protocol":{"type":"string","description":"Protocol name"},"lpp_address":{"type":"string","description":"LPP contract address"},"currency":{"type":"string","description":"LPN currency ticker"},"deposited_nlpn":{"type":"string","description":"Deposited amount in nLPN (receipt tokens)"},"deposited_lpn":{"type":"string","description":"Deposited amount in LPN (actual value)"},"deposited_usd":{"type":["string","null"],"description":"Deposited value in USD"},"lpp_price":{"type":"string","description":"LPP price (nLPN to LPN ratio)"},"current_apy":{"type":"number","format":"double","description":"Current APY for this pool"}}},"EarnPositionsResponse":{"type":"object","required":["positions","total_deposited_usd"],"properties":{"positions":{"type":"array","items":{"$ref":"#/components/schemas/EarnPosition"}},"total_deposited_usd":{"type":"string"}}},"EarnStats":{"type":"object","required":["total_value_locked","pools_count","average_apy"],"properties":{"total_value_locked":{"type":"string","description":"Total value locked across all pools (USD)"},"pools_count":{"type":"integer","format":"int32","description":"Number of active pools","minimum":0},"average_apy":{"type":"number","format":"double","description":"Average APY across pools"},"dispatcher_rewards":{"type":["number","null"],"format":"double","description":"Dispatcher rewards rate"}}},"EarnTransactionResponse":{"type":"object","required":["messages","memo"],"properties":{"messages":{"type":"array","items":{"type":"object"},"description":"Unsigned CosmWasm execute messages for client-side signing"},"memo":{"type":"string"}}},"EligibilityResponse":{"type":"object","required":["eligible"],"properties":{"eligible":{"type":"boolean"},"reason":{"type":["string","null"]},"max_amount":{"type":["string","null"]},"available_slots":{"type":["integer","null"],"format":"int32","minimum":0}}},"ErrorBody":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Machine-readable error code (e.g. `VALIDATION_FAILED`, `NOT_FOUND`)."},"message":{"type":"string","description":"Human-readable message."},"field":{"type":["string","null"],"description":"Field name that failed validation (when applicable)."},"details":{"type":"object","description":"Additional structured details about the error."},"retry_after":{"type":["integer","null"],"format":"int64","description":"Number of seconds the client should wait before retrying (rate-limit responses).","minimum":0}}},"ErrorResponse":{"type":"object","description":"Error response body","required":["error"],"properties":{"error":{"$ref":"#/components/schemas/ErrorBody"}}},"GasFeeConfigResponse":{"type":"object","description":"Gas fee configuration served to the frontend.\nReplaces the direct ABCI query to `/nolus.tax.v2.Query/Params` from the browser.","required":["gas_prices","gas_multiplier"],"properties":{"gas_prices":{"type":"object","description":"Map of denom -> min gas price (e.g., \"ibc/...\" -> \"0.003\")","additionalProperties":{"type":"string"},"propertyNames":{"type":"string"}},"gas_multiplier":{"type":"number","format":"double","description":"Gas estimate multiplier (e.g., 3.5)"}}},"HealthResponse":{"type":"object","description":"Basic health response (for quick checks)","required":["status","version","uptime_seconds"],"properties":{"status":{"type":"string"},"version":{"type":"string"},"uptime_seconds":{"type":"integer","format":"int64","minimum":0}}},"HiddenProposalsResponse":{"type":"object","description":"Response for hidden proposals endpoint","required":["hidden_ids"],"properties":{"hidden_ids":{"type":"array","items":{"type":"string"}}}},"IntercomTokenRequest":{"type":"object","description":"Request for Intercom JWT token generation\nOnly wallet address and type are needed — all portfolio data is fetched server-side","required":["wallet","wallet_type"],"properties":{"wallet":{"type":"string"},"wallet_type":{"type":"string"}}},"IntercomTokenResponse":{"type":"object","description":"Response containing JWT token for Intercom\nMatches beacon's API response: { token: \"...\" }","required":["token"],"properties":{"token":{"type":"string"}}},"LeaseAssetInfo":{"type":"object","required":["ticker","amount"],"properties":{"ticker":{"type":"string"},"amount":{"type":"string"},"amount_usd":{"type":["string","null"]}}},"LeaseClosePolicy":{"type":"object","properties":{"stop_loss":{"type":["integer","null"],"format":"int32","description":"Stop loss threshold (permille)","minimum":0},"take_profit":{"type":["integer","null"],"format":"int32","description":"Take profit threshold (permille)","minimum":0}}},"LeaseConfigResponse":{"type":"object","description":"Response for lease configuration per protocol","required":["protocol","downpayment_ranges","min_asset","min_transaction"],"properties":{"protocol":{"type":"string"},"downpayment_ranges":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/DownpaymentRange"},"propertyNames":{"type":"string"}},"min_asset":{"$ref":"#/components/schemas/AmountSpec"},"min_transaction":{"$ref":"#/components/schemas/AmountSpec"}}},"LeaseDebtInfo":{"type":"object","required":["ticker","principal","overdue_margin","overdue_interest","due_margin","due_interest","total"],"properties":{"ticker":{"type":"string"},"principal":{"type":"string"},"overdue_margin":{"type":"string"},"overdue_interest":{"type":"string"},"due_margin":{"type":"string"},"due_interest":{"type":"string"},"total":{"type":"string"},"total_usd":{"type":["string","null"]}}},"LeaseEtlData":{"type":"object","properties":{"downpayment_amount":{"type":["string","null"],"description":"Downpayment amount (LS_cltr_amnt_stable: asset_micro_units × price)"},"loan_amount_stable":{"type":["string","null"],"description":"Loan principal in stable USD at lease open (LS_loan_amnt_stable, 6\ndecimals). Used to compute frozen initial leverage that doesn't drift\nwith accruing interest or manual repayments."},"collateral_symbol":{"type":["string","null"],"description":"Collateral symbol (e.g., \"USDC_NOBLE\" or \"ALL_BTC\") — determines downpayment decimals"},"price":{"type":["string","null"],"description":"Opening price per asset"},"lpn_price":{"type":["string","null"],"description":"LPN price at opening (for short positions)"},"fee":{"type":["string","null"],"description":"DEX/swap fee"},"ls_asset_symbol":{"type":["string","null"],"description":"Lease asset symbol"},"lease_position_ticker":{"type":["string","null"],"description":"Position ticker"},"repayment_value":{"type":["string","null"],"description":"Repayment value (total repaid so far)"},"history":{"type":["array","null"],"items":{"$ref":"#/components/schemas/LeaseHistoryEntry"},"description":"Transaction history"}}},"LeaseHistoryEntry":{"type":"object","required":["action"],"properties":{"tx_hash":{"type":["string","null"]},"action":{"type":"string"},"amount":{"type":["string","null"]},"symbol":{"type":["string","null"]},"timestamp":{"type":["string","null"]}}},"LeaseInProgress":{"oneOf":[{"type":"object","description":"Lease is opening","required":["opening"],"properties":{"opening":{"type":"object","description":"Lease is opening","properties":{"stage":{"type":["string","null"]}}}}},{"type":"object","description":"Repayment in progress","required":["repayment"],"properties":{"repayment":{"type":"object","description":"Repayment in progress"}}},{"type":"object","description":"Close in progress","required":["close"],"properties":{"close":{"type":"object","description":"Close in progress"}}},{"type":"object","description":"Liquidation in progress","required":["liquidation"],"properties":{"liquidation":{"type":"object","description":"Liquidation in progress","properties":{"cause":{"type":["string","null"]}}}}},{"type":"object","description":"Slippage protection activated — actions blocked","required":["slippage_protection"],"properties":{"slippage_protection":{"type":"object","description":"Slippage protection activated — actions blocked"}}}]},"LeaseInfo":{"type":"object","required":["address","protocol","status","amount","debt","interest"],"properties":{"address":{"type":"string"},"protocol":{"type":"string"},"status":{"$ref":"#/components/schemas/LeaseStatusType"},"amount":{"$ref":"#/components/schemas/LeaseAssetInfo","description":"Asset being held (collateral)"},"debt":{"$ref":"#/components/schemas/LeaseDebtInfo","description":"Current debt (principal + interest)"},"interest":{"$ref":"#/components/schemas/LeaseInterestInfo","description":"Interest rates"},"liquidation_price":{"type":["string","null"],"description":"Liquidation price"},"opened_at":{"type":["string","null"],"description":"Opening timestamp (from ETL)"},"pnl":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/LeasePnlInfo","description":"PnL information"}]},"close_policy":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/LeaseClosePolicy","description":"Close policy (stop loss / take profit)"}]},"overdue_collect_in":{"type":["string","null"],"description":"Time until overdue interest collection (nanoseconds)"},"in_progress":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/LeaseInProgress","description":"In-progress operation (if any)"}]},"opening_info":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/LeaseOpeningStateInfo","description":"Opening state info (for leases still opening)"}]},"etl_data":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/LeaseEtlData","description":"Historical data from ETL"}]}}},"LeaseInterestInfo":{"type":"object","required":["loan_rate","margin_rate","annual_rate_percent"],"properties":{"loan_rate":{"type":"integer","format":"int32","description":"Loan interest rate (permille)","minimum":0},"margin_rate":{"type":"integer","format":"int32","description":"Margin interest rate (percent)","minimum":0},"annual_rate_percent":{"type":"number","format":"double","description":"Combined annual rate as percentage"}}},"LeaseOpeningStateInfo":{"type":"object","required":["currency","downpayment","loan","loan_interest_rate"],"properties":{"currency":{"type":"string","description":"Currency being leased"},"downpayment":{"$ref":"#/components/schemas/LeaseAssetInfo","description":"Downpayment amount"},"loan":{"$ref":"#/components/schemas/LeaseAssetInfo","description":"Loan amount"},"loan_interest_rate":{"type":"integer","format":"int32","description":"Loan interest rate (permille)","minimum":0}}},"LeasePnlInfo":{"type":"object","required":["amount","percent","downpayment","pnl_positive"],"properties":{"amount":{"type":"string"},"percent":{"type":"string"},"downpayment":{"type":"string"},"pnl_positive":{"type":"boolean"}}},"LeaseQuoteRequest":{"type":"object","required":["protocol","downpayment_ticker","downpayment_amount"],"properties":{"protocol":{"type":"string"},"downpayment_ticker":{"type":"string"},"downpayment_amount":{"type":"string"},"max_ltd":{"type":["integer","null"],"format":"int32","minimum":0}}},"LeaseQuoteResponse":{"type":"object","required":["borrow_ticker","borrow_amount","annual_interest_rate"],"properties":{"borrow_ticker":{"type":"string"},"borrow_amount":{"type":"string"},"annual_interest_rate":{"type":"number","format":"double"},"estimated_liquidation_price":{"type":["string","null"]}}},"LeaseStatusType":{"type":"string","enum":["opening","opened","paid_off","closing","closed","liquidated"]},"LeaseTransactionResponse":{"type":"object","required":["messages","memo"],"properties":{"messages":{"type":"array","items":{"type":"object"},"description":"Cosmos SDK transaction messages (opaque `MsgExecuteContract` payloads)"},"memo":{"type":"string"}}},"LeasesResponse":{"type":"object","required":["leases","total_collateral_usd","total_debt_usd"],"properties":{"leases":{"type":"array","items":{"$ref":"#/components/schemas/LeaseInfo"}},"total_collateral_usd":{"type":"string"},"total_debt_usd":{"type":"string"}}},"LoansStatsBatch":{"type":"object","description":"Batch response for loans stats (raw JSON passthrough)","required":["open_position_value","open_interest"],"properties":{"open_position_value":{"type":["object","null"]},"open_interest":{"type":["object","null"]}}},"MarketCloseRequest":{"type":"object","required":["lease_address"],"properties":{"lease_address":{"type":"string"}}},"MessagesRequest":{"type":"object","description":"Slim messages request from frontend — backend injects slippage, timeout, affiliates","required":["source_asset_denom","source_asset_chain_id","dest_asset_denom","dest_asset_chain_id","amount_in","amount_out","operations","address_list"],"properties":{"source_asset_denom":{"type":"string"},"source_asset_chain_id":{"type":"string"},"dest_asset_denom":{"type":"string"},"dest_asset_chain_id":{"type":"string"},"amount_in":{"type":"string"},"amount_out":{"type":"string"},"operations":{"type":"array","items":{},"description":"Route operations from Skip `/route`. Opaque — passed through verbatim."},"address_list":{"type":"array","items":{"type":"string"}}}},"NativeAssetInfo":{"type":"object","required":["ticker","symbol","denom","decimal_digits"],"properties":{"ticker":{"type":"string"},"symbol":{"type":"string"},"denom":{"type":"string"},"decimal_digits":{"type":"integer","format":"int32","minimum":0}}},"NetworkInfo":{"type":"object","required":["key","name","chain_id","prefix","rpc_url","rest_url","gas_price","chain_type","native","value","symbol","gas_multiplier"],"properties":{"key":{"type":"string"},"name":{"type":"string"},"chain_id":{"type":"string"},"prefix":{"type":"string"},"rpc_url":{"type":"string"},"rest_url":{"type":"string"},"gas_price":{"type":"string"},"chain_type":{"type":"string","description":"Chain type (e.g., \"cosmos\", \"evm\")"},"native":{"type":"boolean","description":"Whether this is the native (Nolus) network"},"value":{"type":"string","description":"Lowercase identifier (e.g., \"osmosis\", \"neutron\")"},"symbol":{"type":"string","description":"Network ticker symbol (e.g., \"OSMO\", \"NTRN\")"},"explorer":{"type":["string","null"]},"icon":{"type":["string","null"]},"estimation":{"type":["integer","null"],"format":"int32","minimum":0},"primary_protocol":{"type":["string","null"]},"forward":{"type":["boolean","null"]},"gas_multiplier":{"type":"number","format":"double","description":"Gas multiplier for fee estimation"}}},"NetworkPoolsResponse":{"type":"object","description":"Response for network pools","required":["network","pools","count"],"properties":{"network":{"type":"string"},"pools":{"type":"array","items":{"$ref":"#/components/schemas/PoolResponse"}},"count":{"type":"integer","minimum":0}}},"NetworkResponse":{"type":"object","description":"Network response with config data","required":["network","name","chain_id","prefix","rpc","lcd","gas_price","gas_multiplier"],"properties":{"network":{"type":"string","description":"Network key (e.g., \"OSMOSIS\")"},"name":{"type":"string","description":"Display name"},"chain_id":{"type":"string","description":"Chain ID"},"prefix":{"type":"string","description":"Address prefix"},"rpc":{"type":"string","description":"Primary RPC endpoint"},"lcd":{"type":"string","description":"Primary LCD endpoint"},"fallback_rpc":{"type":"array","items":{"type":"string"},"description":"Fallback RPC endpoints"},"fallback_lcd":{"type":"array","items":{"type":"string"},"description":"Fallback LCD endpoints"},"gas_price":{"type":"string","description":"Gas price"},"explorer":{"type":["string","null"],"description":"Explorer URL"},"icon":{"type":["string","null"],"description":"Network icon"},"primaryProtocol":{"type":["string","null"],"description":"Primary protocol for price deduplication"},"estimation":{"type":["integer","null"],"format":"int32","description":"Transaction estimation time","minimum":0},"gas_multiplier":{"type":"number","format":"double","description":"Gas multiplier for fee estimation"}}},"NetworkStatusResponse":{"type":"object","description":"Network status response","required":["network","latest_block_height","latest_block_time","catching_up"],"properties":{"network":{"type":"string"},"latest_block_height":{"type":"string"},"latest_block_time":{"type":"string"},"catching_up":{"type":"boolean"}}},"NetworksResponse":{"type":"object","description":"Response for all networks","required":["networks","count"],"properties":{"networks":{"type":"array","items":{"$ref":"#/components/schemas/NetworkResponse"}},"count":{"type":"integer","minimum":0}}},"NodeInfoResponse":{"type":"object","description":"Node info response","required":["version","network"],"properties":{"version":{"type":"string"},"network":{"type":"string"}}},"OpenLeaseRequest":{"type":"object","required":["protocol","downpayment_ticker","downpayment_amount"],"properties":{"protocol":{"type":"string"},"downpayment_ticker":{"type":"string"},"downpayment_amount":{"type":"string"},"max_ltd":{"type":["integer","null"],"format":"int32","minimum":0}}},"PaginationInfo":{"type":"object","required":["total"],"properties":{"total":{"type":"string"},"next_key":{"type":["string","null"]}}},"PaymentResponse":{"type":"object","required":["id","lease_address","amount","denom","payment_date","status"],"properties":{"id":{"type":"string"},"lease_address":{"type":"string"},"amount":{"type":"string"},"denom":{"type":"string"},"payment_date":{"type":"string"},"status":{"$ref":"#/components/schemas/PaymentStatus"}}},"PaymentStatus":{"type":"string","enum":["pending","completed","failed","cancelled"]},"PayoutResponse":{"type":"object","required":["id","total_amount","denom","status","created_at"],"properties":{"id":{"type":"integer","format":"int64"},"total_amount":{"type":"string"},"denom":{"type":"string"},"tx_hash":{"type":["string","null"]},"status":{"type":"string"},"created_at":{"type":"string"},"executed_at":{"type":["string","null"]}}},"PayoutStatus":{"type":"string","enum":["pending","submitted","confirmed","failed"]},"PayoutsListResponse":{"type":"object","required":["payouts","total","limit","offset"],"properties":{"payouts":{"type":"array","items":{"$ref":"#/components/schemas/PayoutResponse"}},"total":{"type":"integer","format":"int64","minimum":0},"limit":{"type":"integer","format":"int64","minimum":0},"offset":{"type":"integer","format":"int64","minimum":0}}},"PoolResponse":{"type":"object","description":"Pool info for LPP","required":["protocol","network","lpn","lpn_display"],"properties":{"protocol":{"type":"string","description":"Protocol name"},"network":{"type":"string","description":"Network"},"lpp_address":{"type":["string","null"],"description":"LPP contract address"},"apr":{"type":["string","null"],"description":"Earn APR"},"utilization":{"type":["string","null"],"description":"Pool utilization"},"total_supplied":{"type":["string","null"],"description":"Total supplied"},"total_borrowed":{"type":["string","null"],"description":"Total borrowed"},"borrow_apr":{"type":["string","null"],"description":"Borrow APR"},"lpn":{"type":"string","description":"LPN ticker"},"lpn_display":{"$ref":"#/components/schemas/CurrencyDisplayInfo","description":"LPN display info"},"icon":{"type":["string","null"],"description":"Pool icon path"}}},"PriceInfo":{"type":"object","required":["key","symbol","price_usd"],"properties":{"key":{"type":"string"},"symbol":{"type":"string"},"price_usd":{"type":"string"}}},"PricesResponse":{"type":"object","required":["prices","updated_at"],"properties":{"prices":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/PriceInfo"},"propertyNames":{"type":"string"}},"updated_at":{"type":"string"}}},"ProposalResponse":{"type":"object","description":"Proposal response with tally and vote info","required":["id","status","messages"],"properties":{"id":{"type":"string"},"status":{"type":"string"},"final_tally_result":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/TallyResult"}]},"submit_time":{"type":["string","null"]},"deposit_end_time":{"type":["string","null"]},"voting_start_time":{"type":["string","null"]},"voting_end_time":{"type":["string","null"]},"title":{"type":["string","null"]},"summary":{"type":["string","null"]},"messages":{"type":"array","items":{"type":"object"},"description":"Raw governance messages attached to this proposal (shape depends on proposal type)."},"metadata":{"type":["string","null"]},"tally":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/TallyResult"}]},"voted":{"type":["boolean","null"]}}},"ProposalsListResponse":{"type":"object","description":"Proposals list response","required":["proposals","pagination"],"properties":{"proposals":{"type":"array","items":{"$ref":"#/components/schemas/ProposalResponse"}},"pagination":{"$ref":"#/components/schemas/PaginationInfo"}}},"Protocol":{"type":"object","description":"Protocol information from ETL","required":["name","position_type","lpn","is_active","contracts"],"properties":{"name":{"type":"string"},"network":{"type":["string","null"]},"dex":{"type":["string","null"]},"position_type":{"type":"string"},"lpn":{"type":"string"},"is_active":{"type":"boolean"},"contracts":{"$ref":"#/components/schemas/ProtocolContracts"}}},"ProtocolAssetDetail":{"type":"object","description":"Asset details specific to a protocol","required":["protocol","network","bank_symbol","dex_symbol","group"],"properties":{"protocol":{"type":"string"},"network":{"type":"string"},"bank_symbol":{"type":"string","description":"Bank symbol (denom on Nolus)"},"dex_symbol":{"type":"string","description":"DEX symbol (denom on DEX network)"},"group":{"type":"string","description":"Asset group (collateral, lpn, etc.)"},"price":{"type":["string","null"],"description":"Protocol-specific price from Oracle"}}},"ProtocolContracts":{"type":"object","description":"Protocol contract addresses used in API responses\n\nThis is the canonical type for protocol contracts in handler responses.\nAll fields are optional because not all protocols have all contract types.","properties":{"leaser":{"type":["string","null"]},"lpp":{"type":["string","null"]},"oracle":{"type":["string","null"]},"profit":{"type":["string","null"]},"reserve":{"type":["string","null"]}}},"ProtocolCurrenciesResponse":{"type":"object","description":"Response for protocol currencies","required":["protocol","currencies","count"],"properties":{"protocol":{"type":"string"},"currencies":{"type":"array","items":{"$ref":"#/components/schemas/ProtocolCurrencyResponse"}},"count":{"type":"integer","minimum":0}}},"ProtocolCurrencyResponse":{"type":"object","description":"Currency with protocol-specific info and price","required":["ticker","decimals","icon","displayName","shortName","bank_symbol","dex_symbol","group"],"properties":{"ticker":{"type":"string"},"decimals":{"type":"integer","format":"int32","minimum":0},"icon":{"type":"string"},"displayName":{"type":"string"},"shortName":{"type":"string"},"color":{"type":["string","null"]},"bank_symbol":{"type":"string","description":"Bank symbol (denom on Nolus)"},"dex_symbol":{"type":"string","description":"DEX symbol (denom on DEX)"},"group":{"type":"string","description":"Currency group (collateral, lpn, etc.)"},"price":{"type":["string","null"],"description":"Protocol-specific price"}}},"ProtocolInfo":{"type":"object","description":"Protocol information including contract addresses","required":["name","lpn","position_type","contracts","is_active"],"properties":{"name":{"type":"string"},"network":{"type":["string","null"]},"dex":{"type":["string","null"]},"lpn":{"type":"string"},"position_type":{"type":"string"},"contracts":{"$ref":"#/components/schemas/ProtocolContracts"},"is_active":{"type":"boolean"}}},"ProtocolResponse":{"type":"object","description":"Protocol response with merged data","required":["protocol","network","dex","position_type","lpn","lpn_display","contracts"],"properties":{"protocol":{"type":"string","description":"Protocol name (e.g., \"OSMOSIS-OSMOSIS-USDC_NOBLE\")"},"network":{"type":"string","description":"Network"},"dex":{"type":"string","description":"DEX"},"position_type":{"type":"string","description":"Position type (long/short)"},"lpn":{"type":"string","description":"LPN currency ticker"},"lpn_display":{"$ref":"#/components/schemas/CurrencyDisplayInfo","description":"LPN display info"},"contracts":{"$ref":"#/components/schemas/ProtocolContracts","description":"Contract addresses"}}},"ProtocolsResponse":{"type":"object","description":"Response for all protocols","required":["protocols","count"],"properties":{"protocols":{"type":"array","items":{"$ref":"#/components/schemas/ProtocolResponse"}},"count":{"type":"integer","minimum":0}}},"RedelegateRequest":{"type":"object","required":["src_validator_address","dst_validator_address","amount","denom"],"properties":{"src_validator_address":{"type":"string"},"dst_validator_address":{"type":"string"},"amount":{"type":"string"},"denom":{"type":"string"}}},"ReferralResponse":{"type":"object","required":["id","referred_wallet","assigned_at","status"],"properties":{"id":{"type":"integer","format":"int64"},"referred_wallet":{"type":"string"},"assigned_at":{"type":"string"},"status":{"type":"string"}}},"ReferralStatus":{"type":"string","enum":["active","inactive"]},"ReferralsListResponse":{"type":"object","required":["referrals","total","limit","offset"],"properties":{"referrals":{"type":"array","items":{"$ref":"#/components/schemas/ReferralResponse"}},"total":{"type":"integer","format":"int64","minimum":0},"limit":{"type":"integer","format":"int64","minimum":0},"offset":{"type":"integer","format":"int64","minimum":0}}},"ReferrerResponse":{"type":"object","required":["wallet_address","referral_code","tier","status","created_at"],"properties":{"wallet_address":{"type":"string"},"referral_code":{"type":"string"},"tier":{"type":"string"},"status":{"type":"string"},"created_at":{"type":"string"}}},"ReferrerStatsResponse":{"type":"object","required":["referrer","stats"],"properties":{"referrer":{"$ref":"#/components/schemas/ReferrerResponse"},"stats":{"$ref":"#/components/schemas/StatsResponse"}}},"ReferrerStatus":{"type":"string","enum":["active","disabled"]},"ReferrerTier":{"type":"string","enum":["general","premium"]},"RegisterRequest":{"type":"object","required":["wallet_address"],"properties":{"wallet_address":{"type":"string"}}},"RegisterResponse":{"type":"object","required":["wallet_address","referral_code","tier","created_at","already_registered"],"properties":{"wallet_address":{"type":"string"},"referral_code":{"type":"string"},"tier":{"type":"string"},"created_at":{"type":"string"},"already_registered":{"type":"boolean"}}},"RepayLeaseRequest":{"type":"object","required":["lease_address","amount"],"properties":{"lease_address":{"type":"string"},"amount":{"type":"string"}}},"RewardResponse":{"type":"object","required":["id","lease_id","referred_wallet","period_start","period_end","interest_collected","interest_denom","reward_amount","reward_denom","status","created_at"],"properties":{"id":{"type":"integer","format":"int64"},"lease_id":{"type":"string"},"referred_wallet":{"type":"string"},"period_start":{"type":"string"},"period_end":{"type":"string"},"interest_collected":{"type":"string"},"interest_denom":{"type":"string"},"reward_amount":{"type":"string"},"reward_denom":{"type":"string"},"status":{"type":"string"},"created_at":{"type":"string"}}},"RewardStatus":{"type":"string","enum":["pending","included","paid"]},"RewardsListResponse":{"type":"object","required":["rewards","total","limit","offset"],"properties":{"rewards":{"type":"array","items":{"$ref":"#/components/schemas/RewardResponse"}},"total":{"type":"integer","format":"int64","minimum":0},"limit":{"type":"integer","format":"int64","minimum":0},"offset":{"type":"integer","format":"int64","minimum":0}}},"RouteRequest":{"type":"object","description":"Slim route request from frontend — backend injects all Skip config","required":["source_asset_denom","source_asset_chain_id","dest_asset_denom","dest_asset_chain_id"],"properties":{"source_asset_denom":{"type":"string"},"source_asset_chain_id":{"type":"string"},"dest_asset_denom":{"type":"string"},"dest_asset_chain_id":{"type":"string"},"amount_in":{"type":["string","null"]},"amount_out":{"type":["string","null"]},"network":{"type":["string","null"],"description":"Optional network hint to filter swap venues (e.g., \"osmosis\")"}}},"ServiceHealth":{"type":"object","description":"Health status of external services","required":["etl_api","nolus_rpc","nolus_rest","skip_api","referral_api","zero_interest_api"],"properties":{"etl_api":{"$ref":"#/components/schemas/ServiceStatus"},"nolus_rpc":{"$ref":"#/components/schemas/ServiceStatus"},"nolus_rest":{"$ref":"#/components/schemas/ServiceStatus"},"skip_api":{"$ref":"#/components/schemas/ServiceStatus"},"referral_api":{"$ref":"#/components/schemas/ServiceStatus"},"zero_interest_api":{"$ref":"#/components/schemas/ServiceStatus"}}},"ServiceStatus":{"type":"object","description":"Health status of a single service","required":["status","configured"],"properties":{"status":{"type":"string"},"configured":{"type":"boolean"},"latency_ms":{"type":["integer","null"],"format":"int64","minimum":0},"error":{"type":["string","null"]}}},"StakingParams":{"type":"object","required":["unbonding_time","max_validators","max_entries","bond_denom","min_commission_rate"],"properties":{"unbonding_time":{"type":"string"},"max_validators":{"type":"integer","format":"int32","minimum":0},"max_entries":{"type":"integer","format":"int32","minimum":0},"bond_denom":{"type":"string"},"min_commission_rate":{"type":"string"}}},"StakingPool":{"type":"object","required":["not_bonded_tokens","bonded_tokens"],"properties":{"not_bonded_tokens":{"type":"string"},"bonded_tokens":{"type":"string"}}},"StakingPoolResponse":{"type":"object","required":["pool"],"properties":{"pool":{"$ref":"#/components/schemas/StakingPool"}}},"StakingPosition":{"type":"object","required":["validator_address","shares","balance"],"properties":{"validator_address":{"type":"string"},"validator_moniker":{"type":["string","null"]},"shares":{"type":"string"},"balance":{"$ref":"#/components/schemas/staking.BalanceInfo"}}},"StakingPositionsResponse":{"type":"object","required":["delegations","unbonding","rewards","total_staked","total_rewards"],"properties":{"delegations":{"type":"array","items":{"$ref":"#/components/schemas/StakingPosition"}},"unbonding":{"type":"array","items":{"$ref":"#/components/schemas/UnbondingPosition"}},"rewards":{"type":"array","items":{"$ref":"#/components/schemas/ValidatorReward"}},"total_staked":{"type":"string"},"total_rewards":{"type":"string"}}},"StakingTransactionResponse":{"type":"object","required":["messages","memo"],"properties":{"messages":{"type":"array","items":{"type":"object"},"description":"Unsigned Cosmos SDK messages for client-side signing"},"memo":{"type":"string"}}},"StatsOverviewBatch":{"type":"object","description":"Batch response for stats overview page (raw JSON passthrough)","required":["tvl","tx_volume","buyback_total","realized_pnl_stats","revenue"],"properties":{"tvl":{"type":["object","null"]},"tx_volume":{"type":["object","null"]},"buyback_total":{"type":["object","null"]},"realized_pnl_stats":{"type":["object","null"]},"revenue":{"type":["object","null"]}}},"StatsResponse":{"type":"object","required":["total_referrals","active_referrals","total_rewards_earned","total_rewards_paid","pending_rewards","rewards_denom","bonus_rewards_earned","bonus_rewards_paid","total_bonus_amount_earned","total_bonus_amount_paid"],"properties":{"total_referrals":{"type":"integer","format":"int64","minimum":0},"active_referrals":{"type":"integer","format":"int64","minimum":0},"total_rewards_earned":{"type":"string"},"total_rewards_paid":{"type":"string"},"pending_rewards":{"type":"string"},"rewards_denom":{"type":"string"},"bonus_rewards_earned":{"type":"integer","format":"int64","minimum":0},"bonus_rewards_paid":{"type":"integer","format":"int64","minimum":0},"total_bonus_amount_earned":{"type":"string"},"total_bonus_amount_paid":{"type":"string"}}},"TallyResponse":{"type":"object","required":["tally"],"properties":{"tally":{"$ref":"#/components/schemas/TallyResult"}}},"TallyResult":{"type":"object","required":["yes_count","abstain_count","no_count","no_with_veto_count"],"properties":{"yes_count":{"type":"string"},"abstain_count":{"type":"string"},"no_count":{"type":"string"},"no_with_veto_count":{"type":"string"}}},"TallyingParams":{"type":"object","required":["quorum","threshold","veto_threshold"],"properties":{"quorum":{"type":"string"},"threshold":{"type":"string"},"veto_threshold":{"type":"string"}}},"TallyingParamsResponse":{"type":"object","required":["params"],"properties":{"params":{"$ref":"#/components/schemas/TallyingParams"}}},"TrackRequest":{"type":"object","description":"Request to track a swap transaction on Skip.","required":["chain_id","tx_hash"],"properties":{"chain_id":{"type":"string","description":"Chain ID the transaction was submitted to"},"tx_hash":{"type":"string","description":"Transaction hash to track"}}},"TrackResponse":{"type":"object","description":"Response from Skip tracking registration.","required":["tx_hash"],"properties":{"tx_hash":{"type":"string"},"explorer_link":{"type":["string","null"]}}},"UnbondingEntry":{"type":"object","required":["creation_height","completion_time","initial_balance","balance"],"properties":{"creation_height":{"type":"string"},"completion_time":{"type":"string"},"initial_balance":{"type":"string"},"balance":{"type":"string"}}},"UnbondingPosition":{"type":"object","required":["validator_address","entries"],"properties":{"validator_address":{"type":"string"},"validator_moniker":{"type":["string","null"]},"entries":{"type":"array","items":{"$ref":"#/components/schemas/UnbondingEntry"}}}},"UndelegateRequest":{"type":"object","required":["validator_address","amount","denom"],"properties":{"validator_address":{"type":"string"},"amount":{"type":"string"},"denom":{"type":"string"}}},"UserDashboardBatch":{"type":"object","description":"Batch response for user dashboard data (raw JSON passthrough)","required":["earnings","realized_pnl","position_debt_value"],"properties":{"earnings":{"type":["object","null"]},"realized_pnl":{"type":["object","null"]},"position_debt_value":{"type":["object","null"]}}},"UserHistoryBatch":{"type":"object","description":"Batch response for user history page (raw JSON passthrough)","required":["history_stats","realized_pnl_data"],"properties":{"history_stats":{"type":["object","null"]},"realized_pnl_data":{"type":["object","null"]}}},"ValidateCodeResponse":{"type":"object","required":["valid"],"properties":{"valid":{"type":"boolean"},"referral_code":{"type":["string","null"]},"referrer_wallet":{"type":["string","null"]}}},"Validator":{"type":"object","required":["operator_address","moniker","commission_rate","max_commission_rate","max_commission_change_rate","tokens","delegator_shares","unbonding_height","unbonding_time","status","jailed"],"properties":{"operator_address":{"type":"string"},"moniker":{"type":"string"},"identity":{"type":["string","null"]},"website":{"type":["string","null"]},"details":{"type":["string","null"]},"commission_rate":{"type":"string"},"max_commission_rate":{"type":"string"},"max_commission_change_rate":{"type":"string"},"tokens":{"type":"string"},"delegator_shares":{"type":"string"},"unbonding_height":{"type":"string"},"unbonding_time":{"type":"string"},"status":{"$ref":"#/components/schemas/ValidatorStatus"},"jailed":{"type":"boolean"}}},"ValidatorReward":{"type":"object","required":["validator_address","rewards"],"properties":{"validator_address":{"type":"string"},"rewards":{"type":"array","items":{"$ref":"#/components/schemas/staking.BalanceInfo"}}}},"ValidatorStatus":{"type":"string","enum":["bonded","unbonding","unbonded"]},"Vote":{"type":"object","required":["proposal_id","voter","options"],"properties":{"proposal_id":{"type":"string"},"voter":{"type":"string"},"options":{"type":"array","items":{"$ref":"#/components/schemas/VoteOption"}}}},"VoteOption":{"type":"object","required":["option","weight"],"properties":{"option":{"type":"string"},"weight":{"type":"string"}}},"VoteResponse":{"type":"object","required":["vote"],"properties":{"vote":{"$ref":"#/components/schemas/Vote"}}},"WithdrawRequest":{"type":"object","required":["protocol","amount"],"properties":{"protocol":{"type":"string"},"amount":{"type":"string","description":"Amount in nLPN to withdraw (receipt tokens)"}}},"ZeroInterestCampaign":{"type":"object","description":"Zero-interest campaign information","required":["id","name","active"],"properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"active":{"type":"boolean"},"eligible_protocols":{"type":"array","items":{"type":"string"},"description":"Eligible protocol/leaser addresses (empty = all protocols)"},"eligible_currencies":{"type":"array","items":{"type":"string"},"description":"Eligible currency tickers (empty = all currencies)"},"eligible_wallets":{"type":"array","items":{"type":"string"},"description":"Eligible wallet addresses (empty = all wallets)"},"start_date":{"type":["string","null"],"format":"date-time","description":"Campaign start date"},"end_date":{"type":["string","null"],"format":"date-time","description":"Campaign end date"},"description":{"type":["string","null"],"description":"Human-readable description"}}},"ZeroInterestConfigResponse":{"type":"object","required":["enabled","max_payment_amount","min_lease_value","max_active_payments","supported_denoms"],"properties":{"enabled":{"type":"boolean"},"max_payment_amount":{"type":"string"},"min_lease_value":{"type":"string"},"max_active_payments":{"type":"integer","format":"int32","minimum":0},"supported_denoms":{"type":"array","items":{"type":"string"}}}},"staking.BalanceInfo":{"type":"object","required":["denom","amount"],"properties":{"denom":{"type":"string"},"amount":{"type":"string"}}}}},"tags":[{"name":"health","description":"Liveness and readiness probes"},{"name":"config","description":"Application configuration (protocols, networks, contracts)"},{"name":"currencies","description":"Supported currencies catalog"},{"name":"prices","description":"Oracle price feeds"},{"name":"balances","description":"Wallet balances"},{"name":"protocols","description":"Nolus DeFi sub-protocol registry"},{"name":"locales","description":"Translation blobs for the frontend"},{"name":"fees","description":"Gas fee configuration"},{"name":"leases","description":"Leverage lease positions (read + write)"},{"name":"earn","description":"Liquidity-pool deposits and yields"},{"name":"staking","description":"NLS staking delegations"},{"name":"governance","description":"Proposals, tallies, voting parameters"},{"name":"node","description":"Node info and network status"},{"name":"referral","description":"Referral codes and rewards"},{"name":"zero-interest","description":"Zero-interest payments scheduled on leases"},{"name":"campaigns","description":"Zero-interest campaigns"},{"name":"assets","description":"Gated assets catalog (deduplicated view)"},{"name":"networks","description":"Gated networks catalog"},{"name":"swap","description":"Cross-chain swap (Skip passthrough, opaque bodies)"},{"name":"etl","description":"ETL proxy endpoints (opaque passthrough)"},{"name":"transactions","description":"Enriched transactions (opaque passthrough)"},{"name":"intercom","description":"Intercom user-hash issuance"}]}