TimeLockVaultDestination

class TimeLockVaultDestination(chain: ChainSelector, var unlockValue: Long, _secret: Secret, var hdIndex: Long, var contractName: String? = null) : Pay2TemplateDestination

Pay-to-Template destination for a single time lock vault.

Script-level half of the time lock vault: given a chain, an owner secret, an unlock value (a block height, or a Unix timestamp at/above the BIP-65 500,000,000 split), and a BIP-44 leaf index, this object produces the locking script, the nexa: address, and — at spend time — the satisfier that authorises moving the coins out.

The on-chain layout is a standard Nexa P2T output:

[ tag 0014 ][ templateHash (constant) ][ constraintHash ][ unlockValue, hdIndex ]
  • template is the same script for every vault on the network: pop the index (and ignore it), enforce CHECKLOCKTIMEVERIFY on the unlock value, then CHECKSIGVERIFY against the pubkey.

  • constraint is one push of the 33-byte compressed pubkey derived from secret; its hash160 is what the address commits to.

  • visibleConstraint pushes the cleartext (unlockValue, hdIndex) — visible because the template reads them via FROMALTSTACK, and also load-bearing for wallet rediscovery after a seed restore.

The vault address is a pure function of (chain, pubkey, unlockValue, hdIndex). Identical inputs produce identical addresses; differing inputs produce differing addresses. The destination does not store the address — any party with the four inputs can recompute it.

Persistence is restricted to SerializationType.DISK so the in-process secret cannot accidentally serialise onto the wire. Only the primary inputs are written; derived scripts are rebuilt from them on load.

atomicSpending is true: the satisfier is produced inline by unlockingScript without going through a multi-party signing protocol.

See docs/time-lock-vault.md for the architectural overview and compatibility invariants.

Constructors

Link copied to clipboard
constructor(chain: ChainSelector, unlockValue: Long, _secret: Secret, hdIndex: Long, contractName: String? = null)
constructor(chainSelector: ChainSelector, stream: BCHserialized)

Deserialization constructor. Supplies placeholder primary-ctor args (unlockValue=1, EmptySecret, hdIndex=0) that pass init's range checks, then calls BCHdeserialize to overwrite secret/unlockValue/ hdIndex with the real values from the stream.

Types

Link copied to clipboard
object Companion

Properties

Link copied to clipboard
open override val address: PayAddress

Get the %budoc/glossary/P2SH or %budoc/glossary/P2PKH address associated with this destination Note that only a subset of PayDestinations have addresses. A PayAddress will only exist if this destination constrains spending to require a signature (in the P2PKH case) or a script (P2SH case)

Link copied to clipboard
open override val atomicSpending: Boolean = true

All derived classes that require the execution of a potentially interactive protocol to spend should set this to false and implement member fns

Link copied to clipboard
open override val bloomFilterData: ByteArray?

Return a set of bytes that can be put into a bloom filter to select any transaction that contains this destination

Link copied to clipboard
Link copied to clipboard
open override var contractName: String?

Name of the WalletContract this destination belongs to, or null if not contract-attributed.

Link copied to clipboard
open override val derivedType: Int

What type of destination is this?

Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
open var index: Long

If a Bip44 wallet, this is be the BIP44 index. Otherwise its the an incrementing integer every time a new destination is created

Link copied to clipboard
open override val maxSignedSize: Long

Exact satisfier size for a time lock spend.

Link copied to clipboard

An indication to retire this address as soon as coins are received (typically used for change). RAM only

Link copied to clipboard
open override var pubkey: ByteArray

Get the public key if a single signature is needed to spend this destination

Link copied to clipboard
open override var secret: Secret?

Get the secret key if a single signature is needed to spend this destination

Link copied to clipboard
Link copied to clipboard

Functions

Link copied to clipboard
open override fun BCHdeserialize(stream: BCHserialized): BCHserialized

Rehydrates this destination from the bytes produced by serializeDerived.

