npm.io
0.6.2 • Published 3d ago

@zkp2p/sdk

Licence
MIT
Version
0.6.2
Deps
5
Size
8.3 MB
Vulns
0
Weekly
4.2K

@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.5.2

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 EscrowV2/OrchestratorV2 stack — legacy V1 resolution has been removed.
  • 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.
  • V2-only routing: the client resolves against EscrowV2 and OrchestratorV2. Legacy V1 escrow/orchestrator fallbacks have been removed from both read and write paths.
  • 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 internal curator API key for internal seller verification only
  • authorizationToken / getAuthorizationToken: optional bearer auth for 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 external API key is required. createDeposit, registerPayeeDetails, getQuote, getTakerTier, signalIntent, and the rest of the public SDK flows work without apiKey or authorizationToken. When baseApiUrl is configured, signalIntent() can auto-fetch a gating service signature from curator /v3/intent/sign without auth. Quote responses include resolved maker payee details (offchainId, telegramUsername, metadata) when curator has them.

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
Seller automated release uploadSellerCredential, getSellerCredentialStatus, verifySellerPayment
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

Extension Metadata Bridge

Use createPeerExtensionSdk() when a page needs the Peer extension to open a provider auth tab and interact with the Peer TEE protocol. The extension owns provider-tab capture and Buyer TEE session encryption. For seller automated release, the extension captures seller session material, creates the encrypted attestation-service bundle, and returns only that bundle plus the maker offchainId. The page owns maker payee registration and curator credential storage.

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

const peer = createPeerExtensionSdk();

if ((await peer.getState()) === 'needs_connection') {
  await peer.requestConnection();
}

const unsubscribe = peer.onMetadataMessage((message) => {
  if (message.sarCredentialCapture) {
    console.log('SAR credential bundle captured', message.sarCredentialCapture.credentialBundle);
    return;
  }

  console.log('captured payment metadata', message.metadata);
});

peer.authenticate({
  actionType: 'transfer_venmo',
  captureMode: 'buyerTee',
  platform: 'venmo',
  attestationServiceUrl: 'https://attestation.zkp2p.xyz',
});

requestConnection() is required for third-party origins. authenticate() accepts an optional inline providerConfig object; otherwise the extension fetches the default template from https://api.zkp2p.xyz/providers/. Buyer TEE is API/template driven: pass captureMode: "buyerTee" plus attestationServiceUrl, and the extension returns encrypted session material. For SAR, pass captureMode: "sellerCredential" and optionally pass attestationServiceUrl only when overriding the extension's production attestation default. The extension returns sarCredentialCapture.credentialBundle plus offchainId. The page should call apiUploadSellerCredentialBundle() to register maker payee details with curator, compare the registered hash to the bundle payeeIdHash, and store the encrypted bundle with curator. Plaintext seller session material is never returned to the page.

Zkp2pClient.uploadSellerCredential() remains the backwards-compatible plaintext convenience path for mobile and React Native callers. Internally it creates the encrypted bundle, then uses the same apiUploadSellerCredentialBundle() storage helper.

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: 'maker@example.com' }],
  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: 'maker@example.com' }],
});

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.

Seller Credential Status

await client.uploadSellerCredential({
  platform: 'venmo',
  offchainId: 'alice',
  payeeId: '123456',
  sessionMaterial: {
    recipientUsername: 'alice',
    accountId: '123456',
    sessionCookie: 'session-cookie',
  },
});
const status = await client.getSellerCredentialStatus({
  processorName: 'venmo',
  payeeDetails: '0xPAYEE_DETAILS_HASH',
});

payeeDetails is the hashed payee details bytes32 used by maker registration, quotes, and on-chain intents. The public status endpoint returns { platform, payeeIdHash, status, credentialType }; maker row ids are intentionally not returned by status or upload responses.

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: {
    proofType: 'buyerTee',
    encryptedSessionMaterial,
    params: buyerTeePaymentParams,
  },
});

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: 'maker@example.com' }],
    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. Hook methods are part of the current V2 surface; still validate target contract support before assuming a deployment exposes every hook.

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');

// Received USDC:
// - fulfilledEvents[0].amount is the net USDC transferred to the taker.
// - fulfillment.takerAmountNetFees is the same net taker amount from the Intent row.
// - fulfillment.releasedAmount is gross USDC released from the deposit before fees.

// 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

Keywords