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

@solana/keychain-dfns

v2.0.0

Published

Dfns-based signer for Solana transactions

Downloads

1,518

Readme

@solana/keychain-dfns

Dfns-based signer for Solana transactions using Dfns Keys API.

Installation

pnpm add @solana/keychain-dfns

Prerequisites

  1. A Dfns account with API access
  2. A Solana wallet created in the Dfns dashboard
  3. A service account with signing permissions

Setting Up a Service Account

Follow the Creating a Service Account guide:

  1. Generate a keypair - https://docs.dfns.co/guides/developers/generate-a-key-pair#generate-a-key-pair
  2. Create the service account in Settings > Developers > Service Accounts, pasting your public key
  3. Save the auth token — it is only shown once. Store it securely along with your private key
  4. Configure permissions — assign a role with minimal required permissions

You will need:

  • Auth token (authToken) — the service account token
  • Credential ID (credId) — shown in the service account details
  • Private key (privateKeyPem) — the PEM key you generated in step 1
  • Wallet ID (walletId) — found in the Dfns dashboard under Wallets

Usage

Basic Setup

import { createDfnsSigner } from '@solana/keychain-dfns';

const signer = await createDfnsSigner({
    authToken: 'your-service-account-token',
    credId: 'your-credential-id',
    privateKeyPem: `-----BEGIN PRIVATE KEY-----
...your private key...
-----END PRIVATE KEY-----`,
    walletId: 'wa-xxxxx-xxxxx-xxxxx',
});

console.log('Signer address:', signer.address);

Signing Transactions

import {
    appendTransactionMessageInstructions,
    createSolanaRpc,
    createTransactionMessage,
    getBase64EncodedWireTransaction,
    pipe,
    setTransactionMessageFeePayerSigner,
    setTransactionMessageLifetimeUsingBlockhash,
    signTransactionMessageWithSigners,
} from '@solana/kit';

const rpc = createSolanaRpc('https://api.devnet.solana.com');
const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();

const message = pipe(
    createTransactionMessage({ version: 0 }),
    (tx) => setTransactionMessageFeePayerSigner(signer, tx),
    (tx) => appendTransactionMessageInstructions([/* your instructions */], tx),
    (tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),
);

const signedTx = await signTransactionMessageWithSigners(message);
const encoded = getBase64EncodedWireTransaction(signedTx);
await rpc.sendTransaction(encoded).send();

Signing Messages

const message = new TextEncoder().encode('Hello, Solana!');
const [signatureDictionary] = await signer.signMessages([{ content: message }]);

Configuration

DfnsSignerConfig

| Field | Type | Required | Default | Description | |-----------------|----------|----------|-------------------------|---------------------------------------------------| | authToken | string | Yes | - | Service account token or personal access token | | credId | string | Yes | - | Credential ID for user action signing | | privateKeyPem | string | Yes | - | Private key in PEM format | | walletId | string | Yes | - | Dfns wallet ID (starts with wa-) | | apiBaseUrl | string | No | https://api.dfns.io | Custom API base URL | | requestDelayMs| number | No | 0 | Delay in ms between concurrent signing requests |

How It Works

  1. Initialization: create() fetches the wallet from Dfns API and validates the Ed25519 public key (your Solana address)
  2. Signing: Transactions and messages are sent to the Dfns Keys API (/keys/{keyId}/signatures) which returns Ed25519 signature components (r, s)
  3. User Action Signing: Mutating API requests (like signing) go through a 3-step challenge/response flow — the SDK handles this automatically using your credId and privateKeyPem

Error Handling

The signer throws errors with specific codes from @solana/keychain-core:

  • CONFIG_ERROR — Invalid configuration (missing fields, inactive wallet, unsupported key type)
  • REMOTE_API_ERROR — Dfns API returned an error
  • SIGNING_FAILED — Signature request failed or requires policy approval
  • PARSING_ERROR — Failed to parse Dfns response
import { SignerErrorCode } from '@solana/keychain-core';

try {
    await signer.signMessages([message]);
} catch (error) {
    if (error.code === SignerErrorCode.REMOTE_API_ERROR) {
        console.error('Dfns API error:', error.message);
    }
}

Security Considerations

  1. Token Security: Never hardcode auth tokens. Use environment variables or a secrets manager.
  2. Private Key: Store the PEM private key securely. It is used to sign every user action requests.
  3. Policy Engine: Configure Dfns Policies to enforce signing rules and approval workflows.