Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/packages/helpers/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Utility libraries and helper tools for common BSV operations. Includes high-leve
| -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| [@bsv/simple](simple.md) | High-level wallet API for browser and server — manage payments, tokens, inscriptions, DIDs, and credentials |
| [@bsv/wallet-helper](wallet-helper.md) | Fluent transaction builder for explicit wallet-backed transactions, BRC-29 derivation, and ordinal support |
| [@bsv/templates](templates.md) | Predefined ScriptTemplate examples for protocol engineers, including OpReturn, MultiPushDrop, and P2MSKH lock/unlock patterns |
| [@bsv/templates](templates.md) | ScriptTemplate implementations including OpReturn, MultiPushDrop, P2MSKH, and the hardware-backed R1K1Wallet |
| [@bsv/did](did.md) | SD-JWT VC and optional `did:key` helpers for BSV SDK identity keys |
| [@bsv/did-client](did-client.md) | DID client for creating, revoking, and querying on-chain DIDs with overlay broadcast |
| [@bsv/air-gap](air-gap.md) | One-directional optical air-gap transport — fountain-coded QR parts for arbitrary bytes |
Expand Down
64 changes: 61 additions & 3 deletions docs/packages/helpers/templates.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ id: pkg-templates
title: '@bsv/templates'
kind: package
domain: helpers
version: '1.9.6'
version: '1.10.0'
source_repo: 'bsv-blockchain/ts-stack'
last_updated: '2026-07-30'
last_verified: '2026-07-30'
last_updated: '2026-08-14'
last_verified: '2026-08-14'
review_cadence_days: 30
npm: 'https://www.npmjs.com/package/@bsv/templates'
repo: 'https://github.com/bsv-blockchain/ts-stack/tree/main/packages/helpers/ts-templates'
Expand Down Expand Up @@ -43,6 +43,7 @@ console.log(decodedData) // ['APP', '{"action":"vote"}']
- **OpReturn** — Non-spendable data storage; create and decode OP_RETURN scripts
- **MultiPushDrop** — Encrypted data tokens with multiple trusted owners; BRC-95 format
- **P2MSKH** — Pay-to-Multisig-Key-Hash; M-of-N threshold signing with wallet support
- **R1K1Wallet** — Salted P-256 hardware signing with independent secp256k1 recovery
- **Script utilities** — Type detection, parsing, serialization helpers
- **Wallet integration** — Templates accept WalletInterface for BRC-29/BRC-42 derivation

