From 2ac7495736fa3162ed625bf55f8a6ce678f44f88 Mon Sep 17 00:00:00 2001 From: darkmemo Date: Mon, 19 Mar 2018 10:32:02 +0300 Subject: [PATCH 1/4] Fix Payment source & destination types Payment `source` and `destination` are defined as intersection types, `Adjustment & MaxAdjustment` and `Adjustment & MinAdjustment` respectively. But they should be union types instead. This problem was introduced during js to ts conversion. --- src/transaction/payment.ts | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/transaction/payment.ts b/src/transaction/payment.ts index 37051d5b67..e3a7582dee 100644 --- a/src/transaction/payment.ts +++ b/src/transaction/payment.ts @@ -10,8 +10,8 @@ import {Amount, Adjustment, MaxAdjustment, export type Payment = { - source: Adjustment & MaxAdjustment, - destination: Adjustment & MinAdjustment, + source: Adjustment | MaxAdjustment, + destination: Adjustment | MinAdjustment, paths?: string, memos?: Array, // A 256-bit hash that can be used to identify a particular payment @@ -74,8 +74,8 @@ function createPaymentTransaction(address: string, paymentArgument: Payment throw new ValidationError('address must match payment.source.address') } - if ((payment.source.maxAmount && payment.destination.minAmount) || - (payment.source.amount && payment.destination.amount)) { + if (((payment.source).maxAmount && (payment.destination).minAmount) || + ((payment.source).amount && (payment.destination).amount)) { throw new ValidationError('payment must specify either (source.maxAmount ' + 'and destination.amount) or (source.amount and destination.minAmount)') } @@ -86,9 +86,9 @@ function createPaymentTransaction(address: string, paymentArgument: Payment // send the whole source amount, so we set the destination amount to the // maximum possible amount. otherwise it's possible that the destination // cap could be hit before the source cap. - const amount = payment.destination.minAmount && !isXRPToXRPPayment(payment) ? - createMaximalAmount(payment.destination.minAmount) : - (payment.destination.amount || payment.destination.minAmount) + const amount = (payment.destination).minAmount && !isXRPToXRPPayment(payment) ? + createMaximalAmount((payment.destination).minAmount) : + ((payment.destination).amount || (payment.destination).minAmount) const txJSON: any = { TransactionType: 'Payment', @@ -122,15 +122,15 @@ function createPaymentTransaction(address: string, paymentArgument: Payment // https://github.com/ripple/rippled/commit/ // c522ffa6db2648f1d8a987843e7feabf1a0b7de8/ if (payment.allowPartialPayment === true - || payment.destination.minAmount !== undefined) { + || (payment.destination).minAmount !== undefined) { txJSON.Flags |= paymentFlags.PartialPayment } txJSON.SendMax = toRippledAmount( - payment.source.maxAmount || payment.source.amount) + (payment.source).maxAmount || (payment.source).amount) - if (payment.destination.minAmount !== undefined) { - txJSON.DeliverMin = toRippledAmount(payment.destination.minAmount) + if ((payment.destination).minAmount !== undefined) { + txJSON.DeliverMin = toRippledAmount((payment.destination).minAmount) } if (payment.paths !== undefined) { From 22b3c3b75465ff1752a5f01704391762ff780ae4 Mon Sep 17 00:00:00 2001 From: "Fred K. Schott" Date: Mon, 19 Mar 2018 22:32:07 -0700 Subject: [PATCH 2/4] more clean up for min/max adjustments --- src/transaction/payment.ts | 49 +++++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/src/transaction/payment.ts b/src/transaction/payment.ts index e3a7582dee..5a8e5199c2 100644 --- a/src/transaction/payment.ts +++ b/src/transaction/payment.ts @@ -9,7 +9,7 @@ import {Amount, Adjustment, MaxAdjustment, MinAdjustment, Memo} from '../common/types/objects' - export type Payment = { +export type Payment = { source: Adjustment | MaxAdjustment, destination: Adjustment | MinAdjustment, paths?: string, @@ -30,11 +30,22 @@ import {Amount, Adjustment, MaxAdjustment, limitQuality?: boolean } +function isMaxAdjustment( + source: Adjustment | MaxAdjustment): source is MaxAdjustment { +return (source).maxAmount !== undefined +} + +function isMinAdjustment( + destination: Adjustment | MinAdjustment): destination is MinAdjustment { +return (destination).minAmount !== undefined +} + function isXRPToXRPPayment(payment: Payment): boolean { - const sourceCurrency = _.get(payment, 'source.maxAmount.currency', - _.get(payment, 'source.amount.currency')) - const destinationCurrency = _.get(payment, 'destination.amount.currency', - _.get(payment, 'destination.minAmount.currency')) + const {source, destination} = payment + const sourceCurrency = isMaxAdjustment(source) + ? source.maxAmount.currency : source.amount.currency + const destinationCurrency = isMinAdjustment(destination) + ? destination.minAmount.currency : destination.amount.currency return sourceCurrency === 'XRP' && destinationCurrency === 'XRP' } @@ -74,21 +85,29 @@ function createPaymentTransaction(address: string, paymentArgument: Payment throw new ValidationError('address must match payment.source.address') } - if (((payment.source).maxAmount && (payment.destination).minAmount) || - ((payment.source).amount && (payment.destination).amount)) { + if ( + (isMaxAdjustment(payment.source) && isMinAdjustment(payment.destination)) + || + (!isMaxAdjustment(payment.source) && !isMinAdjustment(payment.destination)) + ) { throw new ValidationError('payment must specify either (source.maxAmount ' + 'and destination.amount) or (source.amount and destination.minAmount)') } + const destinationAmount = isMinAdjustment(payment.destination) + ? payment.destination.minAmount : payment.destination.amount + const sourceAmount = isMaxAdjustment(payment.source) + ? payment.source.maxAmount : payment.source.amount + // when using destination.minAmount, rippled still requires that we set // a destination amount in addition to DeliverMin. the destination amount // is interpreted as the maximum amount to send. we want to be sure to // send the whole source amount, so we set the destination amount to the // maximum possible amount. otherwise it's possible that the destination // cap could be hit before the source cap. - const amount = (payment.destination).minAmount && !isXRPToXRPPayment(payment) ? - createMaximalAmount((payment.destination).minAmount) : - ((payment.destination).amount || (payment.destination).minAmount) + const amount = + (isMinAdjustment(payment.destination) && !isXRPToXRPPayment(payment)) + ? createMaximalAmount(destinationAmount) : destinationAmount const txJSON: any = { TransactionType: 'Payment', @@ -121,16 +140,14 @@ function createPaymentTransaction(address: string, paymentArgument: Payment // temREDUNDANT_SEND_MAX removed in: // https://github.com/ripple/rippled/commit/ // c522ffa6db2648f1d8a987843e7feabf1a0b7de8/ - if (payment.allowPartialPayment === true - || (payment.destination).minAmount !== undefined) { + if (payment.allowPartialPayment || isMinAdjustment(payment.destination)) { txJSON.Flags |= paymentFlags.PartialPayment } - txJSON.SendMax = toRippledAmount( - (payment.source).maxAmount || (payment.source).amount) + txJSON.SendMax = toRippledAmount(sourceAmount) - if ((payment.destination).minAmount !== undefined) { - txJSON.DeliverMin = toRippledAmount((payment.destination).minAmount) + if (isMinAdjustment(payment.destination)) { + txJSON.DeliverMin = toRippledAmount(destinationAmount) } if (payment.paths !== undefined) { From 4b63431d9e1d1e148d650d3d68399be9b1433cf8 Mon Sep 17 00:00:00 2001 From: "Fred K. Schott" Date: Tue, 20 Mar 2018 12:35:14 -0700 Subject: [PATCH 3/4] Update payment.ts --- src/transaction/payment.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transaction/payment.ts b/src/transaction/payment.ts index 5a8e5199c2..230c5ab2a0 100644 --- a/src/transaction/payment.ts +++ b/src/transaction/payment.ts @@ -9,7 +9,7 @@ import {Amount, Adjustment, MaxAdjustment, MinAdjustment, Memo} from '../common/types/objects' -export type Payment = { +export interface Payment { source: Adjustment | MaxAdjustment, destination: Adjustment | MinAdjustment, paths?: string, From a3ae79630710d412361f43b1613509203b369ad8 Mon Sep 17 00:00:00 2001 From: Elliot Lee Date: Thu, 22 Mar 2018 00:46:12 -0700 Subject: [PATCH 4/4] Use recommended syntax for type assertion --- src/transaction/payment.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/transaction/payment.ts b/src/transaction/payment.ts index 230c5ab2a0..53a8b01728 100644 --- a/src/transaction/payment.ts +++ b/src/transaction/payment.ts @@ -32,12 +32,12 @@ export interface Payment { function isMaxAdjustment( source: Adjustment | MaxAdjustment): source is MaxAdjustment { -return (source).maxAmount !== undefined +return (source as MaxAdjustment).maxAmount !== undefined } function isMinAdjustment( destination: Adjustment | MinAdjustment): destination is MinAdjustment { -return (destination).minAmount !== undefined +return (destination as MinAdjustment).minAmount !== undefined } function isXRPToXRPPayment(payment: Payment): boolean {