MidnightContract

High-level interface for calling Midnight smart contract circuits from Android.

Wraps the full pipeline: state fetch → circuit execution → ZK proving → balancing → submission. The developer never touches hex strings, JS expressions, or manual orchestration.

val bboard = MidnightContract.create(config) {
name = "bboard"
contractJs = assets.open("runtime/bboard-contract-iife.js")
address = "4b459404..."
witness("localSecretKey") { WitnessResult(null, secretKeyBytes) }
initialPrivateState = mapOf("secretKey" to ByteArray(32))
coinPublicKey = walletKeys.coinPublicKey
}

val receipt = bboard.call("post", "Hello from Android!")

Types

Link copied to clipboard
object Companion
Link copied to clipboard

DSL builder for creating a MidnightContract.

Link copied to clipboard
data class ReadOutcome(val json: String?, val error: String?)

Per-key outcome of a readMany batch: the circuit's JSON result or its error message.

Link copied to clipboard
data class ReadRequest(val key: String, val circuitName: String, val args: List<Any?> = emptyList())

One view-circuit invocation in a readMany batch, identified by key.

Properties

Link copied to clipboard

Functions

Link copied to clipboard
suspend fun call(circuitName: String, vararg args: Any?, unshieldedFundingJson: String? = null, unshieldedWithdrawalJson: String? = null, onProgress: suspend (ContractCallStage) -> Unit? = null): TransactionReceipt

Call a circuit and submit the transaction to the blockchain.

Link copied to clipboard
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.

Link copied to clipboard
suspend fun deploy(onProgress: suspend (ContractCallStage) -> Unit? = null): DeployResult

Deploy a new contract instance to the blockchain.

Link copied to clipboard
suspend fun ledger(): MidnightLedger

Read the contract's ledger state losslessly.

Link copied to clipboard

Observe this contract's ledger state as it changes on-chain (#255).

Link copied to clipboard
suspend fun prepare(circuitName: String, vararg args: Any?, unshieldedFundingJson: String? = null, unshieldedWithdrawalJson: String? = null, onProgress: suspend (ContractCallStage) -> Unit? = null): PreparedTransaction

Execute and prove a circuit without submitting (offline mode).

Link copied to clipboard
suspend fun read(circuitName: String, vararg args: Any?): String

Call a view/getter circuit and return its result as JSON — no proving, no transaction. Reads a contract's computed views (e.g. a treasury balance or a proposal struct) that aren't exposed as raw ledger fields via observeLedger. BigInt → decimal string, Bytes → hex, structs preserved; parse the JSON per circuit. A read-only handle (no signing keys) is sufficient.

Link copied to clipboard
suspend fun readLocal(circuitName: String, vararg args: Any?): String

Run a PURE (or otherwise state-independent) circuit LOCALLY — against the contract's initialState(), with NO deployed address and NO chain fetch — and return its result as JSON.

Link copied to clipboard
suspend fun readMany(requests: List<MidnightContract.ReadRequest>, notIndexedTimeoutMs: Long = 0): Map<String, MidnightContract.ReadOutcome>

Read MANY view circuits in one shot: ONE state fetch, ONE engine session, every circuit against the SAME state snapshot (each isolated on a native clone). Failures are captured per key instead of failing the batch — probing patterns (enumerate proposals until the contract's not-found assert) read the error from the outcome.