npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

ledger-bitcoin-babylon

v0.3.1-alpha.0

Published

Ledger Hardware Wallet Babylon Application Client

Readme

Ledger Babylon Application Client

Overview

A library designed for seamless integration with the Ledger Babylon application. It's a fork of ledger-bitcoin.

Install

To add the Ledger Babylon Application Client to your project, you can use either Yarn or npm:

$ yarn add ledger-bitcoin-babylon

Or, if you prefer using npm:

$ npm install ledger-bitcoin-babylon

Building

After installing the package, build the project with the following commands:

$ yarn

$ yarn build

Getting Started

Begin by importing the necessary modules and types from the package along with a compatible Ledger transport (for example, the WebUSB transport). The sample code below demonstrates the basic setup:

import Transport from '@ledgerhq/hw-transport-webusb';
import AppClient, {
  DefaultWalletPolicy,
  WalletPolicy,
  computeLeafHash,
  signMessage,
  signPsbt,
  tryParsePsbt,
  slashingPathPolicy,
  stakingTxPolicy,
} from 'ledger-bitcoin-babylon';

import type {
  SignedMessage,
  SlashingParams,
  UnbondingParams,
  TimelockParams,
  StakingTxParams,
} from 'ledger-bitcoin-babylon';

Get Wallet Information

The following example demonstrates how to retrieve key wallet details such as the master key fingerprint, extended public key, and a derived wallet address. You must specify the appropriate derivation path and indicate whether you are working with a testnet.

const DERIVATION_PATH = `m/86'/1'/0'`;
const IS_TESTNET = true;

async function getWalletInfo(transport: Transport) {
  const app = new AppClient(transport);

  const fpr = await app.getMasterFingerprint();
  console.log('Master key fingerprint:', fpr);

  const extendedPubkey = await app.getExtendedPubkey(DERIVATION_PATH);
  console.log('Extended public key:', extendedPubkey);

  const accountPolicy = new DefaultWalletPolicy(
    'tr(@0/**)',
    `[${DERIVATION_PATH.replace('m/', `${fpr}/`)}]${extendedPubkey}`
  );
  const address = await app.getWalletAddress(
    accountPolicy,
    null,
    0,
    0,
    true // show address on the wallet's screen
  );

  console.log('Wallet address:', address);
}

Sign Staking Script

For signing staking script transactions, you must build a specific wallet policy that includes parameters such as the finality provider public key, covenant public keys, and a threshold value. Detailed documentation for staking scripts can be found on the Babylon GitHub repository.

There are two methods available for signing a staking script:

Method 1: Explicitly Pass All Required Parameters to Construct the Policy

This method allows for full control over the wallet policy by explicitly providing all necessary parameters. It computes the leaf hash from the PSBT and sets the required public keys and threshold values.

async function testSlashingScript1(transport: Transport) {
  const psbt = base64.decode(
    'cHNidP8BAH0CAAAAAZUPGfxRcPueN3/UdNQC64mF3lAumoEi9Gv6AgvbdVycAAAAAAD/////AsQJAAAAAAAAFgAUW+EmJNCKK0JAldfAciHDNFDRS/EEpgAAAAAAACJRICyVutUKY9E6qBjfjktoZBga2/RyCoiq+OPBI1ugik2fAAAAAAABAStQwwAAAAAAACJRIEOj7UvRXfRV9er0SUNeReHNqaiqtOoEhmW60JCFUoUyQhXAUJKbdMGgSVS3i0tgNel6XgeKWg8o7JbVR7/ums6AOsCJtgX5iDHD5SbZ6yF5ZRRSk4qMD/f16u7MthJR1dRt6/15ASDcjS+e/wxPTb3gcKSOMw78kItip2ZWjZHmWPKEsyS4eK0gH5MjVzLmTKwzVprRw9vwQTgsO3dPz7BTO5sx1MKna/mtIAruBQmxbbccmZI4pIJ9uUVSaFmxPJVIerRnJTV8mp8lrCARPDoyqdMgtyGQoEoCCg2zl27zaXJnMljpo4o2Tz3DsLogF5Ic8VbMtOc9Qo+ZbtEbJFMT434nyXisTSzCHspGcuS6IDu5PfyLYYh9dx82MOmmPpfLr8/MeFVqR034OjGg74mcuiBAr69HxP+lbehkENjke6ortvBLYE9OokMjc33cP+CS37ogeacf/XHFA+8uL5G8z8j82nlG9GU87w2fPd4geV7zufC6INIfr3jGdRoNOOa9gCi5B/8H6ahppD/IN9az+N/2EZo2uiD1GZ764/KLuCR2Fjp+RYx61EXZv/sGgtENO9sstB+Ojrog+p2ILUX0BgvbgEIYOCjNh1RPHqmXOA5YbKt31f1phze6VpzAARcgUJKbdMGgSVS3i0tgNel6XgeKWg8o7JbVR7/ums6AOsAAAAA='
  );

  const leafHash = computeLeafHash(psbt);
  const finalityProviderPk =
    '1f93235732e64cac33569ad1c3dbf041382c3b774fcfb0533b9b31d4c2a76bf9';
  // keys must be sorted https://github.com/babylonlabs-io/btc-staking-ts/blob/dev/src/staking/stakingScript.ts#L291
  const covenantPks = [
    '0aee0509b16db71c999238a4827db945526859b13c95487ab46725357c9a9f25',
    // Additional public keys omitted for brevity
  ];

  const params: SlashingParams = {
    leafHash,
    finalityProviderPk,
    covenantThreshold: 6,
    covenantPks,
  };

  const policy: WalletPolicy = await slashingPathPolicy({
    policyName: 'Consent to unbonding slashing',
    transport,
    params,
    derivationPath: DERIVATION_PATH,
    isTestnet: IS_TESTNET,
  });

  await signPsbt({ transport, psbt, policy });
}

