Skip to content

Simple js bip352 library for bitcoin silent payment address derivation

License

Notifications You must be signed in to change notification settings

levinster82/bip352-js

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

BIP-352 Silent Payments

A simple JavaScript library for deriving BIP-352 Silent Payment addresses, scan keys, and spend keys. It is designed to work well as a library module alongside other bitcoinjs suite of libraries.

Silent Payments is a privacy-enhancing protocol that allows users to receive Bitcoin payments to a static, reusable address without revealing it on-chain. Each payment generates a unique output address, improving receiver privacy.

Installation

npm install

Usage

Basic Example

const bip39 = require('bip39');
const bip32 = require('bip32');
const ecc = require('tiny-secp256k1');
const bip352 = require('bip352');

const BIP32 = bip32.BIP32Factory(ecc);

// Generate or import a mnemonic
const mnemonic = bip39.generateMnemonic();
const seed = bip39.mnemonicToSeedSync(mnemonic);
const root = BIP32.fromSeed(seed);

// Derive Silent Payment address for account 0
const { address, scanKey, spendKey } = bip352.deriveAddress(
  root,
  0,
  bip352.COIN_TYPE_BTC_MAINNET
);

console.log('Silent Payment Address:', address);
// => sp1qq...

Derive Keys Only

const { scanKey, spendKey } = bip352.deriveKeys(
  root,
  0,
  bip352.COIN_TYPE_BTC_MAINNET
);

console.log('Scan key path:', bip352.getPath('scan', 0, bip352.COIN_TYPE_BTC_MAINNET));
// => m/352'/0'/0'/1'/0

console.log('Spend key path:', bip352.getPath('spend', 0, bip352.COIN_TYPE_BTC_MAINNET));
// => m/352'/0'/0'/0'/0

Encode Address from Public Keys

const address = bip352.toAddress(
  scanKey.publicKey,
  spendKey.publicKey,
  bip352.COIN_TYPE_BTC_MAINNET
);

console.log('Address:', address);

Decode Address

const decoded = bip352.fromAddress(address);

console.log('Version:', decoded.version);
console.log('Scan pubkey:', Buffer.from(decoded.scanPub).toString('hex'));
console.log('Spend pubkey:', Buffer.from(decoded.spendPub).toString('hex'));
console.log('Testnet:', decoded.testnet);

Testnet Support

const { address } = bip352.deriveAddress(
  root,
  0,
  bip352.COIN_TYPE_BTC_TESTNET
);

console.log('Testnet Address:', address);
// => tsp1qq...

API Reference

deriveKeys(rootKey, account, coinType)

Derives scan and spend keys according to BIP-352.

Parameters:

  • rootKey (BIP32Interface): Master BIP32 key
  • account (number, optional): Account index (default: 0)
  • coinType (number, optional): BIP44 coin type - 0 for mainnet, 1 for testnet (default: 0)

Returns: { scanKey, spendKey } - Both are BIP32Interface objects

Derivation paths:

  • Scan: m/352'/coin_type'/account'/1'/0
  • Spend: m/352'/coin_type'/account'/0'/0

toAddress(scanPub, spendPub, coinType)

Encodes a Silent Payment address from public keys.

Parameters:

  • scanPub (Uint8Array): 33-byte compressed scan public key
  • spendPub (Uint8Array): 33-byte compressed spend public key
  • coinType (number, optional): 0 for mainnet, 1 for testnet (default: 0)

Returns: Silent Payment address string (bech32m encoded)

fromAddress(address)

Decodes a Silent Payment address.

Parameters:

  • address (string): Silent Payment address

Returns: { version, scanPub, spendPub, testnet }

  • version (number): Protocol version
  • scanPub (Uint8Array): 33-byte scan public key
  • spendPub (Uint8Array): 33-byte spend public key
  • testnet (boolean): True if testnet address

deriveAddress(rootKey, account, coinType)

Convenience function that combines key derivation and address encoding.

Parameters:

  • rootKey (BIP32Interface): Master BIP32 key
  • account (number, optional): Account index (default: 0)
  • coinType (number, optional): 0 for mainnet, 1 for testnet (default: 0)

Returns: { address, scanKey, spendKey }

getPath(type, account, coinType)

Returns the BIP-32 derivation path string.

Parameters:

  • type (string): 'scan' or 'spend'
  • account (number, optional): Account index (default: 0)
  • coinType (number, optional): 0 for mainnet, 1 for testnet (default: 0)

Returns: Derivation path string (e.g., m/352'/0'/0'/1'/0)

Constants

  • PURPOSE_BIP352: 352
  • COIN_TYPE_BTC_MAINNET: 0
  • COIN_TYPE_BTC_TESTNET: 1
  • VERSION_SP: 0
  • HRP_SP_MAINNET: 'sp'
  • HRP_SP_TESTNET: 'tsp'

Testing

npm test

The test suite uses deterministic test vectors to verify:

  • Correct key derivation paths
  • Expected xpub/xprv values
  • Address encoding/decoding
  • Network type detection
  • Invalid address rejection

Address Format

Silent Payment addresses use bech32m encoding (not bech32):

  • HRP: sp (mainnet) or tsp (testnet)
  • Version: 0
  • Payload: 66 bytes (33-byte scan pubkey + 33-byte spend pubkey)
  • Example: sp1qqw3hksrgxfk0p7lf2h6hatk0n206a59l4wc354rxurvrjnzudfjx6q7dda0gtxsj4n0rp3u7782w8334tp5yt8y4uarpulqf05ca8gecj5p7ke3y

Dependencies

  • bech32: Bech32m encoding/decoding
  • bip32: HD key derivation
  • tiny-secp256k1: Elliptic curve cryptography
  • bip39: Mnemonic generation (for examples/testing)
  • mocha: Test framework

License

GPL-3.0

Resources

About

Simple js bip352 library for bitcoin silent payment address derivation

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published