Skip to content

Commit

Permalink
add AnyAddress
Browse files Browse the repository at this point in the history
  • Loading branch information
paweljakubas committed Oct 26, 2020
1 parent 0027917 commit f264b25
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 16 deletions.
7 changes: 4 additions & 3 deletions lib/core/src/Cardano/Wallet/Api.hs
Expand Up @@ -115,7 +115,8 @@ import Prelude
import Cardano.Wallet
( WalletLayer (..), WalletLog )
import Cardano.Wallet.Api.Types
( ApiAddressIdT
( AnyAddress
, ApiAddressIdT
, ApiAddressInspect
, ApiAddressInspectData
, ApiAddressT
Expand Down Expand Up @@ -333,10 +334,10 @@ type InspectAddress = "addresses"
:> Capture "addressId" ApiAddressInspectData
:> Get '[JSON] ApiAddressInspect

-- | https://input-output-hk.github.io/cardano-wallet/api/#operation/postScriptAddress
-- | https://input-output-hk.github.io/cardano-wallet/api/#operation/postAnyAddress
type PostScriptAddress n = "addresses"
:> ReqBody '[JSON] ApiCredentials
:> PostCreated '[JSON] (ApiAddressT n)
:> PostCreated '[JSON] AnyAddress

{-------------------------------------------------------------------------------
Coin Selections
Expand Down
14 changes: 14 additions & 0 deletions lib/core/src/Cardano/Wallet/Api/Server.hs
Expand Up @@ -77,6 +77,7 @@ module Cardano.Wallet.Api.Server
, selectCoinsForJoin
, selectCoinsForQuit
, signMetadata
, postAnyAddress

-- * Internals
, LiftHandler(..)
Expand Down Expand Up @@ -164,6 +165,7 @@ import Cardano.Wallet.Api.Server.Tls
import Cardano.Wallet.Api.Types
( AccountPostData (..)
, AddressAmount (..)
, AnyAddress (..)
, ApiAccountPublicKey (..)
, ApiAddress (..)
, ApiBlockInfo (..)
Expand All @@ -175,6 +177,7 @@ import Cardano.Wallet.Api.Types
, ApiCoinSelectionChange (..)
, ApiCoinSelectionInput (..)
, ApiCoinSelectionOutput (..)
, ApiCredentials (..)
, ApiEpochInfo (ApiEpochInfo)
, ApiErrorCode (..)
, ApiFee (..)
Expand Down Expand Up @@ -1866,6 +1869,17 @@ derivePublicKey ctx (ApiT wid) (ApiT role_) (ApiT ix) = do
k <- liftHandler $ W.derivePublicKey @_ @s @k @n wrk wid role_ ix
pure $ ApiVerificationKey (getRawKey k, role_)

postAnyAddress
:: forall ctx s t k n.
( s ~ SeqState n k
, k ~ ShelleyKey
, ctx ~ ApiLayer s t k
)
=> ctx
-> ApiCredentials
-> Handler AnyAddress
postAnyAddress ctx body = undefined

{-------------------------------------------------------------------------------
Helpers
-------------------------------------------------------------------------------}
Expand Down
43 changes: 43 additions & 0 deletions lib/core/src/Cardano/Wallet/Api/Types.hs
Expand Up @@ -48,6 +48,8 @@ module Cardano.Wallet.Api.Types
, ApiPubKey (..)
, Credential (..)
, ApiCredentials (..)
, AnyAddress (..)
, AnyAddressType (..)
, ApiCertificate (..)
, ApiEpochInfo (..)
, ApiSelectCoinsData (..)
Expand Down Expand Up @@ -413,6 +415,17 @@ data ApiCredentials = ApiCredentials
, staking :: !(Maybe Credential)
} deriving (Eq, Generic, Show)

data AnyAddressType =
EnterpriseDelegating
| RewardAccount
deriving (Eq, Show)

data AnyAddress = AnyAddress
{ payload :: ByteString
, flavour :: AnyAddressType
, network :: Int
} deriving (Eq, Generic, Show)

data ApiEpochInfo = ApiEpochInfo
{ epochNumber :: !(ApiT EpochNo)
, epochStartTime :: !UTCTime
Expand Down Expand Up @@ -1397,6 +1410,18 @@ instance ToJSON ApiCredentials where
toJSON (ApiCredentials (Just spending') (Just staking')) =
object [ "spending" .= toJSON spending', "staking" .= toJSON staking']

instance FromJSON AnyAddress where
parseJSON = parseJSON >=> eitherToParser . first ShowFmt . fromText
instance ToJSON AnyAddress where
toJSON (AnyAddress p addrType net) = do
let hrp = case (addrType, net) of
(EnterpriseDelegating, 1) -> [Bech32.humanReadablePart|addr|]
(RewardAccount, 1) -> [Bech32.humanReadablePart|stake|]
(EnterpriseDelegating, 0) -> [Bech32.humanReadablePart|addr_test|]
(RewardAccount, 0) -> [Bech32.humanReadablePart|stake_test|]
_ -> error "Wrong network tag"
String $ T.decodeUtf8 $ encode (EBech32 hrp) p

instance MkSomeMnemonic sizes => FromJSON (ApiMnemonicT sizes)
where
parseJSON bytes = do
Expand Down Expand Up @@ -1844,6 +1869,24 @@ instance FromText ApiPubKey where
_ -> Left $ TextDecodingError "ApiPubKey must have either 'addr_vk' or 'stake_vk' prefix."
_ -> Left $ TextDecodingError "ApiPubKey must be must be encoded as Bech32."

instance FromText AnyAddress where
fromText txt = case detectEncoding (T.unpack txt) of
Just EBech32{} -> do
(hrp, dp) <- either
(const $ Left $ TextDecodingError "AnyAddress's Bech32 has invalid text.")
Right (Bech32.decodeLenient txt)
let err1 = TextDecodingError "AnyAddress has invalid Bech32 datapart."
let proceedWhenHrpCorrect ctr net = do
bytes <- maybeToRight err1 (Bech32.dataPartToBytes dp)
Right $ AnyAddress bytes ctr net
case Bech32.humanReadablePartToText hrp of
"addr" -> proceedWhenHrpCorrect EnterpriseDelegating 1
"addr_test" -> proceedWhenHrpCorrect EnterpriseDelegating 0
"stake" -> proceedWhenHrpCorrect RewardAccount 1
"stake_test" -> proceedWhenHrpCorrect RewardAccount 0
_ -> Left $ TextDecodingError "AnyAddress is not correctly prefixed."
_ -> Left $ TextDecodingError "AnyAddress must be must be encoded as Bech32."

{-------------------------------------------------------------------------------
HTTPApiData instances
-------------------------------------------------------------------------------}
Expand Down
12 changes: 3 additions & 9 deletions lib/shelley/src/Cardano/Wallet/Shelley/Api/Server.hs
Expand Up @@ -72,6 +72,7 @@ import Cardano.Wallet.Api.Server
, mkLegacyWallet
, mkShelleyWallet
, postAccountWallet
, postAnyAddress
, postExternalTransaction
, postIcarusWallet
, postLedgerWallet
Expand Down Expand Up @@ -146,14 +147,7 @@ import Fmt
import Network.Ntp
( NtpClient )
import Servant
( (:<|>) (..)
, Handler (..)
, NoContent (..)
, Server
, err400
, err501
, throwError
)
( (:<|>) (..), Handler (..), NoContent (..), Server, err400, throwError )
import Servant.Server
( ServerError (..) )
import Type.Reflection
Expand Down Expand Up @@ -208,7 +202,7 @@ server byron icarus shelley spl ntp =
addresses :: Server (Addresses n)
addresses = listAddresses shelley (normalizeDelegationAddress @_ @ShelleyKey @n)
:<|> (handler ApiAddressInspect . inspectAddress . unApiAddressInspectData)
:<|> (\_ -> throwError err501)
:<|> postAnyAddress shelley
where
toServerError :: TextDecodingError -> ServerError
toServerError = apiError err400 BadRequest . T.pack . getTextDecodingError
Expand Down
8 changes: 4 additions & 4 deletions specifications/api/swagger.yaml
Expand Up @@ -2281,7 +2281,7 @@ x-responsesPostExternalTransaction: &responsesPostExternalTransaction
application/json:
schema: *ApiTxId

x-responsesPostAddress: &responsesPostAddress
x-responsesPostAnyAddress: &responsesPostAnyAddress
<<: *responsesErr400
<<: *responsesErr405
<<: *responsesErr406
Expand Down Expand Up @@ -3303,18 +3303,18 @@ paths:

/addresses:
post:
operationId: postAddress
operationId: postAnyAddress
tags: ["Utils"]
summary: Construct Address
description: |
<p align="right">status: <strong>unstable</strong></p>
Construct an address by specyfying credential for payment or stake.
Construct any address by specyfying credential for payment or stake.
requestBody:
content:
application/json:
schema: *ApiCredentials
responses: *responsesPostAddress
responses: *responsesPostAnyAddress

/settings:
put:
Expand Down

0 comments on commit f264b25

Please sign in to comment.