-
Notifications
You must be signed in to change notification settings - Fork 91
chore: refactor payment network IDs for enforced typing #977
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
| export abstract class AnyToAnyDetector< | ||
| TExtension extends ExtensionTypes.PnFeeReferenceBased.IFeeReferenceBased, | ||
| TPaymentEventParameters, | ||
| TPaymentEventParameters extends Partial<ExtensionTypes.PnFeeReferenceBased.IAddFeeParameters>, |
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.
Here is an example of a hidden mistyping that cannot be missed anymore.
| export abstract class AnyToNativeDetector extends AnyToAnyDetector< | ||
| ExtensionTypes.PnAnyToEth.IAnyToEth, | ||
| PaymentTypes.IETHPaymentEventParameters | ||
| PaymentTypes.IETHFeePaymentEventParameters |
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.
Here is an example of a hidden mistyping that cannot be missed anymore.
| export abstract class DeclarativePaymentDetectorBase< | ||
| TExtension extends ExtensionTypes.PnAnyDeclarative.IAnyDeclarative, | ||
| TPaymentEventParameters extends PaymentTypes.IDeclarativePaymentEventParameters, | ||
| TPaymentEventParameters extends PaymentTypes.IDeclarativePaymentEventParameters<unknown>, |
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.
Here is an example of a hidden mistyping that cannot be missed anymore.
More specifically, Declarative payment events are at the root of many detectors, but when events are declarative for real, they use IIdentity type for from, whereas it's string for overriding children (when it's not declarative)
| export abstract class FeeReferenceBasedDetector< | ||
| TExtension extends ExtensionTypes.PnFeeReferenceBased.IFeeReferenceBased, | ||
| TPaymentEventParameters extends { feeAmount?: string; feeAddress?: string }, | ||
| TPaymentEventParameters extends PaymentTypes.IDeclarativePaymentEventParameters<string> & { |
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.
Here is an example of a hidden mistyping that cannot be missed anymore.
| requestInfo: RequestLogic.ICreateParameters | IRequestInfo; | ||
| signer: Identity.IIdentity; | ||
| paymentNetwork?: Payment.IPaymentNetworkCreateParameters; | ||
| paymentNetwork?: Payment.PaymentNetworkCreateParameters; |
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.
Main change: from interface to type
| PAYMENT_NETWORK_ANY_TO_ETH_PROXY = 'pn-any-to-eth-proxy', | ||
| } | ||
|
|
||
| export enum PAYMENT_NETWORK_ID { |
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.
Strong impact required for the main change: instead of mapping a new enum out of ID to qualify payment network IDs, we now have 2 enums.
| parameters: T; | ||
| } | ||
|
|
||
| export type PaymentNetworkCreateParameters = |
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 is the main change. We strongly type creation parameters based on the different payment networks.
packages/types/src/payment-types.ts
Outdated
| }; | ||
|
|
||
| /** Payment network IDs with known Create Parameters */ | ||
| export type PAYMENT_NETWORK_ID = PaymentNetworkCreateParameters['id']; |
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 is not an enum anymore, and is probably useless outside PaymentTypes.
|
|
||
| /** Parameters for events of Declarative payments */ | ||
| export interface IDeclarativePaymentEventParameters { | ||
| export interface IDeclarativePaymentEventParameters<TFrom = IIdentity> { |
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.
(cf. other comment about this interface) Declarative payment events are at the root of many detectors, but when events are declarative for real, they use IIdentity type for from, whereas it's string for overriding children (when it's not declarative)
| } | ||
| /** Parameters for events of ERC777 payments */ | ||
| export interface IERC777PaymentEventParameters { | ||
| export interface IERC777PaymentEventParameters extends GenericEventParameters { |
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.
Side-improvement. (and a few other similare replacements)
packages/types/src/utils.ts
Outdated
| for (const pn in PaymentTypes.PAYMENT_NETWORK_ID) { | ||
| if (PaymentTypes.PAYMENT_NETWORK_ID[pn] === value) { | ||
| export function isPaymentNetworkId(value: any): value is ExtensionTypes.PAYMENT_NETWORK_ID { | ||
| for (const pn of enumKeys(ExtensionTypes.PAYMENT_NETWORK_ID)) { |
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.
The old trick was not working anymore
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 wonder if isPaymentNetworkId is still necessary. It seems to be there to account for the possibility of the ID not being a payment network ID, but now we have a strong type to enforce it?
btw, you could also do Object.values(ExtensionTypes.PAYMENT_NETWORK_ID).includes(value)
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 agree, it should probably be removed or at least accept only ID values.
benjlevesque
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.
great change 👏
packages/types/src/utils.ts
Outdated
| for (const pn in PaymentTypes.PAYMENT_NETWORK_ID) { | ||
| if (PaymentTypes.PAYMENT_NETWORK_ID[pn] === value) { | ||
| export function isPaymentNetworkId(value: any): value is ExtensionTypes.PAYMENT_NETWORK_ID { | ||
| for (const pn of enumKeys(ExtensionTypes.PAYMENT_NETWORK_ID)) { |
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 wonder if isPaymentNetworkId is still necessary. It seems to be there to account for the possibility of the ID not being a payment network ID, but now we have a strong type to enforce it?
btw, you could also do Object.values(ExtensionTypes.PAYMENT_NETWORK_ID).includes(value)
| } | ||
|
|
||
| /** Interface to create a payment network */ | ||
| export interface IPaymentNetworkCreateParameters<T = any> { |
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.
do we still need the default any?
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 have actually deprecated this interface in the meantime @benjlevesque
alexandre-abrioux
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.
Nice! I remember wanting to do something like this in my previous refactor but refrained as it was already too many changes 🤩 Awesome!
olivier7delf
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.
great job!
Description of the changes
In order to type strongly the Payment Network creation parameters, I had to change the way we declare Payment Network IDs.
This highlighted a few type mistakes, potentially runtime mistakes, for example for the type of
from(cf. comments).This strong typing would have avoided the mistake fixed by this previous change.
chore: enforce the typing of creation parameters with the type
PaymentNetworkCreateParameterschore: deprecate the
IPaymentNetworkCreateParametersinterfacechore: remove enum
PaymentTypes.PAYMENT_NETWORK_IDchore: created enums
ExtensionTypes.OTHER_IDandExtensionTypes.PAYMENT_NETWORK_ID,ExtensionTypes.IDis defined by their unionNote for validators
Most changes are automatic replacements as explained below.
The main changes are highlighted by comments.
(Type) Breaking change and notice
This change is type-breaking but not runtime-breaking, as the enum values are the same.
For uses of
PaymentTypes.PAYMENT_NETWORK_ID.<SOME_ID>, they can be easily replaced withExtensionTypes.PAYMENT_NETWORK_ID.<SOME_ID>, except forDECLARATIVEandANY_TO_NATIVEthat are namedANY_DECLARATIVEandANY_TO_NATIVE_TOKEN.(example 1 and example 2)
References to
ExtensionTypes.ID.PAYMENT_NETWORK_<SOME_ID>should be replaced withExtensionTypes.PAYMENT_NETWORK_ID.<SOME_ID>.(example)
References to
IPaymentNetworkCreateParametersinterface should be replaced withPaymentNetworkCreateParameterstype.