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

arc-sdk-test

v0.0.55

Published

Arc SDK Test

Readme

arcane-sdk

TypeScript SDK for interacting with the Arcane privacy protocol on Solana — deposits, withdrawals, private transfers, and fee quotes.

Installation

npm install arcane-sdk

Peer dependencies (optional, for React):

npm install @solana/wallet-adapter-react react

Prerequisites

  • A Solana wallet (Keypair for backend/scripts, or a wallet adapter with signMessage / signAllTransactions for frontend)
  • A Range API key (rangeApiKey)
  • An RPC endpoint or existing @solana/web3.js Connection

Supported networks: mainnet and devnet (inferred from the RPC URL, or set explicitly via network).


Creating an ArcaneSDK instance

Create one SDK instance per configuration (network, RPC, wallet). Initialization loads active relayers for the target network.

Node / backend

import { Keypair } from "@solana/web3.js";
import { ArcaneSDK } from "arcane-sdk";

const wallet = Keypair.generate(); // or your existing keypair

const sdk = await ArcaneSDK.create({
  rangeApiKey: process.env.RANGE_API_KEY!,
  rpcEndpoint: "https://api.devnet.solana.com",
  wallet,
});

React (wallet-adapter)

Wrap your app with ConnectionProvider and WalletProvider, then use the React hook:

import { useArcaneSdk } from "arcane-sdk/react";

function MyComponent() {
  const sdk = useArcaneSdk({
    rangeApiKey: import.meta.env.VITE_RANGE_API_KEY,
  });

  if (!sdk) return null; // wallet not connected yet

  // use sdk...
}

Init options

| Option | Required | Description | |--------|----------|-------------| | rangeApiKey | yes | Range API key for risk/oracle features | | wallet | yes | Anchor-compatible wallet (Keypair or wallet adapter) | | rpcEndpoint | one of | Solana JSON-RPC URL (Node/scripts) | | connection | one of | Existing Connection (e.g. from useConnection()) | | network | no | "mainnet" or "devnet" — override when the RPC URL has no cluster hint |

After creation, inspect runtime config via sdk.config or helpers like sdk.getNetwork(), sdk.relayers, and sdk.getTokenMints().


getEncryptionKey

Derives a note-encryption key from a wallet signature and stores it on the SDK instance (sdk.encryptKey). Required before any deposit that uses on-chain note backup (onChainBackup: true, including arcaneTransfer).

The wallet signs the message arcane:notes:v1. Accepts a backend Keypair or a frontend wallet adapter with signMessage.

await sdk.getEncryptionKey(wallet);
// sdk.encryptKey is now set

The key is used to encrypt secret notes before they are stored on-chain via backupNotes, so you can recover notes later from the same wallet.


buildDepositTx

Builds an unsigned deposit transaction for a pre-generated secret note.

1. Generate deposit parameters

// 1 SOL deposit (lamports)
const { note } = sdk.generateDepositParams(1_000_000_000n, null);

// SPL token deposit — pass the token mint
const usdcMint = sdk.getTokenMint("USDC");
const { note: usdcNote } = sdk.generateDepositParams(1_000_000n, usdcMint);

Deposit amounts must match supported pool denominations for each token.

2. Build the transaction

await sdk.getEncryptionKey(wallet); // required when onChainBackup is true

const { tx, note } = await sdk.buildDepositTx({
  senderPublicKey: wallet.publicKey,
  note,
  onChainBackup: true,       // encrypt and store note on-chain (recommended)
  computeUnitPrice: 50_000,  // optional priority fee
});

Sign and send the returned tx with your wallet. Save the returned note — it is required to withdraw later.

| Parameter | Description | |-----------|-------------| | senderPublicKey | Depositor's public key | | note | Secret note from generateDepositParams | | onChainBackup | When true, encrypts the note and adds a backupNotes instruction (requires getEncryptionKey) | | computeUnitPrice | Priority fee in micro-lamports (default 50000) |


withdraw

Withdraws funds from the privacy pool to a recipient using a secret note from a prior deposit. The SDK:

  1. Validates the recipient against the risk API
  2. Fetches Merkle commitments from the indexer
  3. Generates a ZK withdraw proof
  4. Submits the proof to a relayer (chosen at random, or by index)
  5. Polls until the relayer confirms the on-chain transaction
const result = await sdk.withdraw({
  note: "arcane-1-...",           // secret note from deposit
  recipient: "RecipientPubkey...", // withdrawal destination
  relayerIdx: 0,                   // optional — random relayer when omitted
});

