# `BoundedAuthorityProtocol.V2`
[🔗](https://github.com/baselabs/bounded_authority_protocol/blob/v1.0.0/lib/bounded_authority_protocol/v2.ex#L1)

Explicit entry point for the v2 wire profile (contract-major 2, the
[`BAP2-Ed25519-SHA256`](../docs/design/registries.md) suite).

The v2 profile is byte-distinct from v1: grant and proof payloads carry `v: 2`,
domain separators are `BAP2-*`, and the selector algebra admits the two
inclusive range kinds `lte`/`gte` (`spec/bap-v2.md` § 4).
Each major verifies under its own complete closed profile; the v1 façade
rejects v2 bytes and this façade rejects v1 bytes.

Every function here has the contract documented on its `BoundedAuthorityProtocol.V1`
namespace counterpart (same arguments, same `{:ok, value}` or exactly `{:error, :invalid}`
results, same redacted facts), applied to this profile. The struct types are shared, except
`Grant`, `Operation`, `Proof`, `Selector`, `DecodedGrant`, `DecodedProof`, and the facts,
which have their own modules under this namespace.

# `assemble_compact`

```elixir
@spec assemble_compact(BoundedAuthorityProtocol.V1.SigningInput.t(), binary()) ::
  {:ok, binary()} | {:error, :invalid}
```

Assembles a validated signing input and raw Ed25519 signature at profile maxima.

# `assemble_compact`

```elixir
@spec assemble_compact(
  BoundedAuthorityProtocol.V1.SigningInput.t(),
  binary(),
  BoundedAuthorityProtocol.V1.Bounds.t() | map()
) :: {:ok, binary()} | {:error, :invalid}
```

Assembles a validated signing input and raw Ed25519 signature under caller bounds.

Since 0.9.0, assembly also refuses, with `{:error, :invalid}`, a
signature that no conforming signer emits: an Ed25519 signature whose `S` is not below the group
order or whose `R` is non-canonical or of small order (erratum 3). It never rewrites the
signature bytes it accepts.

# `boundary_anchor_signing_input`

```elixir
@spec boundary_anchor_signing_input(
  BoundedAuthorityProtocol.V1.BoundaryAnchor.t(),
  BoundedAuthorityProtocol.V1.Bounds.t() | map()
) :: {:ok, BoundedAuthorityProtocol.V1.SigningInput.t()} | {:error, :invalid}
```

Builds the deterministic standard-JWS boundary-anchor signing input.

# `encode_anchored_export`

```elixir
@spec encode_anchored_export(
  BoundedAuthorityProtocol.V1.AnchoredExportInput.t(),
  BoundedAuthorityProtocol.V1.ExpectedExport.t()
) ::
  {:ok, BoundedAuthorityProtocol.V1.EncodedAnchoredExport.t()}
  | {:error, :invalid}
```

Frames an exact deterministic anchored export after semantic validation.

Since 0.9.0, encoding also refuses, with `{:error, :invalid}`, a
signature that no conforming signer emits: an Ed25519 signature whose `S` is not below the group
order or whose `R` is non-canonical or of small order (erratum 3). It never rewrites the
signature bytes it accepts.

# `encode_consumption_entry`

```elixir
@spec encode_consumption_entry(
  BoundedAuthorityProtocol.V1.ConsumptionEntry.t(),
  BoundedAuthorityProtocol.V1.Bounds.t() | map()
) ::
  {:ok, BoundedAuthorityProtocol.V1.EncodedConsumptionEntry.t()}
  | {:error, :invalid}
```

Encodes one exact canonical consumption-chain row.

# `grant_signing_input`

```elixir
@spec grant_signing_input(
  BoundedAuthorityProtocol.V2.Grant.t(),
  BoundedAuthorityProtocol.V1.Bounds.t() | map()
) :: {:ok, BoundedAuthorityProtocol.V1.SigningInput.t()} | {:error, :invalid}
```

Builds the deterministic standard-JWS grant signing input.

# `key_transition_signing_input`

```elixir
@spec key_transition_signing_input(
  BoundedAuthorityProtocol.V1.KeyTransition.t(),
  BoundedAuthorityProtocol.V1.Bounds.t() | map()
) :: {:ok, BoundedAuthorityProtocol.V1.SigningInput.t()} | {:error, :invalid}
```

Builds the deterministic standard-JWS historical-key-transition signing input.

# `proof_signing_input`

```elixir
@spec proof_signing_input(
  BoundedAuthorityProtocol.V2.Proof.t(),
  BoundedAuthorityProtocol.V1.Bounds.t() | map()
) :: {:ok, BoundedAuthorityProtocol.V1.SigningInput.t()} | {:error, :invalid}
```

Builds the deterministic standard-JWS holder-proof signing input.

# `request_digest`

```elixir
@spec request_digest(
  binary(),
  BoundedAuthorityProtocol.V1.Json.value(),
  BoundedAuthorityProtocol.V1.Bounds.t() | map()
) :: {:ok, binary()} | {:error, :invalid}
```

Returns the canonical type-preserving request digest.

# `decode_grant`

```elixir
@spec decode_grant(binary(), BoundedAuthorityProtocol.V1.Bounds.t() | map()) ::
  {:ok, BoundedAuthorityProtocol.V2.DecodedGrant.t()} | {:error, :invalid}
```

Boundedly decodes a raw compact grant without evaluating trust.

# `decode_proof`

```elixir
@spec decode_proof(binary(), BoundedAuthorityProtocol.V1.Bounds.t() | map()) ::
  {:ok, BoundedAuthorityProtocol.V2.DecodedProof.t()} | {:error, :invalid}
```

Boundedly decodes a raw compact proof without evaluating trust.

# `untrusted_key_locator`

```elixir
@spec untrusted_key_locator(binary(), BoundedAuthorityProtocol.V1.Bounds.t() | map()) ::
  {:ok, BoundedAuthorityProtocol.V1.KeyLocator.t()} | {:error, :invalid}
```

Parses only the protected grant header and returns its untrusted `kid` hint.

The complete compact input is bounded. Payload and signature segments are not decoded,
interpreted, or independently size-checked. The header walk is major-neutral (it inspects
`alg`/`typ`/`kid` only), so it delegates to the shared v1 implementation.

# `check_chain`

```elixir
@spec check_chain(
  BoundedAuthorityProtocol.V1.ChainInput.t(),
  BoundedAuthorityProtocol.V1.ExpectedChain.t()
) :: {:ok, BoundedAuthorityProtocol.V2.ChainFacts.t()} | {:error, :invalid}
```

Checks a raw nonempty consumption-chain range against mandatory caller boundaries.

# `check_envelope`

```elixir
@spec check_envelope(
  BoundedAuthorityProtocol.V1.Credentials.t(),
  BoundedAuthorityProtocol.V1.ExpectedRequest.t()
) :: {:ok, BoundedAuthorityProtocol.V2.EnvelopeFacts.t()} | {:error, :invalid}
```

Verifies a raw grant-and-proof envelope against server-derived expected context.

# `verify_anchored_export`

```elixir
@spec verify_anchored_export(
  BoundedAuthorityProtocol.V1.ArchivedObject.t(),
  BoundedAuthorityProtocol.V1.HistoricalKeyChain.t(),
  BoundedAuthorityProtocol.V1.ExpectedAnchoredExport.t()
) ::
  {:ok, BoundedAuthorityProtocol.V2.AnchoredExportFacts.t()}
  | {:error, :invalid}
```

Atomically verifies one raw anchored export against caller boundaries and key history.

# `verify_grant`

```elixir
@spec verify_grant(
  binary(),
  BoundedAuthorityProtocol.V1.TrustedIssuer.t(),
  BoundedAuthorityProtocol.V1.ExpectedGrant.t()
) :: {:ok, BoundedAuthorityProtocol.V2.GrantFacts.t()} | {:error, :invalid}
```

Verifies one raw compact grant against caller-supplied trust and expected context.

# `verify_historical_anchor`

```elixir
@spec verify_historical_anchor(
  binary(),
  BoundedAuthorityProtocol.V1.HistoricalPublicKey.t(),
  BoundedAuthorityProtocol.V1.ExpectedAnchor.t()
) :: {:ok, BoundedAuthorityProtocol.V2.AnchorFacts.t()} | {:error, :invalid}
```

Verifies one raw compact boundary anchor against one exact historical public key.

# `verify_key_transition`

```elixir
@spec verify_key_transition(
  binary(),
  BoundedAuthorityProtocol.V1.HistoricalPublicKey.t(),
  BoundedAuthorityProtocol.V1.HistoricalPublicKey.t(),
  BoundedAuthorityProtocol.V1.ExpectedKeyTransition.t()
) ::
  {:ok, BoundedAuthorityProtocol.V2.KeyTransitionFacts.t()} | {:error, :invalid}
```

Verifies one raw compact authenticated historical-key transition.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
