(** Keys are exposed as phantom types for safety. **)

type ' a key

(** Convert key to array of ints from 0-255. **)

val unsafe_key_to_ints : ' a key -> int array

(** Print key as 8-bit numerals separated by spaces. **)

val print_key : ' a key -> unit

(** A key used to generate proofs. **)

type proof_generation

(** A key used for viewing encrypted cheques by sender, **)

type outgoing_viewing

(** Returns new proof generation key and outgoing viewing key. Not referentially transparent. **)

val new_spending_key : unit -> proof_generation key * outgoing_viewing key

(** Returns a new fresh proof generation key. Without an outgoing viewing key cheques cannot be decrypted by sender. Not referentially transparent. **)

val new_blind_spending_key : unit -> proof_generation key

(** A key used to verify proofs. **)

type verifying

(** A key used for deriving an incoming viewing key and new addresses. **)

type full_viewing

val viewing_key_of_proof_generation_key : proof_generation key -> full_viewing key

(** A key used for viewing encrypted cheques by recipient. **)

type incoming_viewing

val incoming_of_viewing_key : full_viewing key -> incoming_viewing key

(** Address for transactions. Consists of a group key and identifying key. **)

type address

(** A group key that can be shared by multiple distinct addresses. **)

type address_group

(** Returns the group key of an address. **)

val get_address_group : address -> address_group key

(** Returns a new address group. Not referentially transparent. **)

val new_address_group : unit -> address_group key

(** A unique key identifying an address. **)

type address_id

(** Returns a new address. Not referentially transparent. **)

val new_address : address_group key -> full_viewing key -> address

(** Returns the identifying key of an address. **)

val get_address_id : address -> address_id key

(** Returns true if address matches group. **)

val match_address_group : address -> address_group key -> bool

(** Number of satoshis in a cheque. **)

type value

(** Make a new value from an int64. **)

val make_value : int64 -> value

(** The basic unit of a shielded transaction. **)

type cheque

(** Make a new cheque transferring a value to an address. **)

val make_cheque : value -> address -> cheque

(** Returns the value of a cheque. **)

val get_cheque_value : cheque -> value

(** Pedersen commitment to a value **)

type value_commitment

(** Returns the address of a cheque. **)

val get_cheque_address : cheque -> address

(** Pedersen commitment to a cheque. **)

type cheque_commitment

(** Returns the Pedersen commitment of a cheque. **)

val get_cheque_commitment : cheque -> cheque_commitment

(** Unique identifier for cheques. Used to prevent sender from spending tokens that haven't been cashed by recipient. **)

type hold

(** A merkle root. **)

type merkle_root

(** Returns a new merkle root. Not referentially transparent. **)

val new_merkle_root : unit -> merkle_root

(** A witness used to generate a zero knowledge proof. **)

type witness

(** Make a witness from an array of chars. Returns None if argument is not 1065-bit. **)

val new_witness : char array -> witness option

(** A zero knowledge proof. **)

type proof

(** A signature used to sign a cheque. Can be used to delegate proof generation without revealing proof generation key. **)

type signature

(** A public key for encryption, decryption, and verifying proofs of endorsement. Need not be made public. **)

type public

(** A private key for encryption, decryption, and generating proofs of endorsement. **)

type pvt

(** Derives new public and private keys from an address. Not referentially transparent. **)

val new_keypair : address -> public key * pvt key

(** Generates a zero knowledge proof that a cheque has been signed by sender. **)

val sign :

value -> address -> merkle_root -> witness -> proof_generation key ->

proof * verifying key * signature * value_commitment * hold

(** Returns true if a proof of signature is valid. **)

val verify_sign :

signature -> value_commitment -> merkle_root -> hold -> verifying key -> proof ->

( bool , string ) result

(** Generates a zero knowledge proof that a cheque has been cashed by receiver. **)

val endorse :

value -> address -> pvt key ->

proof * verifying key * value_commitment

(** Returns true if a proof of endorsement is valid. **)

val verify_endorse :

value_commitment -> cheque_commitment -> public key -> verifying key -> proof ->

( bool , string ) result

(** A natural language message that accompanies a cheque. **)

type memo

(** Make a memo from a string. Pads with ' ' if argument is < 512-bits. Returns None if argument is > 512-bits **)

val make_memo : string -> memo option

(** An encrypted cheque and memo. **)

type ciphertext

(** Encrypt a cheque and memo for blockchain. **)

val encrypt : public key -> pvt key -> cheque -> memo -> ( ciphertext , string ) result

(** Encrypt a cheque and memo for sender's wallet. **)

val encrypt_for_wallet : outgoing_viewing key -> value_commitment -> cheque_commitment -> public key -> cheque -> memo -> ( ciphertext , string ) result

(** Decrypt a cheque and memo using a full keypair. **)

val decrypt : ciphertext -> public key -> pvt key -> address -> ( cheque * memo , string ) result

(** Decrypt a cheque and memo using an incoming viewing key. **)

val decrypt_incoming : ciphertext -> incoming_viewing key -> public key -> ( cheque * memo , string ) result

(** Decrypt a cheque and memo using an outgoing viewing key. **)