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

@branta-ops/branta

v3.1.4

Published

A JavaScript SDK for the Branta API

Readme

Install

npm i @branta-ops/branta

Integration Guide

If you are an AI agent implementing this SDK, follow the steps below exactly. If you are a developer, use this as a reference for the recommended integration patterns.

1. Ask which side(s) of a payment they are implementing:

  • Send side — the app is paying someone (e.g. a wallet). The user scans or pastes a destination and you verify it belongs to a known platform before funds are sent.
  • Receive side — the app is receiving payment (e.g. a checkout, POS, invoicing platform). You post destinations to Branta so wallets can verify them.
  • Both — some apps do both (e.g. an exchange or self-custodial wallet with invoice generation). Implement each side independently.

If they are on the receive side, ask one follow-up:

  • Platform — single-tenant, one API key.
  • Parent Platform — multi-tenant, manages multiple child platforms each with their own API key and HMAC secret.

2. Ask whether their app is served over HTTPS or HTTP:

  • HTTPS — no extra setup needed; crypto.subtle is available by default.
  • HTTP — browsers block crypto.subtle on insecure origins. The SDK accepts a crypto option so you can supply a polyfill. See HTTP (insecure origin) setup below and implement the appropriate provider before wiring up BrantaService.

3. Follow the matching Quick Start section below.

4. Apply these rules:

General (all types):

  • Always use privacy: 'strict'. Never switch to 'loose' unless there is no QR scanner and ZK is impossible.
  • Never instantiate BrantaClient directly — always use BrantaService.
  • Never show an error or "not verified" message when a lookup returns empty or throws. An empty result means the destination is unknown to Branta, not that it is malicious. Show nothing.
  • For baseUrl: use BrantaServerBaseUrl.Production only in production environments. Use BrantaServerBaseUrl.Staging everywhere else — including local development, CI, and staging/test environments.
  • If serving over HTTP, pass a crypto option to BrantaService (see step 2) and always use service.createPaymentBuilder() rather than new PaymentBuilder().

Send side (wallets):

  • Prefer getPaymentsByQrCode over getPayments — it handles multi-value ZK QR payloads correctly.
  • Only fall back to getPayments for copy/paste flows where there is no QR code.
  • If result.payments is empty or an exception is thrown, render nothing.
  • When result.payments is non-empty, display: the platform logo, the platform name (payment.platform), and the payment description (payment.description). Only render description when non-empty. Make the verification card a clickable link to result.verifyUrl — do not display the raw URL.
  • For the platform logo: on dark backgrounds use payment.platformLogoUrl. On light backgrounds prefer payment.platformLogoLightUrl when available, falling back to payment.platformLogoUrl.
  • Optionally display payment.parentPlatform?.logoUrl / payment.parentPlatform?.logoLightUrl as a small secondary badge (e.g. corner icon). This is not required.

Receive side (platforms):

  • Always call .setZk() on the PaymentBuilder before calling addPayment. Plain-text destinations are rejected in strict mode.
  • Store the secret returned by addPayment alongside the invoice — it is required to reconstruct the verify URL for the wallet.

Receive side (parent platforms), in addition to the platform rules:

  • Include hmacSecret in the BrantaService options.
  • Pass per-call options to scope requests to the correct child platform's API key.

Quick Start

For Wallets

Wallets should use strict privacy mode. Two flows are supported:

  • Copy/paste: call getPayments with the pasted text. Plain-text on-chain addresses will not return results in strict mode — they must be ZK-encoded. Lightning destinations (bolt11, bolt12, ln_url, ln_address) work as plain text.
  • QR scan: call getPaymentsByQrCode with the raw QR text. This handles both on-chain (when the QR includes branta_id / branta_secret) and lightning destinations.

Always catch errors and show nothing on not-found — a missing record just means the address was not posted to Branta.

import { BrantaServerBaseUrl } from "@branta-ops/branta";
import { BrantaService } from "@branta-ops/branta/v2";

