SDK Overview
UPP SDK module structure, subpath exports, and integration paths — a composable toolkit, not a monolithic client.
UPP SDK
@permissionless-technologies/upp-sdk is a TypeScript SDK for integrating UPP privacy into any application. It's built on viem (not ethers) and ships as a composable toolkit — pure transaction encoders, crypto primitives, an indexer, and optional React hooks — rather than a single client object.
Installation
npm install @permissionless-technologies/upp-sdkPeer dependencies: viem (required), wagmi + react (only for the React hook surface).
Two integration paths
| Path | Use when | Start here |
|---|---|---|
| React hooks | You have a wagmi-based app and want privacy primitives that fit your existing wallet + write-contract flow | React Hooks |
| Encoders + crypto | Server-side integrations, non-React frontends, custom indexers, or anything that needs to compose the building blocks differently | Transaction Encoders |
The React hooks compose the encoders, indexer, and crypto. Anything you can do in React you can do in plain TypeScript by calling the same pieces directly.
Subpath exports
// Main entry — encoders, crypto, key derivation, deployments
import { … } from '@permissionless-technologies/upp-sdk'
// React hooks (UPPAccountProvider, useUPPAccount, useShield, …)
import { … } from '@permissionless-technologies/upp-sdk/react'
// Indexer + sync engine (makeRpcIndexer, createSyncEngine, helpers)
import { … } from '@permissionless-technologies/upp-sdk/indexer'
// Proof worker entry point (Web Worker module URL)
import workerUrl from '@permissionless-technologies/upp-sdk/worker?worker&url'
// STARK prover (WebAssembly, lazy-loaded)
import { … } from '@permissionless-technologies/upp-sdk/stwo-prover'| Import path | Surface |
|---|---|
@permissionless-technologies/upp-sdk | Encoders, RELAYER_FEE_AUTH, crypto primitives (createNote, encryptNote, decryptNote, stealth-address helpers), key derivation, deployment configs, constants |
@permissionless-technologies/upp-sdk/react | UPPAccountProvider, useUPPAccount, useShield, usePoolTransfer, useWithdraw, useSwap, usePrivateBalance, usePersonalASP, useCircuitCache, useStarkVerifierType, useProofWorker, useUPPCrypto, plus the bundled UI components |
@permissionless-technologies/upp-sdk/indexer | createSyncEngine, makeRpcIndexer, decryption helpers (decryptCandidates, tryDecryptHashBased), nullifier verifiers (verifyNullifiers, verifyStarkNullifiers), storage adapters |
@permissionless-technologies/upp-sdk/worker | Web Worker entry for off-main-thread PLONK proving |
@permissionless-technologies/upp-sdk/stwo-prover | Circle STARK prover (WASM) |
Quick examples
Non-React (encoders + viem):
import { encodeShieldTx } from '@permissionless-technologies/upp-sdk'
const tx = encodeShieldTx({ token, amount, ownerHash, blinding, encryptedNote })
await walletClient.writeContract({ address: poolAddress, ...tx })React (hooks + wagmi):
import { useShield } from '@permissionless-technologies/upp-sdk/react'
import { encodeShieldTxFromBuildData } from '@permissionless-technologies/upp-sdk'
const { build } = useShield({ poolAddress, tokenAddress: UPD_ADDRESS })
const data = await build({ amount: parseUnits('100', 18), originAddress: address })
await writeContractAsync({ address: poolAddress, ...encodeShieldTxFromBuildData(data) })In both cases the SDK never holds your wallet client — you submit transactions yourself with viem or wagmi.
Module pages
- Transaction Encoders & Crypto —
encode*Tx, crypto primitives, key derivation, deployment config - Note Indexer & Sync Engine —
createSyncEngine,makeRpcIndexer, decryption + nullifier helpers, storage adapters - React Hooks —
UPPAccountProvider,useUPPAccount, discrete operation hooks - Fee System —
FeeAuth, FeeManager admin, the two payment paths
V4 Commit/Flush Transfers
Why a V4 STARK transfer is two transactions instead of one, the FIFO queue between them, and the spendability lifecycle the recipient's note moves through.
Transaction Encoders & Crypto
The composable toolkit at the heart of the UPP SDK — pure encoders that produce viem-compatible tx args, crypto primitives, and key derivation. The non-React integration path.