Expand Down Expand Up @@ -121,6 +122,59 @@ const customInstructions = {
const unlocker = new P2MSKH().unlock(wallet, customInstructions)
```

### Create an R1-K1 hardware-backed output

```typescript
import { Hash, type PrivateKey, Utils } from '@bsv/sdk'
import { R1K1Wallet } from '@bsv/templates'

declare const compressedP256PublicKeyHex: string
declare const k1RecoveryPrivateKey: PrivateKey
declare const signWithYubiKeyPiv: (digest: Uint8Array) => Promise<Uint8Array>

const template = new R1K1Wallet()
const r1PublicKey = Utils.toArray(compressedP256PublicKeyHex, 'hex')
const salt = crypto.getRandomValues(new Uint8Array(32))
const lockingScript = await template.lock(
Hash.hash160([...r1PublicKey, ...salt]),
Hash.hash160(k1RecoveryPrivateKey.toPublicKey().encode(true) as number[])
)

const normalSpend = template.unlock({
path: 'r1',
publicKey: r1PublicKey,
salt,
signDigest: signWithYubiKeyPiv
})
const recoverySpend = template.unlock({
path: 'k1',
privateKey: k1RecoveryPrivateKey
})
```

The R1 signer receives the final 32-byte transaction digest. A PIV adapter must
submit it unchanged to GENERAL AUTHENTICATE and return either the DER ECDSA
signature produced by the device or raw 64-byte `r || s`; applying SHA-256
again creates an invalid signature. Preserve each private 32-byte salt with the
wallet metadata. The salt hides a reused PIV public key only until the R1 output
is spent.

The generated locking script is 959,632 bytes after both commitments are
baked, above common 500 KB miner policy. Confirm target-miner policy before
funding it.

An R1 unlocking script also pushes the BIP-143 preimage, whose `scriptCode`
contains roughly 960 KB of the contract after `OP_CODESEPARATOR`. The R1 path
therefore involves about 2 MB of locking-plus-unlocking script material, and
the witness alone adds roughly 960 KB to the spending transaction. Account for
the resulting fees and confirm any maximum-transaction policy; `estimateLength`
includes this preimage push. The K1 unlocking script remains small.

PIV proves that the hardware key signed the supplied digest, but a YubiKey
does not display or independently validate the Bitcoin transaction. PIN and
touch policies protect key use, not transaction intent; review the transaction
on a trusted host before approving it.

## Key concepts

- **ScriptTemplate Interface** — Implements `lock()` to create locking script and `unlock()` to sign/spend
Expand All @@ -129,6 +183,7 @@ const unlocker = new P2MSKH().unlock(wallet, customInstructions)
- **Multisig** — M-of-N threshold signing; requires m private keys to unlock
- **Wallet Integration** — Templates accept WalletInterface for wallet-compatible key derivation (BRC-29, BRC-42)
- **Direct Key Mode** — Can also use raw public/private keys without wallet
- **Hardware Digest Signer** — R1K1Wallet accepts DER output from a PIV signer without exposing the P-256 private key
- **Protocol ID** — Identifier for script family; used in wallet derivation contexts
- **Reasonableness Limit** — Anti-DoS measure for PushDrop templates

Expand All @@ -138,6 +193,7 @@ const unlocker = new P2MSKH().unlock(wallet, customInstructions)
- Building applications that need P2PKH or multisig payment flows
- Storing data on-chain with OP_RETURN
- Implementing multi-owner token systems with PushDrop
- Building hardware-backed outputs with an intentionally inconvenient K1 recovery path
- Learning Bitcoin Script patterns

## When NOT to use this
Expand All @@ -161,6 +217,8 @@ const unlocker = new P2MSKH().unlock(wallet, customInstructions)
- **Lock/Unlock consistency** — Lock and unlock must use same protocol ID, key ID, and counterparty parameters
- **Wallet context required** — Some templates require WalletInterface if using wallet derivation; pass explicitly
- **Signature generation async** — All `unlock().sign()` calls are async; use await
- **R1 salt backup** — Losing an output's private salt makes its R1 path unusable; retain the K1 recovery key and salt metadata separately
- **Miner policy** — R1K1Wallet's synthesized P-256 script exceeds common 500 KB policy limits
- **OP_RETURN encoding** — Data is UTF-8 by default; encode as hex first and specify `enc: 'hex'` for binary

## Related packages
Expand Down
10 changes: 5 additions & 5 deletions docs/reference/package-api-migrations.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ id: package-api-migrations
title: 'Package API, Declarations, and Migration Ledger'
kind: reference
version: '1.0.0'
last_updated: '2026-08-13'
last_verified: '2026-08-13'
last_updated: '2026-08-14'
last_verified: '2026-08-14'
review_cadence_days: 30
status: stable
tags: [reference, packages, api, declarations, migrations, release-notes]
Expand Down Expand Up @@ -47,7 +47,7 @@ and clean-consumer tests remain the executable type authority.
| `@bsv/payment-express-middleware` | `2.1.1` | `2.1.5` | patch | [API and usage](../packages/middleware/payment-express-middleware.md) | No consumer migration is required; legacy x-bsv-payment JSON behavior remains supported, and Express 4 and 5 applications use their own peer-provided Express installation. |
| `@bsv/sdk` | `2.3.1` | `2.4.0` | minor | [API and usage](../packages/sdk/bsv-sdk.md) | Existing mainnet, testnet, and local routing is unchanged. TTN consumers select teratestnet explicitly because BRC-100 getNetwork continues to report testnet for all test-family chains. |
| `@bsv/simple` | `0.4.1` | `0.5.0` | minor | [API and usage](../packages/helpers/simple.md) | Existing overlay configurations are unchanged. TTN consumers select network teratestnet and use @bsv/sdk 2.4 or later. |
| `@bsv/templates` | `1.9.1` | `1.9.6` | patch | [API and usage](../packages/helpers/templates.md) | No consumer migration is required; template APIs, supported imports, and generated script semantics are unchanged. |
| `@bsv/templates` | `1.9.1` | `1.10.0` | minor | [API and usage](../packages/helpers/templates.md) | No existing consumer migration is required; existing template APIs and generated scripts are unchanged. New R1K1Wallet consumers await lock(), retain each private 32-byte salt, and provide a PIV signer that signs the supplied digest directly without hashing it again. |
| `@bsv/teranode-listener` | `1.1.1` | `1.1.4` | patch | [API and usage](../packages/network/teranode-listener.md) | No consumer migration is required; listener APIs, topics, and network configuration are unchanged. |
| `@bsv/verifast` | `0.3.0` | `0.3.4` | patch | [API and usage](../packages/sdk/verifast.md) | No consumer migration is required; exports, verification behavior, worker protocols, package paths, and runtime defaults are unchanged. |
| `@bsv/wallet-helper` | `0.1.1` | `0.1.6` | patch | [API and usage](../packages/helpers/wallet-helper.md) | No consumer migration is required; fluent builder APIs and transaction semantics are unchanged. |
Expand Down Expand Up @@ -411,8 +411,8 @@ CLI entry points: `{"fund-metanet":"./dist/index.mjs"}`.

- Package documentation: [docs/packages/helpers/templates.md](../packages/helpers/templates.md)
- Source: [packages/helpers/ts-templates](https://github.com/bsv-blockchain/ts-stack/tree/main/packages/helpers/ts-templates)
- Release note: Consolidates MultiPushDrop script construction while preserving the exact generated locking-script sequence, adds an exact-tarball browser-consumer and bundle-size contract, and points contributors to the canonical root policy.
- Migration: No consumer migration is required; template APIs, supported imports, and generated script semantics are unchanged.
- Release note: Adds the R1K1Wallet ScriptTemplate for salted P-256 hardware signing with an independent secp256k1 recovery path, including a checksummed static Runar artifact and browser-safe lazy decompression. Also consolidates MultiPushDrop script construction without changing its output, adds an exact-tarball browser-consumer and bundle-size contract, and points contributors to the canonical root policy.
- Migration: No existing consumer migration is required; existing template APIs and generated scripts are unchanged. New R1K1Wallet consumers await lock(), retain each private 32-byte salt, and provide a PIV signer that signs the supplied digest directly without hashing it again.

| Public subpath | Runtime target(s) | Declaration target(s) |
| -------------- | --------------------------------------- | ------------------------------------------- |
Expand Down
2 changes: 1 addition & 1 deletion docs/reference/stack-facts.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ authorized release action.
| helpers | `@bsv/did-client` | `1.3.0` | browser-library | browser-bundler, browser-esm, node-cjs, node-esm, umd-global | browser, node, umd | `>=22` | [packages/helpers/did-client](https://github.com/bsv-blockchain/ts-stack/tree/main/packages/helpers/did-client) |
| helpers | `@bsv/fund-wallet` | `1.4.3` | cli | cli | node | `>=22` | [packages/helpers/fund-wallet](https://github.com/bsv-blockchain/ts-stack/tree/main/packages/helpers/fund-wallet) |
| helpers | `@bsv/simple` | `0.5.0` | browser-library | browser-bundler, browser-esm, node-cjs, node-esm | browser, node | `>=22` | [packages/helpers/simple](https://github.com/bsv-blockchain/ts-stack/tree/main/packages/helpers/simple) |
| helpers | `@bsv/templates` | `1.9.6` | browser-library | browser-bundler, browser-esm, node-cjs, node-esm | browser, node | `>=22` | [packages/helpers/ts-templates](https://github.com/bsv-blockchain/ts-stack/tree/main/packages/helpers/ts-templates) |
| helpers | `@bsv/templates` | `1.10.0` | browser-library | browser-bundler, browser-esm, node-cjs, node-esm | browser, node | `>=22` | [packages/helpers/ts-templates](https://github.com/bsv-blockchain/ts-stack/tree/main/packages/helpers/ts-templates) |
| helpers | `@bsv/wallet-helper` | `0.1.6` | node-library | node-cjs, node-esm | node | `>=22` | [packages/helpers/bsv-wallet-helper](https://github.com/bsv-blockchain/ts-stack/tree/main/packages/helpers/bsv-wallet-helper) |
| helpers | `create-bsv-app` | `1.1.0` | cli | cli | node | `>=22` | [packages/helpers/create-bsv-app](https://github.com/bsv-blockchain/ts-stack/tree/main/packages/helpers/create-bsv-app) |
| messaging | `@bsv/authsocket` | `2.1.5` | node-library | node-cjs, node-esm | node | `>=22` | [packages/messaging/authsocket](https://github.com/bsv-blockchain/ts-stack/tree/main/packages/messaging/authsocket) |
Expand Down
8 changes: 4 additions & 4 deletions governance/package-release-notes.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"schemaVersion": 1,
"lastReviewed": "2026-08-13",
"lastReviewed": "2026-08-14",
"owner": "ts-stack-maintainers",
"entries": [
{
Expand Down Expand Up @@ -160,9 +160,9 @@
{
"name": "@bsv/templates",
"publishedVersion": "1.9.1",
"releaseType": "patch",
"summary": "Consolidates MultiPushDrop script construction while preserving the exact generated locking-script sequence, adds an exact-tarball browser-consumer and bundle-size contract, and points contributors to the canonical root policy.",
"migration": "No consumer migration is required; template APIs, supported imports, and generated script semantics are unchanged."
"releaseType": "minor",
"summary": "Adds the R1K1Wallet ScriptTemplate for salted P-256 hardware signing with an independent secp256k1 recovery path, including a checksummed static Runar artifact and browser-safe lazy decompression. Also consolidates MultiPushDrop script construction without changing its output, adds an exact-tarball browser-consumer and bundle-size contract, and points contributors to the canonical root policy.",
"migration": "No existing consumer migration is required; existing template APIs and generated scripts are unchanged. New R1K1Wallet consumers await lock(), retain each private 32-byte salt, and provide a PIV signer that signs the supplied digest directly without hashing it again."
},
{
"name": "@bsv/teranode-listener",
Expand Down
2 changes: 1 addition & 1 deletion governance/repository-health/baselines.json
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@
"@bsv/did-client": "1.3.0",
"@bsv/fund-wallet": "1.4.3",
"@bsv/simple": "0.5.0",
"@bsv/templates": "1.9.6",
"@bsv/templates": "1.10.0",
"@bsv/authsocket": "2.1.5",
"@bsv/authsocket-client": "2.1.4",
"@bsv/message-box-client": "2.4.0",
Expand Down
3 changes: 2 additions & 1 deletion packages/helpers/ts-templates/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ All notable changes to this project will be documented in this file. The format
## [Unreleased]

### Added
- (Include new features or significant user-visible enhancements here.)
- `R1K1Wallet`, a static Runar contract template with a salted P-256 hardware
signing path and an independent secp256k1 recovery path.

### Changed
- Point contributors and AI agents to the canonical stack-level contribution
Expand Down
Loading
Loading