Skip to content

susruth/slnt

S⬛l⬛nt — Silent Payments for Solana

Status License Anchor Spec

SLNT is a silent-payment (stealth-address) protocol for Solana — the Solana analog of Bitcoin Silent Payments (BIP-352) and Ethereum Stealth Addresses (ERC-5564 / ERC-6538).

A recipient publishes a single, reusable meta-address. Anyone can pay it such that:

  • every payment lands at a fresh, distinct on-chain address (a stealth address) that is itself a normal, spendable Solana wallet;
  • only the recipient can recognize which addresses are theirs;
  • no observer without the recipient's scan key can link a stealth address to the meta-address, or link two payments to the same meta-address; and
  • in the default (decoupled) mode, the payment transaction is indistinguishable from an ordinary transfer to a fresh address.

The protocol is specified in sRFC-0042, which is normative. This repository is the reference implementation.

Warning

Experimental and unaudited. SLNT has not been security-audited. The devnet/testnet programs remain upgradeable while v1 is draft and unaudited, but the canonical v1 deployment is intended to become immutable as soon as v1 is finalized and independently audited. Do not use with funds you cannot afford to lose. See SECURITY.md.


How it works

            meta-address (slnt1…)                published once, off-chain or
        ┌──────────────────────────┐            via the on-chain registry
        │  B_spend (Ed25519)        │
        │  B_scan  (X25519)         │
        └──────────────────────────┘
                    │
  sender: ECDH(ephemeral r, B_scan) ─► shared secret S ─► tweak t, view_tag
                    │
                    ▼
        stealth address  P = B_spend + t·G        ◄── a real Solana wallet
                    │
   1) transfer asset to P            (looks like any transfer to a fresh address)
   2) announce (R, view_tag) on the `pinboard` program
                    │
                    ▼
  recipient: scans announcements, view-tag filter, ECDH(b_scan, R),
             recomputes P, recovers spend scalar, sweeps via a relayer

The cryptography (Ed25519 spend keys, X25519 scan keys, HKDF-SHA256, bech32m meta-addresses, BIP-352-style labels, the 1-byte view tag) and the on-chain wire formats are defined end-to-end in the sRFC.

Repository layout

Path What it is
programs/pinboard Permissionless, stateless announcement program (post, post_batch, Note event). The ERC-5564 Announcer analog.
programs/registry Optional meta-address registry (register, update, close). The ERC-6538 analog.
crates/slnt-sdk Canonical Rust SDK and cryptographic reference: key derivation, codec, sender/recipient, flows, sweep, announce.
crates/slnt-cli Offline slnt CLI — key derivation, meta-address encode/decode, sender derivation.
crates/slnt-announcer Reference announcement service (HTTP → post_batch).
crates/slnt-indexer Reference indexer (retains announcements, serves by slot range).
clients/typescript @slnt/sdk — TypeScript wallet SDK, byte-compatible with the Rust SDK.
docs/srfc The sRFC, per-component design documents, and the implementation-status tracker.
tests Anchor/Mocha on-chain integration tests.
scripts build.sh (program build) and demo-lifecycle.sh (end-to-end demo).
docs/DEPLOYMENT.md Devnet/testnet deployment addresses, authorities, and operational notes.

On-chain programs

Program ID (localnet, devnet, testnet)
pinboard SLNTPDxgFKwSZ31CbbdSKKHyRpBpKjEMYVj2gpGxkN2
registry SLNTRCsjJXUQM3UbHjgJ48xe4GjKFSiLmrF1mXA8Vn2

The vanity prefixes are mnemonic: SLNTP… = Pinboard, SLNTR… = Registry. Current devnet/testnet deployments are upgradeable while v1 is draft and unaudited; the canonical v1 deployment is intended to become immutable as soon as v1 is finalized and independently audited. See docs/DEPLOYMENT.md.

Quickstart

Prerequisites

Build the programs

./scripts/build.sh

The script passes --tools-version v1.54 to the Solana build toolchain. Solana CLI 2.3.0 ships platform-tools v1.48 (cargo 1.84), which predates Rust edition2024 required by some transitive dependencies; v1.54 ships cargo 1.89, which supports it. See the comments in scripts/build.sh.

Run the tests

# Rust SDK + service unit tests (no validator needed)
cargo test
cargo test -p slnt-sdk --features net      # include networked client/scanner tests

# On-chain integration tests (boots a local validator)
anchor test

# TypeScript SDK
cd clients/typescript && npm install && npm test

Run the end-to-end demo

./scripts/demo-lifecycle.sh

Boots a local validator with the pinboard program, then runs the lifecycle example: derive keys → emit a meta-address → send → scan → recover → sweep.

Lint & format

cargo fmt --all
cargo clippy --all-targets --all-features -- -D warnings
npm run lint            # prettier over JS/TS

Using the SDKs

  • Rust — add slnt-sdk from this workspace; see its README and the lifecycle example.
  • TypeScript@slnt/sdk is feature- and byte-equivalent with the Rust SDK (verified by cross-implementation known-answer tests).

Documentation

Protocol discussion happens in the sRFC thread; see CONTRIBUTING.md for how to propose changes.

Community and governance

Contributing

Contributions are welcome — please read CONTRIBUTING.md. By participating you agree to abide by our Code of Conduct.

Security

This is experimental, unaudited software. Found a vulnerability — including a privacy/unlinkability weakness? Please follow the responsible-disclosure process in SECURITY.md rather than opening a public issue.

License

Licensed under the MIT License.

About

Silent Payments for Solana

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors