mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-21 04:35:49 +00:00
Add prepareTransaction() (#898)
* Export iso8601ToRippleTime(), txFlags, convertStringToHex() * Fix a bug that caused fees exceeding 999 to throw an error e.g. '1,000' would not be recognized as a valid number. To use 6 decimal places, toFixed should be used instead of toFormat.
This commit is contained in:
34
src/api.ts
34
src/api.ts
@@ -1,5 +1,13 @@
|
|||||||
import {EventEmitter} from 'events'
|
import {EventEmitter} from 'events'
|
||||||
import {Connection, errors, validate, xrpToDrops, dropsToXrp} from './common'
|
import {
|
||||||
|
Connection,
|
||||||
|
errors,
|
||||||
|
validate,
|
||||||
|
xrpToDrops,
|
||||||
|
dropsToXrp,
|
||||||
|
iso8601ToRippleTime,
|
||||||
|
txFlags
|
||||||
|
} from './common'
|
||||||
import {
|
import {
|
||||||
connect,
|
connect,
|
||||||
disconnect,
|
disconnect,
|
||||||
@@ -57,9 +65,11 @@ import {
|
|||||||
|
|
||||||
import RangeSet from './common/rangeset'
|
import RangeSet from './common/rangeset'
|
||||||
import * as ledgerUtils from './ledger/utils'
|
import * as ledgerUtils from './ledger/utils'
|
||||||
|
import * as transactionUtils from './transaction/utils'
|
||||||
import * as schemaValidator from './common/schema-validator'
|
import * as schemaValidator from './common/schema-validator'
|
||||||
import {getServerInfo, getFee} from './common/serverinfo'
|
import {getServerInfo, getFee} from './common/serverinfo'
|
||||||
import {clamp} from './ledger/utils'
|
import {clamp} from './ledger/utils'
|
||||||
|
import {Instructions} from './transaction/types'
|
||||||
|
|
||||||
export type APIOptions = {
|
export type APIOptions = {
|
||||||
server?: string,
|
server?: string,
|
||||||
@@ -190,6 +200,26 @@ class RippleAPI extends EventEmitter {
|
|||||||
return this.request(command, nextPageParams)
|
return this.request(command, nextPageParams)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare a transaction.
|
||||||
|
*
|
||||||
|
* You can later submit the transaction with `submit()`.
|
||||||
|
*/
|
||||||
|
async prepareTransaction(txJSON: object, instructions: Instructions = {}) {
|
||||||
|
return transactionUtils.prepareTransaction(txJSON, this, instructions)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a string to hex.
|
||||||
|
*
|
||||||
|
* This can be used to generate `MemoData`, `MemoType`, and `MemoFormat`.
|
||||||
|
*
|
||||||
|
* @param string string to convert to hex
|
||||||
|
*/
|
||||||
|
convertStringToHex(string: string): string {
|
||||||
|
return transactionUtils.convertStringToHex(string)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes multiple paged requests to the API to return a given number of
|
* Makes multiple paged requests to the API to return a given number of
|
||||||
* resources. _requestAll() will make multiple requests until the `limit`
|
* resources. _requestAll() will make multiple requests until the `limit`
|
||||||
@@ -297,6 +327,8 @@ class RippleAPI extends EventEmitter {
|
|||||||
|
|
||||||
xrpToDrops = xrpToDrops
|
xrpToDrops = xrpToDrops
|
||||||
dropsToXrp = dropsToXrp
|
dropsToXrp = dropsToXrp
|
||||||
|
iso8601ToRippleTime = iso8601ToRippleTime
|
||||||
|
txFlags = txFlags
|
||||||
}
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
|||||||
@@ -61,6 +61,8 @@ function getServerInfo(this: RippleAPI): Promise<GetServerInfoResponse> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is a public API that can be called directly.
|
||||||
|
// This is not used by the `prepare*` methods. See `src/transaction/utils.ts`
|
||||||
async function getFee(
|
async function getFee(
|
||||||
this: RippleAPI,
|
this: RippleAPI,
|
||||||
cushion?: number
|
cushion?: number
|
||||||
@@ -79,7 +81,7 @@ async function getFee(
|
|||||||
// Cap fee to `this._maxFeeXRP`
|
// Cap fee to `this._maxFeeXRP`
|
||||||
fee = BigNumber.min(fee, this._maxFeeXRP)
|
fee = BigNumber.min(fee, this._maxFeeXRP)
|
||||||
// Round fee to 6 decimal places
|
// Round fee to 6 decimal places
|
||||||
return (new BigNumber(fee.toFormat(6))).toString(10)
|
return (new BigNumber(fee.toFixed(6))).toString(10)
|
||||||
}
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ const ValidationError = utils.common.errors.ValidationError
|
|||||||
import {Instructions, Prepare} from './types'
|
import {Instructions, Prepare} from './types'
|
||||||
import {Amount, Adjustment, MaxAdjustment,
|
import {Amount, Adjustment, MaxAdjustment,
|
||||||
MinAdjustment, Memo} from '../common/types/objects'
|
MinAdjustment, Memo} from '../common/types/objects'
|
||||||
|
import {xrpToDrops} from '../common'
|
||||||
|
|
||||||
|
|
||||||
export interface Payment {
|
export interface Payment {
|
||||||
@@ -50,7 +51,7 @@ function isXRPToXRPPayment(payment: Payment): boolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function isIOUWithoutCounterparty(amount: Amount): boolean {
|
function isIOUWithoutCounterparty(amount: Amount): boolean {
|
||||||
return amount && amount.currency !== 'XRP'
|
return amount && amount.currency !== 'XRP' && amount.currency !== 'drops'
|
||||||
&& amount.counterparty === undefined
|
&& amount.counterparty === undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,7 +73,14 @@ function applyAnyCounterpartyEncoding(payment: Payment): void {
|
|||||||
function createMaximalAmount(amount: Amount): Amount {
|
function createMaximalAmount(amount: Amount): Amount {
|
||||||
const maxXRPValue = '100000000000'
|
const maxXRPValue = '100000000000'
|
||||||
const maxIOUValue = '9999999999999999e80'
|
const maxIOUValue = '9999999999999999e80'
|
||||||
const maxValue = amount.currency === 'XRP' ? maxXRPValue : maxIOUValue
|
let maxValue
|
||||||
|
if (amount.currency === 'XRP') {
|
||||||
|
maxValue = maxXRPValue
|
||||||
|
} else if (amount.currency === 'drops') {
|
||||||
|
maxValue = xrpToDrops(maxXRPValue)
|
||||||
|
} else {
|
||||||
|
maxValue = maxIOUValue
|
||||||
|
}
|
||||||
return _.assign({}, amount, {value: maxValue})
|
return _.assign({}, amount, {value: maxValue})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
409
test/api-test.js
409
test/api-test.js
@@ -404,6 +404,23 @@ describe('RippleAPI', function () {
|
|||||||
}, /Fee of 2\.1 XRP exceeds max of 2 XRP\. To use this fee, increase `maxFeeXRP` in the RippleAPI constructor\./)
|
}, /Fee of 2\.1 XRP exceeds max of 2 XRP\. To use this fee, increase `maxFeeXRP` in the RippleAPI constructor\./)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('preparePayment - caps fee at 2 XRP by default', function () {
|
||||||
|
this.api._feeCushion = 1000000;
|
||||||
|
|
||||||
|
const expectedResponse = {
|
||||||
|
"txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"Payment\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Destination\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"Amount\":{\"value\":\"0.01\",\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"SendMax\":{\"value\":\"0.01\",\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"LastLedgerSequence\":8820051,\"Fee\":\"2000000\",\"Sequence\":23}",
|
||||||
|
"instructions": {
|
||||||
|
"fee": "2",
|
||||||
|
"sequence": 23,
|
||||||
|
"maxLedgerVersion": 8820051
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.api.preparePayment(
|
||||||
|
address, requests.preparePayment.normal, instructions).then(
|
||||||
|
_.partial(checkResult, expectedResponse, 'prepare'));
|
||||||
|
});
|
||||||
|
|
||||||
it('preparePayment - allows fee exceeding 2 XRP when maxFeeXRP is higher', function () {
|
it('preparePayment - allows fee exceeding 2 XRP when maxFeeXRP is higher', function () {
|
||||||
this.api._maxFeeXRP = '2.2'
|
this.api._maxFeeXRP = '2.2'
|
||||||
const localInstructions = _.defaults({
|
const localInstructions = _.defaults({
|
||||||
@@ -698,6 +715,384 @@ describe('RippleAPI', function () {
|
|||||||
'prepare'));
|
'prepare'));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('prepareTransaction - Payment', function () {
|
||||||
|
|
||||||
|
it('normal', function () {
|
||||||
|
const localInstructions = _.defaults({
|
||||||
|
maxFee: '0.000012'
|
||||||
|
}, instructions);
|
||||||
|
|
||||||
|
const txJSON = {
|
||||||
|
TransactionType: 'Payment',
|
||||||
|
Account: address,
|
||||||
|
Destination: 'rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo',
|
||||||
|
Amount: {
|
||||||
|
currency: 'USD',
|
||||||
|
issuer: 'rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM',
|
||||||
|
value: '0.01'
|
||||||
|
},
|
||||||
|
SendMax: {
|
||||||
|
currency: 'USD',
|
||||||
|
issuer: 'rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM',
|
||||||
|
value: '0.01'
|
||||||
|
},
|
||||||
|
Flags: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.api.prepareTransaction(txJSON, localInstructions).then(
|
||||||
|
_.partial(checkResult, responses.preparePayment.normal, 'prepare'));
|
||||||
|
});
|
||||||
|
|
||||||
|
// prepareTransaction - Payment
|
||||||
|
it('min amount xrp', function () {
|
||||||
|
const localInstructions = _.defaults({
|
||||||
|
maxFee: '0.000012'
|
||||||
|
}, instructions);
|
||||||
|
|
||||||
|
const txJSON = {
|
||||||
|
TransactionType: 'Payment',
|
||||||
|
Account: address,
|
||||||
|
Destination: 'rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo',
|
||||||
|
|
||||||
|
// Max amount to send. Use 100 billion XRP to
|
||||||
|
// ensure that we send the full SendMax amount.
|
||||||
|
Amount: '100000000000000000',
|
||||||
|
|
||||||
|
SendMax: {
|
||||||
|
currency: 'USD',
|
||||||
|
issuer: 'rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM',
|
||||||
|
value: '0.01'
|
||||||
|
},
|
||||||
|
DeliverMin: '10000',
|
||||||
|
Flags: this.api.txFlags.Payment.PartialPayment
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.api.prepareTransaction(txJSON, localInstructions).then(
|
||||||
|
_.partial(checkResult,
|
||||||
|
responses.preparePayment.minAmountXRP, 'prepare'));
|
||||||
|
});
|
||||||
|
|
||||||
|
// prepareTransaction - Payment
|
||||||
|
it('min amount xrp2xrp', function () {
|
||||||
|
const txJSON = {
|
||||||
|
TransactionType: 'Payment',
|
||||||
|
Account: address,
|
||||||
|
Destination: 'rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo',
|
||||||
|
Amount: '10000',
|
||||||
|
Flags: 0
|
||||||
|
}
|
||||||
|
return this.api.prepareTransaction(txJSON, instructions).then(
|
||||||
|
_.partial(checkResult,
|
||||||
|
responses.preparePayment.minAmountXRPXRP, 'prepare'));
|
||||||
|
});
|
||||||
|
|
||||||
|
// prepareTransaction - Payment
|
||||||
|
it('with all options specified', function () {
|
||||||
|
return this.api.getLedgerVersion().then(ver => {
|
||||||
|
const localInstructions = {
|
||||||
|
maxLedgerVersion: ver + 100,
|
||||||
|
fee: '0.000012'
|
||||||
|
};
|
||||||
|
const txJSON = {
|
||||||
|
TransactionType: 'Payment',
|
||||||
|
Account: address,
|
||||||
|
Destination: 'rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo',
|
||||||
|
Amount: '10000',
|
||||||
|
InvoiceID: 'A98FD36C17BE2B8511AD36DC335478E7E89F06262949F36EB88E2D683BBCC50A',
|
||||||
|
SourceTag: 14,
|
||||||
|
DestinationTag: 58,
|
||||||
|
Memos: [
|
||||||
|
{
|
||||||
|
Memo: {
|
||||||
|
MemoType: this.api.convertStringToHex('test'),
|
||||||
|
MemoFormat: this.api.convertStringToHex('text/plain'),
|
||||||
|
MemoData: this.api.convertStringToHex('texted data')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
Flags: 0 | this.api.txFlags.Payment.NoRippleDirect | this.api.txFlags.Payment.LimitQuality
|
||||||
|
}
|
||||||
|
return this.api.prepareTransaction(txJSON, localInstructions).then(
|
||||||
|
_.partial(checkResult,
|
||||||
|
responses.preparePayment.allOptions, 'prepare'));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// prepareTransaction - Payment
|
||||||
|
it('fee is capped at default maxFee of 2 XRP', function () {
|
||||||
|
this.api._feeCushion = 1000000;
|
||||||
|
|
||||||
|
const txJSON = {
|
||||||
|
"Flags": 2147483648,
|
||||||
|
"TransactionType": "Payment",
|
||||||
|
"Account": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
|
||||||
|
"Destination": "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo",
|
||||||
|
"Amount": {
|
||||||
|
"value": "0.01",
|
||||||
|
"currency": "USD",
|
||||||
|
"issuer": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"
|
||||||
|
},
|
||||||
|
"SendMax": {
|
||||||
|
"value": "0.01",
|
||||||
|
"currency": "USD",
|
||||||
|
"issuer": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"
|
||||||
|
},
|
||||||
|
"LastLedgerSequence": 8820051
|
||||||
|
}
|
||||||
|
|
||||||
|
const localInstructions = {
|
||||||
|
"maxLedgerVersion": 8820051
|
||||||
|
}
|
||||||
|
|
||||||
|
const expectedResponse = {
|
||||||
|
"txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"Payment\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Destination\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"Amount\":{\"value\":\"0.01\",\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"SendMax\":{\"value\":\"0.01\",\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"LastLedgerSequence\":8820051,\"Fee\":\"2000000\",\"Sequence\":23}",
|
||||||
|
"instructions": {
|
||||||
|
"fee": "2",
|
||||||
|
"sequence": 23,
|
||||||
|
"maxLedgerVersion": 8820051
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.api.prepareTransaction(txJSON, localInstructions).then(
|
||||||
|
_.partial(checkResult,
|
||||||
|
expectedResponse, 'prepare'));
|
||||||
|
});
|
||||||
|
|
||||||
|
// prepareTransaction - Payment
|
||||||
|
it('fee is capped to custom maxFeeXRP when maxFee exceeds maxFeeXRP', function () {
|
||||||
|
this.api._feeCushion = 1000000
|
||||||
|
this.api._maxFeeXRP = '3'
|
||||||
|
const localInstructions = _.defaults({
|
||||||
|
maxFee: '4' // We are testing that this does not matter; fee is still capped to maxFeeXRP
|
||||||
|
}, instructions);
|
||||||
|
|
||||||
|
const txJSON = {
|
||||||
|
"Flags": 2147483648,
|
||||||
|
"TransactionType": "Payment",
|
||||||
|
"Account": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
|
||||||
|
"Destination": "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo",
|
||||||
|
"Amount": {
|
||||||
|
"value": "0.01",
|
||||||
|
"currency": "USD",
|
||||||
|
"issuer": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"
|
||||||
|
},
|
||||||
|
"SendMax": {
|
||||||
|
"value": "0.01",
|
||||||
|
"currency": "USD",
|
||||||
|
"issuer": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"
|
||||||
|
},
|
||||||
|
"LastLedgerSequence": 8820051
|
||||||
|
}
|
||||||
|
|
||||||
|
const expectedResponse = {
|
||||||
|
"txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"Payment\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Destination\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"Amount\":{\"value\":\"0.01\",\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"SendMax\":{\"value\":\"0.01\",\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"LastLedgerSequence\":8820051,\"Fee\":\"3000000\",\"Sequence\":23}",
|
||||||
|
"instructions": {
|
||||||
|
"fee": "3",
|
||||||
|
"sequence": 23,
|
||||||
|
"maxLedgerVersion": 8820051
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.api.prepareTransaction(txJSON, localInstructions).then(
|
||||||
|
_.partial(checkResult,
|
||||||
|
expectedResponse, 'prepare'));
|
||||||
|
});
|
||||||
|
|
||||||
|
// prepareTransaction - Payment
|
||||||
|
it('fee is capped to maxFee', function () {
|
||||||
|
this.api._feeCushion = 1000000
|
||||||
|
this.api._maxFeeXRP = '5'
|
||||||
|
const localInstructions = _.defaults({
|
||||||
|
maxFee: '4' // maxFeeXRP does not matter if maxFee is lower than maxFeeXRP
|
||||||
|
}, instructions);
|
||||||
|
|
||||||
|
const txJSON = {
|
||||||
|
"Flags": 2147483648,
|
||||||
|
"TransactionType": "Payment",
|
||||||
|
"Account": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
|
||||||
|
"Destination": "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo",
|
||||||
|
"Amount": {
|
||||||
|
"value": "0.01",
|
||||||
|
"currency": "USD",
|
||||||
|
"issuer": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"
|
||||||
|
},
|
||||||
|
"SendMax": {
|
||||||
|
"value": "0.01",
|
||||||
|
"currency": "USD",
|
||||||
|
"issuer": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"
|
||||||
|
},
|
||||||
|
"LastLedgerSequence": 8820051,
|
||||||
|
}
|
||||||
|
|
||||||
|
const expectedResponse = {
|
||||||
|
"txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"Payment\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Destination\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"Amount\":{\"value\":\"0.01\",\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"SendMax\":{\"value\":\"0.01\",\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"LastLedgerSequence\":8820051,\"Fee\":\"4000000\",\"Sequence\":23}",
|
||||||
|
"instructions": {
|
||||||
|
"fee": "4",
|
||||||
|
"sequence": 23,
|
||||||
|
"maxLedgerVersion": 8820051
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.api.prepareTransaction(txJSON, localInstructions).then(
|
||||||
|
_.partial(checkResult,
|
||||||
|
expectedResponse, 'prepare'));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('fee - calculated fee does not use more than 6 decimal places', function () {
|
||||||
|
this.api.connection._send(JSON.stringify({
|
||||||
|
command: 'config',
|
||||||
|
data: { loadFactor: 5407.96875 }
|
||||||
|
}));
|
||||||
|
|
||||||
|
const expectedResponse = {
|
||||||
|
"txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"Payment\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Destination\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"Amount\":{\"value\":\"0.01\",\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"SendMax\":{\"value\":\"0.01\",\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"LastLedgerSequence\":8820051,\"Fee\":\"64896\",\"Sequence\":23}",
|
||||||
|
"instructions": {
|
||||||
|
"fee": "0.064896",
|
||||||
|
"sequence": 23,
|
||||||
|
"maxLedgerVersion": 8820051
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.api.preparePayment(
|
||||||
|
address, requests.preparePayment.normal, instructions).then(
|
||||||
|
_.partial(checkResult, expectedResponse, 'prepare'));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('prepareTransaction - PaymentChannelCreate', function () {
|
||||||
|
const localInstructions = _.defaults({
|
||||||
|
maxFee: '0.000012'
|
||||||
|
}, instructions);
|
||||||
|
return this.api.prepareTransaction({
|
||||||
|
Account: address,
|
||||||
|
TransactionType: 'PaymentChannelCreate',
|
||||||
|
Amount: '1000000', // 1 XRP in drops. Use a string-encoded integer.
|
||||||
|
Destination: 'rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW',
|
||||||
|
SettleDelay: 86400,
|
||||||
|
PublicKey: '32D2471DB72B27E3310F355BB33E339BF26F8392D5A93D3BC0FC3B566612DA0F0A'
|
||||||
|
// If cancelAfter is used, you must use RippleTime.
|
||||||
|
// You can use `iso8601ToRippleTime()` to convert to RippleTime.
|
||||||
|
|
||||||
|
// Other fields are available (but not used in this test),
|
||||||
|
// including `sourceTag` and `destinationTag`.
|
||||||
|
}, localInstructions).then(
|
||||||
|
_.partial(checkResult, responses.preparePaymentChannelCreate.normal,
|
||||||
|
'prepare'));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('prepareTransaction - PaymentChannelCreate full', function () {
|
||||||
|
const txJSON = {
|
||||||
|
Account: address,
|
||||||
|
TransactionType: 'PaymentChannelCreate',
|
||||||
|
Amount: this.api.xrpToDrops('1'), // or '1000000'
|
||||||
|
Destination: 'rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW',
|
||||||
|
SettleDelay: 86400,
|
||||||
|
|
||||||
|
// Ensure this is in upper case if it is not already
|
||||||
|
PublicKey: '32D2471DB72B27E3310F355BB33E339BF26F8392D5A93D3BC0FC3B566612DA0F0A'.toUpperCase(),
|
||||||
|
|
||||||
|
CancelAfter: this.api.iso8601ToRippleTime('2017-02-17T15:04:57Z'),
|
||||||
|
SourceTag: 11747,
|
||||||
|
DestinationTag: 23480
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.api.prepareTransaction(txJSON).then(
|
||||||
|
_.partial(checkResult, responses.preparePaymentChannelCreate.full,
|
||||||
|
'prepare'));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('prepareTransaction - PaymentChannelFund', function () {
|
||||||
|
const localInstructions = _.defaults({
|
||||||
|
maxFee: '0.000012'
|
||||||
|
}, instructions);
|
||||||
|
|
||||||
|
const txJSON = {
|
||||||
|
Account: address,
|
||||||
|
TransactionType: 'PaymentChannelFund',
|
||||||
|
Channel: 'C1AE6DDDEEC05CF2978C0BAD6FE302948E9533691DC749DCDD3B9E5992CA6198',
|
||||||
|
Amount: this.api.xrpToDrops('1') // or '1000000'
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.api.prepareTransaction(txJSON, localInstructions).then(
|
||||||
|
_.partial(checkResult, responses.preparePaymentChannelFund.normal,
|
||||||
|
'prepare'));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('prepareTransaction - PaymentChannelFund full', function () {
|
||||||
|
const txJSON = {
|
||||||
|
Account: address,
|
||||||
|
TransactionType: 'PaymentChannelFund',
|
||||||
|
Channel: 'C1AE6DDDEEC05CF2978C0BAD6FE302948E9533691DC749DCDD3B9E5992CA6198',
|
||||||
|
Amount: this.api.xrpToDrops('1'), // or '1000000'
|
||||||
|
Expiration: this.api.iso8601ToRippleTime('2017-02-17T15:04:57Z')
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.api.prepareTransaction(txJSON).then(
|
||||||
|
_.partial(checkResult, responses.preparePaymentChannelFund.full,
|
||||||
|
'prepare'));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('prepareTransaction - PaymentChannelClaim', function () {
|
||||||
|
const localInstructions = _.defaults({
|
||||||
|
maxFee: '0.000012'
|
||||||
|
}, instructions);
|
||||||
|
|
||||||
|
const txJSON = {
|
||||||
|
Account: address,
|
||||||
|
TransactionType: 'PaymentChannelClaim',
|
||||||
|
Channel: 'C1AE6DDDEEC05CF2978C0BAD6FE302948E9533691DC749DCDD3B9E5992CA6198',
|
||||||
|
Flags: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.api.prepareTransaction(txJSON, localInstructions).then(
|
||||||
|
_.partial(checkResult, responses.preparePaymentChannelClaim.normal,
|
||||||
|
'prepare'));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('prepareTransaction - PaymentChannelClaim with renew', function () {
|
||||||
|
const localInstructions = _.defaults({
|
||||||
|
maxFee: '0.000012'
|
||||||
|
}, instructions);
|
||||||
|
|
||||||
|
const txJSON = {
|
||||||
|
Account: address,
|
||||||
|
TransactionType: 'PaymentChannelClaim',
|
||||||
|
Channel: 'C1AE6DDDEEC05CF2978C0BAD6FE302948E9533691DC749DCDD3B9E5992CA6198',
|
||||||
|
Balance: this.api.xrpToDrops('1'), // or '1000000'
|
||||||
|
Amount: this.api.xrpToDrops('1'), // or '1000000'
|
||||||
|
Signature: '30440220718D264EF05CAED7C781FF6DE298DCAC68D002562C9BF3A07C1E721B420C0DAB02203A5A4779EF4D2CCC7BC3EF886676D803A9981B928D3B8ACA483B80ECA3CD7B9B',
|
||||||
|
PublicKey: '32D2471DB72B27E3310F355BB33E339BF26F8392D5A93D3BC0FC3B566612DA0F0A',
|
||||||
|
Flags: 0
|
||||||
|
}
|
||||||
|
txJSON.Flags |= this.api.txFlags.PaymentChannelClaim.Renew
|
||||||
|
|
||||||
|
return this.api.prepareTransaction(txJSON, localInstructions).then(
|
||||||
|
_.partial(checkResult, responses.preparePaymentChannelClaim.renew,
|
||||||
|
'prepare'));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('prepareTransaction - PaymentChannelClaim with close', function () {
|
||||||
|
const localInstructions = _.defaults({
|
||||||
|
maxFee: '0.000012'
|
||||||
|
}, instructions);
|
||||||
|
|
||||||
|
const txJSON = {
|
||||||
|
Account: address,
|
||||||
|
TransactionType: 'PaymentChannelClaim',
|
||||||
|
Channel: 'C1AE6DDDEEC05CF2978C0BAD6FE302948E9533691DC749DCDD3B9E5992CA6198',
|
||||||
|
Balance: this.api.xrpToDrops('1'), // or 1000000
|
||||||
|
Amount: this.api.xrpToDrops('1'), // or 1000000
|
||||||
|
Signature: '30440220718D264EF05CAED7C781FF6DE298DCAC68D002562C9BF3A07C1E721B420C0DAB02203A5A4779EF4D2CCC7BC3EF886676D803A9981B928D3B8ACA483B80ECA3CD7B9B',
|
||||||
|
PublicKey: '32D2471DB72B27E3310F355BB33E339BF26F8392D5A93D3BC0FC3B566612DA0F0A',
|
||||||
|
Flags: 0
|
||||||
|
}
|
||||||
|
txJSON.Flags |= this.api.txFlags.PaymentChannelClaim.Close
|
||||||
|
|
||||||
|
return this.api.prepareTransaction(txJSON, localInstructions).then(
|
||||||
|
_.partial(checkResult, responses.preparePaymentChannelClaim.close,
|
||||||
|
'prepare'));
|
||||||
|
});
|
||||||
|
|
||||||
it('preparePaymentChannelCreate', function () {
|
it('preparePaymentChannelCreate', function () {
|
||||||
const localInstructions = _.defaults({
|
const localInstructions = _.defaults({
|
||||||
maxFee: '0.000012'
|
maxFee: '0.000012'
|
||||||
@@ -1775,6 +2170,20 @@ describe('RippleAPI', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('getFee - high load_factor with custom maxFeeXRP', function () {
|
||||||
|
// Ensure that overriding with high maxFeeXRP of '51540' causes no errors.
|
||||||
|
// (fee will actually be 51539.607552)
|
||||||
|
this.api._maxFeeXRP = '51540'
|
||||||
|
this.api.connection._send(JSON.stringify({
|
||||||
|
command: 'config',
|
||||||
|
data: { highLoadFactor: true }
|
||||||
|
}));
|
||||||
|
|
||||||
|
return this.api.getFee().then(fee => {
|
||||||
|
assert.strictEqual(fee, '51539.607552');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('fee - default maxFee of 2 XRP', function () {
|
it('fee - default maxFee of 2 XRP', function () {
|
||||||
this.api._feeCushion = 1000000;
|
this.api._feeCushion = 1000000;
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,5 @@
|
|||||||
],
|
],
|
||||||
"invoiceID": "A98FD36C17BE2B8511AD36DC335478E7E89F06262949F36EB88E2D683BBCC50A",
|
"invoiceID": "A98FD36C17BE2B8511AD36DC335478E7E89F06262949F36EB88E2D683BBCC50A",
|
||||||
"noDirectRipple": true,
|
"noDirectRipple": true,
|
||||||
"limitQuality": true,
|
"limitQuality": true
|
||||||
"paths": "[[{\"account\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\",\"currency\":\"USD\",\"issuer\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\",\"type\":49,\"type_hex\":\"0000000000000031\"},{\"currency\":\"LTC\",\"issuer\":\"rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX\",\"type\":48,\"type_hex\":\"0000000000000030\"},{\"account\":\"rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX\",\"currency\":\"LTC\",\"issuer\":\"rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX\",\"type\":49,\"type_hex\":\"0000000000000031\"}]]"
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,7 @@
|
|||||||
"address": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
|
"address": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
|
||||||
"amount": {
|
"amount": {
|
||||||
"value": "0.01",
|
"value": "0.01",
|
||||||
"currency": "XRP",
|
"currency": "XRP"
|
||||||
"counterparty": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"destination": {
|
"destination": {
|
||||||
|
|||||||
Reference in New Issue
Block a user