Link copied to clipboard
open override fun BCHserialize(format: SerializationType = SerializationType.UNKNOWN): BCHserialized
Link copied to clipboard
open fun beginProposal(tx: iTransaction, inputIdx: Int, reason: String): SpendingProposal?

If atomicSpending is false, this is how you initiate whatever protocol is needed to sign this transaction. This should only be called if this is your own spending proposal (it is expected that the user has already agreed to this spend)

Link copied to clipboard
open override fun clean()

Zero key material from this object to minimize exposure scope and time

Link copied to clipboard
Link copied to clipboard
fun contentEquals(other: Any?): Boolean

Two TimeLockVaultDestinations are equal iff they would produce the same on-chain locking script — i.e., the same vault address. That's fully determined by (chainSelector, pubkey, unlockValue, hdIndex):

Link copied to clipboard
open operator override fun equals(other: Any?): Boolean
Link copied to clipboard
open override fun groupedLockingScript(groupId: GroupId, groupAmount: Long): SatoshiScript

Get the output script needed to send tokens to this group destination. This script will contain spend constraints in the non-P2SH case, or in the P2SH case this script only constrains spending to execution of the redeemScript and any additional constraints are located in the redeemScript

Link copied to clipboard
open override fun hashCode(): Int

Standard polynomial-accumulation hash over the same fields equals() compares. The multiplier 31 is the Java/Kotlin convention: it's an odd prime (good bit distribution, no bit loss as values accumulate) and the JVM optimizes 31 * x to (x << 5) - x. Folds each field into a different bit range, so similar destinations (e.g. sequential hdIndex) don't cluster in adjacent HashMap buckets.

Link copied to clipboard
open override fun lockingScript(): SatoshiScript

Get the locking script needed to send coins to this destination. This script will contain spend constraints in the non-template case, or in the template/P2SH case this script contains the hash of the template/redeem script.

Link copied to clipboard
open fun output(satoshis: Long): iTxOutput

Get an output (constrained to this destination) suitable for placing in a transaction

Link copied to clipboard
fun pkh(): ByteArray?

Calculate the public key hash (PKH)

Link copied to clipboard
open override fun satisfierScript(flatTx: ByteArray, inputIdx: Long, sigHashType: ByteArray, inputAmount: Long, spendingProposal: SpendingProposal? = null): SatoshiScript
Link copied to clipboard
open override fun serialize(stream: BCHserialized): BCHserialized
Link copied to clipboard

Writes the time-lock-specific fields in disk format. These bytes get appended after PayDestination.serializeTypeAndDerived has written the shared index: i64 framing every destination starts with — that framing runs unconditionally and is independent of this method.

Link copied to clipboard

serialize any derived class & the type indicator

Link copied to clipboard
open override fun templateScript(): SatoshiScript

Get the template script needed to spend this destination. This script is committed to in the locking script via hash, and must be provided in full in the unlocking script. For P2SH blockchains, this will return the redeemScript since templates are a generalization of P2SH.

Link copied to clipboard

Builds the time lock constraint script for a given owner pubkey.

Link copied to clipboard

Builds the time lock template (redeem) script.

Link copied to clipboard
open fun toByteArray(format: SerializationType = SerializationType.UNKNOWN): ByteArray
Link copied to clipboard
open override fun toString(): String
Link copied to clipboard

Get the output script needed to send native coins to this destination. This script will contain spend constraints in the non-P2SH case, or in the P2SH case this script only constrains spending to execution of the redeemScript and any additional constraints are located in the redeemScript

Link copied to clipboard
open override fun unlockingScript(vararg params: ByteArray): SatoshiScript

Create a spend (input) script that will satisfy the constraints specified by the lockingScript and the templateScript (if applicable). This script will contain the redeemScript in the P2SH case.

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.

Link copied to clipboard

Encodes per-vault parameters as the script-pushable opcodes that go into a time lock vault's locking script.