Search documentation of Cartouche

# Cartouche.Signer (Cartouche v0.1.3)

Copy Markdown View Source

Cartouche.Signer is a GenServer which can sign messages. This module takes an mfa (mod, func, args triple) which defines how to actually sign messages. For instance, `Cartouche.Signer.Curvy` will sign with a public key, or `Cartouche.Signer.CloudKMS` will sign using a GCP Cloud KMS key. In either case, the caller should start the GenServer, and then call: `Cartouche.Signer.sign(MySigner, "message")`. This should return back a properly signed message.

Note: we also enforce that a given signer process knows its public key, such that we can verify signatures recovery bits. That is, since CloudKMS and other signing tools don't return a recovery bit, necessary for Ethereum, we test all 4 possible bits to make sure a signature recovers to the correct signer address, but we need to know what that address should be to accomplish this task.

Additionally, chain_id is used to return EIP-155 compliant signatures.

## Summary

### Functions

address(name \\ Default)

Gets the address for this signer.

chain_id(name \\ Default)

Gets the chain id for this signer.

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

sign(message, name \\ Default, opts \\ [])

Signs a message using this signing key.

sign_direct(message, address, arg, chain_id_or_name)

Directly sign a message, not using a signer process.

start_link(list)

Starts a new Cartouche.Signer process.

## Functions

# address(name \\ Default)

    @spec address(GenServer.name()) :: Cartouche.address()

Gets the address for this signer.

## Examples

    iex> signer_proc = Cartouche.Test.Signer.start_signer()
    iex> Cartouche.Signer.address(signer_proc) |> Cartouche.Hex.to_address()
    "0x63Cc7c25e0cdb121aBb0fE477a6b9901889F99A7"

# chain_id(name \\ Default)

    @spec chain_id(GenServer.name()) :: integer()

Gets the chain id for this signer.

## Examples

    iex> signer_proc = Cartouche.Test.Signer.start_signer()
    iex> Cartouche.Signer.chain_id(signer_proc)
    5

# child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# sign(message, name \\ Default, opts \\ [])

    @spec sign(String.t(), GenServer.name(), Keyword.t()) ::
      {:ok, binary()} | {:error, String.t()}

Signs a message using this signing key.

## Examples

    iex> signer_proc = Cartouche.Test.Signer.start_signer()
    iex> {:ok, sig} = Cartouche.Signer.sign("test", signer_proc)
    iex> Cartouche.Recover.recover_eth("test", sig)
    ...> |> Cartouche.Hex.to_address()
    "0x63Cc7c25e0cdb121aBb0fE477a6b9901889F99A7"

    iex> signer_proc = Cartouche.Test.Signer.start_signer()
    iex> {:ok, <<_r::256, _s::256, v::binary>>} = Cartouche.Signer.sign("test", signer_proc, chain_id: 0x05f5e0ff)
    iex> :binary.decode_unsigned(v)
    0x05f5e0ff * 2 + 35 + 1

# sign_direct(message, address, arg, chain_id_or_name)

    @spec sign_direct(String.t(), binary(), {module(), atom(), [any()]}, integer()) ::
      {:ok, binary()} | {:error, String.t()}

Directly sign a message, not using a signer process.

This is mostly used internally, but can be used safely externally as well.

# start_link(list)

    @spec start_link(mfa: {module(), atom(), [any()]}, name: GenServer.name()) ::
      GenServer.on_start()

Starts a new Cartouche.Signer process.