@styxstack/pmp-sdk
v1.1.1
Published
TypeScript SDK for the Styx Private Memo Program & Virtual State Layer on Solana - Privacy, governance, VTAs, referrals, and novel primitives
Downloads
168
Maintainers
Readme
@styxstack/pmp-sdk
TypeScript SDK for the Styx Private Memo Program & Virtual State Layer on Solana.
Zero accounts. Zero rent. Infinite scale. All on-chain.
Features
🔠Core Privacy
- Private Messages - End-to-end encrypted messaging
- Private Transfers - SOL transfers with hidden amounts
- Routed Messages - Multi-hop onion-routed messages
- Forward Secrecy - Double-ratchet key exchange
- Compliance - Optional auditor disclosure
ðŸ›ï¸ Virtual State Layer (VSL)
- Private Governance - DAO voting with nullifier-based privacy
- Virtual Token Accounts - Balances inscribed to logs, zero rent
- Inscribed Referrals - Progressive reward trees (30% → 15% → 7.5%...)
- Token-2022 Support - Works with SPL and Token-2022 tokens
🔮 Novel Primitives
- Time Capsule - Messages locked until specific slot
- Ghost PDA - ZK-like proofs via PDA derivation
- CPI Inscribe - Universal privacy layer for any program
- Hashlock Swaps - Atomic swaps without escrow
- State Channels - Off-chain transactions with on-chain settlement
Installation
npm install @styxstack/pmp-sdk @solana/web3.js
# or
pnpm add @styxstack/pmp-sdk @solana/web3.jsQuick Start
import { Connection, Keypair, PublicKey } from '@solana/web3.js';
import {
StyxPMP,
StyxGovernance,
StyxNovel,
generateX25519Keypair,
deriveSharedSecret
} from '@styxstack/pmp-sdk';
// Connect to Solana
const connection = new Connection('https://api.mainnet-beta.solana.com');
const styx = new StyxPMP(connection);
// Your wallet
const sender = Keypair.generate();
const recipient = new PublicKey('RecipientPubkeyHere...');
// Key exchange (both parties do this)
const myKeys = generateX25519Keypair();
const theirPubkey = /* get from recipient */;
const sharedSecret = deriveSharedSecret(myKeys.privateKey, theirPubkey);
// Send encrypted message
const signature = await styx.sendPrivateMessage(
sender,
recipient,
"Hello, World!",
sharedSecret
);
console.log('Sent:', signature);API Reference
StyxPMP
Main SDK class.
const styx = new StyxPMP(connection, programId?);| Parameter | Type | Description |
|-----------|------|-------------|
| connection | Connection | Solana RPC connection |
| programId | PublicKey | Optional custom program ID (defaults to mainnet) |
Methods
sendPrivateMessage()
Send an encrypted private message.
await styx.sendPrivateMessage(
sender, // Keypair - sender wallet
recipient, // PublicKey - recipient address
message, // string | Uint8Array - message content
sharedSecret,// Uint8Array - 32-byte shared secret
options? // { stealth?: boolean }
);sendPrivateTransfer()
Send SOL with hidden metadata.
await styx.sendPrivateTransfer(
sender, // Keypair - sender wallet
recipient, // PublicKey - recipient address
amountSol, // number - amount in SOL
memo? // string - optional memo
);sendRoutedMessage()
Send a message through multiple relay hops.
await styx.sendRoutedMessage(
sender, // Keypair
recipient, // PublicKey
hops, // PublicKey[] - relay nodes
message, // Uint8Array
sharedSecret // Uint8Array
);sendRatchetMessage()
Send a forward-secret message using double-ratchet.
await styx.sendRatchetMessage(
sender, // Keypair
ephemeralKeypair, // Keypair - new key per message
counter, // bigint - message counter
chainKey, // Uint8Array - ratchet chain key
message, // Uint8Array
sharedSecret // Uint8Array
);submitComplianceReveal()
Submit disclosure to an auditor.
await styx.submitComplianceReveal(
sender, // Keypair
messageId, // Uint8Array - tx signature
auditor, // PublicKey - auditor address
disclosureKey, // Uint8Array - decryption key
revealType // 'full' | 'amount' | 'recipient' | 'metadata'
);subscribeToMessages()
Listen for incoming messages.
const subscriptionId = styx.subscribeToMessages((payload, signature) => {
console.log('New message:', signature);
});
// Later: unsubscribe
await styx.unsubscribe(subscriptionId);getRecentMessages()
Get historical messages.
const messages = await styx.getRecentMessages(100);
for (const msg of messages) {
console.log(msg.signature, msg.timestamp);
}Crypto Utilities
import {
encryptRecipient,
decryptRecipient,
encryptAmount,
decryptAmount,
deriveSharedSecret,
generateX25519Keypair,
encryptPayload,
decryptPayload
} from '@styxstack/pmp-sdk';| Function | Description |
|----------|-------------|
| generateX25519Keypair() | Generate X25519 key pair for key exchange |
| deriveSharedSecret(privateKey, publicKey) | Derive shared secret via X25519 |
| encryptPayload(message, secret) | ChaCha20-Poly1305 encrypt |
| decryptPayload(ciphertext, secret) | ChaCha20-Poly1305 decrypt |
| encryptRecipient(sender, recipient) | Keccak256 XOR mask |
| decryptRecipient(sender, encrypted) | Reverse XOR mask |
Program IDs
| Network | Program ID |
|---------|------------|
| Mainnet | GhSTPRZFBnWXMjt6xFnpY2ZHFwijFoC44KkxXSEC94X9 |
| Devnet | CFTbFxMeu5cMPWvaaWNdtsv85H7cfkjYVAgXvQ5r643d |
import { STYX_PMP_PROGRAM_ID, STYX_PMP_DEVNET_PROGRAM_ID } from '@styxstack/pmp-sdk';Security Model
Client-Side (SDK Handles)
- ChaCha20-Poly1305 - Message encryption
- X25519 - Key exchange
- Keccak-256 - Nullifiers and hashing
On-Chain (Program Handles)
- Keccak256 XOR - Recipient obfuscation
- Amount masking - Transfer privacy
- Nullifier verification - Double-spend prevention
- PDA derivation - Ghost PDA proofs
âš ï¸ Important: Always encrypt payloads client-side before sending!
Virtual State Layer (VSL)
Private Governance
import { StyxGovernance, buildVoteInstruction } from '@styxstack/pmp-sdk';
const governance = new StyxGovernance(styx);
// Create proposal (inscribed, zero rent!)
await governance.createProposal(proposer, {
title: 'Increase treasury allocation',
descriptionHash: keccak256(description),
votingEndSlot: currentSlot + 432000n, // ~2 days
quorumBps: 1000, // 10%
isToken22: true
});
// Cast private vote (identity hidden by nullifier)
await governance.castVote(voter, {
proposalId,
voterSecret: mySecret, // Generates nullifier
vote: 'yes',
isToken22: true
});Referral System
import { StyxReferral, calculateReferralChainRewards } from '@styxstack/pmp-sdk';
const referral = new StyxReferral(styx);
// Register referral (inscribed to chain)
await referral.register(newUser, {
referrer: myReferrerPubkey,
parentChainHash: referrerChainHash
});
// Calculate progressive rewards
const rewards = calculateReferralChainRewards(1_000_000n);
// Level 0: 300,000 (30%)
// Level 1: 150,000 (15%)
// Level 2: 75,000 (7.5%)
// ...halves each levelNovel Primitives
Time Capsule
Lock messages until a specific slot:
import { StyxNovel, buildTimeCapsuleInstruction } from '@styxstack/pmp-sdk';
const novel = new StyxNovel(styx);
// Create time-locked message
await novel.createTimeCapsule(
sender,
recipient,
secretMessage,
senderSecret,
400000000n // Unlock at slot 400M
);Ghost PDA (ZK-like Proofs)
Prove knowledge of secret WITHOUT revealing it:
import { deriveGhostPDA, GHOST_ACTION_AUTHENTICATE } from '@styxstack/pmp-sdk';
// Prover knows secret
const secret = crypto.getRandomValues(new Uint8Array(32));
const secretHash = keccak256(secret);
// Prove knowledge
await novel.proveSecretKnowledge(
prover,
secret,
GHOST_ACTION_AUTHENTICATE
);
// Program verifies PDA derivation → prover MUST know secretMobile Integration
All instruction builders work with Solana Mobile Wallet Adapter:
import { buildVoteInstruction, STYX_PMP_PROGRAM_ID } from '@styxstack/pmp-sdk';
import { transact } from '@solana-mobile/mobile-wallet-adapter-protocol';
// Build instruction (no signing yet)
const voteIx = buildVoteInstruction(STYX_PMP_PROGRAM_ID, wallet.publicKey, options);
const tx = new Transaction().add(voteIx);
// Sign with mobile wallet
await transact(async (mwa) => {
const signed = await mwa.signTransactions([tx]);
await connection.sendRawTransaction(signed[0].serialize());
});Program IDs
| Network | Program ID |
|---------|------------|
| Mainnet | GhSTPRZFBnWXMjt6xFnpY2ZHFwijFoC44KkxXSEC94X9 |
| Devnet | CFTbFxMeu5cMPWvaaWNdtsv85H7cfkjYVAgXvQ5r643d |
| Treasury | 13xnC9kDksJMBE9FYVW1S7dukLjRDgrh4Dzm6eq5moon |
import { STYX_PMP_PROGRAM_ID, TREASURY, PROTOCOL_FEE_LAMPORTS } from '@styxstack/pmp-sdk';Fee Structure
| Operation | Fee | |-----------|-----| | Private Message | 0.001 SOL | | Private Transfer | 0.001 SOL | | Private Vote | 0.001 SOL | | VTA Transfer | 0.001 SOL | | Time Capsule | 0.001 SOL | | Ghost PDA | 0.001 SOL | | Referral Register | FREE | | Referral Claim | FREE | | Compliance Reveal | FREE |
💠Support Development
If you find this SDK valuable:
Send SOL to: 13xnC9kDksJMBE9FYVW1S7dukLjRDgrh4Dzm6eq5moon
Or contact @solanadevdao
License
Apache-2.0
Attribution Required: When using this SDK, please include:
Powered by Styx Stack - https://github.com/QuarksBlueFoot/StyxStack
Created by @moonmanquark (Bluefoot Labs)Built by @moonmanquark at Bluefoot Labs
