HESTIAdocs

Meta-addresses

The hestia1… string you share to receive private payments — what it encodes and how senders use it.


A meta-address is the public identifier an agent shares to receive shielded funds. It is a Bech32m string that starts with hestia1… and encodes everything a sender needs and nothing they shouldn't have.

text
hestia1q… (Bech32m)
   │
   └─ human-readable prefix "hestia", version 1, and the payload:
        chain tag  +  SK (public spending key)  +  VK (public viewing key)

What it encodes

ts
interface MetaAddress {
  chain: "base" | "baseSepolia"; // chain tag: base = 0, baseSepolia = 1
  SK: bigint;                    // public spending key — becomes the note's owner
  VK: Uint8Array;                // public viewing key — note ciphertext is sealed to it
}
FieldConstant
Human-readable prefixhestia (META_ADDRESS_HRP)
Version1 (META_ADDRESS_VERSION)
Chain tagbase → 0, baseSepolia → 1 (CHAIN_TAG)
EncodingBech32m

It contains only public keys. Sharing a meta-address never exposes the ability to spend or to read your notes — only the ability to pay you.

Encoding and decoding

ts
import { encodeMetaAddress, decodeMetaAddress } from "@hestia/common";

const addr = encodeMetaAddress({ chain: "baseSepolia", SK: keys.SK, VK: keys.VK });
// → "hestia1…"

const meta = decodeMetaAddress(addr);
// → { chain: "baseSepolia", SK, VK }

With the SDK you don't call these directly — read hestia.metaAddress:

ts
const myAddress = hestia.metaAddress; // share this to get paid

How a sender uses it

When you call hestia.send({ token, amount, to }), the SDK decodes the recipient's meta-address and uses both keys:

  1. SK becomes the new note's owner — so only the recipient, holding the matching sk, can ever spend it.
  2. VK encrypts the note plaintext — so only the recipient, holding the matching vk, can discover and read it.
ts
await hestia.send({ token: USDC, amount: 1_000_000n, to: "hestia1…recipient" });

Neither key reveals the recipient's identity on-chain. The output is just another commitment and another ciphertext among thousands.

Why Bech32m

Bech32m gives the address a checksum and a fixed human-readable prefix, so a typo is caught before funds move and the string is unmistakably a Hestia address (not an EVM 0x… address). The chain tag prevents a Base-mainnet address from being used to receive on Base Sepolia by mistake — the SDK's default metaChain is baseSepolia and can be set per identity.

Next: association sets — how a note proves it came from an approved source — and viewing keys, the disclosure side of that same VK/vk pair.