callIdempotent

suspend fun callIdempotent(circuitName: String, vararg args: Any?, isDoneOnLedger: suspend () -> Boolean, onProgress: suspend (ContractCallStage) -> Unit? = null): TransactionReceipt?

Idempotent single call (#254): if isDoneOnLedger is already true the on-chain effect is present, so this SKIPS the call and returns null (no double-submit); otherwise it runs call and returns the receipt.

The check is anchored to the LEDGER, not local state — so a retry (after a crash, or on resume) is always safe: the chain decides whether the work is done. com.midnight.kuira.sdk MidnightSdk.runProtocol's step is the multi-step generalization of this pattern.