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

nostr-signer-capacitor-plugin

v0.0.5

Published

This capacitor plugin uses the intents package to interact with nostr signer apps on the Android platform

Readme

Nostr Signer Capacitor Plugin

This Capacitor plugin allows your application to interact with Nostr signer apps on the Android platform using intents, following the NIP-55 specification.

Install

npm install nostr-signer-capacitor-plugin
npx cap sync

Requirements

  • Android: minSdkVersion 23 or higher.
  • Java 21 (JDK 21) for building Android with Gradle.
  • Capacitor 7.x.

Version

Current version: 0.0.5

0.0.5 (2025-09-22)

  • Bumped Android minSdkVersion to 23 to align with Capacitor Android requirements.
  • Added Android unit tests (Robolectric) covering Content Resolver flows and rejected-provider fallback.
  • Added npm scripts:
    • test:ts – runs TypeScript/Jest tests
    • test:android – runs Android unit tests (testDebugUnitTest)
    • test:all (default npm test) – runs both suites
  • Added GitHub Actions workflow at .github/workflows/ci.yml to run JS and Android unit tests in CI.

Testing

Run TypeScript tests:

npm run test:ts

Run Android unit tests:

cd android
./gradlew clean testDebugUnitTest --no-daemon --stacktrace --info --console=plain

Run all tests:

npm test

Usage

Import the Plugin

import NostrSignerPlugin from 'nostr-signer-capacitor-plugin';

Set the Signer Package Name

Before using the plugin on Android, you need to set the package name of the external signer app.

await NostrSignerPlugin.setPackageName({ packageName: 'com.example.signer' });

Check if External Signer is Installed

const { installed } = await NostrSignerPlugin.isExternalSignerInstalled();
if (!installed) {
  console.log('External signer app is not installed.');
}

Get a List of Installed External Signers

try {
  const result = await NostrSignerPlugin.getInstalledSignerApps();
  signerApps = result.apps;
  console.log('Installed Signer Apps:', signerApps);
} catch (error) {
  console.error('Error getting installed signer apps:', error);
}

The AppInfo object has the following fields"

export interface AppInfo {
  name: string;        // The name of the app as it appears in the System launcher
  packageName: string; // The package name of the app - pass this to setPackageName
  iconData: string;    // the base 64 encoded string of the app's icon
  iconUrl: string;    // the url to app's icon
}

Get Public Key

try {
  const { npub } = await NostrSignerPlugin.getPublicKey();
  console.log('Public Key:', npub);
} catch (error) {
  console.error('Error getting public key:', error);
}

Sign Event

const event = {
  kind: 1,
  content: 'Hello, Nostr!',
  tags: [],
  created_at: Math.floor(Date.now() / 1000),
};

try {
  const { event: signedEventJson } = await NostrSignerPlugin.signEvent({
    eventJson: JSON.stringify(event),
  });
  const signedEvent = JSON.parse(signedEventJson);
  console.log('Signed Event:', signedEvent);
} catch (error) {
  console.error('Error signing event:', error);
}

NIP-04 Encrypt

try {
  const { result: encryptedText } = await NostrSignerPlugin.nip04Encrypt({
    pubKey: 'recipient_public_key',
    plainText: 'Secret message',
  });
  console.log('Encrypted Text:', encryptedText);
} catch (error) {
  console.error('Error encrypting message:', error);
}

NIP-04 Decrypt

try {
  const { result: decryptedText } = await NostrSignerPlugin.nip04Decrypt({
    pubKey: 'sender_public_key',
    encryptedText: 'encrypted_text',
  });
  console.log('Decrypted Text:', decryptedText);
} catch (error) {
  console.error('Error decrypting message:', error);
}

NIP-44 Encrypt

try {
  const { result: encryptedText } = await NostrSignerPlugin.nip44Encrypt({
    pubKey: 'recipient_public_key',
    plainText: 'Secret message',
  });
  console.log('Encrypted Text (NIP-44):', encryptedText);
} catch (error) {
  console.error('Error encrypting message (NIP-44):', error);
}

NIP-44 Decrypt

try {
  const { result: decryptedText } = await NostrSignerPlugin.nip44Decrypt({
    pubKey: 'sender_public_key',
    encryptedText: 'encrypted_text',
  });
  console.log('Decrypted Text (NIP-44):', decryptedText);
} catch (error) {
  console.error('Error decrypting message (NIP-44):', error);
}

