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

@zkp2p/sdk

v0.3.1

Published

ZKP2P Client SDK - TypeScript SDK for deposit management, liquidity provision, and onramping

Readme

@zkp2p/sdk

npm version npm types License: MIT

Stable TypeScript SDK for trustless fiat-to-crypto on Base. ZKP2P combines escrowed on-chain settlement, TLS attestations for payment verification, and API/indexer helpers so makers, takers, wallets, and embedded ramps can ship production-grade fiat liquidity flows without building their own contract or indexing stack.

Current version: 0.3.1

Why This SDK

  • Build maker, taker, vault, and embedded ramp flows from one client.
  • Read live protocol state directly from ProtocolViewer instead of waiting on indexer sync.
  • Route against the upgraded escrow/orchestrator stack while preserving historical deposit visibility.
  • Use prepareable write methods for smart accounts, relayers, gas estimation, and batching.
  • Keep advanced analytics, fund activity history, and vault stats behind client.indexer.*.

Who This Is For

  • maker and liquidity-provider applications
  • wallets and embedded onramp/offramp products
  • backends that need contract-safe deposit and intent operations
  • dashboards and analytics services that query client.indexer.*
  • React apps that want first-party hooks instead of writing transaction glue

Architecture

  • RPC-first reads: primary reads use ProtocolViewer and on-chain fallbacks, so getDeposits(), getDeposit(), getIntents(), getIntent(), and the getPv* methods are not blocked on indexer lag.
  • Indexer for history and filtering: use client.indexer.* for pagination, historical volumes, fund activities, daily snapshots, and vault analytics.
  • Current-stack routing: the client resolves against the upgraded escrow and orchestrator contracts, with historical escrow lookups available for reads and legacy deposits.
  • Modular internals: intent, vault, and ProtocolViewer logic are extracted into IntentOperations, VaultOperations, and ProtocolViewerReader, keeping Zkp2pClient focused on orchestration.
  • App-level rollout control: the SDK is capability-based. Product gating and phase flags belong in your app layer, not inside transaction helpers.

Installation

npm install @zkp2p/sdk viem
# or
pnpm add @zkp2p/sdk viem
# or
bun add @zkp2p/sdk viem

If you use React hooks, add React as well:

pnpm add react

Quick Start

import { Zkp2pClient } from '@zkp2p/sdk';
import { createWalletClient, custom } from 'viem';
import { base } from 'viem/chains';

const walletClient = createWalletClient({
  chain: base,
  transport: custom(window.ethereum),
});

const client = new Zkp2pClient({
  walletClient,
  chainId: base.id,
});

runtimeEnv defaults to 'production'. Use 'preproduction' or 'staging' when you want to point the SDK at those deployments.

