@@ -228,6 +228,46 @@ const active = await tikka.raffle.listActive();
228228simulate tx → estimate fee → build XDR → request wallet signature → submit → poll confirmation
229229```
230230
231+ ### Fee Estimation
232+
233+ Call ` FeeEstimatorService.estimateFee({ method, params }) ` before asking the user to sign.
234+ Returns ` { xlm, stroops, resources } ` — no wallet needed (falls back to an anonymous source key).
235+ Re-call whenever inputs change; each call runs a fresh ` simulateTransaction ` .
236+
237+ ``` ts
238+ const estimate = await feeEstimator .estimateFee ({
239+ method: ContractFn .BUY_TICKET ,
240+ params: [raffleId , buyerPublicKey , quantity ],
241+ });
242+ // estimate.xlm → "0.0051000" (human-readable)
243+ // estimate.stroops → "51000"
244+ // estimate.resources → { cpuInstructions, diskReadBytes, … }
245+ ```
246+
247+ ### Confirmation Polling
248+
249+ After submit, ` lifecycle.poll() ` polls ` getTransaction ` with exponential backoff until the
250+ transaction reaches ` SUCCESS ` or ` FAILED ` . ` RpcService.getTransaction() ` is single-shot;
251+ the retry loop and backoff live entirely in ` lifecycle.poll() ` .
252+
253+ | Parameter | Default | Override via |
254+ | ---| ---| ---|
255+ | Timeout | 60 s | ` PollConfig.timeoutMs ` |
256+ | Initial interval | 2 s | ` PollConfig.intervalMs ` |
257+ | Backoff factor | 1.5× | ` PollConfig.backoffFactor ` |
258+ | Max interval | 10 s | ` PollConfig.maxIntervalMs ` |
259+
260+ Pass ` poll ` inside ` InvokeLifecycleOptions ` to override per-call:
261+
262+ ``` ts
263+ await lifecycle .invoke (ContractFn .BUY_TICKET , params , {
264+ poll: { timeoutMs: 90_000 , intervalMs: 3_000 },
265+ });
266+ ```
267+
268+ RPC-level transient errors (429, 500–504) are retried separately by ` RpcService.executeRequest() `
269+ and do not consume the poll timeout.
270+
231271### Wallet Adapters
232272
233273| Wallet | Priority | Notes |
0 commit comments