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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@keyban/sdk-base

v0.14.0

Published

Keyban Javascript SDK provides core functionalities for the MPC wallet solution, supporting web and Node.js apps with TypeScript, custom storage, and Ethereum blockchain integration.

Downloads

441

Readme

Keyban JavaScript SDK

The official JavaScript SDK for Keyban's Wallet as a Service (WaaS). Integrate secure MPC wallets into your JavaScript or Node.js applications with support for multiple blockchains, NFTs, tokens, and advanced features like Digital Product Passports and loyalty programs.

Installation

npm install @keyban/sdk-base @keyban/types

Quick Start

import { KeybanClient, Network } from "@keyban/sdk-base";

// Initialize the client
const client = new KeybanClient({
  appId: "your-app-id",
  network: Network.PolygonAmoy,
});

// Get an account
const account = await client.initialize();
console.log("Address:", account.address);

// Transfer native currency
const txHash = await account.transfer(
  "0xRecipientAddress",
  1_000_000_000_000_000_000n // 1 token in wei
);

Key Features

  • Multi-Blockchain Support - EVM (Ethereum, Polygon), Starknet, Stellar
  • MPC Security - Non-custodial wallets with threshold signatures
  • NFT & Token Support - ERC-20, ERC-721, ERC-1155, Soroban tokens
  • Digital Product Passports - Claim and manage tokenized products
  • Loyalty Programs - Points, rewards, wallet pass integration
  • GraphQL API - Real-time subscriptions for balances and transfers
  • TypeScript-First - Full type safety with @keyban/types
  • Custom Storage - Flexible client share persistence

Blockchain Support

| Feature | EVM (Ethereum, Polygon) | Starknet | Stellar | |---------|------------------------|----------|---------| | Native Transfers | ✅ ETH, POL | ✅ STRK | ✅ XLM | | ERC-20 Tokens | ✅ | 🚧 | ✅ Soroban | | NFTs (ERC-721/1155) | ✅ | 🚧 | 🚧 | | Message Signing | ✅ Hex | ✅ String[] | ✅ Base64 | | Fee Estimation | ✅ EIP-1559 | ✅ | ✅ Stroops | | Networks | Anvil, Amoy | Devnet, Sepolia, Mainnet | Quickstart, Testnet, Mainnet |

Core Operations

Initialize Account

const account = await client.initialize();
console.log({
  address: account.address,
  publicKey: account.publicKey,
  accountId: account.accountId,
});

Sign Message

// EVM - returns hex string
const signature = await account.signMessage("Hello, Keyban!");

// Stellar - returns base64 string
const signature = await stellarAccount.signMessage("Hello, Keyban!");

// Starknet - returns string array
const signatures = await starknetAccount.signMessage("Hello, Keyban!");

Transfer Native Currency

// Estimate fees first
const fees = await account.estimateTransfer("0xRecipient");
console.log("Estimated fees:", fees);

// Perform transfer
const txHash = await account.transfer(
  "0xRecipient",
  1_000_000_000_000_000_000n, // Amount in smallest unit (wei)
  fees // Optional: use custom fees
);

Transfer ERC-20 Tokens

const txHash = await account.transferERC20({
  contractAddress: "0xTokenContract",
  to: "0xRecipient",
  value: 1_000_000n, // 1 USDC (6 decimals)
});

Transfer NFTs

// ERC-721
await account.transferNft({
  contractAddress: "0xNftContract",
  to: "0xRecipient",
  tokenId: "123",
  standard: "ERC721",
});

// ERC-1155
await account.transferNft({
  contractAddress: "0xNftContract",
  to: "0xRecipient",
  tokenId: "456",
  standard: "ERC1155",
  value: 5n, // Transfer 5 copies
});

GraphQL Queries

The SDK provides pre-built GraphQL documents for querying blockchain data.

Query Token Balances

import { walletTokenBalancesDocument } from "@keyban/sdk-base/graphql";

const { data } = await client.apolloClient.query({
  query: walletTokenBalancesDocument,
  variables: {
    walletId: account.address,
    first: 20,
  },
});

console.log("Token balances:", data.wallet.tokenBalances.nodes);

Query NFTs

import { walletNftsDocument } from "@keyban/sdk-base/graphql";

const { data } = await client.apolloClient.query({
  query: walletNftsDocument,
  variables: {
    walletId: account.address,
    first: 20,
  },
});

console.log("NFTs:", data.wallet.nftBalances.nodes);

Real-Time Subscriptions

import { tokenBalancesSubscriptionDocument } from "@keyban/sdk-base/graphql";

const subscription = client.apolloClient.subscribe({
  query: tokenBalancesSubscriptionDocument,
  variables: { walletId: account.address },
}).subscribe({
  next: ({ data }) => {
    console.log("Balance updated:", data.tokenBalances);
  },
  error: (err) => console.error("Subscription error:", err),
});

// Don't forget to unsubscribe when done
subscription.unsubscribe();

Query Transfer History

import { walletAssetTransfersDocument } from "@keyban/sdk-base/graphql";

const { data } = await client.apolloClient.query({
  query: walletAssetTransfersDocument,
  variables: {
    walletId: account.address,
    first: 50,
  },
});

console.log("Transaction history:", data.wallet.assetTransfers.nodes);

Digital Product Passports (DPP)

Claim tokenized products using the DPP service.