console.log(result.txHash);  // on-chain transaction signature
console.log(result.status);  // "success" | "failed"

| Parameter | Description | |-----------|-------------| | note | Secret note from the original deposit | | recipient | Recipient public key (PublicKey or base58 string) | | relayerIdx | Optional index into sdk.relayers |

Withdraw fees are calculated automatically from the relayer fee and on-chain platform fee.


arcaneTransfer

End-to-end private transfer: deposit into the pool (split across supported denominations), then withdraw each successful note to the recipient. Handles signing, sending, and settlement automatically.

Requires getEncryptionKey before calling — all deposits use on-chain backup.

import { PublicKey } from "@solana/web3.js";

await sdk.getEncryptionKey(wallet);

const result = await sdk.arcaneTransfer(
  [
    {
      mint: new PublicKey(sdk.getTokenMint("USDC")),
      amount: "25.5",                              // human-readable amount
      recipient: new PublicKey("RecipientPubkey..."),
    },
    {
      mint: new PublicKey(sdk.getTokenMints().Solana),
      amount: "1.5",
      recipient: new PublicKey("AnotherRecipient..."),
    },
  ],
  { uniqueRelayer: true } // optional — use one relayer for all withdraws
);

if (result.error) {
  console.log("Deposit failures:", result.depositFailed);
  console.log("Withdraw failures:", result.withdrawFailed);
}

| Field | Description | |-------|-------------| | items[].mint | Token mint to transfer | | items[].amount | Human-readable amount (e.g. "1.5" SOL) | | items[].recipient | Withdrawal destination for that transfer | | options.uniqueRelayer | When true, all withdraws share one randomly selected relayer |

The SDK splits each amount into the nearest supported deposit denominations, builds and sends deposit transactions, waits for settlement, then withdraws each note to its recipient. Partial failures are reported in depositFailed and withdrawFailed without throwing.


getQuote

Fetches a withdraw fee quote from the Arcane indexer before executing a withdrawal. Returns estimated relayer fees, recipient amount, ETA, and how the amount splits across denominations.

const { quote } = await sdk.getQuote({
  amount: 1.5,                    // human-readable amount
  amountLamports: 1_500_000_000,  // same amount in smallest units
  recipient: "RecipientPubkey...",
  asset: "SOL",                   // optional — default "SOL"
});

console.log(quote.recipientAmount);  // amount recipient receives after fees
console.log(quote.totalRelayerFee);
console.log(quote.etaSeconds);
console.log(quote.splits);           // per-denomination breakdown
console.log(quote.platformFee);      // platform fee (added by SDK)

| Parameter | Description | |-----------|-------------| | amount | Human-readable transfer/withdraw amount | | amountLamports | Amount in smallest token units | | recipient | Intended withdrawal recipient | | asset | Indexer asset label (default "SOL") | | network | Optional cluster override |

getQuote is also exported as a standalone function but requires an initialized SDK context.


Typical flows

Deposit and withdraw

const sdk = await ArcaneSDK.create({ rangeApiKey, rpcEndpoint, wallet });

await sdk.getEncryptionKey(wallet);

const { note } = sdk.generateDepositParams(1_000_000_000n, null);
const { tx } = await sdk.buildDepositTx({
  senderPublicKey: wallet.publicKey,
  note,
  onChainBackup: true,
});

// sign and send tx...

const { txHash } = await sdk.withdraw({
  note,
  recipient: "RecipientPubkey...",
});

Quote before withdraw

const { quote } = await sdk.getQuote({
  amount: 1,
  amountLamports: 1_000_000_000,
  recipient: "RecipientPubkey...",
});

console.log(`Recipient receives ~${quote.recipientAmount} SOL`);

await sdk.withdraw({ note, recipient: "RecipientPubkey..." });

Supported deposit denominations

Amounts must decompose exactly into these pool denominations:

| Token | Denominations | |-------|---------------| | SOL | 0.1, 1, 5, 10, 50, 100, 500 | | USDC | 1, 10, 50, 100, 1000, 10000, 100000, 1000000 | | Arcane | 1, 10, 50, 100, 500, 1000, 10000, 100000, 1000000 | | Bitcoin | 0.01, 0.05, 0.1, 0.5, 1, 5 | | Ethereum | 0.1, 1, 10, 50, 100, 500 |

Use sdk.getDepositAmounts("Solana") (or another symbol) to retrieve the list programmatically.


License

MIT