mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-12-03 18:45:48 +00:00
Fix preparePayment when using source.amount/destination.minAmount (#1295)
See: https://github.com/ripple/ripple-lib/issues/1237#issuecomment-631670946 Fix #1237 Thanks to @leobel
This commit is contained in:
@@ -87,7 +87,12 @@ function applyAnyCounterpartyEncoding(payment: Payment): void {
|
|||||||
|
|
||||||
function createMaximalAmount(amount: Amount): Amount {
|
function createMaximalAmount(amount: Amount): Amount {
|
||||||
const maxXRPValue = '100000000000'
|
const maxXRPValue = '100000000000'
|
||||||
const maxIOUValue = '9999999999999999e80'
|
|
||||||
|
// Equivalent to '9999999999999999e80' but we cannot use that because sign()
|
||||||
|
// now checks that the encoded representation exactly matches the transaction
|
||||||
|
// as it was originally provided.
|
||||||
|
const maxIOUValue = '999999999999999900000000000000000000000000000000000000000000000000000000000000000000000000000000'
|
||||||
|
|
||||||
let maxValue
|
let maxValue
|
||||||
if (amount.currency === 'XRP') {
|
if (amount.currency === 'XRP') {
|
||||||
maxValue = maxXRPValue
|
maxValue = maxXRPValue
|
||||||
|
|||||||
@@ -2,6 +2,11 @@ import {assertResultMatch, TestSuite, assertRejects} from '../../utils'
|
|||||||
import responses from '../../fixtures/responses'
|
import responses from '../../fixtures/responses'
|
||||||
import requests from '../../fixtures/requests'
|
import requests from '../../fixtures/requests'
|
||||||
import {ValidationError} from 'ripple-api/common/errors'
|
import {ValidationError} from 'ripple-api/common/errors'
|
||||||
|
import binary from 'ripple-binary-codec'
|
||||||
|
import assert from 'assert-diff'
|
||||||
|
import {RippleAPI} from 'ripple-api'
|
||||||
|
|
||||||
|
const {schemaValidator} = RippleAPI._PRIVATE
|
||||||
const instructionsWithMaxLedgerVersionOffset = {maxLedgerVersionOffset: 100}
|
const instructionsWithMaxLedgerVersionOffset = {maxLedgerVersionOffset: 100}
|
||||||
const {preparePayment: REQUEST_FIXTURES} = requests
|
const {preparePayment: REQUEST_FIXTURES} = requests
|
||||||
const {preparePayment: RESPONSE_FIXTURES} = responses
|
const {preparePayment: RESPONSE_FIXTURES} = responses
|
||||||
@@ -288,6 +293,55 @@ export default <TestSuite>{
|
|||||||
assertResultMatch(response, RESPONSE_FIXTURES.noCounterparty, 'prepare')
|
assertResultMatch(response, RESPONSE_FIXTURES.noCounterparty, 'prepare')
|
||||||
},
|
},
|
||||||
|
|
||||||
|
'preparePayment with source.amount/destination.minAmount can be signed': async (api, address) => {
|
||||||
|
// See also: 'sign succeeds with source.amount/destination.minAmount'
|
||||||
|
|
||||||
|
const localInstructions = {
|
||||||
|
...instructionsWithMaxLedgerVersionOffset,
|
||||||
|
sequence: 23
|
||||||
|
}
|
||||||
|
const response = await api.preparePayment(
|
||||||
|
address,
|
||||||
|
{
|
||||||
|
"source": {
|
||||||
|
address,
|
||||||
|
"amount": {
|
||||||
|
"currency": "GBP",
|
||||||
|
"value": "0.1",
|
||||||
|
"counterparty": "rpat5TmYjDsnFSStmgTumFgXCM9eqsWPro"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"destination": {
|
||||||
|
"address": "rEX4LtGJubaUcMWCJULcy4NVxGT9ZEMVRq",
|
||||||
|
"minAmount": {
|
||||||
|
"currency": "USD",
|
||||||
|
"value": "0.1248548562296331",
|
||||||
|
"counterparty": "rMaa8VLBTjwTJWA2kSme4Sqgphhr6Lr6FH"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
localInstructions
|
||||||
|
)
|
||||||
|
|
||||||
|
// Important: check that the prepared transaction can actually be signed
|
||||||
|
// https://github.com/ripple/ripple-lib/issues/1237#issuecomment-631670946
|
||||||
|
|
||||||
|
const secret = 'shotKgaEotpcYsshSE39vmSnBDRim'
|
||||||
|
const result = api.sign(response.txJSON, secret)
|
||||||
|
const expectedResult = {
|
||||||
|
signedTransaction:
|
||||||
|
'12000022800200002400000017201B0086955361EC6386F26FC0FFFF0000000000000000000000005553440000000000DC596C88BCDE4E818D416FCDEEBF2C8656BADC9A68400000000000000C69D4438D7EA4C6800000000000000000000000000047425000000000000C155FFE99C8C91F67083CEFFDB69EBFE76348CA6AD4446F8C5D8A5E0B0000000000000000000000005553440000000000DC596C88BCDE4E818D416FCDEEBF2C8656BADC9A7321022B05847086686F9D0499B13136B94AD4323EE1B67D4C429ECC987AB35ACFA34574473045022100D9634523D8E232D4A7807A71856023D82AC928FA29848571B820867898413B5F022041AC00EC1F81A26A6504EBF844A38CC3204694EF2CC1A97A87632721631F93DA81145E7B112523F68D2F5E879DB4EAC51C6698A6930483149F500E50C2F016CA01945E5A1E5846B61EF2D376',
|
||||||
|
id: '1C558AA9B926C24FB6BBD6950B2DB1350A83F9F12E4385208867907019761A2D'
|
||||||
|
}
|
||||||
|
const decoded = binary.decode(result.signedTransaction)
|
||||||
|
assert(
|
||||||
|
decoded.Flags === 2147614720,
|
||||||
|
`Flags = ${decoded.Flags}, should be 2147614720`
|
||||||
|
)
|
||||||
|
assert.deepEqual(result, expectedResult)
|
||||||
|
schemaValidator.schemaValidate('sign', result)
|
||||||
|
},
|
||||||
|
|
||||||
'destination.minAmount': async (api, address) => {
|
'destination.minAmount': async (api, address) => {
|
||||||
const response = await api.preparePayment(
|
const response = await api.preparePayment(
|
||||||
address,
|
address,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import binary from 'ripple-binary-codec'
|
|||||||
import requests from '../../fixtures/requests'
|
import requests from '../../fixtures/requests'
|
||||||
import responses from '../../fixtures/responses'
|
import responses from '../../fixtures/responses'
|
||||||
import {TestSuite} from '../../utils'
|
import {TestSuite} from '../../utils'
|
||||||
|
|
||||||
const {schemaValidator} = RippleAPI._PRIVATE
|
const {schemaValidator} = RippleAPI._PRIVATE
|
||||||
const {sign: REQUEST_FIXTURES} = requests
|
const {sign: REQUEST_FIXTURES} = requests
|
||||||
const {sign: RESPONSE_FIXTURES} = responses
|
const {sign: RESPONSE_FIXTURES} = responses
|
||||||
@@ -145,6 +146,27 @@ export default <TestSuite>{
|
|||||||
schemaValidator.schemaValidate('sign', result)
|
schemaValidator.schemaValidate('sign', result)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
'sign succeeds with source.amount/destination.minAmount': async (api, address) => {
|
||||||
|
// See also: 'preparePayment with source.amount/destination.minAmount'
|
||||||
|
|
||||||
|
const txJSON =
|
||||||
|
'{"TransactionType":"Payment","Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Destination":"rEX4LtGJubaUcMWCJULcy4NVxGT9ZEMVRq","Amount":{"currency":"USD","issuer":"rMaa8VLBTjwTJWA2kSme4Sqgphhr6Lr6FH","value":"999999999999999900000000000000000000000000000000000000000000000000000000000000000000000000000000"},"Flags":2147614720,"SendMax":{"currency":"GBP","issuer":"rpat5TmYjDsnFSStmgTumFgXCM9eqsWPro","value":"0.1"},"DeliverMin":{"currency":"USD","issuer":"rMaa8VLBTjwTJWA2kSme4Sqgphhr6Lr6FH","value":"0.1248548562296331"},"Sequence":23,"LastLedgerSequence":8820051,"Fee":"12"}'
|
||||||
|
const secret = 'shotKgaEotpcYsshSE39vmSnBDRim'
|
||||||
|
const result = api.sign(txJSON, secret)
|
||||||
|
const expectedResult = {
|
||||||
|
signedTransaction:
|
||||||
|
'12000022800200002400000017201B0086955361EC6386F26FC0FFFF0000000000000000000000005553440000000000DC596C88BCDE4E818D416FCDEEBF2C8656BADC9A68400000000000000C69D4438D7EA4C6800000000000000000000000000047425000000000000C155FFE99C8C91F67083CEFFDB69EBFE76348CA6AD4446F8C5D8A5E0B0000000000000000000000005553440000000000DC596C88BCDE4E818D416FCDEEBF2C8656BADC9A7321022B05847086686F9D0499B13136B94AD4323EE1B67D4C429ECC987AB35ACFA34574473045022100D9634523D8E232D4A7807A71856023D82AC928FA29848571B820867898413B5F022041AC00EC1F81A26A6504EBF844A38CC3204694EF2CC1A97A87632721631F93DA81145E7B112523F68D2F5E879DB4EAC51C6698A6930483149F500E50C2F016CA01945E5A1E5846B61EF2D376',
|
||||||
|
id: '1C558AA9B926C24FB6BBD6950B2DB1350A83F9F12E4385208867907019761A2D'
|
||||||
|
}
|
||||||
|
const decoded = binary.decode(result.signedTransaction)
|
||||||
|
assert(
|
||||||
|
decoded.Flags === 2147614720,
|
||||||
|
`Flags = ${decoded.Flags}, should be 2147614720`
|
||||||
|
)
|
||||||
|
assert.deepEqual(result, expectedResult)
|
||||||
|
schemaValidator.schemaValidate('sign', result)
|
||||||
|
},
|
||||||
|
|
||||||
'throws when encoded tx does not match decoded tx - prepared payment': async (
|
'throws when encoded tx does not match decoded tx - prepared payment': async (
|
||||||
api,
|
api,
|
||||||
address
|
address
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"txJSON": "{\"Flags\":2147614720,\"TransactionType\":\"Payment\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Destination\":\"ra5nK24KXen9AHvsdFTKHSANinZseWnPcX\",\"Amount\":{\"value\":\"9999999999999999e80\",\"currency\":\"USD\",\"issuer\":\"ra5nK24KXen9AHvsdFTKHSANinZseWnPcX\"},\"SendMax\":{\"value\":\"5\",\"currency\":\"USD\",\"issuer\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\"},\"DeliverMin\":{\"value\":\"4.93463759481038\",\"currency\":\"USD\",\"issuer\":\"ra5nK24KXen9AHvsdFTKHSANinZseWnPcX\"},\"Paths\":[[{\"account\":\"rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B\"},{\"currency\":\"XRP\"},{\"issuer\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\",\"currency\":\"USD\"},{\"account\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\"},{\"account\":\"rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn\"}],[{\"account\":\"rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B\"},{\"currency\":\"XRP\"},{\"issuer\":\"rfsEoNBUBbvkf4jPcFe2u9CyaQagLVHGfP\",\"currency\":\"USD\"},{\"account\":\"rfsEoNBUBbvkf4jPcFe2u9CyaQagLVHGfP\"},{\"account\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\"}]],\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}",
|
"txJSON": "{\"Flags\":2147614720,\"TransactionType\":\"Payment\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Destination\":\"ra5nK24KXen9AHvsdFTKHSANinZseWnPcX\",\"Amount\":{\"value\":\"999999999999999900000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"currency\":\"USD\",\"issuer\":\"ra5nK24KXen9AHvsdFTKHSANinZseWnPcX\"},\"SendMax\":{\"value\":\"5\",\"currency\":\"USD\",\"issuer\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\"},\"DeliverMin\":{\"value\":\"4.93463759481038\",\"currency\":\"USD\",\"issuer\":\"ra5nK24KXen9AHvsdFTKHSANinZseWnPcX\"},\"Paths\":[[{\"account\":\"rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B\"},{\"currency\":\"XRP\"},{\"issuer\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\",\"currency\":\"USD\"},{\"account\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\"},{\"account\":\"rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn\"}],[{\"account\":\"rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B\"},{\"currency\":\"XRP\"},{\"issuer\":\"rfsEoNBUBbvkf4jPcFe2u9CyaQagLVHGfP\",\"currency\":\"USD\"},{\"account\":\"rfsEoNBUBbvkf4jPcFe2u9CyaQagLVHGfP\"},{\"account\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\"}]],\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}",
|
||||||
"instructions": {
|
"instructions": {
|
||||||
"fee": "0.000012",
|
"fee": "0.000012",
|
||||||
"sequence": 23,
|
"sequence": 23,
|
||||||
|
|||||||
Reference in New Issue
Block a user