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 🙏

© 2026 – Pkg Stats / Ryan Hefner

cashtab-connect

v1.1.0

Published

A developer-friendly API for integrating with the Cashtab browser extension

Readme

Cashtab Connect

A developer-friendly API for integrating with the Cashtab browser extension. This library provides a clean, TypeScript-first interface for requesting user addresses and creating transactions through the Cashtab wallet extension.

Installation

npm install cashtab-connect
yarn add cashtab-connect

Quick Start

import { CashtabConnect } from 'cashtab-connect';

// Create an instance
const cashtab = new CashtabConnect();

// Wait for the extension to become available
async function initializeCashtab() {
    try {
        await cashtab.waitForExtension();
        console.log('Cashtab extension is available!');

        // Now you can safely use the extension
        const address = await cashtab.requestAddress();
        console.log('User address:', address);
    } catch (error) {
        console.error('Extension not available:', error.message);
    }
}

// Initialize when your app loads
await initializeCashtab();

API Reference

CashtabConnect Class

The main class for interacting with the Cashtab extension.

Constructor

new CashtabConnect(options?: CashtabConnectOptions)

Options:

  • timeout (number): Timeout in milliseconds for address requests (default: 30000)
  • extensionNotAvailableMessage (string): Custom error message when extension is not available
  • addressDeniedMessage (string): Custom error message when user denies address request

Methods

waitForExtension(timeout?: number): Promise<void>

Wait for the Cashtab extension to become available. This is the recommended way to check for extension availability.

Parameters:

  • timeout (number): Maximum time to wait in milliseconds (default: 3000). In practice this usually takes less than 1s.

Returns: Promise that resolves when extension is available or rejects on timeout.

Example:

try {
    await cashtab.waitForExtension();
    console.log('Extension is ready!');
} catch (error) {
    console.log('Extension not available within timeout');
}
isExtensionAvailable(): Promise<boolean>

Check if the extension is currently available without waiting.

Returns: Promise that resolves to true if extension is available, false otherwise.

Example:

const isAvailable = await cashtab.isExtensionAvailable();
if (isAvailable) {
    // Extension is ready to use
} else {
    // Extension is not available
}
requestAddress(): Promise<string>

Request the user's eCash address from their Cashtab wallet.

Returns: Promise that resolves with the user's address or rejects with an error.

Throws:

  • ExtensionNotAvailableError: When the Cashtab extension is not available
  • AddressRequestDeniedError: When the user denies the address request (includes reason)
  • AddressRequestTimeoutError: When the request times out

Example:

try {
    const address = await cashtab.requestAddress();
    console.log('User address:', address);
} catch (error) {
    if (error instanceof CashtabExtensionUnavailableError) {
        console.log('Please install the Cashtab extension');
    } else if (error instanceof CashtabAddressDeniedError) {
        console.log('User denied address request');
    }
}
sendXec(address: string, amount: string | number): Promise<void>

Send XEC to an address using Cashtab (dev-friendly).

Parameters:

  • address (string): Recipient's eCash address
  • amount (string | number): Amount to send in XEC

Throws:

  • CashtabExtensionUnavailableError: When the Cashtab extension is not available

Example:

cashtab.sendXec('ecash:qp3wj05au4l7q2m5ng4qg0vpeejl42lvl0nqj8q0q0', '1000.12');

Error Classes

CashtabExtensionUnavailableError

Thrown when the Cashtab extension is not available.

CashtabAddressDeniedError

Thrown when the user denies an address request.

CashtabTimeoutError

Thrown when an address request times out.

Advanced Usage

Custom Instance

Create a custom instance with specific timeout:

import { CashtabConnect } from 'cashtab-connect';

const cashtab = new CashtabConnect(60000); // 60 second timeout for address requests

Error Handling

Comprehensive error handling example:

import {
    CashtabConnect,
    CashtabExtensionUnavailableError,
    CashtabAddressDeniedError,
    CashtabTimeoutError,
} from 'cashtab-connect';

async function requestUserAddress() {
    const cashtab = new CashtabConnect();

    try {
        const address = await cashtab.requestAddress();
        return address;
    } catch (error) {
        if (error instanceof CashtabExtensionUnavailableError) {
            // Show installation instructions
            showInstallationInstructions();
        } else if (error instanceof CashtabAddressDeniedError) {
            // Show alternative payment methods
            showAlternativePaymentMethods();
        } else if (error instanceof CashtabTimeoutError) {
            // Retry or show timeout message
            showTimeoutMessage();
        } else {
            // Handle unexpected errors
            console.error('Unexpected error:', error);
        }
        throw error;
    }
}

Browser Compatibility

This library works in all modern browsers that support:

  • ES2020 features
  • TypeScript
  • Browser extensions (Chrome, Firefox, Edge)

