{-# LANGUAGE BinaryLiterals #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeApplications #-}

-- |
-- Copyright: © 2022 IOHK
-- License: Apache-2.0
--
-- Provides various 'Address' constants used by the wallet or its tests.
--
module Cardano.Wallet.Primitive.Types.Address.Constants
    ( maxLengthAddress
    , minLengthAddress
    ) where

import Prelude

import Cardano.Wallet.Primitive.AddressDerivation
    ( BoundedAddressLength (..) )
import Cardano.Wallet.Primitive.AddressDerivation.Byron
    ( ByronKey )
import Cardano.Wallet.Primitive.AddressDerivation.Icarus
    ( IcarusKey )
import Cardano.Wallet.Primitive.AddressDerivation.Shared
    ( SharedKey )
import Cardano.Wallet.Primitive.AddressDerivation.Shelley
    ( ShelleyKey )
import Cardano.Wallet.Primitive.Types.Address
    ( Address (..) )
import Data.Proxy
    ( Proxy (..) )

import Data.Function
    ( on )

import qualified Data.ByteString as BS
import qualified Data.List as L

-- | A dummy 'Address' of the greatest length that the wallet can generate.
--
-- Please note that this address should:
--
--  - never be used for anything besides its length and validity properties.
--  - never be used as a payment target within a real transaction.
--
maxLengthAddress :: Address
maxLengthAddress :: Address
maxLengthAddress = (Address -> Address -> Ordering) -> [Address] -> Address
forall (t :: * -> *) a.
Foldable t =>
(a -> a -> Ordering) -> t a -> a
L.maximumBy (Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Int -> Int -> Ordering)
-> (Address -> Int) -> Address -> Address -> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` (ByteString -> Int
BS.length (ByteString -> Int) -> (Address -> ByteString) -> Address -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Address -> ByteString
unAddress))
    [ Proxy ByronKey -> Address
forall k (key :: k).
BoundedAddressLength key =>
Proxy key -> Address
maxLengthAddressFor (Proxy ByronKey -> Address) -> Proxy ByronKey -> Address
forall a b. (a -> b) -> a -> b
$ Proxy ByronKey
forall k (t :: k). Proxy t
Proxy @ByronKey
    , Proxy IcarusKey -> Address
forall k (key :: k).
BoundedAddressLength key =>
Proxy key -> Address
maxLengthAddressFor (Proxy IcarusKey -> Address) -> Proxy IcarusKey -> Address
forall a b. (a -> b) -> a -> b
$ Proxy IcarusKey
forall k (t :: k). Proxy t
Proxy @IcarusKey
    , Proxy ShelleyKey -> Address
forall k (key :: k).
BoundedAddressLength key =>
Proxy key -> Address
maxLengthAddressFor (Proxy ShelleyKey -> Address) -> Proxy ShelleyKey -> Address
forall a b. (a -> b) -> a -> b
$ Proxy ShelleyKey
forall k (t :: k). Proxy t
Proxy @ShelleyKey
    , Proxy SharedKey -> Address
forall k (key :: k).
BoundedAddressLength key =>
Proxy key -> Address
maxLengthAddressFor (Proxy SharedKey -> Address) -> Proxy SharedKey -> Address
forall a b. (a -> b) -> a -> b
$ Proxy SharedKey
forall k (t :: k). Proxy t
Proxy @SharedKey
    ]

-- | A dummy 'Address' of the shortest length that the wallet can generate.
--
-- Please note that this address should:
--
--  - never be used for anything besides its length and validity properties.
--  - never be used as a payment target within a real transaction.
--
minLengthAddress :: Address
minLengthAddress :: Address
minLengthAddress = Address
minLengthAddressShelley
  where
    minLengthAddressShelley :: Address
minLengthAddressShelley =
        ByteString -> Address
Address (ByteString -> Address) -> ByteString -> Address
forall a b. (a -> b) -> a -> b
$ Word8 -> ByteString
BS.singleton Word8
enterpriseAddressHeaderByte ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
payload
      where
        enterpriseAddressHeaderByte :: Word8
enterpriseAddressHeaderByte = Word8
0b01100000
        payload :: ByteString
payload = Int -> Word8 -> ByteString
BS.replicate Int
28 Word8
0