diff --git a/docs/index.md b/docs/index.md index cd5b581e..2fa42b4d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -27,6 +27,9 @@ - [Escrow Creation](#escrow-creation) - [Escrow Cancellation](#escrow-cancellation) - [Escrow Execution](#escrow-execution) + - [Check Create](#check-create) + - [Check Cancel](#check-cancel) + - [Check Cash](#check-cash) - [Payment Channel Create](#payment-channel-create) - [Payment Channel Fund](#payment-channel-fund) - [Payment Channel Claim](#payment-channel-claim) @@ -60,6 +63,9 @@ - [preparePaymentChannelCreate](#preparepaymentchannelcreate) - [preparePaymentChannelClaim](#preparepaymentchannelclaim) - [preparePaymentChannelFund](#preparepaymentchannelfund) + - [prepareCheckCreate](#preparecheckcreate) + - [prepareCheckCancel](#preparecheckcancel) + - [prepareCheckCash](#preparecheckcash) - [sign](#sign) - [combine](#combine) - [submit](#submit) @@ -266,6 +272,9 @@ Type | Description [escrowCreation](#escrow-creation) | An `escrowCreation` transaction creates an escrow on the ledger, which locks XRP until a cryptographic condition is met or it expires. It is like an escrow service where the XRP Ledger acts as the escrow agent. [escrowCancellation](#escrow-cancellation) | An `escrowCancellation` transaction unlocks the funds in an escrow and sends them back to the creator of the escrow, but it will only work after the escrow expires. [escrowExecution](#escrow-execution) | An `escrowExecution` transaction unlocks the funds in an escrow and sends them to the destination of the escrow, but it will only work if the cryptographic condition is provided. +[checkCreate](#check-create) | A `checkCreate` transaction creates a check on the ledger, which is a deferred payment that can be cashed by its intended destination. +[checkCancel](#check-cancel) | A `checkCancel` transaction cancels an unreedemed Check, removing it from the ledger without sending any money. +[checkCash](#checkCash) | A `checkCash` transaction redeems a Check to receive up to the amount authorized by the corresponding `checkCreate` transaction. Only the `destination` address of a Check can cash it. ## Transaction Flow @@ -280,6 +289,9 @@ Executing a transaction with `RippleAPI` requires the following four steps: * [prepareEscrowCreation](#prepareescrowcreation) * [prepareEscrowCancellation](#prepareescrowcancellation) * [prepareEscrowExecution](#prepareescrowexecution) + * [prepareCheckCreate](#preparecheckcreate) + * [prepareCheckCancel](#preparecheckcancel) + * [prepareCheckCash](#preparecheckcash) 2. [Sign](#sign) - Cryptographically sign the transaction locally and save the [transaction ID](#transaction-id). Signing is how the owner of an account authorizes a transaction to take place. For multisignature transactions, the `signedTransaction` fields returned by `sign` must be collected and passed to the [combine](#combine) method. 3. [Submit](#submit) - Submit the transaction to the connected server. 4. Verify - Verify that the transaction got validated by querying with [getTransaction](#gettransaction). This is necessary because transactions may fail even if they were successfully submitted. @@ -593,6 +605,74 @@ memos | [memos](#transaction-memos) | *Optional* Array of memos to attach to the ``` +## Check Create + +See [Transaction Types](#transaction-types) for a description. + +Name | Type | Description +---- | ---- | ----------- +destination | [address](#address) | Address of the account that can cash the check. +sendMax | [laxAmount](#amount) | Amount of source currency the check is allowed to debit the sender, including transfer fees on non-XRP currencies. +destinationTag | integer | *Optional* Destination tag that identifies the reason for the check, or a hosted recipient to pay. +expiration | date-time string | *Optional* Time after which the check is no longer valid. +invoiceID | string | *Optional* 256-bit hash, as a 64-character hexadecimal string, representing a specific reason or identifier for this check. + +### Example + + +```json +{ + "destination": "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW", + "sendMax": { + "currency": "XRP", + "value": "1" + } +} +``` + + +## Check Cancel + +See [Transaction Types](#transaction-types) for a description. + +Name | Type | Description +---- | ---- | ----------- +checkID | string | The ID of the Check ledger object to cancel, as a 64-character hexadecimal string. + +### Example + + +```json +{ + "checkID": "49647F0D748DC3FE26BDACBC57F251AADEFFF391403EC9BF87C97F67E9977FB0" +} +``` + + +## Check Cash + +See [Transaction Types](#transaction-types) for a description. + +Name | Type | Description +---- | ---- | ----------- +checkID | string | The ID of the Check ledger object to cash, as a 64-character hexadecimal string. +amount | [laxAmount](#amount) | *Optional* Redeem the Check for exactly this amount, if possible. The currency must match that of the sendMax of the corresponding CheckCreate transaction. You must provide either this field or deliverMin. +deliverMin | [laxAmount](#amount) | *Optional* Redeem the Check for at least this amount and for as much as possible. The currency must match that of the sendMax of the corresponding CheckCreate transaction. You must provide either this field or amount. + +### Example + + +```json +{ + "amount": { + "currency": "XRP", + "value": "1" + }, + "checkID": "838766BA2B995C00744175F69A1B11E32C3DBC40E64801A4056FCBD657F57334" +} +``` + + ## Payment Channel Create See [Transaction Types](#transaction-types) for a description. @@ -3592,6 +3672,176 @@ return api.preparePaymentChannelFund(address, paymentChannelFund).then(prepared ``` +## prepareCheckCreate + +`prepareCheckCreate(address: string, checkCreate: Object, instructions: Object): Promise` + +Prepare a Check creation transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit). + +### Parameters + +Name | Type | Description +---- | ---- | ----------- +address | [address](#address) | The address of the account that is creating the transaction. +checkCreate | [checkCreate](#check-create) | The specification of the Check create creation to prepare. +instructions | [instructions](#transaction-instructions) | *Optional* Instructions for executing the transaction + +### Return Value + +This method returns a promise that resolves with an object with the following structure: + + + +Name | Type | Description +---- | ---- | ----------- +txJSON | string | The prepared transaction in rippled JSON format. +instructions | object | The instructions for how to execute the transaction after adding automatic defaults. +*instructions.* fee | [value](#value) | An exact fee to pay for the transaction. See [Transaction Fees](#transaction-fees) for more information. +*instructions.* sequence | [sequence](#account-sequence-number) | The initiating account's sequence number for this transaction. +*instructions.* maxLedgerVersion | integer,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum. + +### Example + +```javascript +const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59'; +const checkCreate = { + "destination": "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW", + "sendMax": { + "currency": "XRP", + "value": "1" + } +}; +return api.prepareCheckCreate(address, checkCreate).then(prepared => + {/* ... */}); +``` + + +```json +{ + "txJSON": "{\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"TransactionType\":\"CheckCreate\",\"Destination\":\"rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW\",\"SendMax\":\"1000000\",\"Flags\":2147483648,\"LastLedgerSequence\":8820051,\"Sequence\":23,\"Fee\":\"12\"}", + "instructions": { + "fee": "0.000012", + "sequence": 23, + "maxLedgerVersion": 8820051 + } +} +``` + + +## prepareCheckCancel + +`prepareCheckCancel(address: string, checkCancel: Object, instructions: Object): Promise` + +Prepare a Check cancellation transaction. This cancels an unredeemed Check, removing it from the ledger without sending any money. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit). + +### Parameters + +Name | Type | Description +---- | ---- | ----------- +address | [address](#address) | The address of the account that is creating the transaction. +checkCancel | [checkCancel](#check-cancel) | The specification of the Check cancellation to prepare. +instructions | [instructions](#transaction-instructions) | *Optional* Instructions for executing the transaction + +### Return Value + +This method returns a promise that resolves with an object with the following structure: + + + +Name | Type | Description +---- | ---- | ----------- +txJSON | string | The prepared transaction in rippled JSON format. +instructions | object | The instructions for how to execute the transaction after adding automatic defaults. +*instructions.* fee | [value](#value) | An exact fee to pay for the transaction. See [Transaction Fees](#transaction-fees) for more information. +*instructions.* sequence | [sequence](#account-sequence-number) | The initiating account's sequence number for this transaction. +*instructions.* maxLedgerVersion | integer,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum. + +### Example + +```javascript +const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59'; +const checkCancel = { + "checkID": "49647F0D748DC3FE26BDACBC57F251AADEFFF391403EC9BF87C97F67E9977FB0" +}; +return api.prepareCheckCancel(address, checkCancel).then(prepared => + {/* ... */}); +``` + + +```json +{ + "txJSON": "{\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"TransactionType\":\"CheckCancel\",\"CheckID\":\"49647F0D748DC3FE26BDACBC57F251AADEFFF391403EC9BF87C97F67E9977FB0\",\"Flags\":2147483648,\"LastLedgerSequence\":8819954,\"Fee\":\"12\",\"Sequence\":23}", + "instructions": { + "fee": "0.000012", + "sequence": 23, + "maxLedgerVersion": 8819954 + } +} +``` + + +## prepareCheckCash + +`prepareCheckCash(address: string, checkCash: Object, instructions: Object): Promise` + +Prepare a Check cashing transaction. This redeems a Check to receive up to the amount authorized by the corresponding CheckCreate transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit). + +### Parameters + +Name | Type | Description +---- | ---- | ----------- +address | [address](#address) | The address of the account that is creating the transaction. +checkCash | [checkCash](#check-cash) | The specification of the Check cash to prepare. +instructions | [instructions](#transaction-instructions) | *Optional* Instructions for executing the transaction + +### Return Value + +This method returns a promise that resolves with an object with the following structure: + + + +Name | Type | Description +---- | ---- | ----------- +txJSON | string | The prepared transaction in rippled JSON format. +instructions | object | The instructions for how to execute the transaction after adding automatic defaults. +*instructions.* fee | [value](#value) | An exact fee to pay for the transaction. See [Transaction Fees](#transaction-fees) for more information. +*instructions.* sequence | [sequence](#account-sequence-number) | The initiating account's sequence number for this transaction. +*instructions.* maxLedgerVersion | integer,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum. + +### Example + +```javascript +const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59'; +const checkCash = { + "amount": { + "currency": "XRP", + "value": "1" + }, + "checkID": "838766BA2B995C00744175F69A1B11E32C3DBC40E64801A4056FCBD657F57334" +}; +return api.prepareCheckCash(address, checkCash).then(prepared => + {/* ... */}); +``` + + +```json +{ + "txJSON": "{\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"TransactionType\":\"CheckCash\",\"CheckID\":\"838766BA2B995C00744175F69A1B11E32C3DBC40E64801A4056FCBD657F57334\",\"Amount\":\"1000000\",\"Flags\":2147483648,\"LastLedgerSequence\":8819954,\"Sequence\":23,\"Fee\":\"12\"}", + "instructions": { + "fee": "0.000012", + "sequence": 23, + "maxLedgerVersion": 8819954 + } +} +``` + + ## sign `sign(txJSON: string, secret: string, options: Object): {signedTransaction: string, id: string}` diff --git a/docs/src/index.md.ejs b/docs/src/index.md.ejs index 8017c549..5ba59633 100644 --- a/docs/src/index.md.ejs +++ b/docs/src/index.md.ejs @@ -34,6 +34,9 @@ <% include preparePaymentChannelCreate.md.ejs %> <% include preparePaymentChannelClaim.md.ejs %> <% include preparePaymentChannelFund.md.ejs %> +<% include prepareCheckCreate.md.ejs %> +<% include prepareCheckCancel.md.ejs %> +<% include prepareCheckCash.md.ejs %> <% include sign.md.ejs %> <% include combine.md.ejs %> <% include submit.md.ejs %> diff --git a/docs/src/prepareCheckCancel.md.ejs b/docs/src/prepareCheckCancel.md.ejs new file mode 100644 index 00000000..b1dc2791 --- /dev/null +++ b/docs/src/prepareCheckCancel.md.ejs @@ -0,0 +1,30 @@ +## prepareCheckCancel + +`prepareCheckCancel(address: string, checkCancel: Object, instructions: Object): Promise` + +Prepare a Check cancellation transaction. This cancels an unredeemed Check, removing it from the ledger without sending any money. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit). + +### Parameters + +<%- renderSchema('input/prepare-check-cancel.json') %> + +### Return Value + +This method returns a promise that resolves with an object with the following structure: + + + +<%- renderSchema('output/prepare.json') %> + +### Example + +```javascript +const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59'; +const checkCancel = <%- importFile('test/fixtures/requests/prepare-check-cancel.json') %>; +return api.prepareCheckCancel(address, checkCancel).then(prepared => + {/* ... */}); +``` + +<%- renderFixture('responses/prepare-check-cancel.json') %> diff --git a/docs/src/prepareCheckCash.md.ejs b/docs/src/prepareCheckCash.md.ejs new file mode 100644 index 00000000..5a646042 --- /dev/null +++ b/docs/src/prepareCheckCash.md.ejs @@ -0,0 +1,30 @@ +## prepareCheckCash + +`prepareCheckCash(address: string, checkCash: Object, instructions: Object): Promise` + +Prepare a Check cashing transaction. This redeems a Check to receive up to the amount authorized by the corresponding CheckCreate transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit). + +### Parameters + +<%- renderSchema('input/prepare-check-cash.json') %> + +### Return Value + +This method returns a promise that resolves with an object with the following structure: + + + +<%- renderSchema('output/prepare.json') %> + +### Example + +```javascript +const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59'; +const checkCash = <%- importFile('test/fixtures/requests/prepare-check-cash-amount.json') %>; +return api.prepareCheckCash(address, checkCash).then(prepared => + {/* ... */}); +``` + +<%- renderFixture('responses/prepare-check-cash-amount.json') %> diff --git a/docs/src/prepareCheckCreate.md.ejs b/docs/src/prepareCheckCreate.md.ejs new file mode 100644 index 00000000..6b776d88 --- /dev/null +++ b/docs/src/prepareCheckCreate.md.ejs @@ -0,0 +1,30 @@ +## prepareCheckCreate + +`prepareCheckCreate(address: string, checkCreate: Object, instructions: Object): Promise` + +Prepare a Check creation transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit). + +### Parameters + +<%- renderSchema('input/prepare-check-create.json') %> + +### Return Value + +This method returns a promise that resolves with an object with the following structure: + + + +<%- renderSchema('output/prepare.json') %> + +### Example + +```javascript +const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59'; +const checkCreate = <%- importFile('test/fixtures/requests/prepare-check-create.json') %>; +return api.prepareCheckCreate(address, checkCreate).then(prepared => + {/* ... */}); +``` + +<%- renderFixture('responses/prepare-check-create.json') %> diff --git a/docs/src/specifications.md.ejs b/docs/src/specifications.md.ejs index d4f4638b..0ab1cb0d 100644 --- a/docs/src/specifications.md.ejs +++ b/docs/src/specifications.md.ejs @@ -82,6 +82,36 @@ See [Transaction Types](#transaction-types) for a description. <%- renderFixture('requests/prepare-escrow-execution.json') %> +## Check Create + +See [Transaction Types](#transaction-types) for a description. + +<%- renderSchema('specifications/check-create.json') %> + +### Example + +<%- renderFixture('requests/prepare-check-create.json') %> + +## Check Cancel + +See [Transaction Types](#transaction-types) for a description. + +<%- renderSchema('specifications/check-cancel.json') %> + +### Example + +<%- renderFixture('requests/prepare-check-cancel.json') %> + +## Check Cash + +See [Transaction Types](#transaction-types) for a description. + +<%- renderSchema('specifications/check-cash.json') %> + +### Example + +<%- renderFixture('requests/prepare-check-cash-amount.json') %> + ## Payment Channel Create See [Transaction Types](#transaction-types) for a description. diff --git a/docs/src/transactions.md.ejs b/docs/src/transactions.md.ejs index 1df5c2c6..4689b258 100644 --- a/docs/src/transactions.md.ejs +++ b/docs/src/transactions.md.ejs @@ -14,6 +14,9 @@ Type | Description [escrowCreation](#escrow-creation) | An `escrowCreation` transaction creates an escrow on the ledger, which locks XRP until a cryptographic condition is met or it expires. It is like an escrow service where the XRP Ledger acts as the escrow agent. [escrowCancellation](#escrow-cancellation) | An `escrowCancellation` transaction unlocks the funds in an escrow and sends them back to the creator of the escrow, but it will only work after the escrow expires. [escrowExecution](#escrow-execution) | An `escrowExecution` transaction unlocks the funds in an escrow and sends them to the destination of the escrow, but it will only work if the cryptographic condition is provided. +[checkCreate](#check-create) | A `checkCreate` transaction creates a check on the ledger, which is a deferred payment that can be cashed by its intended destination. +[checkCancel](#check-cancel) | A `checkCancel` transaction cancels an unreedemed Check, removing it from the ledger without sending any money. +[checkCash](#checkCash) | A `checkCash` transaction redeems a Check to receive up to the amount authorized by the corresponding `checkCreate` transaction. Only the `destination` address of a Check can cash it. ## Transaction Flow @@ -28,6 +31,9 @@ Executing a transaction with `RippleAPI` requires the following four steps: * [prepareEscrowCreation](#prepareescrowcreation) * [prepareEscrowCancellation](#prepareescrowcancellation) * [prepareEscrowExecution](#prepareescrowexecution) + * [prepareCheckCreate](#preparecheckcreate) + * [prepareCheckCancel](#preparecheckcancel) + * [prepareCheckCash](#preparecheckcash) 2. [Sign](#sign) - Cryptographically sign the transaction locally and save the [transaction ID](#transaction-id). Signing is how the owner of an account authorizes a transaction to take place. For multisignature transactions, the `signedTransaction` fields returned by `sign` must be collected and passed to the [combine](#combine) method. 3. [Submit](#submit) - Submit the transaction to the connected server. 4. Verify - Verify that the transaction got validated by querying with [getTransaction](#gettransaction). This is necessary because transactions may fail even if they were successfully submitted. diff --git a/package.json b/package.json index 187bc83a..af92ffa3 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "jsonschema": "^1.1.1", "lodash": "^4.17.4", "ripple-address-codec": "^2.0.1", - "ripple-binary-codec": "^0.1.10", + "ripple-binary-codec": "^0.1.13", "ripple-hashes": "^0.3.1", "ripple-keypairs": "^0.10.1", "ripple-lib-transactionparser": "^0.6.2", diff --git a/src/api.ts b/src/api.ts index b1594be7..82be4f69 100644 --- a/src/api.ts +++ b/src/api.ts @@ -31,6 +31,9 @@ import prepareEscrowCancellation from './transaction/escrow-cancellation' import preparePaymentChannelCreate from './transaction/payment-channel-create' import preparePaymentChannelFund from './transaction/payment-channel-fund' import preparePaymentChannelClaim from './transaction/payment-channel-claim' +import prepareCheckCreate from './transaction/check-create' +import prepareCheckCancel from './transaction/check-cancel' +import prepareCheckCash from './transaction/check-cash' import prepareSettings from './transaction/settings' import sign from './transaction/sign' import combine from './transaction/combine' @@ -250,6 +253,9 @@ class RippleAPI extends EventEmitter { preparePaymentChannelCreate = preparePaymentChannelCreate preparePaymentChannelFund = preparePaymentChannelFund preparePaymentChannelClaim = preparePaymentChannelClaim + prepareCheckCreate = prepareCheckCreate + prepareCheckCash = prepareCheckCash + prepareCheckCancel = prepareCheckCancel prepareSettings = prepareSettings sign = sign combine = combine diff --git a/src/common/errors.ts b/src/common/errors.ts index 46ec21b3..7cf8a1df 100644 --- a/src/common/errors.ts +++ b/src/common/errors.ts @@ -29,7 +29,7 @@ class RippleError extends Error { } /* console.log in node uses util.inspect on object, and util.inspect allows - us to cutomize its output: + us to customize its output: https://nodejs.org/api/util.html#util_custom_inspect_function_on_objects */ inspect() { return this.toString() diff --git a/src/common/schema-validator.ts b/src/common/schema-validator.ts index 51161fb3..b48bd866 100644 --- a/src/common/schema-validator.ts +++ b/src/common/schema-validator.ts @@ -53,6 +53,9 @@ function loadSchemas() { require('./schemas/specifications/payment-channel-create.json'), require('./schemas/specifications/payment-channel-fund.json'), require('./schemas/specifications/payment-channel-claim.json'), + require('./schemas/specifications/check-create.json'), + require('./schemas/specifications/check-cash.json'), + require('./schemas/specifications/check-cancel.json'), require('./schemas/specifications/trustline.json'), require('./schemas/output/sign.json'), require('./schemas/output/submit.json'), @@ -100,6 +103,9 @@ function loadSchemas() { require('./schemas/input/prepare-payment-channel-create.json'), require('./schemas/input/prepare-payment-channel-fund.json'), require('./schemas/input/prepare-payment-channel-claim.json'), + require('./schemas/input/prepare-check-create.json'), + require('./schemas/input/prepare-check-cash.json'), + require('./schemas/input/prepare-check-cancel.json'), require('./schemas/input/compute-ledger-hash.json'), require('./schemas/input/sign.json'), require('./schemas/input/submit.json'), diff --git a/src/common/schemas/input/prepare-check-cancel.json b/src/common/schemas/input/prepare-check-cancel.json new file mode 100644 index 00000000..430e47ff --- /dev/null +++ b/src/common/schemas/input/prepare-check-cancel.json @@ -0,0 +1,18 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "prepareCheckCancelParameters", + "type": "object", + "properties": { + "address": { + "$ref": "address", + "description": "The address of the account that is creating the transaction." + }, + "checkCancel": { + "$ref": "checkCancel", + "description": "The specification of the Check cancellation to prepare." + }, + "instructions": {"$ref": "instructions"} + }, + "additionalProperties": false, + "required": ["address", "checkCancel"] +} diff --git a/src/common/schemas/input/prepare-check-cash.json b/src/common/schemas/input/prepare-check-cash.json new file mode 100644 index 00000000..16d491bf --- /dev/null +++ b/src/common/schemas/input/prepare-check-cash.json @@ -0,0 +1,18 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "prepareCheckCashParameters", + "type": "object", + "properties": { + "address": { + "$ref": "address", + "description": "The address of the account that is creating the transaction." + }, + "checkCash": { + "$ref": "checkCash", + "description": "The specification of the Check cash to prepare." + }, + "instructions": {"$ref": "instructions"} + }, + "additionalProperties": false, + "required": ["address", "checkCash"] +} diff --git a/src/common/schemas/input/prepare-check-create.json b/src/common/schemas/input/prepare-check-create.json new file mode 100644 index 00000000..180281b8 --- /dev/null +++ b/src/common/schemas/input/prepare-check-create.json @@ -0,0 +1,18 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "prepareCheckCreateParameters", + "type": "object", + "properties": { + "address": { + "$ref": "address", + "description": "The address of the account that is creating the transaction." + }, + "checkCreate": { + "$ref": "checkCreate", + "description": "The specification of the Check create creation to prepare." + }, + "instructions": {"$ref": "instructions"} + }, + "additionalProperties": false, + "required": ["address", "checkCreate"] +} diff --git a/src/common/schemas/objects/tx-type.json b/src/common/schemas/objects/tx-type.json index 0200ff67..0b120cf9 100644 --- a/src/common/schemas/objects/tx-type.json +++ b/src/common/schemas/objects/tx-type.json @@ -15,6 +15,9 @@ "escrowExecution", "paymentChannelCreate", "paymentChannelFund", - "paymentChannelClaim" + "paymentChannelClaim", + "checkCreate", + "checkCancel", + "checkCash" ] } diff --git a/src/common/schemas/output/get-transaction.json b/src/common/schemas/output/get-transaction.json index 9665b1b3..0f860110 100644 --- a/src/common/schemas/output/get-transaction.json +++ b/src/common/schemas/output/get-transaction.json @@ -96,6 +96,42 @@ } } }, + { + "properties": { + "type": { + "enum": [ + "checkCreate" + ] + }, + "specification": { + "$ref": "checkCreate" + } + } + }, + { + "properties": { + "type": { + "enum": [ + "checkCancel" + ] + }, + "specification": { + "$ref": "checkCancel" + } + } + }, + { + "properties": { + "type": { + "enum": [ + "checkCash" + ] + }, + "specification": { + "$ref": "checkCash" + } + } + }, { "properties": { "type": { diff --git a/src/common/schemas/specifications/check-cancel.json b/src/common/schemas/specifications/check-cancel.json new file mode 100644 index 00000000..a3558a18 --- /dev/null +++ b/src/common/schemas/specifications/check-cancel.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "checkCancel", + "link": "check-cancel", + "type": "object", + "properties": { + "checkID": { + "$ref": "hash256", + "description": "The ID of the Check ledger object to cancel, as a 64-character hexadecimal string." + } + }, + "required": ["checkID"], + "additionalProperties": false +} diff --git a/src/common/schemas/specifications/check-cash.json b/src/common/schemas/specifications/check-cash.json new file mode 100644 index 00000000..9895f318 --- /dev/null +++ b/src/common/schemas/specifications/check-cash.json @@ -0,0 +1,26 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "checkCash", + "link": "check-cash", + "type": "object", + "properties": { + "checkID": { + "$ref": "hash256", + "description": "The ID of the Check ledger object to cash, as a 64-character hexadecimal string." + }, + "amount": { + "$ref": "laxAmount", + "description": "Redeem the Check for exactly this amount, if possible. The currency must match that of the sendMax of the corresponding CheckCreate transaction. You must provide either this field or deliverMin." + }, + "deliverMin": { + "$ref": "laxAmount", + "description": "Redeem the Check for at least this amount and for as much as possible. The currency must match that of the sendMax of the corresponding CheckCreate transaction. You must provide either this field or amount." + } + }, + "required": ["checkID"], + "oneOf": [ + {"required": ["amount"]}, + {"required": ["deliverMin"]} + ], + "additionalProperties": false +} diff --git a/src/common/schemas/specifications/check-create.json b/src/common/schemas/specifications/check-create.json new file mode 100644 index 00000000..b8bb228b --- /dev/null +++ b/src/common/schemas/specifications/check-create.json @@ -0,0 +1,31 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "checkCreate", + "link": "check-create", + "type": "object", + "properties": { + "destination": { + "$ref": "address", + "description": "Address of the account that can cash the check." + }, + "sendMax": { + "$ref": "laxAmount", + "description": "Amount of source currency the check is allowed to debit the sender, including transfer fees on non-XRP currencies." + }, + "destinationTag": { + "$ref": "tag", + "description": "Destination tag that identifies the reason for the check, or a hosted recipient to pay." + }, + "expiration": { + "type": "string", + "format": "date-time", + "description": "Time after which the check is no longer valid." + }, + "invoiceID": { + "$ref": "hash256", + "description": "256-bit hash, as a 64-character hexadecimal string, representing a specific reason or identifier for this check." + } + }, + "required": ["destination", "sendMax"], + "additionalProperties": false +} diff --git a/src/common/validate.ts b/src/common/validate.ts index 3ffac667..3b229c3f 100644 --- a/src/common/validate.ts +++ b/src/common/validate.ts @@ -89,6 +89,15 @@ _.partial(schemaValidate, 'preparePaymentChannelFundParameters') export const preparePaymentChannelClaim = _.partial(schemaValidate, 'preparePaymentChannelClaimParameters') +export const prepareCheckCreate = +_.partial(schemaValidate, 'prepareCheckCreateParameters') + +export const prepareCheckCash = +_.partial(schemaValidate, 'prepareCheckCashParameters') + +export const prepareCheckCancel = +_.partial(schemaValidate, 'prepareCheckCancelParameters') + export const sign = _.partial(schemaValidate, 'signParameters') diff --git a/src/ledger/parse/check-cancel.ts b/src/ledger/parse/check-cancel.ts new file mode 100644 index 00000000..437944bb --- /dev/null +++ b/src/ledger/parse/check-cancel.ts @@ -0,0 +1,18 @@ +import * as assert from 'assert' +import {removeUndefined} from '../../common' + +export type FormattedCheckCancel = { + + // ID of the Check ledger object to cancel. + checkID: string +} + +function parseCheckCancel(tx: any): FormattedCheckCancel { + assert(tx.TransactionType === 'CheckCancel') + + return removeUndefined({ + checkID: tx.CheckID + }) +} + +export default parseCheckCancel diff --git a/src/ledger/parse/check-cash.ts b/src/ledger/parse/check-cash.ts new file mode 100644 index 00000000..211bf046 --- /dev/null +++ b/src/ledger/parse/check-cash.ts @@ -0,0 +1,35 @@ +import * as assert from 'assert' +import {removeUndefined} from '../../common' +import parseAmount from './amount' +import {Amount} from '../../common/types/objects' + +export type FormattedCheckCash = { + + // ID of the Check ledger object to cash. + checkID: string, + + // (Optional) redeem the Check for exactly this amount, if possible. + // The currency must match that of the `SendMax` of the corresponding + // `CheckCreate` transaction. + amount: Amount, + + // (Optional) redeem the Check for at least this amount and + // for as much as possible. + // The currency must match that of the `SendMax` of the corresponding + // `CheckCreate` transaction. + deliverMin: Amount + + // *must* include either Amount or DeliverMin, but not both. +} + +function parseCheckCash(tx: any): FormattedCheckCash { + assert(tx.TransactionType === 'CheckCash') + + return removeUndefined({ + checkID: tx.CheckID, + amount: tx.Amount && parseAmount(tx.Amount), + deliverMin: tx.DeliverMin && parseAmount(tx.DeliverMin) + }) +} + +export default parseCheckCash diff --git a/src/ledger/parse/check-create.ts b/src/ledger/parse/check-create.ts new file mode 100644 index 00000000..e468add9 --- /dev/null +++ b/src/ledger/parse/check-create.ts @@ -0,0 +1,38 @@ +import * as assert from 'assert' +import {parseTimestamp} from './utils' +import {removeUndefined} from '../../common' +import parseAmount from './amount' +import {Amount} from '../../common/types/objects' + +export type FormattedCheckCreate = { + + // account that can cash the check. + destination: string, + + // amount the check is allowed to debit the sender, + // including transfer fees on non-XRP currencies. + sendMax: Amount, + + // (Optional) identifies the reason for the check, or a hosted recipient. + destinationTag?: string, + + // (Optional) time in seconds since the Ripple Epoch. + expiration?: string, + + // (Optional) 256-bit hash representing a specific reason or identifier. + invoiceID?: string +} + +function parseCheckCreate(tx: any): FormattedCheckCreate { + assert(tx.TransactionType === 'CheckCreate') + + return removeUndefined({ + destination: tx.Destination, + sendMax: parseAmount(tx.SendMax), + destinationTag: tx.DestinationTag, + expiration: tx.Expiration && parseTimestamp(tx.Expiration), + invoiceID: tx.InvoiceID + }) +} + +export default parseCheckCreate diff --git a/src/ledger/parse/transaction.ts b/src/ledger/parse/transaction.ts index f5a0c082..7d19d3ba 100644 --- a/src/ledger/parse/transaction.ts +++ b/src/ledger/parse/transaction.ts @@ -9,6 +9,9 @@ import parseSettings from './settings' import parseEscrowCreation from './escrow-creation' import parseEscrowExecution from './escrow-execution' import parseEscrowCancellation from './escrow-cancellation' +import parseCheckCreate from './check-create' +import parseCheckCash from './check-cash' +import parseCheckCancel from './check-cancel' import parsePaymentChannelCreate from './payment-channel-create' import parsePaymentChannelFund from './payment-channel-fund' import parsePaymentChannelClaim from './payment-channel-claim' @@ -26,6 +29,9 @@ function parseTransactionType(type) { EscrowCreate: 'escrowCreation', EscrowFinish: 'escrowExecution', EscrowCancel: 'escrowCancellation', + CheckCreate: 'checkCreate', + CheckCash: 'checkCash', + CheckCancel: 'checkCancel', PaymentChannelCreate: 'paymentChannelCreate', PaymentChannelFund: 'paymentChannelFund', PaymentChannelClaim: 'paymentChannelClaim', @@ -47,6 +53,9 @@ function parseTransaction(tx: any): any { 'escrowCreation': parseEscrowCreation, 'escrowExecution': parseEscrowExecution, 'escrowCancellation': parseEscrowCancellation, + 'checkCreate': parseCheckCreate, + 'checkCash': parseCheckCash, + 'checkCancel': parseCheckCancel, 'paymentChannelCreate': parsePaymentChannelCreate, 'paymentChannelFund': parsePaymentChannelFund, 'paymentChannelClaim': parsePaymentChannelClaim, diff --git a/src/transaction/check-cancel.ts b/src/transaction/check-cancel.ts new file mode 100644 index 00000000..9a694672 --- /dev/null +++ b/src/transaction/check-cancel.ts @@ -0,0 +1,32 @@ +import * as utils from './utils' +import {validate} from '../common' +import {Instructions, Prepare} from './types' + +type CheckCancel = { + checkID: string +} + +function createCheckCancelTransaction(account: string, + cancel: CheckCancel +): object { + const txJSON = { + Account: account, + TransactionType: 'CheckCancel', + CheckID: cancel.checkID + } + + return txJSON +} + +function prepareCheckCancel(address: string, + checkCancel: CheckCancel, + instructions: Instructions = {} +): Promise { + validate.prepareCheckCancel( + {address, checkCancel, instructions}) + const txJSON = createCheckCancelTransaction( + address, checkCancel) + return utils.prepareTransaction(txJSON, this, instructions) +} + +export default prepareCheckCancel diff --git a/src/transaction/check-cash.ts b/src/transaction/check-cash.ts new file mode 100644 index 00000000..67686bf4 --- /dev/null +++ b/src/transaction/check-cash.ts @@ -0,0 +1,50 @@ +import * as utils from './utils' +const ValidationError = utils.common.errors.ValidationError +const toRippledAmount = utils.common.toRippledAmount +import {validate} from '../common' +import {Instructions, Prepare} from './types' +import {Amount} from '../common/types/objects' + +type CheckCash = { + checkID: string, + amount?: Amount, + deliverMin?: Amount +} + +function createCheckCashTransaction(account: string, + checkCash: CheckCash +): object { + if (checkCash.amount && checkCash.deliverMin) { + throw new ValidationError('"amount" and "deliverMin" properties on ' + + 'CheckCash are mutually exclusive') + } + + const txJSON: any = { + Account: account, + TransactionType: 'CheckCash', + CheckID: checkCash.checkID + } + + if (checkCash.amount !== undefined) { + txJSON.Amount = toRippledAmount(checkCash.amount) + } + + if (checkCash.deliverMin !== undefined) { + txJSON.DeliverMin = toRippledAmount(checkCash.deliverMin) + } + + return txJSON +} + +function prepareCheckCash(address: string, + checkCash: CheckCash, + instructions: Instructions = {} +): Promise { + validate.prepareCheckCash( + {address, checkCash, instructions}) + const txJSON = createCheckCashTransaction( + address, checkCash) + return utils.prepareTransaction(txJSON, this, instructions) +} + +export default prepareCheckCash diff --git a/src/transaction/check-create.ts b/src/transaction/check-create.ts new file mode 100644 index 00000000..8fce9ef0 --- /dev/null +++ b/src/transaction/check-create.ts @@ -0,0 +1,51 @@ +import * as utils from './utils' +const toRippledAmount = utils.common.toRippledAmount +import {validate, iso8601ToRippleTime} from '../common' +import {Instructions, Prepare} from './types' +import {Amount} from '../common/types/objects' + +type CheckCreate = { + destination: string, + sendMax: Amount, + destinationTag?: number, + expiration?: string, + invoiceID?: string +} + +function createCheckCreateTransaction(account: string, + check: CheckCreate +): object { + const txJSON: any = { + Account: account, + TransactionType: 'CheckCreate', + Destination: check.destination, + SendMax: toRippledAmount(check.sendMax) + } + + if (check.destinationTag !== undefined) { + txJSON.DestinationTag = check.destinationTag + } + + if (check.expiration !== undefined) { + txJSON.Expiration = iso8601ToRippleTime(check.expiration) + } + + if (check.invoiceID !== undefined) { + txJSON.InvoiceID = check.invoiceID + } + + return txJSON +} + +function prepareCheckCreate(address: string, + checkCreate: CheckCreate, + instructions: Instructions = {} +): Promise { + validate.prepareCheckCreate( + {address, checkCreate, instructions}) + const txJSON = createCheckCreateTransaction( + address, checkCreate) + return utils.prepareTransaction(txJSON, this, instructions) +} + +export default prepareCheckCreate diff --git a/test/api-test.js b/test/api-test.js index 3bd4aa4f..968c3423 100644 --- a/test/api-test.js +++ b/test/api-test.js @@ -346,6 +346,45 @@ describe('RippleAPI', function () { 'prepare')); }); + it('prepareCheckCreate', function () { + const localInstructions = _.defaults({ + maxFee: '0.000012' + }, instructions); + return this.api.prepareCheckCreate( + address, requests.prepareCheckCreate.normal, + localInstructions).then( + _.partial(checkResult, responses.prepareCheckCreate.normal, + 'prepare')); + }); + + it('prepareCheckCreate full', function () { + return this.api.prepareCheckCreate( + address, requests.prepareCheckCreate.full).then( + _.partial(checkResult, responses.prepareCheckCreate.full, + 'prepare')); + }); + + it('prepareCheckCash amount', function () { + return this.api.prepareCheckCash( + address, requests.prepareCheckCash.amount).then( + _.partial(checkResult, responses.prepareCheckCash.amount, + 'prepare')); + }); + + it('prepareCheckCash deliverMin', function () { + return this.api.prepareCheckCash( + address, requests.prepareCheckCash.deliverMin).then( + _.partial(checkResult, responses.prepareCheckCash.deliverMin, + 'prepare')); + }); + + it('prepareCheckCancel', function () { + return this.api.prepareCheckCancel( + address, requests.prepareCheckCancel.normal).then( + _.partial(checkResult, responses.prepareCheckCancel.normal, + 'prepare')); + }); + it('preparePaymentChannelCreate', function () { const localInstructions = _.defaults({ maxFee: '0.000012' @@ -786,6 +825,37 @@ describe('RippleAPI', function () { }); }); + // Checks + + it('getTransaction - CheckCreate', function () { + const hash = + '605A2E2C8E48AECAF5C56085D1AEAA0348DC838CE122C9188F94EB19DA05C2FE'; + return this.api.getTransaction(hash).then( + _.partial(checkResult, + responses.getTransaction.checkCreate, + 'getTransaction')); + }); + + it('getTransaction - CheckCancel', function () { + const hash = + 'B4105D1B2D83819647E4692B7C5843D674283F669524BD50C9614182E3A12CD4'; + return this.api.getTransaction(hash).then( + _.partial(checkResult, + responses.getTransaction.checkCancel, + 'getTransaction')); + }); + + it('getTransaction - CheckCash', function () { + const hash = + '8321208465F70BA52C28BCC4F646BAF3B012BA13B57576C0336F42D77E3E0749'; + return this.api.getTransaction(hash/*, options*/).then( + _.partial(checkResult, + responses.getTransaction.checkCash, + 'getTransaction')); + }); + + // Escrows + it('getTransaction - EscrowCreation', function () { const hash = '144F272380BDB4F1BD92329A2178BABB70C20F59042C495E10BF72EBFB408EE1'; diff --git a/test/fixtures/requests/index.js b/test/fixtures/requests/index.js index 2e337711..14deb4d1 100644 --- a/test/fixtures/requests/index.js +++ b/test/fixtures/requests/index.js @@ -38,6 +38,17 @@ module.exports = { normal: require('./prepare-escrow-cancellation'), memos: require('./prepare-escrow-cancellation-memos') }, + prepareCheckCreate: { + normal: require('./prepare-check-create'), + full: require('./prepare-check-create-full') + }, + prepareCheckCash: { + amount: require('./prepare-check-cash-amount'), + deliverMin: require('./prepare-check-cash-delivermin') + }, + prepareCheckCancel: { + normal: require('./prepare-check-cancel') + }, preparePaymentChannelCreate: { normal: require('./prepare-payment-channel-create'), full: require('./prepare-payment-channel-create-full') diff --git a/test/fixtures/requests/prepare-check-cancel.json b/test/fixtures/requests/prepare-check-cancel.json new file mode 100644 index 00000000..f1e62400 --- /dev/null +++ b/test/fixtures/requests/prepare-check-cancel.json @@ -0,0 +1,3 @@ +{ + "checkID": "49647F0D748DC3FE26BDACBC57F251AADEFFF391403EC9BF87C97F67E9977FB0" +} diff --git a/test/fixtures/requests/prepare-check-cash-amount.json b/test/fixtures/requests/prepare-check-cash-amount.json new file mode 100644 index 00000000..a02ab588 --- /dev/null +++ b/test/fixtures/requests/prepare-check-cash-amount.json @@ -0,0 +1,7 @@ +{ + "amount": { + "currency": "XRP", + "value": "1" + }, + "checkID": "838766BA2B995C00744175F69A1B11E32C3DBC40E64801A4056FCBD657F57334" +} diff --git a/test/fixtures/requests/prepare-check-cash-delivermin.json b/test/fixtures/requests/prepare-check-cash-delivermin.json new file mode 100644 index 00000000..92c455ef --- /dev/null +++ b/test/fixtures/requests/prepare-check-cash-delivermin.json @@ -0,0 +1,7 @@ +{ + "deliverMin": { + "currency": "XRP", + "value": "0.8" + }, + "checkID": "838766BA2B995C00744175F69A1B11E32C3DBC40E64801A4056FCBD657F57334" +} diff --git a/test/fixtures/requests/prepare-check-create-full.json b/test/fixtures/requests/prepare-check-create-full.json new file mode 100644 index 00000000..a1d70b47 --- /dev/null +++ b/test/fixtures/requests/prepare-check-create-full.json @@ -0,0 +1,10 @@ +{ + "destination": "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW", + "sendMax": { + "currency": "XRP", + "value": "1" + }, + "destinationTag": 2, + "expiration": "2018-09-24T21:21:50.000Z", + "invoiceID": "1F40FC92DA241694750979EE6CF582F2D5D7D28E18335DE05ABC54D0560E0F53" +} diff --git a/test/fixtures/requests/prepare-check-create.json b/test/fixtures/requests/prepare-check-create.json new file mode 100644 index 00000000..4edfd38b --- /dev/null +++ b/test/fixtures/requests/prepare-check-create.json @@ -0,0 +1,7 @@ +{ + "destination": "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW", + "sendMax": { + "currency": "XRP", + "value": "1" + } +} diff --git a/test/fixtures/responses/get-transaction-check-cancel.json b/test/fixtures/responses/get-transaction-check-cancel.json new file mode 100644 index 00000000..e1720381 --- /dev/null +++ b/test/fixtures/responses/get-transaction-check-cancel.json @@ -0,0 +1,25 @@ +{ + "type": "checkCancel", + "address": "rNpdNFXNMvEcaXDqMypi48gdSABZkYuyQE", + "sequence": 6, + "id": "B4105D1B2D83819647E4692B7C5843D674283F669524BD50C9614182E3A12CD4", + "specification": { + "checkID": "6EE1727598693635183A3D967342A46C739FC06F973CA6A3277A92E8D997E7A8" + }, + "outcome": { + "result": "tesSUCCESS", + "timestamp": "2018-02-23T22:45:41.000Z", + "fee": "0.000012", + "balanceChanges": { + "rNpdNFXNMvEcaXDqMypi48gdSABZkYuyQE": [ + { + "currency": "XRP", + "value": "-0.000012" + } + ] + }, + "orderbookChanges": {}, + "ledgerVersion": 6967970, + "indexInLedger": 4 + } +} diff --git a/test/fixtures/responses/get-transaction-check-cash.json b/test/fixtures/responses/get-transaction-check-cash.json new file mode 100644 index 00000000..7b449783 --- /dev/null +++ b/test/fixtures/responses/get-transaction-check-cash.json @@ -0,0 +1,35 @@ +{ + "type": "checkCash", + "address": "raLHvSZXacoGiCoWrdBhVGstZm6GhF7oRr", + "sequence": 3, + "id": "8321208465F70BA52C28BCC4F646BAF3B012BA13B57576C0336F42D77E3E0749", + "specification": { + "checkID": "4F6DDA7972A5E8C8F2AA3D2A475E56475FA573C65B935E26EABDA5F06A982C70", + "amount": { + "currency": "XRP", + "value": "2.5" + } + }, + "outcome": { + "result": "tesSUCCESS", + "timestamp": "2018-02-23T22:26:52.000Z", + "fee": "0.000012", + "balanceChanges": { + "raLHvSZXacoGiCoWrdBhVGstZm6GhF7oRr": [ + { + "currency": "XRP", + "value": "2.499988" + } + ], + "rNpdNFXNMvEcaXDqMypi48gdSABZkYuyQE": [ + { + "currency": "XRP", + "value": "-2.5" + } + ] + }, + "orderbookChanges": {}, + "ledgerVersion": 6967596, + "indexInLedger": 0 + } +} diff --git a/test/fixtures/responses/get-transaction-check-create.json b/test/fixtures/responses/get-transaction-check-create.json new file mode 100644 index 00000000..177f2c75 --- /dev/null +++ b/test/fixtures/responses/get-transaction-check-create.json @@ -0,0 +1,32 @@ +{ + "type": "checkCreate", + "address": "rNpdNFXNMvEcaXDqMypi48gdSABZkYuyQE", + "sequence": 3, + "id": "605A2E2C8E48AECAF5C56085D1AEAA0348DC838CE122C9188F94EB19DA05C2FE", + "specification": { + "destination": "raLHvSZXacoGiCoWrdBhVGstZm6GhF7oRr", + "sendMax": { + "currency": "XRP", + "value": "3" + }, + "destinationTag": 1235, + "expiration": "2018-02-25T21:22:47.000Z", + "invoiceID": "DEADBEEF2FE8A32E40E1F2C05CF1C15545BAB56B617F9C6C2D63A6B704BEF59B" + }, + "outcome": { + "result": "tesSUCCESS", + "timestamp": "2018-02-23T22:20:01.000Z", + "fee": "0.000012", + "balanceChanges": { + "rNpdNFXNMvEcaXDqMypi48gdSABZkYuyQE": [ + { + "currency": "XRP", + "value": "-0.000012" + } + ] + }, + "orderbookChanges": {}, + "ledgerVersion": 6967458, + "indexInLedger": 1 + } +} diff --git a/test/fixtures/responses/get-transaction-escrow-create.json b/test/fixtures/responses/get-transaction-escrow-creation.json similarity index 100% rename from test/fixtures/responses/get-transaction-escrow-create.json rename to test/fixtures/responses/get-transaction-escrow-creation.json diff --git a/test/fixtures/responses/index.js b/test/fixtures/responses/index.js index c2e66a58..d4facacc 100644 --- a/test/fixtures/responses/index.js +++ b/test/fixtures/responses/index.js @@ -42,8 +42,14 @@ module.exports = { trustlineFrozenOff: require('./get-transaction-trust-set-frozen-off.json'), trustlineNoQuality: require('./get-transaction-trust-no-quality.json'), notValidated: require('./get-transaction-not-validated.json'), + checkCreate: + require('./get-transaction-check-create.json'), + checkCancel: + require('./get-transaction-check-cancel.json'), + checkCash: + require('./get-transaction-check-cash.json'), escrowCreation: - require('./get-transaction-escrow-create.json'), + require('./get-transaction-escrow-creation.json'), escrowCancellation: require('./get-transaction-escrow-cancellation.json'), escrowExecution: @@ -113,6 +119,17 @@ module.exports = { noMaxLedgerVersion: require('./prepare-settings-no-maxledgerversion.json'), signers: require('./prepare-settings-signers.json') }, + prepareCheckCreate: { + normal: require('./prepare-check-create'), + full: require('./prepare-check-create-full') + }, + prepareCheckCash: { + amount: require('./prepare-check-cash-amount'), + deliverMin: require('./prepare-check-cash-delivermin') + }, + prepareCheckCancel: { + normal: require('./prepare-check-cancel') + }, prepareEscrowCreation: { normal: require('./prepare-escrow-creation'), full: require('./prepare-escrow-creation-full') diff --git a/test/fixtures/responses/prepare-check-cancel.json b/test/fixtures/responses/prepare-check-cancel.json new file mode 100644 index 00000000..493fe250 --- /dev/null +++ b/test/fixtures/responses/prepare-check-cancel.json @@ -0,0 +1,8 @@ +{ + "txJSON": "{\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"TransactionType\":\"CheckCancel\",\"CheckID\":\"49647F0D748DC3FE26BDACBC57F251AADEFFF391403EC9BF87C97F67E9977FB0\",\"Flags\":2147483648,\"LastLedgerSequence\":8819954,\"Fee\":\"12\",\"Sequence\":23}", + "instructions": { + "fee": "0.000012", + "sequence": 23, + "maxLedgerVersion": 8819954 + } +} diff --git a/test/fixtures/responses/prepare-check-cash-amount.json b/test/fixtures/responses/prepare-check-cash-amount.json new file mode 100644 index 00000000..a344cdf4 --- /dev/null +++ b/test/fixtures/responses/prepare-check-cash-amount.json @@ -0,0 +1,8 @@ +{ + "txJSON": "{\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"TransactionType\":\"CheckCash\",\"CheckID\":\"838766BA2B995C00744175F69A1B11E32C3DBC40E64801A4056FCBD657F57334\",\"Amount\":\"1000000\",\"Flags\":2147483648,\"LastLedgerSequence\":8819954,\"Sequence\":23,\"Fee\":\"12\"}", + "instructions": { + "fee": "0.000012", + "sequence": 23, + "maxLedgerVersion": 8819954 + } +} diff --git a/test/fixtures/responses/prepare-check-cash-delivermin.json b/test/fixtures/responses/prepare-check-cash-delivermin.json new file mode 100644 index 00000000..524515fb --- /dev/null +++ b/test/fixtures/responses/prepare-check-cash-delivermin.json @@ -0,0 +1,8 @@ +{ + "txJSON": "{\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"TransactionType\":\"CheckCash\",\"CheckID\":\"838766BA2B995C00744175F69A1B11E32C3DBC40E64801A4056FCBD657F57334\",\"DeliverMin\":\"800000\",\"Flags\":2147483648,\"LastLedgerSequence\":8819954,\"Sequence\":23,\"Fee\":\"12\"}", + "instructions": { + "fee": "0.000012", + "sequence": 23, + "maxLedgerVersion": 8819954 + } +} diff --git a/test/fixtures/responses/prepare-check-create-full.json b/test/fixtures/responses/prepare-check-create-full.json new file mode 100644 index 00000000..a43e7d57 --- /dev/null +++ b/test/fixtures/responses/prepare-check-create-full.json @@ -0,0 +1,8 @@ +{ + "txJSON": "{\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"TransactionType\":\"CheckCreate\",\"Destination\":\"rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW\",\"SendMax\":\"1000000\",\"DestinationTag\":2,\"Expiration\":591139310,\"InvoiceID\":\"1F40FC92DA241694750979EE6CF582F2D5D7D28E18335DE05ABC54D0560E0F53\",\"Flags\":2147483648,\"LastLedgerSequence\":8819954,\"Sequence\":23,\"Fee\":\"12\"}", + "instructions": { + "fee": "0.000012", + "sequence": 23, + "maxLedgerVersion": 8819954 + } +} diff --git a/test/fixtures/responses/prepare-check-create.json b/test/fixtures/responses/prepare-check-create.json new file mode 100644 index 00000000..355b16f1 --- /dev/null +++ b/test/fixtures/responses/prepare-check-create.json @@ -0,0 +1,8 @@ +{ + "txJSON": "{\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"TransactionType\":\"CheckCreate\",\"Destination\":\"rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW\",\"SendMax\":\"1000000\",\"Flags\":2147483648,\"LastLedgerSequence\":8820051,\"Sequence\":23,\"Fee\":\"12\"}", + "instructions": { + "fee": "0.000012", + "sequence": 23, + "maxLedgerVersion": 8820051 + } +} diff --git a/test/fixtures/rippled/index.js b/test/fixtures/rippled/index.js index 94ca6890..bc5073e4 100644 --- a/test/fixtures/rippled/index.js +++ b/test/fixtures/rippled/index.js @@ -72,6 +72,9 @@ module.exports = { LedgerWithoutTime: require('./tx/ledger-without-time.json'), NotValidated: require('./tx/not-validated.json'), OfferWithExpiration: require('./tx/order-with-expiration.json'), + CheckCreate: require('./tx/check-create.json'), + CheckCancel: require('./tx/check-cancel.json'), + CheckCash: require('./tx/check-cash.json'), EscrowCreation: require('./tx/escrow-creation.json'), EscrowCancellation: require('./tx/escrow-cancellation.json'), diff --git a/test/fixtures/rippled/tx/check-cancel.json b/test/fixtures/rippled/tx/check-cancel.json new file mode 100644 index 00000000..5e166404 --- /dev/null +++ b/test/fixtures/rippled/tx/check-cancel.json @@ -0,0 +1,89 @@ +{ + "id": 0, + "result": { + "Account": "rNpdNFXNMvEcaXDqMypi48gdSABZkYuyQE", + "CheckID": "6EE1727598693635183A3D967342A46C739FC06F973CA6A3277A92E8D997E7A8", + "Fee": "12", + "Flags": 2147483648, + "LastLedgerSequence": 6968242, + "Sequence": 6, + "SigningPubKey": "03C1B24925182F5B881D34E07993FAAD90B918EF3D6661963A3E9EE402B6F87659", + "TransactionType": "CheckCancel", + "TxnSignature": "3045022100B3BC49F917E408DB5FFE1570CDE69E28AA4BD99AABAC7043EE71BDC346BF76F902200F8E4E059B1AF33BBD595CEDB86A556C40E40ADFB86F1B4451F447E88DD01A0B", + "date": 572741141, + "hash": "B4105D1B2D83819647E4692B7C5843D674283F669524BD50C9614182E3A12CD4", + "inLedger": 6967970, + "ledger_index": 6967970, + "meta": { + "AffectedNodes": [ + { + "ModifiedNode": { + "FinalFields": { + "Flags": 0, + "Owner": "rNpdNFXNMvEcaXDqMypi48gdSABZkYuyQE", + "RootIndex": "46B6FD7D2C937D6A5D2832CAC94F424300B3FE72B5D1D460C20E6FADAD2FF7C7" + }, + "LedgerEntryType": "DirectoryNode", + "LedgerIndex": "46B6FD7D2C937D6A5D2832CAC94F424300B3FE72B5D1D460C20E6FADAD2FF7C7" + } + }, + { + "DeletedNode": { + "FinalFields": { + "Account": "rNpdNFXNMvEcaXDqMypi48gdSABZkYuyQE", + "Destination": "raLHvSZXacoGiCoWrdBhVGstZm6GhF7oRr", + "DestinationNode": "0000000000000000", + "DestinationTag": 1236, + "Expiration": 572908967, + "Flags": 0, + "InvoiceID": "DEADBEEF3FE8A32E40E1F2C05CF1C15545BAB56B617F9C6C2D63A6B704BEF59B", + "OwnerNode": "0000000000000000", + "PreviousTxnID": "FCE773D30272546ADD1ADF1763AE8C69B857C7AD0B4A13B9B524991D5611740E", + "PreviousTxnLgrSeq": 6967917, + "SendMax": "4000000", + "Sequence": 5 + }, + "LedgerEntryType": "Check", + "LedgerIndex": "6EE1727598693635183A3D967342A46C739FC06F973CA6A3277A92E8D997E7A8" + } + }, + { + "ModifiedNode": { + "FinalFields": { + "Account": "rNpdNFXNMvEcaXDqMypi48gdSABZkYuyQE", + "Balance": "9996499928", + "Flags": 0, + "OwnerCount": 0, + "Sequence": 7 + }, + "LedgerEntryType": "AccountRoot", + "LedgerIndex": "8FD7FBA4C35956B4964015D938AD50A939458E8CD13FA24A58F40A07ABE47E52", + "PreviousFields": { + "Balance": "9996499940", + "OwnerCount": 1, + "Sequence": 6 + }, + "PreviousTxnID": "FCE773D30272546ADD1ADF1763AE8C69B857C7AD0B4A13B9B524991D5611740E", + "PreviousTxnLgrSeq": 6967917 + } + }, + { + "ModifiedNode": { + "FinalFields": { + "Flags": 0, + "Owner": "raLHvSZXacoGiCoWrdBhVGstZm6GhF7oRr", + "RootIndex": "A33DF86647D19B7868A6FAD1E65F753837F8CFEF8F1C4F34717FD5CC7E6EA2E3" + }, + "LedgerEntryType": "DirectoryNode", + "LedgerIndex": "A33DF86647D19B7868A6FAD1E65F753837F8CFEF8F1C4F34717FD5CC7E6EA2E3" + } + } + ], + "TransactionIndex": 4, + "TransactionResult": "tesSUCCESS" + }, + "validated": true + }, + "status": "success", + "type": "response" +} \ No newline at end of file diff --git a/test/fixtures/rippled/tx/check-cash.json b/test/fixtures/rippled/tx/check-cash.json new file mode 100644 index 00000000..f941570e --- /dev/null +++ b/test/fixtures/rippled/tx/check-cash.json @@ -0,0 +1,108 @@ +{ + "id": 0, + "result": { + "Account": "raLHvSZXacoGiCoWrdBhVGstZm6GhF7oRr", + "Amount": "2500000", + "CheckID": "4F6DDA7972A5E8C8F2AA3D2A475E56475FA573C65B935E26EABDA5F06A982C70", + "Fee": "12", + "Flags": 2147483648, + "LastLedgerSequence": 6967889, + "Sequence": 3, + "SigningPubKey": "02ACB1C22D68E01414D2F527B4666E119F36E5B996D1CE6C8DBDE03769E5B2B95B", + "TransactionType": "CheckCash", + "TxnSignature": "304402205CA374B304F5D595E930489D70D5EDD062142D6D231D55AC0123F2AA02C8F10202206B5B9AA6A8560382053FF628662D42E74BB79B84B4A507719180823A720A261F", + "date": 572740012, + "hash": "8321208465F70BA52C28BCC4F646BAF3B012BA13B57576C0336F42D77E3E0749", + "inLedger": 6967596, + "ledger_index": 6967596, + "meta": { + "AffectedNodes": [ + { + "ModifiedNode": { + "FinalFields": { + "Account": "raLHvSZXacoGiCoWrdBhVGstZm6GhF7oRr", + "Balance": "10003499964", + "Flags": 0, + "OwnerCount": 0, + "Sequence": 4 + }, + "LedgerEntryType": "AccountRoot", + "LedgerIndex": "1F5CCAAAAE908C0F449ADB267084DFFD3E4432921E64A020EEBC59D95BD4940A", + "PreviousFields": { + "Balance": "10000999976", + "Sequence": 3 + }, + "PreviousTxnID": "7D1400825FD25D17B0283B71B0CC2ACC921F32D057B66BB7331F1B43483BC3DA", + "PreviousTxnLgrSeq": 6967427 + } + }, + { + "ModifiedNode": { + "FinalFields": { + "Flags": 0, + "Owner": "rNpdNFXNMvEcaXDqMypi48gdSABZkYuyQE", + "RootIndex": "46B6FD7D2C937D6A5D2832CAC94F424300B3FE72B5D1D460C20E6FADAD2FF7C7" + }, + "LedgerEntryType": "DirectoryNode", + "LedgerIndex": "46B6FD7D2C937D6A5D2832CAC94F424300B3FE72B5D1D460C20E6FADAD2FF7C7" + } + }, + { + "DeletedNode": { + "FinalFields": { + "Account": "rNpdNFXNMvEcaXDqMypi48gdSABZkYuyQE", + "Destination": "raLHvSZXacoGiCoWrdBhVGstZm6GhF7oRr", + "DestinationNode": "0000000000000000", + "DestinationTag": 1235, + "Expiration": 572908967, + "Flags": 0, + "InvoiceID": "DEADBEEF2FE8A32E40E1F2C05CF1C15545BAB56B617F9C6C2D63A6B704BEF59B", + "OwnerNode": "0000000000000000", + "PreviousTxnID": "605A2E2C8E48AECAF5C56085D1AEAA0348DC838CE122C9188F94EB19DA05C2FE", + "PreviousTxnLgrSeq": 6967458, + "SendMax": "3000000", + "Sequence": 3 + }, + "LedgerEntryType": "Check", + "LedgerIndex": "4F6DDA7972A5E8C8F2AA3D2A475E56475FA573C65B935E26EABDA5F06A982C70" + } + }, + { + "ModifiedNode": { + "FinalFields": { + "Account": "rNpdNFXNMvEcaXDqMypi48gdSABZkYuyQE", + "Balance": "9996499952", + "Flags": 0, + "OwnerCount": 0, + "Sequence": 5 + }, + "LedgerEntryType": "AccountRoot", + "LedgerIndex": "8FD7FBA4C35956B4964015D938AD50A939458E8CD13FA24A58F40A07ABE47E52", + "PreviousFields": { + "Balance": "9998999952", + "OwnerCount": 1 + }, + "PreviousTxnID": "4FE09BCC476230E75A45014CD8F77E91C7FF95C07BB8E55923EB55741911C85D", + "PreviousTxnLgrSeq": 6967586 + } + }, + { + "ModifiedNode": { + "FinalFields": { + "Flags": 0, + "Owner": "raLHvSZXacoGiCoWrdBhVGstZm6GhF7oRr", + "RootIndex": "A33DF86647D19B7868A6FAD1E65F753837F8CFEF8F1C4F34717FD5CC7E6EA2E3" + }, + "LedgerEntryType": "DirectoryNode", + "LedgerIndex": "A33DF86647D19B7868A6FAD1E65F753837F8CFEF8F1C4F34717FD5CC7E6EA2E3" + } + } + ], + "TransactionIndex": 0, + "TransactionResult": "tesSUCCESS" + }, + "validated": true + }, + "status": "success", + "type": "response" +} \ No newline at end of file diff --git a/test/fixtures/rippled/tx/check-create.json b/test/fixtures/rippled/tx/check-create.json new file mode 100644 index 00000000..2a0caa1b --- /dev/null +++ b/test/fixtures/rippled/tx/check-create.json @@ -0,0 +1,88 @@ +{ + "id": 0, + "result": { + "Account": "rNpdNFXNMvEcaXDqMypi48gdSABZkYuyQE", + "Destination": "raLHvSZXacoGiCoWrdBhVGstZm6GhF7oRr", + "DestinationTag": 1235, + "Expiration": 572908967, + "Fee": "12", + "Flags": 2147483648, + "InvoiceID": "DEADBEEF2FE8A32E40E1F2C05CF1C15545BAB56B617F9C6C2D63A6B704BEF59B", + "LastLedgerSequence": 6967747, + "SendMax": "3000000", + "Sequence": 3, + "SigningPubKey": "03C1B24925182F5B881D34E07993FAAD90B918EF3D6661963A3E9EE402B6F87659", + "TransactionType": "CheckCreate", + "TxnSignature": "3044022058FD0FBB7486D84DBEFE6C10BE0D43C3344E6B175BED19C1FF514C379A4FB344022021DE0087152FCDD6EB7ED14E057BBA94CAF70B920AA79CB82AAD4B82E7AFF760", + "date": 572739601, + "hash": "605A2E2C8E48AECAF5C56085D1AEAA0348DC838CE122C9188F94EB19DA05C2FE", + "inLedger": 6967458, + "ledger_index": 6967458, + "meta": { + "AffectedNodes": [ + { + "ModifiedNode": { + "FinalFields": { + "Flags": 0, + "Owner": "rNpdNFXNMvEcaXDqMypi48gdSABZkYuyQE", + "RootIndex": "46B6FD7D2C937D6A5D2832CAC94F424300B3FE72B5D1D460C20E6FADAD2FF7C7" + }, + "LedgerEntryType": "DirectoryNode", + "LedgerIndex": "46B6FD7D2C937D6A5D2832CAC94F424300B3FE72B5D1D460C20E6FADAD2FF7C7" + } + }, + { + "CreatedNode": { + "LedgerEntryType": "Check", + "LedgerIndex": "4F6DDA7972A5E8C8F2AA3D2A475E56475FA573C65B935E26EABDA5F06A982C70", + "NewFields": { + "Account": "rNpdNFXNMvEcaXDqMypi48gdSABZkYuyQE", + "Destination": "raLHvSZXacoGiCoWrdBhVGstZm6GhF7oRr", + "DestinationTag": 1235, + "Expiration": 572908967, + "InvoiceID": "DEADBEEF2FE8A32E40E1F2C05CF1C15545BAB56B617F9C6C2D63A6B704BEF59B", + "SendMax": "3000000", + "Sequence": 3 + } + } + }, + { + "ModifiedNode": { + "FinalFields": { + "Account": "rNpdNFXNMvEcaXDqMypi48gdSABZkYuyQE", + "Balance": "9998999964", + "Flags": 0, + "OwnerCount": 1, + "Sequence": 4 + }, + "LedgerEntryType": "AccountRoot", + "LedgerIndex": "8FD7FBA4C35956B4964015D938AD50A939458E8CD13FA24A58F40A07ABE47E52", + "PreviousFields": { + "Balance": "9998999976", + "OwnerCount": 0, + "Sequence": 3 + }, + "PreviousTxnID": "7D1400825FD25D17B0283B71B0CC2ACC921F32D057B66BB7331F1B43483BC3DA", + "PreviousTxnLgrSeq": 6967427 + } + }, + { + "ModifiedNode": { + "FinalFields": { + "Flags": 0, + "Owner": "raLHvSZXacoGiCoWrdBhVGstZm6GhF7oRr", + "RootIndex": "A33DF86647D19B7868A6FAD1E65F753837F8CFEF8F1C4F34717FD5CC7E6EA2E3" + }, + "LedgerEntryType": "DirectoryNode", + "LedgerIndex": "A33DF86647D19B7868A6FAD1E65F753837F8CFEF8F1C4F34717FD5CC7E6EA2E3" + } + } + ], + "TransactionIndex": 1, + "TransactionResult": "tesSUCCESS" + }, + "validated": true + }, + "status": "success", + "type": "response" +} \ No newline at end of file diff --git a/test/mock-rippled.js b/test/mock-rippled.js index bcef9d93..db6ebe7e 100644 --- a/test/mock-rippled.js +++ b/test/mock-rippled.js @@ -289,7 +289,24 @@ module.exports = function createMockRippled(port) { } else if (request.transaction === '097B9491CC76B64831F1FEA82EAA93BCD728106D90B65A072C933888E946C40B') { conn.send(createResponse(request, fixtures.tx.OfferWithExpiration)); + } + + // Checks + + else if (request.transaction === + '605A2E2C8E48AECAF5C56085D1AEAA0348DC838CE122C9188F94EB19DA05C2FE') { + conn.send(createResponse(request, fixtures.tx.CheckCreate)); } else if (request.transaction === + 'B4105D1B2D83819647E4692B7C5843D674283F669524BD50C9614182E3A12CD4') { + conn.send(createResponse(request, fixtures.tx.CheckCancel)); + } else if (request.transaction === + '8321208465F70BA52C28BCC4F646BAF3B012BA13B57576C0336F42D77E3E0749') { + conn.send(createResponse(request, fixtures.tx.CheckCash)); + } + + // Escrows + + else if (request.transaction === '144F272380BDB4F1BD92329A2178BABB70C20F59042C495E10BF72EBFB408EE1') { conn.send(createResponse(request, fixtures.tx.EscrowCreation)); } else if (request.transaction === @@ -302,7 +319,11 @@ module.exports = function createMockRippled(port) { 'CC5277137B3F25EE8B86259C83CB0EAADE818505E4E9BCBF19B1AC6FD1369931') { conn.send(createResponse(request, fixtures.tx.EscrowExecutionSimple)); - } else if (request.transaction === + } + + // Payment Channels + + else if (request.transaction === '0E9CA3AB1053FC0C1CBAA75F636FE1EC92F118C7056BBEF5D63E4C116458A16D') { conn.send(createResponse(request, fixtures.tx.PaymentChannelCreate)); } else if (request.transaction === diff --git a/yarn.lock b/yarn.lock index 4d6cf268..f9e8df9b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -803,8 +803,8 @@ core-js@^1.0.0: resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" core-js@^2.4.0: - version "2.5.1" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.1.tgz#ae6874dc66937789b80754ff5428df66819ca50b" + version "2.5.3" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.3.tgz#8acc38345824f16d8365b7c9b4259168e8ed603e" core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" @@ -2590,7 +2590,11 @@ lodash@3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.6.0.tgz#5266a8f49dd989be4f9f681b6f2a0c55285d0d9a" -lodash@^4.12.0, lodash@^4.14.0, lodash@^4.17.4: +lodash@^4.12.0: + version "4.17.5" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511" + +lodash@^4.14.0, lodash@^4.17.4: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" @@ -3502,8 +3506,8 @@ rechoir@^0.6.2: resolve "^1.1.6" regenerator-runtime@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz#7e54fe5b5ccd5d6624ea6255c3473be090b802e1" + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" regex-cache@^0.4.2: version "0.4.4" @@ -3696,7 +3700,7 @@ ripple-address-codec@^2.0.1: hash.js "^1.0.3" x-address-codec "^0.7.0" -ripple-binary-codec@^0.1.0, ripple-binary-codec@^0.1.10: +ripple-binary-codec@^0.1.0: version "0.1.12" resolved "https://registry.yarnpkg.com/ripple-binary-codec/-/ripple-binary-codec-0.1.12.tgz#30fb61a8d5bf61301899616c6f842e393082e385" dependencies: @@ -3708,6 +3712,18 @@ ripple-binary-codec@^0.1.0, ripple-binary-codec@^0.1.10: lodash "^4.12.0" ripple-address-codec "^2.0.1" +ripple-binary-codec@^0.1.13: + version "0.1.13" + resolved "https://registry.yarnpkg.com/ripple-binary-codec/-/ripple-binary-codec-0.1.13.tgz#c68951405a17a71695551e789966ff376da552e4" + dependencies: + babel-runtime "^6.6.1" + bn.js "^4.11.3" + create-hash "^1.1.2" + decimal.js "^5.0.8" + inherits "^2.0.1" + lodash "^4.12.0" + ripple-address-codec "^2.0.1" + ripple-hashes@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/ripple-hashes/-/ripple-hashes-0.3.1.tgz#f2f46f1ff05e6487500a99839019114cd2482411" @@ -3796,7 +3812,14 @@ setimmediate@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" -sha.js@^2.4.0, sha.js@^2.4.8: +sha.js@^2.4.0: + version "2.4.10" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.10.tgz#b1fde5cd7d11a5626638a07c604ab909cfa31f9b" + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +sha.js@^2.4.8: version "2.4.9" resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.9.tgz#98f64880474b74f4a38b8da9d3c0f2d104633e7d" dependencies: