Locks
An amount put out of reach until a block height, and paid out by anybody once that height arrives. It is what a vesting schedule is made of, what a mainnet distribution sits behind, and the second provable promise a token creator can make — the first being a burn, which is not the same promise and must never be shown as though it were.
Using it
./baklava timelock -asset BKLV -amount 20000000 -height 2600000
./baklava timelock -asset <token id> -amount 250000000 -height 2600000 -to bkx1...
./baklava timelock -asset pool:<pool id> -amount 50000000 -height 2600000
./baklava tranche -tranche 5e3540b1...
./baklava release -tranche 5e3540b1...Or /timelock, /tranche and /release from the console. It is /timelock and not /lock because /lock locks the wallet, and a command name that collides is a command somebody runs by accident.
A lock is an address, not a flag on a balance.
The money moves. It leaves the locker's account and sits at SHA-256("baklava/release/v1")[:20], twenty bytes no key produces, and a rule moves it out again when the height arrives.
The obvious shape is a condition inside the debit path — and that path is on every module's route, so it has to stay arithmetic. Worse, a balance that means different things to different readers is how a wallet ends up displaying money nobody can spend. This is the same shape the chain already wears three times over: a stake is moved rather than marked, a listed item belongs to the escrow, and a burned share sits at an address with no key.
What the rules are
| Three kinds of asset | BKLV, a token balance, or a liquidity share. The tranche records which, so nothing has to work it out by looking the id up somewhere. |
|---|---|
| Anybody may release it | And it pays the address the tranche names, never the sender — who pays the fee for the privilege. There is nothing left to decide once the height has arrived, so requiring a particular sender would only mean a payment that never arrives because one person forgot. |
| Nothing can cancel it | No transition redirects a tranche, brings it forward, or takes it back. A height already past is refused rather than paid at once: accepting it would charge a fee for a transaction that changed nothing and read, to whoever sent it, as though the lock had worked. |
| A share lock pays its own sender | The one asymmetry. A free recipient would make it a share transfer with one block of delay — and a share's non-transferability is an absence rather than a check, so ending it sideways in a rule about time would describe a transferable share without ever deciding what one is. What a share lock is for is the proof “I cannot take this liquidity out before N”, and that proof has no use for a recipient field. |
| It costs no price of its own | A token and a collection pay ten BKLV because they write a row every node carries for ever. A tranche is deleted the moment it is paid, so it pays a fee and nothing else. |
A lock is not a burn
They look alike on a page and they are opposite promises. A burn is one-way: the reserves behind those shares can never leave, ever. A lock comes back at its height and then they can. A surface that prints them in one column teaches a reader they are the same thing, so Launch shows them as separate states with the height on the row.
It is also where a mainnet supply sits before it reaches anybody.
A genesis file can carry a release list: tranches written at height 0, funded from the release address, on a schedule no transaction can change. The derivation refuses both directions of a mismatch — owing more than is held is a promise the chain cannot keep, and holding more than is owed is a silent burn.
Put a keyless treasury at the end of it and no key exists anywhere on the path: the supply leaves the release address on its schedule, into a treasury nobody holds, and out of there only through a spend proposal standing four epochs in public.
The reasoning in full is under The lock in the protocol document.