For developers · @umbra/sdk

Build private payments on Stellar.

Umbra is the privacy layer for Stellar — a pool whose validity is enforced by a zero-knowledge proof verified on-chain. The SDK hands you the exact, on-chain-verified primitives our own products run on. No new contracts, no new circuits — build on the frozen, proven protocol.

On-chain verified Secrets never leave the client One protocol, every app
$ npm i @umbra/sdk
mainnet

A private payment link, end to end

create-link.ts
import {
  makeNote, commitment, buildShieldInput,
  encodePaymentLink, UMBRA_CONTRACTS,
} from "@umbra/sdk";

// 1 · Mint a note — the secret stays with the recipient, never in the link.
const note = makeNote(50n);

// 2 · Build the Groth16 witness, prove it in the browser (snarkjs · BLS12-381).
const proof = await proveShield(buildShieldInput(note));

// 3 · Package a tamper-evident, backend-free private payment link.
const id = encodePaymentLink({
  v: 1, title: "Design work", recipientName: "Alex",
  amount: "50", commitment: commitment(note).toString(),
  description: "", proof,
});

// 4 · The Soroban contract verifies the proof on-chain. Done.
const { pool } = UMBRA_CONTRACTS.mainnet;
verify-link.ts
import { decodePaymentLink } from "@umbra/sdk";

// Throws if the amount/commitment was tampered —
// the proof's public signals won't match.
const req = decodePaymentLink(id);
//   → { amount: "50", recipientName: "Alex", proof, … }

What’s in the box

Notes & commitments

Private money as a Poseidon commitment, spent exactly once via its nullifier.

makeNote · commitment · nullifier

Contract-mirroring tree

Compute roots and Merkle paths the on-chain pool accepts — same Poseidon, same depth.

MerkleTree · DEPTH

Witness inputs

Ready-to-prove Groth16 witnesses for shield and withdraw.

buildShieldInput · buildWithdrawInput

Soroban encoding

Turn a snarkjs proof / verifying key into the contract’s exact byte layout.

g1ToSoroban · g2ToSoroban

Payment-link codec

Self-contained, integrity-checked links — a pre-authorized shield, no backend.

encodePaymentLink · decodePaymentLink

Live contracts

The deployed pool id + network config, ready to invoke.

UMBRA_CONTRACTS.mainnet

How a private payment works

1

Shield

A note enters the pool under a Poseidon commitment, with a ZK proof that it really holds the deposited amount.

2

Prove

A withdrawal proves — without revealing which note — Merkle inclusion, ownership, a one-time nullifier, recipient binding, and amount conservation.

3

Verify on-chain

The Soroban contract verifies the Groth16 proof using Stellar’s native BLS12-381 host functions, then releases funds. No trusted server.

Live on Stellar mainnet

UmbraPool contract

CBWIV33FQ27LOTA2LGM5SVL2WHAMBFLZTYOZXWKEMDBFCLU4BNIUQOLU

Network

Public Global Stellar Network ; September 2015

Soroban RPC

https://mainnet.sorobanrpc.com

What is real today vs roadmap

Real, in the SDK today

  • Notes, commitments, nullifiers, recipient binding
  • Contract-mirroring Poseidon Merkle tree
  • Shield / withdraw Groth16 witness inputs
  • BLS12-381 → Soroban byte encoding
  • Integrity-checked payment-link codec
  • Live mainnet pool + network config

Roadmap

  • Published to npm (workspace deps unwired)
  • Join-split / shielded→shielded transfer inputs
  • Multi-asset notes
  • Auditor public keys for selective disclosure

The SDK is workspace-local today; it depends on two workspace packages, so it ships once those are published or bundled. Honest by default — we haven’t published a half-wired package.

Build privacy into your Stellar app.

Payments, donations, payroll, treasury — if it moves value on Stellar, it can be private. Start from the wallet, or wire the SDK into your own product.