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

@happyvertical/signatures

v0.84.0

Published

Provider-neutral e-signature workflows with a BoldSign adapter

Downloads

3,473

Readme

@happyvertical/signatures

Provider-neutral e-signature request, lifecycle, verified-webhook, and execution-evidence contracts. BoldSign is the first adapter.

Status

This package is experimental while the first downstream agreement workflow validates the provider-neutral contract.

Install

pnpm add @happyvertical/signatures

BoldSign quick start

Create one adapter per tenant credential and webhook signing secret. HappyVertical deployments use BoldSign's Canadian region by default.

import { createSignatureProvider } from '@happyvertical/signatures';

const signatures = await createSignatureProvider({
  type: 'boldsign',
  tenantId: 'tenant_123',
  apiKey: process.env.BOLDSIGN_API_KEY!,
  webhookSecrets: [process.env.BOLDSIGN_WEBHOOK_SECRET!],
  region: 'ca',
});

const request = await signatures.createRequest({
  tenantId: 'tenant_123',
  idempotencyKey: 'referral-agreement:version_456',
  title: 'Referral Agreement',
  documents: [
    {
      name: 'referral-agreement.pdf',
      mediaType: 'application/pdf',
      data: generatedPdf,
    },
  ],
  signers: [
    {
      name: 'Alex Example',
      email: '[email protected]',
      authentication: { method: 'email_otp' },
      fields: [
        {
          id: 'referrer_signature',
          type: 'signature',
          page: 3,
          bounds: { x: 72, y: 620, width: 180, height: 36 },
        },
      ],
    },
  ],
  expiresInDays: 30,
});

Adapters

  • BoldSign (type: 'boldsign') uses the regional v1 document API, HMAC-verified webhooks, and PDF artifact endpoints.

The package sends JSON with base64 documents to BoldSign's asynchronous POST /v1/document/send API. A successful create response means BoldSign accepted processing; the verified Sent or SendFailed webhook is authoritative for the next transition.

Webhooks and replay protection

Pass the exact raw UTF-8 request body and X-BoldSign-Signature header. Do not parse and re-serialize the body before verification.

const event = signatures.parseWebhook({
  payload: rawBody,
  signature: request.headers.get('x-boldsign-signature')!,
});

The adapter verifies BoldSign's HMAC-SHA256 signature using constant-time comparison and rejects timestamps outside the configured tolerance (five minutes by default). It also requires the signed payload's hvTenantId metadata to match the adapter tenant. Persist event.id under a unique constraint before applying an event; the SDK intentionally does not pretend an in-memory replay cache is durable.

Configure the webhook for Sent, Signed, Completed, Viewed, Declined, Revoked, Expired, DeliveryFailed, and SendFailed. Other signed event types are rejected until the provider-neutral contract defines their semantics.

BoldSign sends an unsigned Verification callback while a webhook endpoint is configured. Acknowledge that control request before calling parseWebhook; do not treat it as a document event.

Idempotency and ambiguous failures

createRequest requires an idempotency key and stores it in BoldSign metadata as hvIdempotencyKey. BoldSign's public send-document contract does not advertise an atomic idempotency header, so capabilities.providerEnforcedIdempotency is false. The durable application layer must claim the tenant/key before sending and persist the returned document ID. When SignatureProviderError.requestMayHaveSucceeded is true, reconcile rather than blindly sending a duplicate agreement.

Execution evidence

Artifacts are available only after the normalized request status is completed:

const signed = await signatures.downloadArtifact({
  tenantId: 'tenant_123',
  requestId: request.id,
  kind: 'signed_document',
});

const audit = await signatures.downloadArtifact({
  tenantId: 'tenant_123',
  requestId: request.id,
  kind: 'audit_trail',
});

await immutableAssets.put(signed.filename, signed.stream);
const signedSha256 = await signed.sha256;

Each artifact exposes a single-use byte stream and a SHA-256 promise that resolves after that stream is consumed. Persist the stream to immutable/versioned storage, then await and record the digest together with the provider request ID, event ID, tenant, signer identity, retrieval time, and agreement version. The provider is a retrieval source, not the system of record for an executed agreement.

Operations and security

  • Keep API keys, OAuth tokens, access codes, and webhook secrets in the SDK/SMRT secret store; never put them in agreement metadata or logs.
  • Scope an adapter instance to exactly one tenant. Reads, mutations, downloads, and webhooks all enforce that tenant binding.
  • For secret rotation, configure both valid webhook secrets temporarily. BoldSign may also include both s0 and s1 signatures in its header.
  • cancelRequest requires a reason. extendExpiry verifies tenant ownership first and only accepts a future date.
  • API credentials may use either X-API-KEY or an OAuth bearer token, never both.
  • Use the sandbox for contract testing, but do not treat its watermarked PDFs as legal artifacts.

Provider references