Discovery Providers

Everything on the previous page - discoverNotes, discoverChannels, discoverRequirement, the autoDiscover options - is served by the discoveryProvider you wired into createPrivateTransfers. The SDK ships two implementations.

Provider Backend Use for
IndexerDiscoveryProvider Discovery service over HTTP Production - pagination and reorg detection handled server-side
ContractDiscoveryProvider Pool contract via Starknet RPC Development, testing, no-extra-infra setups

IndexerDiscoveryProvider

// Deep import - the package-root export's TypeScript declaration does not
// currently satisfy DiscoveryProviderInterface at v0.14.2.
// @ts-expect-error
import { IndexerDiscoveryProvider } from "@starkware-libs/starknet-privacy-sdk/dist/internal/indexer-discovery.js"

const discoveryProvider = new IndexerDiscoveryProvider(
  process.env.INDEXER_URL!,
  process.env.POOL_ADDRESS!, // hex string, like everywhere else
)

The deep import is a temporary workaround, not a style choice: importing from the package root type-errors even though it works at runtime. When the SDK ships type-clean exports, drop the deep path and the @ts-expect-error in the same change.

ContractDiscoveryProvider

import { ContractDiscoveryProvider } from "@starkware-libs/starknet-privacy-sdk"

const discoveryProvider = new ContractDiscoveryProvider(poolContract, {
  rateLimit: { maxConcurrent: 4, minDelay: 100 },
})

It replays pool events by querying the contract directly - every scan is a burst of RPC calls. The rateLimit option (max concurrent requests plus a minimum delay between them) keeps you under public-RPC rate limits; without it, a full scan against a free endpoint gets you HTTP 429s mid-discovery.

Things to notice

  • Both satisfy the same DiscoveryProviderInterface - swap them behind an environment variable and no other code changes.
  • Contract-based discovery cost grows with pool history. Fine on a devnet or a young Sepolia deployment; painful on a busy pool. The indexer does the scanning once, server-side.
  • Reorg handling: the indexer detects L2 reorgs and repairs its cursor. With the contract provider you inherit whatever your RPC node reports - one more reason it is the development option.
  • Cursors are provider-specific opaque values. Do not persist a cursor from one provider and feed it to the other.

Next: Proving Configuration - the proving side of the same wiring.