unlockingScript

open override fun unlockingScript(flatTx: ByteArray, inputIdx: Long, sigHashType: ByteArray, inputAmount: Long, spendingProposal: SpendingProposal? = null): SatoshiScript

Build the unlocking ("satisfier") script that authorises spending a UTXO locked to this destination.

The wallet's signing path (signInput in wallet.kt) calls this with the in-flight transaction bytes, the input index being signed, the sighash flags, and the input's amount. The returned script is then planted as tx.inputs[idx].script.

Three pushes, in this order — the network's interpreter consumes them left-to-right and feeds the altstack the values the template script pops in timeLockTemplateScript:

  1. Template script bytes. The locking script only commits to the template via its hash160; the spender must reveal the full template here so the network can verify hash160(template) == committed.

  2. Constraint script bytes. Same story — the locking script commits to hash160(constraint), the constraint contains the owner pubkey, and we reveal it so the network can both verify the hash and push the pubkey onto the altstack for CHECKSIGVERIFY.

  3. Schnorr signature over the canonical sighash. The scriptCode used in the sighash is the template script bytes (NOT the locking script, NOT the constraint) — that's the Nexa template-script convention, mirroring what Pay2PubKeyTemplateDestination does.

The shape (3 pushes vs the 2-push form Pay2PubKeyTemplateDestination uses at payDestination.kt:510) reflects that the time-lock template is not a well-known op — well-known templates skip the template push because the network already knows the bytes. We can't.

Always called with spendingProposal == null because atomicSpending is true: time-lock spends don't go through a multi-party signing protocol.