{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeApplications #-}
module Mantra.Asset (
assetFingerprint
, assetFingerprintString
, assetFingerprintBytes
) where
import Cardano.Api (AssetId(..), AssetName(..), PolicyId(..), serialiseToRawBytes)
import Codec.Binary.Bech32 (HumanReadablePart, dataPartFromBytes, encodeLenient, humanReadablePartFromText)
import Crypto.Hash (hash)
import Crypto.Hash.Algorithms (Blake2b_160)
import Data.ByteArray (convert)
import Data.Text (Text)
import Mantra.Types (MantraM, foistMantraEither, throwMantra)
import qualified Data.ByteString.Char8 as BS (ByteString, pack)
import qualified Data.ByteString.Base16 as Base16 (decode)
assetPrefix :: HumanReadablePart
Right HumanReadablePart
assetPrefix = Text -> Either HumanReadablePartError HumanReadablePart
humanReadablePartFromText Text
"asset"
assetFingerprintBytes :: BS.ByteString
-> BS.ByteString
-> Text
assetFingerprintBytes :: ByteString -> ByteString -> Text
assetFingerprintBytes ByteString
policyId ByteString
assetName =
HumanReadablePart -> DataPart -> Text
encodeLenient HumanReadablePart
assetPrefix
(DataPart -> Text)
-> (ByteString -> DataPart) -> ByteString -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> DataPart
dataPartFromBytes
(ByteString -> DataPart)
-> (ByteString -> ByteString) -> ByteString -> DataPart
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Digest Blake2b_160 -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
convert
(Digest Blake2b_160 -> ByteString)
-> (ByteString -> Digest Blake2b_160) -> ByteString -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ByteArrayAccess ByteString, HashAlgorithm Blake2b_160) =>
ByteString -> Digest Blake2b_160
forall ba a.
(ByteArrayAccess ba, HashAlgorithm a) =>
ba -> Digest a
hash @_ @Blake2b_160
(ByteString -> Text) -> ByteString -> Text
forall a b. (a -> b) -> a -> b
$ ByteString
policyId ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
assetName
assetFingerprintString :: Monad m
=> String
-> String
-> MantraM m Text
assetFingerprintString :: String -> String -> MantraM m Text
assetFingerprintString String
policyId String
assetName =
let
assetName' :: ByteString
assetName' = String -> ByteString
BS.pack String
assetName
in
(ByteString -> Text) -> MantraM m ByteString -> MantraM m Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (ByteString -> ByteString -> Text
`assetFingerprintBytes` ByteString
assetName')
(MantraM m ByteString -> MantraM m Text)
-> (ByteString -> MantraM m ByteString)
-> ByteString
-> MantraM m Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Either String ByteString -> MantraM m ByteString
forall (m :: * -> *) e a.
(Monad m, Show e) =>
Either e a -> MantraM m a
foistMantraEither
(Either String ByteString -> MantraM m ByteString)
-> (ByteString -> Either String ByteString)
-> ByteString
-> MantraM m ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either String ByteString
Base16.decode
(ByteString -> MantraM m Text) -> ByteString -> MantraM m Text
forall a b. (a -> b) -> a -> b
$ String -> ByteString
BS.pack String
policyId
assetFingerprint :: Monad m
=> AssetId
-> MantraM m Text
assetFingerprint :: AssetId -> MantraM m Text
assetFingerprint (AssetId (PolicyId ScriptHash
scriptHash) (AssetName ByteString
assetName)) =
Text -> MantraM m Text
forall (m :: * -> *) a. Monad m => a -> m a
return
(Text -> MantraM m Text) -> Text -> MantraM m Text
forall a b. (a -> b) -> a -> b
$ ByteString -> ByteString -> Text
assetFingerprintBytes
(ScriptHash -> ByteString
forall a. SerialiseAsRawBytes a => a -> ByteString
serialiseToRawBytes ScriptHash
scriptHash)
ByteString
assetName
assetFingerprint AssetId
_ = String -> MantraM m Text
forall (m :: * -> *) a. Monad m => String -> MantraM m a
throwMantra String
"Non-token asset."