Skip to main content
Low-level stealth address functions for EVM-compatible chains (Horizen, Ethereum, Polygon, Base, etc.) using secp256k1. Import from @wraith-protocol/sdk/chains/evm. Most developers should use the Agent Client instead. These primitives are for power users building custom stealth address integrations.

Import

Types

Constants


Functions

deriveStealthKeys(signature)

Derive spending and viewing key pairs from a wallet signature.
Algorithm:
  1. Split the 65-byte signature: r = sig[0:32], s = sig[32:64]
  2. spendingKey = keccak256(r)
  3. viewingKey = keccak256(s)
  4. Derive compressed public keys from each private key
Same signature always produces the same keys. The spending key is never equal to the viewing key.

generateStealthAddress(spendingPubKey, viewingPubKey, ephemeralKey?)

Generate a one-time stealth address for a recipient.
Algorithm:
  1. Generate random ephemeral key pair (r, R = r * G)
  2. Compute ECDH shared secret S = r * viewingPubKey
  3. hashedSecret = keccak256(S)
  4. viewTag = hashedSecret[0]
  5. stealthPoint = spendingPubKey + hash(S) * G
  6. stealthAddress = keccak256(stealthPoint)[12:32]
Each call produces a different address (new ephemeral key). Pass an explicit ephemeralKey for deterministic testing.

checkStealthAddress(ephemeralPubKey, viewingKey, spendingPubKey, viewTag)

Check if a stealth address announcement belongs to you.
Uses view tag for fast rejection — eliminates ~255/256 non-matching announcements without computing the full stealth address.

scanAnnouncements(announcements, viewingKey, spendingPubKey, spendingKey)

Scan an array of on-chain announcements and return the ones that belong to you.
For each announcement:
  1. Skip if schemeId doesn’t match
  2. Extract view tag from metadata
  3. Check if it matches using checkStealthAddress
  4. If matched, derive the stealth private key

deriveStealthPrivateKey(spendingKey, ephemeralPubKey, viewingKey)

Compute the private key that controls a specific stealth address.
Algorithm:
  1. S = viewingKey * ephemeralPubKey (shared secret)
  2. hashScalar = keccak256(S) mod n
  3. stealthPrivateKey = (spendingKey + hashScalar) mod n

encodeStealthMetaAddress(spendingPubKey, viewingPubKey)

Encode two public keys into a stealth meta-address string.
Both keys must be 33-byte compressed secp256k1 points.

decodeStealthMetaAddress(metaAddress)

Decode a meta-address back into its component public keys.
Validates the prefix, length, and that both keys are valid curve points.

metaAddressToBytes(metaAddress)

Strip the st:eth: prefix from a meta-address, returning the raw hex bytes.

signNameRegistration(name, metaAddressBytes, spendingKey)

Sign a message for on-chain .wraith name registration.

signNameRegistrationOnBehalf(name, metaAddressBytes, spendingKey, nonce)

Sign with a nonce for delegated registration.

signNameUpdate(name, newMetaAddressBytes, spendingKey)

Sign a name update to point to a new meta-address.

signNameRelease(name, spendingKey)

Sign a name release to give up ownership.

End-to-End Flow

Transaction Builders

Builders return { to, data, value? } objects — submit with any library (viem, ethers, wagmi, raw RPC).

buildSendStealth(params)

Send ETH privately via stealth address. Uses the WraithSender contract for atomic send + announce.
Returns: { transaction: { to, data, value }, stealthAddress, ephemeralPubKey, viewTag }

buildSendERC20(params)

Send an ERC-20 token privately. The sender must have approved the WraithSender contract first.

buildRegisterName(params)

Register a .wraith name on-chain. The name is bound to the spending key.

buildUpdateName(params)

Update a .wraith name’s meta-address. Must be signed by the current owner.

buildReleaseName(params)

Release a .wraith name. After release, anyone can register it.

buildRegisterMetaAddress(params)

Register a stealth meta-address in the ERC-6538 registry. Makes it discoverable by wallet address.

buildAnnounce(params)

Publish a stealth address announcement on-chain. Use this if you’re sending assets directly (not via WraithSender) and need to announce separately.

buildResolveName(params)

Build calldata to resolve a .wraith name. Returns data for a static call (read-only, no transaction).

Contract ABIs

The raw ABIs are exported if you need to encode calls yourself:

Chain Deployments

The SDK ships with deployed contract addresses and subgraph URLs for supported chains. No need to deploy contracts yourself.

getDeployment(chain)

Returns the full deployment config for a chain:

DEPLOYMENTS

Access all deployments directly:

Supported EVM Chains

Fetching Announcements

fetchAnnouncements(chain, subgraphUrl?)

Fetches all stealth address announcements from the Goldsky subgraph for the specified chain. Handles pagination automatically.
Override the subgraph URL if needed: