Skip to content

Commit

Permalink
api: add /addresses/:address/extended endpoint, AddressInfoExtended type
Browse files Browse the repository at this point in the history
  • Loading branch information
sorki committed Dec 18, 2023
1 parent ef5053f commit 1233e39
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 0 deletions.
1 change: 1 addition & 0 deletions blockfrost-api/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* Additions [#43](https://github.com/blockfrost/blockfrost-haskell/pull/43)
* `Env` enum extended with `Sanchonet` for `cardano-sanchonet` network
* `/accounts/:stake_address/addresses/total` endpoint and `AddressAssociatedTotal` type
* `/addresses/:address/extended` endpoint and `AddressInfoExtended` type (uses `AmountExtended` type)
* `/pools/extended` endpoint and `Pool` type
* `/utils` API
* `/utils/addresses/xpub/:xpub/:role/:index` endpoint and `DerivedAddress` type
Expand Down
7 changes: 7 additions & 0 deletions blockfrost-api/src/Blockfrost/API/Cardano/Addresses.hs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ data AddressesAPI route =
:> Description "Obtain information about a specific address."
:> Capture "address" Address
:> Get '[JSON] AddressInfo
, _addressInfoExtended
:: route
:- Summary "Specific address - extended"
:> Description "Obtain extended information about a specific address."
:> Capture "address" Address
:> "extended"
:> Get '[JSON] AddressInfoExtended
, _addressDetails
:: route
:- Summary "Address details"
Expand Down
33 changes: 33 additions & 0 deletions blockfrost-api/src/Blockfrost/Types/Cardano/Addresses.hs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

module Blockfrost.Types.Cardano.Addresses
( AddressInfo (..)
, AddressInfoExtended (..)
, AddressType (..)
, AddressDetails (..)
, AddressUtxo (..)
Expand Down Expand Up @@ -43,6 +44,38 @@ instance ToSample AddressInfo where
, _addressInfoScript = False
}

-- | Information about Cardano address
data AddressInfoExtended = AddressInfoExtended
{ _addressInfoExtendedAddress :: Address -- ^ Bech32 encoded addresses
, _addressInfoExtendedAmount :: [AmountExtended] -- ^ Lovelaces or tokens stored on this address
, _addressInfoExtendedStakeAddress :: Maybe Address -- ^ Stake address that controls the key
, _addressInfoExtendedType :: AddressType -- ^ Address era
, _addressInfoExtendedScript :: Bool -- ^ True if this is a script address
} deriving stock (Show, Eq, Generic)
deriving (FromJSON, ToJSON)
via CustomJSON '[FieldLabelModifier '[StripPrefix "_addressInfoExtended", CamelToSnake]] AddressInfoExtended

