---
name: bsv-script-conditions
description: "Design or implement spending conditions in BSV script: several keys (multi-key), not before a time using nLockTime and nSequence, revealing a secret, and combinations such as inheritance and time-based recovery. Use when asked to 'add a timelock', 'build a vault', 'multi-sig', 'two of three keys', 'inheritance', 'recovery after inactivity', 'escrow', 'CHECKLOCKTIMEVERIFY', or anything about conditions on when and how money can be spent."
---

> Start from [bitcoinsv-design](../bitcoinsv-design/SKILL.md). Shared states, labels, errors, amounts and fees: [shared patterns](../bitcoinsv-design/references/shared-patterns.md).

# Lock BSV behind keys, time or a secret

**Scope:** Custom locking conditions and the interface around them: what they do, how time works on BSV, and how they fail.

**Does NOT cover:**

- Ordinary backup of a single-key wallet: see [bsv-backup-and-recovery](../bsv-backup-and-recovery/SKILL.md)
- Building and signing transactions in general: see [bsv-actions](../bsv-actions/SKILL.md)

**Cross-references:** [bsv-actions](../bsv-actions/SKILL.md), [bsv-backup-and-recovery](../bsv-backup-and-recovery/SKILL.md), [shared patterns](../bitcoinsv-design/references/shared-patterns.md).

An output's locking script can say almost anything: two of three keys, not before a date, only if a secret is revealed. These conditions turn a wallet into more than a purse, and they are also the fastest way to lock people out of their own money. Two BSV facts decide the design. Time is enforced with `nLockTime` and `nSequence`, because `CHECKLOCKTIMEVERIFY` and `CHECKSEQUENCEVERIFY` are no-ops on BSV and a script relying on them locks nothing. And new pay-to-script-hash outputs are not allowed, so every condition is visible in the output from the moment it exists.

## ALWAYS

- Build time conditions with nLockTime and nSequence, and test that an early spend fails. A test that only proves the late spend succeeds proves nothing. _([costs money](https://www.bitcoinsv.design/guide/rule/b62aa2ae7d/))_
- State where a pre-signed future transaction lives, who holds it, and what happens if the inputs are spent before its date. That is a backup requirement, not an implementation detail. _([costs money](https://www.bitcoinsv.design/guide/rule/31f330a837/))_
- Warn before a condition becomes unmeetable, not after. "One more lost key and this is unrecoverable" is useful; the same message afterwards is not. _([costs money](https://www.bitcoinsv.design/guide/rule/039e20ae48/))_
- Back up the wallet configuration alongside the key material, and include it in the recovery drill. A condition nobody can reconstruct is money nobody can move. See Backups. _([costs money](https://www.bitcoinsv.design/guide/rule/85a7914dd7/))_
- Back up the wallet configuration with the same care as a key. It names every key in the arrangement. _([costs money](https://www.bitcoinsv.design/guide/rule/63bb703e74/))_
- Make sure they keep the pre-signed transaction, since without it the path is theoretical. The wallet should hold it and the backup should include it. _([costs money](https://www.bitcoinsv.design/guide/rule/6b029ec268/))_

## NEVER

- Let a user create a condition they have not demonstrably tested. Require a small-value rehearsal of the unlock path before real money goes in. _([costs money](https://www.bitcoinsv.design/guide/rule/b13bd63634/))_
- Offer a period shorter than a few months. A path that opens while somebody is on a long trip is a theft risk dressed as a feature. _([costs money](https://www.bitcoinsv.design/guide/rule/a67beef669/))_
- Add somebody to a recovery path without telling them. The arrangement only works if they still have their key when it matters. _([costs money](https://www.bitcoinsv.design/guide/rule/83ba29796b/))_
- Let somebody be removed from a recovery path without the wallet confirming the replacement transaction actually reached everybody who needs it. _([costs money](https://www.bitcoinsv.design/guide/rule/9f8f455aa6/))_
- Finish setup without the user having restored from it once, with a small amount. An untested multi-key wallet has more ways to fail than a single-key one. _([costs money](https://www.bitcoinsv.design/guide/rule/18966d7037/))_
- Let the limit be raised with a single key. Raising the threshold for spending is itself a high-value action and needs the quorum. _([costs money](https://www.bitcoinsv.design/guide/rule/3e6a8e94db/))_

## Patterns

_Design guidance in each pattern comes from the guide page it cites. Method names, arguments and code are implementation notes checked against `@bsv/sdk` 4.0.0._

### 1. Lock by time with nLockTime and nSequence

**When:** Anything that should not be spendable before a date or block height.

**How:**

1. Set `lockTime` on the `createAction` call (a block height or a timestamp) and give each input a `sequenceNumber` below the final value so the lock applies.
2. A locked transaction is one that cannot be broadcast yet, not an output nobody can spend. Build it with `options: { noSend: true }` so it is signed but not sent, and keep it.
3. Test that an early spend actually fails. A test that only proves the late spend succeeds proves nothing.
4. State the minimum transaction version the script needs and set `version` accordingly: scripts using the opcodes restored by the Chronicle upgrade only run for transactions marked with that version.

```ts
import { WalletClient } from "@bsv/sdk";

const wallet = new WalletClient("auto", "example.com");
declare const outpoint: string, lockingScript: string;

const { tx } = await wallet.createAction({
  description: "Recovery path for Maya",
  lockTime: 1_000_000, // a block height in the future
  inputs: [{ outpoint, inputDescription: "Savings", sequenceNumber: 0 }],
  outputs: [{ lockingScript, satoshis: 50_000, outputDescription: "To recovery key" }],
  options: { noSend: true },
});
```

**Error states:**

- **Script copied from elsewhere uses CHECKLOCKTIMEVERIFY or CHECKSEQUENCEVERIFY:** Do not ship it. On BSV it runs, returns true and locks nothing; rebuild the condition with nLockTime and nSequence.

_Source: [Spending conditions](https://www.bitcoinsv.design/guide/patterns/spending-conditions/)_

### 2. Keep what makes the condition spendable

**When:** Any condition beyond a single key.

**How:**

1. Say where a pre-signed future transaction lives, who holds it, and what happens if its inputs are spent before its date. That is a backup requirement.
2. Back up the wallet configuration (script, keys, parameters) alongside the key material, and include it in the recovery drill. A quorum of signers with no record of the arrangement cannot construct a spend.
3. Treat the condition as public. A recovery path that works only because nobody knows it exists is not a security property.

_Source: [Spending conditions](https://www.bitcoinsv.design/guide/patterns/spending-conditions/)_

### 3. Present it as consequences, with templates

**When:** Setting up or showing any condition.

**How:**

1. Say what it does, not what it is: "Locked until 1 March 2027. Nobody can move this, including you." "Needs 2 of your 3 keys."
2. Offer two or three named arrangements rather than a condition builder, and let setup be saved and resumed: these need several devices or people.
3. Show the whole schedule, including what has not happened yet. Show dates as dates, not countdowns.
4. Show multi-key progress as collected and outstanding, naming the device or person still needed.
5. Require a small-value rehearsal of the unlock path before real money goes in, and warn before a condition becomes unmeetable: "One more lost key and this is unrecoverable."

_Source: [Spending conditions](https://www.bitcoinsv.design/guide/patterns/spending-conditions/)_

## All the rules

`references/rules.md`: 50 rules from 4 pages, 21 of them costly, most costly first.
Every rule in the guide, most costly first: https://www.bitcoinsv.design/api/rules.json

## Implementation resources

- **[@bsv/sdk](https://bsv-blockchain.github.io/ts-sdk/)**: The TypeScript SDK: `WalletClient` for every BRC-100 call, `AuthFetch` for HTTP 402, transactions, scripts and BEEF. Source at github.com/bsv-blockchain/ts-sdk.
- **[Wallet Toolbox](https://github.com/bsv-blockchain/wallet-toolbox)**: The wallet side of the interface: storage, signing and `WalletPermissionsManager`. Start here if you are building a wallet rather than an app.
- **[BRCs](https://github.com/bsv-blockchain/BRCs)**: Every proposal the skills cite, by number.

---

_Generated from https://www.bitcoinsv.design/, Open BSV License Version 6. Rules are extracted from the guide's pages and cannot be out of date about what it says; the patterns may still need updating._
