{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}

{-# LANGUAGE TypeFamilies #-}
-- |
-- Copyright: © 2021 IOHK
-- License: Apache-2.0
--
-- Address books consist of a 'Prologue'
-- and discovered addresses ('Discoveries').
module Cardano.Wallet.Address.Book
    ( AddressBookIso (..)
    , Prologue (..)
    , Discoveries (..)
    , getPrologue
    , getDiscoveries
    , SeqAddressMap (..)
    , SharedAddressMap (..)
    )
  where

import Prelude

import Cardano.Wallet.Primitive.AddressDerivation
    ( Depth (..)
    , DerivationType (..)
    , Index (..)
    , KeyFingerprint (..)
    , Role (..)
    )
import Cardano.Wallet.Primitive.AddressDerivation.Shared
    ()
import Cardano.Wallet.Primitive.AddressDerivation.SharedKey
    ( SharedKey (..) )
import Cardano.Wallet.Primitive.Types.Address
    ( Address (..), AddressState (..) )
import Data.Generics.Internal.VL
    ( Iso', iso, withIso )
import Data.Kind
    ( Type )
import Data.Map.Strict
    ( Map )
import Data.Type.Equality
    ( type (==) )
import Fmt
    ( Buildable (..) )

import qualified Cardano.Wallet.Address.Pool as AddressPool
import qualified Cardano.Wallet.Primitive.AddressDiscovery.Random as Rnd
import qualified Cardano.Wallet.Primitive.AddressDiscovery.Sequential as Seq
import qualified Cardano.Wallet.Primitive.AddressDiscovery.Shared as Shared
import qualified Data.Map.Strict as Map

{-------------------------------------------------------------------------------
    AddressBook isomorphism
-------------------------------------------------------------------------------}
-- | FIXME LATER during ADP-1043:
-- Move 'Prologue' and 'Discoveries' closer into address types.
class (Eq (Prologue s), Eq (Discoveries s)) => AddressBookIso s where
    -- | Address information contained in the prologue of the address book,
    -- such as public keys or the address gap.
    data Prologue s :: Type
    -- | Addresses that were collected during discovery on the blockchain.
    data Discoveries s :: Type

    -- | Isomorphism between the address book type 's'
    -- and its two components.
    addressIso :: Iso' s (Prologue s, Discoveries s)

getPrologue :: AddressBookIso s => s -> Prologue s
getPrologue :: s -> Prologue s
getPrologue = Iso s s (Prologue s, Discoveries s) (Prologue s, Discoveries s)
-> ((s -> (Prologue s, Discoveries s))
    -> ((Prologue s, Discoveries s) -> s) -> s -> Prologue s)
-> s
-> Prologue s
forall s t a b r. Iso s t a b -> ((s -> a) -> (b -> t) -> r) -> r
withIso forall s. AddressBookIso s => Iso' s (Prologue s, Discoveries s)
Iso s s (Prologue s, Discoveries s) (Prologue s, Discoveries s)
addressIso (((s -> (Prologue s, Discoveries s))
  -> ((Prologue s, Discoveries s) -> s) -> s -> Prologue s)
 -> s -> Prologue s)
-> ((s -> (Prologue s, Discoveries s))
    -> ((Prologue s, Discoveries s) -> s) -> s -> Prologue s)
-> s
-> Prologue s
forall a b. (a -> b) -> a -> b
$ \s -> (Prologue s, Discoveries s)
from (Prologue s, Discoveries s) -> s
_ -> (Prologue s, Discoveries s) -> Prologue s
forall a b. (a, b) -> a
fst ((Prologue s, Discoveries s) -> Prologue s)
-> (s -> (Prologue s, Discoveries s)) -> s -> Prologue s
forall b c a. (b -> c) -> (a -> b) -> a -> c
. s -> (Prologue s, Discoveries s)
from

getDiscoveries :: AddressBookIso s => s -> Discoveries s
getDiscoveries :: s -> Discoveries s
getDiscoveries = Iso s s (Prologue s, Discoveries s) (Prologue s, Discoveries s)
-> ((s -> (Prologue s, Discoveries s))
    -> ((Prologue s, Discoveries s) -> s) -> s -> Discoveries s)
-> s
-> Discoveries s
forall s t a b r. Iso s t a b -> ((s -> a) -> (b -> t) -> r) -> r
withIso forall s. AddressBookIso s => Iso' s (Prologue s, Discoveries s)
Iso s s (Prologue s, Discoveries s) (Prologue s, Discoveries s)
addressIso (((s -> (Prologue s, Discoveries s))
  -> ((Prologue s, Discoveries s) -> s) -> s -> Discoveries s)
 -> s -> Discoveries s)
-> ((s -> (Prologue s, Discoveries s))
    -> ((Prologue s, Discoveries s) -> s) -> s -> Discoveries s)
-> s
-> Discoveries s
forall a b. (a -> b) -> a -> b
$ \s -> (Prologue s, Discoveries s)
from (Prologue s, Discoveries s) -> s
_ -> (Prologue s, Discoveries s) -> Discoveries s
forall a b. (a, b) -> b
snd ((Prologue s, Discoveries s) -> Discoveries s)
-> (s -> (Prologue s, Discoveries s)) -> s -> Discoveries s
forall b c a. (b -> c) -> (a -> b) -> a -> c
. s -> (Prologue s, Discoveries s)
from

{-------------------------------------------------------------------------------
    Sequential address book
-------------------------------------------------------------------------------}
-- piggy-back on SeqState existing instance, to simulate the same behavior.
instance ( (key == SharedKey) ~ 'False, Eq (Seq.SeqState n key))
    => AddressBookIso (Seq.SeqAnyState n key p)
  where
    data Prologue (Seq.SeqAnyState n key p) = PS (Prologue (Seq.SeqState n key))
    data Discoveries (Seq.SeqAnyState n key p) = DS (Discoveries (Seq.SeqState n key))

    addressIso :: p (Prologue (SeqAnyState n key p),
   Discoveries (SeqAnyState n key p))
  (f (Prologue (SeqAnyState n key p),
      Discoveries (SeqAnyState n key p)))
-> p (SeqAnyState n key p) (f (SeqAnyState n key p))
addressIso = Iso
  (SeqState n key)
  (SeqState n key)
  (Prologue (SeqState n key), Discoveries (SeqState n key))
  (Prologue (SeqState n key), Discoveries (SeqState n key))
-> ((SeqState n key
     -> (Prologue (SeqState n key), Discoveries (SeqState n key)))
    -> ((Prologue (SeqState n key), Discoveries (SeqState n key))
        -> SeqState n key)
    -> p (Prologue (SeqAnyState n key p),
          Discoveries (SeqAnyState n key p))
         (f (Prologue (SeqAnyState n key p),
             Discoveries (SeqAnyState n key p)))
    -> p (SeqAnyState n key p) (f (SeqAnyState n key p)))
-> p (Prologue (SeqAnyState n key p),
      Discoveries (SeqAnyState n key p))
     (f (Prologue (SeqAnyState n key p),
         Discoveries (SeqAnyState n key p)))
-> p (SeqAnyState n key p) (f (SeqAnyState n key p))
forall s t a b r. Iso s t a b -> ((s -> a) -> (b -> t) -> r) -> r
withIso forall s. AddressBookIso s => Iso' s (Prologue s, Discoveries s)
Iso
  (SeqState n key)
  (SeqState n key)
  (Prologue (SeqState n key), Discoveries (SeqState n key))
  (Prologue (SeqState n key), Discoveries (SeqState n key))
addressIso (((SeqState n key
   -> (Prologue (SeqState n key), Discoveries (SeqState n key)))
  -> ((Prologue (SeqState n key), Discoveries (SeqState n key))
      -> SeqState n key)
  -> p (Prologue (SeqAnyState n key p),
        Discoveries (SeqAnyState n key p))
       (f (Prologue (SeqAnyState n key p),
           Discoveries (SeqAnyState n key p)))
  -> p (SeqAnyState n key p) (f (SeqAnyState n key p)))
 -> p (Prologue (SeqAnyState n key p),
       Discoveries (SeqAnyState n key p))
      (f (Prologue (SeqAnyState n key p),
          Discoveries (SeqAnyState n key p)))
 -> p (SeqAnyState n key p) (f (SeqAnyState n key p)))
-> ((SeqState n key
     -> (Prologue (SeqState n key), Discoveries (SeqState n key)))
    -> ((Prologue (SeqState n key), Discoveries (SeqState n key))
        -> SeqState n key)
    -> p (Prologue (SeqAnyState n key p),
          Discoveries (SeqAnyState n key p))
         (f (Prologue (SeqAnyState n key p),
             Discoveries (SeqAnyState n key p)))
    -> p (SeqAnyState n key p) (f (SeqAnyState n key p)))
-> p (Prologue (SeqAnyState n key p),
      Discoveries (SeqAnyState n key p))
     (f (Prologue (SeqAnyState n key p),
         Discoveries (SeqAnyState n key p)))
-> p (SeqAnyState n key p) (f (SeqAnyState n key p))
forall a b. (a -> b) -> a -> b
$ \SeqState n key
-> (Prologue (SeqState n key), Discoveries (SeqState n key))
from (Prologue (SeqState n key), Discoveries (SeqState n key))
-> SeqState n key
to ->
        let from2 :: SeqAnyState n key p
-> (Prologue (SeqAnyState n key p),
    Discoveries (SeqAnyState n key p))
from2 SeqAnyState n key p
st = let (Prologue (SeqState n key)
a,Discoveries (SeqState n key)
b) = SeqState n key
-> (Prologue (SeqState n key), Discoveries (SeqState n key))
from (SeqState n key
 -> (Prologue (SeqState n key), Discoveries (SeqState n key)))
-> SeqState n key
-> (Prologue (SeqState n key), Discoveries (SeqState n key))
forall a b. (a -> b) -> a -> b
$ SeqAnyState n key p -> SeqState n key
forall (network :: NetworkDiscriminant) (key :: Depth -> * -> *)
       (p :: Nat).
SeqAnyState network key p -> SeqState network key
Seq.innerState SeqAnyState n key p
st in (Prologue (SeqState n key) -> Prologue (SeqAnyState n key p)
forall (n :: NetworkDiscriminant) (key :: Depth -> * -> *)
       (p :: Nat).
Prologue (SeqState n key) -> Prologue (SeqAnyState n key p)
PS Prologue (SeqState n key)
a, Discoveries (SeqState n key) -> Discoveries (SeqAnyState n key p)
forall (n :: NetworkDiscriminant) (key :: Depth -> * -> *)
       (p :: Nat).
Discoveries (SeqState n key) -> Discoveries (SeqAnyState n key p)
DS Discoveries (SeqState n key)
b)
            to2 :: (Prologue (SeqAnyState n key p), Discoveries (SeqAnyState n key p))
-> SeqAnyState n key p
to2 (PS a, DS b) = SeqState n key -> SeqAnyState n key p
forall (network :: NetworkDiscriminant) (key :: Depth -> * -> *)
       (p :: Nat).
SeqState network key -> SeqAnyState network key p
Seq.SeqAnyState (SeqState n key -> SeqAnyState n key p)
-> SeqState n key -> SeqAnyState n key p
forall a b. (a -> b) -> a -> b
$ (Prologue (SeqState n key), Discoveries (SeqState n key))
-> SeqState n key
to (Prologue (SeqState n key)
a,Discoveries (SeqState n key)
b)
        in  (SeqAnyState n key p
 -> (Prologue (SeqAnyState n key p),
     Discoveries (SeqAnyState n key p)))
-> ((Prologue (SeqAnyState n key p),
     Discoveries (SeqAnyState n key p))
    -> SeqAnyState n key p)
-> Iso'
     (SeqAnyState n key p)
     (Prologue (SeqAnyState n key p), Discoveries (SeqAnyState n key p))
forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
iso SeqAnyState n key p
-> (Prologue (SeqAnyState n key p),
    Discoveries (SeqAnyState n key p))
from2 (Prologue (SeqAnyState n key p), Discoveries (SeqAnyState n key p))
-> SeqAnyState n key p
to2

instance Eq (Seq.SeqState n k) => Eq (Prologue (Seq.SeqAnyState n k p)) where
    (PS a) == :: Prologue (SeqAnyState n k p)
-> Prologue (SeqAnyState n k p) -> Bool
== (PS b) = Prologue (SeqState n k)
a Prologue (SeqState n k) -> Prologue (SeqState n k) -> Bool
forall a. Eq a => a -> a -> Bool
== Prologue (SeqState n k)
b

instance Eq (Seq.SeqState n k) => Eq (Discoveries (Seq.SeqAnyState n k p)) where
    (DS a) == :: Discoveries (SeqAnyState n k p)
-> Discoveries (SeqAnyState n k p) -> Bool
== (DS b) = Discoveries (SeqState n k)
a Discoveries (SeqState n k) -> Discoveries (SeqState n k) -> Bool
forall a. Eq a => a -> a -> Bool
== Discoveries (SeqState n k)
b

-- | Isomorphism for sequential address book.
instance ( (key == SharedKey) ~ 'False, Eq (Seq.SeqState n key) )
    => AddressBookIso (Seq.SeqState n key)
  where
    data Prologue (Seq.SeqState n key)
        = SeqPrologue (Seq.SeqState n key)
        -- Trick: We keep the type, but we empty the discovered addresses
    data Discoveries (Seq.SeqState n key)
        = SeqDiscoveries
            (SeqAddressMap 'UtxoInternal key)
            (SeqAddressMap 'UtxoExternal key)

    addressIso :: p (Prologue (SeqState n key), Discoveries (SeqState n key))
  (f (Prologue (SeqState n key), Discoveries (SeqState n key)))
-> p (SeqState n key) (f (SeqState n key))
addressIso = (SeqState n key
 -> (Prologue (SeqState n key), Discoveries (SeqState n key)))
-> ((Prologue (SeqState n key), Discoveries (SeqState n key))
    -> SeqState n key)
-> Iso'
     (SeqState n key)
     (Prologue (SeqState n key), Discoveries (SeqState n key))
forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
iso SeqState n key
-> (Prologue (SeqState n key), Discoveries (SeqState n key))
forall (n :: NetworkDiscriminant) (k :: Depth -> * -> *)
       (n :: NetworkDiscriminant) (n :: NetworkDiscriminant).
SeqState n k
-> (Prologue (SeqState n k), Discoveries (SeqState n k))
from (Prologue (SeqState n key), Discoveries (SeqState n key))
-> SeqState n key
forall (n :: NetworkDiscriminant) (k :: Depth -> * -> *)
       (n :: NetworkDiscriminant) (n :: NetworkDiscriminant).
(Prologue (SeqState n k), Discoveries (SeqState n k))
-> SeqState n k
to
      where
        from :: SeqState n k
-> (Prologue (SeqState n k), Discoveries (SeqState n k))
from (Seq.SeqState SeqAddressPool 'UtxoInternal k
int SeqAddressPool 'UtxoExternal k
ext PendingIxs 'AddressK
a k 'AccountK XPub
b Maybe (k 'PolicyK XPub)
c k 'AddressK XPub
d DerivationPrefix
e) =
            let int0 :: SeqAddressPool 'UtxoInternal k
int0 = SeqAddressPool 'UtxoInternal k -> SeqAddressPool 'UtxoInternal k
forall (c :: Role) (k :: Depth -> * -> *).
SeqAddressPool c k -> SeqAddressPool c k
clear SeqAddressPool 'UtxoInternal k
int
                ext0 :: SeqAddressPool 'UtxoExternal k
ext0 = SeqAddressPool 'UtxoExternal k -> SeqAddressPool 'UtxoExternal k
forall (c :: Role) (k :: Depth -> * -> *).
SeqAddressPool c k -> SeqAddressPool c k
clear SeqAddressPool 'UtxoExternal k
ext
            in  ( SeqState n k -> Prologue (SeqState n k)
forall (n :: NetworkDiscriminant) (key :: Depth -> * -> *).
SeqState n key -> Prologue (SeqState n key)
SeqPrologue (SeqState n k -> Prologue (SeqState n k))
-> SeqState n k -> Prologue (SeqState n k)
forall a b. (a -> b) -> a -> b
$ SeqAddressPool 'UtxoInternal k
-> SeqAddressPool 'UtxoExternal k
-> PendingIxs 'AddressK
-> k 'AccountK XPub
-> Maybe (k 'PolicyK XPub)
-> k 'AddressK XPub
-> DerivationPrefix
-> SeqState n k
forall (n :: NetworkDiscriminant) (k :: Depth -> * -> *).
SeqAddressPool 'UtxoInternal k
-> SeqAddressPool 'UtxoExternal k
-> PendingIxs 'AddressK
-> k 'AccountK XPub
-> Maybe (k 'PolicyK XPub)
-> k 'AddressK XPub
-> DerivationPrefix
-> SeqState n k
Seq.SeqState SeqAddressPool 'UtxoInternal k
int0 SeqAddressPool 'UtxoExternal k
ext0 PendingIxs 'AddressK
a k 'AccountK XPub
b Maybe (k 'PolicyK XPub)
c k 'AddressK XPub
d DerivationPrefix
e
                , SeqAddressMap 'UtxoInternal k
-> SeqAddressMap 'UtxoExternal k -> Discoveries (SeqState n k)
forall (n :: NetworkDiscriminant) (key :: Depth -> * -> *).
SeqAddressMap 'UtxoInternal key
-> SeqAddressMap 'UtxoExternal key -> Discoveries (SeqState n key)
SeqDiscoveries (SeqAddressPool 'UtxoInternal k -> SeqAddressMap 'UtxoInternal k
forall (c :: Role) (k :: Depth -> * -> *).
SeqAddressPool c k -> SeqAddressMap c k
addresses SeqAddressPool 'UtxoInternal k
int) (SeqAddressPool 'UtxoExternal k -> SeqAddressMap 'UtxoExternal k
forall (c :: Role) (k :: Depth -> * -> *).
SeqAddressPool c k -> SeqAddressMap c k
addresses SeqAddressPool 'UtxoExternal k
ext)
                )
        to :: (Prologue (SeqState n k), Discoveries (SeqState n k))
-> SeqState n k
to  ( SeqPrologue (Seq.SeqState int0 ext0 a b c d e)
            , SeqDiscoveries ints exts
            )
            = SeqAddressPool 'UtxoInternal k
-> SeqAddressPool 'UtxoExternal k
-> PendingIxs 'AddressK
-> k 'AccountK XPub
-> Maybe (k 'PolicyK XPub)
-> k 'AddressK XPub
-> DerivationPrefix
-> SeqState n k
forall (n :: NetworkDiscriminant) (k :: Depth -> * -> *).
SeqAddressPool 'UtxoInternal k
-> SeqAddressPool 'UtxoExternal k
-> PendingIxs 'AddressK
-> k 'AccountK XPub
-> Maybe (k 'PolicyK XPub)
-> k 'AddressK XPub
-> DerivationPrefix
-> SeqState n k
Seq.SeqState
                (SeqAddressPool 'UtxoInternal k
-> SeqAddressMap 'UtxoInternal k -> SeqAddressPool 'UtxoInternal k
forall (c :: Role) (k :: Depth -> * -> *).
SeqAddressPool c k -> SeqAddressMap c k -> SeqAddressPool c k
loadUnsafe SeqAddressPool 'UtxoInternal k
int0 SeqAddressMap 'UtxoInternal k
ints) (SeqAddressPool 'UtxoExternal k
-> SeqAddressMap 'UtxoExternal k -> SeqAddressPool 'UtxoExternal k
forall (c :: Role) (k :: Depth -> * -> *).
SeqAddressPool c k -> SeqAddressMap c k -> SeqAddressPool c k
loadUnsafe SeqAddressPool 'UtxoExternal k
ext0 SeqAddressMap 'UtxoExternal k
exts) PendingIxs 'AddressK
a k 'AccountK XPub
b Maybe (k 'PolicyK XPub)
c k 'AddressK XPub
d DerivationPrefix
e

-- | Address data from sequential address pool.
-- The phantom type parameter @c@ prevents mixing up
-- the internal with the external pool.
newtype SeqAddressMap (c :: Role) (key :: Depth -> Type -> Type) =
    SeqAddressMap
        ( Map
            (KeyFingerprint "payment" key)
            (Index 'Soft 'AddressK, AddressState)
        )
    deriving SeqAddressMap c key -> SeqAddressMap c key -> Bool
(SeqAddressMap c key -> SeqAddressMap c key -> Bool)
-> (SeqAddressMap c key -> SeqAddressMap c key -> Bool)
-> Eq (SeqAddressMap c key)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall (c :: Role) (key :: Depth -> * -> *).
SeqAddressMap c key -> SeqAddressMap c key -> Bool
/= :: SeqAddressMap c key -> SeqAddressMap c key -> Bool
$c/= :: forall (c :: Role) (key :: Depth -> * -> *).
SeqAddressMap c key -> SeqAddressMap c key -> Bool
== :: SeqAddressMap c key -> SeqAddressMap c key -> Bool
$c== :: forall (c :: Role) (key :: Depth -> * -> *).
SeqAddressMap c key -> SeqAddressMap c key -> Bool
Eq

clear :: Seq.SeqAddressPool c k -> Seq.SeqAddressPool c k
clear :: SeqAddressPool c k -> SeqAddressPool c k
clear = Pool (KeyFingerprint "payment" k) (Index 'Soft 'AddressK)
-> SeqAddressPool c k
forall (c :: Role) (key :: Depth -> * -> *).
Pool (KeyFingerprint "payment" key) (Index 'Soft 'AddressK)
-> SeqAddressPool c key
Seq.SeqAddressPool (Pool (KeyFingerprint "payment" k) (Index 'Soft 'AddressK)
 -> SeqAddressPool c k)
-> (SeqAddressPool c k
    -> Pool (KeyFingerprint "payment" k) (Index 'Soft 'AddressK))
-> SeqAddressPool c k
-> SeqAddressPool c k
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pool (KeyFingerprint "payment" k) (Index 'Soft 'AddressK)
-> Pool (KeyFingerprint "payment" k) (Index 'Soft 'AddressK)
forall addr ix. (Ord addr, Enum ix) => Pool addr ix -> Pool addr ix
AddressPool.clear (Pool (KeyFingerprint "payment" k) (Index 'Soft 'AddressK)
 -> Pool (KeyFingerprint "payment" k) (Index 'Soft 'AddressK))
-> (SeqAddressPool c k
    -> Pool (KeyFingerprint "payment" k) (Index 'Soft 'AddressK))
-> SeqAddressPool c k
-> Pool (KeyFingerprint "payment" k) (Index 'Soft 'AddressK)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SeqAddressPool c k
-> Pool (KeyFingerprint "payment" k) (Index 'Soft 'AddressK)
forall (c :: Role) (key :: Depth -> * -> *).
SeqAddressPool c key
-> Pool (KeyFingerprint "payment" key) (Index 'Soft 'AddressK)
Seq.getPool

addresses :: Seq.SeqAddressPool c k -> SeqAddressMap c k
addresses :: SeqAddressPool c k -> SeqAddressMap c k
addresses = Map
  (KeyFingerprint "payment" k) (Index 'Soft 'AddressK, AddressState)
-> SeqAddressMap c k
forall (c :: Role) (key :: Depth -> * -> *).
Map
  (KeyFingerprint "payment" key)
  (Index 'Soft 'AddressK, AddressState)
-> SeqAddressMap c key
SeqAddressMap (Map
   (KeyFingerprint "payment" k) (Index 'Soft 'AddressK, AddressState)
 -> SeqAddressMap c k)
-> (SeqAddressPool c k
    -> Map
         (KeyFingerprint "payment" k) (Index 'Soft 'AddressK, AddressState))
-> SeqAddressPool c k
-> SeqAddressMap c k
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pool (KeyFingerprint "payment" k) (Index 'Soft 'AddressK)
-> Map
     (KeyFingerprint "payment" k) (Index 'Soft 'AddressK, AddressState)
forall addr ix. Pool addr ix -> Map addr (ix, AddressState)
AddressPool.addresses (Pool (KeyFingerprint "payment" k) (Index 'Soft 'AddressK)
 -> Map
      (KeyFingerprint "payment" k) (Index 'Soft 'AddressK, AddressState))
-> (SeqAddressPool c k
    -> Pool (KeyFingerprint "payment" k) (Index 'Soft 'AddressK))
-> SeqAddressPool c k
-> Map
     (KeyFingerprint "payment" k) (Index 'Soft 'AddressK, AddressState)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SeqAddressPool c k
-> Pool (KeyFingerprint "payment" k) (Index 'Soft 'AddressK)
forall (c :: Role) (key :: Depth -> * -> *).
SeqAddressPool c key
-> Pool (KeyFingerprint "payment" key) (Index 'Soft 'AddressK)
Seq.getPool

loadUnsafe
    :: Seq.SeqAddressPool c k
    -> SeqAddressMap c k -> Seq.SeqAddressPool c k
loadUnsafe :: SeqAddressPool c k -> SeqAddressMap c k -> SeqAddressPool c k
loadUnsafe (Seq.SeqAddressPool Pool (KeyFingerprint "payment" k) (Index 'Soft 'AddressK)
pool0) (SeqAddressMap Map
  (KeyFingerprint "payment" k) (Index 'Soft 'AddressK, AddressState)
addrs) =
    Pool (KeyFingerprint "payment" k) (Index 'Soft 'AddressK)
-> SeqAddressPool c k
forall (c :: Role) (key :: Depth -> * -> *).
Pool (KeyFingerprint "payment" key) (Index 'Soft 'AddressK)
-> SeqAddressPool c key
Seq.SeqAddressPool (Pool (KeyFingerprint "payment" k) (Index 'Soft 'AddressK)
 -> SeqAddressPool c k)
-> Pool (KeyFingerprint "payment" k) (Index 'Soft 'AddressK)
-> SeqAddressPool c k
forall a b. (a -> b) -> a -> b
$ Pool (KeyFingerprint "payment" k) (Index 'Soft 'AddressK)
-> Map
     (KeyFingerprint "payment" k) (Index 'Soft 'AddressK, AddressState)
-> Pool (KeyFingerprint "payment" k) (Index 'Soft 'AddressK)
forall addr ix.
Pool addr ix -> Map addr (ix, AddressState) -> Pool addr ix
AddressPool.loadUnsafe Pool (KeyFingerprint "payment" k) (Index 'Soft 'AddressK)
pool0 Map
  (KeyFingerprint "payment" k) (Index 'Soft 'AddressK, AddressState)
addrs

instance Buildable (Prologue (Seq.SeqState n k)) where
    build :: Prologue (SeqState n k) -> Builder
build (SeqPrologue st) = Builder
"Prologue of " Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> SeqState n k -> Builder
forall p. Buildable p => p -> Builder
build SeqState n k
st

instance Eq (Seq.SeqState n k) => Eq (Prologue (Seq.SeqState n k)) where
    SeqPrologue a == :: Prologue (SeqState n k) -> Prologue (SeqState n k) -> Bool
== SeqPrologue b = SeqState n k
a SeqState n k -> SeqState n k -> Bool
forall a. Eq a => a -> a -> Bool
== SeqState n k
b

instance Eq (Seq.SeqState n k) => Eq (Discoveries (Seq.SeqState n k)) where
    (SeqDiscoveries a x) == :: Discoveries (SeqState n k) -> Discoveries (SeqState n k) -> Bool
== (SeqDiscoveries b y) = SeqAddressMap 'UtxoInternal k
a SeqAddressMap 'UtxoInternal k
-> SeqAddressMap 'UtxoInternal k -> Bool
forall a. Eq a => a -> a -> Bool
== SeqAddressMap 'UtxoInternal k
b Bool -> Bool -> Bool
&& SeqAddressMap 'UtxoExternal k
x SeqAddressMap 'UtxoExternal k
-> SeqAddressMap 'UtxoExternal k -> Bool
forall a. Eq a => a -> a -> Bool
== SeqAddressMap 'UtxoExternal k
y

{-------------------------------------------------------------------------------
    Shared key address book
-------------------------------------------------------------------------------}

newtype SharedAddressMap (c :: Role) (key :: Depth -> Type -> Type) =
    SharedAddressMap
        ( Map
            (KeyFingerprint "payment" key)
            (Index 'Soft 'ScriptK, AddressState)
        )
    deriving SharedAddressMap c key -> SharedAddressMap c key -> Bool
(SharedAddressMap c key -> SharedAddressMap c key -> Bool)
-> (SharedAddressMap c key -> SharedAddressMap c key -> Bool)
-> Eq (SharedAddressMap c key)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall (c :: Role) (key :: Depth -> * -> *).
SharedAddressMap c key -> SharedAddressMap c key -> Bool
/= :: SharedAddressMap c key -> SharedAddressMap c key -> Bool
$c/= :: forall (c :: Role) (key :: Depth -> * -> *).
SharedAddressMap c key -> SharedAddressMap c key -> Bool
== :: SharedAddressMap c key -> SharedAddressMap c key -> Bool
$c== :: forall (c :: Role) (key :: Depth -> * -> *).
SharedAddressMap c key -> SharedAddressMap c key -> Bool
Eq


-- | Isomorphism for multi-sig address book.
instance ( key ~ SharedKey ) => AddressBookIso (Shared.SharedState n key)
  where
    data Prologue (Shared.SharedState n key)
        = SharedPrologue (Shared.SharedState n key)
        -- Trick: We keep the type, but we empty the discovered addresses
    data Discoveries (Shared.SharedState n key)
        = SharedDiscoveries
            (SharedAddressMap 'UtxoExternal key)
            (SharedAddressMap 'UtxoInternal key)

    addressIso :: p (Prologue (SharedState n key), Discoveries (SharedState n key))
  (f (Prologue (SharedState n key), Discoveries (SharedState n key)))
-> p (SharedState n key) (f (SharedState n key))
addressIso = (SharedState n key
 -> (Prologue (SharedState n key), Discoveries (SharedState n key)))
-> ((Prologue (SharedState n key), Discoveries (SharedState n key))
    -> SharedState n key)
-> Iso'
     (SharedState n key)
     (Prologue (SharedState n key), Discoveries (SharedState n key))
forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
iso SharedState n key
-> (Prologue (SharedState n key), Discoveries (SharedState n key))
forall (n :: NetworkDiscriminant) (key :: Depth -> * -> *)
       (n :: NetworkDiscriminant).
SharedState n key
-> (Prologue (SharedState n key), Discoveries (SharedState n key))
from (Prologue (SharedState n key), Discoveries (SharedState n key))
-> SharedState n key
forall (n :: NetworkDiscriminant) (key :: Depth -> * -> *)
       (n :: NetworkDiscriminant).
(Prologue (SharedState n key), Discoveries (SharedState n key))
-> SharedState n key
to
      where
        from :: SharedState n key
-> (Prologue (SharedState n key), Discoveries (SharedState n key))
from SharedState n key
st = case SharedState n key -> Readiness (SharedAddressPools key)
forall (n :: NetworkDiscriminant) (k :: Depth -> * -> *).
SharedState n k -> Readiness (SharedAddressPools k)
Shared.ready SharedState n key
st of
            Readiness (SharedAddressPools key)
Shared.Pending ->
                ( SharedState n key -> Prologue (SharedState n key)
forall (n :: NetworkDiscriminant) (key :: Depth -> * -> *).
SharedState n key -> Prologue (SharedState n key)
SharedPrologue SharedState n key
st
                , SharedAddressMap 'UtxoExternal key
-> SharedAddressMap 'UtxoInternal key
-> Discoveries (SharedState n key)
forall (n :: NetworkDiscriminant) (key :: Depth -> * -> *).
SharedAddressMap 'UtxoExternal key
-> SharedAddressMap 'UtxoInternal key
-> Discoveries (SharedState n key)
SharedDiscoveries (Map
  (KeyFingerprint "payment" key) (Index 'Soft 'ScriptK, AddressState)
-> SharedAddressMap 'UtxoExternal key
forall (c :: Role) (key :: Depth -> * -> *).
Map
  (KeyFingerprint "payment" key) (Index 'Soft 'ScriptK, AddressState)
-> SharedAddressMap c key
SharedAddressMap Map
  (KeyFingerprint "payment" key) (Index 'Soft 'ScriptK, AddressState)
forall k a. Map k a
Map.empty) (Map
  (KeyFingerprint "payment" key) (Index 'Soft 'ScriptK, AddressState)
-> SharedAddressMap 'UtxoInternal key
forall (c :: Role) (key :: Depth -> * -> *).
Map
  (KeyFingerprint "payment" key) (Index 'Soft 'ScriptK, AddressState)
-> SharedAddressMap c key
SharedAddressMap Map
  (KeyFingerprint "payment" key) (Index 'Soft 'ScriptK, AddressState)
forall k a. Map k a
Map.empty))
            Shared.Active (Shared.SharedAddressPools SharedAddressPool 'UtxoExternal key
extPool SharedAddressPool 'UtxoInternal key
intPool PendingIxs 'ScriptK
pending) ->
                let extPool0 :: SharedAddressPool 'UtxoExternal key
extPool0 = SharedAddressPool 'UtxoExternal key
-> SharedAddressPool 'UtxoExternal key
forall (c :: Role) (k :: Depth -> * -> *).
SharedAddressPool c k -> SharedAddressPool c k
clearShared SharedAddressPool 'UtxoExternal key
extPool
                    intPool0 :: SharedAddressPool 'UtxoInternal key
intPool0 = SharedAddressPool 'UtxoInternal key
-> SharedAddressPool 'UtxoInternal key
forall (c :: Role) (k :: Depth -> * -> *).
SharedAddressPool c k -> SharedAddressPool c k
clearShared SharedAddressPool 'UtxoInternal key
intPool
                    pools0 :: SharedAddressPools key
pools0 = SharedAddressPool 'UtxoExternal key
-> SharedAddressPool 'UtxoInternal key
-> PendingIxs 'ScriptK
-> SharedAddressPools key
forall (key :: Depth -> * -> *).
SharedAddressPool 'UtxoExternal key
-> SharedAddressPool 'UtxoInternal key
-> PendingIxs 'ScriptK
-> SharedAddressPools key
Shared.SharedAddressPools SharedAddressPool 'UtxoExternal key
extPool0 SharedAddressPool 'UtxoInternal key
intPool0 PendingIxs 'ScriptK
pending
                in  ( SharedState n key -> Prologue (SharedState n key)
forall (n :: NetworkDiscriminant) (key :: Depth -> * -> *).
SharedState n key -> Prologue (SharedState n key)
SharedPrologue SharedState n key
st{ ready :: Readiness (SharedAddressPools key)
Shared.ready = SharedAddressPools key -> Readiness (SharedAddressPools key)
forall a. a -> Readiness a
Shared.Active SharedAddressPools key
pools0 }
                    , SharedAddressMap 'UtxoExternal key
-> SharedAddressMap 'UtxoInternal key
-> Discoveries (SharedState n key)
forall (n :: NetworkDiscriminant) (key :: Depth -> * -> *).
SharedAddressMap 'UtxoExternal key
-> SharedAddressMap 'UtxoInternal key
-> Discoveries (SharedState n key)
SharedDiscoveries
                        (SharedAddressPool 'UtxoExternal key
-> SharedAddressMap 'UtxoExternal key
forall (c :: Role) (k :: Depth -> * -> *).
SharedAddressPool c k -> SharedAddressMap c k
addressesShared SharedAddressPool 'UtxoExternal key
extPool)
                        (SharedAddressPool 'UtxoInternal key
-> SharedAddressMap 'UtxoInternal key
forall (c :: Role) (k :: Depth -> * -> *).
SharedAddressPool c k -> SharedAddressMap c k
addressesShared SharedAddressPool 'UtxoInternal key
intPool)
                    )
        to :: (Prologue (SharedState n key), Discoveries (SharedState n key))
-> SharedState n key
to (SharedPrologue st, SharedDiscoveries exts ints)
          = case SharedState n key -> Readiness (SharedAddressPools key)
forall (n :: NetworkDiscriminant) (k :: Depth -> * -> *).
SharedState n k -> Readiness (SharedAddressPools k)
Shared.ready SharedState n key
st of
            Readiness (SharedAddressPools key)
Shared.Pending -> SharedState n key
st
            Shared.Active (Shared.SharedAddressPools SharedAddressPool 'UtxoExternal key
extPool0 SharedAddressPool 'UtxoInternal key
intPool0 PendingIxs 'ScriptK
pending0) ->
                let extPool :: SharedAddressPool 'UtxoExternal key
extPool = SharedAddressPool 'UtxoExternal key
-> SharedAddressMap 'UtxoExternal key
-> SharedAddressPool 'UtxoExternal key
forall (c :: Role) (k :: Depth -> * -> *).
SharedAddressPool c k
-> SharedAddressMap c k -> SharedAddressPool c k
loadUnsafeShared SharedAddressPool 'UtxoExternal key
extPool0 SharedAddressMap 'UtxoExternal key
exts
                    intPool :: SharedAddressPool 'UtxoInternal key
intPool = SharedAddressPool 'UtxoInternal key
-> SharedAddressMap 'UtxoInternal key
-> SharedAddressPool 'UtxoInternal key
forall (c :: Role) (k :: Depth -> * -> *).
SharedAddressPool c k
-> SharedAddressMap c k -> SharedAddressPool c k
loadUnsafeShared SharedAddressPool 'UtxoInternal key
intPool0 SharedAddressMap 'UtxoInternal key
ints
                    pools :: SharedAddressPools key
pools = SharedAddressPool 'UtxoExternal key
-> SharedAddressPool 'UtxoInternal key
-> PendingIxs 'ScriptK
-> SharedAddressPools key
forall (key :: Depth -> * -> *).
SharedAddressPool 'UtxoExternal key
-> SharedAddressPool 'UtxoInternal key
-> PendingIxs 'ScriptK
-> SharedAddressPools key
Shared.SharedAddressPools SharedAddressPool 'UtxoExternal key
extPool SharedAddressPool 'UtxoInternal key
intPool PendingIxs 'ScriptK
pending0
                in  SharedState n key
st{ ready :: Readiness (SharedAddressPools key)
Shared.ready = SharedAddressPools key -> Readiness (SharedAddressPools key)
forall a. a -> Readiness a
Shared.Active SharedAddressPools key
pools }

clearShared :: Shared.SharedAddressPool c k -> Shared.SharedAddressPool c k
clearShared :: SharedAddressPool c k -> SharedAddressPool c k
clearShared = Pool (KeyFingerprint "payment" k) (Index 'Soft 'ScriptK)
-> SharedAddressPool c k
forall (c :: Role) (key :: Depth -> * -> *).
Pool (KeyFingerprint "payment" key) (Index 'Soft 'ScriptK)
-> SharedAddressPool c key
Shared.SharedAddressPool (Pool (KeyFingerprint "payment" k) (Index 'Soft 'ScriptK)
 -> SharedAddressPool c k)
-> (SharedAddressPool c k
    -> Pool (KeyFingerprint "payment" k) (Index 'Soft 'ScriptK))
-> SharedAddressPool c k
-> SharedAddressPool c k
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pool (KeyFingerprint "payment" k) (Index 'Soft 'ScriptK)
-> Pool (KeyFingerprint "payment" k) (Index 'Soft 'ScriptK)
forall addr ix. (Ord addr, Enum ix) => Pool addr ix -> Pool addr ix
AddressPool.clear (Pool (KeyFingerprint "payment" k) (Index 'Soft 'ScriptK)
 -> Pool (KeyFingerprint "payment" k) (Index 'Soft 'ScriptK))
-> (SharedAddressPool c k
    -> Pool (KeyFingerprint "payment" k) (Index 'Soft 'ScriptK))
-> SharedAddressPool c k
-> Pool (KeyFingerprint "payment" k) (Index 'Soft 'ScriptK)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SharedAddressPool c k
-> Pool (KeyFingerprint "payment" k) (Index 'Soft 'ScriptK)
forall (c :: Role) (key :: Depth -> * -> *).
SharedAddressPool c key
-> Pool (KeyFingerprint "payment" key) (Index 'Soft 'ScriptK)
Shared.getPool

addressesShared :: Shared.SharedAddressPool c k -> SharedAddressMap c k
addressesShared :: SharedAddressPool c k -> SharedAddressMap c k
addressesShared = Map
  (KeyFingerprint "payment" k) (Index 'Soft 'ScriptK, AddressState)
-> SharedAddressMap c k
forall (c :: Role) (key :: Depth -> * -> *).
Map
  (KeyFingerprint "payment" key) (Index 'Soft 'ScriptK, AddressState)
-> SharedAddressMap c key
SharedAddressMap (Map
   (KeyFingerprint "payment" k) (Index 'Soft 'ScriptK, AddressState)
 -> SharedAddressMap c k)
-> (SharedAddressPool c k
    -> Map
         (KeyFingerprint "payment" k) (Index 'Soft 'ScriptK, AddressState))
-> SharedAddressPool c k
-> SharedAddressMap c k
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pool (KeyFingerprint "payment" k) (Index 'Soft 'ScriptK)
-> Map
     (KeyFingerprint "payment" k) (Index 'Soft 'ScriptK, AddressState)
forall addr ix. Pool addr ix -> Map addr (ix, AddressState)
AddressPool.addresses (Pool (KeyFingerprint "payment" k) (Index 'Soft 'ScriptK)
 -> Map
      (KeyFingerprint "payment" k) (Index 'Soft 'ScriptK, AddressState))
-> (SharedAddressPool c k
    -> Pool (KeyFingerprint "payment" k) (Index 'Soft 'ScriptK))
-> SharedAddressPool c k
-> Map
     (KeyFingerprint "payment" k) (Index 'Soft 'ScriptK, AddressState)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SharedAddressPool c k
-> Pool (KeyFingerprint "payment" k) (Index 'Soft 'ScriptK)
forall (c :: Role) (key :: Depth -> * -> *).
SharedAddressPool c key
-> Pool (KeyFingerprint "payment" key) (Index 'Soft 'ScriptK)
Shared.getPool

loadUnsafeShared
    :: Shared.SharedAddressPool c k
    -> SharedAddressMap c k
    -> Shared.SharedAddressPool c k
loadUnsafeShared :: SharedAddressPool c k
-> SharedAddressMap c k -> SharedAddressPool c k
loadUnsafeShared (Shared.SharedAddressPool Pool (KeyFingerprint "payment" k) (Index 'Soft 'ScriptK)
pool0) (SharedAddressMap Map
  (KeyFingerprint "payment" k) (Index 'Soft 'ScriptK, AddressState)
addrs) =
    Pool (KeyFingerprint "payment" k) (Index 'Soft 'ScriptK)
-> SharedAddressPool c k
forall (c :: Role) (key :: Depth -> * -> *).
Pool (KeyFingerprint "payment" key) (Index 'Soft 'ScriptK)
-> SharedAddressPool c key
Shared.SharedAddressPool (Pool (KeyFingerprint "payment" k) (Index 'Soft 'ScriptK)
 -> SharedAddressPool c k)
-> Pool (KeyFingerprint "payment" k) (Index 'Soft 'ScriptK)
-> SharedAddressPool c k
forall a b. (a -> b) -> a -> b
$ Pool (KeyFingerprint "payment" k) (Index 'Soft 'ScriptK)
-> Map
     (KeyFingerprint "payment" k) (Index 'Soft 'ScriptK, AddressState)
-> Pool (KeyFingerprint "payment" k) (Index 'Soft 'ScriptK)
forall addr ix.
Pool addr ix -> Map addr (ix, AddressState) -> Pool addr ix
AddressPool.loadUnsafe Pool (KeyFingerprint "payment" k) (Index 'Soft 'ScriptK)
pool0 Map
  (KeyFingerprint "payment" k) (Index 'Soft 'ScriptK, AddressState)
addrs

instance ( key ~ SharedKey )
    => Buildable (Prologue (Shared.SharedState n key))
  where
    build :: Prologue (SharedState n key) -> Builder
build (SharedPrologue st) = Builder
"Prologue of " Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> SharedState n key -> Builder
forall p. Buildable p => p -> Builder
build SharedState n key
st

instance ( key ~ SharedKey ) => Eq (Prologue (Shared.SharedState n key)) where
    SharedPrologue a == :: Prologue (SharedState n key)
-> Prologue (SharedState n key) -> Bool
== SharedPrologue b = SharedState n key
a SharedState n key -> SharedState n key -> Bool
forall a. Eq a => a -> a -> Bool
== SharedState n key
b

instance ( key ~ SharedKey ) => Eq (Discoveries (Shared.SharedState n key)) where
    SharedDiscoveries ext1 int1 == :: Discoveries (SharedState n key)
-> Discoveries (SharedState n key) -> Bool
== SharedDiscoveries ext2 int2 =
        SharedAddressMap 'UtxoExternal key
ext1 SharedAddressMap 'UtxoExternal key
-> SharedAddressMap 'UtxoExternal key -> Bool
forall a. Eq a => a -> a -> Bool
== SharedAddressMap 'UtxoExternal key
ext2 Bool -> Bool -> Bool
&& SharedAddressMap 'UtxoInternal key
int1 SharedAddressMap 'UtxoInternal key
-> SharedAddressMap 'UtxoInternal key -> Bool
forall a. Eq a => a -> a -> Bool
== SharedAddressMap 'UtxoInternal key
int2

{-------------------------------------------------------------------------------
    HD Random address book
-------------------------------------------------------------------------------}
-- piggy-back on SeqState existing instance, to simulate the same behavior.
instance AddressBookIso (Rnd.RndAnyState n p)
  where
    data Prologue (Rnd.RndAnyState n p) = PR (Prologue (Rnd.RndState n))
    data Discoveries (Rnd.RndAnyState n p) = DR (Discoveries (Rnd.RndState n))

    addressIso :: p (Prologue (RndAnyState n p), Discoveries (RndAnyState n p))
  (f (Prologue (RndAnyState n p), Discoveries (RndAnyState n p)))
-> p (RndAnyState n p) (f (RndAnyState n p))
addressIso = Iso
  (RndState n)
  (RndState n)
  (Prologue (RndState n), Discoveries (RndState n))
  (Prologue (RndState n), Discoveries (RndState n))
-> ((RndState n
     -> (Prologue (RndState n), Discoveries (RndState n)))
    -> ((Prologue (RndState n), Discoveries (RndState n))
        -> RndState n)
    -> p (Prologue (RndAnyState n p), Discoveries (RndAnyState n p))
         (f (Prologue (RndAnyState n p), Discoveries (RndAnyState n p)))
    -> p (RndAnyState n p) (f (RndAnyState n p)))
-> p (Prologue (RndAnyState n p), Discoveries (RndAnyState n p))
     (f (Prologue (RndAnyState n p), Discoveries (RndAnyState n p)))
-> p (RndAnyState n p) (f (RndAnyState n p))
forall s t a b r. Iso s t a b -> ((s -> a) -> (b -> t) -> r) -> r
withIso forall s. AddressBookIso s => Iso' s (Prologue s, Discoveries s)
Iso
  (RndState n)
  (RndState n)
  (Prologue (RndState n), Discoveries (RndState n))
  (Prologue (RndState n), Discoveries (RndState n))
addressIso (((RndState n -> (Prologue (RndState n), Discoveries (RndState n)))
  -> ((Prologue (RndState n), Discoveries (RndState n))
      -> RndState n)
  -> p (Prologue (RndAnyState n p), Discoveries (RndAnyState n p))
       (f (Prologue (RndAnyState n p), Discoveries (RndAnyState n p)))
  -> p (RndAnyState n p) (f (RndAnyState n p)))
 -> p (Prologue (RndAnyState n p), Discoveries (RndAnyState n p))
      (f (Prologue (RndAnyState n p), Discoveries (RndAnyState n p)))
 -> p (RndAnyState n p) (f (RndAnyState n p)))
-> ((RndState n
     -> (Prologue (RndState n), Discoveries (RndState n)))
    -> ((Prologue (RndState n), Discoveries (RndState n))
        -> RndState n)
    -> p (Prologue (RndAnyState n p), Discoveries (RndAnyState n p))
         (f (Prologue (RndAnyState n p), Discoveries (RndAnyState n p)))
    -> p (RndAnyState n p) (f (RndAnyState n p)))
-> p (Prologue (RndAnyState n p), Discoveries (RndAnyState n p))
     (f (Prologue (RndAnyState n p), Discoveries (RndAnyState n p)))
-> p (RndAnyState n p) (f (RndAnyState n p))
forall a b. (a -> b) -> a -> b
$ \RndState n -> (Prologue (RndState n), Discoveries (RndState n))
from (Prologue (RndState n), Discoveries (RndState n)) -> RndState n
to ->
        let from2 :: RndAnyState n p
-> (Prologue (RndAnyState n p), Discoveries (RndAnyState n p))
from2 RndAnyState n p
st = let (Prologue (RndState n)
a,Discoveries (RndState n)
b) = RndState n -> (Prologue (RndState n), Discoveries (RndState n))
from (RndState n -> (Prologue (RndState n), Discoveries (RndState n)))
-> RndState n -> (Prologue (RndState n), Discoveries (RndState n))
forall a b. (a -> b) -> a -> b
$ RndAnyState n p -> RndState n
forall (network :: NetworkDiscriminant) (p :: Nat).
RndAnyState network p -> RndState network
Rnd.innerState RndAnyState n p
st in (Prologue (RndState n) -> Prologue (RndAnyState n p)
forall (n :: NetworkDiscriminant) (p :: Nat).
Prologue (RndState n) -> Prologue (RndAnyState n p)
PR Prologue (RndState n)
a, Discoveries (RndState n) -> Discoveries (RndAnyState n p)
forall (n :: NetworkDiscriminant) (p :: Nat).
Discoveries (RndState n) -> Discoveries (RndAnyState n p)
DR Discoveries (RndState n)
b)
            to2 :: (Prologue (RndAnyState n p), Discoveries (RndAnyState n p))
-> RndAnyState n p
to2 (PR a, DR b) = RndState n -> RndAnyState n p
forall (network :: NetworkDiscriminant) (p :: Nat).
RndState network -> RndAnyState network p
Rnd.RndAnyState (RndState n -> RndAnyState n p) -> RndState n -> RndAnyState n p
forall a b. (a -> b) -> a -> b
$ (Prologue (RndState n), Discoveries (RndState n)) -> RndState n
to (Prologue (RndState n)
a,Discoveries (RndState n)
b)
        in  (RndAnyState n p
 -> (Prologue (RndAnyState n p), Discoveries (RndAnyState n p)))
-> ((Prologue (RndAnyState n p), Discoveries (RndAnyState n p))
    -> RndAnyState n p)
-> Iso'
     (RndAnyState n p)
     (Prologue (RndAnyState n p), Discoveries (RndAnyState n p))
forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
iso RndAnyState n p
-> (Prologue (RndAnyState n p), Discoveries (RndAnyState n p))
from2 (Prologue (RndAnyState n p), Discoveries (RndAnyState n p))
-> RndAnyState n p
to2

instance Eq (Prologue (Rnd.RndAnyState n p)) where PR a == :: Prologue (RndAnyState n p) -> Prologue (RndAnyState n p) -> Bool
== PR b = Prologue (RndState n)
a Prologue (RndState n) -> Prologue (RndState n) -> Bool
forall a. Eq a => a -> a -> Bool
== Prologue (RndState n)
b

instance Eq (Discoveries (Rnd.RndAnyState n p)) where DR a == :: Discoveries (RndAnyState n p)
-> Discoveries (RndAnyState n p) -> Bool
== DR b = Discoveries (RndState n)
a Discoveries (RndState n) -> Discoveries (RndState n) -> Bool
forall a. Eq a => a -> a -> Bool
== Discoveries (RndState n)
b

-- | Isomorphism for HD random address book.
instance AddressBookIso (Rnd.RndState n) where
    data Prologue (Rnd.RndState n)
        = RndPrologue (Rnd.RndState n)
        -- Trick: We keep the type, but we empty the discovered addresses
    data Discoveries (Rnd.RndState n)
        = RndDiscoveries (Map Rnd.DerivationPath (Address, AddressState))

    addressIso :: p (Prologue (RndState n), Discoveries (RndState n))
  (f (Prologue (RndState n), Discoveries (RndState n)))
-> p (RndState n) (f (RndState n))
addressIso = (RndState n -> (Prologue (RndState n), Discoveries (RndState n)))
-> ((Prologue (RndState n), Discoveries (RndState n))
    -> RndState n)
-> Iso'
     (RndState n) (Prologue (RndState n), Discoveries (RndState n))
forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
iso RndState n -> (Prologue (RndState n), Discoveries (RndState n))
forall (network :: NetworkDiscriminant) (n :: NetworkDiscriminant)
       (n :: NetworkDiscriminant).
RndState network
-> (Prologue (RndState n), Discoveries (RndState n))
from (Prologue (RndState n), Discoveries (RndState n)) -> RndState n
forall (n :: NetworkDiscriminant) (n :: NetworkDiscriminant)
       (network :: NetworkDiscriminant).
(Prologue (RndState n), Discoveries (RndState n))
-> RndState network
to
      where
        from :: RndState network
-> (Prologue (RndState n), Discoveries (RndState n))
from (Rnd.RndState Passphrase "addr-derivation-payload"
a Index 'Hardened 'AccountK
b Map DerivationPath (Address, AddressState)
addrs Map DerivationPath Address
c StdGen
d)
            = (RndState n -> Prologue (RndState n)
forall (n :: NetworkDiscriminant).
RndState n -> Prologue (RndState n)
RndPrologue (Passphrase "addr-derivation-payload"
-> Index 'Hardened 'AccountK
-> Map DerivationPath (Address, AddressState)
-> Map DerivationPath Address
-> StdGen
-> RndState n
forall (network :: NetworkDiscriminant).
Passphrase "addr-derivation-payload"
-> Index 'Hardened 'AccountK
-> Map DerivationPath (Address, AddressState)
-> Map DerivationPath Address
-> StdGen
-> RndState network
Rnd.RndState Passphrase "addr-derivation-payload"
a Index 'Hardened 'AccountK
b Map DerivationPath (Address, AddressState)
forall k a. Map k a
Map.empty Map DerivationPath Address
c StdGen
d), Map DerivationPath (Address, AddressState)
-> Discoveries (RndState n)
forall (n :: NetworkDiscriminant).
Map DerivationPath (Address, AddressState)
-> Discoveries (RndState n)
RndDiscoveries Map DerivationPath (Address, AddressState)
addrs)
        to :: (Prologue (RndState n), Discoveries (RndState n))
-> RndState network
to (RndPrologue (Rnd.RndState a b _ c d), RndDiscoveries addrs)
            = Passphrase "addr-derivation-payload"
-> Index 'Hardened 'AccountK
-> Map DerivationPath (Address, AddressState)
-> Map DerivationPath Address
-> StdGen
-> RndState network
forall (network :: NetworkDiscriminant).
Passphrase "addr-derivation-payload"
-> Index 'Hardened 'AccountK
-> Map DerivationPath (Address, AddressState)
-> Map DerivationPath Address
-> StdGen
-> RndState network
Rnd.RndState Passphrase "addr-derivation-payload"
a Index 'Hardened 'AccountK
b Map DerivationPath (Address, AddressState)
addrs Map DerivationPath Address
c StdGen
d

instance Buildable (Prologue (Rnd.RndState n)) where
    build :: Prologue (RndState n) -> Builder
build (RndPrologue st) = Builder
"Prologue of " Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> RndState n -> Builder
forall p. Buildable p => p -> Builder
build RndState n
st

instance Eq (Prologue (Rnd.RndState n)) where
    RndPrologue a == :: Prologue (RndState n) -> Prologue (RndState n) -> Bool
== RndPrologue b = RndState n
a RndState n -> RndState n -> Bool
forall a. Eq a => a -> a -> Bool
== RndState n
b

instance Eq (Discoveries (Rnd.RndState n)) where
    RndDiscoveries a == :: Discoveries (RndState n) -> Discoveries (RndState n) -> Bool
== RndDiscoveries b = Map DerivationPath (Address, AddressState)
a Map DerivationPath (Address, AddressState)
-> Map DerivationPath (Address, AddressState) -> Bool
forall a. Eq a => a -> a -> Bool
== Map DerivationPath (Address, AddressState)
b