# `X402.Signer.LocalKey`
[🔗](https://github.com/cardotrejos/x402/blob/v0.9.0/lib/x402/signer/local_key.ex#L1)

`X402.Signer` backed by a raw secp256k1 private key held in memory.

Requires the optional `ex_secp256k1` and `ex_keccak` dependencies;
`new/1` returns `{:error, :missing_dependency}` when they are unavailable.

The struct redacts the private key when inspected, but the key still lives
in process memory — prefer an external signer implementation (KMS, hardware
wallet) for production payers holding significant funds.

## Examples

    {:ok, signer} = X402.Signer.LocalKey.new("0x" <> String.duplicate("11", 32))
    {:ok, address} = X402.Signer.LocalKey.address(signer)

# `t`

```elixir
@type t() :: %X402.Signer.LocalKey{address: String.t(), private_key: binary()}
```

A local secp256k1 signing key with its derived EVM address.

# `address`
*since 0.6.0* 

```elixir
@spec address(t()) :: {:ok, String.t()}
```

Returns the EVM address derived from the private key.

# `new`
*since 0.6.0* 

```elixir
@spec new(binary()) ::
  {:ok, t()} | {:error, :invalid_private_key | :missing_dependency}
```

Builds a signer from a 32-byte secp256k1 private key.

Accepts the raw 32-byte binary or its hex encoding (with or without a
leading `0x`). The EVM address is derived once at construction.

Returns `{:error, :invalid_private_key}` for malformed keys and
`{:error, :missing_dependency}` when the optional `ex_secp256k1` /
`ex_keccak` dependencies are unavailable.

## Examples

    iex> X402.Signer.LocalKey.new("not hex")
    {:error, :invalid_private_key}

    iex> {:ok, signer} = X402.Signer.LocalKey.new("0x" <> String.duplicate("11", 32))
    iex> signer.address
    "0x19e7e376e7c213b7e7e7e46cc70a5dd086daff2a"

# `sign_eip712`
*since 0.6.0* 

```elixir
@spec sign_eip712(t(), binary(), X402.Signer.typed_data()) ::
  {:ok, X402.Signer.signature()} | {:error, term()}
```

Signs the precomputed EIP-712 digest with the local key.

The typed data is ignored — a local key can sign the digest directly.

# `sign_message`
*since 0.9.0* 

```elixir
@spec sign_message(t(), binary()) :: {:ok, String.t()} | {:error, term()}
```

Signs `message` with EIP-191 `personal_sign` using the local key.

Hashes `"\x19Ethereum Signed Message:\n" <> byte_size(message) <> message`
with keccak256 and returns the `0x`-prefixed hex `r || s || v` signature
(`v` is `27` or `28`), the format `X402.Extensions.SIWX.Verifier.Default`
verifies. Requires the optional `ex_secp256k1` and `ex_keccak`
dependencies.

# `sign_transaction`
*since 0.9.0* 

```elixir
@spec sign_transaction(t(), binary(), X402.Transaction.t()) ::
  {:ok, X402.Signer.signature()} | {:error, term()}
```

Signs a transaction digest with the local key, without broadcasting.

The dispatcher computes the digest from the transaction. This callback
independently recomputes it and rejects a mismatched digest.

---

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