Towerz exposes indicative SOL/USDC funding quotes and canonical-USDC context for Kamino's main lending market. These readers do not request a user's wallet address, build a transaction, sign, execute, route Towerz pool funds or change credit terms. Neither a quoted output nor a displayed lending rate is a promise of execution or return.
Endpoints and SDK
| Towerz GET endpoint | Purpose |
|---|---|
/api/defi/status |
Reader configuration. checked: false explicitly means this is not a provider health check. |
/api/defi/jupiter/quote?inputMint=...&outputMint=...&amount=...&slippageBps=50 |
Exact-input SOL to USDC or USDC to SOL indicative quote. |
/api/defi/kamino/markets |
Main-market reserves whose exact mint is canonical mainnet USDC. |
createTowerzDefiClient({ baseUrl: 'https://towerz.credit' }) exposes status(), jupiterQuote(input) and kaminoMarkets(). The client calls Towerz, not the providers, and needs no provider credential. Unsupported query parameters and duplicate parameters are rejected. Only GET is supported.
The browser and SDK receive a snapshot with:
state:fresh,stale,unavailableorunconfigured.network:solana-mainnet.source: provider name.observedAt: when Towerz received the successful observation.expiresAt: the local freshness boundary, shortened by any Jupiter quote expiration.sourceUpdatedAt: null. The APIs do not establish a trustworthy update time for the underlying source data in this integration. Receipt time must not be displayed as source time or chain confirmation.data: validated, limited fields, or null on unavailable/unconfigured reads.error: a safe public code/message when applicable. Raw provider error text is discarded.
The status endpoint may include a provider-specific lastFailure from its latest completed upstream attempt. This is a fixed diagnostic stage, a numeric HTTP status, or an allowlisted schema field/type/issue. Quote failures may add a fixed check-detail enum and a bounded integer only for slippage, fee basis points or a numeric provider error code. It never includes raw amounts, account identifiers, bodies, URLs, headers or exception text. It is ephemeral operational state and clears after a successful upstream read. Cached observations and local request-budget denials do not overwrite it. The status endpoint remains configuration and diagnostics, not a health check.
Failed refreshes may return a bounded previous snapshot marked stale, retaining its original timestamp. An expired snapshot never becomes a fresh zero. The UI must identify stale/unavailable states and avoid using indicative observations to authorize transactions.
Jupiter
The fixed upstream is https://api.jup.ag/swap/v2/order. Towerz sends only inputMint, outputMint, integer amount, slippageBps and swapMode=ExactIn. It deliberately omits taker, payer, receiver, referral configuration and execution requests. A response containing a nonempty transaction or taker is rejected. Returned transaction/request identifiers and unrelated provider fields are never forwarded.
Permitted mints:
- Wrapped SOL:
So11111111111111111111111111111111111111112, 9 decimals. - Native Circle USDC on Solana mainnet:
EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v, 6 decimals.
Input amounts are exact positive base-unit strings, limited to 100 SOL or 10,000 USDC per indicative request. The caller's slippage cap is 1 to 100 basis points, default 50. Jupiter may return a stricter tolerance, including zero. slippageBps retains the caller cap for compatibility; providerSlippageBps records the actual router tolerance. The provider tolerance must be an integer from zero through the cap, and the minimum output must satisfy the provider's stricter tolerance. SDK 0.2.2 also validates that constraint; legacy responses without providerSlippageBps are validated against their existing cap. Input/output identity, exact input amount, minimum output, fee mint, fee bounds, router and expiration are checked. Fees are quote data, not authorization. Output fields include exact inAmount, outAmount, minimumOutAmount, feeBps, feeMint and optional priceImpactPct in percentage points.
Jupiter's current official documentation says quote-only requests work without an API key at 0.5 requests per second. An optional JUPITER_API_KEY is read only in the server and sent only as the fixed Jupiter upstream's x-api-key header. Keyless access is the default. Both modes retain Towerz's conservative per-process upstream cadence.
Kamino
The fixed upstream is:
https://api.kamino.finance/reserves/batch/stats?market=7u3HeHxYDLhnCoErrtycNokbQYbWGzLs6JSDqGAv5PfF
Kamino's official SDK identifies that address as the main market. The reader selects by exact canonical-USDC mint, never by token ticker. It returns reserve addresses, total supply/borrowing in decimal token-unit strings, current supply/borrow APY ratios and the exact decimal difference between reported supply and borrowing. Provider metrics permit up to 20 integer digits and 128 fractional digits so accrued debt below one token base unit remains exact. Subtraction uses integer arithmetic at the shared decimal scale. This does not change the six-decimal USDC transfer denomination or any payment amount bound.
indicativeLiquidityTokens means only reported supply less borrowing. It does not account for borrow caps, rate limits, reserve status, withdrawals, account eligibility, transaction simulation or execution liquidity. If reported borrowing exceeds supply, the field is null. The reader does not quietly clamp that situation into an apparently valid zero. APY ratios exclude incentive assumptions and are not guaranteed future yields.
These are provider-reported data, not independent chain-state verification. This integration does not deposit to Kamino, collateralize Towerz borrowing with a Kamino position or claim a partnership.
Configuration and bounds
| Server environment variable | Default | Purpose |
|---|---|---|
TOWERZ_JUPITER_CONTEXT_ENABLED |
enabled | Set exactly false to disable the reader. |
TOWERZ_KAMINO_CONTEXT_ENABLED |
enabled | Set exactly false to disable the reader. |
JUPITER_API_KEY |
unset | Optional server-side Jupiter key. Never place this in a VITE_ variable. |
No configurable upstream URL exists. All upstream requests omit credentials, referrers and cookies; redirects and changed response URLs fail closed. JSON responses are streamed with a 1 MiB bound, with a maximum six-second timeout that also covers fetch implementations that ignore abort signals. At most four requests may be in flight. Identical requests share one in-flight request. A maximum of 64 observations are cached. Jupiter freshness lasts at most 10 seconds with up to 60 seconds of explicitly stale fallback; Kamino freshness lasts 60 seconds with up to five minutes of stale fallback. Provider 429 responses create bounded cooldowns.
Limits are per server process, not a distributed quota guarantee. The public edge should apply its ordinary IP/request budget before these routes. A shared cache or distributed quota is necessary before scaling to many workers under a shared provider quota.
These ephemeral caches hold replaceable provider observations only. They are not financial records or recovery receipts. Towerz balances, loans, receipts, audit events and transaction recovery continue to require their existing chain/PostgreSQL paths. No new financial record is stored only in this cache.
Sources and validation
Documentation checked on 20 October 2026:
- Jupiter Swap API overview: V2, keyless quotes, explicit
takerrequirement for transaction construction. - Jupiter's official
jup-ag/docsrepository,openapi-spec/swap/v2/swap.yaml: quote response field definitions, exact-input mode and fee/expiration fields. - Kamino Lending SDK: the official repository's README identifies the main-market address; its
src/utils/constants.tsidentifies the public API origin and/v2/kamino-marketdiscovery route. - DefiLlama's current
yield-serverKamino adapter independently corroborates the/reserves/batch/stats?market=...endpoint andtoken,totalSupply,totalBorrow,supplyApy.currentandborrowApy.currentfield usage. This is secondary schema evidence, not an official API compatibility guarantee.
The tests also start the real production HTTP server in isolated subprocesses with synthetic read-only upstreams, proving route wiring, origin checks, network gating, method restrictions, response headers, secret redaction and edge rate limits. No deployment credentials or external network calls are used in that check.
The adapter tests use explicit provider fixtures and cover validation, mint substitution, exact large decimal arithmetic, slippage weakening, unexpected executable responses, response bounds, redirects, failures, timeouts, rate limits, request coalescing, stale-cache deadlines, disabled providers, routes and SDK response validation.
Direct provider probes from the build environment were blocked by its outbound proxy before reaching either provider. Deployed Towerz endpoint checks on 21 October 2026 subsequently returned fresh Jupiter quotes and four canonical-USDC Kamino reserve observations. The SDK successfully parsed those unaltered production responses and preserved exact decimal strings. These live checks identified two compatibility constraints: Kamino accrued borrowing may exceed 24 fractional decimal places, and Jupiter may tighten the caller's 50-basis-point cap to zero. The adapters now retain bounded 128-place decimal metrics and validate the provider's stricter slippage without weakening the caller cap.
These checks demonstrate successful observations at the recorded times, not universal provider availability. Invalid provider responses remain unavailable or use an explicitly stale bounded fallback. Provider schema changes, network failures and out-of-policy quotes must never become fabricated data or transaction authorization. Current builds add providerSlippageBps while preserving the existing caller-cap meaning of slippageBps for older clients.