-
Notifications
You must be signed in to change notification settings - Fork 629
[CBR-349] Pave the way for redemption #3373
Conversation
adinapoli-iohk
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, but we can simplify our handler signature 😉
| -> Maybe AccountIndex | ||
| -> Redemption | ||
| -> Handler (WalletResponse Transaction) | ||
| redeemAda layer mWId mAccIx redemption = do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can do better here -- if you replace your API types from using QueryParam to CaptureWalletId and CaptureAccountId, we can avoid the Maybe altogether.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't write the endpoint, just went with the endpoint as specified by @KtorZ . I can change it of course but that didn't feel like it was my decision to make :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, @adinapoli-iohk insists that CaptureWalletId and co are the way to go here so will change, despite it being inconsistent with the other endpoint :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wouldn't mind having this endpoint placed under the Transactions group built the following way:
/wallets/{walletId}/accounts/{accountIndex}/certificates
(basically, as it was before, under the accounts API, but here under the transaction API).
In essence, it's a transaction, but still a very specific one related to one wallet and one account of that particular wallet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I hear you, but at the same time if we do down this line of reasoning we would have to move the entire transaction machinery under /accounts, because you never generate transactions out of thin air, they are always originated from a source wallet and account, so I'm not sure I buy into the dream here 😁
To me, we should try to follow the RESTful principles (which I know some times are more art than science) -- we are manipulating transaction resources at the end of the day, because it's what we create and list , so that seems to suggest we should stick with the /transactions hierarchy here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, let's get back to the principles here. We are creating a transactions, right, so we ought to do a POST /transactions. But, it's actually a kind of special transaction, it's a certificate redemption. Thus, I see three options here:
-
We consider certificates as a resource on its own and create a new set of handlers under
/certificates. However, their representation is strictly identical to transactions, they don't have any representation on their own. So this feels weird. -
We consider certificates as a sub-resource of a Transaction which also feels weird. It's just a special kind of transactions. So having something like
/transactions/certificatesfeels really RPC-like. Going this way, let's be honest and simply name this/redemption-transactions... Meh. -
A third option would be to simply extend the current
POST /transactionsendpoint to accept either aPayment | Redemption, picking the right handler depending on which inputs are received. Extending theRedemptiontype to:
data Redemption = Redemption
{ redemptionRedemptionCode :: ShieldedRedemptionCode
, redemptionMnemonic :: Maybe RedemptionMnemonic
, redemptionSpendingPassword :: SpendingPassword
, redemptionTarget :: PaymentSource
} deriving (Eq, Show, Generic)Even though PaymentSource feels like a wrong name now 🙃 as it is more like a FullyQualifiedAccount but well, you know what we say about naming things ^^"
What's your opinion on that @adinapoli-iohk ?
| , getTransactionFee | ||
| :: Payment -> Resp m EstimatedFees | ||
| , redeemAda | ||
| :: Maybe WalletId |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto here -- these can be now purged from the Maybe.
| where | ||
| -- Read-only operations | ||
| ro :: (Kernel.DB -> x) -> n x | ||
| ro g = g <$> liftIO (Kernel.getWalletSnapshot w) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! 😉
KtorZ
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
|
May I ask you however not to merge anything before: I am smelling a small conflict there. CI is green, we just need a final approval on the story before it gets in. |
|
@edsko I know you are probably going to 🔪 me, but after a bit of rethinking with @KtorZ we reached the middle ground of keeping this endpoint as-it-is but to get rid of the explicit passing of the Sorry, pal. 🙉 🙉 |
| :> CaptureWalletId | ||
| :> CaptureAccountId | ||
| :> ReqBody '[ValidJSON] Redemption | ||
| :> Post '[ValidJSON] (WalletResponse Transaction) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This API structure is called like:
transactions/certificates/3/321234
This is a little odd an difficult to read. The previous URL structure looked like:
wallets/3/accounts/321234/certificates
which is clearer on what those numbered parameters actually mean.
I think the route structure should include the wallets/:walletId/accounts/:accountIndex/ "prefixes" or they should be included as part of the Redemption datatype. Folding them into the Redemption datatype would make for prettier routes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LOL, Looks like y'all came to the same conclusion!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then I guess it's probably our most acceptable solution :D
@adinapoli-iohk @KtorZ so concretely, what is the proposal now? And do you want me to do that in this PR? |
If Matthias is happy with that, I would be more than happy to have you do the amending 😉 |
|
@edsko Cardano/Wallet/API/V1/Transactions.hs :<|> "transactions" :> "certificates"
:> Summary "Redeem a certificate"
:> ReqBody '[ValidJSON] Redemption
:> Post '[ValidJSON] (WalletResponse Transaction)Cardano/Wallet/API/V1/Types.hs data Redemption = Redemption
{ redemptionRedemptionCode :: ShieldedRedemptionCode
, redemptionMnemonic :: Maybe RedemptionMnemonic
, redemptionSpendingPassword :: SpendingPassword
, redemptionWalletId :: WalletId
, redemptionAccountIndex :: AccountIndex
} deriving (Eq, Show, Generic)If you could amend this PR with this, that'd be wonderful 🦋 |
|
@KtorZ @adinapoli-iohk ok, will amend accordingly, and also push a separate commit that refactors out some common patterns in our V1 wrapping code for the new wallet layer. |
5158d0f to
f3771f2
Compare
This cleans up some of the code a bit, stubs out some handlers for the redemption end point. As agreed with squad 1, this also moves the redemption endpoint to be part of transactions endpoint rather than the accounts endpoint. This makes more sense, since redemption creates a new transaction (otherwise it was the odd one out on the accounts endpoint, the only one requiring additional parameters in the legacy implementation, or requiring the active wallet in the new implementation). Also: * Add WalletId and AccountIndex to Redemption, as requested. * Factor out common functions, use ExceptT to avoid deeply nested pattern matching. * Remove some time limits where they were not necessary. * In `setupPayment`, return an address decoding error in the same way that we do this everywhere.
f3771f2 to
36a5df3
Compare
| :<|> "transactions" :> "certificates" | ||
| :> Summary "Redeem a certificate" | ||
| :> ReqBody '[ValidJSON] Redemption | ||
| :> Post '[ValidJSON] (WalletResponse Transaction) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
| , redemptionWalletId :: WalletId | ||
| -- ^ Redeem to this wallet | ||
| , redemptionAccountIndex :: AccountIndex | ||
| -- ^ Redeem to this account index in the wallet |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
|
Merging, AppVeyor timeout. Reviewed by two squad leads. |
This cleans up some of the code a bit, stubs out some handlers for the
redemption end point.
As agreed with squad 1, this also moves the redemption endpoint to be part of
transactions endpoint rather than the accounts endpoint. This makes more sense,
since redemption creates a new transaction (otherwise it was the odd one out on
the accounts endpoint, the only one requiring additional parameters in the
legacy implementation, or requiring the active wallet in the new
implementation).
Description
https://iohk.myjetbrains.com/youtrack/issue/CBR-349
Linked issue
Type of change
Developer checklist
Testing checklist
QA Steps
Screenshots (if available)