instance ToSample AddressInfoExtended where
toSamples = pure $ singleSample
AddressInfoExtended
{ _addressInfoExtendedAddress = "addr1qxqs59lphg8g6qndelq8xwqn60ag3aeyfcp33c2kdp46a09re5df3pzwwmyq946axfcejy5n4x0y99wqpgtp2gd0k09qsgy6pz"
, _addressInfoExtendedAmount =
[ AdaAmountExtended 42000000
, AssetAmountExtended
{ assetAmountExtendedDecimals = Nothing
, assetAmountExtendedHasNftOnchainMetadata = True
, assetAmountExtendedValue =
Money.toSomeDiscrete
(12 :: Money.Discrete'
"b0d07d45fe9514f80213f4020e5a61241458be626841cde717cb38a76e7574636f696e"
'(1,1))
}
]
, _addressInfoExtendedStakeAddress = pure "stake1ux3g2c9dx2nhhehyrezyxpkstartcqmu9hk63qgfkccw5rqttygt7"
, _addressInfoExtendedType = Shelley
, _addressInfoExtendedScript = False
}

-- | Type (era) of an address
data AddressType = Byron | Shelley
deriving stock (Show, Eq, Generic)
Expand Down
57 changes: 57 additions & 0 deletions blockfrost-api/src/Blockfrost/Types/Shared/Amount.hs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
-- | Amount sum type

{-# LANGUAGE NumericUnderscores #-}
{-# LANGUAGE RecordWildCards #-}

module Blockfrost.Types.Shared.Amount
where
Expand Down Expand Up @@ -79,3 +80,59 @@ instance ToSample Amount where
"6804edf9712d2b619edb6ac86861fe93a730693183a262b165fcc1ba1bc99cad"
'(1,1))
]

-- | Like @Amount@, extended with @decimals` and `has_nft_onchain_metadata`
data AmountExtended =
AdaAmountExtended Lovelaces
| AssetAmountExtended
{ assetAmountExtendedDecimals :: Maybe Int
, assetAmountExtendedHasNftOnchainMetadata :: Bool
, assetAmountExtendedValue :: Money.SomeDiscrete
}
deriving (Eq, Show, Ord, Generic)

instance ToJSON AmountExtended where
toJSON (AdaAmountExtended lovelaces) =
object [ "unit" .= ("lovelace" :: String)
, "quantity" .= toJSON lovelaces
, "decimals" .= (6 :: Int)
, "has_nft_onchain_metadata" .= False
]
toJSON (AssetAmountExtended {..}) =
object [ "unit" .= Money.someDiscreteCurrency assetAmountExtendedValue
, "quantity" .= show (Money.someDiscreteAmount assetAmountExtendedValue)
, "decimals" .= assetAmountExtendedDecimals
, "has_nft_onchain_metadata" .= assetAmountExtendedHasNftOnchainMetadata
]

instance FromJSON AmountExtended where
parseJSON x@(Object o) = do
(u :: String) <- o .: "unit"
v <- o .: "quantity"
assetAmountExtendedDecimals
<- o .: "decimals"
assetAmountExtendedHasNftOnchainMetadata
<- o .: "has_nft_onchain_metadata"
case u of
"lovelace" -> AdaAmountExtended <$> parseJSON v
_ -> do
assetAmountExtendedValue <- parseJSON x
pure AssetAmountExtended{..}

parseJSON other = fail $ "Amount expecting object, got" ++ show other

instance ToSample AmountExtended where
toSamples = pure $ samples
[ AdaAmountExtended 42000000
, AssetAmountExtended
{ assetAmountExtendedDecimals = Nothing
, assetAmountExtendedHasNftOnchainMetadata = True
, assetAmountExtendedValue =
Money.toSomeDiscrete
(12 :: Money.Discrete'
"b0d07d45fe9514f80213f4020e5a61241458be626841cde717cb38a76e7574636f696e"
'(1,1))
}
]


48 changes: 48 additions & 0 deletions blockfrost-api/test/Cardano/Addresses.hs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ spec_sample = do
`shouldBe`
Right addressInfoExpected

it "parses address info extended sample" $ do
eitherDecode addressInfoExtendedSample
`shouldBe`
Right addressInfoExtendedExpected

it "parses address info sample" $ do
eitherDecode addressInfoSample
`shouldBe`
Expand Down Expand Up @@ -77,6 +82,49 @@ addressInfoExpected =
, _addressInfoScript = False
}

addressInfoExtendedSample = [r|
{
"address": "addr1qxqs59lphg8g6qndelq8xwqn60ag3aeyfcp33c2kdp46a09re5df3pzwwmyq946axfcejy5n4x0y99wqpgtp2gd0k09qsgy6pz",
"amount": [
{
"unit": "lovelace",
"quantity": "42000000",
"decimals": 6,
"has_nft_onchain_metadata": false
},
{
"unit": "b0d07d45fe9514f80213f4020e5a61241458be626841cde717cb38a76e7574636f696e",
"quantity": "12",
"decimals": null,
"has_nft_onchain_metadata": true
}
],
"stake_address": "stake1ux3g2c9dx2nhhehyrezyxpkstartcqmu9hk63qgfkccw5rqttygt7",
"type": "shelley",
"script": false
}
|]

addressInfoExtendedExpected =
AddressInfoExtended
{ _addressInfoExtendedAddress = "addr1qxqs59lphg8g6qndelq8xwqn60ag3aeyfcp33c2kdp46a09re5df3pzwwmyq946axfcejy5n4x0y99wqpgtp2gd0k09qsgy6pz"
, _addressInfoExtendedAmount =
[ AdaAmountExtended 42000000
, AssetAmountExtended
{ assetAmountExtendedDecimals = Nothing
, assetAmountExtendedHasNftOnchainMetadata = True
, assetAmountExtendedValue =
Money.mkSomeDiscrete
"b0d07d45fe9514f80213f4020e5a61241458be626841cde717cb38a76e7574636f696e"
unitScale
12
}
]
, _addressInfoExtendedStakeAddress = pure "stake1ux3g2c9dx2nhhehyrezyxpkstartcqmu9hk63qgfkccw5rqttygt7"
, _addressInfoExtendedType = Shelley
, _addressInfoExtendedScript = False
}

addressDetailsSample = [r|
{
"address": "addr1qxqs59lphg8g6qndelq8xwqn60ag3aeyfcp33c2kdp46a09re5df3pzwwmyq946axfcejy5n4x0y99wqpgtp2gd0k09qsgy6pz",
Expand Down

0 comments on commit 1233e39

Please sign in to comment.