Prerequisites

  • The Cashtab browser extension must be installed and active
  • The extension injects a global flag window.bitcoinAbc = 'cashtab' when available

Security Considerations

  1. User Consent: All address requests require explicit user approval through a popup
  2. Transaction Review: Transaction creation opens Cashtab for user review before sending
  3. Origin Validation: The extension only accepts messages from the same window

Troubleshooting

Extension Not Detected

  1. Ensure the Cashtab extension is installed
  2. Check that the extension is enabled
  3. Verify the extension is compatible with your browser
  4. Use waitForExtension() instead of checking availability immediately on page load

Address Request Fails

  1. Check that the user approves the request in the popup
  2. Verify the extension is available before making requests using waitForExtension()
  3. Handle timeout errors appropriately

Transaction Not Opening

  1. Check that the address and amount parameters are valid
  2. Ensure the extension is available using waitForExtension()
  3. Verify the address format is correct

Examples

React Component

import React, { useEffect, useState } from 'react';
import {
    CashtabConnect,
    CashtabExtensionUnavailableError,
    CashtabAddressDeniedError,
    CashtabTimeoutError,
} from 'cashtab-connect';

function CashtabIntegration() {
    const [address, setAddress] = useState<string | null>(null);
    const [isExtensionAvailable, setIsExtensionAvailable] = useState(false);
    const [isCheckingExtension, setIsCheckingExtension] = useState(true);
    const [isLoading, setIsLoading] = useState(false);
    const [addressResult, setAddressResult] = useState<{
        message: string;
        type: 'success' | 'error';
    } | null>(null);

    // Initialize CashtabConnect in state
    const [cashtab] = useState(() => new CashtabConnect());

    // Check extension availability on mount
    useEffect(() => {
        const checkAvailability = async () => {
            try {
                await cashtab.waitForExtension();
                setIsExtensionAvailable(true);
                setIsCheckingExtension(false);
            } catch (error) {
                console.log('Extension not available after waiting:', error);
                setIsCheckingExtension(false);
            }
        };

        checkAvailability();
    }, [cashtab]);

    const handleRequestAddress = async () => {
        setIsLoading(true);
        setAddressResult(null);

        try {
            const userAddress = await cashtab.requestAddress();
            setAddress(userAddress);
            setAddressResult({
                message: `Address received: ${userAddress}`,
                type: 'success',
            });
        } catch (error) {
            let errorMessage = 'Unknown error occurred';

            if (error instanceof CashtabExtensionUnavailableError) {
                errorMessage = 'Extension is not available';
            } else if (error instanceof CashtabAddressDeniedError) {
                errorMessage = 'User denied the address request';
            } else if (error instanceof CashtabTimeoutError) {
                errorMessage = 'Address request timed out';
            } else if (error instanceof Error) {
                errorMessage = error.message;
            }

            setAddressResult({ message: errorMessage, type: 'error' });
        } finally {
            setIsLoading(false);
        }
    };

    const handleSendXec = () => {
        cashtab.sendXec(
            'ecash:qp3wj05au4l7q2m5ng4qg0vpeejl42lvl0nqj8q0q0',
            '1000.12',
        );
    };

    if (isCheckingExtension) {
        return <div>Checking for Cashtab extension...</div>;
    }

    return (
        <div>
            <p>
                Cashtab Extension:{' '}
                {isExtensionAvailable ? 'Available' : 'Not Available'}
            </p>
            {address && <p>User Address: {address}</p>}
            {addressResult && (
                <p
                    style={{
                        color:
                            addressResult.type === 'success' ? 'green' : 'red',
                    }}
                >
                    {addressResult.message}
                </p>
            )}
            <button
                onClick={handleRequestAddress}
                disabled={!isExtensionAvailable || isLoading}
            >
                {isLoading ? 'Requesting...' : 'Request Address'}
            </button>
            <button onClick={handleSendXec} disabled={!isExtensionAvailable}>
                Send XEC
            </button>
        </div>
    );
}

Development

Running Tests

npm test

Running the Demo

The library includes a React demo application that showcases all features:

npm start

Then open http://localhost:3000 in your browser. The demo requires the Cashtab browser extension to be installed.

The React demo demonstrates:

  • Extension status detection
  • Address requests with network selection
  • Transaction creation with form validation
  • Error handling for various scenarios
  • Real-time event logging
  • Both class-based and convenience function usage patterns

See the demo README for more details.

Building

npm run build

Linting

npm run lint

Changelog

  • 1.1.0 - Add transaction approval/rejection support for transactions. Extension transactions send responses back to the originating webpage. D18348

License

MIT License - see COPYING file at top level of the monorepo for details.

Support

For support, please visit the Cashtab documentation or GitHub repository.