§ Developers · /developers/view-keys
View-key format.
View keys give scoped, revocable decryption authority without spending authority. The construction follows Zcash Sapling sub-view-keys, refined for Adamant's multi-dimensional scope (date range + amount + counterparty + contract).
§ 01 / Encoding
Bech32m, prefix vkey1.
vkey1 <bech32m-payload>
payload = version(1B)
|| scope_bits(2B) // bitmask: DATE | AMOUNT | COUNTERPARTY | CONTRACT
|| not_before(8B, unix-ms)
|| not_after(8B, unix-ms)
|| amount_min(8B) // base units (10^-9 ADM); 0 = any
|| amount_max(8B) // 0 = any
|| counterparty_hash(32B)// SHA3-256 of bech32m address; 0 = any
|| contract_id(32B) // ObjectId; 0 = any
|| derived_pubkey(32B)
|| sig(64B) // master spending key signs the scope § 02 / Derivation
Sub-keys from a master.
master_view_key = SHAKE-256("ADAMANT-v1-view-master" || spend_key, 32)
sub_view_key(scope) = HKDF-SHA3-256(
salt = "ADAMANT-v1-view-sub",
ikm = master_view_key,
info = canonical_serialise(scope),
L = 32
) Sub-keys cannot derive other sub-keys; each scope has exactly one canonical key. Revocation publishes an on-chain revocation record keyed by derived_pubkey.
§ 03 / Disclosure
Decrypting under a sub-key.
use adamant_sdk::view::{ViewKey, Disclosure};
let vk: ViewKey = ViewKey::decode("vkey1...")?;
let d = Disclosure::scan(&client, &vk, range).await?;
for tx in d.iter() {
println!("{} -> {} : {} ADM", tx.from, tx.to, tx.amount);
} Scans run locally. The chain has no idea who is decrypting; it only verifies signature validity if the disclosure is published on-chain (paying fee dimension F.05).