bip388
v1.0.3
Published
bip388 utils for typescript
Downloads
2,461
Maintainers
Readme
bip388
TypeScript library for building Bitcoin scripts and BIP-388 wallet policies, with first-class support for Ledger hardware wallets.
Install
npm install bip388Features
- BIP-388 Wallet Policies - Descriptor templates with key placeholders for Ledger registration
- BIP-379 Miniscript - Typesafe miniscript fragment builders
- HTLCs - Hash Time-Locked Contracts for both Taproot and SegWit
- Multisig - k-of-n multisig for Taproot and SegWit
Quick Start
Taproot HTLC
import { taprootHtlc } from "bip388";
const htlc = taprootHtlc({
payee: {
xpub: "tpub...",
fingerprint: "3442193e",
originPath: "86'/1'/0'",
},
payer: {
xpub: "tpub...",
fingerprint: "3442193e",
originPath: "86'/1'/1'",
},
secretHash: "deadbeef...",
timelock: 800000,
network: "testnet",
});
// Address to fund
console.log(htlc.address);
// BIP-388 policy for Ledger
console.log(htlc.policy?.template);
// => tr(@0/**,{and_v(v:sha256(...),pk(@1/**)),and_v(v:after(800000),pk(@2/**))})
// Witness for spending with preimage
const witness = htlc.witness.secret(signature, preimage);
// Witness for timeout refund
const witness = htlc.witness.timeout(signature);SegWit HTLC
import { segwitHtlc } from "bip388";
const htlc = segwitHtlc({
payee: { xpub: "tpub...", fingerprint: "...", originPath: "..." },
payer: { xpub: "tpub...", fingerprint: "...", originPath: "..." },
secretHash: "deadbeef...",
timelock: 800000,
network: "testnet",
});
console.log(htlc.address); // tb1q...Taproot Multisig (2-of-3)
import { taprootMultisig } from "bip388";
const multisig = taprootMultisig({
threshold: 2,
keys: [
{ xpub: "tpub...", fingerprint: "...", originPath: "..." },
{ xpub: "tpub...", fingerprint: "...", originPath: "..." },
{ xpub: "tpub...", fingerprint: "...", originPath: "..." },
],
network: "testnet",
});
console.log(multisig.address);
console.log(multisig.policy?.template);
// => tr(@0/**,sortedmulti_a(2,@1/**,@2/**,@3/**))
// Build witness with signatures (empty buffer for non-signers)
const witness = multisig.witness([sig1, sig2, Buffer.alloc(0)]);SegWit Multisig
import { segwitMultisig } from "bip388";
const multisig = segwitMultisig({
threshold: 2,
keys: [key1, key2, key3],
network: "testnet",
});
console.log(multisig.policy?.template);
// => wsh(sortedmulti(2,@0/**,@1/**,@2/**))Key Types
Keys can be either XpubKey (for BIP-388 policy generation) or RawKey (just a pubkey):
// XpubKey - enables BIP-388 policy generation
const xpubKey: XpubKey = {
xpub: "tpub...",
fingerprint: "3442193e", // master fingerprint
originPath: "86'/1'/0'", // derivation path
index: 0, // optional, default 0
change: 0, // optional, 0=receive, 1=change
};
// RawKey - no policy generated
const rawKey: RawKey = {
pubkey: "02abc...", // 33-byte compressed or 32-byte x-only
};When all keys are XpubKey, a WalletPolicy is generated for Ledger registration. When using RawKey, policy will be null.
Miniscript Fragments
Build miniscript expressions directly:
import { pk, sha256, and_v, or_i, older, after, multi_a } from "bip388";
// pk(@0/**)
pk(keyPlaceholder(0));
// and_v(v:sha256(H),pk(@0/**))
and_v(sha256("deadbeef..."), pk(keyPlaceholder(0)));
// or_i(and_v(v:sha256(H),pk(@0/**)),and_v(v:after(144),pk(@1/**)))
or_i(
and_v(sha256("..."), pk(keyPlaceholder(0))),
and_v(after(144), pk(keyPlaceholder(1))),
);
// multi_a(2,@0/**,@1/**,@2/**) - Taproot
multi_a(2, [keyPlaceholder(0), keyPlaceholder(1), keyPlaceholder(2)]);Low-Level Scripts
For direct Bitcoin Script building:
import {
pkScript,
pkhScript,
multiScript,
cltvScript,
csvScript,
} from "bip388";
// <pubkey> OP_CHECKSIG
pkScript(pubkey);
// OP_DUP OP_HASH160 <hash> OP_EQUALVERIFY OP_CHECKSIG
pkhScript(pubkey);
// OP_2 <key1> <key2> <key3> OP_3 OP_CHECKMULTISIG
multiScript(2, [key1, key2, key3]);
// <time> OP_CHECKLOCKTIMEVERIFY OP_DROP <pubkey> OP_CHECKSIG
cltvScript(pubkey, locktime);
// <blocks> OP_CHECKSEQUENCEVERIFY OP_DROP <pubkey> OP_CHECKSIG
csvScript(pubkey, blocks);API Reference
Pattern Builders
| Function | Description |
| ------------------------- | ------------------------------------------ |
| taprootHtlc(params) | Taproot HTLC with secret and timeout paths |
| segwitHtlc(params) | SegWit P2WSH HTLC |
| taprootMultisig(params) | Taproot k-of-n multisig |
| segwitMultisig(params) | SegWit P2WSH k-of-n multisig |
BIP-388 Builders
| Function | Description |
| ---------------------- | -------------------------------------- |
| buildTaprootPolicy() | Build a tr() wallet policy |
| buildSegwitPolicy() | Build a wsh() wallet policy |
| keyPlaceholder(n) | Create @n/** key placeholder |
| formatKeyInfo() | Format key as [fingerprint/path]xpub |
Miniscript Fragments
| Function | Description |
| ------------------------ | ------------------------- |
| pk(key) | Public key check |
| sha256(hash) | SHA256 preimage check |
| and_v(left, right) | Verify AND |
| or_i(left, right) | IF/ELSE OR |
| older(blocks) | Relative timelock (CSV) |
| after(time) | Absolute timelock (CLTV) |
| multi(k, keys) | k-of-n multisig (SegWit) |
| multi_a(k, keys) | k-of-n multisig (Taproot) |
| sortedmulti(k, keys) | Sorted k-of-n (SegWit) |
| sortedmulti_a(k, keys) | Sorted k-of-n (Taproot) |
License
MIT