Environment and Authentication

  • Supported runtime environments: 'production', 'preproduction', 'staging'
  • runtimeEnv default: 'production'
  • rpcUrl: optional RPC URL override (defaults to wallet's chain RPC)
  • apiKey: optional curator-issued API key — used when the SDK auto-fetches signalIntent() gating signatures and enables richer authenticated getQuote() responses with resolved maker payee details (offchainId, telegramUsername, metadata)
  • authorizationToken / getAuthorizationToken: optional bearer auth for hybrid client and indexer flows
  • indexerApiKey: optional x-api-key for indexer proxy auth
  • indexerUrl and baseApiUrl: override defaults when you are targeting custom deployments
  • timeouts: { api?: number } — API timeout in milliseconds (default 15000)

No API key is required to get started. createDeposit, registerPayeeDetails, getQuote, getTakerTier, and the rest of the SDK work without apiKey or authorizationToken. The main tradeoff is that signalIntent() only auto-fetches a gating service signature from curator /v3/intent/sign when apiKey or authorizationToken is available; otherwise provide both gatingServiceSignature and signatureExpiration manually if your integration needs one. Authenticated quotes also include resolved maker payee details (offchainId, telegramUsername, metadata).

Indexer defaults by environment:

  • production: https://indexer.zkp2p.xyz/v1/graphql
  • preproduction: https://indexer-preprod.zkp2p.xyz/v1/graphql
  • staging: https://indexer-staging.zkp2p.xyz/v1/graphql

Core Capabilities

| Area | Stable surface | | ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Deposits | createDeposit, addFunds, removeFunds, withdrawDeposit, ensureAllowance, setAcceptingIntents, setIntentRange, setCurrencyMinRate, setRetainOnEmpty | | Payment methods and currencies | addPaymentMethods, removePaymentMethod, setPaymentMethodActive, addCurrencies, removeCurrency, deactivateCurrency, pruneExpiredIntents | | Intents | signalIntent, fulfillIntent, cancelIntent, releaseFundsToPayer, getFulfillIntentInputs | | Prepared transactions | client.prepareCreateDeposit(...), client.signalIntent.prepare(...), client.fulfillIntent.prepare(...), client.setVaultFee.prepare(...), and equivalent prepare flows across the rest of the prepareable write surface | | Payee and quote APIs | registerPayeeDetails, resolvePayeeHash, getQuote, getQuotesBestByPlatform, getTakerTier | | Delegation and hooks | setDelegate, removeDelegate, setRateManager, clearRateManager, setDepositRateManager, clearDepositRateManager, setDepositPreIntentHook, setDepositWhitelistHook | | Vault / DRM | createRateManager, setVaultMinRate, setVaultMinRatesBatch, setVaultFee, setVaultConfig, getDepositRateManager, getManagerFee, getEffectiveRate | | Oracle config | setOracleRateConfig, setOracleRateConfigBatch, removeOracleRateConfig, updateCurrencyConfigBatch, deactivateCurrenciesBatch, supportsInlineOracleRateConfig, validateOracleFeedsOnChain | | RPC reads | getDeposits, getDeposit, getDepositsById, getIntents, getIntent, getPvDepositById, getPvDepositsFromIds, getPvAccountDeposits, getPvAccountIntents, getPvIntent | | Indexer | client.indexer.getDeposits, getDepositsWithRelations, getDepositById, getDepositsByIds, getDepositsByIdsWithRelations, getDepositsByPayeeHash, getIntentsForDeposits, getOwnerIntents, getIntentsByRateManager, getIntentByHash, getExpiredIntents, getFulfilledIntentEvents, getIntentFulfillmentAmounts, getFulfillmentAndPayment, getDepositFundActivities, getMakerFundActivities, getDepositDailySnapshots, getProfitSnapshotsByDeposits, getRateManagers, getRateManagerDetail, getRateManagerDelegations, getDelegationForDeposit, getManagerDailySnapshots, getManualRateUpdates, getOracleConfigUpdates, query | | React hooks | @zkp2p/sdk/react exports hooks for deposits, intents, delegation, vaults, payment methods, and taker tier | | Attribution | ERC-8021 helpers like sendTransactionWithAttribution, encodeWithAttribution, and txOverrides.referrer support |

Create a Deposit

import { Currency } from '@zkp2p/sdk';

const result = await client.createDeposit({
  token: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
  amount: 10_000_000n,
  intentAmountRange: { min: 100_000n, max: 5_000_000n },
  processorNames: ['wise'],
  depositData: [{ email: '[email protected]' }],
  conversionRates: [[{ currency: Currency.USD, conversionRate: '1020000000000000000' }]],
});

console.log(result.hash);
console.log(result.depositDetails);

If you do not pass payeeDetailsHashes, createDeposit() can register the payee details for you. If you want to pre-register or reuse hashes across deposits, use registerPayeeDetails() first.

Payee Registration, Quotes, and Taker Tier

import { resolvePaymentMethodHash } from '@zkp2p/sdk';

const { hashedOnchainIds } = await client.registerPayeeDetails({
  processorNames: ['wise'],
  depositData: [{ email: '[email protected]' }],
});

const quote = await client.getQuote({
  paymentPlatforms: ['wise'],
  fiatCurrency: 'USD',
  user: '0xBuyer',
  recipient: '0xBuyer',
  destinationChainId: 8453,
  destinationToken: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
  amount: '250',
  isExactFiat: true,
});

const takerTier = await client.getTakerTier({
  owner: '0xBuyer',
  chainId: 8453,
});

const payeeHash = await client.resolvePayeeHash(
  42n,
  resolvePaymentMethodHash('wise', { env: 'production' }),
);

getQuote() returns available liquidity plus payee details when authenticated. Use getQuotesBestByPlatform() to fetch the best quote per supported payment platform in a single call (handy for cross-platform comparison UIs). getTakerTier() returns limits and cooldown data for taker UX.

Signal, Fulfill, and Release Intents

const intentHash = await client.signalIntent({
  depositId: 42n,
  amount: 250_000n,
  toAddress: '0xBuyer',
  processorName: 'wise',
  payeeDetails: '0xPAYEE_DETAILS_HASH',
  fiatCurrencyCode: 'USD',
  conversionRate: 1_020_000_000_000_000_000n,
  referralFees: [
    { recipient: '0xPlatformFeeRecipient', fee: 2_500n },
    { recipient: '0xPartnerFeeRecipient', fee: 1_250n },
  ],
});

await client.fulfillIntent({
  intentHash,
  proof: zkTlsProofJson,
});

await client.releaseFundsToPayer({
  intentHash,
});

Use referralFees[] for multi-recipient fee distribution on OrchestratorV2.

Prepared Transactions

Most write methods expose .prepare(params) and return a PreparedTransaction without sending the transaction. createDeposit() is the main exception and uses client.prepareCreateDeposit(params), which returns { depositDetails, prepared }. This is the stable pattern for smart accounts, batched user-ops, relayers, gas estimation, and custom senders.

const prepared = await client.signalIntent.prepare({
  depositId: 42n,
  amount: 250_000n,
  toAddress: '0xBuyer',
  processorName: 'wise',
  payeeDetails: '0xPAYEE_DETAILS_HASH',
  fiatCurrencyCode: 'USD',
  conversionRate: 1_020_000_000_000_000_000n,
});

console.log(prepared);
// { to, data, value, chainId }

React hooks mirror this where useful. For example, useSignalIntent() returns prepareSignalIntent() and prepared.

Error Handling

The SDK exports a normalized error model:

  • ZKP2PError
  • ValidationError
  • NetworkError
  • APIError
  • ContractError
  • ErrorCode
import { APIError, ErrorCode, ValidationError, ZKP2PError } from '@zkp2p/sdk';

try {
  await client.createDeposit({
    token: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
    amount: 10_000_000n,
    intentAmountRange: { min: 100_000n, max: 5_000_000n },
    processorNames: ['wise'],
    depositData: [{ email: '[email protected]' }],
    conversionRates: [[{ currency: 'USD', conversionRate: '1020000000000000000' }]],
  });
} catch (error) {
  if (error instanceof ValidationError) {
    console.error('Invalid field:', error.field, error.message);
  } else if (error instanceof APIError) {
    console.error('HTTP status:', error.status, error.message);
  } else if (error instanceof ZKP2PError) {
    console.error('SDK error:', error.code ?? ErrorCode.UNKNOWN, error.details);
  } else {
    console.error('Unknown error:', error);
  }
}

You should still handle generic Error for lower-level transport or wallet failures that originate outside the normalized SDK wrappers.

Oracle Configuration

The SDK exports Chainlink and Pyth adapter helpers, plus a Chainlink-first getSpreadOracleConfig() resolver for bundled feed metadata.

import {
  getSpreadOracleConfig,
  resolveFiatCurrencyBytes32,
  resolvePaymentMethodHash,
  validateOracleFeedsOnChain,
} from '@zkp2p/sdk';

const paymentMethodHash = resolvePaymentMethodHash('wise', { env: 'production' });
const currencyHash = resolveFiatCurrencyBytes32('USD');
const oracle = getSpreadOracleConfig('USD');

if (!oracle) throw new Error('No bundled oracle config for USD');

await client.setOracleRateConfig({
  depositId: 42n,
  paymentMethodHash,
  currencyHash,
  config: {
    adapter: oracle.adapter,
    adapterConfig: oracle.adapterConfig,
    spreadBps: -50,
    maxStaleness: oracle.maxStaleness,
  },
});

await client.updateCurrencyConfigBatch({
  depositId: 42n,
  paymentMethods: [paymentMethodHash],
  updates: [
    [
      {
        code: currencyHash,
        minConversionRate: 1_020_000_000_000_000_000n,
        updateOracle: true,
        oracleRateConfig: {
          adapter: oracle.adapter,
          adapterConfig: oracle.adapterConfig,
          spreadBps: -50,
          maxStaleness: oracle.maxStaleness,
        },
      },
    ],
  ],
});

const availableFeeds = await validateOracleFeedsOnChain(client.publicClient);
console.log([...availableFeeds].sort());

Useful helpers and methods in this area:

  • CHAINLINK_ORACLE_ADAPTER
  • PYTH_ORACLE_ADAPTER
  • encodeSpreadOracleAdapterConfig
  • encodePythAdapterConfig
  • getSpreadOracleConfig
  • setOracleRateConfigBatch
  • updateCurrencyConfigBatch
  • deactivateCurrenciesBatch

Delegation and Hooks

await client.setDelegate({
  depositId: 42n,
  delegate: '0xDelegate',
});

await client.setRateManager({
  depositId: 42n,
  rateManagerAddress: '0xVaultAddress',
  rateManagerId: '0xVaultId',
});

await client.setDepositPreIntentHook({
  depositId: 42n,
  preIntentHook: '0xHookAddress',
});

await client.setDepositWhitelistHook({
  depositId: 42n,
  whitelistHook: '0xHookAddress',
});

Use removeDelegate() and clearRateManager() to unwind delegation. Phase-4 hook methods are available when the target deployment supports them.

Vault / DRM

const createHash = await client.createRateManager({
  config: {
    manager: '0xManager',
    feeRecipient: '0xFeeRecipient',
    maxFee: 50_000_000_000_000_000n,
    fee: 10_000_000_000_000_000n,
    name: 'My Vault',
    uri: 'ipfs://vault-metadata',
  },
});

await client.setVaultFee({
  rateManagerId: '0xVaultId',
  newFee: 20_000_000_000_000_000n,
});

await client.setVaultMinRate({
  rateManagerId: '0xVaultId',
  paymentMethodHash: resolvePaymentMethodHash('wise', { env: 'production' }),
  currencyHash: resolveFiatCurrencyBytes32('USD'),
  rate: 1_010_000_000_000_000_000n,
});

await client.setVaultConfig({
  rateManagerId: '0xVaultId',
  newManager: '0xNewManager',
  newFeeRecipient: '0xNewFeeRecipient',
  newName: 'Updated Vault',
  newUri: 'ipfs://updated-vault-metadata',
});

Protocol Viewer (RPC) Reads

ProtocolViewer methods bypass indexer lag and are the right default for primary user-facing reads.

const deposit = await client.getPvDepositById(42n);
const deposits = await client.getPvDepositsFromIds([42n, 43n]);
const makerDeposits = await client.getPvAccountDeposits('0xMaker');
const takerIntents = await client.getPvAccountIntents('0xTaker');
const intent = await client.getPvIntent('0xIntentHash');

You can also use the convenience wrappers getDeposits(), getDeposit(), getIntents(), and getIntent() for common flows.

Indexer Queries

Use the indexer for filtered queries, pagination, fund activity history, snapshots, and vault analytics. All methods live on the flat client.indexer.* namespace.

// Deposit queries
const deposits = await client.indexer.getDeposits(
  { status: 'ACTIVE', depositor: '0xMaker' },
  { limit: 25, orderBy: 'updatedAt', orderDirection: 'desc' },
);
const depositsWithRelations = await client.indexer.getDepositsWithRelations(
  { status: 'ACTIVE' },
  { limit: 10 },
  { includeIntents: true },
);
const deposit = await client.indexer.getDepositById('8453_0xEscrowAddress_42', {
  includeIntents: true,
});
const depositsByIds = await client.indexer.getDepositsByIds(['8453_0xEscrow_42']);
const depositsByIdsWithRelations = await client.indexer.getDepositsByIdsWithRelations(
  ['8453_0xEscrow_42'],
  { includeIntents: true },
);
const depositsByPayee = await client.indexer.getDepositsByPayeeHash('0xPayeeHash', {
  paymentMethodHash: '0x...',
  limit: 10,
  includeIntents: true,
});

// Intent queries
const intentsForDeposits = await client.indexer.getIntentsForDeposits(
  ['8453_0xEscrow_42'],
  ['SIGNALED'],
);
const ownerIntents = await client.indexer.getOwnerIntents('0xTaker', ['SIGNALED', 'FULFILLED']);
const intentsByVault = await client.indexer.getIntentsByRateManager('0xVaultId');
const intent = await client.indexer.getIntentByHash('0xIntentHash');
const expiredIntents = await client.indexer.getExpiredIntents({
  now: BigInt(Math.floor(Date.now() / 1000)),
  depositIds: ['8453_0xEscrow_42'],
});
const fulfilledEvents = await client.indexer.getFulfilledIntentEvents(['0xIntentHash']);
const fulfillment = await client.indexer.getIntentFulfillmentAmounts('0xIntentHash');
const fulfillmentAndPayment = await client.indexer.getFulfillmentAndPayment('0xIntentHash');

// Fund activity and snapshots
const fundActivities = await client.indexer.getDepositFundActivities('8453_0xEscrowAddress_42');
const makerActivities = await client.indexer.getMakerFundActivities('0xMaker', 50);
const snapshots = await client.indexer.getDepositDailySnapshots('8453_0xEscrowAddress_42', 30);
const profitSnapshots = await client.indexer.getProfitSnapshotsByDeposits(['8453_0xEscrow_42']);

// Rate manager (vault) queries
const managers = await client.indexer.getRateManagers({
  limit: 10,
  orderBy: 'currentDelegatedBalance',
  orderDirection: 'desc',
});
const managerDetail = await client.indexer.getRateManagerDetail('0xVaultId', {
  rateManagerAddress: '0xVaultAddress',
  statsLimit: 30,
});
const delegations = await client.indexer.getRateManagerDelegations('0xVaultId');
const delegation = await client.indexer.getDelegationForDeposit('8453_0xEscrow_42');
const managerSnapshots = await client.indexer.getManagerDailySnapshots('0xVaultId');
const manualRates = await client.indexer.getManualRateUpdates('0xVaultId');
const oracleUpdates = await client.indexer.getOracleConfigUpdates('0xVaultId');

// Raw GraphQL
const custom = await client.indexer.query<MyType>({
  query: '{ deposits(limit: 5) { id } }',
});

React Hooks

Install React and import hooks from @zkp2p/sdk/react. React is an optional peer dependency of the SDK.

Most mutation hooks return a named action plus status fields such as isLoading, error, and txHash. Hooks with prepare support expose dedicated prepare... helpers, and some of them also store the latest prepared transaction in hook state. Every hook exports a matching Use*Options type.

import {
  useCreateDeposit,
  useSignalIntent,
  useCreateVault,
  useVaultDelegation,
  useGetTakerTier,
} from '@zkp2p/sdk/react';

const createDeposit = useCreateDeposit({ client });
const signalIntent = useSignalIntent({ client });
const createVault = useCreateVault({ client, sendTransaction });
const vaultDelegation = useVaultDelegation({ client, sendTransaction, sendBatch });
const takerTier = useGetTakerTier({ client, owner, chainId, autoFetch: true });

Hook groups:

  • Deposit lifecycle: useCreateDeposit, useAddFunds, useRemoveFunds, useWithdrawDeposit, useSetAcceptingIntents, useSetIntentRange, useSetCurrencyMinRate, useSetRetainOnEmpty
  • Payment and currency management: useAddPaymentMethods, useRemovePaymentMethod, useSetPaymentMethodActive, useAddCurrencies, useRemoveCurrency, useDeactivateCurrency
  • Intent lifecycle: useSignalIntent, useFulfillIntent, useReleaseFundsToPayer, usePruneExpiredIntents
  • Delegation: useSetDelegate, useRemoveDelegate
  • Vault / DRM: useCreateVault, useVaultDelegation, useSetVaultFee, useSetVaultMinRate, useSetVaultConfig
  • Taker tier: useGetTakerTier, plus getTierDisplayInfo() and getNextTierCap() helpers

useVaultDelegation() is the batching-oriented hook. It returns delegateDeposit, delegateDeposits, clearDelegation, and clearDelegations.

Contracts and Catalog Helpers

import {
  getContracts,
  getPaymentMethodsCatalog,
  getRateManagerContracts,
  resolveFiatCurrencyBytes32,
  resolvePaymentMethodHash,
} from '@zkp2p/sdk';

const contracts = getContracts(8453, 'production');
const rateManagerContracts = getRateManagerContracts(8453, 'production');
const paymentMethods = getPaymentMethodsCatalog(8453, 'production');
const usdHash = resolveFiatCurrencyBytes32('USD');
const wiseHash = resolvePaymentMethodHash('wise', { env: 'production' });

Supported Currencies

The SDK ships currency metadata for 34 fiat currencies:

AED, ARS, AUD, BRL, CAD, CHF, CNY, CZK, DKK, EUR, GBP, HKD, HUF, IDR, ILS, INR, JPY, KES, MXN, MYR, NOK, NZD, PHP, PLN, RON, SAR, SEK, SGD, THB, TRY, UGX, USD, VND, ZAR

Supported Payment Platforms

wise, venmo, revolut, cashapp, mercadopago, zelle, paypal, monzo, chime, luxon, n26, alipay

Attribution (ERC-8021)

The SDK includes builder-code attribution helpers and transaction overrides for partner attribution:

const hash = await client.signalIntent({
  depositId: 42n,
  amount: 250_000n,
  toAddress: '0xBuyer',
  processorName: 'wise',
  payeeDetails: '0xPAYEE_DETAILS_HASH',
  fiatCurrencyCode: 'USD',
  conversionRate: 1_020_000_000_000_000_000n,
  txOverrides: {
    referrer: ['my-app', 'campaign-42'],
  },
});

Lower-level helpers are also exported: BASE_BUILDER_CODE, ZKP2P_IOS_REFERRER, ZKP2P_ANDROID_REFERRER, getAttributionDataSuffix(), appendAttributionToCalldata(), encodeWithAttribution(), and sendTransactionWithAttribution().

TypeDoc API Reference

The package already includes TypeDoc configuration. Generate the full API reference locally with:

pnpm --filter @zkp2p/sdk docs

This writes documentation to packages/sdk/docs and now includes the React entry point as well as the main SDK and extension surfaces.

Debug Logging

Use setLogLevel() when you want verbose SDK logging during local development or integration debugging.

import { setLogLevel } from '@zkp2p/sdk';

setLogLevel('debug');

Supported log levels: 'error', 'info', 'debug'

Development

cd packages/sdk
pnpm build
pnpm test
pnpm typecheck
pnpm lint
pnpm docs

Links

  • NPM: https://www.npmjs.com/package/@zkp2p/sdk
  • Docs: https://docs.zkp2p.xyz
  • Monorepo: https://github.com/zkp2p/zkp2p-clients
  • TypeDoc output: packages/sdk/docs