# Class BSV::Primitives::ExtendedKey <a id="class-BSV-Primitives-ExtendedKey"></a>

**Inherits:** `Object`

BIP-32 hierarchical deterministic (HD) extended key.

Supports both private and public extended keys, serialised as Base58Check
xprv/xpub strings. Provides child key derivation (normal and hardened),
path-based derivation (+m/44'/0'/0'+), and neutering (private → public).

**@example Derive keys from a seed**
```ruby
seed = SecureRandom.random_bytes(32)
master = BSV::Primitives::ExtendedKey.from_seed(seed)
child  = master.derive_path("m/44'/0'/0'/0/0")
child.public_key.address #=> "1..."
```

**@example Parse an xpub string**
```ruby
xpub = BSV::Primitives::ExtendedKey.from_string('xpub6...')
xpub.public? #=> true
```

## Constants
### `HARDENED` <a id="constant-HARDENED"></a> <a id="HARDENED-constant"></a>
Offset added to child indices for hardened derivation.

### `PRIVATE_VERSIONS` <a id="constant-PRIVATE_VERSIONS"></a> <a id="PRIVATE_VERSIONS-constant"></a>
Private extended key version bytes.

### `PUBLIC_VERSIONS` <a id="constant-PUBLIC_VERSIONS"></a> <a id="PUBLIC_VERSIONS-constant"></a>
Public extended key version bytes.

### `VERSIONS` <a id="constant-VERSIONS"></a> <a id="VERSIONS-constant"></a>
Version bytes for extended key serialisation (BIP-32).

## Attributes
### `chain_code` [R] <a id="attribute-i-chain_code"></a> <a id="chain_code-instance_method"></a>
- **@return** [String] 32-byte chain code for child derivation

### `child_number` [R] <a id="attribute-i-child_number"></a> <a id="child_number-instance_method"></a>
- **@return** [Integer] child number (index used to derive this key)

### `depth` [R] <a id="attribute-i-depth"></a> <a id="depth-instance_method"></a>
- **@return** [Integer] depth in the derivation tree (0 = master)

### `key` [R] <a id="attribute-i-key"></a> <a id="key-instance_method"></a>
- **@return** [String] raw key bytes (32-byte private or 33-byte compressed public)

### `parent_fingerprint` [R] <a id="attribute-i-parent_fingerprint"></a> <a id="parent_fingerprint-instance_method"></a>
- **@return** [String] 4-byte fingerprint of the parent key

### `version` [R] <a id="attribute-i-version"></a> <a id="version-instance_method"></a>
- **@return** [String] 4-byte version prefix

## Public Class Methods
### `from_seed(seed, network: = :mainnet)` <a id="method-c-from_seed"></a> <a id="from_seed-class_method"></a>
Derive a master extended key from a binary seed.

Uses HMAC-SHA-512 with key +"Bitcoin seed"+ per BIP-32.
- **@param** `seed` [String] 16-64 byte seed (typically from {Mnemonic#to_seed})
- **@param** `network` [Symbol] +:mainnet+ or +:testnet+
- **@raise** [ArgumentError] if the seed length is invalid or derives an invalid key
- **@return** [ExtendedKey] the master private extended key

### `from_string(base58)` <a id="method-c-from_string"></a> <a id="from_string-class_method"></a>
Parse an extended key from a Base58Check-encoded string (xprv/xpub).
- **@param** `base58` [String] Base58Check-encoded extended key
- **@raise** [ArgumentError] if the encoding, length, or version/key mismatch is invalid
- **@return** [ExtendedKey]

## Public Instance Methods
### `child(index)` <a id="method-i-child"></a> <a id="child-instance_method"></a>
Derive a child key at the given index.

Indices below {HARDENED} produce normal (public-derivable) children. Indices
>= {HARDENED} produce hardened children (private key required).
- **@param** `index` [Integer] the child index (use +HARDENED + n+ for hardened)
- **@raise** [ArgumentError] if deriving hardened from a public key, or at max depth
- **@return** [ExtendedKey] the derived child key

### `derive_path(path)` <a id="method-i-derive_path"></a> <a id="derive_path-instance_method"></a>
Derive a child key from a BIP-32 path string.
- **@param** `path` [String] derivation path (e.g. +"m/44'/0'/0'/0/0"+)
- **@raise** [ArgumentError] if the path does not start with +'m'+
- **@return** [ExtendedKey] the derived key

### `fingerprint()` <a id="method-i-fingerprint"></a> <a id="fingerprint-instance_method"></a>
The 4-byte fingerprint of this key (first 4 bytes of identifier).
- **@return** [String] 4-byte fingerprint

### `identifier()` <a id="method-i-identifier"></a> <a id="identifier-instance_method"></a>
The 20-byte Hash160 identifier for this key.
- **@return** [String] 20-byte Hash160 of the compressed public key

### `initialize(key:, chain_code:, version:, depth: = 0, parent_fingerprint: = "\x00\x00\x00\x00".b, child_number: = 0)` <a id="method-i-initialize"></a> <a id="initialize-instance_method"></a>
- **@param** `key` [String] raw key bytes
- **@param** `chain_code` [String] 32-byte chain code
- **@param** `version` [String] 4-byte version prefix
- **@param** `depth` [Integer] derivation depth
- **@param** `parent_fingerprint` [String] 4-byte parent fingerprint
- **@param** `child_number` [Integer] child index
- **@return** [ExtendedKey] a new instance of ExtendedKey

### `neuter()` <a id="method-i-neuter"></a> <a id="neuter-instance_method"></a>
Convert a private extended key to its public counterpart.
- **@raise** [ArgumentError] if already a public key
- **@return** [ExtendedKey] the public extended key (xpub)

### `private?()` <a id="method-i-private-3F"></a> <a id="private?-instance_method"></a>
Whether this is a private extended key.
- **@return** [Boolean]

### `private_key()` <a id="method-i-private_key"></a> <a id="private_key-instance_method"></a>
Extract the {PrivateKey} from a private extended key.
- **@raise** [ArgumentError] if this is a public extended key
- **@return** [PrivateKey]

### `public?()` <a id="method-i-public-3F"></a> <a id="public?-instance_method"></a>
Whether this is a public extended key.
- **@return** [Boolean]

### `public_key()` <a id="method-i-public_key"></a> <a id="public_key-instance_method"></a>
Extract the {PublicKey} from this extended key.
- **@return** [PublicKey]

### `to_s()` <a id="method-i-to_s"></a> <a id="to_s-instance_method"></a>
Serialise as a Base58Check-encoded string (xprv or xpub).
- **@return** [String] the Base58Check-encoded extended key