// Claim a product with authentication
const result = await client.api.dpp.claim({
  productId: "product-uuid",
  password: "product-password",
});

// Magic claim (passwordless)
const result = await client.api.dpp.magicClaim({
  productId: "product-uuid",
  magicToken: "magic-token-uuid",
});

// Get product details
const product = await client.api.dpp.getProduct("product-uuid");
console.log("Product:", product.name, product.status);

Loyalty Programs

Access loyalty points, rewards, and wallet passes.

// Get loyalty balance
const balance = await client.api.loyalty.getBalance();
console.log("Points:", balance.points);

// Get reward tiers
const tiers = await client.api.loyalty.getRewardTiers();
console.log("Available rewards:", tiers);

// Add to Apple/Google Wallet
const passUrl = await client.api.loyalty.addToWalletPass("google");
window.open(passUrl, "_blank");

Balance Formatting

import { formatBalance } from "@keyban/sdk-base";

const balance = {
  raw: 1_500_000_000_000_000_000n,
  decimals: 18,
  symbol: "ETH",
  isNative: true,
};

const formatted = formatBalance(client, balance);
console.log(formatted); // "1.5 ETH"

Error Handling

The SDK provides typed errors for precise error handling.

import { SdkError, SdkErrorTypes } from "@keyban/sdk-base";

try {
  await account.transfer(recipient, amount);
} catch (error) {
  if (error instanceof SdkError) {
    switch (error.type) {
      case SdkErrorTypes.InsufficientFunds:
        console.error("Not enough balance");
        break;
      case SdkErrorTypes.AddressInvalid:
        console.error("Invalid recipient address");
        break;
      case SdkErrorTypes.AmountInvalid:
        console.error("Invalid amount");
        break;
      default:
        console.error("SDK error:", error.message);
    }
  } else {
    console.error("Unexpected error:", error);
  }
}

Available Error Types

SdkErrorTypes:

  • AddressInvalid - Invalid blockchain address format
  • AmountInvalid - Invalid amount (zero, negative, or exceeds limits)
  • AmountRequired - Amount is required but not provided
  • AmountIrrelevant - Amount provided when not needed
  • RecipientAddressEqualsSender - Cannot send to yourself
  • EstimateGasExecution - Gas estimation failed
  • InsufficientFunds - Insufficient balance
  • InvalidNftStandard - Unsupported NFT standard
  • NftNotFound - NFT not found
  • TokenBalanceNotFound - Token balance not found
  • UnknownTransactionError - Unknown transaction error
  • UnknownIframeApiError - Unknown API communication error

Other Error Classes:

  • CryptoError - Cryptographic operations (encrypt, decrypt, key import)
  • JwtError - Token parsing/validation
  • IFrameApiError - IFrame communication errors

Custom Client Share Provider

Implement custom storage for MPC client shares.

import { ClientShareProvider } from "@keyban/sdk-base";

class MyClientShareProvider implements ClientShareProvider {
  async get(key: string): Promise<string | null> {
    // Retrieve from your backend
    const response = await fetch(`/api/shares/${key}`, {
      headers: { Authorization: `Bearer ${userToken}` },
    });
    return response.ok ? await response.text() : null;
  }

  async set(key: string, clientShare: string): Promise<void> {
    // Store in your backend
    await fetch("/api/shares", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${userToken}`,
      },
      body: JSON.stringify({ key, clientShare }),
    });
  }
}

// Use custom provider
const client = new KeybanClient({
  appId: "your-app-id",
  network: Network.PolygonAmoy,
  clientShareProvider: new MyClientShareProvider(),
});

Security Best Practices

  • ✅ Protect storage endpoints with authentication
  • ✅ Use per-user keys (not shared keys)
  • ✅ Enable audit logging for access
  • ✅ Never expose client shares in logs or error messages
  • ✅ Consider encryption at rest
  • ✅ Implement key rotation if possible

Authentication & API Services

The SDK provides access to additional services through client.api:

// Authentication
await client.api.auth.signUp({ email, password });
await client.api.auth.signIn({ email, password });
await client.api.auth.sendOtp({ email });

// Account info
const address = await client.api.account.getAddress();
const accountId = await client.api.account.getAccountId();

// Application info
const app = await client.api.application.getApplication();
console.log("App:", app.name, app.features);

// Signer operations (advanced)
await client.api.signerEcdsa.dkg();
const signature = await client.api.signerEcdsa.sign(message);

Network Configuration

Fee Units

| Network | Fee Unit | Decimals | Example | |---------|----------|----------|---------| | EVM (Ethereum, Polygon) | gwei | 9 | 20 gwei = 20_000_000_000 wei | | Starknet | FRI | 18 | 1 FRI = 1_000_000_000_000_000_000 | | Stellar | stroop | 7 | 100 stroops = 0.00001 XLM |

Native Currency

| Network | Symbol | Decimals | |---------|--------|----------| | Ethereum Anvil | ETH | 18 | | Polygon Amoy | POL | 18 | | Starknet | STRK | 18 | | Stellar | XLM | 7 |

Development

# Build the package
npm run build

# Type check
npm run typecheck

# Run tests
npm test

# Lint
npm run lint

Compatibility

  • Node.js: 18+ recommended
  • Browsers: Modern browsers with ESM support
  • TypeScript: 5.0+ for best type inference
  • Bundlers: Vite, webpack, rollup supported

Related Packages

License

See the main repository for license information.