Repository navigation
feat(soroban): adaptive concurrency, cache window, gateway retry and network presets (#978, #979, #980, #981) - #1015
Merged
Jaydbrown merged 6 commits intoOct 18, 2026
Conversation
…ow, gateway retry and network presets Covers four Stellar Wave issues assigned to iyanujohn612 on conduit-protocol/conduit-sdk: - conduit-protocol#978 mapWithAdaptiveConcurrency: AIMD limit that grows when calls finish under targetLatencyMs and halves when they do not, clamped to [min, max]. - conduit-protocol#979 coalesceAsync windowMs: keep a settled value for a short window so back-to-back render cycles reuse it; failures are still evicted at once. - conduit-protocol#980 custom fetch gateway retry: retry idempotent JSON-RPC reads on 502/503/504 with exponential backoff; sendTransaction is never replayed. - conduit-protocol#981 NETWORK_CONFIG and CONTRACT_IDS for futurenet and standalone. No contract IDs are hardcoded because they are derived per deployment. These tests are expected to fail on upstream/main until the implementation commits land.
…onduit-protocol#978) A fixed concurrency ceiling ignores how fast the endpoint is. On a fast link it leaves throughput unused, and on a slow one it still floods the RPC. mapWithAdaptiveConcurrency adjusts the in-flight limit from measured latency: a call that finishes within targetLatencyMs adds one slot up to max, and a slower call halves the limit down to min. Results keep input order and the first rejection propagates, matching mapWithConcurrency. The existing mapWithConcurrency signature is unchanged. Closes conduit-protocol#978
Deduplication only covered calls that overlap in flight. Calls from separate React render cycles that arrive a few hundred milliseconds apart still refetched the same value. The optional windowMs argument keeps a successful result for that window after it settles, so those calls share it. Omitting windowMs, or passing zero, a negative value or a non-finite value, keeps the existing behaviour: a settled entry stays until the caller removes it. Failed fetches are evicted immediately in every case. Closes conduit-protocol#979
…rs (conduit-protocol#980) Public RPC providers often answer with a transient 503 or 504 that clears within about a second, but the custom fetch path threw on the first response. Idempotent calls now retry up to 3 times with exponential backoff (250, 500, 1000 ms) on 502, 503 and 504. Other errors, including 500 and 429, are thrown unchanged. Soroban RPC is JSON-RPC over POST, so the HTTP method alone cannot mark a request as a read. Idempotency is decided from the JSON-RPC method: getLatestLedger, getLedgerEntries, simulateTransaction and similar reads retry. sendTransaction is never replayed, because a retry after a gateway timeout could submit the same transaction twice. Closes conduit-protocol#980
…t ID registry (conduit-protocol#981) Local developers on a standalone container and anyone on Futurenet had no preset to start from. NETWORK_CONFIG now carries the RPC URL and network passphrase for both. The standalone entry matches the existing `local` preset in soroban.ts. Contract IDs are derived from the deployer's address and salt, so an ID published here would point at someone else's contract. CONTRACT_IDS therefore holds null for every role on these networks until a deployment is recorded, and getContractId returns null in that case so callers pass their own factoryAddress or governorAddress explicitly. Closes conduit-protocol#981
…etry and network presets Adds CHANGELOG entries under Unreleased for the four changes and a section in docs/api.md for NETWORK_CONFIG, CONTRACT_IDS and getContractId. The section says why no contract IDs are published for futurenet or standalone, and how to pass addresses explicitly. Refs conduit-protocol#978, conduit-protocol#979, conduit-protocol#980, conduit-protocol#981
|
@iyanujohn612 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
This was referenced Oct 19, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #978
Closes #979
Closes #980
Closes #981
One PR for the four Stellar Wave issues assigned to iyanujohn612.
Changes
mapWithAdaptiveConcurrency(src/map-with-concurrency.ts): a new function next tomapWithConcurrency, which keeps its signature. The in-flight limit follows AIMD: a call that finishes withintargetLatencyMsadds one slot up tomax, and a slower call halves the limit down tomin.coalesceAsync(..., windowMs?)(src/coalesce-async.ts): an optional fourth argument keeps a successful result forwindowMsafter it settles. Omitting it, or passing 0, a negative value or a non-finite value, keeps the previous behaviour. Failed fetches are still evicted immediately.src/custom-fetch.ts): on the custom-fetch path, idempotent calls retry up to 3 times on 502/503/504, with 250/500/1000 ms backoff.src/constants.ts,src/index.ts):NETWORK_CONFIGforfuturenetandstandalone, andCONTRACT_IDS/getContractId().Decisions to review
sendTransactionis excluded so a submission is never replayed. The issue text says "GET", so this is a deliberate deviation.customFetchconfigured) is not changed. Making it retry would mean an axios response interceptor and would affect every RPC call, so I left it for a follow-up.CONTRACT_IDSentries arenullandgetContractId()returnsnull. Callers passfactoryAddress/governorAddressexplicitly. The Futurenet passphrase and RPC URL come from the Stellar docs. If maintainers want a deployment registry instead, that can replace this shape.windowMsopts into a bounded TTL.Commits
Follows the CONTRIBUTING order: failing tests first, then one
featcommit per issue, then docs. The typecheck and lint commit from the 5-commit convention is not included. The tests and build have not been run locally, so CI is the first run.