[!IMPORTANT] For new code, prefer
/stealth-sdk— it bundles these primitives with the scanner and pay-link helpers in a single dependency.
[!IMPORTANT] For new code, prefer
@notrace/stealth-sdk— it bundles these primitives with the scanner and pay-link helpers in a single dependency.
ECDH-derived stealth addresses on ed25519. ERC-5564 ported to Solana's native curve.
stealth-core implements the cryptographic primitives for stealth addresses on
Solana's native ed25519 curve. It is a faithful port of ERC-5564
semantics, adapted to ed25519 from the original secp256k1 design.
The library is intentionally minimal — no networking, no chain calls, no wallet integration. Just the math.
npm install @notracesol/stealth-coreimport {
generateMetaKey, deriveStealthSender, recoverStealth, signWithScalar,
encodeMemo, parseMemo
} from "@notracesol/stealth-core";
// Recipient generates a meta-keypair
const meta = generateMetaKey();
// Publish meta.pub. Keep meta.scalar private.
// Sender derives a one-time stealth address from the meta-pub
const { stealthPub, ephPub } = deriveStealthSender(meta.pub);
// Send funds to stealthPub. Attach memo with encodeMemo(ephPub).
// Recipient scans memos. For each:
const { stealthScalar, stealthPub: recovered } = recoverStealth(
meta.scalar, meta.pub, ephPub
);
// If recovered === stealthPub on chain → it is your payment.
// signWithScalar lets you spend from it.┌─────────────┐ ┌──────────────┐
│ recipient │── publish meta.pub ─────▶│ sender │
└──────┬──────┘ └──────┬───────┘
│ │
│ derive stealth │
│ via ECDH│
│ ▼
│ send to
│ stealth_addr
│ + memo(eph_pub)
│ │
│ scan memos │
│ recover via ECDH ◀───────────────────
│
│ verify match
│ derive spending scalar
▼
sweep
generateMetaKey() → { seed, scalar, pub }metaFromSeed(seed) → metaderiveStealthSender(metaPub) → { stealthPub, ephPub }recoverStealth(metaScalar, metaPub, ephPub) → { stealthScalar, stealthPub }signWithScalar(scalar, pub, msg) → Uint8Array(64)encodeMemo(ephPub) → string("nt1:..." format)parseMemo(memo) → Uint8Array(32) | null
Built on @noble/curves — audited
primitives. The protocol-level math (point addition, scalar arithmetic mod L)
follows ERC-5564 verbatim with ed25519 substitutions.
The signWithScalar function implements Schnorr-style ed25519 signing using
a raw scalar (not a seed), producing signatures verifiable by standard
ed25519.verify. This is needed because stealth scalars are derived via
ECDH and have no associated seed.
MIT