@tecneural/tapvaultcore
v0.1.0
Published
Reusable escrow flows
Maintainers
Readme
@tecneural/tapvaultcore
Reusable Taproot escrow primitives for Bitcoin apps.
Build escrow addresses, create/sign/finalize PSBTs, derive child pubkeys from xpub, and securely sign using encrypted seed data.
TapVault flow diagram :
+----------------------------------------+
| 1) Create escrow |
| Set buyer/seller/arbitrator |
+-------------------+--------------------+
|
v
+----------------------------------------+
| 2) Fund with BTC |
| Buyer pays to escrow |
+-------------------+--------------------+
|
v
+----------------------------------------+
| Bitcoin locked safely |
| No one can spend alone |
+-------------------+--------------------+
|
+--------------------------+--------------------------+
| | |
v v v
+----------------------------+ +----------------------------+ +----------------------------+
| Both agree | | Disagreement | | Deadline reached |
| Seller gets paid | | Arbitrator decides | | Buyer auto-refund |
+----------------------------+ +----------------------------+ +----------------------------+
## How to setup `@tecneural/tapvaultcore`
```bash
npm install @tecneural/tapvaultcoreThat command automatically installs required runtime dependencies:
This library is ESM-only and requires Node.js 18+.
Quick start (example)
import {
buildEscrowAddress,
buildEscrowPSBT,
reconstructAddress,
} from "@tecneural/tapvaultcore";
const buyerPubKey = "11".repeat(32); // 64 hex chars (x-only pubkey)
const sellerPubKey = "22".repeat(32);
const arbitratorPubKey = "33".repeat(32);
const escrow = buildEscrowAddress(
buyerPubKey,
sellerPubKey,
arbitratorPubKey,
144,
"testnet",
);
const rebuiltAddress = reconstructAddress(escrow.scriptTreeHex, "testnet");
console.log("escrow address:", escrow.address);
console.log("rebuilt address:", rebuiltAddress);
const psbtBase64 = buildEscrowPSBT({
utxos: [{ txid: "00".repeat(32), vout: 0, value: 20000 }],
toAddress: escrow.address,
amount: 15000,
fee: 500,
spendPath: "buyerSeller",
scripts: escrow.scripts,
internalPubkey: escrow.internalPubkey,
network: "testnet",
});
console.log("unsigned escrow psbt:", psbtBase64);For a runnable TypeScript example file inside this package:
examples/basic-usage.ts- Run with:
npm run example
Supported networks
| Network | coinType (default) |
| :--- | :--- |
| mainnet | 0 |
| testnet | 1 |
| regtest | 1 |
API reference (public exports)
Main package export: @tecneural/tapvaultcore
buildEscrowAddress(...)
buildEscrowAddress(
buyerPubKey: string,
sellerPubKey: string,
arbitratorPubKey: string,
timelockBlocks: number,
network = "testnet",
): EscrowAddressResultRequest data types
| Parameter | Type | Description |
| :--- | :--- | :--- |
| buyerPubKey | string | Required. x-only pubkey hex (64 chars) |
| sellerPubKey | string | Required. x-only pubkey hex (64 chars) |
| arbitratorPubKey | string | Required. x-only pubkey hex (64 chars) |
| timelockBlocks | number | Required. CSV timelock blocks (1..65535) |
| network | "mainnet" \| "testnet" \| "regtest" | Optional. Default testnet |
Response data types
| Field | Type | Description |
| :--- | :--- | :--- |
| address | string | Generated P2TR escrow address |
| output | Buffer | scriptPubKey bytes |
| scriptTreeHex | string | Serialized script tree payload |
| scripts | EscrowScripts | Compiled scripts for all spend paths |
| leaves | object | Tapleaf metadata for each spend path |
| internalPubkey | Buffer | Internal x-only key bytes |
Throws
- invalid x-only pubkey format
- address/script tree generation failure
reconstructAddress(scriptTreeHex, network?)
Request data types
| Parameter | Type | Description |
| :--- | :--- | :--- |
| scriptTreeHex | string | Required. JSON payload created by buildEscrowAddress |
| network | "mainnet" \| "testnet" \| "regtest" | Optional. Default testnet |
Response
string(reconstructed P2TR escrow address)
Throws
- malformed payload
- reconstruction failure
buildEscrowPSBT(params)
Request data types
| Parameter | Type | Description |
| :--- | :--- | :--- |
| utxos | EscrowUTXO[] | Required. UTXO list (txid, vout, value) |
| toAddress | string | Required. destination address |
| amount | number | Required. gross output amount |
| fee | number | Required. fee deducted from amount |
| spendPath | "buyerSeller" \| "buyerArbitrator" \| "sellerArbitrator" \| "timelockRefund" | Required. selected Taproot script path |
| scripts | EscrowScripts | Required. scripts returned by buildEscrowAddress |
| internalPubkey | Buffer | Required. internal key from buildEscrowAddress |
| network | "mainnet" \| "testnet" \| "regtest" | Required. network context |
| timelockBlocks | number | Optional. required when spendPath = "timelockRefund" |
Response
string(unsigned PSBT in base64)
Throws
- missing UTXOs
- invalid timelock for refund path
- invalid output value (
amount - fee <= 0)
signAllPSBTInputs(psbtBase64, privateKey, network?)
Request data types
| Parameter | Type | Description |
| :--- | :--- | :--- |
| psbtBase64 | string | Required. unsigned/partial PSBT |
| privateKey | Buffer | Required. 32-byte private key |
| network | "mainnet" \| "testnet" \| "regtest" | Optional. Default testnet |
Response
string(PSBT base64 with signatures applied)
Throws
- invalid private key data
validateSignedPSBT(pendingPsbtBase64, signedPsbtBase64, expectedPubkeyHex, network?)
Request data types
| Parameter | Type | Description |
| :--- | :--- | :--- |
| pendingPsbtBase64 | string | Required. server-side reference PSBT |
| signedPsbtBase64 | string | Required. client-signed PSBT |
| expectedPubkeyHex | string | Required. expected x-only signer pubkey (64 chars) |
| network | "mainnet" \| "testnet" \| "regtest" | Optional. Default testnet |
Response
{ ok: true } | { ok: false; reason: string }combinePSBTsAndFinalize(psbtBase64A, psbtBase64B, network?)
Request data types
| Parameter | Type | Description |
| :--- | :--- | :--- |
| psbtBase64A | string | Required. signed PSBT A |
| psbtBase64B | string | Required. signed PSBT B |
| network | "mainnet" \| "testnet" \| "regtest" | Optional. Default testnet |
Response
string(final raw transaction hex)
finalizePSBT(psbtBase64, network?)
Request data types
| Parameter | Type | Description |
| :--- | :--- | :--- |
| psbtBase64 | string | Required. signed PSBT |
| network | "mainnet" \| "testnet" \| "regtest" | Optional. Default testnet |
Response
string(final raw transaction hex)
signEscrowPSBT(psbtBase64, encryptedSeed, password, derivationIndex, network?)
Request data types
| Parameter | Type | Description |
| :--- | :--- | :--- |
| psbtBase64 | string | Required. unsigned/partial PSBT |
| encryptedSeed | EncryptedSeed | Required. object with ciphertext, salt, iv |
| password | string | Required. password for seed decryption |
| derivationIndex | number | Required. child index for key derivation |
| network | "mainnet" \| "testnet" \| "regtest" | Optional. Default testnet |
Response data types
| Field | Type | Description |
| :--- | :--- | :--- |
| signedPSBT | string | Signed PSBT in base64 |
derivePubKeyFromXpub(xpub, index, network?)
Request data types
| Parameter | Type | Description |
| :--- | :--- | :--- |
| xpub | string | Required. account xpub at m/86'/{coinType}'/0' |
| index | number | Required. child index (.../0/{index}) |
| network | "mainnet" \| "testnet" \| "regtest" | Optional. Default testnet |
Response
string(x-only pubkey hex, 64 chars)
Throws
- invalid xpub for selected network
- child derivation failure
Wallet subpath export: @tecneural/tapvaultcore/wallet
mnemonicToSeed(mnemonic, passphrase?)
Request data types
| Parameter | Type | Description |
| :--- | :--- | :--- |
| mnemonic | string | Required. valid BIP39 mnemonic |
| passphrase | string | Optional. BIP39 passphrase |
Response
Promise<Buffer>(seed bytes)
Throws
- invalid mnemonic phrase
encryptSeed(mnemonic, password)
Request data types
| Parameter | Type | Description |
| :--- | :--- | :--- |
| mnemonic | string | Required. plaintext mnemonic |
| password | string | Required. minimum 8 characters |
Response data types
| Field | Type | Description |
| :--- | :--- | :--- |
| ciphertext | string | AES-GCM encrypted payload (base64) |
| salt | string | PBKDF2 salt (hex) |
| iv | string | AES-GCM IV (hex) |
Throws
- password too short
decryptSeed(blob, password)
Request data types
| Parameter | Type | Description |
| :--- | :--- | :--- |
| blob | EncryptedSeed | Required. encrypted seed payload |
| password | string | Required. encryption password |
Response
Promise<string>(decrypted mnemonic)
Throws
- wrong password
- corrupted payload
deriveP2TRKeypair(seed, index, network?, account?, coinType?)
Request data types
| Parameter | Type | Description |
| :--- | :--- | :--- |
| seed | Buffer | Required. BIP39 seed bytes |
| index | number | Required. child index |
| network | "mainnet" \| "testnet" \| "regtest" | Optional. Default testnet |
| account | number | Optional. Default 0 |
| coinType | number | Optional. Override network default coin type |
Response data types
| Field | Type | Description |
| :--- | :--- | :--- |
| publicKey | Uint8Array | x-only pubkey (32 bytes) |
| privateKey | Uint8Array | private key (32 bytes) |
| path | string | derived path (example m/86'/1'/0'/0/5) |
| index | number | derived index |
deriveXpub(seed, network?, coinType?)
Request data types
| Parameter | Type | Description |
| :--- | :--- | :--- |
| seed | Buffer | Required. BIP39 seed bytes |
| network | "mainnet" \| "testnet" \| "regtest" | Optional. Default testnet |
| coinType | number | Optional. coin type override |
Response
string(account xpub atm/86'/{coinType}'/0')
Common types used in signatures
These types appear in API signatures for clarity. Not all of them are directly re-exported from package entrypoints.
| Type | Purpose | Key variables | Description |
| :--- | :--- | :--- | :--- |
| EscrowAddressResult | Result of escrow address creation | address, output, scriptTreeHex, scripts, leaves, internalPubkey | Address generation output and Taproot script tree details |
| EscrowUTXO | Represents one input UTXO used in PSBT building | txid, vout, value | UTXO reference and value used as PSBT input |
| BuildPSBTParams | Input configuration object for buildEscrowPSBT(...) | utxos, toAddress, amount, fee, spendPath, scripts, internalPubkey, network, timelockBlocks | Complete input parameters required to build escrow PSBT |
| ValidateResult | Validation result from validateSignedPSBT(...) | ok, reason | Validation status and failure reason (if any) |
| SignResult | Signing result from signEscrowPSBT(...) | signedPSBT | Contains signed PSBT output |
| EncryptedSeed | Encrypted mnemonic container for wallet operations | ciphertext, salt, iv | Encrypted seed payload plus crypto metadata |
| P2TRKeypair | Derived Taproot keypair details | publicKey, privateKey, path, index | Derived keypair and derivation path information |
Input and validation requirements
- Public keys used by script/address APIs must be x-only (32 bytes / 64 hex chars).
timelockBlocksmust be within1..65535.- In PSBT builder,
amount - feemust stay positive. - For
timelockRefundPSBT flow, passtimelockBlocksin params.
