mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-17 10:55:48 +00:00
Compare commits
53 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
de47263087 | ||
|
|
3b9679a673 | ||
|
|
f175966816 | ||
|
|
f1f5364d07 | ||
|
|
1b8b0c76ac | ||
|
|
1a8096ab18 | ||
|
|
f177771c67 | ||
|
|
081fcbfa32 | ||
|
|
0a5e4e2155 | ||
|
|
19eb88a00e | ||
|
|
c8f2967de0 | ||
|
|
b5564330f6 | ||
|
|
43ccb83f73 | ||
|
|
e2d92126c0 | ||
|
|
8c8eef45d5 | ||
|
|
a574e1158a | ||
|
|
af687a6aed | ||
|
|
016e82ab5d | ||
|
|
f300a412d7 | ||
|
|
75e2249cf3 | ||
|
|
1942bcb971 | ||
|
|
9393adf66f | ||
|
|
917aae9bf3 | ||
|
|
da36457d5c | ||
|
|
15a0ededc8 | ||
|
|
68d7864f93 | ||
|
|
1eddbf995f | ||
|
|
592385ac73 | ||
|
|
56d626f5b1 | ||
|
|
7a14300409 | ||
|
|
30fa8d658e | ||
|
|
c0101cb5e7 | ||
|
|
fd640cd65e | ||
|
|
11528eff92 | ||
|
|
3c9175459d | ||
|
|
bd4e0e01e2 | ||
|
|
cfcf6e473c | ||
|
|
50c6af3158 | ||
|
|
1d4310cd3a | ||
|
|
2191596e68 | ||
|
|
acf8f87a88 | ||
|
|
cfac146620 | ||
|
|
f3234ad853 | ||
|
|
b65fee3d85 | ||
|
|
82b294bc7d | ||
|
|
2a58573823 | ||
|
|
a96f71b7fd | ||
|
|
077f4a4c79 | ||
|
|
9a495467fb | ||
|
|
db2e62b219 | ||
|
|
2fafa493a2 | ||
|
|
7617c3005c | ||
|
|
5cdbb71277 |
@@ -30,7 +30,7 @@ Then see the [documentation](https://github.com/ripple/ripple-lib/blob/develop/d
|
||||
|
||||
##Generating Documentation
|
||||
|
||||
The continuous integration tests require that the documentation stays up-to-date. If you make changes the the JSON schemas, fixtures, or documentation sources, you must update the documentation by running `npm run docgen`.
|
||||
The continuous integration tests require that the documentation stays up-to-date. If you make changes to the JSON schemas, fixtures, or documentation sources, you must update the documentation by running `npm run docgen`.
|
||||
|
||||
##More Information
|
||||
|
||||
|
||||
560
docs/index.md
560
docs/index.md
@@ -24,9 +24,12 @@
|
||||
- [Order](#order)
|
||||
- [Order Cancellation](#order-cancellation)
|
||||
- [Settings](#settings)
|
||||
- [Suspended Payment Creation](#suspended-payment-creation)
|
||||
- [Suspended Payment Cancellation](#suspended-payment-cancellation)
|
||||
- [Suspended Payment Execution](#suspended-payment-execution)
|
||||
- [Escrow Creation](#escrow-creation)
|
||||
- [Escrow Cancellation](#escrow-cancellation)
|
||||
- [Escrow Execution](#escrow-execution)
|
||||
- [Payment Channel Create](#payment-channel-create)
|
||||
- [Payment Channel Fund](#payment-channel-fund)
|
||||
- [Payment Channel Claim](#payment-channel-claim)
|
||||
- [API Methods](#api-methods)
|
||||
- [connect](#connect)
|
||||
- [disconnect](#disconnect)
|
||||
@@ -44,19 +47,25 @@
|
||||
- [getOrderbook](#getorderbook)
|
||||
- [getSettings](#getsettings)
|
||||
- [getAccountInfo](#getaccountinfo)
|
||||
- [getPaymentChannel](#getpaymentchannel)
|
||||
- [getLedger](#getledger)
|
||||
- [preparePayment](#preparepayment)
|
||||
- [prepareTrustline](#preparetrustline)
|
||||
- [prepareOrder](#prepareorder)
|
||||
- [prepareOrderCancellation](#prepareordercancellation)
|
||||
- [prepareSettings](#preparesettings)
|
||||
- [prepareSuspendedPaymentCreation](#preparesuspendedpaymentcreation)
|
||||
- [prepareSuspendedPaymentCancellation](#preparesuspendedpaymentcancellation)
|
||||
- [prepareSuspendedPaymentExecution](#preparesuspendedpaymentexecution)
|
||||
- [prepareEscrowCreation](#prepareescrowcreation)
|
||||
- [prepareEscrowCancellation](#prepareescrowcancellation)
|
||||
- [prepareEscrowExecution](#prepareescrowexecution)
|
||||
- [preparePaymentChannelCreate](#preparepaymentchannelcreate)
|
||||
- [preparePaymentChannelClaim](#preparepaymentchannelclaim)
|
||||
- [preparePaymentChannelFund](#preparepaymentchannelfund)
|
||||
- [sign](#sign)
|
||||
- [combine](#combine)
|
||||
- [submit](#submit)
|
||||
- [generateAddress](#generateaddress)
|
||||
- [signPaymentChannelClaim](#signpaymentchannelclaim)
|
||||
- [verifyPaymentChannelClaim](#verifypaymentchannelclaim)
|
||||
- [computeLedgerHash](#computeledgerhash)
|
||||
- [API Events](#api-events)
|
||||
- [ledger](#ledger)
|
||||
@@ -180,9 +189,9 @@ Methods that depend on the state of the Ripple Consensus Ledger are unavailable
|
||||
* [prepareOrder](#prepareorder)
|
||||
* [prepareOrderCancellation](#prepareordercancellation)
|
||||
* [prepareSettings](#preparesettings)
|
||||
* [prepareSuspendedPaymentCreation](#preparesuspendedpaymentcreation)
|
||||
* [prepareSuspendedPaymentCancellation](#preparesuspendedpaymentcancellation)
|
||||
* [prepareSuspendedPaymentExecution](#preparesuspendedpaymentexecution)
|
||||
* [prepareEscrowCreation](#prepareescrowcreation)
|
||||
* [prepareEscrowCancellation](#prepareescrowcancellation)
|
||||
* [prepareEscrowExecution](#prepareescrowexecution)
|
||||
* [sign](#sign)
|
||||
* [generateAddress](#generateaddress)
|
||||
* [computeLedgerHash](#computeledgerhash)
|
||||
@@ -261,11 +270,9 @@ Type | Description
|
||||
[orderCancellation](#order-cancellation) | An `orderCancellation` transaction cancels an order in the Ripple Consensus Ledger's order book.
|
||||
[trustline](#trustline) | A `trustline` transactions creates or modifies a trust line between two accounts.
|
||||
[settings](#settings) | A `settings` transaction modifies the settings of an account in the Ripple Consensus Ledger.
|
||||
[suspendedPaymentCreation](#suspended-payment-creation) | A `suspendedPaymentCreation` transaction creates a suspended payment on the ledger, which locks XRP until a cryptographic condition is met or it expires. It is like an escrow service where the Ripple network acts as the escrow agent.
|
||||
[suspendedPaymentCancellation](#suspended-payment-cancellation) | A `suspendedPaymentCancellation` transaction unlocks the funds in a suspended payment and sends them back to the creator of the suspended payment, but it will only work after the suspended payment expires.
|
||||
[suspendedPaymentExecution](#suspended-payment-execution) | A `suspendedPaymentExecution` transaction unlocks the funds in a suspended payment and sends them to the destination of the suspended payment, but it will only work if the cryptographic condition is provided.
|
||||
|
||||
The three "suspended payment" transaction types are not supported by the production Ripple peer-to-peer network at this time. They are available for testing purposes if you [configure RippleAPI](#boilerplate) to connect to the [Ripple Test Net](https://ripple.com/build/ripple-test-net/) instead.
|
||||
[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 Ripple network 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.
|
||||
|
||||
## Transaction Flow
|
||||
|
||||
@@ -277,9 +284,9 @@ Executing a transaction with `RippleAPI` requires the following four steps:
|
||||
* [prepareOrder](#prepareorder)
|
||||
* [prepareOrderCancellation](#prepareordercancellation)
|
||||
* [prepareSettings](#preparesettings)
|
||||
* [prepareSuspendedPaymentCreation](#preparesuspendedpaymentcreation)
|
||||
* [prepareSuspendedPaymentCancellation](#preparesuspendedpaymentcancellation)
|
||||
* [prepareSuspendedPaymentExecution](#preparesuspendedpaymentexecution)
|
||||
* [prepareEscrowCreation](#prepareescrowcreation)
|
||||
* [prepareEscrowCancellation](#prepareescrowcancellation)
|
||||
* [prepareEscrowExecution](#prepareescrowexecution)
|
||||
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.
|
||||
@@ -430,6 +437,7 @@ expirationTime | date-time string | *Optional* Time after which the offer is no
|
||||
fillOrKill | boolean | *Optional* Treat the offer as a [Fill or Kill order](http://en.wikipedia.org/wiki/Fill_or_kill). Only attempt to match existing offers in the ledger, and only do so if the entire quantity can be exchanged.
|
||||
immediateOrCancel | boolean | *Optional* Treat the offer as an [Immediate or Cancel order](http://en.wikipedia.org/wiki/Immediate_or_cancel). If enabled, the offer will never become a ledger node: it only attempts to match existing offers in the ledger.
|
||||
memos | [memos](#transaction-memos) | *Optional* Array of memos to attach to the transaction.
|
||||
orderToReplace | [sequence](#account-sequence-number) | *Optional* The [account sequence number](#account-sequence-number) of an order to cancel before the new order is created, effectively replacing the old order.
|
||||
passive | boolean | *Optional* If enabled, the offer will not consume offers that exactly match it, and instead becomes an Offer node in the ledger. It will still consume offers that cross it.
|
||||
|
||||
### Example
|
||||
@@ -498,7 +506,7 @@ signers | object | *Optional* Settings that determine what sets of accounts can
|
||||
*signers.* weights[] | object | An association of an address and a weight.
|
||||
*signers.weights[].* address | [address](#ripple-address) | A Ripple account address
|
||||
*signers.weights[].* weight | integer | The weight that the signature of this account counts as towards the threshold.
|
||||
transferRate | number,null | *Optional* The fee to charge when users transfer this account’s issuances, represented as billionths of a unit. Use `null` to set no fee.
|
||||
transferRate | number,null | *Optional* The fee to charge when users transfer this account’s issuances, as the decimal amount that must be sent to deliver 1 unit. Has precision up to 9 digits beyond the decimal point. Use `null` to set no fee.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -517,59 +525,41 @@ transferRate | number,null | *Optional* The fee to charge when users transfer t
|
||||
```
|
||||
|
||||
|
||||
## Suspended Payment Creation
|
||||
## Escrow Creation
|
||||
|
||||
See [Transaction Types](#transaction-types) for a description.
|
||||
|
||||
Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
source | object | Fields pertaining to the source of the payment.
|
||||
*source.* address | [address](#ripple-address) | The address to send from.
|
||||
*source.* maxAmount | [laxAmount](#amount) | The maximum amount to send. (This field is exclusive with source.amount)
|
||||
*source.* tag | integer | *Optional* An arbitrary unsigned 32-bit integer that identifies a reason for payment or a non-Ripple account.
|
||||
destination | object | Fields pertaining to the destination of the payment.
|
||||
*destination.* address | [address](#ripple-address) | The address to receive at.
|
||||
*destination.* amount | [laxAmount](#amount) | An exact amount to deliver to the recipient. If the counterparty is not specified, amounts with any counterparty may be used. (This field is exclusive with destination.minAmount).
|
||||
*destination.* tag | integer | *Optional* An arbitrary unsigned 32-bit integer that identifies a reason for payment or a non-Ripple account.
|
||||
allowCancelAfter | date-time string | *Optional* If present, the suspended payment may be cancelled after this time.
|
||||
allowExecuteAfter | date-time string | *Optional* If present, the suspended payment can not be executed before this time.
|
||||
digest | string | *Optional* If present, proof is required upon execution.
|
||||
amount | [value](#value) | Amount of XRP for sender to escrow.
|
||||
destination | [address](#ripple-address) | Address to receive escrowed XRP.
|
||||
allowCancelAfter | date-time string | *Optional* If present, the escrow may be cancelled after this time.
|
||||
allowExecuteAfter | date-time string | *Optional* If present, the escrow can not be executed before this time.
|
||||
condition | string | *Optional* A hex value representing a [PREIMAGE-SHA-256 crypto-condition](https://tools.ietf.org/html/draft-thomas-crypto-conditions-02#section-8.1). If present, `fulfillment` is required upon execution.
|
||||
destinationTag | integer | *Optional* Destination tag.
|
||||
memos | [memos](#transaction-memos) | *Optional* Array of memos to attach to the transaction.
|
||||
sourceTag | integer | *Optional* Source tag.
|
||||
|
||||
### Example
|
||||
|
||||
|
||||
```json
|
||||
{
|
||||
"source": {
|
||||
"address": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
|
||||
"maxAmount": {
|
||||
"value": "0.01",
|
||||
"currency": "USD",
|
||||
"counterparty": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"
|
||||
}
|
||||
},
|
||||
"destination": {
|
||||
"address": "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo",
|
||||
"amount": {
|
||||
"value": "0.01",
|
||||
"currency": "USD",
|
||||
"counterparty": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"
|
||||
}
|
||||
},
|
||||
"destination": "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo",
|
||||
"amount": "0.01",
|
||||
"allowCancelAfter": "2014-09-24T21:21:50.000Z"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Suspended Payment Cancellation
|
||||
## Escrow Cancellation
|
||||
|
||||
See [Transaction Types](#transaction-types) for a description.
|
||||
|
||||
Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
owner | [address](#ripple-address) | The address of the owner of the suspended payment to cancel.
|
||||
suspensionSequence | [sequence](#account-sequence-number) | The [account sequence number](#account-sequence-number) of the [Suspended Payment Creation](#suspended-payment-creation) transaction for the suspended payment to cancel.
|
||||
owner | [address](#ripple-address) | The address of the owner of the escrow to cancel.
|
||||
escrowSequence | [sequence](#account-sequence-number) | The [account sequence number](#account-sequence-number) of the [Escrow Creation](#escrow-creation) transaction for the escrow to cancel.
|
||||
memos | [memos](#transaction-memos) | *Optional* Array of memos to attach to the transaction.
|
||||
|
||||
### Example
|
||||
@@ -578,23 +568,22 @@ memos | [memos](#transaction-memos) | *Optional* Array of memos to attach to the
|
||||
```json
|
||||
{
|
||||
"owner": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
|
||||
"suspensionSequence": 1234
|
||||
"escrowSequence": 1234
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Suspended Payment Execution
|
||||
## Escrow Execution
|
||||
|
||||
See [Transaction Types](#transaction-types) for a description.
|
||||
|
||||
Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
owner | [address](#ripple-address) | The address of the owner of the suspended payment to execute.
|
||||
suspensionSequence | [sequence](#account-sequence-number) | The [account sequence number](#account-sequence-number) of the [Suspended Payment Creation](#suspended-payment-creation) transaction for the suspended payment to execute.
|
||||
digest | string | *Optional* The original `digest` from the suspended payment creation transaction. This is sha256 hash of `proof` string. It is replicated here so that the relatively expensive hashing operation can be delegated to a server without ledger history and the server with ledger history only has to do a quick comparison of the old digest with the new digest.
|
||||
owner | [address](#ripple-address) | The address of the owner of the escrow to execute.
|
||||
escrowSequence | [sequence](#account-sequence-number) | The [account sequence number](#account-sequence-number) of the [Escrow Creation](#escrow-creation) transaction for the escrow to execute.
|
||||
condition | string | *Optional* A hex value representing a [PREIMAGE-SHA-256 crypto-condition](https://tools.ietf.org/html/draft-thomas-crypto-conditions-02#section-8.1). This must match the original `condition` from the escrow creation transaction.
|
||||
fulfillment | string | *Optional* A hex value representing the [PREIMAGE-SHA-256 crypto-condition](https://tools.ietf.org/html/draft-thomas-crypto-conditions-02#section-8.1) fulfillment for `condition`.
|
||||
memos | [memos](#transaction-memos) | *Optional* Array of memos to attach to the transaction.
|
||||
method | integer | *Optional* The method for verifying the proof; only method `1` is supported.
|
||||
proof | string | *Optional* A value that produces the digest when hashed. It must be 32 charaters long and contain only 8-bit characters.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -602,10 +591,81 @@ proof | string | *Optional* A value that produces the digest when hashed. It mus
|
||||
```json
|
||||
{
|
||||
"owner": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
|
||||
"suspensionSequence": 1234,
|
||||
"method": 1,
|
||||
"digest": "712C36933822AD3A3D136C5DF97AA863B69F9CE88B2D6CE6BDD11BFDE290C19D",
|
||||
"proof": "this must have 32 characters...."
|
||||
"escrowSequence": 1234,
|
||||
"condition": "A0258020E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855810100",
|
||||
"fulfillment": "A0028000"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Payment Channel Create
|
||||
|
||||
See [Transaction Types](#transaction-types) for a description.
|
||||
|
||||
Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
amount | [value](#value) | Amount of XRP for sender to set aside in this channel.
|
||||
destination | [address](#ripple-address) | Address to receive XRP claims against this channel.
|
||||
settleDelay | number | Amount of seconds the source address must wait before closing the channel if it has unclaimed XRP.
|
||||
publicKey | string | Public key of the key pair the source will use to sign claims against this channel.
|
||||
cancelAfter | date-time string | *Optional* Time when this channel expires.
|
||||
destinationTag | integer | *Optional* Destination tag.
|
||||
sourceTag | integer | *Optional* Source tag.
|
||||
|
||||
### Example
|
||||
|
||||
|
||||
```json
|
||||
{
|
||||
"amount": "1",
|
||||
"destination": "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
|
||||
"settleDelay": 86400,
|
||||
"publicKey": "32D2471DB72B27E3310F355BB33E339BF26F8392D5A93D3BC0FC3B566612DA0F0A"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Payment Channel Fund
|
||||
|
||||
See [Transaction Types](#transaction-types) for a description.
|
||||
|
||||
Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
amount | [value](#value) | Amount of XRP to fund the channel with.
|
||||
channel | string | 256-bit hexadecimal channel identifier.
|
||||
expiration | date-time string | *Optional* New expiration for this channel.
|
||||
|
||||
### Example
|
||||
|
||||
|
||||
```json
|
||||
{
|
||||
"channel": "C1AE6DDDEEC05CF2978C0BAD6FE302948E9533691DC749DCDD3B9E5992CA6198",
|
||||
"amount": "1"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Payment Channel Claim
|
||||
|
||||
See [Transaction Types](#transaction-types) for a description.
|
||||
|
||||
Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
channel | string | 256-bit hexadecimal channel identifier.
|
||||
amount | [value](#value) | *Optional* XRP balance of this channel after claim is processed.
|
||||
balance | [value](#value) | *Optional* Amount of XRP authorized by signature.
|
||||
close | boolean | *Optional* Request to close the channel.
|
||||
publicKey | string | *Optional* Public key of the channel's sender
|
||||
renew | boolean | *Optional* Clear the channel's expiration time.
|
||||
signature | string | *Optional* Signature of this claim.
|
||||
|
||||
### Example
|
||||
|
||||
|
||||
```json
|
||||
{
|
||||
"channel": "C1AE6DDDEEC05CF2978C0BAD6FE302948E9533691DC749DCDD3B9E5992CA6198"
|
||||
}
|
||||
```
|
||||
|
||||
@@ -1511,7 +1571,7 @@ options | object | *Optional* Options to determine how the balances will be calc
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns a promise that resolves with an array of objects with the following structure:
|
||||
This method returns a promise that resolves with an object with the following structure:
|
||||
|
||||
Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
@@ -2684,7 +2744,7 @@ signers | object | *Optional* Settings that determine what sets of accounts can
|
||||
*signers.* weights[] | object | An association of an address and a weight.
|
||||
*signers.weights[].* address | [address](#ripple-address) | A Ripple account address
|
||||
*signers.weights[].* weight | integer | The weight that the signature of this account counts as towards the threshold.
|
||||
transferRate | number,null | *Optional* The fee to charge when users transfer this account’s issuances, represented as billionths of a unit. Use `null` to set no fee.
|
||||
transferRate | number,null | *Optional* The fee to charge when users transfer this account’s issuances, as the decimal amount that must be sent to deliver 1 unit. Has precision up to 9 digits beyond the decimal point. Use `null` to set no fee.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -2753,6 +2813,61 @@ return api.getAccountInfo(address).then(info =>
|
||||
```
|
||||
|
||||
|
||||
## getPaymentChannel
|
||||
|
||||
`getPaymentChannel(id: string): Promise<Object>`
|
||||
|
||||
Returns specified payment channel.
|
||||
|
||||
### Parameters
|
||||
|
||||
Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
id | string | 256-bit hexadecimal channel identifier.
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns a promise that resolves with an object with the following structure:
|
||||
|
||||
Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
account | [address](#ripple-address) | Address that created the payment channel.
|
||||
destination | [address](#ripple-address) | Address to receive XRP claims against this channel.
|
||||
amount | [value](#value) | The total amount of XRP funded in this channel.
|
||||
balance | [value](#value) | The total amount of XRP delivered by this channel.
|
||||
settleDelay | number | Amount of seconds the source address must wait before closing the channel if it has unclaimed XRP.
|
||||
previousAffectingTransactionID | string | Hash value representing the most recent transaction that affected this payment channel.
|
||||
previousAffectingTransactionLedgerVersion | integer | The ledger version that the transaction identified by the `previousAffectingTransactionID` was validated in.
|
||||
cancelAfter | date-time string | *Optional* Time when this channel expires as specified at creation.
|
||||
destinationTag | integer | *Optional* Destination tag.
|
||||
expiration | date-time string | *Optional* Time when this channel expires.
|
||||
publicKey | string | *Optional* Public key of the key pair the source will use to sign claims against this channel.
|
||||
sourceTag | integer | *Optional* Source tag.
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
const channelId =
|
||||
'E30E709CF009A1F26E0E5C48F7AA1BFB79393764F15FB108BDC6E06D3CBD8415';
|
||||
return api.getPaymentChannel(channelId).then(channel =>
|
||||
{/* ... */});
|
||||
```
|
||||
|
||||
|
||||
```json
|
||||
{
|
||||
"account": "r6ZtfQFWbCkp4XqaUygzHaXsQXBT67xLj",
|
||||
"amount": "10",
|
||||
"balance": "0",
|
||||
"destination": "rQf9vCwQtzQQwtnGvr6zc1fqzqg7QBuj7G",
|
||||
"publicKey": "02A05282CB6197E34490BACCD9405E81D9DFBE123B0969F9F40EC3F9987AD9A97D",
|
||||
"settleDelay": 10000,
|
||||
"previousAffectingTransactionID": "F939A0BEF139465403C56CCDC49F59A77C868C78C5AEC184E29D15E9CD1FF675",
|
||||
"previousAffectingTransactionLedgerVersion": 151322
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## getLedger
|
||||
|
||||
`getLedger(options: Object): Promise<Object>`
|
||||
@@ -3051,7 +3166,7 @@ instructions | object | The instructions for how to execute the transaction afte
|
||||
```javascript
|
||||
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
|
||||
const orderCancellation = {orderSequence: 123};
|
||||
return api.prepareOrderCancellation(address, sequence)
|
||||
return api.prepareOrderCancellation(address, orderCancellation)
|
||||
.then(prepared => {/* ... */});
|
||||
```
|
||||
|
||||
@@ -3131,20 +3246,18 @@ return api.prepareSettings(address, settings)
|
||||
```
|
||||
|
||||
|
||||
## prepareSuspendedPaymentCreation
|
||||
## prepareEscrowCreation
|
||||
|
||||
`prepareSuspendedPaymentCreation(address: string, suspendedPaymentCreation: Object, instructions: Object): Promise<Object>`
|
||||
`prepareEscrowCreation(address: string, escrowCreation: Object, instructions: Object): Promise<Object>`
|
||||
|
||||
Prepare a suspended payment creation transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
|
||||
|
||||
**Caution:** Suspended Payments are currently available on the [Ripple Test Net](https://ripple.com/build/ripple-test-net/) only.
|
||||
Prepare an escrow creation transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
|
||||
|
||||
### Parameters
|
||||
|
||||
Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
address | [address](#ripple-address) | The address of the account that is creating the transaction.
|
||||
suspendedPaymentCreation | [suspendedPaymentCreation](#suspended-payment-creation) | The specification of the suspended payment creation to prepare.
|
||||
escrowCreation | [escrowCreation](#escrow-creation) | The specification of the escrow creation to prepare.
|
||||
instructions | [instructions](#transaction-instructions) | *Optional* Instructions for executing the transaction
|
||||
|
||||
### Return Value
|
||||
@@ -3167,33 +3280,19 @@ instructions | object | The instructions for how to execute the transaction afte
|
||||
|
||||
```javascript
|
||||
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
|
||||
const suspendedPaymentCreation = {
|
||||
"source": {
|
||||
"address": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
|
||||
"maxAmount": {
|
||||
"value": "0.01",
|
||||
"currency": "USD",
|
||||
"counterparty": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"
|
||||
}
|
||||
},
|
||||
"destination": {
|
||||
"address": "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo",
|
||||
"amount": {
|
||||
"value": "0.01",
|
||||
"currency": "USD",
|
||||
"counterparty": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"
|
||||
}
|
||||
},
|
||||
const escrowCreation = {
|
||||
"destination": "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo",
|
||||
"amount": "0.01",
|
||||
"allowCancelAfter": "2014-09-24T21:21:50.000Z"
|
||||
};
|
||||
return api.prepareSuspendedPaymentCreation(address, suspendedPaymentCreation).then(prepared =>
|
||||
return api.prepareEscrowCreation(address, escrowCreation).then(prepared =>
|
||||
{/* ... */});
|
||||
```
|
||||
|
||||
|
||||
```json
|
||||
{
|
||||
"txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"SuspendedPaymentCreate\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Destination\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"Amount\":{\"value\":\"0.01\",\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"CancelAfter\":464908910,\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}",
|
||||
"txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"EscrowCreate\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Destination\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"Amount\":\"10000\",\"CancelAfter\":464908910,\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}",
|
||||
"instructions": {
|
||||
"fee": "0.000012",
|
||||
"sequence": 23,
|
||||
@@ -3203,20 +3302,18 @@ return api.prepareSuspendedPaymentCreation(address, suspendedPaymentCreation).th
|
||||
```
|
||||
|
||||
|
||||
## prepareSuspendedPaymentCancellation
|
||||
## prepareEscrowCancellation
|
||||
|
||||
`prepareSuspendedPaymentCancellation(address: string, suspendedPaymentCancellation: Object, instructions: Object): Promise<Object>`
|
||||
`prepareEscrowCancellation(address: string, escrowCancellation: Object, instructions: Object): Promise<Object>`
|
||||
|
||||
Prepare a suspended payment cancellation transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
|
||||
|
||||
**Caution:** Suspended Payments are currently available on the [Ripple Test Net](https://ripple.com/build/ripple-test-net/) only.
|
||||
Prepare an escrow cancellation transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
|
||||
|
||||
### Parameters
|
||||
|
||||
Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
address | [address](#ripple-address) | The address of the account that is creating the transaction.
|
||||
suspendedPaymentCancellation | [suspendedPaymentCancellation](#suspended-payment-cancellation) | The specification of the suspended payment cancellation to prepare.
|
||||
escrowCancellation | [escrowCancellation](#escrow-cancellation) | The specification of the escrow cancellation to prepare.
|
||||
instructions | [instructions](#transaction-instructions) | *Optional* Instructions for executing the transaction
|
||||
|
||||
### Return Value
|
||||
@@ -3239,18 +3336,18 @@ instructions | object | The instructions for how to execute the transaction afte
|
||||
|
||||
```javascript
|
||||
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
|
||||
const suspendedPaymentCancellation = {
|
||||
const escrowCancellation = {
|
||||
"owner": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
|
||||
"suspensionSequence": 1234
|
||||
"escrowSequence": 1234
|
||||
};
|
||||
return api.prepareSuspendedPaymentCancellation(address, suspendedPaymentCancellation).then(prepared =>
|
||||
return api.prepareEscrowCancellation(address, escrowCancellation).then(prepared =>
|
||||
{/* ... */});
|
||||
```
|
||||
|
||||
|
||||
```json
|
||||
{
|
||||
"txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"SuspendedPaymentCancel\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Owner\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"OfferSequence\":1234,\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}",
|
||||
"txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"EscrowCancel\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Owner\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"OfferSequence\":1234,\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}",
|
||||
"instructions": {
|
||||
"fee": "0.000012",
|
||||
"sequence": 23,
|
||||
@@ -3260,20 +3357,18 @@ return api.prepareSuspendedPaymentCancellation(address, suspendedPaymentCancella
|
||||
```
|
||||
|
||||
|
||||
## prepareSuspendedPaymentExecution
|
||||
## prepareEscrowExecution
|
||||
|
||||
`prepareSuspendedPaymentExecution(address: string, suspendedPaymentExecution: Object, instructions: Object): Promise<Object>`
|
||||
`prepareEscrowExecution(address: string, escrowExecution: Object, instructions: Object): Promise<Object>`
|
||||
|
||||
Prepare a suspended payment execution transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
|
||||
|
||||
**Caution:** Suspended Payments are currently available on the [Ripple Test Net](https://ripple.com/build/ripple-test-net/) only.
|
||||
Prepare an escrow execution transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
|
||||
|
||||
### Parameters
|
||||
|
||||
Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
address | [address](#ripple-address) | The address of the account that is creating the transaction.
|
||||
suspendedPaymentExecution | [suspendedPaymentExecution](#suspended-payment-execution) | The specification of the suspended payment execution to prepare.
|
||||
escrowExecution | [escrowExecution](#escrow-execution) | The specification of the escrow execution to prepare.
|
||||
instructions | [instructions](#transaction-instructions) | *Optional* Instructions for executing the transaction
|
||||
|
||||
### Return Value
|
||||
@@ -3296,21 +3391,186 @@ instructions | object | The instructions for how to execute the transaction afte
|
||||
|
||||
```javascript
|
||||
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
|
||||
const suspendedPaymentExecution = {
|
||||
const escrowExecution = {
|
||||
"owner": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
|
||||
"suspensionSequence": 1234,
|
||||
"method": 1,
|
||||
"digest": "712C36933822AD3A3D136C5DF97AA863B69F9CE88B2D6CE6BDD11BFDE290C19D",
|
||||
"proof": "this must have 32 characters...."
|
||||
"escrowSequence": 1234,
|
||||
"condition": "A0258020E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855810100",
|
||||
"fulfillment": "A0028000"
|
||||
};
|
||||
return api.prepareSuspendedPaymentExecution(address, suspendedPaymentExecution).then(prepared =>
|
||||
return api.prepareEscrowExecution(address, escrowExecution).then(prepared =>
|
||||
{/* ... */});
|
||||
```
|
||||
|
||||
|
||||
```json
|
||||
{
|
||||
"txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"SuspendedPaymentFinish\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Owner\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"OfferSequence\":1234,\"Method\":1,\"Digest\":\"712C36933822AD3A3D136C5DF97AA863B69F9CE88B2D6CE6BDD11BFDE290C19D\",\"Proof\":\"74686973206D757374206861766520333220636861726163746572732E2E2E2E\",\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}",
|
||||
"txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"EscrowFinish\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Owner\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"OfferSequence\":1234,\"Condition\":\"A0258020E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855810100\",\"Fulfillment\":\"A0028000\",\"LastLedgerSequence\":8820051,\"Fee\":\"396\",\"Sequence\":23}",
|
||||
"instructions": {
|
||||
"fee": "0.000396",
|
||||
"sequence": 23,
|
||||
"maxLedgerVersion": 8820051
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## preparePaymentChannelCreate
|
||||
|
||||
`preparePaymentChannelCreate(address: string, paymentChannelCreate: Object, instructions: Object): Promise<Object>`
|
||||
|
||||
Prepare a payment channel creation transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
|
||||
|
||||
### Parameters
|
||||
|
||||
Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
address | [address](#ripple-address) | The address of the account that is creating the transaction.
|
||||
paymentChannelCreate | [paymentChannelCreate](#payment-channel-create) | The specification of the payment channel to create.
|
||||
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:
|
||||
|
||||
<aside class="notice">
|
||||
All "prepare*" methods have the same return type.
|
||||
</aside>
|
||||
|
||||
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 paymentChannelCreate = {
|
||||
"amount": "1",
|
||||
"destination": "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
|
||||
"settleDelay": 86400,
|
||||
"publicKey": "32D2471DB72B27E3310F355BB33E339BF26F8392D5A93D3BC0FC3B566612DA0F0A"
|
||||
};
|
||||
return api.preparePaymentChannelCreate(address, paymentChannelCreate).then(prepared =>
|
||||
{/* ... */});
|
||||
```
|
||||
|
||||
|
||||
```json
|
||||
{
|
||||
"txJSON":"{\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"TransactionType\":\"PaymentChannelCreate\",\"Amount\":\"1000000\",\"Destination\":\"rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW\",\"SettleDelay\":86400,\"PublicKey\":\"32D2471DB72B27E3310F355BB33E339BF26F8392D5A93D3BC0FC3B566612DA0F0A\",\"Flags\":2147483648,\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}",
|
||||
"instructions": {
|
||||
"fee": "0.000012",
|
||||
"sequence": 23,
|
||||
"maxLedgerVersion": 8820051
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## preparePaymentChannelClaim
|
||||
|
||||
`preparePaymentChannelClaim(address: string, paymentChannelClaim: Object, instructions: Object): Promise<Object>`
|
||||
|
||||
Prepare a payment channel claim transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
|
||||
|
||||
### Parameters
|
||||
|
||||
Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
address | [address](#ripple-address) | The address of the account that is creating the transaction.
|
||||
paymentChannelClaim | [paymentChannelClaim](#payment-channel-claim) | Details of the channel and claim.
|
||||
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:
|
||||
|
||||
<aside class="notice">
|
||||
All "prepare*" methods have the same return type.
|
||||
</aside>
|
||||
|
||||
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 paymentChannelClaim = {
|
||||
"channel": "C1AE6DDDEEC05CF2978C0BAD6FE302948E9533691DC749DCDD3B9E5992CA6198"
|
||||
};
|
||||
return api.preparePaymentChannelClaim(address, paymentChannelClaim).then(prepared =>
|
||||
{/* ... */});
|
||||
```
|
||||
|
||||
|
||||
```json
|
||||
{
|
||||
"txJSON": "{\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"TransactionType\":\"PaymentChannelClaim\",\"Channel\":\"C1AE6DDDEEC05CF2978C0BAD6FE302948E9533691DC749DCDD3B9E5992CA6198\",\"Flags\":2147483648,\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}",
|
||||
"instructions": {
|
||||
"fee": "0.000012",
|
||||
"sequence": 23,
|
||||
"maxLedgerVersion": 8820051
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## preparePaymentChannelFund
|
||||
|
||||
`preparePaymentChannelFund(address: string, paymentChannelFund: Object, instructions: Object): Promise<Object>`
|
||||
|
||||
Prepare a payment channel fund transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
|
||||
|
||||
### Parameters
|
||||
|
||||
Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
address | [address](#ripple-address) | The address of the account that is creating the transaction.
|
||||
paymentChannelFund | [paymentChannelFund](#payment-channel-fund) | The channel to fund, and the details of how to fund it.
|
||||
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:
|
||||
|
||||
<aside class="notice">
|
||||
All "prepare*" methods have the same return type.
|
||||
</aside>
|
||||
|
||||
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 paymentChannelFund = {
|
||||
"channel": "C1AE6DDDEEC05CF2978C0BAD6FE302948E9533691DC749DCDD3B9E5992CA6198",
|
||||
"amount": "1"
|
||||
};
|
||||
return api.preparePaymentChannelFund(address, paymentChannelFund).then(prepared =>
|
||||
{/* ... */});
|
||||
```
|
||||
|
||||
|
||||
```json
|
||||
{
|
||||
"txJSON":"{\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"TransactionType\":\"PaymentChannelFund\",\"Channel\":\"C1AE6DDDEEC05CF2978C0BAD6FE302948E9533691DC749DCDD3B9E5992CA6198\",\"Amount\":\"1000000\",\"Flags\":2147483648,\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}",
|
||||
"instructions": {
|
||||
"fee": "0.000012",
|
||||
"sequence": 23,
|
||||
@@ -3475,6 +3735,84 @@ return api.generateAddress();
|
||||
```
|
||||
|
||||
|
||||
## signPaymentChannelClaim
|
||||
|
||||
`signPaymentChannelClaim(channel: string, amount: string, privateKey: string): string`
|
||||
|
||||
Sign a payment channel claim. The signature can be submitted in a subsequent [PaymentChannelClaim](#preparePaymmentChannelClaim) transaction.
|
||||
|
||||
### Parameters
|
||||
|
||||
Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
channel | string | 256-bit hexadecimal channel identifier.
|
||||
amount | [value](#value) | Amount of XRP authorized by the claim.
|
||||
privateKey | string | The private key to sign the payment channel claim.
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns a signature string:
|
||||
|
||||
Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
| string | The hexadecimal representation of a signature.
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
const channel =
|
||||
'3E18C05AD40319B809520F1A136370C4075321B285217323396D6FD9EE1E9037';
|
||||
const amount = '.00001';
|
||||
const privateKey =
|
||||
'ACCD3309DB14D1A4FC9B1DAE608031F4408C85C73EE05E035B7DC8B25840107A';
|
||||
return api.signPaymentChannelClaim(channel, amount, privateKey);
|
||||
```
|
||||
|
||||
|
||||
```json
|
||||
"3045022100B5C54654221F154347679B97AE7791CBEF5E6772A3F894F9C781B8F1B400F89F022021E466D29DC5AEB5DFAFC76E8A88D2E388EBD25A84143B6AC3B647F479CB89B7"
|
||||
```
|
||||
|
||||
|
||||
## verifyPaymentChannelClaim
|
||||
|
||||
`verifyPaymentChannelClaim(channel: string, amount: string, signature: string, publicKey: string): boolean`
|
||||
|
||||
Verify a payment channel claim signature.
|
||||
|
||||
### Parameters
|
||||
|
||||
Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
channel | string | 256-bit hexadecimal channel identifier.
|
||||
amount | [value](#value) | Amount of XRP authorized by the claim.
|
||||
signature | string | Signature of this claim.
|
||||
publicKey | string | Public key of the channel's sender
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns `true` if the claim signature is valid.
|
||||
|
||||
Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
| boolean |
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
const channel =
|
||||
'3E18C05AD40319B809520F1A136370C4075321B285217323396D6FD9EE1E9037';
|
||||
const amount = '.00001';
|
||||
const signature = "3045022100B5C54654221F154347679B97AE7791CBEF5E6772A3F894F9C781B8F1B400F89F022021E466D29DC5AEB5DFAFC76E8A88D2E388EBD25A84143B6AC3B647F479CB89B7";
|
||||
const publicKey =
|
||||
'02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8';
|
||||
return api.verifyPaymentChannelClaim(channel, amount, signature, publicKey);
|
||||
```
|
||||
|
||||
```json
|
||||
true
|
||||
```
|
||||
|
||||
## computeLedgerHash
|
||||
|
||||
`computeLedgerHash(ledger: Object): string`
|
||||
|
||||
@@ -10,7 +10,7 @@ Returns aggregate balances by currency plus a breakdown of assets and obligation
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns a promise that resolves with an array of objects with the following structure:
|
||||
This method returns a promise that resolves with an object with the following structure:
|
||||
|
||||
<%- renderSchema('output/get-balance-sheet.json') %>
|
||||
|
||||
|
||||
26
docs/src/getPaymentChannel.md.ejs
Normal file
26
docs/src/getPaymentChannel.md.ejs
Normal file
@@ -0,0 +1,26 @@
|
||||
## getPaymentChannel
|
||||
|
||||
`getPaymentChannel(id: string): Promise<Object>`
|
||||
|
||||
Returns specified payment channel.
|
||||
|
||||
### Parameters
|
||||
|
||||
<%- renderSchema('input/get-payment-channel.json') %>
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns a promise that resolves with an object with the following structure:
|
||||
|
||||
<%- renderSchema('output/get-payment-channel.json') %>
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
const channelId =
|
||||
'E30E709CF009A1F26E0E5C48F7AA1BFB79393764F15FB108BDC6E06D3CBD8415';
|
||||
return api.getPaymentChannel(channelId).then(channel =>
|
||||
{/* ... */});
|
||||
```
|
||||
|
||||
<%- renderFixture('responses/get-payment-channel.json') %>
|
||||
@@ -21,18 +21,24 @@
|
||||
<% include getOrderbook.md.ejs %>
|
||||
<% include getSettings.md.ejs %>
|
||||
<% include getAccountInfo.md.ejs %>
|
||||
<% include getPaymentChannel.md.ejs %>
|
||||
<% include getLedger.md.ejs %>
|
||||
<% include preparePayment.md.ejs %>
|
||||
<% include prepareTrustline.md.ejs %>
|
||||
<% include prepareOrder.md.ejs %>
|
||||
<% include prepareOrderCancellation.md.ejs %>
|
||||
<% include prepareSettings.md.ejs %>
|
||||
<% include prepareSuspendedPaymentCreation.md.ejs %>
|
||||
<% include prepareSuspendedPaymentCancellation.md.ejs %>
|
||||
<% include prepareSuspendedPaymentExecution.md.ejs %>
|
||||
<% include prepareEscrowCreation.md.ejs %>
|
||||
<% include prepareEscrowCancellation.md.ejs %>
|
||||
<% include prepareEscrowExecution.md.ejs %>
|
||||
<% include preparePaymentChannelCreate.md.ejs %>
|
||||
<% include preparePaymentChannelClaim.md.ejs %>
|
||||
<% include preparePaymentChannelFund.md.ejs %>
|
||||
<% include sign.md.ejs %>
|
||||
<% include combine.md.ejs %>
|
||||
<% include submit.md.ejs %>
|
||||
<% include generateAddress.md.ejs %>
|
||||
<% include signPaymentChannelClaim.md.ejs %>
|
||||
<% include verifyPaymentChannelClaim.md.ejs %>
|
||||
<% include computeLedgerHash.md.ejs %>
|
||||
<% include events.md.ejs %>
|
||||
|
||||
@@ -18,9 +18,9 @@ Methods that depend on the state of the Ripple Consensus Ledger are unavailable
|
||||
* [prepareOrder](#prepareorder)
|
||||
* [prepareOrderCancellation](#prepareordercancellation)
|
||||
* [prepareSettings](#preparesettings)
|
||||
* [prepareSuspendedPaymentCreation](#preparesuspendedpaymentcreation)
|
||||
* [prepareSuspendedPaymentCancellation](#preparesuspendedpaymentcancellation)
|
||||
* [prepareSuspendedPaymentExecution](#preparesuspendedpaymentexecution)
|
||||
* [prepareEscrowCreation](#prepareescrowcreation)
|
||||
* [prepareEscrowCancellation](#prepareescrowcancellation)
|
||||
* [prepareEscrowExecution](#prepareescrowexecution)
|
||||
* [sign](#sign)
|
||||
* [generateAddress](#generateaddress)
|
||||
* [computeLedgerHash](#computeledgerhash)
|
||||
|
||||
30
docs/src/prepareEscrowCancellation.md.ejs
Normal file
30
docs/src/prepareEscrowCancellation.md.ejs
Normal file
@@ -0,0 +1,30 @@
|
||||
## prepareEscrowCancellation
|
||||
|
||||
`prepareEscrowCancellation(address: string, escrowCancellation: Object, instructions: Object): Promise<Object>`
|
||||
|
||||
Prepare an escrow cancellation transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
|
||||
|
||||
### Parameters
|
||||
|
||||
<%- renderSchema('input/prepare-escrow-cancellation.json') %>
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns a promise that resolves with an object with the following structure:
|
||||
|
||||
<aside class="notice">
|
||||
All "prepare*" methods have the same return type.
|
||||
</aside>
|
||||
|
||||
<%- renderSchema('output/prepare.json') %>
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
|
||||
const escrowCancellation = <%- importFile('test/fixtures/requests/prepare-escrow-cancellation.json') %>;
|
||||
return api.prepareEscrowCancellation(address, escrowCancellation).then(prepared =>
|
||||
{/* ... */});
|
||||
```
|
||||
|
||||
<%- renderFixture('responses/prepare-escrow-cancellation.json') %>
|
||||
30
docs/src/prepareEscrowCreation.md.ejs
Normal file
30
docs/src/prepareEscrowCreation.md.ejs
Normal file
@@ -0,0 +1,30 @@
|
||||
## prepareEscrowCreation
|
||||
|
||||
`prepareEscrowCreation(address: string, escrowCreation: Object, instructions: Object): Promise<Object>`
|
||||
|
||||
Prepare an escrow creation transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
|
||||
|
||||
### Parameters
|
||||
|
||||
<%- renderSchema('input/prepare-escrow-creation.json') %>
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns a promise that resolves with an object with the following structure:
|
||||
|
||||
<aside class="notice">
|
||||
All "prepare*" methods have the same return type.
|
||||
</aside>
|
||||
|
||||
<%- renderSchema('output/prepare.json') %>
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
|
||||
const escrowCreation = <%- importFile('test/fixtures/requests/prepare-escrow-creation.json') %>;
|
||||
return api.prepareEscrowCreation(address, escrowCreation).then(prepared =>
|
||||
{/* ... */});
|
||||
```
|
||||
|
||||
<%- renderFixture('responses/prepare-escrow-creation.json') %>
|
||||
30
docs/src/prepareEscrowExecution.md.ejs
Normal file
30
docs/src/prepareEscrowExecution.md.ejs
Normal file
@@ -0,0 +1,30 @@
|
||||
## prepareEscrowExecution
|
||||
|
||||
`prepareEscrowExecution(address: string, escrowExecution: Object, instructions: Object): Promise<Object>`
|
||||
|
||||
Prepare an escrow execution transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
|
||||
|
||||
### Parameters
|
||||
|
||||
<%- renderSchema('input/prepare-escrow-execution.json') %>
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns a promise that resolves with an object with the following structure:
|
||||
|
||||
<aside class="notice">
|
||||
All "prepare*" methods have the same return type.
|
||||
</aside>
|
||||
|
||||
<%- renderSchema('output/prepare.json') %>
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
|
||||
const escrowExecution = <%- importFile('test/fixtures/requests/prepare-escrow-execution.json') %>;
|
||||
return api.prepareEscrowExecution(address, escrowExecution).then(prepared =>
|
||||
{/* ... */});
|
||||
```
|
||||
|
||||
<%- renderFixture('responses/prepare-escrow-execution.json') %>
|
||||
@@ -23,7 +23,7 @@ All "prepare*" methods have the same return type.
|
||||
```javascript
|
||||
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
|
||||
const orderCancellation = {orderSequence: 123};
|
||||
return api.prepareOrderCancellation(address, sequence)
|
||||
return api.prepareOrderCancellation(address, orderCancellation)
|
||||
.then(prepared => {/* ... */});
|
||||
```
|
||||
|
||||
|
||||
30
docs/src/preparePaymentChannelClaim.md.ejs
Normal file
30
docs/src/preparePaymentChannelClaim.md.ejs
Normal file
@@ -0,0 +1,30 @@
|
||||
## preparePaymentChannelClaim
|
||||
|
||||
`preparePaymentChannelClaim(address: string, paymentChannelClaim: Object, instructions: Object): Promise<Object>`
|
||||
|
||||
Prepare a payment channel claim transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
|
||||
|
||||
### Parameters
|
||||
|
||||
<%- renderSchema('input/prepare-payment-channel-claim.json') %>
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns a promise that resolves with an object with the following structure:
|
||||
|
||||
<aside class="notice">
|
||||
All "prepare*" methods have the same return type.
|
||||
</aside>
|
||||
|
||||
<%- renderSchema('output/prepare.json') %>
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
|
||||
const paymentChannelClaim = <%- importFile('test/fixtures/requests/prepare-payment-channel-claim.json') %>;
|
||||
return api.preparePaymentChannelClaim(address, paymentChannelClaim).then(prepared =>
|
||||
{/* ... */});
|
||||
```
|
||||
|
||||
<%- renderFixture('responses/prepare-payment-channel-claim.json') %>
|
||||
30
docs/src/preparePaymentChannelCreate.md.ejs
Normal file
30
docs/src/preparePaymentChannelCreate.md.ejs
Normal file
@@ -0,0 +1,30 @@
|
||||
## preparePaymentChannelCreate
|
||||
|
||||
`preparePaymentChannelCreate(address: string, paymentChannelCreate: Object, instructions: Object): Promise<Object>`
|
||||
|
||||
Prepare a payment channel creation transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
|
||||
|
||||
### Parameters
|
||||
|
||||
<%- renderSchema('input/prepare-payment-channel-create.json') %>
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns a promise that resolves with an object with the following structure:
|
||||
|
||||
<aside class="notice">
|
||||
All "prepare*" methods have the same return type.
|
||||
</aside>
|
||||
|
||||
<%- renderSchema('output/prepare.json') %>
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
|
||||
const paymentChannelCreate = <%- importFile('test/fixtures/requests/prepare-payment-channel-create.json') %>;
|
||||
return api.preparePaymentChannelCreate(address, paymentChannelCreate).then(prepared =>
|
||||
{/* ... */});
|
||||
```
|
||||
|
||||
<%- renderFixture('responses/prepare-payment-channel-create.json') %>
|
||||
30
docs/src/preparePaymentChannelFund.md.ejs
Normal file
30
docs/src/preparePaymentChannelFund.md.ejs
Normal file
@@ -0,0 +1,30 @@
|
||||
## preparePaymentChannelFund
|
||||
|
||||
`preparePaymentChannelFund(address: string, paymentChannelFund: Object, instructions: Object): Promise<Object>`
|
||||
|
||||
Prepare a payment channel fund transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
|
||||
|
||||
### Parameters
|
||||
|
||||
<%- renderSchema('input/prepare-payment-channel-fund.json') %>
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns a promise that resolves with an object with the following structure:
|
||||
|
||||
<aside class="notice">
|
||||
All "prepare*" methods have the same return type.
|
||||
</aside>
|
||||
|
||||
<%- renderSchema('output/prepare.json') %>
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
|
||||
const paymentChannelFund = <%- importFile('test/fixtures/requests/prepare-payment-channel-fund.json') %>;
|
||||
return api.preparePaymentChannelFund(address, paymentChannelFund).then(prepared =>
|
||||
{/* ... */});
|
||||
```
|
||||
|
||||
<%- renderFixture('responses/prepare-payment-channel-fund.json') %>
|
||||
@@ -1,32 +0,0 @@
|
||||
## prepareSuspendedPaymentCancellation
|
||||
|
||||
`prepareSuspendedPaymentCancellation(address: string, suspendedPaymentCancellation: Object, instructions: Object): Promise<Object>`
|
||||
|
||||
Prepare a suspended payment cancellation transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
|
||||
|
||||
**Caution:** Suspended Payments are currently available on the [Ripple Test Net](https://ripple.com/build/ripple-test-net/) only.
|
||||
|
||||
### Parameters
|
||||
|
||||
<%- renderSchema('input/prepare-suspended-payment-cancellation.json') %>
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns a promise that resolves with an object with the following structure:
|
||||
|
||||
<aside class="notice">
|
||||
All "prepare*" methods have the same return type.
|
||||
</aside>
|
||||
|
||||
<%- renderSchema('output/prepare.json') %>
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
|
||||
const suspendedPaymentCancellation = <%- importFile('test/fixtures/requests/prepare-suspended-payment-cancellation.json') %>;
|
||||
return api.prepareSuspendedPaymentCancellation(address, suspendedPaymentCancellation).then(prepared =>
|
||||
{/* ... */});
|
||||
```
|
||||
|
||||
<%- renderFixture('responses/prepare-suspended-payment-cancellation.json') %>
|
||||
@@ -1,32 +0,0 @@
|
||||
## prepareSuspendedPaymentCreation
|
||||
|
||||
`prepareSuspendedPaymentCreation(address: string, suspendedPaymentCreation: Object, instructions: Object): Promise<Object>`
|
||||
|
||||
Prepare a suspended payment creation transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
|
||||
|
||||
**Caution:** Suspended Payments are currently available on the [Ripple Test Net](https://ripple.com/build/ripple-test-net/) only.
|
||||
|
||||
### Parameters
|
||||
|
||||
<%- renderSchema('input/prepare-suspended-payment-creation.json') %>
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns a promise that resolves with an object with the following structure:
|
||||
|
||||
<aside class="notice">
|
||||
All "prepare*" methods have the same return type.
|
||||
</aside>
|
||||
|
||||
<%- renderSchema('output/prepare.json') %>
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
|
||||
const suspendedPaymentCreation = <%- importFile('test/fixtures/requests/prepare-suspended-payment-creation.json') %>;
|
||||
return api.prepareSuspendedPaymentCreation(address, suspendedPaymentCreation).then(prepared =>
|
||||
{/* ... */});
|
||||
```
|
||||
|
||||
<%- renderFixture('responses/prepare-suspended-payment-creation.json') %>
|
||||
@@ -1,32 +0,0 @@
|
||||
## prepareSuspendedPaymentExecution
|
||||
|
||||
`prepareSuspendedPaymentExecution(address: string, suspendedPaymentExecution: Object, instructions: Object): Promise<Object>`
|
||||
|
||||
Prepare a suspended payment execution transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
|
||||
|
||||
**Caution:** Suspended Payments are currently available on the [Ripple Test Net](https://ripple.com/build/ripple-test-net/) only.
|
||||
|
||||
### Parameters
|
||||
|
||||
<%- renderSchema('input/prepare-suspended-payment-execution.json') %>
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns a promise that resolves with an object with the following structure:
|
||||
|
||||
<aside class="notice">
|
||||
All "prepare*" methods have the same return type.
|
||||
</aside>
|
||||
|
||||
<%- renderSchema('output/prepare.json') %>
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
|
||||
const suspendedPaymentExecution = <%- importFile('test/fixtures/requests/prepare-suspended-payment-execution.json') %>;
|
||||
return api.prepareSuspendedPaymentExecution(address, suspendedPaymentExecution).then(prepared =>
|
||||
{/* ... */});
|
||||
```
|
||||
|
||||
<%- renderFixture('responses/prepare-suspended-payment-execution.json') %>
|
||||
28
docs/src/signPaymentChannelClaim.md.ejs
Normal file
28
docs/src/signPaymentChannelClaim.md.ejs
Normal file
@@ -0,0 +1,28 @@
|
||||
## signPaymentChannelClaim
|
||||
|
||||
`signPaymentChannelClaim(channel: string, amount: string, privateKey: string): string`
|
||||
|
||||
Sign a payment channel claim. The signature can be submitted in a subsequent [PaymentChannelClaim](#preparePaymmentChannelClaim) transaction.
|
||||
|
||||
### Parameters
|
||||
|
||||
<%- renderSchema("input/sign-payment-channel-claim.json") %>
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns a signature string:
|
||||
|
||||
<%- renderSchema("output/sign-payment-channel-claim.json") %>
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
const channel =
|
||||
'3E18C05AD40319B809520F1A136370C4075321B285217323396D6FD9EE1E9037';
|
||||
const amount = '.00001';
|
||||
const privateKey =
|
||||
'ACCD3309DB14D1A4FC9B1DAE608031F4408C85C73EE05E035B7DC8B25840107A';
|
||||
return api.signPaymentChannelClaim(channel, amount, privateKey);
|
||||
```
|
||||
|
||||
<%- renderFixture("responses/sign-payment-channel-claim.json") %>
|
||||
@@ -52,32 +52,62 @@ See [Transaction Types](#transaction-types) for a description.
|
||||
|
||||
<%- renderFixture('requests/prepare-settings.json') %>
|
||||
|
||||
## Suspended Payment Creation
|
||||
## Escrow Creation
|
||||
|
||||
See [Transaction Types](#transaction-types) for a description.
|
||||
|
||||
<%- renderSchema('specifications/suspended-payment-creation.json') %>
|
||||
<%- renderSchema('specifications/escrow-creation.json') %>
|
||||
|
||||
### Example
|
||||
|
||||
<%- renderFixture('requests/prepare-suspended-payment-creation.json') %>
|
||||
<%- renderFixture('requests/prepare-escrow-creation.json') %>
|
||||
|
||||
## Suspended Payment Cancellation
|
||||
## Escrow Cancellation
|
||||
|
||||
See [Transaction Types](#transaction-types) for a description.
|
||||
|
||||
<%- renderSchema('specifications/suspended-payment-cancellation.json') %>
|
||||
<%- renderSchema('specifications/escrow-cancellation.json') %>
|
||||
|
||||
### Example
|
||||
|
||||
<%- renderFixture('requests/prepare-suspended-payment-cancellation.json') %>
|
||||
<%- renderFixture('requests/prepare-escrow-cancellation.json') %>
|
||||
|
||||
## Suspended Payment Execution
|
||||
## Escrow Execution
|
||||
|
||||
See [Transaction Types](#transaction-types) for a description.
|
||||
|
||||
<%- renderSchema('specifications/suspended-payment-execution.json') %>
|
||||
<%- renderSchema('specifications/escrow-execution.json') %>
|
||||
|
||||
### Example
|
||||
|
||||
<%- renderFixture('requests/prepare-suspended-payment-execution.json') %>
|
||||
<%- renderFixture('requests/prepare-escrow-execution.json') %>
|
||||
|
||||
## Payment Channel Create
|
||||
|
||||
See [Transaction Types](#transaction-types) for a description.
|
||||
|
||||
<%- renderSchema('specifications/payment-channel-create.json') %>
|
||||
|
||||
### Example
|
||||
|
||||
<%- renderFixture('requests/prepare-payment-channel-create.json') %>
|
||||
|
||||
## Payment Channel Fund
|
||||
|
||||
See [Transaction Types](#transaction-types) for a description.
|
||||
|
||||
<%- renderSchema('specifications/payment-channel-fund.json') %>
|
||||
|
||||
### Example
|
||||
|
||||
<%- renderFixture('requests/prepare-payment-channel-fund.json') %>
|
||||
|
||||
## Payment Channel Claim
|
||||
|
||||
See [Transaction Types](#transaction-types) for a description.
|
||||
|
||||
<%- renderSchema('specifications/payment-channel-claim.json') %>
|
||||
|
||||
### Example
|
||||
|
||||
<%- renderFixture('requests/prepare-payment-channel-claim.json') %>
|
||||
|
||||
@@ -11,11 +11,9 @@ Type | Description
|
||||
[orderCancellation](#order-cancellation) | An `orderCancellation` transaction cancels an order in the Ripple Consensus Ledger's order book.
|
||||
[trustline](#trustline) | A `trustline` transactions creates or modifies a trust line between two accounts.
|
||||
[settings](#settings) | A `settings` transaction modifies the settings of an account in the Ripple Consensus Ledger.
|
||||
[suspendedPaymentCreation](#suspended-payment-creation) | A `suspendedPaymentCreation` transaction creates a suspended payment on the ledger, which locks XRP until a cryptographic condition is met or it expires. It is like an escrow service where the Ripple network acts as the escrow agent.
|
||||
[suspendedPaymentCancellation](#suspended-payment-cancellation) | A `suspendedPaymentCancellation` transaction unlocks the funds in a suspended payment and sends them back to the creator of the suspended payment, but it will only work after the suspended payment expires.
|
||||
[suspendedPaymentExecution](#suspended-payment-execution) | A `suspendedPaymentExecution` transaction unlocks the funds in a suspended payment and sends them to the destination of the suspended payment, but it will only work if the cryptographic condition is provided.
|
||||
|
||||
The three "suspended payment" transaction types are not supported by the production Ripple peer-to-peer network at this time. They are available for testing purposes if you [configure RippleAPI](#boilerplate) to connect to the [Ripple Test Net](https://ripple.com/build/ripple-test-net/) instead.
|
||||
[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 Ripple network 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.
|
||||
|
||||
## Transaction Flow
|
||||
|
||||
@@ -27,9 +25,9 @@ Executing a transaction with `RippleAPI` requires the following four steps:
|
||||
* [prepareOrder](#prepareorder)
|
||||
* [prepareOrderCancellation](#prepareordercancellation)
|
||||
* [prepareSettings](#preparesettings)
|
||||
* [prepareSuspendedPaymentCreation](#preparesuspendedpaymentcreation)
|
||||
* [prepareSuspendedPaymentCancellation](#preparesuspendedpaymentcancellation)
|
||||
* [prepareSuspendedPaymentExecution](#preparesuspendedpaymentexecution)
|
||||
* [prepareEscrowCreation](#prepareescrowcreation)
|
||||
* [prepareEscrowCancellation](#prepareescrowcancellation)
|
||||
* [prepareEscrowExecution](#prepareescrowexecution)
|
||||
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.
|
||||
|
||||
31
docs/src/verifyPaymentChannelClaim.md.ejs
Normal file
31
docs/src/verifyPaymentChannelClaim.md.ejs
Normal file
@@ -0,0 +1,31 @@
|
||||
## verifyPaymentChannelClaim
|
||||
|
||||
`verifyPaymentChannelClaim(channel: string, amount: string, signature: string, publicKey: string): boolean`
|
||||
|
||||
Verify a payment channel claim signature.
|
||||
|
||||
### Parameters
|
||||
|
||||
<%- renderSchema("input/verify-payment-channel-claim.json") %>
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns `true` if the claim signature is valid.
|
||||
|
||||
<%- renderSchema("output/verify-payment-channel-claim.json") %>
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
const channel =
|
||||
'3E18C05AD40319B809520F1A136370C4075321B285217323396D6FD9EE1E9037';
|
||||
const amount = '.00001';
|
||||
const signature = <%- importFile("test/fixtures/responses/sign-payment-channel-claim.json") %>;
|
||||
const publicKey =
|
||||
'02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8';
|
||||
return api.verifyPaymentChannelClaim(channel, amount, signature, publicKey);
|
||||
```
|
||||
|
||||
```json
|
||||
true
|
||||
```
|
||||
3891
npm-shrinkwrap.json
generated
3891
npm-shrinkwrap.json
generated
File diff suppressed because it is too large
Load Diff
20
package.json
20
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ripple-lib",
|
||||
"version": "0.17.1",
|
||||
"version": "0.17.7",
|
||||
"license": "ISC",
|
||||
"description": "A JavaScript API for interacting with Ripple in Node.js and the browser",
|
||||
"files": [
|
||||
@@ -15,17 +15,15 @@
|
||||
"test": "test"
|
||||
},
|
||||
"dependencies": {
|
||||
"ajv": "^4.0.5",
|
||||
"ajv-i18n": "^1.2.0",
|
||||
"babel-polyfill": "^6.3.14",
|
||||
"babel-runtime": "^6.3.19",
|
||||
"bignumber.js": "^2.0.3",
|
||||
"https-proxy-agent": "^1.0.0",
|
||||
"jayson": "^1.2.2",
|
||||
"jsonschema": "^1.1.1",
|
||||
"lodash": "^3.1.0",
|
||||
"ripple-address-codec": "^2.0.1",
|
||||
"ripple-binary-codec": "^0.1.3",
|
||||
"ripple-hashes": "^0.1.0",
|
||||
"ripple-binary-codec": "^0.1.10",
|
||||
"ripple-hashes": "^0.3.0",
|
||||
"ripple-keypairs": "^0.10.0",
|
||||
"ripple-lib-transactionparser": "^0.6.0",
|
||||
"ws": "^1.0.1"
|
||||
@@ -41,23 +39,23 @@
|
||||
"babel-preset-es2015": "^6.3.13",
|
||||
"babel-preset-stage-1": "^6.3.13",
|
||||
"babel-register": "^6.3.13",
|
||||
"coveralls": "^2.10.0",
|
||||
"coveralls": "^2.11.9",
|
||||
"doctoc": "^0.15.0",
|
||||
"ejs": "^2.3.4",
|
||||
"eslint": "^2.9.0",
|
||||
"eventemitter2": "^0.4.14",
|
||||
"flow-bin": "^0.24.2",
|
||||
"gulp": "^3.8.10",
|
||||
"gulp-bump": "^0.1.13",
|
||||
"gulp-rename": "^1.2.0",
|
||||
"gulp-uglify": "^1.1.0",
|
||||
"http-server": "^0.8.5",
|
||||
"isparta": "^4.0.0",
|
||||
"istanbul": "^1.1.0-alpha.1",
|
||||
"jayson": "^1.2.2",
|
||||
"json-loader": "^0.5.2",
|
||||
"json-schema-to-markdown-table": "^0.4.0",
|
||||
"mocha": "^2.1.0",
|
||||
"mocha-junit-reporter": "^1.9.1",
|
||||
"mocha-in-sauce": "^0.0.1",
|
||||
"mocha-junit-reporter": "^1.9.1",
|
||||
"null-loader": "^0.1.1",
|
||||
"webpack": "^1.5.3",
|
||||
"yargs": "^1.3.1"
|
||||
@@ -72,7 +70,7 @@
|
||||
"watch": "babel -w -D --optional runtime -d dist/npm/ src/",
|
||||
"compile-with-source-maps": "babel -D --optional runtime -s -t -d dist/npm/ src/",
|
||||
"prepublish": "npm run clean && npm run compile",
|
||||
"test": "babel-node node_modules/isparta/lib/cli cover ./node_modules/mocha/bin/_mocha",
|
||||
"test": "babel-node ./node_modules/.bin/istanbul cover ./node_modules/mocha/bin/_mocha",
|
||||
"coveralls": "cat ./coverage/lcov.info | coveralls",
|
||||
"lint": "if ! [ -f eslintrc ]; then curl -o eslintrc 'https://raw.githubusercontent.com/ripple/javascript-style-guide/es6/eslintrc'; echo 'parser: babel-eslint' >> eslintrc; fi; eslint -c eslintrc src/",
|
||||
"perf": "./scripts/perf_test.sh",
|
||||
|
||||
@@ -35,21 +35,21 @@ unittest() {
|
||||
ln -nfs ../../dist/npm test-compiled/node_modules/ripple-api
|
||||
mocha --opts test-compiled/mocha.opts test-compiled
|
||||
|
||||
# compile tests for browser testing
|
||||
gulp build-min build-tests
|
||||
node --harmony test-compiled/mocked-server.js > /dev/null &
|
||||
#compile tests for browser testing
|
||||
#gulp build-min build-tests
|
||||
#node --harmony test-compiled/mocked-server.js > /dev/null &
|
||||
|
||||
#echo "Running tests in PhantomJS"
|
||||
#mocha-phantomjs test/localrunner.html
|
||||
#echo "Running tests using minified version in PhantomJS"
|
||||
#mocha-phantomjs test/localrunnermin.html
|
||||
|
||||
echo "Running tests in SauceLabs"
|
||||
http-server &
|
||||
npm run sauce
|
||||
#echo "Running tests in SauceLabs"
|
||||
#http-server &
|
||||
#npm run sauce
|
||||
|
||||
pkill -f mocked-server.js
|
||||
pkill -f http-server
|
||||
#pkill -f mocked-server.js
|
||||
#pkill -f http-server
|
||||
rm -rf test-compiled
|
||||
}
|
||||
|
||||
@@ -76,7 +76,6 @@ oneNode() {
|
||||
checkEOL
|
||||
doctest
|
||||
lint
|
||||
typecheck
|
||||
unittest
|
||||
integrationtest
|
||||
}
|
||||
@@ -84,7 +83,7 @@ oneNode() {
|
||||
twoNodes() {
|
||||
case "$NODE_INDEX" in
|
||||
0) doctest; lint; integrationtest;;
|
||||
1) checkEOL; typecheck; unittest;;
|
||||
1) checkEOL; unittest;;
|
||||
*) echo "ERROR: invalid usage"; exit 2;;
|
||||
esac
|
||||
}
|
||||
@@ -92,7 +91,7 @@ twoNodes() {
|
||||
threeNodes() {
|
||||
case "$NODE_INDEX" in
|
||||
0) doctest; lint; integrationtest;;
|
||||
1) checkEOL; typecheck;;
|
||||
1) checkEOL;;
|
||||
2) unittest;;
|
||||
*) echo "ERROR: invalid usage"; exit 2;;
|
||||
esac
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
const createHTTPServer = require('../src/index').createHTTPServer;
|
||||
'use strict';
|
||||
|
||||
const createHTTPServer = require('../src/http').createHTTPServer;
|
||||
const port = 5990;
|
||||
const serverUrl = 'wss://s1.ripple.com';
|
||||
|
||||
|
||||
143
src/api.js
143
src/api.js
@@ -1,5 +1,5 @@
|
||||
/* @flow */
|
||||
'use strict'; // eslint-disable-line
|
||||
'use strict' // eslint-disable-line strict
|
||||
|
||||
/* eslint-disable max-len */
|
||||
// Enable core-js polyfills. This allows use of ES6/7 extensions listed here:
|
||||
@@ -9,48 +9,59 @@
|
||||
// In node.js env, polyfill might be already loaded (from any npm package),
|
||||
// that's why we do this check.
|
||||
if (!global._babelPolyfill) {
|
||||
require('babel-polyfill');
|
||||
require('babel-polyfill')
|
||||
}
|
||||
|
||||
const _ = require('lodash');
|
||||
const EventEmitter = require('events').EventEmitter;
|
||||
const common = require('./common');
|
||||
const server = require('./server/server');
|
||||
const connect = server.connect;
|
||||
const disconnect = server.disconnect;
|
||||
const getServerInfo = server.getServerInfo;
|
||||
const getFee = server.getFee;
|
||||
const isConnected = server.isConnected;
|
||||
const getLedgerVersion = server.getLedgerVersion;
|
||||
const getTransaction = require('./ledger/transaction');
|
||||
const getTransactions = require('./ledger/transactions');
|
||||
const getTrustlines = require('./ledger/trustlines');
|
||||
const getBalances = require('./ledger/balances');
|
||||
const getBalanceSheet = require('./ledger/balance-sheet');
|
||||
const getPaths = require('./ledger/pathfind');
|
||||
const getOrders = require('./ledger/orders');
|
||||
const getOrderbook = require('./ledger/orderbook');
|
||||
const getSettings = require('./ledger/settings');
|
||||
const getAccountInfo = require('./ledger/accountinfo');
|
||||
const preparePayment = require('./transaction/payment');
|
||||
const prepareTrustline = require('./transaction/trustline');
|
||||
const prepareOrder = require('./transaction/order');
|
||||
const prepareOrderCancellation = require('./transaction/ordercancellation');
|
||||
const prepareSuspendedPaymentCreation =
|
||||
require('./transaction/suspended-payment-creation');
|
||||
const prepareSuspendedPaymentExecution =
|
||||
require('./transaction/suspended-payment-execution');
|
||||
const prepareSuspendedPaymentCancellation =
|
||||
require('./transaction/suspended-payment-cancellation');
|
||||
const prepareSettings = require('./transaction/settings');
|
||||
const sign = require('./transaction/sign');
|
||||
const combine = require('./transaction/combine');
|
||||
const submit = require('./transaction/submit');
|
||||
const errors = require('./common').errors;
|
||||
const _ = require('lodash')
|
||||
const EventEmitter = require('events').EventEmitter
|
||||
const common = require('./common')
|
||||
const server = require('./server/server')
|
||||
const connect = server.connect
|
||||
const disconnect = server.disconnect
|
||||
const getServerInfo = server.getServerInfo
|
||||
const getFee = server.getFee
|
||||
const isConnected = server.isConnected
|
||||
const getLedgerVersion = server.getLedgerVersion
|
||||
const getTransaction = require('./ledger/transaction')
|
||||
const getTransactions = require('./ledger/transactions')
|
||||
const getTrustlines = require('./ledger/trustlines')
|
||||
const getBalances = require('./ledger/balances')
|
||||
const getBalanceSheet = require('./ledger/balance-sheet')
|
||||
const getPaths = require('./ledger/pathfind')
|
||||
const getOrders = require('./ledger/orders')
|
||||
const getOrderbook = require('./ledger/orderbook')
|
||||
const getSettings = require('./ledger/settings')
|
||||
const getAccountInfo = require('./ledger/accountinfo')
|
||||
const getPaymentChannel = require('./ledger/payment-channel')
|
||||
const preparePayment = require('./transaction/payment')
|
||||
const prepareTrustline = require('./transaction/trustline')
|
||||
const prepareOrder = require('./transaction/order')
|
||||
const prepareOrderCancellation = require('./transaction/ordercancellation')
|
||||
const prepareEscrowCreation =
|
||||
require('./transaction/escrow-creation')
|
||||
const prepareEscrowExecution =
|
||||
require('./transaction/escrow-execution')
|
||||
const prepareEscrowCancellation =
|
||||
require('./transaction/escrow-cancellation')
|
||||
const preparePaymentChannelCreate =
|
||||
require('./transaction/payment-channel-create')
|
||||
const preparePaymentChannelFund =
|
||||
require('./transaction/payment-channel-fund')
|
||||
const preparePaymentChannelClaim =
|
||||
require('./transaction/payment-channel-claim')
|
||||
const prepareSettings = require('./transaction/settings')
|
||||
const sign = require('./transaction/sign')
|
||||
const combine = require('./transaction/combine')
|
||||
const submit = require('./transaction/submit')
|
||||
const errors = require('./common').errors
|
||||
const generateAddress =
|
||||
require('./offline/generate-address').generateAddressAPI;
|
||||
const computeLedgerHash = require('./offline/ledgerhash');
|
||||
const getLedger = require('./ledger/ledger');
|
||||
require('./offline/generate-address').generateAddressAPI
|
||||
const computeLedgerHash = require('./offline/ledgerhash')
|
||||
const signPaymentChannelClaim =
|
||||
require('./offline/sign-payment-channel-claim')
|
||||
const verifyPaymentChannelClaim =
|
||||
require('./offline/verify-payment-channel-claim')
|
||||
const getLedger = require('./ledger/ledger')
|
||||
|
||||
type APIOptions = {
|
||||
server?: string,
|
||||
@@ -63,42 +74,42 @@ type APIOptions = {
|
||||
// prevent access to non-validated ledger versions
|
||||
class RestrictedConnection extends common.Connection {
|
||||
request(request, timeout) {
|
||||
const ledger_index = request.ledger_index;
|
||||
const ledger_index = request.ledger_index
|
||||
if (ledger_index !== undefined && ledger_index !== 'validated') {
|
||||
if (!_.isNumber(ledger_index) || ledger_index > this._ledgerVersion) {
|
||||
return Promise.reject(new errors.LedgerVersionError(
|
||||
`ledgerVersion ${ledger_index} is greater than server\'s ` +
|
||||
`most recent validated ledger: ${this._ledgerVersion}`));
|
||||
`most recent validated ledger: ${this._ledgerVersion}`))
|
||||
}
|
||||
}
|
||||
return super.request(request, timeout);
|
||||
return super.request(request, timeout)
|
||||
}
|
||||
}
|
||||
|
||||
class RippleAPI extends EventEmitter {
|
||||
constructor(options: APIOptions = {}) {
|
||||
common.validate.apiOptions(options);
|
||||
super();
|
||||
this._feeCushion = options.feeCushion || 1.2;
|
||||
const serverURL = options.server;
|
||||
common.validate.apiOptions(options)
|
||||
super()
|
||||
this._feeCushion = options.feeCushion || 1.2
|
||||
const serverURL = options.server
|
||||
if (serverURL !== undefined) {
|
||||
this.connection = new RestrictedConnection(serverURL, options);
|
||||
this.connection = new RestrictedConnection(serverURL, options)
|
||||
this.connection.on('ledgerClosed', message => {
|
||||
this.emit('ledger', server.formatLedgerClose(message));
|
||||
});
|
||||
this.emit('ledger', server.formatLedgerClose(message))
|
||||
})
|
||||
this.connection.on('error', (errorCode, errorMessage, data) => {
|
||||
this.emit('error', errorCode, errorMessage, data);
|
||||
});
|
||||
this.emit('error', errorCode, errorMessage, data)
|
||||
})
|
||||
this.connection.on('connected', () => {
|
||||
this.emit('connected');
|
||||
});
|
||||
this.emit('connected')
|
||||
})
|
||||
this.connection.on('disconnected', code => {
|
||||
this.emit('disconnected', code);
|
||||
});
|
||||
this.emit('disconnected', code)
|
||||
})
|
||||
} else {
|
||||
// use null object pattern to provide better error message if user
|
||||
// tries to call a method that requires a connection
|
||||
this.connection = new RestrictedConnection(null, options);
|
||||
this.connection = new RestrictedConnection(null, options)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -121,15 +132,19 @@ _.assign(RippleAPI.prototype, {
|
||||
getOrderbook,
|
||||
getSettings,
|
||||
getAccountInfo,
|
||||
getPaymentChannel,
|
||||
getLedger,
|
||||
|
||||
preparePayment,
|
||||
prepareTrustline,
|
||||
prepareOrder,
|
||||
prepareOrderCancellation,
|
||||
prepareSuspendedPaymentCreation,
|
||||
prepareSuspendedPaymentExecution,
|
||||
prepareSuspendedPaymentCancellation,
|
||||
prepareEscrowCreation,
|
||||
prepareEscrowExecution,
|
||||
prepareEscrowCancellation,
|
||||
preparePaymentChannelCreate,
|
||||
preparePaymentChannelFund,
|
||||
preparePaymentChannelClaim,
|
||||
prepareSettings,
|
||||
sign,
|
||||
combine,
|
||||
@@ -137,8 +152,10 @@ _.assign(RippleAPI.prototype, {
|
||||
|
||||
generateAddress,
|
||||
computeLedgerHash,
|
||||
signPaymentChannelClaim,
|
||||
verifyPaymentChannelClaim,
|
||||
errors
|
||||
});
|
||||
})
|
||||
|
||||
// these are exposed only for use by unit tests; they are not part of the API
|
||||
RippleAPI._PRIVATE = {
|
||||
@@ -146,8 +163,8 @@ RippleAPI._PRIVATE = {
|
||||
RangeSet: require('./common/rangeset').RangeSet,
|
||||
ledgerUtils: require('./ledger/utils'),
|
||||
schemaValidator: require('./common/schema-validator')
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
RippleAPI
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,70 +1,70 @@
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const RippleAPI = require('./api').RippleAPI;
|
||||
'use strict' // eslint-disable-line strict
|
||||
const _ = require('lodash')
|
||||
const RippleAPI = require('./api').RippleAPI
|
||||
|
||||
class RippleAPIBroadcast extends RippleAPI {
|
||||
constructor(servers, options) {
|
||||
super(options);
|
||||
this.ledgerVersion = 0;
|
||||
super(options)
|
||||
this.ledgerVersion = 0
|
||||
|
||||
const apis = servers.map(server => new RippleAPI(
|
||||
_.assign({}, options, {server})
|
||||
));
|
||||
))
|
||||
|
||||
// exposed for testing
|
||||
this._apis = apis;
|
||||
this._apis = apis
|
||||
|
||||
this.getMethodNames().forEach(name => {
|
||||
this[name] = function() { // eslint-disable-line no-loop-func
|
||||
return Promise.race(apis.map(api => api[name].apply(api, arguments)));
|
||||
};
|
||||
});
|
||||
return Promise.race(apis.map(api => api[name](...arguments)))
|
||||
}
|
||||
})
|
||||
|
||||
// connection methods must be overridden to apply to all api instances
|
||||
this.connect = function() {
|
||||
return Promise.all(apis.map(api => api.connect()));
|
||||
};
|
||||
return Promise.all(apis.map(api => api.connect()))
|
||||
}
|
||||
this.disconnect = function() {
|
||||
return Promise.all(apis.map(api => api.disconnect()));
|
||||
};
|
||||
return Promise.all(apis.map(api => api.disconnect()))
|
||||
}
|
||||
this.isConnected = function() {
|
||||
return _.every(apis.map(api => api.isConnected()));
|
||||
};
|
||||
return _.every(apis.map(api => api.isConnected()))
|
||||
}
|
||||
|
||||
// synchronous methods are all passed directly to the first api instance
|
||||
const defaultAPI = apis[0];
|
||||
const syncMethods = ['sign', 'generateAddress', 'computeLedgerHash'];
|
||||
const defaultAPI = apis[0]
|
||||
const syncMethods = ['sign', 'generateAddress', 'computeLedgerHash']
|
||||
syncMethods.forEach(name => {
|
||||
this[name] = defaultAPI[name].bind(defaultAPI);
|
||||
});
|
||||
this[name] = defaultAPI[name].bind(defaultAPI)
|
||||
})
|
||||
|
||||
apis.forEach(api => {
|
||||
api.on('ledger', this.onLedgerEvent.bind(this));
|
||||
api.on('ledger', this.onLedgerEvent.bind(this))
|
||||
api.on('error', (errorCode, errorMessage, data) =>
|
||||
this.emit('error', errorCode, errorMessage, data));
|
||||
});
|
||||
this.emit('error', errorCode, errorMessage, data))
|
||||
})
|
||||
}
|
||||
|
||||
onLedgerEvent(ledger) {
|
||||
if (ledger.ledgerVersion > this.ledgerVersion) {
|
||||
this.ledgerVersion = ledger.ledgerVersion;
|
||||
this.emit('ledger', ledger);
|
||||
this.ledgerVersion = ledger.ledgerVersion
|
||||
this.emit('ledger', ledger)
|
||||
}
|
||||
}
|
||||
|
||||
getMethodNames() {
|
||||
const methodNames = [];
|
||||
const methodNames = []
|
||||
for (const name in RippleAPI.prototype) {
|
||||
if (RippleAPI.prototype.hasOwnProperty(name)) {
|
||||
if (typeof RippleAPI.prototype[name] === 'function') {
|
||||
methodNames.push(name);
|
||||
methodNames.push(name)
|
||||
}
|
||||
}
|
||||
}
|
||||
return methodNames;
|
||||
return methodNames
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
RippleAPIBroadcast
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
'use strict';
|
||||
'use strict' // eslint-disable-line strict
|
||||
|
||||
function setPrototypeOf(object, prototype) {
|
||||
// Object.setPrototypeOf not supported on Internet Explorer 9
|
||||
@@ -12,10 +12,10 @@ function getConstructorName(object) {
|
||||
// hack for internet explorer
|
||||
return process.browser ?
|
||||
object.constructor.toString().match(/^function\s+([^(]*)/)[1] :
|
||||
object.constructor.name;
|
||||
object.constructor.name
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getConstructorName,
|
||||
setPrototypeOf
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,125 +1,133 @@
|
||||
'use strict'; // eslint-disable-line
|
||||
'use strict' // eslint-disable-line strict
|
||||
|
||||
const _ = require('lodash');
|
||||
const {EventEmitter} = require('events');
|
||||
const WebSocket = require('ws');
|
||||
const parseURL = require('url').parse;
|
||||
const RangeSet = require('./rangeset').RangeSet;
|
||||
const _ = require('lodash')
|
||||
const {EventEmitter} = require('events')
|
||||
const WebSocket = require('ws')
|
||||
const parseURL = require('url').parse
|
||||
const RangeSet = require('./rangeset').RangeSet
|
||||
const {RippledError, DisconnectedError, NotConnectedError,
|
||||
TimeoutError, ResponseFormatError, ConnectionError,
|
||||
RippledNotInitializedError} = require('./errors');
|
||||
RippledNotInitializedError} = require('./errors')
|
||||
|
||||
function isStreamMessageType(type) {
|
||||
return type === 'ledgerClosed' ||
|
||||
type === 'transaction' ||
|
||||
type === 'path_find';
|
||||
type === 'path_find'
|
||||
}
|
||||
|
||||
class Connection extends EventEmitter {
|
||||
constructor(url, options = {}) {
|
||||
super();
|
||||
this.setMaxListeners(Infinity);
|
||||
this._url = url;
|
||||
this._trace = options.trace;
|
||||
super()
|
||||
this.setMaxListeners(Infinity)
|
||||
this._url = url
|
||||
this._trace = options.trace
|
||||
if (this._trace) {
|
||||
// for easier unit testing
|
||||
this._console = console;
|
||||
this._console = console
|
||||
}
|
||||
this._proxyURL = options.proxy;
|
||||
this._proxyAuthorization = options.proxyAuthorization;
|
||||
this._authorization = options.authorization;
|
||||
this._trustedCertificates = options.trustedCertificates;
|
||||
this._key = options.key;
|
||||
this._passphrase = options.passphrase;
|
||||
this._certificate = options.certificate;
|
||||
this._timeout = options.timeout || (20 * 1000);
|
||||
this._isReady = false;
|
||||
this._ws = null;
|
||||
this._ledgerVersion = null;
|
||||
this._availableLedgerVersions = new RangeSet();
|
||||
this._nextRequestID = 1;
|
||||
this._retry = 0;
|
||||
this._retryTimer = null;
|
||||
this._onOpenErrorBound = null;
|
||||
this._onUnexpectedCloseBound = null;
|
||||
this._proxyURL = options.proxy
|
||||
this._proxyAuthorization = options.proxyAuthorization
|
||||
this._authorization = options.authorization
|
||||
this._trustedCertificates = options.trustedCertificates
|
||||
this._key = options.key
|
||||
this._passphrase = options.passphrase
|
||||
this._certificate = options.certificate
|
||||
this._timeout = options.timeout || (20 * 1000)
|
||||
this._isReady = false
|
||||
this._ws = null
|
||||
this._ledgerVersion = null
|
||||
this._availableLedgerVersions = new RangeSet()
|
||||
this._nextRequestID = 1
|
||||
this._retry = 0
|
||||
this._retryTimer = null
|
||||
this._onOpenErrorBound = null
|
||||
this._onUnexpectedCloseBound = null
|
||||
this._fee_base = null
|
||||
this._fee_ref = null
|
||||
}
|
||||
|
||||
_updateLedgerVersions(data) {
|
||||
this._ledgerVersion = Number(data.ledger_index);
|
||||
this._ledgerVersion = Number(data.ledger_index)
|
||||
if (data.validated_ledgers) {
|
||||
this._availableLedgerVersions.reset();
|
||||
this._availableLedgerVersions.reset()
|
||||
this._availableLedgerVersions.parseAndAddRanges(
|
||||
data.validated_ledgers);
|
||||
data.validated_ledgers)
|
||||
} else {
|
||||
this._availableLedgerVersions.addValue(this._ledgerVersion);
|
||||
this._availableLedgerVersions.addValue(this._ledgerVersion)
|
||||
}
|
||||
}
|
||||
|
||||
_updateFees(data) {
|
||||
this._fee_base = Number(data.fee_base)
|
||||
this._fee_ref = Number(data.fee_ref)
|
||||
}
|
||||
|
||||
// return value is array of arguments to Connection.emit
|
||||
_parseMessage(message) {
|
||||
const data = JSON.parse(message);
|
||||
const data = JSON.parse(message)
|
||||
if (data.type === 'response') {
|
||||
if (!(Number.isInteger(data.id) && data.id >= 0)) {
|
||||
throw new ResponseFormatError('valid id not found in response');
|
||||
throw new ResponseFormatError('valid id not found in response')
|
||||
}
|
||||
return [data.id.toString(), data];
|
||||
return [data.id.toString(), data]
|
||||
} else if (isStreamMessageType(data.type)) {
|
||||
if (data.type === 'ledgerClosed') {
|
||||
this._updateLedgerVersions(data);
|
||||
this._updateLedgerVersions(data)
|
||||
this._updateFees(data)
|
||||
}
|
||||
return [data.type, data];
|
||||
return [data.type, data]
|
||||
} else if (data.type === undefined && data.error) {
|
||||
return ['error', data.error, data.error_message, data]; // e.g. slowDown
|
||||
return ['error', data.error, data.error_message, data] // e.g. slowDown
|
||||
}
|
||||
throw new ResponseFormatError('unrecognized message type: ' + data.type);
|
||||
throw new ResponseFormatError('unrecognized message type: ' + data.type)
|
||||
}
|
||||
|
||||
_onMessage(message) {
|
||||
let parameters;
|
||||
let parameters
|
||||
if (this._trace) {
|
||||
this._console.log(message);
|
||||
this._console.log(message)
|
||||
}
|
||||
try {
|
||||
parameters = this._parseMessage(message);
|
||||
parameters = this._parseMessage(message)
|
||||
} catch (error) {
|
||||
this.emit('error', 'badMessage', error.message, message);
|
||||
return;
|
||||
this.emit('error', 'badMessage', error.message, message)
|
||||
return
|
||||
}
|
||||
// we don't want this inside the try/catch or exceptions in listener
|
||||
// will be caught
|
||||
this.emit(...parameters);
|
||||
this.emit(...parameters)
|
||||
}
|
||||
|
||||
get _state() {
|
||||
return this._ws ? this._ws.readyState : WebSocket.CLOSED;
|
||||
return this._ws ? this._ws.readyState : WebSocket.CLOSED
|
||||
}
|
||||
|
||||
get _shouldBeConnected() {
|
||||
return this._ws !== null;
|
||||
return this._ws !== null
|
||||
}
|
||||
|
||||
isConnected() {
|
||||
return this._state === WebSocket.OPEN && this._isReady;
|
||||
return this._state === WebSocket.OPEN && this._isReady
|
||||
}
|
||||
|
||||
_onUnexpectedClose(beforeOpen, resolve, reject, code) {
|
||||
if (this._onOpenErrorBound) {
|
||||
this._ws.removeListener('error', this._onOpenErrorBound);
|
||||
this._onOpenErrorBound = null;
|
||||
this._ws.removeListener('error', this._onOpenErrorBound)
|
||||
this._onOpenErrorBound = null
|
||||
}
|
||||
// just in case
|
||||
this._ws.removeAllListeners('open');
|
||||
this._ws = null;
|
||||
this._isReady = false;
|
||||
this._ws.removeAllListeners('open')
|
||||
this._ws = null
|
||||
this._isReady = false
|
||||
if (beforeOpen) {
|
||||
// connection was closed before it was properly opened, so we must return
|
||||
// error to connect's caller
|
||||
this.connect().then(resolve, reject);
|
||||
this.connect().then(resolve, reject)
|
||||
} else {
|
||||
// if first parameter ws lib sends close code,
|
||||
// but sometimes it forgots about it, so default to 1006 - CLOSE_ABNORMAL
|
||||
this.emit('disconnected', code || 1006);
|
||||
this._retryConnect();
|
||||
this.emit('disconnected', code || 1006)
|
||||
this._retryConnect()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,91 +142,92 @@ class Connection extends EventEmitter {
|
||||
// Then, for 10 minutes: once every 10 seconds
|
||||
? (10 * 1000)
|
||||
// Then: once every 30 seconds
|
||||
: (30 * 1000);
|
||||
: (30 * 1000)
|
||||
}
|
||||
|
||||
_retryConnect() {
|
||||
this._retry += 1;
|
||||
const retryTimeout = this._calculateTimeout(this._retry);
|
||||
this._retry += 1
|
||||
const retryTimeout = this._calculateTimeout(this._retry)
|
||||
this._retryTimer = setTimeout(() => {
|
||||
this.emit('reconnecting', this._retry);
|
||||
this.connect().catch(this._retryConnect.bind(this));
|
||||
}, retryTimeout);
|
||||
this.emit('reconnecting', this._retry)
|
||||
this.connect().catch(this._retryConnect.bind(this))
|
||||
}, retryTimeout)
|
||||
}
|
||||
|
||||
_clearReconnectTimer() {
|
||||
clearTimeout(this._retryTimer);
|
||||
this._retryTimer = null;
|
||||
clearTimeout(this._retryTimer)
|
||||
this._retryTimer = null
|
||||
}
|
||||
|
||||
_onOpen() {
|
||||
if (!this._ws) {
|
||||
return Promise.reject(new DisconnectedError());
|
||||
return Promise.reject(new DisconnectedError())
|
||||
}
|
||||
if (this._onOpenErrorBound) {
|
||||
this._ws.removeListener('error', this._onOpenErrorBound);
|
||||
this._onOpenErrorBound = null;
|
||||
this._ws.removeListener('error', this._onOpenErrorBound)
|
||||
this._onOpenErrorBound = null
|
||||
}
|
||||
|
||||
const request = {
|
||||
command: 'subscribe',
|
||||
streams: ['ledger']
|
||||
};
|
||||
}
|
||||
return this.request(request).then(data => {
|
||||
if (_.isEmpty(data) || !data.ledger_index) {
|
||||
// rippled instance doesn't have validated ledgers
|
||||
return this._disconnect(false).then(() => {
|
||||
throw new RippledNotInitializedError('Rippled not initialized');
|
||||
});
|
||||
throw new RippledNotInitializedError('Rippled not initialized')
|
||||
})
|
||||
}
|
||||
|
||||
this._updateLedgerVersions(data);
|
||||
this._rebindOnUnxpectedClose();
|
||||
this._updateLedgerVersions(data)
|
||||
this._updateFees(data)
|
||||
this._rebindOnUnxpectedClose()
|
||||
|
||||
this._retry = 0;
|
||||
this._retry = 0
|
||||
this._ws.on('error', error => {
|
||||
if (process.browser && error && error.type === 'error') {
|
||||
// we are in browser, ignore error - `close` event will be fired
|
||||
// after error
|
||||
return;
|
||||
return
|
||||
}
|
||||
this.emit('error', 'websocket', error.message, error);
|
||||
});
|
||||
this.emit('error', 'websocket', error.message, error)
|
||||
})
|
||||
|
||||
this._isReady = true;
|
||||
this.emit('connected');
|
||||
this._isReady = true
|
||||
this.emit('connected')
|
||||
|
||||
return undefined;
|
||||
});
|
||||
return undefined
|
||||
})
|
||||
}
|
||||
|
||||
_rebindOnUnxpectedClose() {
|
||||
if (this._onUnexpectedCloseBound) {
|
||||
this._ws.removeListener('close', this._onUnexpectedCloseBound);
|
||||
this._ws.removeListener('close', this._onUnexpectedCloseBound)
|
||||
}
|
||||
this._onUnexpectedCloseBound =
|
||||
this._onUnexpectedClose.bind(this, false, null, null);
|
||||
this._ws.once('close', this._onUnexpectedCloseBound);
|
||||
this._onUnexpectedClose.bind(this, false, null, null)
|
||||
this._ws.once('close', this._onUnexpectedCloseBound)
|
||||
}
|
||||
|
||||
_unbindOnUnxpectedClose() {
|
||||
if (this._onUnexpectedCloseBound) {
|
||||
this._ws.removeListener('close', this._onUnexpectedCloseBound);
|
||||
this._ws.removeListener('close', this._onUnexpectedCloseBound)
|
||||
}
|
||||
this._onUnexpectedCloseBound = null;
|
||||
this._onUnexpectedCloseBound = null
|
||||
}
|
||||
|
||||
_onOpenError(reject, error) {
|
||||
this._onOpenErrorBound = null;
|
||||
this._unbindOnUnxpectedClose();
|
||||
reject(new NotConnectedError(error && error.message));
|
||||
this._onOpenErrorBound = null
|
||||
this._unbindOnUnxpectedClose()
|
||||
reject(new NotConnectedError(error && error.message))
|
||||
}
|
||||
|
||||
_createWebSocket() {
|
||||
const options = {};
|
||||
const options = {}
|
||||
if (this._proxyURL !== undefined) {
|
||||
const parsedURL = parseURL(this._url);
|
||||
const parsedProxyURL = parseURL(this._proxyURL);
|
||||
const parsedURL = parseURL(this._url)
|
||||
const parsedProxyURL = parseURL(this._proxyURL)
|
||||
const proxyOverrides = _.omit({
|
||||
secureEndpoint: (parsedURL.protocol === 'wss:'),
|
||||
secureProxy: (parsedProxyURL.protocol === 'https:'),
|
||||
@@ -227,49 +236,49 @@ class Connection extends EventEmitter {
|
||||
key: this._key,
|
||||
passphrase: this._passphrase,
|
||||
cert: this._certificate
|
||||
}, _.isUndefined);
|
||||
const proxyOptions = _.assign({}, parsedProxyURL, proxyOverrides);
|
||||
let HttpsProxyAgent;
|
||||
}, _.isUndefined)
|
||||
const proxyOptions = _.assign({}, parsedProxyURL, proxyOverrides)
|
||||
let HttpsProxyAgent
|
||||
try {
|
||||
HttpsProxyAgent = require('https-proxy-agent');
|
||||
HttpsProxyAgent = require('https-proxy-agent')
|
||||
} catch (error) {
|
||||
throw new Error('"proxy" option is not supported in the browser');
|
||||
throw new Error('"proxy" option is not supported in the browser')
|
||||
}
|
||||
options.agent = new HttpsProxyAgent(proxyOptions);
|
||||
options.agent = new HttpsProxyAgent(proxyOptions)
|
||||
}
|
||||
if (this._authorization !== undefined) {
|
||||
const base64 = new Buffer(this._authorization).toString('base64');
|
||||
options.headers = {Authorization: `Basic ${base64}`};
|
||||
const base64 = new Buffer(this._authorization).toString('base64')
|
||||
options.headers = {Authorization: `Basic ${base64}`}
|
||||
}
|
||||
const optionsOverrides = _.omit({
|
||||
ca: this._trustedCertificates,
|
||||
key: this._key,
|
||||
passphrase: this._passphrase,
|
||||
cert: this._certificate
|
||||
}, _.isUndefined);
|
||||
const websocketOptions = _.assign({}, options, optionsOverrides);
|
||||
const websocket = new WebSocket(this._url, null, websocketOptions);
|
||||
}, _.isUndefined)
|
||||
const websocketOptions = _.assign({}, options, optionsOverrides)
|
||||
const websocket = new WebSocket(this._url, null, websocketOptions)
|
||||
// we will have a listener for each outstanding request,
|
||||
// so we have to raise the limit (the default is 10)
|
||||
if (typeof websocket.setMaxListeners === 'function') {
|
||||
websocket.setMaxListeners(Infinity);
|
||||
websocket.setMaxListeners(Infinity)
|
||||
}
|
||||
return websocket;
|
||||
return websocket
|
||||
}
|
||||
|
||||
connect() {
|
||||
this._clearReconnectTimer();
|
||||
this._clearReconnectTimer()
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!this._url) {
|
||||
reject(new ConnectionError(
|
||||
'Cannot connect because no server was specified'));
|
||||
'Cannot connect because no server was specified'))
|
||||
}
|
||||
if (this._state === WebSocket.OPEN) {
|
||||
resolve();
|
||||
resolve()
|
||||
} else if (this._state === WebSocket.CONNECTING) {
|
||||
this._ws.once('open', resolve);
|
||||
this._ws.once('open', resolve)
|
||||
} else {
|
||||
this._ws = this._createWebSocket();
|
||||
this._ws = this._createWebSocket()
|
||||
// when an error causes the connection to close, the close event
|
||||
// should still be emitted; the "ws" documentation says: "The close
|
||||
// event is also emitted when then underlying net.Socket closes the
|
||||
@@ -277,156 +286,164 @@ class Connection extends EventEmitter {
|
||||
// In case if there is connection error (say, server is not responding)
|
||||
// we must return this error to connection's caller. After successful
|
||||
// opening, we will forward all errors to main api object.
|
||||
this._onOpenErrorBound = this._onOpenError.bind(this, reject);
|
||||
this._ws.once('error', this._onOpenErrorBound);
|
||||
this._ws.on('message', this._onMessage.bind(this));
|
||||
this._onOpenErrorBound = this._onOpenError.bind(this, reject)
|
||||
this._ws.once('error', this._onOpenErrorBound)
|
||||
this._ws.on('message', this._onMessage.bind(this))
|
||||
// in browser close event can came before open event, so we must
|
||||
// resolve connect's promise after reconnect in that case.
|
||||
// after open event we will rebound _onUnexpectedCloseBound
|
||||
// without resolve and reject functions
|
||||
this._onUnexpectedCloseBound = this._onUnexpectedClose.bind(this, true,
|
||||
resolve, reject);
|
||||
this._ws.once('close', this._onUnexpectedCloseBound);
|
||||
this._ws.once('open', () => this._onOpen().then(resolve, reject));
|
||||
resolve, reject)
|
||||
this._ws.once('close', this._onUnexpectedCloseBound)
|
||||
this._ws.once('open', () => this._onOpen().then(resolve, reject))
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
return this._disconnect(true);
|
||||
return this._disconnect(true)
|
||||
}
|
||||
|
||||
_disconnect(calledByUser) {
|
||||
if (calledByUser) {
|
||||
this._clearReconnectTimer();
|
||||
this._retry = 0;
|
||||
this._clearReconnectTimer()
|
||||
this._retry = 0
|
||||
}
|
||||
return new Promise(resolve => {
|
||||
if (this._state === WebSocket.CLOSED) {
|
||||
resolve();
|
||||
resolve()
|
||||
} else if (this._state === WebSocket.CLOSING) {
|
||||
this._ws.once('close', resolve);
|
||||
this._ws.once('close', resolve)
|
||||
} else {
|
||||
if (this._onUnexpectedCloseBound) {
|
||||
this._ws.removeListener('close', this._onUnexpectedCloseBound);
|
||||
this._onUnexpectedCloseBound = null;
|
||||
this._ws.removeListener('close', this._onUnexpectedCloseBound)
|
||||
this._onUnexpectedCloseBound = null
|
||||
}
|
||||
this._ws.once('close', code => {
|
||||
this._ws = null;
|
||||
this._isReady = false;
|
||||
this._ws = null
|
||||
this._isReady = false
|
||||
if (calledByUser) {
|
||||
this.emit('disconnected', code || 1000); // 1000 - CLOSE_NORMAL
|
||||
this.emit('disconnected', code || 1000) // 1000 - CLOSE_NORMAL
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
this._ws.close();
|
||||
resolve()
|
||||
})
|
||||
this._ws.close()
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
reconnect() {
|
||||
return this.disconnect().then(() => this.connect());
|
||||
return this.disconnect().then(() => this.connect())
|
||||
}
|
||||
|
||||
_whenReady(promise) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!this._shouldBeConnected) {
|
||||
reject(new NotConnectedError());
|
||||
reject(new NotConnectedError())
|
||||
} else if (this._state === WebSocket.OPEN && this._isReady) {
|
||||
promise.then(resolve, reject);
|
||||
promise.then(resolve, reject)
|
||||
} else {
|
||||
this.once('connected', () => promise.then(resolve, reject));
|
||||
this.once('connected', () => promise.then(resolve, reject))
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
getLedgerVersion() {
|
||||
return this._whenReady(Promise.resolve(this._ledgerVersion));
|
||||
return this._whenReady(Promise.resolve(this._ledgerVersion))
|
||||
}
|
||||
|
||||
hasLedgerVersions(lowLedgerVersion, highLedgerVersion) {
|
||||
return this._whenReady(Promise.resolve(
|
||||
this._availableLedgerVersions.containsRange(
|
||||
lowLedgerVersion, highLedgerVersion || this._ledgerVersion)));
|
||||
lowLedgerVersion, highLedgerVersion || this._ledgerVersion)))
|
||||
}
|
||||
|
||||
hasLedgerVersion(ledgerVersion) {
|
||||
return this.hasLedgerVersions(ledgerVersion, ledgerVersion);
|
||||
return this.hasLedgerVersions(ledgerVersion, ledgerVersion)
|
||||
}
|
||||
|
||||
getFeeBase() {
|
||||
return this._whenReady(Promise.resolve(Number(this._fee_base)))
|
||||
}
|
||||
|
||||
getFeeRef() {
|
||||
return this._whenReady(Promise.resolve(Number(this._fee_ref)))
|
||||
}
|
||||
|
||||
_send(message) {
|
||||
if (this._trace) {
|
||||
this._console.log(message);
|
||||
this._console.log(message)
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
this._ws.send(message, undefined, (error, result) => {
|
||||
if (error) {
|
||||
reject(new DisconnectedError(error.message));
|
||||
reject(new DisconnectedError(error.message))
|
||||
} else {
|
||||
resolve(result);
|
||||
resolve(result)
|
||||
}
|
||||
});
|
||||
});
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
request(request, timeout) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!this._shouldBeConnected) {
|
||||
reject(new NotConnectedError());
|
||||
reject(new NotConnectedError())
|
||||
}
|
||||
|
||||
let timer = null;
|
||||
const self = this;
|
||||
const id = this._nextRequestID;
|
||||
this._nextRequestID += 1;
|
||||
const eventName = id.toString();
|
||||
let timer = null
|
||||
const self = this
|
||||
const id = this._nextRequestID
|
||||
this._nextRequestID += 1
|
||||
const eventName = id.toString()
|
||||
|
||||
function onDisconnect() {
|
||||
clearTimeout(timer);
|
||||
self.removeAllListeners(eventName);
|
||||
reject(new DisconnectedError());
|
||||
clearTimeout(timer)
|
||||
self.removeAllListeners(eventName)
|
||||
reject(new DisconnectedError())
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
clearTimeout(timer);
|
||||
self.removeAllListeners(eventName);
|
||||
clearTimeout(timer)
|
||||
self.removeAllListeners(eventName)
|
||||
if (self._ws !== null) {
|
||||
self._ws.removeListener('close', onDisconnect);
|
||||
self._ws.removeListener('close', onDisconnect)
|
||||
}
|
||||
}
|
||||
|
||||
function _resolve(response) {
|
||||
cleanup();
|
||||
resolve(response);
|
||||
cleanup()
|
||||
resolve(response)
|
||||
}
|
||||
|
||||
function _reject(error) {
|
||||
cleanup();
|
||||
reject(error);
|
||||
cleanup()
|
||||
reject(error)
|
||||
}
|
||||
|
||||
this.once(eventName, response => {
|
||||
if (response.status === 'error') {
|
||||
_reject(new RippledError(response.error));
|
||||
_reject(new RippledError(response.error))
|
||||
} else if (response.status === 'success') {
|
||||
_resolve(response.result);
|
||||
_resolve(response.result)
|
||||
} else {
|
||||
_reject(new ResponseFormatError(
|
||||
'unrecognized status: ' + response.status));
|
||||
'unrecognized status: ' + response.status))
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
this._ws.once('close', onDisconnect);
|
||||
this._ws.once('close', onDisconnect)
|
||||
|
||||
// JSON.stringify automatically removes keys with value of 'undefined'
|
||||
const message = JSON.stringify(Object.assign({}, request, {id}));
|
||||
const message = JSON.stringify(Object.assign({}, request, {id}))
|
||||
|
||||
this._whenReady(this._send(message)).then(() => {
|
||||
const delay = timeout || this._timeout;
|
||||
timer = setTimeout(() => _reject(new TimeoutError()), delay);
|
||||
}).catch(_reject);
|
||||
});
|
||||
const delay = timeout || this._timeout
|
||||
timer = setTimeout(() => _reject(new TimeoutError()), delay)
|
||||
}).catch(_reject)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Connection;
|
||||
module.exports = Connection
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
'use strict';
|
||||
const flagIndices = require('./txflags').txFlagIndices.AccountSet;
|
||||
'use strict' // eslint-disable-line strict
|
||||
const flagIndices = require('./txflags').txFlagIndices.AccountSet
|
||||
|
||||
const accountRootFlags = {
|
||||
PasswordSpent: 0x00010000, // password set fee is spent
|
||||
@@ -10,7 +10,7 @@ const accountRootFlags = {
|
||||
NoFreeze: 0x00200000, // permanently disallowed freezing trustlines
|
||||
GlobalFreeze: 0x00400000, // trustlines globally frozen
|
||||
DefaultRipple: 0x00800000
|
||||
};
|
||||
}
|
||||
|
||||
const AccountFlags = {
|
||||
passwordSpent: accountRootFlags.PasswordSpent,
|
||||
@@ -21,7 +21,7 @@ const AccountFlags = {
|
||||
noFreeze: accountRootFlags.NoFreeze,
|
||||
globalFreeze: accountRootFlags.GlobalFreeze,
|
||||
defaultRipple: accountRootFlags.DefaultRipple
|
||||
};
|
||||
}
|
||||
|
||||
const AccountFlagIndices = {
|
||||
requireDestinationTag: flagIndices.asfRequireDest,
|
||||
@@ -32,7 +32,7 @@ const AccountFlagIndices = {
|
||||
noFreeze: flagIndices.asfNoFreeze,
|
||||
globalFreeze: flagIndices.asfGlobalFreeze,
|
||||
defaultRipple: flagIndices.asfDefaultRipple
|
||||
};
|
||||
}
|
||||
|
||||
const AccountFields = {
|
||||
EmailHash: {name: 'emailHash', encoding: 'hex',
|
||||
@@ -40,10 +40,10 @@ const AccountFields = {
|
||||
MessageKey: {name: 'messageKey'},
|
||||
Domain: {name: 'domain', encoding: 'hex'},
|
||||
TransferRate: {name: 'transferRate', defaults: 0, shift: 9}
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
AccountFields,
|
||||
AccountFlagIndices,
|
||||
AccountFlags
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,43 +1,43 @@
|
||||
'use strict'; // eslint-disable-line
|
||||
const util = require('util');
|
||||
const browserHacks = require('./browser-hacks');
|
||||
'use strict' // eslint-disable-line strict
|
||||
const util = require('util')
|
||||
const browserHacks = require('./browser-hacks')
|
||||
|
||||
// this is needed because extending builtins doesn't work in babel 6.x
|
||||
function extendableBuiltin(cls) {
|
||||
function ExtendableBuiltin() {
|
||||
cls.apply(this, arguments);
|
||||
cls.apply(this, arguments)
|
||||
}
|
||||
ExtendableBuiltin.prototype = Object.create(cls.prototype);
|
||||
browserHacks.setPrototypeOf(ExtendableBuiltin, cls);
|
||||
return ExtendableBuiltin;
|
||||
ExtendableBuiltin.prototype = Object.create(cls.prototype)
|
||||
browserHacks.setPrototypeOf(ExtendableBuiltin, cls)
|
||||
return ExtendableBuiltin
|
||||
}
|
||||
|
||||
class RippleError extends extendableBuiltin(Error) {
|
||||
constructor(message, data) {
|
||||
super(message);
|
||||
super(message)
|
||||
|
||||
this.name = browserHacks.getConstructorName(this);
|
||||
this.message = message;
|
||||
this.data = data;
|
||||
this.name = browserHacks.getConstructorName(this)
|
||||
this.message = message
|
||||
this.data = data
|
||||
if (Error.captureStackTrace) {
|
||||
Error.captureStackTrace(this, this.constructor.name);
|
||||
Error.captureStackTrace(this, this.constructor.name)
|
||||
}
|
||||
}
|
||||
|
||||
toString() {
|
||||
let result = '[' + this.name + '(' + this.message;
|
||||
let result = '[' + this.name + '(' + this.message
|
||||
if (this.data) {
|
||||
result += ', ' + util.inspect(this.data);
|
||||
result += ', ' + util.inspect(this.data)
|
||||
}
|
||||
result += ')]';
|
||||
return result;
|
||||
result += ')]'
|
||||
return result
|
||||
}
|
||||
|
||||
/* console.log in node uses util.inspect on object, and util.inspect allows
|
||||
us to cutomize its output:
|
||||
https://nodejs.org/api/util.html#util_custom_inspect_function_on_objects */
|
||||
inspect() {
|
||||
return this.toString();
|
||||
return this.toString()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,20 +63,20 @@ class ValidationError extends RippleError {}
|
||||
|
||||
class NotFoundError extends RippleError {
|
||||
constructor(message) {
|
||||
super(message || 'Not found');
|
||||
super(message || 'Not found')
|
||||
}
|
||||
}
|
||||
|
||||
class MissingLedgerHistoryError extends RippleError {
|
||||
constructor(message) {
|
||||
super(message || 'Server is missing ledger history in the specified range');
|
||||
super(message || 'Server is missing ledger history in the specified range')
|
||||
}
|
||||
}
|
||||
|
||||
class PendingLedgerVersionError extends RippleError {
|
||||
constructor(message) {
|
||||
super(message || 'maxLedgerVersion is greater than server\'s'
|
||||
+ ' most recent validated ledger');
|
||||
+ ' most recent validated ledger')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,4 +95,4 @@ module.exports = {
|
||||
PendingLedgerVersionError,
|
||||
MissingLedgerHistoryError,
|
||||
LedgerVersionError
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
'use strict';
|
||||
const utils = require('./utils');
|
||||
'use strict' // eslint-disable-line strict
|
||||
const utils = require('./utils')
|
||||
|
||||
module.exports = {
|
||||
Connection: require('./connection'),
|
||||
@@ -19,4 +19,4 @@ module.exports = {
|
||||
iso8601ToRippleTime: utils.iso8601ToRippleTime,
|
||||
rippleTimeToISO8601: utils.rippleTimeToISO8601,
|
||||
isValidSecret: utils.isValidSecret
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,61 +1,61 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const assert = require('assert');
|
||||
const ranges = Symbol();
|
||||
'use strict' // eslint-disable-line strict
|
||||
const _ = require('lodash')
|
||||
const assert = require('assert')
|
||||
const ranges = Symbol()
|
||||
|
||||
function mergeIntervals(intervals: Array<[number, number]>) {
|
||||
const stack = [[-Infinity, -Infinity]];
|
||||
const stack = [[-Infinity, -Infinity]]
|
||||
_.forEach(_.sortBy(intervals, x => x[0]), interval => {
|
||||
const lastInterval = stack.pop();
|
||||
const lastInterval = stack.pop()
|
||||
if (interval[0] <= lastInterval[1] + 1) {
|
||||
stack.push([lastInterval[0], Math.max(interval[1], lastInterval[1])]);
|
||||
stack.push([lastInterval[0], Math.max(interval[1], lastInterval[1])])
|
||||
} else {
|
||||
stack.push(lastInterval);
|
||||
stack.push(interval);
|
||||
stack.push(lastInterval)
|
||||
stack.push(interval)
|
||||
}
|
||||
});
|
||||
return stack.slice(1);
|
||||
})
|
||||
return stack.slice(1)
|
||||
}
|
||||
|
||||
class RangeSet {
|
||||
constructor() {
|
||||
this.reset();
|
||||
this.reset()
|
||||
}
|
||||
|
||||
reset() {
|
||||
this[ranges] = [];
|
||||
this[ranges] = []
|
||||
}
|
||||
|
||||
serialize() {
|
||||
return this[ranges].map(range =>
|
||||
range[0].toString() + '-' + range[1].toString()).join(',');
|
||||
range[0].toString() + '-' + range[1].toString()).join(',')
|
||||
}
|
||||
|
||||
addRange(start: number, end: number) {
|
||||
assert(start <= end, 'invalid range');
|
||||
this[ranges] = mergeIntervals(this[ranges].concat([[start, end]]));
|
||||
assert(start <= end, 'invalid range')
|
||||
this[ranges] = mergeIntervals(this[ranges].concat([[start, end]]))
|
||||
}
|
||||
|
||||
addValue(value: number) {
|
||||
this.addRange(value, value);
|
||||
this.addRange(value, value)
|
||||
}
|
||||
|
||||
parseAndAddRanges(rangesString: string) {
|
||||
const rangeStrings = rangesString.split(',');
|
||||
const rangeStrings = rangesString.split(',')
|
||||
_.forEach(rangeStrings, rangeString => {
|
||||
const range = rangeString.split('-').map(Number);
|
||||
this.addRange(range[0], range.length === 1 ? range[0] : range[1]);
|
||||
});
|
||||
const range = rangeString.split('-').map(Number)
|
||||
this.addRange(range[0], range.length === 1 ? range[0] : range[1])
|
||||
})
|
||||
}
|
||||
|
||||
containsRange(start: number, end: number) {
|
||||
return _.some(this[ranges], range => range[0] <= start && range[1] >= end);
|
||||
return _.some(this[ranges], range => range[0] <= start && range[1] >= end)
|
||||
}
|
||||
|
||||
containsValue(value: number) {
|
||||
return this.containsRange(value, value);
|
||||
return this.containsRange(value, value)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.RangeSet = RangeSet;
|
||||
module.exports.RangeSet = RangeSet
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
// flow is disabled for this file until support for requiring json is added:
|
||||
// https://github.com/facebook/flow/issues/167
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const assert = require('assert');
|
||||
const Ajv = require('ajv');
|
||||
const ValidationError = require('./errors').ValidationError;
|
||||
const {isValidAddress} = require('ripple-address-codec');
|
||||
const {isValidSecret} = require('./utils');
|
||||
'use strict' // eslint-disable-line strict
|
||||
const _ = require('lodash')
|
||||
const assert = require('assert')
|
||||
const Validator = require('jsonschema').Validator
|
||||
const ValidationError = require('./errors').ValidationError
|
||||
const {isValidAddress} = require('ripple-address-codec')
|
||||
const {isValidSecret} = require('./utils')
|
||||
|
||||
function loadSchemas() {
|
||||
// listed explicitly for webpack (instead of scanning schemas directory)
|
||||
@@ -16,11 +16,13 @@ function loadSchemas() {
|
||||
require('./schemas/objects/hash128.json'),
|
||||
require('./schemas/objects/hash256.json'),
|
||||
require('./schemas/objects/sequence.json'),
|
||||
require('./schemas/objects/signature.json'),
|
||||
require('./schemas/objects/issue.json'),
|
||||
require('./schemas/objects/ledgerversion.json'),
|
||||
require('./schemas/objects/max-adjustment.json'),
|
||||
require('./schemas/objects/memo.json'),
|
||||
require('./schemas/objects/memos.json'),
|
||||
require('./schemas/objects/public-key.json'),
|
||||
require('./schemas/objects/uint32.json'),
|
||||
require('./schemas/objects/value.json'),
|
||||
require('./schemas/objects/source-adjustment.json'),
|
||||
@@ -46,21 +48,25 @@ function loadSchemas() {
|
||||
require('./schemas/objects/settings.json'),
|
||||
require('./schemas/specifications/settings.json'),
|
||||
require('./schemas/specifications/payment.json'),
|
||||
require('./schemas/specifications/suspended-payment-cancellation.json'),
|
||||
require('./schemas/specifications/escrow-cancellation.json'),
|
||||
require('./schemas/specifications/order-cancellation.json'),
|
||||
require('./schemas/specifications/order.json'),
|
||||
require('./schemas/specifications/suspended-payment-execution.json'),
|
||||
require('./schemas/specifications/suspended-payment-creation.json'),
|
||||
require('./schemas/specifications/escrow-execution.json'),
|
||||
require('./schemas/specifications/escrow-creation.json'),
|
||||
require('./schemas/specifications/payment-channel-create.json'),
|
||||
require('./schemas/specifications/payment-channel-fund.json'),
|
||||
require('./schemas/specifications/payment-channel-claim.json'),
|
||||
require('./schemas/specifications/trustline.json'),
|
||||
require('./schemas/output/sign.json'),
|
||||
require('./schemas/output/submit.json'),
|
||||
require('./schemas/output/get-account-info.json'),
|
||||
require('./schemas/output/get-balances.json'),
|
||||
require('./schemas/output/get-balance-sheet'),
|
||||
require('./schemas/output/get-balance-sheet.json'),
|
||||
require('./schemas/output/get-ledger.json'),
|
||||
require('./schemas/output/get-orderbook.json'),
|
||||
require('./schemas/output/get-orders.json'),
|
||||
require('./schemas/output/order-change.json'),
|
||||
require('./schemas/output/get-payment-channel.json'),
|
||||
require('./schemas/output/prepare.json'),
|
||||
require('./schemas/output/ledger-event.json'),
|
||||
require('./schemas/output/get-paths.json'),
|
||||
@@ -71,12 +77,15 @@ function loadSchemas() {
|
||||
require('./schemas/output/get-transaction.json'),
|
||||
require('./schemas/output/get-transactions.json'),
|
||||
require('./schemas/output/get-trustlines.json'),
|
||||
require('./schemas/output/sign-payment-channel-claim.json'),
|
||||
require('./schemas/output/verify-payment-channel-claim.json'),
|
||||
require('./schemas/input/get-balances.json'),
|
||||
require('./schemas/input/get-balance-sheet.json'),
|
||||
require('./schemas/input/get-ledger.json'),
|
||||
require('./schemas/input/get-orders.json'),
|
||||
require('./schemas/input/get-orderbook.json'),
|
||||
require('./schemas/input/get-paths.json'),
|
||||
require('./schemas/input/get-payment-channel.json'),
|
||||
require('./schemas/input/api-options.json'),
|
||||
require('./schemas/input/get-settings.json'),
|
||||
require('./schemas/input/get-account-info.json'),
|
||||
@@ -88,35 +97,60 @@ function loadSchemas() {
|
||||
require('./schemas/input/prepare-trustline.json'),
|
||||
require('./schemas/input/prepare-order-cancellation.json'),
|
||||
require('./schemas/input/prepare-settings.json'),
|
||||
require('./schemas/input/prepare-suspended-payment-creation.json'),
|
||||
require('./schemas/input/prepare-suspended-payment-cancellation.json'),
|
||||
require('./schemas/input/prepare-suspended-payment-execution.json'),
|
||||
require('./schemas/input/compute-ledger-hash'),
|
||||
require('./schemas/input/prepare-escrow-creation.json'),
|
||||
require('./schemas/input/prepare-escrow-cancellation.json'),
|
||||
require('./schemas/input/prepare-escrow-execution.json'),
|
||||
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/compute-ledger-hash.json'),
|
||||
require('./schemas/input/sign.json'),
|
||||
require('./schemas/input/submit.json'),
|
||||
require('./schemas/input/generate-address.json'),
|
||||
require('./schemas/input/sign-payment-channel-claim.json'),
|
||||
require('./schemas/input/verify-payment-channel-claim.json'),
|
||||
require('./schemas/input/combine.json')
|
||||
];
|
||||
const titles = _.map(schemas, schema => schema.title);
|
||||
const duplicates = _.keys(_.pick(_.countBy(titles), count => count > 1));
|
||||
assert(duplicates.length === 0, 'Duplicate schemas for: ' + duplicates);
|
||||
const ajv = new Ajv();
|
||||
_.forEach(schemas, schema => ajv.addSchema(schema, schema.title));
|
||||
ajv.addFormat('address', isValidAddress);
|
||||
ajv.addFormat('secret', isValidSecret);
|
||||
return ajv;
|
||||
]
|
||||
const titles = _.map(schemas, schema => schema.title)
|
||||
const duplicates = _.keys(_.pick(_.countBy(titles), count => count > 1))
|
||||
assert(duplicates.length === 0, 'Duplicate schemas for: ' + duplicates)
|
||||
const v = new Validator()
|
||||
// Register custom format validators that ignore undefined instances
|
||||
// since jsonschema will still call the format validator on a missing
|
||||
// (optional) property
|
||||
v.customFormats.address = function(instance) {
|
||||
if (instance === undefined) {
|
||||
return true
|
||||
}
|
||||
return isValidAddress(instance)
|
||||
}
|
||||
v.customFormats.secret = function(instance) {
|
||||
if (instance === undefined) {
|
||||
return true
|
||||
}
|
||||
return isValidSecret(instance)
|
||||
}
|
||||
|
||||
// Register under the root URI '/'
|
||||
_.forEach(schemas, schema => v.addSchema(schema, '/' + schema.title))
|
||||
return v
|
||||
}
|
||||
|
||||
const ajv = loadSchemas();
|
||||
const v = loadSchemas()
|
||||
|
||||
function schemaValidate(schemaName: string, object: any): void {
|
||||
const isValid = ajv.validate(schemaName, object);
|
||||
if (!isValid) {
|
||||
throw new ValidationError(ajv.errorsText());
|
||||
// Lookup under the root URI '/'
|
||||
const schema = v.getSchema('/' + schemaName)
|
||||
if (schema === undefined) {
|
||||
throw new ValidationError('no schema for ' + schemaName)
|
||||
}
|
||||
const result = v.validate(object, schema)
|
||||
if (!result.valid) {
|
||||
throw new ValidationError(result.errors.join())
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
schemaValidate,
|
||||
isValidSecret
|
||||
};
|
||||
}
|
||||
|
||||
14
src/common/schemas/input/get-payment-channel.json
Normal file
14
src/common/schemas/input/get-payment-channel.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "getPaymentChannelParameters",
|
||||
"description": "Parameters for getPaymentChannel",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "hash256",
|
||||
"description": "256-bit hexadecimal channel identifier."
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": ["id"]
|
||||
}
|
||||
@@ -1,18 +1,18 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "prepareSuspendedPaymentCreationParameters",
|
||||
"title": "prepareEscrowCancellationParameters",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"address": {
|
||||
"$ref": "address",
|
||||
"description": "The address of the account that is creating the transaction."
|
||||
},
|
||||
"suspendedPaymentCreation": {
|
||||
"$ref": "suspendedPaymentCreation",
|
||||
"description": "The specification of the suspended payment creation to prepare."
|
||||
"escrowCancellation": {
|
||||
"$ref": "escrowCancellation",
|
||||
"description": "The specification of the escrow cancellation to prepare."
|
||||
},
|
||||
"instructions": {"$ref": "instructions"}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": ["address", "suspendedPaymentCreation"]
|
||||
"required": ["address", "escrowCancellation"]
|
||||
}
|
||||
@@ -1,18 +1,18 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "prepareSuspendedPaymentExecutionParameters",
|
||||
"title": "prepareEscrowCreationParameters",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"address": {
|
||||
"$ref": "address",
|
||||
"description": "The address of the account that is creating the transaction."
|
||||
},
|
||||
"suspendedPaymentExecution": {
|
||||
"$ref": "suspendedPaymentExecution",
|
||||
"description": "The specification of the suspended payment execution to prepare."
|
||||
"escrowCreation": {
|
||||
"$ref": "escrowCreation",
|
||||
"description": "The specification of the escrow creation to prepare."
|
||||
},
|
||||
"instructions": {"$ref": "instructions"}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": ["address", "suspendedPaymentExecution"]
|
||||
"required": ["address", "escrowCreation"]
|
||||
}
|
||||
@@ -1,18 +1,18 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "prepareSuspendedPaymentCancellationParameters",
|
||||
"title": "prepareEscrowExecutionParameters",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"address": {
|
||||
"$ref": "address",
|
||||
"description": "The address of the account that is creating the transaction."
|
||||
},
|
||||
"suspendedPaymentCancellation": {
|
||||
"$ref": "suspendedPaymentCancellation",
|
||||
"description": "The specification of the suspended payment cancellation to prepare."
|
||||
"escrowExecution": {
|
||||
"$ref": "escrowExecution",
|
||||
"description": "The specification of the escrow execution to prepare."
|
||||
},
|
||||
"instructions": {"$ref": "instructions"}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": ["address", "suspendedPaymentCancellation"]
|
||||
"required": ["address", "escrowExecution"]
|
||||
}
|
||||
18
src/common/schemas/input/prepare-payment-channel-claim.json
Normal file
18
src/common/schemas/input/prepare-payment-channel-claim.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "preparePaymentChannelClaimParameters",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"address": {
|
||||
"$ref": "address",
|
||||
"description": "The address of the account that is creating the transaction."
|
||||
},
|
||||
"paymentChannelClaim": {
|
||||
"$ref": "paymentChannelClaim",
|
||||
"description": "Details of the channel and claim."
|
||||
},
|
||||
"instructions": {"$ref": "instructions"}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": ["address", "paymentChannelClaim"]
|
||||
}
|
||||
18
src/common/schemas/input/prepare-payment-channel-create.json
Normal file
18
src/common/schemas/input/prepare-payment-channel-create.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "preparePaymentChannelCreateParameters",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"address": {
|
||||
"$ref": "address",
|
||||
"description": "The address of the account that is creating the transaction."
|
||||
},
|
||||
"paymentChannelCreate": {
|
||||
"$ref": "paymentChannelCreate",
|
||||
"description": "The specification of the payment channel to create."
|
||||
},
|
||||
"instructions": {"$ref": "instructions"}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": ["address", "paymentChannelCreate"]
|
||||
}
|
||||
18
src/common/schemas/input/prepare-payment-channel-fund.json
Normal file
18
src/common/schemas/input/prepare-payment-channel-fund.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "preparePaymentChannelFundParameters",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"address": {
|
||||
"$ref": "address",
|
||||
"description": "The address of the account that is creating the transaction."
|
||||
},
|
||||
"paymentChannelFund": {
|
||||
"$ref": "paymentChannelFund",
|
||||
"description": "The channel to fund, and the details of how to fund it."
|
||||
},
|
||||
"instructions": {"$ref": "instructions"}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": ["address", "paymentChannelFund"]
|
||||
}
|
||||
21
src/common/schemas/input/sign-payment-channel-claim.json
Normal file
21
src/common/schemas/input/sign-payment-channel-claim.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "signPaymentChannelClaimParameters",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"channel": {
|
||||
"$ref": "hash256",
|
||||
"description": "256-bit hexadecimal channel identifier."
|
||||
},
|
||||
"amount": {
|
||||
"$ref": "value",
|
||||
"description": "Amount of XRP authorized by the claim."
|
||||
},
|
||||
"privateKey": {
|
||||
"$ref": "publicKey",
|
||||
"description": "The private key to sign the payment channel claim."
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": ["channel", "amount", "privateKey"]
|
||||
}
|
||||
25
src/common/schemas/input/verify-payment-channel-claim.json
Normal file
25
src/common/schemas/input/verify-payment-channel-claim.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "verifyPaymentChannelClaimParameters",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"channel": {
|
||||
"$ref": "hash256",
|
||||
"description": "256-bit hexadecimal channel identifier."
|
||||
},
|
||||
"amount": {
|
||||
"$ref": "value",
|
||||
"description": "Amount of XRP authorized by the claim."
|
||||
},
|
||||
"signature": {
|
||||
"$ref": "signature",
|
||||
"description": "Signature of this claim."
|
||||
},
|
||||
"publicKey": {
|
||||
"$ref": "publicKey",
|
||||
"description": "Public key of the channel's sender"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": ["channel", "amount", "signature", "publicKey"]
|
||||
}
|
||||
7
src/common/schemas/objects/public-key.json
Normal file
7
src/common/schemas/objects/public-key.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "publicKey",
|
||||
"description": "The hexadecimal representation of a secp256k1 or Ed25519 public key.",
|
||||
"type": "string",
|
||||
"pattern": "^[A-F0-9]+$"
|
||||
}
|
||||
@@ -55,7 +55,7 @@
|
||||
"description": " The domain that owns this account, as a hexadecimal string representing the ASCII for the domain in lowercase."
|
||||
},
|
||||
"transferRate": {
|
||||
"description": " The fee to charge when users transfer this account’s issuances, represented as billionths of a unit. Use `null` to set no fee.",
|
||||
"description": " The fee to charge when users transfer this account’s issuances, as the decimal amount that must be sent to deliver 1 unit. Has precision up to 9 digits beyond the decimal point. Use `null` to set no fee.",
|
||||
"oneOf": [
|
||||
{"type": "null"},
|
||||
{"type": "number", "minimum": 1, "maximum": 4.294967295}
|
||||
|
||||
7
src/common/schemas/objects/signature.json
Normal file
7
src/common/schemas/objects/signature.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "signature",
|
||||
"description": "The hexadecimal representation of a signature.",
|
||||
"type": "string",
|
||||
"pattern": "^[A-F0-9]+$"
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
"description": "The type of the transaction.",
|
||||
"type": "string",
|
||||
"enum": ["payment", "order", "orderCancellation", "trustline", "settings",
|
||||
"suspendedPaymentCreation", "suspendedPaymentCancellation",
|
||||
"suspendedPaymentExecution"]
|
||||
"escrowCreation", "escrowCancellation",
|
||||
"escrowExecution", "paymentChannelCreate",
|
||||
"paymentChannelFund", "paymentChannelClaim"]
|
||||
}
|
||||
|
||||
67
src/common/schemas/output/get-payment-channel.json
Normal file
67
src/common/schemas/output/get-payment-channel.json
Normal file
@@ -0,0 +1,67 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "getPaymentChannel",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"account": {
|
||||
"$ref": "address",
|
||||
"description": "Address that created the payment channel."
|
||||
},
|
||||
"destination": {
|
||||
"$ref": "address",
|
||||
"description": "Address to receive XRP claims against this channel."
|
||||
},
|
||||
"amount": {
|
||||
"$ref": "value",
|
||||
"description": "The total amount of XRP funded in this channel."
|
||||
},
|
||||
"balance": {
|
||||
"$ref": "value",
|
||||
"description": "The total amount of XRP delivered by this channel."
|
||||
},
|
||||
"settleDelay": {
|
||||
"type": "number",
|
||||
"description": "Amount of seconds the source address must wait before closing the channel if it has unclaimed XRP."
|
||||
},
|
||||
"expiration": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "Time when this channel expires."
|
||||
},
|
||||
"publicKey": {
|
||||
"$ref": "publicKey",
|
||||
"description": "Public key of the key pair the source will use to sign claims against this channel."
|
||||
},
|
||||
"cancelAfter": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "Time when this channel expires as specified at creation."
|
||||
},
|
||||
"sourceTag": {
|
||||
"$ref": "tag",
|
||||
"description": "Source tag."
|
||||
},
|
||||
"destinationTag": {
|
||||
"$ref": "tag",
|
||||
"description": "Destination tag."
|
||||
},
|
||||
"previousAffectingTransactionID": {
|
||||
"$ref": "hash256",
|
||||
"description": "Hash value representing the most recent transaction that affected this payment channel."
|
||||
},
|
||||
"previousAffectingTransactionLedgerVersion": {
|
||||
"$ref": "ledgerVersion",
|
||||
"description": "The ledger version that the transaction identified by the `previousAffectingTransactionID` was validated in."
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"account",
|
||||
"destination",
|
||||
"amount",
|
||||
"balance",
|
||||
"settleDelay",
|
||||
"previousAffectingTransactionID",
|
||||
"previousAffectingTransactionLedgerVersion"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
@@ -59,20 +59,38 @@
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"type": {"enum": ["suspendedPaymentCreation"]},
|
||||
"specification": {"$ref": "suspendedPaymentCreation"}
|
||||
"type": {"enum": ["escrowCreation"]},
|
||||
"specification": {"$ref": "escrowCreation"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"type": {"enum": ["suspendedPaymentCancellation"]},
|
||||
"specification": {"$ref": "suspendedPaymentCancellation"}
|
||||
"type": {"enum": ["escrowCancellation"]},
|
||||
"specification": {"$ref": "escrowCancellation"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"type": {"enum": ["suspendedPaymentExecution"]},
|
||||
"specification": {"$ref": "suspendedPaymentExecution"}
|
||||
"type": {"enum": ["escrowExecution"]},
|
||||
"specification": {"$ref": "escrowExecution"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"type": {"enum": ["paymentChannelCreate"]},
|
||||
"specification": {"$ref": "paymentChannelCreate"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"type": {"enum": ["paymentChannelFund"]},
|
||||
"specification": {"$ref": "paymentChannelFund"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"type": {"enum": ["paymentChannelClaim"]},
|
||||
"specification": {"$ref": "paymentChannelClaim"}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "signPaymentChannelClaim",
|
||||
"type": "string",
|
||||
"$ref": "signature",
|
||||
"additionalProperties": false
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "verifyPaymentChannelClaim",
|
||||
"type": "boolean",
|
||||
"additionalProperties": false
|
||||
}
|
||||
19
src/common/schemas/specifications/escrow-cancellation.json
Normal file
19
src/common/schemas/specifications/escrow-cancellation.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "escrowCancellation",
|
||||
"link": "escrow-cancellation",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"memos": {"$ref": "memos"},
|
||||
"owner": {
|
||||
"$ref": "address",
|
||||
"description": "The address of the owner of the escrow to cancel."
|
||||
},
|
||||
"escrowSequence": {
|
||||
"$ref": "sequence",
|
||||
"description": "The [account sequence number](#account-sequence-number) of the [Escrow Creation](#escrow-creation) transaction for the escrow to cancel."
|
||||
}
|
||||
},
|
||||
"required": ["owner", "escrowSequence"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
42
src/common/schemas/specifications/escrow-creation.json
Normal file
42
src/common/schemas/specifications/escrow-creation.json
Normal file
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "escrowCreation",
|
||||
"link": "escrow-creation",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"amount": {
|
||||
"$ref": "value",
|
||||
"description": "Amount of XRP for sender to escrow."
|
||||
},
|
||||
"destination": {
|
||||
"$ref": "address",
|
||||
"description": "Address to receive escrowed XRP."
|
||||
},
|
||||
"memos": {"$ref": "memos"},
|
||||
"condition": {
|
||||
"type": "string",
|
||||
"description": "A hex value representing a [PREIMAGE-SHA-256 crypto-condition](https://tools.ietf.org/html/draft-thomas-crypto-conditions-02#section-8.1). If present, `fulfillment` is required upon execution.",
|
||||
"pattern": "^[A-F0-9]{0,256}$"
|
||||
},
|
||||
"allowCancelAfter": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "If present, the escrow may be cancelled after this time."
|
||||
},
|
||||
"allowExecuteAfter": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "If present, the escrow can not be executed before this time."
|
||||
},
|
||||
"sourceTag": {
|
||||
"$ref": "tag",
|
||||
"description": "Source tag."
|
||||
},
|
||||
"destinationTag": {
|
||||
"$ref": "tag",
|
||||
"description": "Destination tag."
|
||||
}
|
||||
},
|
||||
"required": ["amount", "destination"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
29
src/common/schemas/specifications/escrow-execution.json
Normal file
29
src/common/schemas/specifications/escrow-execution.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "escrowExecution",
|
||||
"link": "escrow-execution",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"memos": {"$ref": "memos"},
|
||||
"owner": {
|
||||
"$ref": "address",
|
||||
"description": "The address of the owner of the escrow to execute."
|
||||
},
|
||||
"escrowSequence": {
|
||||
"$ref": "sequence",
|
||||
"description": "The [account sequence number](#account-sequence-number) of the [Escrow Creation](#escrow-creation) transaction for the escrow to execute."
|
||||
},
|
||||
"condition": {
|
||||
"type": "string",
|
||||
"description": "A hex value representing a [PREIMAGE-SHA-256 crypto-condition](https://tools.ietf.org/html/draft-thomas-crypto-conditions-02#section-8.1). This must match the original `condition` from the escrow creation transaction.",
|
||||
"pattern": "^[A-F0-9]{0,256}$"
|
||||
},
|
||||
"fulfillment": {
|
||||
"type": "string",
|
||||
"description": "A hex value representing the [PREIMAGE-SHA-256 crypto-condition](https://tools.ietf.org/html/draft-thomas-crypto-conditions-02#section-8.1) fulfillment for `condition`.",
|
||||
"pattern": "^[A-F0-9]+$"
|
||||
}
|
||||
},
|
||||
"required": ["owner", "escrowSequence"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
@@ -34,6 +34,10 @@
|
||||
"format": "date-time",
|
||||
"description": "Time after which the offer is no longer active, as an [ISO 8601 date-time](https://en.wikipedia.org/wiki/ISO_8601)."
|
||||
},
|
||||
"orderToReplace": {
|
||||
"$ref": "sequence",
|
||||
"description": "The [account sequence number](#account-sequence-number) of an order to cancel before the new order is created, effectively replacing the old order."
|
||||
},
|
||||
"memos": {"$ref": "memos"}
|
||||
},
|
||||
"required": ["direction", "quantity", "totalPrice"],
|
||||
|
||||
38
src/common/schemas/specifications/payment-channel-claim.json
Normal file
38
src/common/schemas/specifications/payment-channel-claim.json
Normal file
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "paymentChannelClaim",
|
||||
"link": "payment-channel-claim",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"channel": {
|
||||
"$ref": "hash256",
|
||||
"description": "256-bit hexadecimal channel identifier."
|
||||
},
|
||||
"amount": {
|
||||
"$ref": "value",
|
||||
"description": "XRP balance of this channel after claim is processed."
|
||||
},
|
||||
"balance": {
|
||||
"$ref": "value",
|
||||
"description": "Amount of XRP authorized by signature."
|
||||
},
|
||||
"signature": {
|
||||
"$ref": "signature",
|
||||
"description": "Signature of this claim."
|
||||
},
|
||||
"publicKey": {
|
||||
"$ref": "publicKey",
|
||||
"description": "Public key of the channel's sender"
|
||||
},
|
||||
"renew": {
|
||||
"type": "boolean",
|
||||
"description": "Clear the channel's expiration time."
|
||||
},
|
||||
"close": {
|
||||
"type": "boolean",
|
||||
"description": "Request to close the channel."
|
||||
}
|
||||
},
|
||||
"required": ["channel"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "paymentChannelCreate",
|
||||
"link": "payment-channel-create",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"amount": {
|
||||
"$ref": "value",
|
||||
"description": "Amount of XRP for sender to set aside in this channel."
|
||||
},
|
||||
"destination": {
|
||||
"$ref": "address",
|
||||
"description": "Address to receive XRP claims against this channel."
|
||||
},
|
||||
"settleDelay": {
|
||||
"type": "number",
|
||||
"description": "Amount of seconds the source address must wait before closing the channel if it has unclaimed XRP."
|
||||
},
|
||||
"publicKey": {
|
||||
"$ref": "publicKey",
|
||||
"description": "Public key of the key pair the source will use to sign claims against this channel."
|
||||
},
|
||||
"cancelAfter": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "Time when this channel expires."
|
||||
},
|
||||
"sourceTag": {
|
||||
"$ref": "tag",
|
||||
"description": "Source tag."
|
||||
},
|
||||
"destinationTag": {
|
||||
"$ref": "tag",
|
||||
"description": "Destination tag."
|
||||
}
|
||||
},
|
||||
"required": ["amount", "destination", "settleDelay", "publicKey"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
23
src/common/schemas/specifications/payment-channel-fund.json
Normal file
23
src/common/schemas/specifications/payment-channel-fund.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "paymentChannelFund",
|
||||
"link": "payment-channel-fund",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"amount": {
|
||||
"$ref": "value",
|
||||
"description": "Amount of XRP to fund the channel with."
|
||||
},
|
||||
"channel": {
|
||||
"$ref": "hash256",
|
||||
"description": "256-bit hexadecimal channel identifier."
|
||||
},
|
||||
"expiration": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "New expiration for this channel."
|
||||
}
|
||||
},
|
||||
"required": ["amount", "channel"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "suspendedPaymentCancellation",
|
||||
"link": "suspended-payment-cancellation",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"memos": {"$ref": "memos"},
|
||||
"owner": {
|
||||
"$ref": "address",
|
||||
"description": "The address of the owner of the suspended payment to cancel."
|
||||
},
|
||||
"suspensionSequence": {
|
||||
"$ref": "sequence",
|
||||
"description": "The [account sequence number](#account-sequence-number) of the [Suspended Payment Creation](#suspended-payment-creation) transaction for the suspended payment to cancel."
|
||||
}
|
||||
},
|
||||
"required": ["owner", "suspensionSequence"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "suspendedPaymentCreation",
|
||||
"link": "suspended-payment-creation",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"source": {
|
||||
"$ref": "maxAdjustment",
|
||||
"description": "Fields pertaining to the source of the payment."
|
||||
},
|
||||
"destination": {
|
||||
"$ref": "destinationExactAdjustment",
|
||||
"description": "Fields pertaining to the destination of the payment."
|
||||
},
|
||||
"memos": {"$ref": "memos"},
|
||||
"digest": {
|
||||
"$ref": "hash256",
|
||||
"description": "If present, proof is required upon execution."
|
||||
},
|
||||
"allowCancelAfter": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "If present, the suspended payment may be cancelled after this time."
|
||||
},
|
||||
"allowExecuteAfter": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "If present, the suspended payment can not be executed before this time."
|
||||
}
|
||||
},
|
||||
"required": ["source", "destination"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "suspendedPaymentExecution",
|
||||
"link": "suspended-payment-execution",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"memos": {"$ref": "memos"},
|
||||
"owner": {
|
||||
"$ref": "address",
|
||||
"description": "The address of the owner of the suspended payment to execute."
|
||||
},
|
||||
"suspensionSequence": {
|
||||
"$ref": "sequence",
|
||||
"description": "The [account sequence number](#account-sequence-number) of the [Suspended Payment Creation](#suspended-payment-creation) transaction for the suspended payment to execute."
|
||||
},
|
||||
"method": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 255,
|
||||
"description": "The method for verifying the proof; only method `1` is supported."
|
||||
},
|
||||
"digest": {
|
||||
"$ref": "hash256",
|
||||
"description": "The original `digest` from the suspended payment creation transaction. This is sha256 hash of `proof` string. It is replicated here so that the relatively expensive hashing operation can be delegated to a server without ledger history and the server with ledger history only has to do a quick comparison of the old digest with the new digest."
|
||||
},
|
||||
"proof": {
|
||||
"type": "string",
|
||||
"description": "A value that produces the digest when hashed. It must be 32 charaters long and contain only 8-bit characters.",
|
||||
"pattern": "^[\\x00-\\xFF]{32}$"
|
||||
}
|
||||
},
|
||||
"required": ["owner", "suspensionSequence"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
'use strict'; // eslint-disable-line
|
||||
const _ = require('lodash');
|
||||
const {convertKeysFromSnakeCaseToCamelCase} = require('./utils');
|
||||
import type {Connection} from './connection';
|
||||
'use strict' // eslint-disable-line strict
|
||||
const _ = require('lodash')
|
||||
const {convertKeysFromSnakeCaseToCamelCase} = require('./utils')
|
||||
import type {Connection} from './connection'
|
||||
|
||||
export type GetServerInfoResponse = {
|
||||
buildVersion: string,
|
||||
@@ -34,46 +34,46 @@ export type GetServerInfoResponse = {
|
||||
|
||||
function renameKeys(object, mapping) {
|
||||
_.forEach(mapping, (to, from) => {
|
||||
object[to] = object[from];
|
||||
delete object[from];
|
||||
});
|
||||
object[to] = object[from]
|
||||
delete object[from]
|
||||
})
|
||||
}
|
||||
|
||||
function getServerInfo(connection: Connection): Promise<GetServerInfoResponse> {
|
||||
return connection.request({command: 'server_info'}).then(response => {
|
||||
const info = convertKeysFromSnakeCaseToCamelCase(response.info);
|
||||
renameKeys(info, {hostid: 'hostID'});
|
||||
const info = convertKeysFromSnakeCaseToCamelCase(response.info)
|
||||
renameKeys(info, {hostid: 'hostID'})
|
||||
if (info.validatedLedger) {
|
||||
renameKeys(info.validatedLedger, {
|
||||
baseFeeXrp: 'baseFeeXRP',
|
||||
reserveBaseXrp: 'reserveBaseXRP',
|
||||
reserveIncXrp: 'reserveIncrementXRP',
|
||||
seq: 'ledgerVersion'
|
||||
});
|
||||
})
|
||||
info.validatedLedger.baseFeeXRP =
|
||||
info.validatedLedger.baseFeeXRP.toString();
|
||||
info.validatedLedger.baseFeeXRP.toString()
|
||||
info.validatedLedger.reserveBaseXRP =
|
||||
info.validatedLedger.reserveBaseXRP.toString();
|
||||
info.validatedLedger.reserveBaseXRP.toString()
|
||||
info.validatedLedger.reserveIncrementXRP =
|
||||
info.validatedLedger.reserveIncrementXRP.toString();
|
||||
info.validatedLedger.reserveIncrementXRP.toString()
|
||||
}
|
||||
return info;
|
||||
});
|
||||
return info
|
||||
})
|
||||
}
|
||||
|
||||
function computeFeeFromServerInfo(cushion: number,
|
||||
serverInfo: GetServerInfoResponse
|
||||
): number {
|
||||
return (Number(serverInfo.validatedLedger.baseFeeXRP)
|
||||
* Number(serverInfo.loadFactor) * cushion).toString();
|
||||
* Number(serverInfo.loadFactor) * cushion).toString()
|
||||
}
|
||||
|
||||
function getFee(connection: Connection, cushion: number) {
|
||||
return getServerInfo(connection).then(
|
||||
_.partial(computeFeeFromServerInfo, cushion));
|
||||
_.partial(computeFeeFromServerInfo, cushion))
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getServerInfo,
|
||||
getFee
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
'use strict';
|
||||
'use strict' // eslint-disable-line strict
|
||||
|
||||
const txFlags = {
|
||||
// Universal flags can apply to any transaction type
|
||||
@@ -35,8 +35,13 @@ const txFlags = {
|
||||
NoRippleDirect: 0x00010000,
|
||||
PartialPayment: 0x00020000,
|
||||
LimitQuality: 0x00040000
|
||||
},
|
||||
|
||||
PaymentChannelClaim: {
|
||||
Renew: 0x00010000,
|
||||
Close: 0x00020000
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// The following are integer (as opposed to bit) flags
|
||||
// that can be set for particular transactions in the
|
||||
@@ -52,9 +57,9 @@ const txFlagIndices = {
|
||||
asfGlobalFreeze: 7,
|
||||
asfDefaultRipple: 8
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
txFlags,
|
||||
txFlagIndices
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
'use strict' // eslint-disable-line strict
|
||||
|
||||
export type RippledAmountIOU = {
|
||||
currency: string,
|
||||
|
||||
@@ -1,59 +1,59 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const BigNumber = require('bignumber.js');
|
||||
const {deriveKeypair} = require('ripple-keypairs');
|
||||
'use strict' // eslint-disable-line strict
|
||||
const _ = require('lodash')
|
||||
const BigNumber = require('bignumber.js')
|
||||
const {deriveKeypair} = require('ripple-keypairs')
|
||||
|
||||
import type {Amount, RippledAmount} from './types.js';
|
||||
import type {Amount, RippledAmount} from './types.js'
|
||||
|
||||
function isValidSecret(secret: string): boolean {
|
||||
try {
|
||||
deriveKeypair(secret);
|
||||
return true;
|
||||
deriveKeypair(secret)
|
||||
return true
|
||||
} catch (err) {
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
function dropsToXrp(drops: string): string {
|
||||
return (new BigNumber(drops)).dividedBy(1000000.0).toString();
|
||||
return (new BigNumber(drops)).dividedBy(1000000.0).toString()
|
||||
}
|
||||
|
||||
function xrpToDrops(xrp: string): string {
|
||||
return (new BigNumber(xrp)).times(1000000.0).floor().toString();
|
||||
return (new BigNumber(xrp)).times(1000000.0).floor().toString()
|
||||
}
|
||||
|
||||
function toRippledAmount(amount: Amount): RippledAmount {
|
||||
if (amount.currency === 'XRP') {
|
||||
return xrpToDrops(amount.value);
|
||||
return xrpToDrops(amount.value)
|
||||
}
|
||||
return {
|
||||
currency: amount.currency,
|
||||
issuer: amount.counterparty ? amount.counterparty :
|
||||
(amount.issuer ? amount.issuer : undefined),
|
||||
value: amount.value
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function convertKeysFromSnakeCaseToCamelCase(obj: any): any {
|
||||
if (typeof obj === 'object') {
|
||||
let newKey;
|
||||
let newKey
|
||||
return _.reduce(obj, (result, value, key) => {
|
||||
newKey = key;
|
||||
newKey = key
|
||||
// taking this out of function leads to error in PhantomJS
|
||||
const FINDSNAKE = /([a-zA-Z]_[a-zA-Z])/g;
|
||||
const FINDSNAKE = /([a-zA-Z]_[a-zA-Z])/g
|
||||
if (FINDSNAKE.test(key)) {
|
||||
newKey = key.replace(FINDSNAKE, r => r[0] + r[2].toUpperCase());
|
||||
newKey = key.replace(FINDSNAKE, r => r[0] + r[2].toUpperCase())
|
||||
}
|
||||
result[newKey] = convertKeysFromSnakeCaseToCamelCase(value);
|
||||
return result;
|
||||
}, {});
|
||||
result[newKey] = convertKeysFromSnakeCaseToCamelCase(value)
|
||||
return result
|
||||
}, {})
|
||||
}
|
||||
return obj;
|
||||
return obj
|
||||
}
|
||||
|
||||
function removeUndefined(obj: Object): Object {
|
||||
return _.omit(obj, _.isUndefined);
|
||||
return _.omit(obj, _.isUndefined)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -62,7 +62,7 @@ function removeUndefined(obj: Object): Object {
|
||||
*
|
||||
*/
|
||||
function rippleToUnixTimestamp(rpepoch: number): number {
|
||||
return (rpepoch + 0x386D4380) * 1000;
|
||||
return (rpepoch + 0x386D4380) * 1000
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,15 +70,15 @@ function rippleToUnixTimestamp(rpepoch: number): number {
|
||||
* @return {Number} seconds since ripple epoch ( 1/1/2000 GMT)
|
||||
*/
|
||||
function unixToRippleTimestamp(timestamp: number): number {
|
||||
return Math.round(timestamp / 1000) - 0x386D4380;
|
||||
return Math.round(timestamp / 1000) - 0x386D4380
|
||||
}
|
||||
|
||||
function rippleTimeToISO8601(rippleTime: number): string {
|
||||
return new Date(rippleToUnixTimestamp(rippleTime)).toISOString();
|
||||
return new Date(rippleToUnixTimestamp(rippleTime)).toISOString()
|
||||
}
|
||||
|
||||
function iso8601ToRippleTime(iso8601: string): number {
|
||||
return unixToRippleTimestamp(Date.parse(iso8601));
|
||||
return unixToRippleTimestamp(Date.parse(iso8601))
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
@@ -90,4 +90,4 @@ module.exports = {
|
||||
rippleTimeToISO8601,
|
||||
iso8601ToRippleTime,
|
||||
isValidSecret
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const ValidationError = require('./errors').ValidationError;
|
||||
const schemaValidate = require('./schema-validator').schemaValidate;
|
||||
'use strict' // eslint-disable-line strict
|
||||
const _ = require('lodash')
|
||||
const ValidationError = require('./errors').ValidationError
|
||||
const schemaValidate = require('./schema-validator').schemaValidate
|
||||
|
||||
function error(text) {
|
||||
return new ValidationError(text);
|
||||
return new ValidationError(text)
|
||||
}
|
||||
|
||||
function validateLedgerRange(options) {
|
||||
if (!_.isUndefined(options) && !_.isUndefined(options.minLedgerVersion)
|
||||
&& !_.isUndefined(options.maxLedgerVersion)) {
|
||||
if (Number(options.minLedgerVersion) > Number(options.maxLedgerVersion)) {
|
||||
throw error('minLedgerVersion must not be greater than maxLedgerVersion');
|
||||
throw error('minLedgerVersion must not be greater than maxLedgerVersion')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function validateOptions(schema, instance) {
|
||||
schemaValidate(schema, instance);
|
||||
validateLedgerRange(instance.options);
|
||||
schemaValidate(schema, instance)
|
||||
validateLedgerRange(instance.options)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
@@ -33,6 +33,7 @@ module.exports = {
|
||||
getOrders: _.partial(validateOptions, 'getOrdersParameters'),
|
||||
getOrderbook: _.partial(validateOptions, 'getOrderbookParameters'),
|
||||
getTransaction: _.partial(validateOptions, 'getTransactionParameters'),
|
||||
getPaymentChannel: _.partial(validateOptions, 'getPaymentChannelParameters'),
|
||||
getLedger: _.partial(validateOptions, 'getLedgerParameters'),
|
||||
preparePayment: _.partial(schemaValidate, 'preparePaymentParameters'),
|
||||
prepareOrder: _.partial(schemaValidate, 'prepareOrderParameters'),
|
||||
@@ -40,17 +41,27 @@ module.exports = {
|
||||
_.partial(schemaValidate, 'prepareOrderCancellationParameters'),
|
||||
prepareTrustline: _.partial(schemaValidate, 'prepareTrustlineParameters'),
|
||||
prepareSettings: _.partial(schemaValidate, 'prepareSettingsParameters'),
|
||||
prepareSuspendedPaymentCreation: _.partial(schemaValidate,
|
||||
'prepareSuspendedPaymentCreationParameters'),
|
||||
prepareSuspendedPaymentCancellation: _.partial(schemaValidate,
|
||||
'prepareSuspendedPaymentCancellationParameters'),
|
||||
prepareSuspendedPaymentExecution: _.partial(schemaValidate,
|
||||
'prepareSuspendedPaymentExecutionParameters'),
|
||||
prepareEscrowCreation: _.partial(schemaValidate,
|
||||
'prepareEscrowCreationParameters'),
|
||||
prepareEscrowCancellation: _.partial(schemaValidate,
|
||||
'prepareEscrowCancellationParameters'),
|
||||
prepareEscrowExecution: _.partial(schemaValidate,
|
||||
'prepareEscrowExecutionParameters'),
|
||||
preparePaymentChannelCreate: _.partial(schemaValidate,
|
||||
'preparePaymentChannelCreateParameters'),
|
||||
preparePaymentChannelFund: _.partial(schemaValidate,
|
||||
'preparePaymentChannelFundParameters'),
|
||||
preparePaymentChannelClaim: _.partial(schemaValidate,
|
||||
'preparePaymentChannelClaimParameters'),
|
||||
sign: _.partial(schemaValidate, 'signParameters'),
|
||||
combine: _.partial(schemaValidate, 'combineParameters'),
|
||||
submit: _.partial(schemaValidate, 'submitParameters'),
|
||||
computeLedgerHash: _.partial(schemaValidate, 'computeLedgerHashParameters'),
|
||||
generateAddress: _.partial(schemaValidate, 'generateAddressParameters'),
|
||||
signPaymentChannelClaim: _.partial(schemaValidate,
|
||||
'signPaymentChannelClaimParameters'),
|
||||
verifyPaymentChannelClaim: _.partial(schemaValidate,
|
||||
'verifyPaymentChannelClaimParameters'),
|
||||
apiOptions: _.partial(schemaValidate, 'api-options'),
|
||||
instructions: _.partial(schemaValidate, 'instructions')
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use strict';
|
||||
'use strict' // eslint-disable-line strict
|
||||
|
||||
const {EventEmitter} = require('events');
|
||||
const {EventEmitter} = require('events')
|
||||
|
||||
function unsused() {}
|
||||
|
||||
@@ -10,50 +10,50 @@ function unsused() {}
|
||||
*/
|
||||
class WSWrapper extends EventEmitter {
|
||||
constructor(url, protocols = null, websocketOptions = {}) {
|
||||
super();
|
||||
unsused(protocols);
|
||||
unsused(websocketOptions);
|
||||
this.setMaxListeners(Infinity);
|
||||
super()
|
||||
unsused(protocols)
|
||||
unsused(websocketOptions)
|
||||
this.setMaxListeners(Infinity)
|
||||
|
||||
this._ws = new WebSocket(url);
|
||||
this._ws = new WebSocket(url)
|
||||
|
||||
this._ws.onclose = () => {
|
||||
this.emit('close');
|
||||
};
|
||||
this.emit('close')
|
||||
}
|
||||
|
||||
this._ws.onopen = () => {
|
||||
this.emit('open');
|
||||
};
|
||||
this.emit('open')
|
||||
}
|
||||
|
||||
this._ws.onerror = error => {
|
||||
this.emit('error', error);
|
||||
};
|
||||
this.emit('error', error)
|
||||
}
|
||||
|
||||
this._ws.onmessage = message => {
|
||||
this.emit('message', message.data);
|
||||
};
|
||||
this.emit('message', message.data)
|
||||
}
|
||||
}
|
||||
|
||||
close() {
|
||||
if (this.readyState === 1) {
|
||||
this._ws.close();
|
||||
this._ws.close()
|
||||
}
|
||||
}
|
||||
|
||||
send(message) {
|
||||
this._ws.send(message);
|
||||
this._ws.send(message)
|
||||
}
|
||||
|
||||
get readyState() {
|
||||
return this._ws.readyState;
|
||||
return this._ws.readyState
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
WSWrapper.CONNECTING = 0;
|
||||
WSWrapper.OPEN = 1;
|
||||
WSWrapper.CLOSING = 2;
|
||||
WSWrapper.CLOSED = 3;
|
||||
WSWrapper.CONNECTING = 0
|
||||
WSWrapper.OPEN = 1
|
||||
WSWrapper.CLOSING = 2
|
||||
WSWrapper.CLOSED = 3
|
||||
|
||||
module.exports = WSWrapper;
|
||||
module.exports = WSWrapper
|
||||
|
||||
|
||||
78
src/http.js
78
src/http.js
@@ -1,86 +1,86 @@
|
||||
/* eslint-disable new-cap */
|
||||
'use strict';
|
||||
'use strict' // eslint-disable-line strict
|
||||
|
||||
const assert = require('assert');
|
||||
const _ = require('lodash');
|
||||
const jayson = require('jayson');
|
||||
const assert = require('assert')
|
||||
const _ = require('lodash')
|
||||
const jayson = require('jayson')
|
||||
|
||||
const RippleAPI = require('./api').RippleAPI;
|
||||
const RippleAPI = require('./api').RippleAPI
|
||||
|
||||
|
||||
/* istanbul ignore next */
|
||||
function createHTTPServer(options, httpPort) {
|
||||
const rippleAPI = new RippleAPI(options);
|
||||
const rippleAPI = new RippleAPI(options)
|
||||
|
||||
const methodNames = _.filter(_.keys(RippleAPI.prototype), k => {
|
||||
return typeof RippleAPI.prototype[k] === 'function'
|
||||
&& k !== 'connect'
|
||||
&& k !== 'disconnect'
|
||||
&& k !== 'constructor'
|
||||
&& k !== 'RippleAPI';
|
||||
});
|
||||
&& k !== 'RippleAPI'
|
||||
})
|
||||
|
||||
function applyPromiseWithCallback(fnName, callback, args_) {
|
||||
try {
|
||||
let args = args_;
|
||||
let args = args_
|
||||
if (!_.isArray(args_)) {
|
||||
const fnParameters = jayson.Utils.getParameterNames(rippleAPI[fnName]);
|
||||
args = fnParameters.map(name => args_[name]);
|
||||
const defaultArgs = _.omit(args_, fnParameters);
|
||||
const fnParameters = jayson.Utils.getParameterNames(rippleAPI[fnName])
|
||||
args = fnParameters.map(name => args_[name])
|
||||
const defaultArgs = _.omit(args_, fnParameters)
|
||||
assert(_.size(defaultArgs) <= 1,
|
||||
'Function must have no more than one default argument');
|
||||
'Function must have no more than one default argument')
|
||||
if (_.size(defaultArgs) > 0) {
|
||||
args.push(defaultArgs[_.keys(defaultArgs)[0]]);
|
||||
args.push(defaultArgs[_.keys(defaultArgs)[0]])
|
||||
}
|
||||
}
|
||||
Promise.resolve(rippleAPI[fnName].apply(rippleAPI, args))
|
||||
Promise.resolve(rippleAPI[fnName](...args))
|
||||
.then(res => callback(null, res))
|
||||
.catch(err => {
|
||||
callback({code: 99, message: err.message, data: {name: err.name}});
|
||||
});
|
||||
callback({code: 99, message: err.message, data: {name: err.name}})
|
||||
})
|
||||
} catch (err) {
|
||||
callback({code: 99, message: err.message, data: {name: err.name}});
|
||||
callback({code: 99, message: err.message, data: {name: err.name}})
|
||||
}
|
||||
}
|
||||
|
||||
const methods = {};
|
||||
const methods = {}
|
||||
_.forEach(methodNames, fn => {
|
||||
methods[fn] = jayson.Method((args, cb) => {
|
||||
applyPromiseWithCallback(fn, cb, args);
|
||||
}, {collect: true});
|
||||
});
|
||||
applyPromiseWithCallback(fn, cb, args)
|
||||
}, {collect: true})
|
||||
})
|
||||
|
||||
const server = jayson.server(methods);
|
||||
let httpServer = null;
|
||||
const server = jayson.server(methods)
|
||||
let httpServer = null
|
||||
|
||||
return {
|
||||
server: server,
|
||||
start: function() {
|
||||
if (httpServer !== null) {
|
||||
return Promise.reject('Already started');
|
||||
return Promise.reject('Already started')
|
||||
}
|
||||
return new Promise((resolve) => {
|
||||
return new Promise(resolve => {
|
||||
rippleAPI.connect().then(() => {
|
||||
httpServer = server.http();
|
||||
httpServer.listen(httpPort, resolve);
|
||||
});
|
||||
});
|
||||
httpServer = server.http()
|
||||
httpServer.listen(httpPort, resolve)
|
||||
})
|
||||
})
|
||||
},
|
||||
stop: function() {
|
||||
if (httpServer === null) {
|
||||
return Promise.reject('Not started');
|
||||
return Promise.reject('Not started')
|
||||
}
|
||||
return new Promise((resolve) => {
|
||||
rippleAPI.disconnect();
|
||||
return new Promise(resolve => {
|
||||
rippleAPI.disconnect()
|
||||
httpServer.close(() => {
|
||||
httpServer = null;
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
httpServer = null
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
createHTTPServer
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
'use strict';
|
||||
'use strict' // eslint-disable-line strict
|
||||
|
||||
module.exports = {
|
||||
RippleAPI: require('./api').RippleAPI,
|
||||
// Broadcast api is experimental
|
||||
RippleAPIBroadcast: require('./broadcast').RippleAPIBroadcast,
|
||||
// HTTP server is experimental
|
||||
createHTTPServer: require('./http').createHTTPServer
|
||||
};
|
||||
RippleAPIBroadcast: require('./broadcast').RippleAPIBroadcast
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/* @flow */
|
||||
|
||||
'use strict';
|
||||
const utils = require('./utils');
|
||||
const {validate, removeUndefined} = utils.common;
|
||||
'use strict' // eslint-disable-line strict
|
||||
const utils = require('./utils')
|
||||
const {validate, removeUndefined} = utils.common
|
||||
|
||||
type AccountData = {
|
||||
Sequence: number,
|
||||
@@ -39,7 +39,7 @@ type AccountInfoResponse = {
|
||||
}
|
||||
|
||||
function formatAccountInfo(response: AccountDataResponse) {
|
||||
const data = response.account_data;
|
||||
const data = response.account_data
|
||||
return removeUndefined({
|
||||
sequence: data.Sequence,
|
||||
xrpBalance: utils.common.dropsToXrp(data.Balance),
|
||||
@@ -47,20 +47,20 @@ function formatAccountInfo(response: AccountDataResponse) {
|
||||
previousInitiatedTransactionID: data.AccountTxnID,
|
||||
previousAffectingTransactionID: data.PreviousTxnID,
|
||||
previousAffectingTransactionLedgerVersion: data.PreviousTxnLgrSeq
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
function getAccountInfo(address: string, options: AccountInfoOptions = {}
|
||||
): Promise<AccountInfoResponse> {
|
||||
validate.getAccountInfo({address, options});
|
||||
validate.getAccountInfo({address, options})
|
||||
|
||||
const request = {
|
||||
command: 'account_info',
|
||||
account: address,
|
||||
ledger_index: options.ledgerVersion || 'validated'
|
||||
};
|
||||
}
|
||||
|
||||
return this.connection.request(request).then(formatAccountInfo);
|
||||
return this.connection.request(request).then(formatAccountInfo)
|
||||
}
|
||||
|
||||
module.exports = getAccountInfo;
|
||||
module.exports = getAccountInfo
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
'use strict' // eslint-disable-line strict
|
||||
|
||||
const _ = require('lodash');
|
||||
const utils = require('./utils');
|
||||
const {validate} = utils.common;
|
||||
import type {Amount} from '../common/types.js';
|
||||
const _ = require('lodash')
|
||||
const utils = require('./utils')
|
||||
const {validate} = utils.common
|
||||
import type {Amount} from '../common/types.js'
|
||||
|
||||
type BalanceSheetOptions = {
|
||||
excludeAddresses?: Array<string>,
|
||||
@@ -21,35 +21,35 @@ type GetBalanceSheet = {
|
||||
}
|
||||
|
||||
function formatBalanceSheet(balanceSheet): GetBalanceSheet {
|
||||
const result = {};
|
||||
const result = {}
|
||||
|
||||
if (!_.isUndefined(balanceSheet.balances)) {
|
||||
result.balances = [];
|
||||
result.balances = []
|
||||
_.forEach(balanceSheet.balances, (balances, counterparty) => {
|
||||
_.forEach(balances, (balance) => {
|
||||
result.balances.push(Object.assign({counterparty}, balance));
|
||||
});
|
||||
});
|
||||
_.forEach(balances, balance => {
|
||||
result.balances.push(Object.assign({counterparty}, balance))
|
||||
})
|
||||
})
|
||||
}
|
||||
if (!_.isUndefined(balanceSheet.assets)) {
|
||||
result.assets = [];
|
||||
result.assets = []
|
||||
_.forEach(balanceSheet.assets, (assets, counterparty) => {
|
||||
_.forEach(assets, (balance) => {
|
||||
result.assets.push(Object.assign({counterparty}, balance));
|
||||
});
|
||||
});
|
||||
_.forEach(assets, balance => {
|
||||
result.assets.push(Object.assign({counterparty}, balance))
|
||||
})
|
||||
})
|
||||
}
|
||||
if (!_.isUndefined(balanceSheet.obligations)) {
|
||||
result.obligations = _.map(balanceSheet.obligations, (value, currency) =>
|
||||
({currency, value}));
|
||||
({currency, value}))
|
||||
}
|
||||
|
||||
return result;
|
||||
return result
|
||||
}
|
||||
|
||||
function getBalanceSheet(address: string, options: BalanceSheetOptions = {}
|
||||
): Promise<GetBalanceSheet> {
|
||||
validate.getBalanceSheet({address, options});
|
||||
validate.getBalanceSheet({address, options})
|
||||
|
||||
return utils.ensureLedgerVersion.call(this, options).then(_options => {
|
||||
const request = {
|
||||
@@ -58,10 +58,10 @@ function getBalanceSheet(address: string, options: BalanceSheetOptions = {}
|
||||
strict: true,
|
||||
hotwallet: _options.excludeAddresses,
|
||||
ledger_index: _options.ledgerVersion
|
||||
};
|
||||
}
|
||||
|
||||
return this.connection.request(request).then(formatBalanceSheet);
|
||||
});
|
||||
return this.connection.request(request).then(formatBalanceSheet)
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = getBalanceSheet;
|
||||
module.exports = getBalanceSheet
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const utils = require('./utils');
|
||||
const {validate} = utils.common;
|
||||
import type {Connection} from '../common/connection.js';
|
||||
import type {TrustlinesOptions, Trustline} from './trustlines-types.js';
|
||||
'use strict' // eslint-disable-line strict
|
||||
const utils = require('./utils')
|
||||
const {validate} = utils.common
|
||||
import type {Connection} from '../common/connection.js'
|
||||
import type {TrustlinesOptions, Trustline} from './trustlines-types.js'
|
||||
|
||||
|
||||
type Balance = {
|
||||
@@ -19,38 +19,38 @@ function getTrustlineBalanceAmount(trustline: Trustline) {
|
||||
currency: trustline.specification.currency,
|
||||
counterparty: trustline.specification.counterparty,
|
||||
value: trustline.state.balance
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function formatBalances(options, balances) {
|
||||
const result = balances.trustlines.map(getTrustlineBalanceAmount);
|
||||
const result = balances.trustlines.map(getTrustlineBalanceAmount)
|
||||
if (!(options.counterparty ||
|
||||
(options.currency && options.currency !== 'XRP')
|
||||
)) {
|
||||
const xrpBalance = {
|
||||
currency: 'XRP',
|
||||
value: balances.xrp
|
||||
};
|
||||
result.unshift(xrpBalance);
|
||||
}
|
||||
result.unshift(xrpBalance)
|
||||
}
|
||||
if (options.limit && result.length > options.limit) {
|
||||
const toRemove = result.length - options.limit;
|
||||
result.splice(-toRemove, toRemove);
|
||||
const toRemove = result.length - options.limit
|
||||
result.splice(-toRemove, toRemove)
|
||||
}
|
||||
return result;
|
||||
return result
|
||||
}
|
||||
|
||||
function getLedgerVersionHelper(connection: Connection, optionValue?: number
|
||||
): Promise<number> {
|
||||
if (optionValue !== undefined && optionValue !== null) {
|
||||
return Promise.resolve(optionValue);
|
||||
return Promise.resolve(optionValue)
|
||||
}
|
||||
return connection.getLedgerVersion();
|
||||
return connection.getLedgerVersion()
|
||||
}
|
||||
|
||||
function getBalances(address: string, options: TrustlinesOptions = {}
|
||||
): Promise<GetBalances> {
|
||||
validate.getTrustlines({address, options});
|
||||
validate.getTrustlines({address, options})
|
||||
|
||||
return Promise.all([
|
||||
getLedgerVersionHelper(this.connection, options.ledgerVersion).then(
|
||||
@@ -58,7 +58,7 @@ function getBalances(address: string, options: TrustlinesOptions = {}
|
||||
utils.getXRPBalance(this.connection, address, ledgerVersion)),
|
||||
this.getTrustlines(address, options)
|
||||
]).then(results =>
|
||||
formatBalances(options, {xrp: results[0], trustlines: results[1]}));
|
||||
formatBalances(options, {xrp: results[0], trustlines: results[1]}))
|
||||
}
|
||||
|
||||
module.exports = getBalances;
|
||||
module.exports = getBalances
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const utils = require('./utils');
|
||||
const {validate} = utils.common;
|
||||
const parseLedger = require('./parse/ledger');
|
||||
import type {GetLedger} from './types.js';
|
||||
'use strict' // eslint-disable-line strict
|
||||
const utils = require('./utils')
|
||||
const {validate} = utils.common
|
||||
const parseLedger = require('./parse/ledger')
|
||||
import type {GetLedger} from './types.js'
|
||||
|
||||
type LedgerOptions = {
|
||||
ledgerVersion?: number,
|
||||
@@ -14,7 +14,7 @@ type LedgerOptions = {
|
||||
|
||||
|
||||
function getLedger(options: LedgerOptions = {}): Promise<GetLedger> {
|
||||
validate.getLedger({options});
|
||||
validate.getLedger({options})
|
||||
|
||||
const request = {
|
||||
command: 'ledger',
|
||||
@@ -22,10 +22,10 @@ function getLedger(options: LedgerOptions = {}): Promise<GetLedger> {
|
||||
expand: options.includeAllData,
|
||||
transactions: options.includeTransactions,
|
||||
accounts: options.includeState
|
||||
};
|
||||
}
|
||||
|
||||
return this.connection.request(request).then(response =>
|
||||
parseLedger(response.ledger));
|
||||
parseLedger(response.ledger))
|
||||
}
|
||||
|
||||
module.exports = getLedger;
|
||||
module.exports = getLedger
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const utils = require('./utils');
|
||||
const {validate} = utils.common;
|
||||
const parseOrderbookOrder = require('./parse/orderbook-order');
|
||||
import type {Connection} from '../common/connection.js';
|
||||
import type {OrdersOptions, OrderSpecification} from './types.js';
|
||||
import type {Amount, Issue} from '../common/types.js';
|
||||
'use strict' // eslint-disable-line strict
|
||||
const _ = require('lodash')
|
||||
const utils = require('./utils')
|
||||
const {validate} = utils.common
|
||||
const parseOrderbookOrder = require('./parse/orderbook-order')
|
||||
import type {Connection} from '../common/connection.js'
|
||||
import type {OrdersOptions, OrderSpecification} from './types.js'
|
||||
import type {Amount, Issue} from '../common/types.js'
|
||||
|
||||
type Orderbook = {
|
||||
base: Issue,
|
||||
@@ -46,31 +46,31 @@ function getBookOffers(connection: Connection, account: string,
|
||||
ledger_index: ledgerVersion || 'validated',
|
||||
limit: limit,
|
||||
taker: account
|
||||
})).then(data => data.offers);
|
||||
})).then(data => data.offers)
|
||||
}
|
||||
|
||||
function isSameIssue(a: Amount, b: Amount) {
|
||||
return a.currency === b.currency && a.counterparty === b.counterparty;
|
||||
return a.currency === b.currency && a.counterparty === b.counterparty
|
||||
}
|
||||
|
||||
function directionFilter(direction: string, order: OrderbookItem) {
|
||||
return order.specification.direction === direction;
|
||||
return order.specification.direction === direction
|
||||
}
|
||||
|
||||
function flipOrder(order: OrderbookItem) {
|
||||
const specification = order.specification;
|
||||
const specification = order.specification
|
||||
const flippedSpecification = {
|
||||
quantity: specification.totalPrice,
|
||||
totalPrice: specification.quantity,
|
||||
direction: specification.direction === 'buy' ? 'sell' : 'buy'
|
||||
};
|
||||
const newSpecification = _.merge({}, specification, flippedSpecification);
|
||||
return _.merge({}, order, {specification: newSpecification});
|
||||
}
|
||||
const newSpecification = _.merge({}, specification, flippedSpecification)
|
||||
return _.merge({}, order, {specification: newSpecification})
|
||||
}
|
||||
|
||||
function alignOrder(base: Amount, order: OrderbookItem) {
|
||||
const quantity = order.specification.quantity;
|
||||
return isSameIssue(quantity, base) ? order : flipOrder(order);
|
||||
const quantity = order.specification.quantity
|
||||
return isSameIssue(quantity, base) ? order : flipOrder(order)
|
||||
}
|
||||
|
||||
function formatBidsAndAsks(orderbook: Orderbook, offers) {
|
||||
@@ -84,24 +84,24 @@ function formatBidsAndAsks(orderbook: Orderbook, offers) {
|
||||
// for asks: lowest quality => lowest totalPrice/quantity => lowest price
|
||||
// for both bids and asks, lowest quality is closest to mid-market
|
||||
// we sort the orders so that earlier orders are closer to mid-market
|
||||
const orders = _.sortBy(offers, 'quality').map(parseOrderbookOrder);
|
||||
const alignedOrders = orders.map(_.partial(alignOrder, orderbook.base));
|
||||
const bids = alignedOrders.filter(_.partial(directionFilter, 'buy'));
|
||||
const asks = alignedOrders.filter(_.partial(directionFilter, 'sell'));
|
||||
return {bids, asks};
|
||||
const orders = _.sortBy(offers, 'quality').map(parseOrderbookOrder)
|
||||
const alignedOrders = orders.map(_.partial(alignOrder, orderbook.base))
|
||||
const bids = alignedOrders.filter(_.partial(directionFilter, 'buy'))
|
||||
const asks = alignedOrders.filter(_.partial(directionFilter, 'sell'))
|
||||
return {bids, asks}
|
||||
}
|
||||
|
||||
function getOrderbook(address: string, orderbook: Orderbook,
|
||||
options: OrdersOptions = {}
|
||||
): Promise<GetOrderbook> {
|
||||
validate.getOrderbook({address, orderbook, options});
|
||||
validate.getOrderbook({address, orderbook, options})
|
||||
|
||||
const getter = _.partial(getBookOffers, this.connection, address,
|
||||
options.ledgerVersion, options.limit);
|
||||
const getOffers = _.partial(getter, orderbook.base, orderbook.counter);
|
||||
const getReverseOffers = _.partial(getter, orderbook.counter, orderbook.base);
|
||||
options.ledgerVersion, options.limit)
|
||||
const getOffers = _.partial(getter, orderbook.base, orderbook.counter)
|
||||
const getReverseOffers = _.partial(getter, orderbook.counter, orderbook.base)
|
||||
return Promise.all([getOffers(), getReverseOffers()]).then(data =>
|
||||
formatBidsAndAsks(orderbook, _.flatten(data)));
|
||||
formatBidsAndAsks(orderbook, _.flatten(data)))
|
||||
}
|
||||
|
||||
module.exports = getOrderbook;
|
||||
module.exports = getOrderbook
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const utils = require('./utils');
|
||||
const {validate} = utils.common;
|
||||
const parseAccountOrder = require('./parse/account-order');
|
||||
import type {Connection} from '../common/connection.js';
|
||||
import type {OrdersOptions, Order} from './types.js';
|
||||
'use strict' // eslint-disable-line strict
|
||||
const _ = require('lodash')
|
||||
const utils = require('./utils')
|
||||
const {validate} = utils.common
|
||||
const parseAccountOrder = require('./parse/account-order')
|
||||
import type {Connection} from '../common/connection.js'
|
||||
import type {OrdersOptions, Order} from './types.js'
|
||||
|
||||
type GetOrders = Array<Order>
|
||||
|
||||
@@ -22,20 +22,20 @@ function requestAccountOffers(connection: Connection, address: string,
|
||||
return {
|
||||
marker: data.marker,
|
||||
results: data.offers.map(_.partial(parseAccountOrder, address))
|
||||
};
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function getOrders(address: string, options: OrdersOptions = {}
|
||||
): Promise<GetOrders> {
|
||||
validate.getOrders({address, options});
|
||||
validate.getOrders({address, options})
|
||||
|
||||
return utils.ensureLedgerVersion.call(this, options).then(_options => {
|
||||
const getter = _.partial(requestAccountOffers, this.connection, address,
|
||||
_options.ledgerVersion);
|
||||
_options.ledgerVersion)
|
||||
return utils.getRecursive(getter, _options.limit).then(orders =>
|
||||
_.sortBy(orders, (order) => order.properties.sequence));
|
||||
});
|
||||
_.sortBy(orders, order => order.properties.sequence))
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = getOrders;
|
||||
module.exports = getOrders
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
/* @flow */
|
||||
'use strict'; // eslint-disable-line strict
|
||||
const utils = require('./utils');
|
||||
const flags = require('./flags').orderFlags;
|
||||
const parseAmount = require('./amount');
|
||||
const BigNumber = require('bignumber.js');
|
||||
'use strict' // eslint-disable-line strict
|
||||
const utils = require('./utils')
|
||||
const flags = require('./flags').orderFlags
|
||||
const parseAmount = require('./amount')
|
||||
const BigNumber = require('bignumber.js')
|
||||
|
||||
// TODO: remove this function once rippled provides quality directly
|
||||
function computeQuality(takerGets, takerPays) {
|
||||
const quotient = new BigNumber(takerPays.value).dividedBy(takerGets.value);
|
||||
return quotient.toDigits(16, BigNumber.ROUND_HALF_UP).toString();
|
||||
const quotient = new BigNumber(takerPays.value).dividedBy(takerGets.value)
|
||||
return quotient.toDigits(16, BigNumber.ROUND_HALF_UP).toString()
|
||||
}
|
||||
|
||||
// rippled 'account_offers' returns a different format for orders than 'tx'
|
||||
// the flags are also different
|
||||
function parseAccountOrder(address: string, order: Object): Object {
|
||||
const direction = (order.flags & flags.Sell) === 0 ? 'buy' : 'sell';
|
||||
const takerGetsAmount = parseAmount(order.taker_gets);
|
||||
const takerPaysAmount = parseAmount(order.taker_pays);
|
||||
const quantity = (direction === 'buy') ? takerPaysAmount : takerGetsAmount;
|
||||
const totalPrice = (direction === 'buy') ? takerGetsAmount : takerPaysAmount;
|
||||
const direction = (order.flags & flags.Sell) === 0 ? 'buy' : 'sell'
|
||||
const takerGetsAmount = parseAmount(order.taker_gets)
|
||||
const takerPaysAmount = parseAmount(order.taker_pays)
|
||||
const quantity = (direction === 'buy') ? takerPaysAmount : takerGetsAmount
|
||||
const totalPrice = (direction === 'buy') ? takerGetsAmount : takerPaysAmount
|
||||
|
||||
// note: immediateOrCancel and fillOrKill orders cannot enter the order book
|
||||
// so we can omit those flags here
|
||||
@@ -29,19 +29,19 @@ function parseAccountOrder(address: string, order: Object): Object {
|
||||
passive: ((order.flags & flags.Passive) !== 0) || undefined,
|
||||
// rippled currently does not provide "expiration" in account_offers
|
||||
expirationTime: utils.parseTimestamp(order.expiration)
|
||||
});
|
||||
})
|
||||
|
||||
const makerExchangeRate = order.quality ?
|
||||
utils.adjustQualityForXRP(order.quality.toString(),
|
||||
takerGetsAmount.currency, takerPaysAmount.currency) :
|
||||
computeQuality(takerGetsAmount, takerPaysAmount);
|
||||
computeQuality(takerGetsAmount, takerPaysAmount)
|
||||
const properties = {
|
||||
maker: address,
|
||||
sequence: order.seq,
|
||||
makerExchangeRate: makerExchangeRate
|
||||
};
|
||||
}
|
||||
|
||||
return {specification, properties};
|
||||
return {specification, properties}
|
||||
}
|
||||
|
||||
module.exports = parseAccountOrder;
|
||||
module.exports = parseAccountOrder
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const utils = require('./utils');
|
||||
'use strict' // eslint-disable-line strict
|
||||
const utils = require('./utils')
|
||||
|
||||
type Trustline = {
|
||||
account: string, limit: number, currency: string, quality_in: ?number,
|
||||
@@ -29,18 +29,18 @@ function parseAccountTrustline(trustline: Trustline): AccountTrustline {
|
||||
ripplingDisabled: trustline.no_ripple || undefined,
|
||||
frozen: trustline.freeze || undefined,
|
||||
authorized: trustline.authorized || undefined
|
||||
});
|
||||
})
|
||||
// rippled doesn't provide the counterparty's qualities
|
||||
const counterparty = utils.removeUndefined({
|
||||
limit: trustline.limit_peer,
|
||||
ripplingDisabled: trustline.no_ripple_peer || undefined,
|
||||
frozen: trustline.freeze_peer || undefined,
|
||||
authorized: trustline.peer_authorized || undefined
|
||||
});
|
||||
})
|
||||
const state = {
|
||||
balance: trustline.balance
|
||||
};
|
||||
return {specification, counterparty, state};
|
||||
}
|
||||
return {specification, counterparty, state}
|
||||
}
|
||||
|
||||
module.exports = parseAccountTrustline;
|
||||
module.exports = parseAccountTrustline
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
'use strict'; // eslint-disable-line strict
|
||||
'use strict' // eslint-disable-line strict
|
||||
|
||||
function parseAmendment(tx: Object) {
|
||||
return {
|
||||
amendment: tx.Amendment
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = parseAmendment;
|
||||
module.exports = parseAmendment
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const utils = require('../utils');
|
||||
import type {Amount, RippledAmount} from '../../common/types.js';
|
||||
'use strict' // eslint-disable-line strict
|
||||
const utils = require('../utils')
|
||||
import type {Amount, RippledAmount} from '../../common/types.js'
|
||||
|
||||
|
||||
function parseAmount(amount: RippledAmount): Amount {
|
||||
@@ -9,13 +9,13 @@ function parseAmount(amount: RippledAmount): Amount {
|
||||
return {
|
||||
currency: 'XRP',
|
||||
value: utils.common.dropsToXrp(amount)
|
||||
};
|
||||
}
|
||||
}
|
||||
return {
|
||||
currency: amount.currency,
|
||||
value: amount.value,
|
||||
counterparty: amount.issuer
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = parseAmount;
|
||||
module.exports = parseAmount
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const assert = require('assert');
|
||||
'use strict' // eslint-disable-line strict
|
||||
const assert = require('assert')
|
||||
|
||||
function parseOrderCancellation(tx: Object): Object {
|
||||
assert(tx.TransactionType === 'OfferCancel');
|
||||
assert(tx.TransactionType === 'OfferCancel')
|
||||
return {
|
||||
orderSequence: tx.OfferSequence
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = parseOrderCancellation;
|
||||
module.exports = parseOrderCancellation
|
||||
|
||||
16
src/ledger/parse/escrow-cancellation.js
Normal file
16
src/ledger/parse/escrow-cancellation.js
Normal file
@@ -0,0 +1,16 @@
|
||||
/* @flow */
|
||||
'use strict' // eslint-disable-line strict
|
||||
const assert = require('assert')
|
||||
const utils = require('./utils')
|
||||
|
||||
function parseEscrowCancellation(tx: Object): Object {
|
||||
assert(tx.TransactionType === 'EscrowCancel')
|
||||
|
||||
return utils.removeUndefined({
|
||||
memos: utils.parseMemos(tx),
|
||||
owner: tx.Owner,
|
||||
escrowSequence: tx.OfferSequence
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = parseEscrowCancellation
|
||||
23
src/ledger/parse/escrow-creation.js
Normal file
23
src/ledger/parse/escrow-creation.js
Normal file
@@ -0,0 +1,23 @@
|
||||
/* @flow */
|
||||
'use strict' // eslint-disable-line strict
|
||||
const _ = require('lodash')
|
||||
const assert = require('assert')
|
||||
const utils = require('./utils')
|
||||
const parseAmount = require('./amount')
|
||||
|
||||
function parseEscrowCreation(tx: Object): Object {
|
||||
assert(tx.TransactionType === 'EscrowCreate')
|
||||
|
||||
return utils.removeUndefined({
|
||||
amount: parseAmount(tx.Amount).value,
|
||||
destination: tx.Destination,
|
||||
memos: utils.parseMemos(tx),
|
||||
condition: tx.Condition,
|
||||
allowCancelAfter: utils.parseTimestamp(tx.CancelAfter),
|
||||
allowExecuteAfter: utils.parseTimestamp(tx.FinishAfter),
|
||||
sourceTag: tx.SourceTag,
|
||||
destinationTag: tx.DestinationTag
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = parseEscrowCreation
|
||||
18
src/ledger/parse/escrow-execution.js
Normal file
18
src/ledger/parse/escrow-execution.js
Normal file
@@ -0,0 +1,18 @@
|
||||
/* @flow */
|
||||
'use strict' // eslint-disable-line strict
|
||||
const assert = require('assert')
|
||||
const utils = require('./utils')
|
||||
|
||||
function parseEscrowExecution(tx: Object): Object {
|
||||
assert(tx.TransactionType === 'EscrowFinish')
|
||||
|
||||
return utils.removeUndefined({
|
||||
memos: utils.parseMemos(tx),
|
||||
owner: tx.Owner,
|
||||
escrowSequence: tx.OfferSequence,
|
||||
condition: tx.Condition,
|
||||
fulfillment: tx.Fulfillment
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = parseEscrowExecution
|
||||
@@ -1,15 +1,15 @@
|
||||
'use strict'; // eslint-disable-line strict
|
||||
const BigNumber = require('bignumber.js');
|
||||
const {dropsToXrp} = require('./utils');
|
||||
'use strict' // eslint-disable-line strict
|
||||
const BigNumber = require('bignumber.js')
|
||||
const {dropsToXrp} = require('./utils')
|
||||
|
||||
function parseFeeUpdate(tx: Object) {
|
||||
const baseFeeDrops = (new BigNumber(tx.BaseFee, 16)).toString();
|
||||
const baseFeeDrops = (new BigNumber(tx.BaseFee, 16)).toString()
|
||||
return {
|
||||
baseFeeXRP: dropsToXrp(baseFeeDrops),
|
||||
referenceFeeUnits: tx.ReferenceFeeUnits,
|
||||
reserveBaseXRP: dropsToXrp(tx.ReserveBase),
|
||||
reserveIncrementXRP: dropsToXrp(tx.ReserveIncrement)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = parseFeeUpdate;
|
||||
module.exports = parseFeeUpdate
|
||||
|
||||
@@ -1,49 +1,49 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const BigNumber = require('bignumber.js');
|
||||
const AccountFields = require('./utils').constants.AccountFields;
|
||||
'use strict' // eslint-disable-line strict
|
||||
const _ = require('lodash')
|
||||
const BigNumber = require('bignumber.js')
|
||||
const AccountFields = require('./utils').constants.AccountFields
|
||||
|
||||
function parseField(info, value) {
|
||||
if (info.encoding === 'hex' && !info.length) { // e.g. "domain"
|
||||
return new Buffer(value, 'hex').toString('ascii');
|
||||
return new Buffer(value, 'hex').toString('ascii')
|
||||
}
|
||||
if (info.shift) {
|
||||
return (new BigNumber(value)).shift(-info.shift).toNumber();
|
||||
return (new BigNumber(value)).shift(-info.shift).toNumber()
|
||||
}
|
||||
return value;
|
||||
return value
|
||||
}
|
||||
|
||||
function parseFields(data: Object): Object {
|
||||
const settings = {};
|
||||
const settings = {}
|
||||
for (const fieldName in AccountFields) {
|
||||
const fieldValue = data[fieldName];
|
||||
const fieldValue = data[fieldName]
|
||||
if (fieldValue !== undefined) {
|
||||
const info = AccountFields[fieldName];
|
||||
settings[info.name] = parseField(info, fieldValue);
|
||||
const info = AccountFields[fieldName]
|
||||
settings[info.name] = parseField(info, fieldValue)
|
||||
}
|
||||
}
|
||||
|
||||
if (data.RegularKey) {
|
||||
settings.regularKey = data.RegularKey;
|
||||
settings.regularKey = data.RegularKey
|
||||
}
|
||||
|
||||
// TODO: this isn't implemented in rippled yet, may have to change this later
|
||||
if (data.SignerQuorum || data.SignerEntries) {
|
||||
settings.signers = {};
|
||||
settings.signers = {}
|
||||
if (data.SignerQuorum) {
|
||||
settings.signers.threshold = data.SignerQuorum;
|
||||
settings.signers.threshold = data.SignerQuorum
|
||||
}
|
||||
if (data.SignerEntries) {
|
||||
settings.signers.weights = _.map(data.SignerEntries, entry => {
|
||||
return {
|
||||
address: entry.SignerEntry.Account,
|
||||
weight: entry.SignerEntry.SignerWeight
|
||||
};
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
return settings;
|
||||
return settings
|
||||
}
|
||||
|
||||
module.exports = parseFields;
|
||||
module.exports = parseFields
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
'use strict';
|
||||
'use strict' // eslint-disable-line strict
|
||||
|
||||
const orderFlags = {
|
||||
Passive: 0x00010000,
|
||||
Sell: 0x00020000 // offer was placed as a sell
|
||||
};
|
||||
}
|
||||
|
||||
const trustlineFlags = {
|
||||
LowReserve: 0x00010000, // entry counts toward reserve
|
||||
@@ -14,9 +14,9 @@ const trustlineFlags = {
|
||||
HighNoRipple: 0x00200000,
|
||||
LowFreeze: 0x00400000,
|
||||
HighFreeze: 0x00800000
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
orderFlags,
|
||||
trustlineFlags
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,46 +1,48 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const {removeUndefined, rippleTimeToISO8601} = require('./utils');
|
||||
const parseTransaction = require('./transaction');
|
||||
import type {GetLedger} from '../types.js';
|
||||
'use strict' // eslint-disable-line strict
|
||||
const _ = require('lodash')
|
||||
const {removeUndefined, rippleTimeToISO8601} = require('./utils')
|
||||
const parseTransaction = require('./transaction')
|
||||
import type {GetLedger} from '../types.js'
|
||||
|
||||
function parseTransactionWrapper(ledgerVersion, tx) {
|
||||
const transaction = _.assign({}, _.omit(tx, 'metaData'),
|
||||
{meta: tx.metaData});
|
||||
const result = parseTransaction(transaction);
|
||||
const transaction = _.assign({}, _.omit(tx, 'metaData'), {
|
||||
meta: tx.metaData,
|
||||
ledger_index: ledgerVersion
|
||||
})
|
||||
const result = parseTransaction(transaction)
|
||||
if (!result.outcome.ledgerVersion) {
|
||||
result.outcome.ledgerVersion = ledgerVersion;
|
||||
result.outcome.ledgerVersion = ledgerVersion
|
||||
}
|
||||
return result;
|
||||
return result
|
||||
}
|
||||
|
||||
function parseTransactions(transactions, ledgerVersion) {
|
||||
if (_.isEmpty(transactions)) {
|
||||
return {};
|
||||
return {}
|
||||
}
|
||||
if (_.isString(transactions[0])) {
|
||||
return {transactionHashes: transactions};
|
||||
return {transactionHashes: transactions}
|
||||
}
|
||||
return {
|
||||
transactions: _.map(transactions,
|
||||
_.partial(parseTransactionWrapper, ledgerVersion)),
|
||||
rawTransactions: JSON.stringify(transactions)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function parseState(state) {
|
||||
if (_.isEmpty(state)) {
|
||||
return {};
|
||||
return {}
|
||||
}
|
||||
if (_.isString(state[0])) {
|
||||
return {stateHashes: state};
|
||||
return {stateHashes: state}
|
||||
}
|
||||
return {rawState: JSON.stringify(state)};
|
||||
return {rawState: JSON.stringify(state)}
|
||||
}
|
||||
|
||||
function parseLedger(ledger: Object): GetLedger {
|
||||
const ledgerVersion = parseInt(ledger.ledger_index || ledger.seqNum, 10);
|
||||
const ledgerVersion = parseInt(ledger.ledger_index || ledger.seqNum, 10)
|
||||
return removeUndefined(_.assign({
|
||||
stateHash: ledger.account_hash,
|
||||
closeTime: rippleTimeToISO8601(ledger.close_time),
|
||||
@@ -55,7 +57,7 @@ function parseLedger(ledger: Object): GetLedger {
|
||||
},
|
||||
parseTransactions(ledger.transactions, ledgerVersion),
|
||||
parseState(ledger.accountState)
|
||||
));
|
||||
))
|
||||
}
|
||||
|
||||
module.exports = parseLedger;
|
||||
module.exports = parseLedger
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const assert = require('assert');
|
||||
const utils = require('./utils');
|
||||
const parseAmount = require('./amount');
|
||||
const flags = utils.txFlags.OfferCreate;
|
||||
'use strict' // eslint-disable-line strict
|
||||
const assert = require('assert')
|
||||
const utils = require('./utils')
|
||||
const parseAmount = require('./amount')
|
||||
const flags = utils.txFlags.OfferCreate
|
||||
|
||||
function parseOrder(tx: Object): Object {
|
||||
assert(tx.TransactionType === 'OfferCreate');
|
||||
assert(tx.TransactionType === 'OfferCreate')
|
||||
|
||||
const direction = (tx.Flags & flags.Sell) === 0 ? 'buy' : 'sell';
|
||||
const takerGetsAmount = parseAmount(tx.TakerGets);
|
||||
const takerPaysAmount = parseAmount(tx.TakerPays);
|
||||
const quantity = (direction === 'buy') ? takerPaysAmount : takerGetsAmount;
|
||||
const totalPrice = (direction === 'buy') ? takerGetsAmount : takerPaysAmount;
|
||||
const direction = (tx.Flags & flags.Sell) === 0 ? 'buy' : 'sell'
|
||||
const takerGetsAmount = parseAmount(tx.TakerGets)
|
||||
const takerPaysAmount = parseAmount(tx.TakerPays)
|
||||
const quantity = (direction === 'buy') ? takerPaysAmount : takerGetsAmount
|
||||
const totalPrice = (direction === 'buy') ? takerGetsAmount : takerPaysAmount
|
||||
|
||||
return utils.removeUndefined({
|
||||
direction: direction,
|
||||
@@ -23,7 +23,7 @@ function parseOrder(tx: Object): Object {
|
||||
|| undefined,
|
||||
fillOrKill: ((tx.Flags & flags.FillOrKill) !== 0) || undefined,
|
||||
expirationTime: utils.parseTimestamp(tx.Expiration)
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = parseOrder;
|
||||
module.exports = parseOrder
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const utils = require('./utils');
|
||||
const flags = require('./flags').orderFlags;
|
||||
const parseAmount = require('./amount');
|
||||
'use strict' // eslint-disable-line strict
|
||||
const _ = require('lodash')
|
||||
const utils = require('./utils')
|
||||
const flags = require('./flags').orderFlags
|
||||
const parseAmount = require('./amount')
|
||||
|
||||
function parseOrderbookOrder(order: Object): Object {
|
||||
const direction = (order.Flags & flags.Sell) === 0 ? 'buy' : 'sell';
|
||||
const takerGetsAmount = parseAmount(order.TakerGets);
|
||||
const takerPaysAmount = parseAmount(order.TakerPays);
|
||||
const quantity = (direction === 'buy') ? takerPaysAmount : takerGetsAmount;
|
||||
const totalPrice = (direction === 'buy') ? takerGetsAmount : takerPaysAmount;
|
||||
const direction = (order.Flags & flags.Sell) === 0 ? 'buy' : 'sell'
|
||||
const takerGetsAmount = parseAmount(order.TakerGets)
|
||||
const takerPaysAmount = parseAmount(order.TakerPays)
|
||||
const quantity = (direction === 'buy') ? takerPaysAmount : takerGetsAmount
|
||||
const totalPrice = (direction === 'buy') ? takerGetsAmount : takerPaysAmount
|
||||
|
||||
// note: immediateOrCancel and fillOrKill orders cannot enter the order book
|
||||
// so we can omit those flags here
|
||||
@@ -20,25 +20,25 @@ function parseOrderbookOrder(order: Object): Object {
|
||||
totalPrice: totalPrice,
|
||||
passive: ((order.Flags & flags.Passive) !== 0) || undefined,
|
||||
expirationTime: utils.parseTimestamp(order.Expiration)
|
||||
});
|
||||
})
|
||||
|
||||
const properties = {
|
||||
maker: order.Account,
|
||||
sequence: order.Sequence,
|
||||
makerExchangeRate: utils.adjustQualityForXRP(order.quality,
|
||||
takerGetsAmount.currency, takerPaysAmount.currency)
|
||||
};
|
||||
}
|
||||
|
||||
const takerGetsFunded = order.taker_gets_funded ?
|
||||
parseAmount(order.taker_gets_funded) : undefined;
|
||||
parseAmount(order.taker_gets_funded) : undefined
|
||||
const takerPaysFunded = order.taker_pays_funded ?
|
||||
parseAmount(order.taker_pays_funded) : undefined;
|
||||
parseAmount(order.taker_pays_funded) : undefined
|
||||
const available = utils.removeUndefined({
|
||||
fundedAmount: takerGetsFunded,
|
||||
priceOfFundedAmount: takerPaysFunded
|
||||
});
|
||||
const state = _.isEmpty(available) ? undefined : available;
|
||||
return utils.removeUndefined({specification, properties, state});
|
||||
})
|
||||
const state = _.isEmpty(available) ? undefined : available
|
||||
return utils.removeUndefined({specification, properties, state})
|
||||
}
|
||||
|
||||
module.exports = parseOrderbookOrder;
|
||||
module.exports = parseOrderbookOrder
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const parseAmount = require('./amount');
|
||||
import type {Amount, RippledAmount} from '../../common/types.js';
|
||||
import type {GetPaths, RippledPathsResponse} from '../pathfind-types.js';
|
||||
'use strict' // eslint-disable-line strict
|
||||
const _ = require('lodash')
|
||||
const parseAmount = require('./amount')
|
||||
import type {Amount, RippledAmount} from '../../common/types.js'
|
||||
import type {GetPaths, RippledPathsResponse} from '../pathfind-types.js'
|
||||
|
||||
function parsePaths(paths) {
|
||||
return paths.map(steps => steps.map(step =>
|
||||
_.omit(step, ['type', 'type_hex'])));
|
||||
_.omit(step, ['type', 'type_hex'])))
|
||||
}
|
||||
|
||||
function removeAnyCounterpartyEncoding(address: string, amount: Amount) {
|
||||
return amount.counterparty === address ?
|
||||
_.omit(amount, 'counterparty') : amount;
|
||||
_.omit(amount, 'counterparty') : amount
|
||||
}
|
||||
|
||||
function createAdjustment(address: string, adjustmentWithoutAddress: Object) {
|
||||
const amountKey = _.keys(adjustmentWithoutAddress)[0];
|
||||
const amount = adjustmentWithoutAddress[amountKey];
|
||||
const amountKey = _.keys(adjustmentWithoutAddress)[0]
|
||||
const amount = adjustmentWithoutAddress[amountKey]
|
||||
return _.set({address: address}, amountKey,
|
||||
removeAnyCounterpartyEncoding(address, amount));
|
||||
removeAnyCounterpartyEncoding(address, amount))
|
||||
}
|
||||
|
||||
function parseAlternative(sourceAddress: string, destinationAddress: string,
|
||||
@@ -31,21 +31,21 @@ function parseAlternative(sourceAddress: string, destinationAddress: string,
|
||||
{source: {amount: parseAmount(alternative.source_amount)},
|
||||
destination: {minAmount: parseAmount(alternative.destination_amount)}} :
|
||||
{source: {maxAmount: parseAmount(alternative.source_amount)},
|
||||
destination: {amount: parseAmount(destinationAmount)}};
|
||||
destination: {amount: parseAmount(destinationAmount)}}
|
||||
|
||||
return {
|
||||
source: createAdjustment(sourceAddress, amounts.source),
|
||||
destination: createAdjustment(destinationAddress, amounts.destination),
|
||||
paths: JSON.stringify(parsePaths(alternative.paths_computed))
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function parsePathfind(pathfindResult: RippledPathsResponse): GetPaths {
|
||||
const sourceAddress = pathfindResult.source_account;
|
||||
const destinationAddress = pathfindResult.destination_account;
|
||||
const destinationAmount = pathfindResult.destination_amount;
|
||||
const sourceAddress = pathfindResult.source_account
|
||||
const destinationAddress = pathfindResult.destination_account
|
||||
const destinationAmount = pathfindResult.destination_amount
|
||||
return pathfindResult.alternatives.map(_.partial(parseAlternative,
|
||||
sourceAddress, destinationAddress, destinationAmount));
|
||||
sourceAddress, destinationAddress, destinationAmount))
|
||||
}
|
||||
|
||||
module.exports = parsePathfind;
|
||||
module.exports = parsePathfind
|
||||
|
||||
22
src/ledger/parse/payment-channel-claim.js
Normal file
22
src/ledger/parse/payment-channel-claim.js
Normal file
@@ -0,0 +1,22 @@
|
||||
/* @flow */
|
||||
'use strict' // eslint-disable-line strict
|
||||
const assert = require('assert')
|
||||
const utils = require('./utils')
|
||||
const parseAmount = require('./amount')
|
||||
const claimFlags = utils.txFlags.PaymentChannelClaim
|
||||
|
||||
function parsePaymentChannelClaim(tx: Object): Object {
|
||||
assert(tx.TransactionType === 'PaymentChannelClaim')
|
||||
|
||||
return utils.removeUndefined({
|
||||
channel: tx.Channel,
|
||||
balance: tx.Balance && parseAmount(tx.Balance).value,
|
||||
amount: tx.Amount && parseAmount(tx.Amount).value,
|
||||
signature: tx.Signature,
|
||||
publicKey: tx.PublicKey,
|
||||
renew: Boolean(tx.Flags & claimFlags.Renew) || undefined,
|
||||
close: Boolean(tx.Flags & claimFlags.Close) || undefined
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = parsePaymentChannelClaim
|
||||
21
src/ledger/parse/payment-channel-create.js
Normal file
21
src/ledger/parse/payment-channel-create.js
Normal file
@@ -0,0 +1,21 @@
|
||||
/* @flow */
|
||||
'use strict' // eslint-disable-line strict
|
||||
const assert = require('assert')
|
||||
const utils = require('./utils')
|
||||
const parseAmount = require('./amount')
|
||||
|
||||
function parsePaymentChannelCreate(tx: Object): Object {
|
||||
assert(tx.TransactionType === 'PaymentChannelCreate')
|
||||
|
||||
return utils.removeUndefined({
|
||||
amount: parseAmount(tx.Amount).value,
|
||||
destination: tx.Destination,
|
||||
settleDelay: tx.SettleDelay,
|
||||
publicKey: tx.PublicKey,
|
||||
cancelAfter: tx.CancelAfter && utils.parseTimestamp(tx.CancelAfter),
|
||||
sourceTag: tx.SourceTag,
|
||||
destinationTag: tx.DestinationTag
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = parsePaymentChannelCreate
|
||||
17
src/ledger/parse/payment-channel-fund.js
Normal file
17
src/ledger/parse/payment-channel-fund.js
Normal file
@@ -0,0 +1,17 @@
|
||||
/* @flow */
|
||||
'use strict' // eslint-disable-line strict
|
||||
const assert = require('assert')
|
||||
const utils = require('./utils')
|
||||
const parseAmount = require('./amount')
|
||||
|
||||
function parsePaymentChannelFund(tx: Object): Object {
|
||||
assert(tx.TransactionType === 'PaymentChannelFund')
|
||||
|
||||
return utils.removeUndefined({
|
||||
channel: tx.Channel,
|
||||
amount: parseAmount(tx.Amount).value,
|
||||
expiration: tx.Expiration && utils.parseTimestamp(tx.Expiration)
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = parsePaymentChannelFund
|
||||
37
src/ledger/parse/payment-channel.js
Normal file
37
src/ledger/parse/payment-channel.js
Normal file
@@ -0,0 +1,37 @@
|
||||
/* @flow */
|
||||
'use strict' // eslint-disable-line strict
|
||||
const _ = require('lodash')
|
||||
const utils = require('./utils')
|
||||
|
||||
type PaymentChannelResponse = {
|
||||
account: string,
|
||||
balance: string,
|
||||
publicKey: number,
|
||||
destination: string,
|
||||
settleDelay: number,
|
||||
expiration?: number,
|
||||
cancelAfter?: number,
|
||||
sourceTag?: number,
|
||||
destinationTag?: number,
|
||||
previousAffectingTransactionID: string,
|
||||
previousAffectingTransactionLedgerVersion: number
|
||||
}
|
||||
|
||||
function parsePaymentChannel(data: Object): PaymentChannelResponse {
|
||||
return utils.removeUndefined({
|
||||
account: data.Account,
|
||||
amount: utils.dropsToXrp(data.Amount),
|
||||
balance: utils.dropsToXrp(data.Balance),
|
||||
destination: data.Destination,
|
||||
publicKey: data.PublicKey,
|
||||
settleDelay: data.SettleDelay,
|
||||
expiration: utils.parseTimestamp(data.Expiration),
|
||||
cancelAfter: utils.parseTimestamp(data.CancelAfter),
|
||||
sourceTag: data.SourceTag,
|
||||
destinationTag: data.DestinationTag,
|
||||
previousAffectingTransactionID: data.PreviousTxnID,
|
||||
previousAffectingTransactionLedgerVersion: data.PreviousTxnLgrSeq
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = parsePaymentChannel
|
||||
@@ -1,39 +1,39 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const assert = require('assert');
|
||||
const utils = require('./utils');
|
||||
const parseAmount = require('./amount');
|
||||
const txFlags = utils.txFlags;
|
||||
'use strict' // eslint-disable-line strict
|
||||
const _ = require('lodash')
|
||||
const assert = require('assert')
|
||||
const utils = require('./utils')
|
||||
const parseAmount = require('./amount')
|
||||
const txFlags = utils.txFlags
|
||||
|
||||
function isNoDirectRipple(tx) {
|
||||
return (tx.Flags & txFlags.Payment.NoRippleDirect) !== 0;
|
||||
return (tx.Flags & txFlags.Payment.NoRippleDirect) !== 0
|
||||
}
|
||||
|
||||
function isQualityLimited(tx) {
|
||||
return (tx.Flags & txFlags.Payment.LimitQuality) !== 0;
|
||||
return (tx.Flags & txFlags.Payment.LimitQuality) !== 0
|
||||
}
|
||||
|
||||
function removeGenericCounterparty(amount, address) {
|
||||
return amount.counterparty === address ?
|
||||
_.omit(amount, 'counterparty') : amount;
|
||||
_.omit(amount, 'counterparty') : amount
|
||||
}
|
||||
|
||||
function parsePayment(tx: Object): Object {
|
||||
assert(tx.TransactionType === 'Payment');
|
||||
assert(tx.TransactionType === 'Payment')
|
||||
|
||||
const source = {
|
||||
address: tx.Account,
|
||||
maxAmount: removeGenericCounterparty(
|
||||
parseAmount(tx.SendMax || tx.Amount), tx.Account),
|
||||
tag: tx.SourceTag
|
||||
};
|
||||
}
|
||||
|
||||
const destination = {
|
||||
address: tx.Destination,
|
||||
amount: removeGenericCounterparty(parseAmount(tx.Amount), tx.Destination),
|
||||
tag: tx.DestinationTag
|
||||
};
|
||||
}
|
||||
|
||||
return utils.removeUndefined({
|
||||
source: utils.removeUndefined(source),
|
||||
@@ -44,7 +44,7 @@ function parsePayment(tx: Object): Object {
|
||||
allowPartialPayment: utils.isPartialPayment(tx) || undefined,
|
||||
noDirectRipple: isNoDirectRipple(tx) || undefined,
|
||||
limitQuality: isQualityLimited(tx) || undefined
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = parsePayment;
|
||||
module.exports = parsePayment
|
||||
|
||||
@@ -1,61 +1,61 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const assert = require('assert');
|
||||
const AccountFlags = require('./utils').constants.AccountFlags;
|
||||
const parseFields = require('./fields');
|
||||
'use strict' // eslint-disable-line strict
|
||||
const _ = require('lodash')
|
||||
const assert = require('assert')
|
||||
const AccountFlags = require('./utils').constants.AccountFlags
|
||||
const parseFields = require('./fields')
|
||||
|
||||
function getAccountRootModifiedNode(tx: Object) {
|
||||
const modifiedNodes = tx.meta.AffectedNodes.filter(node =>
|
||||
node.ModifiedNode.LedgerEntryType === 'AccountRoot');
|
||||
assert(modifiedNodes.length === 1);
|
||||
return modifiedNodes[0].ModifiedNode;
|
||||
node.ModifiedNode.LedgerEntryType === 'AccountRoot')
|
||||
assert(modifiedNodes.length === 1)
|
||||
return modifiedNodes[0].ModifiedNode
|
||||
}
|
||||
|
||||
function parseFlags(tx: Object) {
|
||||
const settings = {};
|
||||
const settings = {}
|
||||
if (tx.TransactionType !== 'AccountSet') {
|
||||
return settings;
|
||||
return settings
|
||||
}
|
||||
|
||||
const node = getAccountRootModifiedNode(tx);
|
||||
const oldFlags = _.get(node.PreviousFields, 'Flags');
|
||||
const newFlags = _.get(node.FinalFields, 'Flags');
|
||||
const node = getAccountRootModifiedNode(tx)
|
||||
const oldFlags = _.get(node.PreviousFields, 'Flags')
|
||||
const newFlags = _.get(node.FinalFields, 'Flags')
|
||||
|
||||
if (oldFlags !== undefined && newFlags !== undefined) {
|
||||
const changedFlags = oldFlags ^ newFlags;
|
||||
const setFlags = newFlags & changedFlags;
|
||||
const clearedFlags = oldFlags & changedFlags;
|
||||
const changedFlags = oldFlags ^ newFlags
|
||||
const setFlags = newFlags & changedFlags
|
||||
const clearedFlags = oldFlags & changedFlags
|
||||
_.forEach(AccountFlags, (flagValue, flagName) => {
|
||||
if (setFlags & flagValue) {
|
||||
settings[flagName] = true;
|
||||
settings[flagName] = true
|
||||
} else if (clearedFlags & flagValue) {
|
||||
settings[flagName] = false;
|
||||
settings[flagName] = false
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
// enableTransactionIDTracking requires a special case because it
|
||||
// does not affect the Flags field; instead it adds/removes a field called
|
||||
// "AccountTxnID" to/from the account root.
|
||||
|
||||
const oldField = _.get(node.PreviousFields, 'AccountTxnID');
|
||||
const newField = _.get(node.FinalFields, 'AccountTxnID');
|
||||
const oldField = _.get(node.PreviousFields, 'AccountTxnID')
|
||||
const newField = _.get(node.FinalFields, 'AccountTxnID')
|
||||
if (newField && !oldField) {
|
||||
settings.enableTransactionIDTracking = true;
|
||||
settings.enableTransactionIDTracking = true
|
||||
} else if (oldField && !newField) {
|
||||
settings.enableTransactionIDTracking = false;
|
||||
settings.enableTransactionIDTracking = false
|
||||
}
|
||||
|
||||
return settings;
|
||||
return settings
|
||||
}
|
||||
|
||||
function parseSettings(tx: Object) {
|
||||
const txType = tx.TransactionType;
|
||||
const txType = tx.TransactionType
|
||||
assert(txType === 'AccountSet' || txType === 'SetRegularKey' ||
|
||||
txType === 'SignerListSet');
|
||||
txType === 'SignerListSet')
|
||||
|
||||
return _.assign({}, parseFlags(tx), parseFields(tx));
|
||||
return _.assign({}, parseFlags(tx), parseFields(tx))
|
||||
}
|
||||
|
||||
module.exports = parseSettings;
|
||||
module.exports = parseSettings
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const assert = require('assert');
|
||||
const utils = require('./utils');
|
||||
|
||||
function parseSuspendedPaymentCancellation(tx: Object): Object {
|
||||
assert(tx.TransactionType === 'SuspendedPaymentCancel');
|
||||
|
||||
return utils.removeUndefined({
|
||||
memos: utils.parseMemos(tx),
|
||||
owner: tx.Owner,
|
||||
suspensionSequence: tx.OfferSequence
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = parseSuspendedPaymentCancellation;
|
||||
@@ -1,39 +0,0 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const assert = require('assert');
|
||||
const utils = require('./utils');
|
||||
const parseAmount = require('./amount');
|
||||
|
||||
function removeGenericCounterparty(amount, address) {
|
||||
return amount.counterparty === address ?
|
||||
_.omit(amount, 'counterparty') : amount;
|
||||
}
|
||||
|
||||
function parseSuspendedPaymentCreation(tx: Object): Object {
|
||||
assert(tx.TransactionType === 'SuspendedPaymentCreate');
|
||||
|
||||
const source = {
|
||||
address: tx.Account,
|
||||
maxAmount: removeGenericCounterparty(
|
||||
parseAmount(tx.SendMax || tx.Amount), tx.Account),
|
||||
tag: tx.SourceTag
|
||||
};
|
||||
|
||||
const destination = {
|
||||
address: tx.Destination,
|
||||
amount: removeGenericCounterparty(parseAmount(tx.Amount), tx.Destination),
|
||||
tag: tx.DestinationTag
|
||||
};
|
||||
|
||||
return utils.removeUndefined({
|
||||
source: utils.removeUndefined(source),
|
||||
destination: utils.removeUndefined(destination),
|
||||
memos: utils.parseMemos(tx),
|
||||
digest: tx.Digest,
|
||||
allowCancelAfter: utils.parseTimestamp(tx.CancelAfter),
|
||||
allowExecuteAfter: utils.parseTimestamp(tx.FinishAfter)
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = parseSuspendedPaymentCreation;
|
||||
@@ -1,19 +0,0 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const assert = require('assert');
|
||||
const utils = require('./utils');
|
||||
|
||||
function parseSuspendedPaymentExecution(tx: Object): Object {
|
||||
assert(tx.TransactionType === 'SuspendedPaymentFinish');
|
||||
|
||||
return utils.removeUndefined({
|
||||
memos: utils.parseMemos(tx),
|
||||
owner: tx.Owner,
|
||||
suspensionSequence: tx.OfferSequence,
|
||||
method: tx.Method,
|
||||
digest: tx.Digest,
|
||||
proof: tx.Proof ? utils.hexToString(tx.Proof) : undefined
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = parseSuspendedPaymentExecution;
|
||||
@@ -1,18 +1,20 @@
|
||||
/* @flow */
|
||||
'use strict'; // eslint-disable-line strict
|
||||
const assert = require('assert');
|
||||
const utils = require('./utils');
|
||||
const parsePayment = require('./payment');
|
||||
const parseTrustline = require('./trustline');
|
||||
const parseOrder = require('./order');
|
||||
const parseOrderCancellation = require('./cancellation');
|
||||
const parseSettings = require('./settings');
|
||||
const parseSuspendedPaymentCreation = require('./suspended-payment-creation');
|
||||
const parseSuspendedPaymentExecution = require('./suspended-payment-execution');
|
||||
const parseSuspendedPaymentCancellation =
|
||||
require('./suspended-payment-cancellation');
|
||||
const parseFeeUpdate = require('./fee-update');
|
||||
const parseAmendment = require('./amendment');
|
||||
'use strict' // eslint-disable-line strict
|
||||
const assert = require('assert')
|
||||
const utils = require('./utils')
|
||||
const parsePayment = require('./payment')
|
||||
const parseTrustline = require('./trustline')
|
||||
const parseOrder = require('./order')
|
||||
const parseOrderCancellation = require('./cancellation')
|
||||
const parseSettings = require('./settings')
|
||||
const parseEscrowCreation = require('./escrow-creation')
|
||||
const parseEscrowExecution = require('./escrow-execution')
|
||||
const parseEscrowCancellation = require('./escrow-cancellation')
|
||||
const parsePaymentChannelCreate = require('./payment-channel-create')
|
||||
const parsePaymentChannelFund = require('./payment-channel-fund')
|
||||
const parsePaymentChannelClaim = require('./payment-channel-claim')
|
||||
const parseFeeUpdate = require('./fee-update')
|
||||
const parseAmendment = require('./amendment')
|
||||
|
||||
function parseTransactionType(type) {
|
||||
const mapping = {
|
||||
@@ -22,34 +24,40 @@ function parseTransactionType(type) {
|
||||
OfferCancel: 'orderCancellation',
|
||||
AccountSet: 'settings',
|
||||
SetRegularKey: 'settings',
|
||||
SuspendedPaymentCreate: 'suspendedPaymentCreation',
|
||||
SuspendedPaymentFinish: 'suspendedPaymentExecution',
|
||||
SuspendedPaymentCancel: 'suspendedPaymentCancellation',
|
||||
EscrowCreate: 'escrowCreation',
|
||||
EscrowFinish: 'escrowExecution',
|
||||
EscrowCancel: 'escrowCancellation',
|
||||
PaymentChannelCreate: 'paymentChannelCreate',
|
||||
PaymentChannelFund: 'paymentChannelFund',
|
||||
PaymentChannelClaim: 'paymentChannelClaim',
|
||||
SignerListSet: 'settings',
|
||||
SetFee: 'feeUpdate', // pseudo-transaction
|
||||
EnableAmendment: 'amendment' // pseudo-transaction
|
||||
};
|
||||
return mapping[type] || null;
|
||||
}
|
||||
return mapping[type] || null
|
||||
}
|
||||
|
||||
function parseTransaction(tx: Object): Object {
|
||||
const type = parseTransactionType(tx.TransactionType);
|
||||
const type = parseTransactionType(tx.TransactionType)
|
||||
const mapping = {
|
||||
'payment': parsePayment,
|
||||
'trustline': parseTrustline,
|
||||
'order': parseOrder,
|
||||
'orderCancellation': parseOrderCancellation,
|
||||
'settings': parseSettings,
|
||||
'suspendedPaymentCreation': parseSuspendedPaymentCreation,
|
||||
'suspendedPaymentExecution': parseSuspendedPaymentExecution,
|
||||
'suspendedPaymentCancellation': parseSuspendedPaymentCancellation,
|
||||
'escrowCreation': parseEscrowCreation,
|
||||
'escrowExecution': parseEscrowExecution,
|
||||
'escrowCancellation': parseEscrowCancellation,
|
||||
'paymentChannelCreate': parsePaymentChannelCreate,
|
||||
'paymentChannelFund': parsePaymentChannelFund,
|
||||
'paymentChannelClaim': parsePaymentChannelClaim,
|
||||
'feeUpdate': parseFeeUpdate,
|
||||
'amendment': parseAmendment
|
||||
};
|
||||
const parser = mapping[type];
|
||||
assert(parser !== undefined, 'Unrecognized transaction type');
|
||||
const specification = parser(tx);
|
||||
const outcome = utils.parseOutcome(tx);
|
||||
}
|
||||
const parser = mapping[type]
|
||||
assert(parser !== undefined, 'Unrecognized transaction type')
|
||||
const specification = parser(tx)
|
||||
const outcome = utils.parseOutcome(tx)
|
||||
return utils.removeUndefined({
|
||||
type: type,
|
||||
address: tx.Account,
|
||||
@@ -57,7 +65,7 @@ function parseTransaction(tx: Object): Object {
|
||||
id: tx.hash,
|
||||
specification: utils.removeUndefined(specification),
|
||||
outcome: outcome ? utils.removeUndefined(outcome) : undefined
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = parseTransaction;
|
||||
module.exports = parseTransaction
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const assert = require('assert');
|
||||
const utils = require('./utils');
|
||||
const flags = utils.txFlags.TrustSet;
|
||||
'use strict' // eslint-disable-line strict
|
||||
const assert = require('assert')
|
||||
const utils = require('./utils')
|
||||
const flags = utils.txFlags.TrustSet
|
||||
|
||||
function parseFlag(flagsValue, trueValue, falseValue) {
|
||||
if (flagsValue & trueValue) {
|
||||
return true;
|
||||
return true
|
||||
}
|
||||
if (flagsValue & falseValue) {
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
return undefined;
|
||||
return undefined
|
||||
}
|
||||
|
||||
function parseTrustline(tx: Object): Object {
|
||||
assert(tx.TransactionType === 'TrustSet');
|
||||
assert(tx.TransactionType === 'TrustSet')
|
||||
|
||||
return utils.removeUndefined({
|
||||
limit: tx.LimitAmount.value,
|
||||
@@ -27,7 +27,7 @@ function parseTrustline(tx: Object): Object {
|
||||
tx.Flags, flags.SetNoRipple, flags.ClearNoRipple),
|
||||
frozen: parseFlag(tx.Flags, flags.SetFreeze, flags.ClearFreeze),
|
||||
authorized: parseFlag(tx.Flags, flags.SetAuth, 0)
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = parseTrustline;
|
||||
module.exports = parseTrustline
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user