Decrypt Zap Event

try {
  const { result: decryptedEventJson } = await NostrSignerPlugin.decryptZapEvent({
    eventJson: JSON.stringify(encryptedEvent),
  });
  const decryptedEvent = JSON.parse(decryptedEventJson);
  console.log('Decrypted Zap Event:', decryptedEvent);
} catch (error) {
  console.error('Error decrypting zap event:', error);
}

API

getInstalledSignerApps(...)

getInstalledSignerApps() => Promise<{ apps: AppInfo[] }>

Returns a list of AppInfo objects which contain information about which Signer apps are installed.

Returns: Promise<{ apps: AppInfop[] }>

setPackageName(...)

setPackageName(options: { packageName: string; }) => Promise<void>

Sets the package name of the external Nostr signer app. This is required on Android to specify which app to interact with.

| Param | Type | Description | | ------------- | ------------------------------------ | --------------------------------------------- | | options | { packageName: string; } | An object containing the package name string. |


isExternalSignerInstalled()

isExternalSignerInstalled() => Promise<{ installed: boolean; }>

Checks if the external Nostr signer app is installed on the device.

Returns: Promise<{ installed: boolean; }>

An object indicating whether the signer app is installed.


getPublicKey()

getPublicKey() => Promise<{ npub: string; }>

Requests the public key from the Nostr signer app or extension.

Returns: Promise<{ npub: string; }>

An object containing the public key in npub format.


signEvent(...)

signEvent(options: { eventJson: string; }) => Promise<{ event: string; }>

Requests the signer app to sign a Nostr event.

| Param | Type | Description | | ------------- | ----------------------------------- | --------------------------------- | | options | { eventJson: string; } | An object containing the event in JSON string format. |

Returns: Promise<{ event: string; }>

An object containing the signed event in JSON string format.


nip04Encrypt(...)

nip04Encrypt(options: { plainText: string; pubKey: string; }) => Promise<{ result: string; }>

Encrypts a message using NIP-04 encryption.

| Param | Type | Description | | ------------- | ----------------------------------------------------- | ------------------------------------------- | | options | { plainText: string; pubKey: string; } | An object containing the plaintext and the recipient's public key. |

Returns: Promise<{ result: string; }>

An object containing the encrypted text.


nip04Decrypt(...)

nip04Decrypt(options: { encryptedText: string; pubKey: string; }) => Promise<{ result: string; }>

Decrypts a message using NIP-04 decryption.

| Param | Type | Description | | ------------- | ------------------------------------------------------- | ------------------------------------------- | | options | { encryptedText: string; pubKey: string; } | An object containing the encrypted text and the sender's public key. |

Returns: Promise<{ result: string; }>

An object containing the decrypted plaintext.


nip44Encrypt(...)

nip44Encrypt(options: { plainText: string; pubKey: string; }) => Promise<{ result: string; }>

Encrypts a message using NIP-44 encryption.

| Param | Type | Description | | ------------- | ----------------------------------------------------- | ------------------------------------------- | | options | { plainText: string; pubKey: string; } | An object containing the plaintext and the recipient's public key. |

Returns: Promise<{ result: string; }>

An object containing the encrypted text.


nip44Decrypt(...)

nip44Decrypt(options: { encryptedText: string; pubKey: string; }) => Promise<{ result: string; }>

Decrypts a message using NIP-44 decryption.

| Param | Type | Description | | ------------- | ------------------------------------------------------- | ------------------------------------------- | | options | { encryptedText: string; pubKey: string; } | An object containing the encrypted text and the sender's public key. |

Returns: Promise<{ result: string; }>

An object containing the decrypted plaintext.


decryptZapEvent(...)

decryptZapEvent(options: { eventJson: string; }) => Promise<{ result: string; }>

Decrypts a zap event.

| Param | Type | Description | | ------------- | ----------------------------------- | --------------------------------- | | options | { eventJson: string; } | An object containing the encrypted zap event in JSON string format. |

Returns: Promise<{ result: string; }>

An object containing the decrypted zap event in JSON string format.


Notes

  • On Android, the plugin communicates with external signer apps using intents and the Content Resolver as per NIP-55.
  • Ensure that the external signer app or browser extension supports the required NIP specifications.

License

MIT License