async function testUnbondingScript(transport: Transport) {
  const psbt = base64.decode(
    'cHNidP8BAF4CAAAAAdajXvIOyMVu2knpIqn8Z4cB1RGOCjtzVW1vKmKOpcx1AAAAAAD/////AYC7AAAAAAAAIlEgnFilULMWlJWBOW4utZZmFQn5n+nx6SxFU/2uNYB466kAAAAAAAEBK1DDAAAAAAAAIlEgVkKHpDPhbdkKYx0fHmv6lVhBUJ5bodNd3+U54bY9cvZiFcBQkpt0waBJVLeLS2A16XpeB4paDyjsltVHv+6azoA6wPpWf/izaVoDwufHxf/Hlsfg5PxlMSgtzwdIJWBl2Cq6LxMAuyt0TjP/kXX23pW+KgyXYBx2RloUqwUjNLOhChH9VwEgP49Elqc2enw/54+VwIRXiyKOIDJWl8/kI5NrkF96wGKtIAruBQmxbbccmZI4pIJ9uUVSaFmxPJVIerRnJTV8mp8lrCARPDoyqdMgtyGQoEoCCg2zl27zaXJnMljpo4o2Tz3DsLogF5Ic8VbMtOc9Qo+ZbtEbJFMT434nyXisTSzCHspGcuS6IDu5PfyLYYh9dx82MOmmPpfLr8/MeFVqR034OjGg74mcuiBAr69HxP+lbehkENjke6ortvBLYE9OokMjc33cP+CS37ogeacf/XHFA+8uL5G8z8j82nlG9GU87w2fPd4geV7zufC6INIfr3jGdRoNOOa9gCi5B/8H6ahppD/IN9az+N/2EZo2uiD1GZ764/KLuCR2Fjp+RYx61EXZv/sGgtENO9sstB+Ojrog+p2ILUX0BgvbgEIYOCjNh1RPHqmXOA5YbKt31f1phze6VpzAARcgUJKbdMGgSVS3i0tgNel6XgeKWg8o7JbVR7/ums6AOsAAAA=='
  );

  const leafHash = computeLeafHash(psbt);
  const finalityProviderPk =
    'd23c2c25e1fcf8fd1c21b9a402c19e2e309e531e45e92fb1e9805b6056b0cc76';
  // keys must be sorted https://github.com/babylonlabs-io/btc-staking-ts/blob/dev/src/staking/stakingScript.ts#L291
  const covenantPks = [
    '0aee0509b16db71c999238a4827db945526859b13c95487ab46725357c9a9f25',
    // Additional public keys omitted for brevity
  ];

  const params: UnbondingParams = {
    leafHash,
    timelockBlocks: 64000,
    finalityProviderPk,
    covenantThreshold: 6,
    covenantPks,
  };

  const policy: WalletPolicy = await unbondingPathPolicy({
    policyName: 'Unbonding',
    transport,
    params,
    derivationPath: DERIVATION_PATH,
    isTestnet: IS_TESTNET,
  });

  await signPsbt({ transport, psbt, policy });
}

This method is ideal if you want complete control over each parameter required for constructing the wallet policy for staking scripts.

Method 2: Automatically Parse the Policy from the Content of the Provided PSBT

This method simplifies the process by automatically extracting the required policy information directly from the PSBT content. It is a more streamlined approach—if the PSBT is successfully parsed, the wallet policy is generated automatically.

You can also construct the wallet policies for the slashing script and the timelock script in this way.

