This PR implements four SDK improvements across a single branch to keep the changes cohesive and easy to review.
Files: client/src/types/index.ts, client/src/index.ts, client/src/StellarGrantsSDK.ts
- Added fully-typed
GrantDataandMilestoneDatainterfaces whose field names match Soroban'sscValToNativeoutput (snake_case keys exactly as returned by the contract). - Updated
grantGet()return type fromanytoGrantData | nullandmilestoneGet()toMilestoneData | null. - Added
assertGrantData/assertMilestoneDatainternal shape validators that emit aconsole.warnin non-production environments when the response is missing expected fields, without ever hard-throwing on partial data (safe for unit-test mocks). - Exported new types from
src/index.ts.
Files: client/src/StellarGrantsSDK.ts
- Added automatic WebSocket URL derivation from the configured
rpcUrl:http://→ws://,https://→wss://— no separatewebsocketUrlconfig needed. - Added a 5-second connection timeout on WebSocket initiation; if the socket does not reach
onopenwithin that window, the SDK falls back to HTTP polling. - Set
useWebSocket = falsepermanently after any connection error or close, preventing reconnect loops that keep hammering a non-WS RPC endpoint. - WebSocket errors are forwarded to
options.onErrorbefore cleanup. - All existing WebSocket unit tests continue to pass.
Files: client/src/StellarGrantsSDK.ts
-
Added a
private getDynamicFeeStats(horizonUrl)helper that fetches/fee_statsfrom Horizon and selects the fee percentile adaptively based on real-time ledger saturation:Network Load Capacity Usage Percentile Modifiers (low / med / high) surge> 95% p90 1.6 / 2.5 / 3.5 high> 80% p80 1.3 / 2.0 / 2.8 moderate> 50% p70 1.0 / 1.5 / 2.0 normal≤ 50% p50 0.9 / 1.2 / 1.6 -
estimateFees()now delegates togetDynamicFeeStats()and exposespercentilein the response alongsidenetworkLoad,source, and fee tiers. -
invokeWrite()now queries Horizon (whenhorizonUrlis configured) to scaleminResourceFeeup to the competitiverecommendedBasebefore applying the priority multiplier — preventing transactions from hanging during congestion while avoiding overpayment during idle periods. -
Falls back gracefully to
simulation-fallbackstatic tiers when Horizon is unavailable.
Files: client/tsup.config.ts (new), client/package.json
- Migrated the build pipeline from
tsctotsup. - New
tsup.config.tsbuilds dual CJS + ESM output with tree-shaking, source maps, and proper externals — reducing the installed bundle footprint for downstream consumers. - Added
moduleandexportsfields topackage.jsonfor ESM-first consumers and bundlers. - Removed the unused
axiosruntime dependency (it was not imported anywhere in the codebase).
Test Suites: 20 passed, 20 total
Tests: 261 passed, 261 total
All existing tests pass. The fee estimation suite (tests/fee-estimation.test.ts) was verified to be unaffected by the dynamic stats refactor.
- All 261 tests pass locally
- No new lint or TypeScript errors
- Backward compatible — existing callers need no config changes
-
axiosremoved fromdependencies -
tsupadded todevDependenciesonly (not bundled into the SDK)
Closes #497 Closes #498 Closes #501 Closes #503