Sigma Identity bridges two key systems: BAP (Bitcoin Attestation Protocol) for identity continuity, and BRC-100 for wallet operations. The important correction is that these are related but not identical keys.
Key Hierarchy
The current hierarchy has a stable identity root and a rotatable wallet root:
Layer by Layer
| Layer | Key | Derived Via | Purpose |
|---|---|---|---|
| Master | Sigma master private key (WIF) | User-generated | Top-level secret, never transmitted |
| Member | BAP member key at rootPath | deriveChild(masterPub, "bap:N") | Stable identity root; defines rootAddress and BAP ID |
| Wallet Root | Active BRC-100 wallet root at currentPath | getPathDerivedKey(currentPath) | Active wallet/auth root; rotates with incrementPath() |
| Signing | BAP signing key | deriveChild(walletRootPub, "1-bap-identity") | Attestation signatures from the active wallet root |
For Type 42 identities, rotation paths look like this:
bap:0= initial identity and wallet rootbap:0:1= first wallet rotationbap:0:2= second wallet rotation
rootPath stays fixed. currentPath changes.
BAP ID vs BRC-31 Identity Key
These identifiers are often confused, but they diverge once wallet rotation begins.
| BAP ID | BRC-31 Identity Key | |
|---|---|---|
| What | Stable identity hash | Compressed secp256k1 public key |
| Format | ~27 char base58 string | 66 hex chars (02/03 prefix) |
| Derived from | Member key's address at rootPath | Active wallet root public key at currentPath |
| Used in | BAP identity lookup, Sigma bap_id | BRC-31 auth headers, wallet auth, BRC-42/43 derivation |
| Rotates? | No | Yes, when the wallet root rotates |
BAP ID Derivation
memberKey(rootPath).toPublicKey().toAddress() = rootAddress
BAP ID = base58(ripemd160(sha256(rootAddress)))BAP ID is derived from the stable member key at rootPath, never from the active wallet root or the signing key.
Stable Member Key vs Active Wallet Root
The stable member key and the active wallet root are equal only at the beginning, when currentPath === rootPath.
After rotation:
- the member key still defines the same BAP ID
- the wallet root changes to a new path-derived key
- the BRC-31 identity key changes with the wallet root
- the signing key changes because it is derived from the wallet root
That means systems should store these values separately:
member_pubkey: stable identity linkage atrootPathwallet_pubkey: active wallet/auth key atcurrentPath
Library API
bsv-bap exposes the relationship explicitly:
import { BAP, bapIdFromPubkey } from 'bsv-bap';
const bap = new BAP({ rootPk: masterKey.toWif() });
const identity = bap.newId('Alice');
const memberPubkey = identity.getMemberKey(); // stable rootPath member key
const walletPubkey = identity.getWalletPubkey(); // active currentPath wallet root
const walletRoot = identity.getWalletRoot(); // active wallet root private key
const bapId = bapIdFromPubkey(memberPubkey); // validbapIdFromPubkey(pubkey) is only valid when pubkey is the stable member key at rootPath. After rotation, the active wallet pubkey is no longer a direct BAP-ID input.
Rotation Example
const bap = new BAP({ rootPk: masterKey.toWif() });
const identity = bap.newId('Alice');
const stableBapId = identity.getIdentityKey();
const memberPubkey1 = identity.getMemberKey();
const walletPubkey1 = identity.getWalletPubkey();
identity.incrementPath();
const memberPubkey2 = identity.getMemberKey();
const walletPubkey2 = identity.getWalletPubkey();
stableBapId === identity.getIdentityKey(); // true
memberPubkey1 === memberPubkey2; // true
walletPubkey1 !== walletPubkey2; // trueIntegration Patterns
Server-Side: stable identity lookup
Use the stable member pubkey when you need deterministic BAP ID resolution:
import { bapIdFromPubkey } from 'bsv-bap';
const bapId = bapIdFromPubkey(memberPubkeyAtRootPath);Wallet/Auth flows: active wallet pubkey
Use the active wallet pubkey for BRC-31 or BRC-100 wallet authentication, and map it separately to the BAP identity:
await api.connectWallet({
bapId,
memberPubkey, // stable identity linkage
walletPubkey, // active auth key from currentPath
});Client-side exports
If a user exports a portable "member backup" for identity ownership, export the stable member key at rootPath, not the active rotated wallet key.