async function testSlashingScript2(transport: Transport) {
  const psbtBase64 =
    'cHNidP8BAH0CAAAAAZUPGfxRcPueN3/UdNQC64mF3lAumoEi9Gv6AgvbdVycAAAAAAD/////AsQJAAAAAAAAFgAUW+EmJNCKK0JAldfAciHDNFDRS/EEpgAAAAAAACJRICyVutUKY9E6qBjfjktoZBga2/RyCoiq+OPBI1ugik2fAAAAAAABAStQwwAAAAAAACJRIEOj7UvRXfRV9er0SUNeReHNqaiqtOoEhmW60JCFUoUyQhXAUJKbdMGgSVS3i0tgNel6XgeKWg8o7JbVR7/ums6AOsCJtgX5iDHD5SbZ6yF5ZRRSk4qMD/f16u7MthJR1dRt6/15ASDcjS+e/wxPTb3gcKSOMw78kItip2ZWjZHmWPKEsyS4eK0gH5MjVzLmTKwzVprRw9vwQTgsO3dPz7BTO5sx1MKna/mtIAruBQmxbbccmZI4pIJ9uUVSaFmxPJVIerRnJTV8mp8lrCARPDoyqdMgtyGQoEoCCg2zl27zaXJnMljpo4o2Tz3DsLogF5Ic8VbMtOc9Qo+ZbtEbJFMT434nyXisTSzCHspGcuS6IDu5PfyLYYh9dx82MOmmPpfLr8/MeFVqR034OjGg74mcuiBAr69HxP+lbehkENjke6ortvBLYE9OokMjc33cP+CS37ogeacf/XHFA+8uL5G8z8j82nlG9GU87w2fPd4geV7zufC6INIfr3jGdRoNOOa9gCi5B/8H6ahppD/IN9az+N/2EZo2uiD1GZ764/KLuCR2Fjp+RYx61EXZv/sGgtENO9sstB+Ojrog+p2ILUX0BgvbgEIYOCjNh1RPHqmXOA5YbKt31f1phze6VpzAARcgUJKbdMGgSVS3i0tgNel6XgeKWg8o7JbVR7/ums6AOsAAAAA=';

  const policy = await tryParsePsbt(transport, psbtBase64, IS_TESTNET);
  if (!policy) {
    throw new Error('PSBT parsing failed');
  }

  await signPsbt({ transport, psbt: psbtBase64, policy });
}

Sign Message

The SDK supports two methods for message signing, allowing you to choose between the traditional ECDSA signature scheme or the BIP-322 simple signature format for Bitcoin.

ECDSA

async function testSignECDSAMessage(transport: Transport) {
  const result: SignedMessage = await signMessage({
    transport,
    message: 'hello world',
    type: 'ecdsa',
    derivationPath: DERIVATION_PATH,
    isTestnet: IS_TESTNET,
  });

  console.log(result);
}

BIP-322

async function testSignBIP322Message(transport: Transport) {
  const result: SignedMessage = await signMessage({
    transport,
    message: 'hello world',
    type: 'bip322-simple',
    derivationPath: DERIVATION_PATH,
    isTestnet: IS_TESTNET,
  });

  console.log(result);
}

Sign Staking Transaction

Staking transactions in this context are standard Bitcoin transfer transactions that require extra context to be understood by the Ledger Babylon application. Since these PSBTs do not include parameters such as finalityProviderPk, covenantPks, or timelockBlocks, you must create a custom wallet policy using the stakingTxPolicy method.

async function testStakingTx(transport: Transport) {
  const psbtBase64 =
    'cHNidP8BAIkCAAAAAZd78ohF47nbYYlbqpsG1C2SbwFnvX5vlD6YxdwhkQ50AQAAAAD/////AlDDAAAAAAAAIlEgvuEgqB2XZe+afeBe8ZLwNCRA7hqxujxpU15NDJOT+tElQCIAAAAAACJRIHQO5k5FLjuu4SewPBlbzCGtPt3tLvJsWvSD2cVjBNHlAAAAAAABASsuBCMAAAAAACJRIHQO5k5FLjuu4SewPBlbzCGtPt3tLvJsWvSD2cVjBNHlARcg3I0vnv8MT0294HCkjjMO/JCLYqdmVo2R5ljyhLMkuHgAAAA=';

  const finalityProviderPk = '1f93235732e64cac33569ad1c3dbf041382c3b774fcfb0533b9b31d4c2a76bf9';
  // keys must be sorted https://github.com/babylonlabs-io/btc-staking-ts/blob/dev/src/staking/stakingScript.ts#L291
  const covenantPks = [
    '0aee0509b16db71c999238a4827db945526859b13c95487ab46725357c9a9f25',
    '113c3a32a9d320b72190a04a020a0db3976ef36972673258e9a38a364f3dc3b0',
    '17921cf156ccb4e73d428f996ed11b245313e37e27c978ac4d2cc21eca4672e4',
    '3bb93dfc8b61887d771f3630e9a63e97cbafcfcc78556a474df83a31a0ef899c',
    '40afaf47c4ffa56de86410d8e47baa2bb6f04b604f4ea24323737ddc3fe092df',
    '79a71ffd71c503ef2e2f91bccfc8fcda7946f4653cef0d9f3dde20795ef3b9f0',
    'd21faf78c6751a0d38e6bd8028b907ff07e9a869a43fc837d6b3f8dff6119a36',
    'f5199efae3f28bb82476163a7e458c7ad445d9bffb0682d10d3bdb2cb41f8e8e',
    'fa9d882d45f4060bdb8042183828cd87544f1ea997380e586cab77d5fd698737',
  ];

  const params: StakingTxParams = {
    timelockBlocks: 64000,
    finalityProviderPk,
    covenantThreshold: 6,
    covenantPks,
  };

  const policy: WalletPolicy = await stakingTxPolicy({
    policyName: 'Staking transaction',
    transport,
    params,
    derivationPath: DERIVATION_PATH,
    isTestnet: IS_TESTNET,
  });

  await signPsbt({ transport, psbt: psbtBase64, policy });
}