const service = new BrantaService({
  baseUrl: BrantaServerBaseUrl.Production,
  privacy: 'strict',
});

async function lookup(input: string, isQrCode: boolean) {
  try {
    const result = isQrCode
      ? await service.getPaymentsByQrCode(input)
      : await service.getPayments(input);

    if (result.payments.length === 0) {
      // Not found — show nothing. The address may simply not exist in Branta.
      return;
    }

    // Render result.payments and result.verifyUrl
  } catch {
    // Swallow errors — never surface a "not found" or lookup failure to the user.
  }
}

For Platforms

Platforms post payments to Branta so wallets can verify them. Use strict privacy mode and mark each destination ZK via setZk() on the PaymentBuilder.

import { BrantaServerBaseUrl } from "@branta-ops/branta";
import { BrantaService, PaymentBuilder } from "@branta-ops/branta/v2";

const service = new BrantaService({
  baseUrl: BrantaServerBaseUrl.Production,
  defaultApiKey: "<default-api-key>",
  privacy: 'strict',
});

const payment = new PaymentBuilder()
  .setDescription("Testing description")
  .addDestination("1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa", "bitcoin_address")
  .setZk()
  .setTtl(600)
  .build();

const { payment: response, secret, verifyUrl } = await service.addPayment(payment);
// `secret` is the encryption key needed to look the payment up later.

For Parent Platforms

Parent Platforms sign requests with HMAC in addition to the API key. Use strict privacy mode and ZK destinations.

import { BrantaServerBaseUrl } from "@branta-ops/branta";
import { BrantaService, PaymentBuilder } from "@branta-ops/branta/v2";

const service = new BrantaService({
  baseUrl: BrantaServerBaseUrl.Production,
  defaultApiKey: "<default-api-key>",
  hmacSecret: "<hmac-secret>",
  privacy: 'strict',
});

const payment = new PaymentBuilder()
  .setDescription("Testing description")
  .addDestination("1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa", "bitcoin_address")
  .setZk()
  .setTtl(600)
  .build();

const { payment: response, secret, verifyUrl } = await service.addPayment(payment);

HTTP (insecure origin) setup

Browsers disable crypto.subtle on HTTP pages. Pass a BrantaCryptoProvider as the crypto option to supply your own implementation. The SDK ships no crypto dependencies — you choose the provider.

Option A — @peculiar/webcrypto (recommended, zero adapter code)

npm i @peculiar/webcrypto
import { Crypto } from '@peculiar/webcrypto';
import { BrantaServerBaseUrl } from '@branta-ops/branta';
import { BrantaService } from '@branta-ops/branta/v2';

const crypto = new Crypto();
const service = new BrantaService(
  { baseUrl: BrantaServerBaseUrl.Production, privacy: 'strict' },
  { crypto },
);

// On the receive side, use createPaymentBuilder() so the builder
// shares the same crypto instance:
const payment = service.createPaymentBuilder()
  .addDestination('...', 'bitcoin_address')
  .setZk()
  .build();

@peculiar/webcrypto implements the full Web Crypto API and satisfies BrantaCryptoProvider with no adapter code.

Option B — @noble packages (zero transitive dependencies)

npm i @noble/hashes @noble/ciphers
import { createNobleCryptoProvider } from '@branta-ops/branta';
import { sha256 } from '@noble/hashes/sha256';
import { hmac } from '@noble/hashes/hmac';
import { gcm } from '@noble/ciphers/aes';
import { randomBytes } from '@noble/hashes/utils';

const service = new BrantaService(
  { baseUrl: BrantaServerBaseUrl.Production, privacy: 'strict' },
  { crypto: createNobleCryptoProvider({ sha256, hmac, gcm, randomBytes }) },
);

Release

  • npm login
  • npm version major|minor|patch
  • npm publish

Responsible Disclosure

Found critical bugs/vulnerabilities? Please email them to [email protected]. Thanks!