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

@icp-sdk/signer

v5.4.0

Published

Library to interact with signers on the Internet Computer

Downloads

8,922

Readme

@icp-sdk/signer

Library to interact with ICRC-25 compliant signers on the Internet Computer.

What are signers?

A signer is an application that holds private keys and can sign messages on behalf of a user. Each signer chooses which standards to implement, but they typically fall into two categories:

  • Asset wallets support accounts and canister calls — users approve transactions directly through the signer (e.g. OISY, Plug, PrimeVault).
  • Authentication providers support delegations — users grant a session key that can sign on their behalf for a limited time (e.g. Internet Identity).

Some signers support both (e.g. NFID). This library provides a unified interface to interact with all of them.

Installation

npm install @icp-sdk/signer

Import Paths

  • @icp-sdk/signerSigner for standardized signer interaction
  • @icp-sdk/signer/agentSignerAgent as a drop-in replacement for HttpAgent
  • @icp-sdk/signer/webPostMessageTransport for web-based signers
  • @icp-sdk/signer/extensionBrowserExtensionTransport for browser extension signers

Connecting to a Signer

Two transport types are supported. Web-based signers (like OISY, NFID, Internet Identity) use a window opened to the signer's URL. Browser extensions (like Plug, PrimeVault) are discovered automatically.

Web

The ICRC-29 post message transport communicates with signers that run as web applications. A window is opened to the signer's URL, and messages are exchanged via postMessage.

import { Signer } from "@icp-sdk/signer";
import { PostMessageTransport } from "@icp-sdk/signer/web";

const transport = new PostMessageTransport({ url: SIGNER_URL });
const signer = new Signer({ transport });

Extension

The ICRC-94 transport communicates with signers installed as browser extensions. Extensions announce themselves and are discovered automatically.

import { Signer } from "@icp-sdk/signer";
import { BrowserExtensionTransport } from "@icp-sdk/signer/extension";

// Discover all installed extension signers
const providerDetails = await BrowserExtensionTransport.discover();

// Let the user choose, then create a transport
const transport = new BrowserExtensionTransport({
  providerDetail: providerDetails[0],
});
const signer = new Signer({ transport });

Or connect directly by UUID if you know which extension to use:

const transport = await BrowserExtensionTransport.findTransport({
  uuid: EXTENSION_UUID,
});

Checking Capabilities

Signers vary in what they support. Query the supported standards before making calls so you can handle unsupported features gracefully:

const standards = await signer.getSupportedStandards();

// signer.getAccounts() requires ICRC-27
const canGetAccounts = standards.some((s) => s.name === "ICRC-27");

// signer.callCanister() requires ICRC-49
const canCallCanisters = standards.some((s) => s.name === "ICRC-49");

// signer.requestDelegation() requires ICRC-34
const canDelegate = standards.some((s) => s.name === "ICRC-34");

// Asset wallets need both accounts and canister calls
const isAssetWallet = canGetAccounts && canCallCanisters;

// The returned standards also include token standards (e.g. ICRC-1 for
// fungible tokens, ICRC-7 for NFTs), so you can check whether the
// signer can manage a particular asset type.
const supportsFungibleTokens = standards.some((s) => s.name === "ICRC-1");

Transactions

Asset wallets allow users to approve transactions. Use SignerAgent as a drop-in replacement for HttpAgent — it routes canister calls through the signer for user approval.

import { Signer } from "@icp-sdk/signer";
import { PostMessageTransport } from "@icp-sdk/signer/web";
import { SignerAgent } from "@icp-sdk/signer/agent";

// Connect to an asset wallet
const transport = new PostMessageTransport({ url: "https://oisy.com/sign" });
const signer = new Signer({ transport });

// Get the user's accounts — some asset wallets return multiple (e.g. NFID),
// others only one (e.g. OISY).
// Each account has an `owner` (Principal) and an optional `subaccount`.
const accounts = await signer.getAccounts();
const account = accounts[0]; // Let the user choose if there are multiple

// Create an agent for the chosen account's principal.
// The agent only needs the owner — the principal that controls the account
// and on whose behalf canister calls are signed.
const agent = await SignerAgent.create({
  signer,
  account: account.owner,
});

// Use the agent with any canister library
import { IcrcLedgerCanister } from "@icp-sdk/canisters/ledger/icrc";

const icpLedger = IcrcLedgerCanister.create({
  agent,
  canisterId: ICP_LEDGER_CANISTER_ID,
});
await icpLedger.transfer({
  to: TARGET_ACCOUNT,
  amount: 100_000_000n,
});

Authentication

Authentication providers issue delegations — temporary keys that can sign on behalf of the user. This is useful for session-based authentication where individual transaction approval is not needed.

import { Signer } from "@icp-sdk/signer";
import { PostMessageTransport } from "@icp-sdk/signer/web";
import { ECDSAKeyIdentity, DelegationIdentity } from "@icp-sdk/core/identity";
import { HttpAgent } from "@icp-sdk/core/agent";

// Connect to an authentication provider
const transport = new PostMessageTransport({ url: "https://id.ai/authorize" });
const signer = new Signer({ transport });

// Create a session key and request a delegation
const sessionKey = await ECDSAKeyIdentity.generate();
const delegationChain = await signer.requestDelegation({
  publicKey: sessionKey.getPublicKey().toDer(),
});

// Create a DelegationIdentity that can sign without further user interaction
const identity = DelegationIdentity.fromDelegation(sessionKey, delegationChain);
const agent = await HttpAgent.create({ identity });

TypeScript

This package requires the node16 (or later) moduleResolution strategy.

License

This project is licensed under the Apache-2.0 license.