Skip to main content
Low-level stealth address functions for Solana using ed25519. Import from @wraith-protocol/sdk/chains/solana. Most developers should use the Agent Client instead. These primitives are for power users building custom stealth address integrations on Solana.

Installation

Import

Types

Relationship to Stellar Module

Solana uses the same ed25519 curve as Stellar. The cryptographic algorithms are identical — only the address encoding and transaction format differ.

Constants


Functions

deriveStealthKeys(signature)

Derive spending and viewing key pairs from a 64-byte ed25519 signature.
Algorithm:
  1. spendingKey = SHA-256("wraith:spending:" || signature) — 32-byte seed
  2. viewingKey = SHA-256("wraith:viewing:" || signature) — 32-byte seed
  3. Each seed is expanded via seedToScalar() (SHA-512 + clamping)
  4. Public keys derived via ed25519.getPublicKey(seed)

seedToScalar(seed)

Convert a 32-byte ed25519 seed to its clamped scalar.

computeSharedSecret(privateKey, publicKey)

Compute an ECDH shared secret using X25519 (Montgomery form conversion).

computeViewTag(sharedSecret)

Compute the view tag from a shared secret.

hashToScalar(sharedSecret)

Hash a shared secret to a scalar value for stealth address derivation.

generateStealthAddress(spendingPubKey, viewingPubKey, ephemeralSeed?)

Generate a one-time stealth address for a Solana recipient.
Algorithm:
  1. Generate random ephemeral ed25519 seed
  2. Compute shared secret via X25519 ECDH
  3. viewTag = computeViewTag(sharedSecret)
  4. hScalar = hashToScalar(sharedSecret)
  5. stealthPoint = spendingPubKey + hScalar * G (ed25519 point addition)
  6. Encode as base58 Solana address via PublicKey

checkStealthAddress(ephemeralPubKey, viewingKey, spendingPubKey, viewTag)

Check if an announcement belongs to you.

scanAnnouncements(announcements, viewingKey, spendingPubKey, spendingScalar)

Scan announcements and return matches with their private scalars.
The fourth argument is spendingScalar (bigint), same as the Stellar module.

deriveStealthPrivateScalar(spendingScalar, viewingKey, ephemeralPubKey)

Derive the private scalar for a specific stealth address.

signWithScalar(message, scalar, publicKey)

Sign a message using a raw scalar instead of a seed.

signSolanaTransaction(txMessageBytes, stealthScalar, stealthPubKey)

Sign a Solana transaction message with a stealth private scalar.

encodeStealthMetaAddress(spendingPubKey, viewingPubKey)

Encode two 32-byte public keys into a Solana stealth meta-address.

decodeStealthMetaAddress(metaAddress)

Decode a Solana meta-address back into its component keys.

pubKeyToSolanaAddress(publicKey)

Convert a 32-byte ed25519 public key to a base58 Solana address.

bytesToHex(bytes) / hexToBytes(hex)

Utility functions for converting between Uint8Array and hex strings.

End-to-End Flow

Solana-Specific Considerations

  • No account deployment: Unlike Stellar, Solana doesn’t require createAccount. An ed25519 public key is a valid address — send SOL directly to it.
  • Rent exemption: Accounts need ~0.00089 SOL to be rent-exempt. When withdrawing all, send balance - txFee (5000 lamports). The account is garbage collected when balance drops below rent exemption.
  • SPL tokens: Token transfers use associated token accounts (ATAs), not direct transfers. The ATA must be created for the stealth address before transferring SPL tokens.
  • Announcements: Fetched from program transaction logs via fetchAnnouncements("solana"), not a subgraph.
  • Signing: Same signWithScalar() as Stellar — stealth scalars are derived and can’t be used with standard Solana Keypair.

Chain Deployments

The SDK ships with deployed program IDs and RPC URLs for supported Solana networks.

getDeployment(chain)

Supported Networks

Fetching Announcements

fetchAnnouncements(chain?)

Fetches all stealth address announcements from the announcer program’s transaction history. Parses Anchor event logs automatically.