Merge branch 'develop' into connection-cleanup-tests

This commit is contained in:
FKSRipple
2020-01-10 16:15:16 -08:00
committed by GitHub
30 changed files with 1571 additions and 963 deletions

View File

@@ -1,5 +1,25 @@
# ripple-lib Release History # ripple-lib Release History
## 1.6.0 (2020-01-06)
* Add support for AccountDelete (#1120)
* Improve error type given on rejected message _send to be DisconnectedError (#1098)
* Internal
* Add unit test for unhandled promise rejection warning on message _send (#1098)
* Dependencies
* Update @types/node, @typescript-eslint/parser
## 1.5.1 (2019-12-28)
* Fix support for CDNs (#1142)
* Internal
* Clean up connection trace logic (#1114)
* Clean up the connection config (#1115)
* Run prettier format (#1116)
* Update eslint command (#1118)
* Dependencies
* Update webpack-cli, webpack, ts-node, @types/lodash, @types/ws, @types/node, @typescript-eslint/parser, @typescript-eslint/eslint-plugin, https-proxy-agent, mocha, eventemitter2
## 1.5.0 (2019-12-14) ## 1.5.0 (2019-12-14)
* Add support for `WalletLocator` (#1083) * Add support for `WalletLocator` (#1083)

View File

@@ -119,7 +119,6 @@ Using RippleAPI, you can:
This page contains documentation for ripple-lib. To use ripple-lib with npm/yarn, begin with the [Getting Started](https://github.com/ripple/ripple-lib#getting-started) steps. This page contains documentation for ripple-lib. To use ripple-lib with npm/yarn, begin with the [Getting Started](https://github.com/ripple/ripple-lib#getting-started) steps.
**What is ripple-lib used for?** Here's a [list of applications that use `ripple-lib`](https://github.com/ripple/ripple-lib/blob/develop/APPLICATIONS.md). Open a PR to add your app or project to the list! **What is ripple-lib used for?** Here's a [list of applications that use `ripple-lib`](https://github.com/ripple/ripple-lib/blob/develop/APPLICATIONS.md). Open a PR to add your app or project to the list!
## Boilerplate ## Boilerplate
Use the following [boilerplate code](https://en.wikipedia.org/wiki/Boilerplate_code) to wrap your custom code using RippleAPI. Use the following [boilerplate code](https://en.wikipedia.org/wiki/Boilerplate_code) to wrap your custom code using RippleAPI.
@@ -195,7 +194,6 @@ If you omit the `server` parameter, RippleAPI operates [offline](#offline-functi
After you have installed ripple-lib, you can create scripts using the [boilerplate](#boilerplate) and run them using the Node.js executable, typically named `node`: After you have installed ripple-lib, you can create scripts using the [boilerplate](#boilerplate) and run them using the Node.js executable, typically named `node`:
`node script.js` `node script.js`
## Offline functionality ## Offline functionality
RippleAPI can also function without internet connectivity. This can be useful in order to generate secrets and sign transactions from a secure, isolated machine. RippleAPI can also function without internet connectivity. This can be useful in order to generate secrets and sign transactions from a secure, isolated machine.
@@ -221,8 +219,8 @@ Methods that depend on the state of the XRP Ledger are unavailable in offline mo
* [prepareEscrowExecution](#prepareescrowexecution) * [prepareEscrowExecution](#prepareescrowexecution)
* [sign](#sign) * [sign](#sign)
* [generateAddress](#generateaddress) * [generateAddress](#generateaddress)
* [generateXAddress](#generatexaddress)
* [computeLedgerHash](#computeledgerhash) * [computeLedgerHash](#computeledgerhash)
# Basic Types # Basic Types
## Address ## Address
@@ -294,7 +292,6 @@ Name | Type | Description
currency | [currency](#currency) | The three-character code or hexadecimal string used to denote currencies, or "drops" for the smallest unit of XRP. currency | [currency](#currency) | The three-character code or hexadecimal string used to denote currencies, or "drops" for the smallest unit of XRP.
counterparty | [address](#address) | *Optional* The XRP Ledger address of the account that owes or is owed the funds (omitted if `currency` is "XRP" or "drops") counterparty | [address](#address) | *Optional* The XRP Ledger address of the account that owes or is owed the funds (omitted if `currency` is "XRP" or "drops")
value | [value](#value) | *Optional* The quantity of the currency, denoted as a string to retain floating point precision value | [value](#value) | *Optional* The quantity of the currency, denoted as a string to retain floating point precision
# Transaction Overview # Transaction Overview
## Transaction Types ## Transaction Types
@@ -381,7 +378,6 @@ Name | Type | Description
data | string | *Optional* Arbitrary string, conventionally containing the content of the memo. data | string | *Optional* Arbitrary string, conventionally containing the content of the memo.
format | string | *Optional* Conventionally containing information on how the memo is encoded, for example as a [MIME type](http://www.iana.org/assignments/media-types/media-types.xhtml). Only characters allowed in URLs are permitted. format | string | *Optional* Conventionally containing information on how the memo is encoded, for example as a [MIME type](http://www.iana.org/assignments/media-types/media-types.xhtml). Only characters allowed in URLs are permitted.
type | string | *Optional* Conventionally, a unique relation (according to [RFC 5988](http://tools.ietf.org/html/rfc5988#section-4)) that defines the format of this memo. Only characters allowed in URLs are permitted. type | string | *Optional* Conventionally, a unique relation (according to [RFC 5988](http://tools.ietf.org/html/rfc5988#section-4)) that defines the format of this memo. Only characters allowed in URLs are permitted.
# Transaction Specifications # Transaction Specifications
A *transaction specification* specifies what a transaction should do. Each [Transaction Type](#transaction-types) has its own type of specification. A *transaction specification* specifies what a transaction should do. Each [Transaction Type](#transaction-types) has its own type of specification.
@@ -792,7 +788,6 @@ signature | string | *Optional* Signed claim authorizing withdrawal of XRP from
} }
``` ```
# rippled APIs # rippled APIs
ripple-lib relies on [rippled APIs](https://ripple.com/build/rippled-apis/) for online functionality. In addition to ripple-lib's own methods, you can also access rippled APIs through ripple-lib. Use the `request()`, `hasNextPage()`, and `requestNextPage()` methods: ripple-lib relies on [rippled APIs](https://ripple.com/build/rippled-apis/) for online functionality. In addition to ripple-lib's own methods, you can also access rippled APIs through ripple-lib. Use the `request()`, `hasNextPage()`, and `requestNextPage()` methods:
@@ -834,6 +829,7 @@ Type | Description
`manifestReceived` | Sent by the `manifests` stream when the server receives a manifest. `manifestReceived` | Sent by the `manifests` stream when the server receives a manifest.
`transaction` | Sent by many subscriptions including `transactions`, `transactions_proposed`, `accounts`, `accounts_proposed`, and `book` (Order Book). See [Transaction Streams](https://ripple.com/build/rippled-apis/#transaction-streams) for details. `transaction` | Sent by many subscriptions including `transactions`, `transactions_proposed`, `accounts`, `accounts_proposed`, and `book` (Order Book). See [Transaction Streams](https://ripple.com/build/rippled-apis/#transaction-streams) for details.
`peerStatusChange` | (Admin-only) Reports a large amount of information on the activities of other `rippled` servers to which the server is connected. `peerStatusChange` | (Admin-only) Reports a large amount of information on the activities of other `rippled` servers to which the server is connected.
`path_find` | Asynchronous follow-up response to the currently open path\_find request. See [rippled path\_find method](https://xrpl.org/path_find.html) for details.
To register your listener function, use `connection.on(type, handler)`. To register your listener function, use `connection.on(type, handler)`.
@@ -864,7 +860,6 @@ api.connect().then(() => { // Omit this if you are already connected
The subscription ends when you unsubscribe or the WebSocket connection is closed. The subscription ends when you unsubscribe or the WebSocket connection is closed.
For full details, see [rippled Subscriptions](https://ripple.com/build/rippled-apis/#subscriptions). For full details, see [rippled Subscriptions](https://ripple.com/build/rippled-apis/#subscriptions).
## request ## request
`request(command: string, options: object): Promise<object>` `request(command: string, options: object): Promise<object>`
@@ -918,7 +913,6 @@ return api.request('ledger', {
} }
``` ```
## hasNextPage ## hasNextPage
`hasNextPage(currentResponse): boolean` `hasNextPage(currentResponse): boolean`
@@ -946,7 +940,6 @@ return api.request('ledger_data', {
} }
}).catch(console.error); }).catch(console.error);
``` ```
## requestNextPage ## requestNextPage
`requestNextPage(command: string, params: object = {}, currentResponse: object): Promise<object>` `requestNextPage(command: string, params: object = {}, currentResponse: object): Promise<object>`
@@ -977,9 +970,7 @@ return api.request(command, params).then(response => {
}).catch(console.error); }).catch(console.error);
``` ```
# Static Methods # Static Methods
## renameCounterpartyToIssuer ## renameCounterpartyToIssuer
`renameCounterpartyToIssuer(issue: {currency: string, counterparty: address}): {currency: string, issuer: address}` `renameCounterpartyToIssuer(issue: {currency: string, counterparty: address}): {currency: string, issuer: address}`
@@ -1017,7 +1008,6 @@ console.log(RippleAPI.renameCounterpartyToIssuer(orderbookInfo.counter))
{ currency: 'USD', issuer: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B' } { currency: 'USD', issuer: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B' }
{ currency: 'BTC', issuer: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B' } { currency: 'BTC', issuer: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B' }
``` ```
## formatBidsAndAsks ## formatBidsAndAsks
`formatBidsAndAsks(orderbookInfo: {base: Issue, counter: Issue}, offers: BookOffer[]): orderbook` `formatBidsAndAsks(orderbookInfo: {base: Issue, counter: Issue}, offers: BookOffer[]): orderbook`
@@ -1296,9 +1286,7 @@ return Promise.all(
} }
``` ```
# API Methods # API Methods
## connect ## connect
`connect(): Promise<void>` `connect(): Promise<void>`
@@ -1316,7 +1304,6 @@ This method returns a promise that resolves with a void value when a connection
### Example ### Example
See [Boilerplate](#boilerplate) for code sample. See [Boilerplate](#boilerplate) for code sample.
## disconnect ## disconnect
`disconnect(): Promise<void>` `disconnect(): Promise<void>`
@@ -1334,7 +1321,6 @@ This method returns a promise that resolves with a void value when a connection
### Example ### Example
See [Boilerplate](#boilerplate) for code sample See [Boilerplate](#boilerplate) for code sample
## isConnected ## isConnected
`isConnected(): boolean` `isConnected(): boolean`
@@ -1358,7 +1344,6 @@ return api.isConnected();
```json ```json
true true
``` ```
## getServerInfo ## getServerInfo
`getServerInfo(): Promise<object>` `getServerInfo(): Promise<object>`
@@ -1432,7 +1417,6 @@ return api.getServerInfo().then(info => {/* ... */});
} }
``` ```
## getFee ## getFee
`getFee(): Promise<string>` `getFee(): Promise<string>`
@@ -1460,7 +1444,6 @@ return api.getFee().then(fee => {/* ... */});
```json ```json
"0.000012" "0.000012"
``` ```
## getLedgerVersion ## getLedgerVersion
`getLedgerVersion(): Promise<number>` `getLedgerVersion(): Promise<number>`
@@ -1487,7 +1470,6 @@ return api.getLedgerVersion().then(ledgerVersion => {
16869039 16869039
``` ```
## getTransaction ## getTransaction
`getTransaction(id: string, options: object): Promise<object>` `getTransaction(id: string, options: object): Promise<object>`
@@ -1639,7 +1621,6 @@ return api.getTransaction(id).then(transaction => {
} }
``` ```
## getTransactions ## getTransactions
`getTransactions(address: string, options: object): Promise<Array<object>>` `getTransactions(address: string, options: object): Promise<Array<object>>`
@@ -1873,7 +1854,6 @@ return api.getTransactions(address).then(transaction => {
] ]
``` ```
## getTrustlines ## getTrustlines
`getTrustlines(address: string, options: object): Promise<Array<object>>` `getTrustlines(address: string, options: object): Promise<Array<object>>`
@@ -2018,7 +1998,6 @@ return api.getTrustlines(address).then(trustlines =>
] ]
``` ```
## getBalances ## getBalances
`getBalances(address: string, options: object): Promise<Array<object>>` `getBalances(address: string, options: object): Promise<Array<object>>`
@@ -2185,7 +2164,6 @@ return api.getBalances(address).then(balances =>
] ]
``` ```
## getBalanceSheet ## getBalanceSheet
`getBalanceSheet(address: string, options: object): Promise<object>` `getBalanceSheet(address: string, options: object): Promise<object>`
@@ -2281,7 +2259,6 @@ return api.getBalanceSheet(address).then(balanceSheet =>
} }
``` ```
## getPaths ## getPaths
`getPaths(pathfind: object): Promise<Array<object>>` `getPaths(pathfind: object): Promise<Array<object>>`
@@ -2402,7 +2379,6 @@ return api.getPaths(pathfind)
] ]
``` ```
## getOrders ## getOrders
`getOrders(address: string, options: object): Promise<Array<object>>` `getOrders(address: string, options: object): Promise<Array<object>>`
@@ -2783,7 +2759,6 @@ return api.getOrders(address).then(orders =>
] ]
``` ```
## getOrderbook ## getOrderbook
`getOrderbook(address: string, orderbook: object, options: object): Promise<object>` `getOrderbook(address: string, orderbook: object, options: object): Promise<object>`
@@ -3889,7 +3864,6 @@ return api.getOrderbook(address, orderbook)
} }
``` ```
## getSettings ## getSettings
`getSettings(address: string, options: object): Promise<object>` `getSettings(address: string, options: object): Promise<object>`
@@ -3972,7 +3946,6 @@ return api.getSettings(address).then(settings =>
} }
``` ```
## getAccountInfo ## getAccountInfo
`getAccountInfo(address: string, options: object): Promise<object>` `getAccountInfo(address: string, options: object): Promise<object>`
@@ -4021,7 +3994,6 @@ return api.getAccountInfo(address).then(info =>
} }
``` ```
## getAccountObjects ## getAccountObjects
`getAccountObjects(address: string, options: object): Promise<AccountObjectsResponse>` `getAccountObjects(address: string, options: object): Promise<AccountObjectsResponse>`
@@ -4346,7 +4318,6 @@ return api.getAccountObjects(address: address).then(objects =>
} }
``` ```
## getPaymentChannel ## getPaymentChannel
`getPaymentChannel(id: string): Promise<object>` `getPaymentChannel(id: string): Promise<object>`
@@ -4402,7 +4373,6 @@ return api.getPaymentChannel(channelId).then(channel =>
} }
``` ```
## getLedger ## getLedger
`getLedger(options: object): Promise<object>` `getLedger(options: object): Promise<object>`
@@ -4466,7 +4436,6 @@ return api.getLedger()
} }
``` ```
## parseAccountFlags ## parseAccountFlags
`parseAccountFlags(Flags: number): object` `parseAccountFlags(Flags: number): object`
@@ -4502,7 +4471,6 @@ console.log(JSON.stringify(flags, null, 2))
"defaultRipple": false "defaultRipple": false
} }
``` ```
## prepareTransaction ## prepareTransaction
`prepareTransaction(transaction: object, instructions: object): Promise<object>` `prepareTransaction(transaction: object, instructions: object): Promise<object>`
@@ -4511,7 +4479,7 @@ Prepare a transaction. The prepared transaction must subsequently be [signed](#s
This method works with any of [the transaction types supported by rippled](https://developers.ripple.com/transaction-types.html). This method works with any of [the transaction types supported by rippled](https://developers.ripple.com/transaction-types.html).
Notably, this is the preferred method for preparing a `DepositPreauth` transaction (added in rippled 1.1.0). Notably, this is the preferred method for preparing `DepositPreauth` or `AccountDelete` transactions.
### Parameters ### Parameters
@@ -4560,7 +4528,6 @@ async function preparedPreauth() {
} }
} }
``` ```
## preparePayment ## preparePayment
`preparePayment(address: string, payment: object, instructions: object): Promise<object>` `preparePayment(address: string, payment: object, instructions: object): Promise<object>`
@@ -4633,7 +4600,6 @@ return api.preparePayment(address, payment).then(prepared => {
} }
``` ```
## prepareTrustline ## prepareTrustline
`prepareTrustline(address: string, trustline: object, instructions: object): Promise<object>` `prepareTrustline(address: string, trustline: object, instructions: object): Promise<object>`
@@ -4701,7 +4667,6 @@ return api.prepareTrustline(address, trustline).then(prepared =>
} }
``` ```
## prepareOrder ## prepareOrder
`prepareOrder(address: string, order: object, instructions: object): Promise<object>` `prepareOrder(address: string, order: object, instructions: object): Promise<object>`
@@ -4769,7 +4734,6 @@ return api.prepareOrder(address, order)
} }
``` ```
## prepareOrderCancellation ## prepareOrderCancellation
`prepareOrderCancellation(address: string, orderCancellation: object, instructions: object): Promise<object>` `prepareOrderCancellation(address: string, orderCancellation: object, instructions: object): Promise<object>`
@@ -4822,7 +4786,6 @@ return api.prepareOrderCancellation(address, orderCancellation)
} }
``` ```
## prepareSettings ## prepareSettings
`prepareSettings(address: string, settings: object, instructions: object): Promise<object>` `prepareSettings(address: string, settings: object, instructions: object): Promise<object>`
@@ -4886,7 +4849,6 @@ return api.prepareSettings(address, settings)
} }
``` ```
## prepareEscrowCreation ## prepareEscrowCreation
`prepareEscrowCreation(address: string, escrowCreation: object, instructions: object): Promise<object>` `prepareEscrowCreation(address: string, escrowCreation: object, instructions: object): Promise<object>`
@@ -4950,7 +4912,6 @@ return api.prepareEscrowCreation(address, escrowCreation).then(prepared =>
} }
``` ```
## prepareEscrowCancellation ## prepareEscrowCancellation
`prepareEscrowCancellation(address: string, escrowCancellation: object, instructions: object): Promise<object>` `prepareEscrowCancellation(address: string, escrowCancellation: object, instructions: object): Promise<object>`
@@ -5006,7 +4967,6 @@ return api.prepareEscrowCancellation(address, escrowCancellation).then(prepared
} }
``` ```
## prepareEscrowExecution ## prepareEscrowExecution
`prepareEscrowExecution(address: string, escrowExecution: object, instructions: object): Promise<object>` `prepareEscrowExecution(address: string, escrowExecution: object, instructions: object): Promise<object>`
@@ -5064,7 +5024,6 @@ return api.prepareEscrowExecution(address, escrowExecution).then(prepared =>
} }
``` ```
## preparePaymentChannelCreate ## preparePaymentChannelCreate
`preparePaymentChannelCreate(address: string, paymentChannelCreate: object, instructions: object): Promise<object>` `preparePaymentChannelCreate(address: string, paymentChannelCreate: object, instructions: object): Promise<object>`
@@ -5122,7 +5081,6 @@ return api.preparePaymentChannelCreate(address, paymentChannelCreate).then(prepa
} }
``` ```
## preparePaymentChannelClaim ## preparePaymentChannelClaim
`preparePaymentChannelClaim(address: string, paymentChannelClaim: object, instructions: object): Promise<object>` `preparePaymentChannelClaim(address: string, paymentChannelClaim: object, instructions: object): Promise<object>`
@@ -5177,7 +5135,6 @@ return api.preparePaymentChannelClaim(address, paymentChannelClaim).then(prepare
} }
``` ```
## preparePaymentChannelFund ## preparePaymentChannelFund
`preparePaymentChannelFund(address: string, paymentChannelFund: object, instructions: object): Promise<object>` `preparePaymentChannelFund(address: string, paymentChannelFund: object, instructions: object): Promise<object>`
@@ -5233,7 +5190,6 @@ return api.preparePaymentChannelFund(address, paymentChannelFund).then(prepared
} }
``` ```
## prepareCheckCreate ## prepareCheckCreate
`prepareCheckCreate(address: string, checkCreate: object, instructions: object): Promise<object>` `prepareCheckCreate(address: string, checkCreate: object, instructions: object): Promise<object>`
@@ -5292,7 +5248,6 @@ return api.prepareCheckCreate(address, checkCreate).then(prepared =>
} }
``` ```
## prepareCheckCancel ## prepareCheckCancel
`prepareCheckCancel(address: string, checkCancel: object, instructions: object): Promise<object>` `prepareCheckCancel(address: string, checkCancel: object, instructions: object): Promise<object>`
@@ -5347,7 +5302,6 @@ return api.prepareCheckCancel(address, checkCancel).then(prepared =>
} }
``` ```
## prepareCheckCash ## prepareCheckCash
`prepareCheckCash(address: string, checkCash: object, instructions: object): Promise<object>` `prepareCheckCash(address: string, checkCash: object, instructions: object): Promise<object>`
@@ -5406,7 +5360,6 @@ return api.prepareCheckCash(address, checkCash).then(prepared =>
} }
``` ```
## sign ## sign
``` ```
@@ -5548,7 +5501,6 @@ If any of `{signAs: some_address}` options were missing the code will return a v
``` ```
[ValidationError(txJSON is not the same for all signedTransactions)] [ValidationError(txJSON is not the same for all signedTransactions)]
``` ```
## combine ## combine
`combine(signedTransactions: Array<string>): {signedTransaction: string, id: string}` `combine(signedTransactions: Array<string>): {signedTransaction: string, id: string}`
@@ -5586,7 +5538,6 @@ return api.combine(signedTransactions);
} }
``` ```
## submit ## submit
`submit(signedTransaction: string): Promise<object>` `submit(signedTransaction: string): Promise<object>`
@@ -5649,7 +5600,6 @@ return api.submit(signedTransaction)
} }
``` ```
## generateXAddress ## generateXAddress
`generateXAddress(options?: object): {address: string, secret: string}` `generateXAddress(options?: object): {address: string, secret: string}`
@@ -5662,7 +5612,7 @@ Name | Type | Description
---- | ---- | ----------- ---- | ---- | -----------
options | object | *Optional* Options to control how the address and secret are generated. options | object | *Optional* Options to control how the address and secret are generated.
*options.* algorithm | string | *Optional* The digital signature algorithm to generate an address for. Can be `ecdsa-secp256k1` (default) or `ed25519`. *options.* algorithm | string | *Optional* The digital signature algorithm to generate an address for. Can be `ecdsa-secp256k1` (default) or `ed25519`.
*options.* entropy | array\<integer\> | *Optional* The entropy to use to generate the seed. *options.* entropy | array\<integer\> | *Optional* The entropy to use to generate the seed. Must be an array of length 16 with values from 0-255 (16 bytes of entropy)
*options.* test | boolean | *Optional* Specifies whether the address is intended for use on a test network such as Testnet or Devnet. If `true`, the address should only be used for testing, and will start with `T`. If `false`, the address should only be used on mainnet, and will start with `X`. *options.* test | boolean | *Optional* Specifies whether the address is intended for use on a test network such as Testnet or Devnet. If `true`, the address should only be used for testing, and will start with `T`. If `false`, the address should only be used on mainnet, and will start with `X`.
### Return Value ### Return Value
@@ -5688,7 +5638,6 @@ return api.generateAddress();
} }
``` ```
## generateAddress ## generateAddress
`generateAddress(options?: object): {address: string, secret: string}` `generateAddress(options?: object): {address: string, secret: string}`
@@ -5703,7 +5652,7 @@ Name | Type | Description
---- | ---- | ----------- ---- | ---- | -----------
options | object | *Optional* Options to control how the address and secret are generated. options | object | *Optional* Options to control how the address and secret are generated.
*options.* algorithm | string | *Optional* The digital signature algorithm to generate an address for. Can be `ecdsa-secp256k1` (default) or `ed25519`. *options.* algorithm | string | *Optional* The digital signature algorithm to generate an address for. Can be `ecdsa-secp256k1` (default) or `ed25519`.
*options.* entropy | array\<integer\> | *Optional* The entropy to use to generate the seed. *options.* entropy | array\<integer\> | *Optional* The entropy to use to generate the seed. Must be an array of length 16 with values from 0-255 (16 bytes of entropy)
*options.* includeClassicAddress | boolean | *Optional* If `true`, return the classic address, in addition to the X-address. *options.* includeClassicAddress | boolean | *Optional* If `true`, return the classic address, in addition to the X-address.
*options.* test | boolean | *Optional* Specifies whether the address is intended for use on a test network such as Testnet or Devnet. If `true`, the address should only be used for testing, and will start with `T`. If `false`, the address should only be used on mainnet, and will start with `X`. *options.* test | boolean | *Optional* Specifies whether the address is intended for use on a test network such as Testnet or Devnet. If `true`, the address should only be used for testing, and will start with `T`. If `false`, the address should only be used on mainnet, and will start with `X`.
@@ -5734,7 +5683,6 @@ return api.generateAddress();
} }
``` ```
## isValidAddress ## isValidAddress
`isValidAddress(address: string): boolean` `isValidAddress(address: string): boolean`
@@ -5754,7 +5702,6 @@ This method returns `true` if the address is valid and `false` if it is not.
```javascript ```javascript
return api.isValidAddress("address") return api.isValidAddress("address")
``` ```
## isValidSecret ## isValidSecret
`isValidSecret(secret: string): boolean` `isValidSecret(secret: string): boolean`
@@ -5774,7 +5721,6 @@ This method returns `true` if the secret is valid and `false` if it is not.
```javascript ```javascript
return api.isValidSecret("secret") return api.isValidSecret("secret")
``` ```
## deriveKeypair ## deriveKeypair
`deriveKeypair(seed: string): {privateKey: string, publicKey: string}` `deriveKeypair(seed: string): {privateKey: string, publicKey: string}`
@@ -5796,7 +5742,6 @@ var keypair = api.deriveKeypair(seed)
var public_key = keypair.publicKey; var public_key = keypair.publicKey;
var private_key = keypair.privateKey; var private_key = keypair.privateKey;
``` ```
## deriveAddress ## deriveAddress
`deriveAddress(publicKey: string): string` `deriveAddress(publicKey: string): string`
@@ -5816,7 +5761,6 @@ This method returns a string corresponding to the address derived from the publi
```javascript ```javascript
var address = api.deriveAddress(public_key); var address = api.deriveAddress(public_key);
``` ```
## signPaymentChannelClaim ## signPaymentChannelClaim
`signPaymentChannelClaim(channel: string, amount: string, privateKey: string): string` `signPaymentChannelClaim(channel: string, amount: string, privateKey: string): string`
@@ -5855,7 +5799,6 @@ return api.signPaymentChannelClaim(channel, amount, privateKey);
"3045022100B5C54654221F154347679B97AE7791CBEF5E6772A3F894F9C781B8F1B400F89F022021E466D29DC5AEB5DFAFC76E8A88D2E388EBD25A84143B6AC3B647F479CB89B7" "3045022100B5C54654221F154347679B97AE7791CBEF5E6772A3F894F9C781B8F1B400F89F022021E466D29DC5AEB5DFAFC76E8A88D2E388EBD25A84143B6AC3B647F479CB89B7"
``` ```
## verifyPaymentChannelClaim ## verifyPaymentChannelClaim
`verifyPaymentChannelClaim(channel: string, amount: string, signature: string, publicKey: string): boolean` `verifyPaymentChannelClaim(channel: string, amount: string, signature: string, publicKey: string): boolean`
@@ -5894,7 +5837,6 @@ return api.verifyPaymentChannelClaim(channel, amount, signature, publicKey);
```json ```json
true true
``` ```
## computeLedgerHash ## computeLedgerHash
`computeLedgerHash(ledger: object): string` `computeLedgerHash(ledger: object): string`
@@ -5950,7 +5892,6 @@ return api.computeLedgerHash(ledger);
```json ```json
"F4D865D83EB88C1A1911B9E90641919A1314F36E1B099F8E95FE3B7C77BE3349" "F4D865D83EB88C1A1911B9E90641919A1314F36E1B099F8E95FE3B7C77BE3349"
``` ```
## xrpToDrops ## xrpToDrops
`xrpToDrops(xrp: string | BigNumber): string` `xrpToDrops(xrp: string | BigNumber): string`
@@ -5998,7 +5939,6 @@ return api.dropsToXrp('1');
```json ```json
'0.000001' '0.000001'
``` ```
## iso8601ToRippleTime ## iso8601ToRippleTime
`iso8601ToRippleTime(iso8601: string): number` `iso8601ToRippleTime(iso8601: string): number`
@@ -6026,7 +5966,6 @@ api.iso8601ToRippleTime('2017-02-17T15:04:57Z');
```json ```json
540659097 540659097
``` ```
## rippleTimeToISO8601 ## rippleTimeToISO8601
`rippleTimeToISO8601(rippleTime: number): string` `rippleTimeToISO8601(rippleTime: number): string`
@@ -6054,7 +5993,6 @@ api.rippleTimeToISO8601(540659097);
```json ```json
'2017-02-17T15:04:57.000Z' '2017-02-17T15:04:57.000Z'
``` ```
## txFlags ## txFlags
`txFlags.TRANSACTION_TYPE.FLAG` `txFlags.TRANSACTION_TYPE.FLAG`
@@ -6136,7 +6074,6 @@ The remaining transaction types do not have any flags at this time.
* EscrowCancel * EscrowCancel
* PaymentChannelCreate * PaymentChannelCreate
* PaymentChannelFund * PaymentChannelFund
## schemaValidator ## schemaValidator
Unlike the rest of the ripple-lib API, schemaValidator is a static object on RippleAPI. It provides utility methods that do not use a server. Unlike the rest of the ripple-lib API, schemaValidator is a static object on RippleAPI. It provides utility methods that do not use a server.
@@ -6172,7 +6109,6 @@ RippleAPI.schemaValidator.schemaValidate('sign', {
``` ```
[ValidationError(instance.id does not match pattern "^[A-F0-9]{64}$")] [ValidationError(instance.id does not match pattern "^[A-F0-9]{64}$")]
``` ```
# API Events # API Events
## ledger ## ledger
@@ -6277,4 +6213,3 @@ api.on('disconnected', (code) => {
} }
}); });
``` ```

View File

@@ -1,69 +1,69 @@
<% include introduction.md.ejs %> <%- include('introduction.md.ejs') -%>
<% include boilerplate.md.ejs %> <%- include('boilerplate.md.ejs') -%>
<% include offline.md.ejs %> <%- include('offline.md.ejs') -%>
<% include basictypes.md.ejs %> <%- include('basictypes.md.ejs') -%>
<% include transactions.md.ejs %> <%- include('transactions.md.ejs') -%>
<% include specifications.md.ejs %> <%- include('specifications.md.ejs') -%>
<% include rippledAPIs.md.ejs %> <%- include('rippledAPIs.md.ejs') -%>
<% include request.md.ejs %> <%- include('request.md.ejs') -%>
<% include hasNextPage.md.ejs %> <%- include('hasNextPage.md.ejs') -%>
<% include requestNextPage.md.ejs %> <%- include('requestNextPage.md.ejs') -%>
<% include staticMethods.md.ejs %> <%- include('staticMethods.md.ejs') -%>
<% include renameCounterpartyToIssuer.md.ejs %> <%- include('renameCounterpartyToIssuer.md.ejs') -%>
<% include formatBidsAndAsks.md.ejs %> <%- include('formatBidsAndAsks.md.ejs') -%>
<% include methods.md.ejs %> <%- include('methods.md.ejs') -%>
<% include connect.md.ejs %> <%- include('connect.md.ejs') -%>
<% include disconnect.md.ejs %> <%- include('disconnect.md.ejs') -%>
<% include isConnected.md.ejs %> <%- include('isConnected.md.ejs') -%>
<% include getServerInfo.md.ejs %> <%- include('getServerInfo.md.ejs') -%>
<% include getFee.md.ejs %> <%- include('getFee.md.ejs') -%>
<% include getLedgerVersion.md.ejs %> <%- include('getLedgerVersion.md.ejs') -%>
<% include getTransaction.md.ejs %> <%- include('getTransaction.md.ejs') -%>
<% include getTransactions.md.ejs %> <%- include('getTransactions.md.ejs') -%>
<% include getTrustlines.md.ejs %> <%- include('getTrustlines.md.ejs') -%>
<% include getBalances.md.ejs %> <%- include('getBalances.md.ejs') -%>
<% include getBalanceSheet.md.ejs %> <%- include('getBalanceSheet.md.ejs') -%>
<% include getPaths.md.ejs %> <%- include('getPaths.md.ejs') -%>
<% include getOrders.md.ejs %> <%- include('getOrders.md.ejs') -%>
<% include getOrderbook.md.ejs %> <%- include('getOrderbook.md.ejs') -%>
<% include getSettings.md.ejs %> <%- include('getSettings.md.ejs') -%>
<% include getAccountInfo.md.ejs %> <%- include('getAccountInfo.md.ejs') -%>
<% include getAccountObjects.md.ejs %> <%- include('getAccountObjects.md.ejs') -%>
<% include getPaymentChannel.md.ejs %> <%- include('getPaymentChannel.md.ejs') -%>
<% include getLedger.md.ejs %> <%- include('getLedger.md.ejs') -%>
<% include parseAccountFlags.md.ejs %> <%- include('parseAccountFlags.md.ejs') -%>
<% include prepareTransaction.md.ejs %> <%- include('prepareTransaction.md.ejs') -%>
<% include preparePayment.md.ejs %> <%- include('preparePayment.md.ejs') -%>
<% include prepareTrustline.md.ejs %> <%- include('prepareTrustline.md.ejs') -%>
<% include prepareOrder.md.ejs %> <%- include('prepareOrder.md.ejs') -%>
<% include prepareOrderCancellation.md.ejs %> <%- include('prepareOrderCancellation.md.ejs') -%>
<% include prepareSettings.md.ejs %> <%- include('prepareSettings.md.ejs') -%>
<% include prepareEscrowCreation.md.ejs %> <%- include('prepareEscrowCreation.md.ejs') -%>
<% include prepareEscrowCancellation.md.ejs %> <%- include('prepareEscrowCancellation.md.ejs') -%>
<% include prepareEscrowExecution.md.ejs %> <%- include('prepareEscrowExecution.md.ejs') -%>
<% include preparePaymentChannelCreate.md.ejs %> <%- include('preparePaymentChannelCreate.md.ejs') -%>
<% include preparePaymentChannelClaim.md.ejs %> <%- include('preparePaymentChannelClaim.md.ejs') -%>
<% include preparePaymentChannelFund.md.ejs %> <%- include('preparePaymentChannelFund.md.ejs') -%>
<% include prepareCheckCreate.md.ejs %> <%- include('prepareCheckCreate.md.ejs') -%>
<% include prepareCheckCancel.md.ejs %> <%- include('prepareCheckCancel.md.ejs') -%>
<% include prepareCheckCash.md.ejs %> <%- include('prepareCheckCash.md.ejs') -%>
<% include sign.md.ejs %> <%- include('sign.md.ejs') -%>
<% include combine.md.ejs %> <%- include('combine.md.ejs') -%>
<% include submit.md.ejs %> <%- include('submit.md.ejs') -%>
<% include generateXAddress.md.ejs %> <%- include('generateXAddress.md.ejs') -%>
<% include generateAddress.md.ejs %> <%- include('generateAddress.md.ejs') -%>
<% include isValidAddress.md.ejs %> <%- include('isValidAddress.md.ejs') -%>
<% include isValidSecret.md.ejs %> <%- include('isValidSecret.md.ejs') -%>
<% include deriveKeypair.md.ejs %> <%- include('deriveKeypair.md.ejs') -%>
<% include deriveAddress.md.ejs %> <%- include('deriveAddress.md.ejs') -%>
<% include signPaymentChannelClaim.md.ejs %> <%- include('signPaymentChannelClaim.md.ejs') -%>
<% include verifyPaymentChannelClaim.md.ejs %> <%- include('verifyPaymentChannelClaim.md.ejs') -%>
<% include computeLedgerHash.md.ejs %> <%- include('computeLedgerHash.md.ejs') -%>
<% include xrpToDropsAndDropsToXrp.md.ejs %> <%- include('xrpToDropsAndDropsToXrp.md.ejs') -%>
<% include iso8601ToRippleTime.md.ejs %> <%- include('iso8601ToRippleTime.md.ejs') -%>
<% include rippleTimeToISO8601.md.ejs %> <%- include('rippleTimeToISO8601.md.ejs') -%>
<% include txFlags.md.ejs %> <%- include('txFlags.md.ejs') -%>
<% include schemaValidator.md.ejs %> <%- include('schemaValidator.md.ejs') -%>
<% include events.md.ejs %> <%- include('events.md.ejs') -%>

View File

@@ -23,4 +23,5 @@ Methods that depend on the state of the XRP Ledger are unavailable in offline mo
* [prepareEscrowExecution](#prepareescrowexecution) * [prepareEscrowExecution](#prepareescrowexecution)
* [sign](#sign) * [sign](#sign)
* [generateAddress](#generateaddress) * [generateAddress](#generateaddress)
* [generateXAddress](#generatexaddress)
* [computeLedgerHash](#computeledgerhash) * [computeLedgerHash](#computeledgerhash)

View File

@@ -6,7 +6,7 @@ Prepare a transaction. The prepared transaction must subsequently be [signed](#s
This method works with any of [the transaction types supported by rippled](https://developers.ripple.com/transaction-types.html). This method works with any of [the transaction types supported by rippled](https://developers.ripple.com/transaction-types.html).
Notably, this is the preferred method for preparing a `DepositPreauth` transaction (added in rippled 1.1.0). Notably, this is the preferred method for preparing `DepositPreauth` or `AccountDelete` transactions.
### Parameters ### Parameters

View File

@@ -39,6 +39,7 @@ Type | Description
`manifestReceived` | Sent by the `manifests` stream when the server receives a manifest. `manifestReceived` | Sent by the `manifests` stream when the server receives a manifest.
`transaction` | Sent by many subscriptions including `transactions`, `transactions_proposed`, `accounts`, `accounts_proposed`, and `book` (Order Book). See [Transaction Streams](https://ripple.com/build/rippled-apis/#transaction-streams) for details. `transaction` | Sent by many subscriptions including `transactions`, `transactions_proposed`, `accounts`, `accounts_proposed`, and `book` (Order Book). See [Transaction Streams](https://ripple.com/build/rippled-apis/#transaction-streams) for details.
`peerStatusChange` | (Admin-only) Reports a large amount of information on the activities of other `rippled` servers to which the server is connected. `peerStatusChange` | (Admin-only) Reports a large amount of information on the activities of other `rippled` servers to which the server is connected.
`path_find` | Asynchronous follow-up response to the currently open path\_find request. See [rippled path\_find method](https://xrpl.org/path_find.html) for details.
To register your listener function, use `connection.on(type, handler)`. To register your listener function, use `connection.on(type, handler)`.

View File

@@ -1,13 +1,16 @@
{ {
"name": "ripple-lib", "name": "ripple-lib",
"version": "1.5.0", "version": "1.6.0",
"license": "ISC", "license": "ISC",
"description": "A TypeScript/JavaScript API for interacting with the XRP Ledger in Node.js and the browser", "description": "A TypeScript/JavaScript API for interacting with the XRP Ledger in Node.js and the browser",
"files": [ "files": [
"dist/npm/*", "dist/npm/*",
"build/ripple-latest-min.js" "build/ripple-latest-min.js",
"build/ripple-latest.js"
], ],
"main": "dist/npm/", "main": "dist/npm/",
"unpkg": "build/ripple-latest-min.js",
"jsdelivr": "build/ripple-latest-min.js",
"types": "dist/npm/index.d.ts", "types": "dist/npm/index.d.ts",
"browser": { "browser": {
"ws": "./dist/npm/common/wswrapper.js", "ws": "./dist/npm/common/wswrapper.js",
@@ -20,30 +23,30 @@
"@types/lodash": "^4.14.136", "@types/lodash": "^4.14.136",
"@types/ws": "^6.0.3", "@types/ws": "^6.0.3",
"bignumber.js": "^9.0.0", "bignumber.js": "^9.0.0",
"https-proxy-agent": "^3.0.0", "https-proxy-agent": "^4.0.0",
"jsonschema": "1.2.2", "jsonschema": "1.2.2",
"lodash": "^4.17.4", "lodash": "^4.17.4",
"lodash.isequal": "^4.5.0", "lodash.isequal": "^4.5.0",
"ripple-address-codec": "^4.0.0", "ripple-address-codec": "^4.0.0",
"ripple-binary-codec": "^0.2.5", "ripple-binary-codec": "^0.2.5",
"ripple-keypairs": "^0.11.0", "ripple-keypairs": "^0.11.0",
"ripple-lib-transactionparser": "0.8.1", "ripple-lib-transactionparser": "0.8.2",
"ws": "^7.2.0" "ws": "^7.2.0"
}, },
"devDependencies": { "devDependencies": {
"@types/mocha": "^5.2.7", "@types/mocha": "^5.2.7",
"@types/node": "^12.12.5", "@types/node": "^13.1.1",
"@typescript-eslint/eslint-plugin": "^2.3.3", "@typescript-eslint/eslint-plugin": "^2.3.3",
"@typescript-eslint/parser": "^2.3.3", "@typescript-eslint/parser": "^2.3.3",
"assert-diff": "^2.0.3", "assert-diff": "^2.0.3",
"doctoc": "^0.15.0", "doctoc": "^1.4.0",
"ejs": "^2.3.4", "ejs": "^3.0.1",
"eslint": "^6.5.1", "eslint": "^6.5.1",
"eventemitter2": "^5.0.1", "eventemitter2": "^6.0.0",
"json-schema-to-markdown-table": "^0.4.0", "json-schema-to-markdown-table": "^0.4.0",
"mocha": "6.2.0", "mocha": "7.0.0",
"mocha-junit-reporter": "^1.9.1", "mocha-junit-reporter": "^1.9.1",
"nyc": "^14.1.1", "nyc": "^15.0.0",
"prettier": "^1.19.1", "prettier": "^1.19.1",
"ts-node": "^8.4.1", "ts-node": "^8.4.1",
"typescript": "^3.6.4", "typescript": "^3.6.4",

View File

@@ -62,6 +62,8 @@ function loadSchemas() {
require('./schemas/specifications/check-cash.json'), require('./schemas/specifications/check-cash.json'),
require('./schemas/specifications/check-cancel.json'), require('./schemas/specifications/check-cancel.json'),
require('./schemas/specifications/trustline.json'), require('./schemas/specifications/trustline.json'),
require('./schemas/specifications/deposit-preauth.json'),
require('./schemas/specifications/account-delete.json'),
require('./schemas/output/sign.json'), require('./schemas/output/sign.json'),
require('./schemas/output/submit.json'), require('./schemas/output/submit.json'),
require('./schemas/output/get-account-info.json'), require('./schemas/output/get-account-info.json'),

View File

@@ -14,7 +14,7 @@
"minimum": 0, "minimum": 0,
"maximum": 255 "maximum": 255
}, },
"description": "The entropy to use to generate the seed." "description": "The entropy to use to generate the seed. Must be an array of length 16 with values from 0-255 (16 bytes of entropy)"
}, },
"algorithm": { "algorithm": {
"type": "string", "type": "string",

View File

@@ -14,7 +14,7 @@
"minimum": 0, "minimum": 0,
"maximum": 255 "maximum": 255
}, },
"description": "The entropy to use to generate the seed." "description": "The entropy to use to generate the seed. Must be an array of length 16 with values from 0-255 (16 bytes of entropy)"
}, },
"algorithm": { "algorithm": {
"type": "string", "type": "string",

View File

@@ -18,6 +18,8 @@
"paymentChannelClaim", "paymentChannelClaim",
"checkCreate", "checkCreate",
"checkCancel", "checkCancel",
"checkCash" "checkCash",
"depositPreauth",
"accountDelete"
] ]
} }

View File

@@ -208,6 +208,30 @@
"$ref": "paymentChannelClaim" "$ref": "paymentChannelClaim"
} }
} }
},
{
"properties": {
"type": {
"enum": [
"depositPreauth"
]
},
"specification": {
"$ref": "depositPreauth"
}
}
},
{
"properties": {
"type": {
"enum": [
"accountDelete"
]
},
"specification": {
"$ref": "accountDelete"
}
}
} }
] ]
} }

View File

@@ -0,0 +1,29 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "accountDelete",
"link": "account-delete",
"type": "object",
"properties": {
"destination": {
"$ref": "address",
"description": "Address of an account to receive any leftover XRP after deleting the sending account. Must be a funded account in the ledger, and must not be the sending account."
},
"destinationTag": {
"$ref": "tag",
"description": "(Optional) Arbitrary destination tag that identifies a hosted recipient or other information for the recipient of the deleted account's leftover XRP."
},
"destinationXAddress": {
"$ref": "address",
"description": "X-address of an account to receive any leftover XRP after deleting the sending account. Must be a funded account in the ledger, and must not be the sending account."
}
},
"anyOf": [
{
"required": ["destination"]
},
{
"required": ["destinationXAddress"]
}
],
"additionalProperties": false
}

View File

@@ -0,0 +1,21 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "depositPreauth",
"link": "deposit-preauth",
"type": "object",
"properties": {
"authorize": {
"$ref": "address",
"description": "Address of the account that can cash the check."
},
"unauthorize": {
"$ref": "address",
"description": "Address of the account that can cash the check."
}
},
"oneOf": [
{"required": ["authorize"]},
{"required": ["unauthorize"]}
],
"additionalProperties": false
}

View File

@@ -1,4 +1,6 @@
export interface SignerEntry { export interface SignerEntry {
SignerEntry: {
Account: string Account: string
SignerWeight: number SignerWeight: number
} }
}

View File

@@ -0,0 +1,34 @@
import * as assert from 'assert'
import {removeUndefined} from '../../common'
import {classicAddressToXAddress} from 'ripple-address-codec'
export type FormattedAccountDelete = {
// account (address) of an account to receive any leftover XRP after deleting the sending account.
// Must be a funded account in the ledger, and must not be the sending account.
destination: string
// (Optional) Arbitrary destination tag that identifies a hosted recipient or other information
// for the recipient of the deleted account's leftover XRP. NB: Ensure that the hosted recipient is
// able to account for AccountDelete transactions; if not, your balance may not be properly credited.
destinationTag?: number
// X-address of an account to receive any leftover XRP after deleting the sending account.
// Must be a funded account in the ledger, and must not be the sending account.
destinationXAddress: string
}
function parseAccountDelete(tx: any): FormattedAccountDelete {
assert.ok(tx.TransactionType === 'AccountDelete')
return removeUndefined({
destination: tx.Destination,
destinationTag: tx.DestinationTag,
destinationXAddress: classicAddressToXAddress(
tx.Destination,
tx.DestinationTag === undefined ? false : tx.DestinationTag,
false
)
})
}
export default parseAccountDelete

View File

@@ -1,27 +1,31 @@
import {parseOutcome} from './utils' import {parseOutcome} from './utils'
import {removeUndefined} from '../../common' import {removeUndefined} from '../../common'
import parsePayment from './payment'
import parseTrustline from './trustline'
import parseOrder from './order'
import parseOrderCancellation from './cancellation'
import parseSettings from './settings' import parseSettings from './settings'
import parseAccountDelete from './account-delete'
import parseCheckCancel from './check-cancel'
import parseCheckCash from './check-cash'
import parseCheckCreate from './check-create'
import parseDepositPreauth from './deposit-preauth'
import parseEscrowCancellation from './escrow-cancellation'
import parseEscrowCreation from './escrow-creation' import parseEscrowCreation from './escrow-creation'
import parseEscrowExecution from './escrow-execution' import parseEscrowExecution from './escrow-execution'
import parseEscrowCancellation from './escrow-cancellation' import parseOrderCancellation from './cancellation'
import parseCheckCreate from './check-create' import parseOrder from './order'
import parseCheckCash from './check-cash' import parsePayment from './payment'
import parseCheckCancel from './check-cancel' import parsePaymentChannelClaim from './payment-channel-claim'
import parseDepositPreauth from './deposit-preauth'
import parsePaymentChannelCreate from './payment-channel-create' import parsePaymentChannelCreate from './payment-channel-create'
import parsePaymentChannelFund from './payment-channel-fund' import parsePaymentChannelFund from './payment-channel-fund'
import parsePaymentChannelClaim from './payment-channel-claim' import parseTrustline from './trustline'
import parseFeeUpdate from './fee-update'
import parseAmendment from './amendment' import parseAmendment from './amendment' // pseudo-transaction
import parseFeeUpdate from './fee-update' // pseudo-transaction
function parseTransactionType(type) { function parseTransactionType(type) {
// Ordering matches https://developers.ripple.com/transaction-types.html // Ordering matches https://developers.ripple.com/transaction-types.html
const mapping = { const mapping = {
AccountSet: 'settings', AccountSet: 'settings',
AccountDelete: 'accountDelete',
CheckCancel: 'checkCancel', CheckCancel: 'checkCancel',
CheckCash: 'checkCash', CheckCash: 'checkCash',
CheckCreate: 'checkCreate', CheckCreate: 'checkCreate',
@@ -49,23 +53,25 @@ function parseTransactionType(type) {
function parseTransaction(tx: any, includeRawTransaction: boolean): any { function parseTransaction(tx: any, includeRawTransaction: boolean): any {
const type = parseTransactionType(tx.TransactionType) const type = parseTransactionType(tx.TransactionType)
const mapping = { const mapping = {
payment: parsePayment,
trustline: parseTrustline,
order: parseOrder,
orderCancellation: parseOrderCancellation,
settings: parseSettings, settings: parseSettings,
accountDelete: parseAccountDelete,
checkCancel: parseCheckCancel,
checkCash: parseCheckCash,
checkCreate: parseCheckCreate,
depositPreauth: parseDepositPreauth,
escrowCancellation: parseEscrowCancellation,
escrowCreation: parseEscrowCreation, escrowCreation: parseEscrowCreation,
escrowExecution: parseEscrowExecution, escrowExecution: parseEscrowExecution,
escrowCancellation: parseEscrowCancellation, orderCancellation: parseOrderCancellation,
checkCreate: parseCheckCreate, order: parseOrder,
checkCash: parseCheckCash, payment: parsePayment,
checkCancel: parseCheckCancel, paymentChannelClaim: parsePaymentChannelClaim,
depositPreauth: parseDepositPreauth,
paymentChannelCreate: parsePaymentChannelCreate, paymentChannelCreate: parsePaymentChannelCreate,
paymentChannelFund: parsePaymentChannelFund, paymentChannelFund: parsePaymentChannelFund,
paymentChannelClaim: parsePaymentChannelClaim, trustline: parseTrustline,
feeUpdate: parseFeeUpdate,
amendment: parseAmendment amendment: parseAmendment, // pseudo-transaction
feeUpdate: parseFeeUpdate // pseudo-transaction
} }
const parser: Function = mapping[type] const parser: Function = mapping[type]

View File

@@ -354,6 +354,16 @@ export default <TestSuite>{
) )
}, },
'AccountDelete': async (api, address) => {
const hash = 'EC2AB14028DC84DE525470AB4DAAA46358B50A8662C63804BFF38244731C0CB9'
const response = await api.getTransaction(hash)
assertResultMatch(
response,
RESPONSE_FIXTURES.accountDelete,
'getTransaction'
)
},
'no Meta': async (api, address) => { 'no Meta': async (api, address) => {
const hash = const hash =
'AFB3ADF22F3C605E23FAEFAA185F3BD763C4692CAC490D9819D117CD33BFAA1B' 'AFB3ADF22F3C605E23FAEFAA185F3BD763C4692CAC490D9819D117CD33BFAA1B'

View File

@@ -745,6 +745,33 @@ export default <TestSuite>{
return assertResultMatch(response, expected, 'prepare') return assertResultMatch(response, expected, 'prepare')
}, },
'AccountDelete': async (api, address) => {
const localInstructions = {
...instructionsWithMaxLedgerVersionOffset,
maxFee: '5.0' // 5 XRP fee for AccountDelete
}
const txJSON = {
TransactionType: 'AccountDelete',
Account: address,
Destination: 'rPT1Sjq2YGrBMTttX4GZHjKu9dyfzbpAYe'
}
const response = await api.prepareTransaction(txJSON, localInstructions)
const expected = {
txJSON:
'{"TransactionType":"AccountDelete","Account":"' +
address +
'","Destination":"rPT1Sjq2YGrBMTttX4GZHjKu9dyfzbpAYe","Flags":2147483648,"LastLedgerSequence":8820051,"Fee":"12","Sequence":23}',
instructions: {
fee: '0.000012',
sequence: 23,
maxLedgerVersion: 8820051
}
}
return assertResultMatch(response, expected, 'prepare')
},
// prepareTransaction - Payment // prepareTransaction - Payment
'Payment - normal': async (api, address) => { 'Payment - normal': async (api, address) => {
const localInstructions = { const localInstructions = {

View File

@@ -212,7 +212,7 @@ export default <TestSuite>{
) => { ) => {
const secret = 'shsWGZcmZz6YsWWmcnpfr6fLTdtFV' const secret = 'shsWGZcmZz6YsWWmcnpfr6fLTdtFV'
const request = { const request = {
// TODO: This fails when address is X-Address // TODO: This fails when address is X-address
txJSON: `{"Flags":2147483648,"TransactionType":"AccountSet","Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Domain":"726970706C652E636F6D","LastLedgerSequence":8820051,"Fee":"1.2","Sequence":23,"SigningPubKey":"02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8"}`, txJSON: `{"Flags":2147483648,"TransactionType":"AccountSet","Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Domain":"726970706C652E636F6D","LastLedgerSequence":8820051,"Fee":"1.2","Sequence":23,"SigningPubKey":"02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8"}`,
instructions: { instructions: {
fee: '0.0000012', fee: '0.0000012',
@@ -232,7 +232,7 @@ export default <TestSuite>{
) => { ) => {
const secret = 'shsWGZcmZz6YsWWmcnpfr6fLTdtFV' const secret = 'shsWGZcmZz6YsWWmcnpfr6fLTdtFV'
const request = { const request = {
// TODO: This fails when address is X-Address // TODO: This fails when address is X-address
txJSON: `{"Flags":2147483648,"TransactionType":"AccountSet","Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Domain":"726970706C652E636F6D","LastLedgerSequence":8820051,"Fee":"1123456.7","Sequence":23,"SigningPubKey":"02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8"}`, txJSON: `{"Flags":2147483648,"TransactionType":"AccountSet","Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Domain":"726970706C652E636F6D","LastLedgerSequence":8820051,"Fee":"1123456.7","Sequence":23,"SigningPubKey":"02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8"}`,
instructions: { instructions: {
fee: '1.1234567', fee: '1.1234567',
@@ -289,7 +289,7 @@ export default <TestSuite>{
api._maxFeeXRP = '2.1' api._maxFeeXRP = '2.1'
const secret = 'shsWGZcmZz6YsWWmcnpfr6fLTdtFV' const secret = 'shsWGZcmZz6YsWWmcnpfr6fLTdtFV'
const request = { const request = {
// TODO: This fails when address is X-Address // TODO: This fails when address is X-address
txJSON: `{"Flags":2147483648,"TransactionType":"AccountSet","Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Domain":"726970706C652E636F6D","LastLedgerSequence":8820051,"Fee":"2010000","Sequence":23,"SigningPubKey":"02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8"}`, txJSON: `{"Flags":2147483648,"TransactionType":"AccountSet","Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Domain":"726970706C652E636F6D","LastLedgerSequence":8820051,"Fee":"2010000","Sequence":23,"SigningPubKey":"02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8"}`,
instructions: { instructions: {
fee: '2.01', fee: '2.01',

View File

@@ -220,6 +220,30 @@ describe('Connection', function() {
}) })
}) })
it('DisconnectedError on initial _onOpen send', async function() {
// _onOpen previously could throw PromiseRejectionHandledWarning: Promise rejection was handled asynchronously
// do not rely on the api.setup hook to test this as it bypasses the case, disconnect api connection first
await this.api.disconnect();
// stub _onOpen to only run logic relevant to test case
this.api.connection._onOpen = () => {
// overload websocket send on open when _ws exists
this.api.connection._ws.send = function(data, options, cb) {
// recent ws throws this error instead of calling back
throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');
}
const request = {command: 'subscribe', streams: ['ledger']};
return this.api.connection.request(request);
}
try {
await this.api.connect();
} catch (error) {
assert(error instanceof this.api.errors.DisconnectedError);
assert.strictEqual(error.message, 'WebSocket is not open: readyState 0 (CONNECTING)');
}
});
it('ResponseFormatError', function() { it('ResponseFormatError', function() {
return this.api return this.api
.request('test_command', {data: {unrecognizedResponse: true}}) .request('test_command', {data: {unrecognizedResponse: true}})

View File

@@ -0,0 +1,32 @@
{
"type": "accountDelete",
"address": "rM5qup5BYDLMXaR5KU1hiC9HhFMuBVrnKv",
"sequence": 3227049,
"id": "EC2AB14028DC84DE525470AB4DAAA46358B50A8662C63804BFF38244731C0CB9",
"specification": {
"destination": "rPT1Sjq2YGrBMTttX4GZHjKu9dyfzbpAYe",
"destinationXAddress": "XV5kHfQmzDQjbFNv4jX3FX9Y7ig5QhpKGEFCq4mdLfhdxMq"
},
"outcome": {
"result": "tesSUCCESS",
"timestamp": "2019-12-17T09:16:51.000Z",
"fee": "5",
"balanceChanges": {
"rM5qup5BYDLMXaR5KU1hiC9HhFMuBVrnKv": [
{
"currency": "XRP",
"value": "-10000"
}
],
"rPT1Sjq2YGrBMTttX4GZHjKu9dyfzbpAYe": [
{
"currency": "XRP",
"value": "9995"
}
]
},
"orderbookChanges": {},
"ledgerVersion": 3232071,
"indexInLedger": 0
}
}

View File

@@ -67,7 +67,8 @@ module.exports = {
paymentChannelClaim: paymentChannelClaim:
require('./get-transaction-payment-channel-claim.json'), require('./get-transaction-payment-channel-claim.json'),
amendment: require('./get-transaction-amendment.json'), amendment: require('./get-transaction-amendment.json'),
feeUpdate: require('./get-transaction-fee-update.json') feeUpdate: require('./get-transaction-fee-update.json'),
accountDelete: require('./get-transaction-account-delete.json')
}, },
getTransactions: { getTransactions: {
normal: require('./get-transactions.json'), normal: require('./get-transactions.json'),

View File

@@ -99,6 +99,7 @@ module.exports = {
NoMeta: require('./tx/no-meta.json'), NoMeta: require('./tx/no-meta.json'),
LedgerZero: require('./tx/ledger-zero.json'), LedgerZero: require('./tx/ledger-zero.json'),
Amendment: require('./tx/amendment.json'), Amendment: require('./tx/amendment.json'),
SetFee: require('./tx/set-fee.json') SetFee: require('./tx/set-fee.json'),
AccountDelete: require('./tx/account-delete.json')
} }
}; };

View File

@@ -0,0 +1,66 @@
{
"id": 0,
"result": {
"Account": "rM5qup5BYDLMXaR5KU1hiC9HhFMuBVrnKv",
"Destination": "rPT1Sjq2YGrBMTttX4GZHjKu9dyfzbpAYe",
"Fee": "5000000",
"Flags": 2147483648,
"LastLedgerSequence": 3232818,
"Sequence": 3227049,
"SigningPubKey": "022E0DBF14BC4CFF96BC839557EE6F12F6DA45DCD917376F805E65D1B1C60A8CE6",
"TransactionType": "AccountDelete",
"TxnSignature": "304402207BDBE1B71C8BD00363905817C9373880CE9E8F0080623D457495E2B760BBBEE402202EDEB977D1ED865C1EAB88FE28581E3F8A672097B8BB0956E977C6EC87CA668C",
"date": 629889411,
"hash": "EC2AB14028DC84DE525470AB4DAAA46358B50A8662C63804BFF38244731C0CB9",
"inLedger": 3232071,
"ledger_index": 3232071,
"meta": {
"AffectedNodes": [
{
"DeletedNode": {
"FinalFields": {
"Account": "rM5qup5BYDLMXaR5KU1hiC9HhFMuBVrnKv",
"Balance": "0",
"Flags": 0,
"OwnerCount": 0,
"PreviousTxnID": "2737BEDDDA1D7FB523CFB84B891216331CC4CC999349828D81C6C727A1115A44",
"PreviousTxnLgrSeq": 3227049,
"Sequence": 3227050
},
"LedgerEntryType": "AccountRoot",
"LedgerIndex": "08EBF94D7BB527442E0B51F533B902DDCFBD423D8E95FAE752BE7876A29E875B",
"PreviousFields": {
"Balance": "10000000000",
"Sequence": 3227049
}
}
},
{
"ModifiedNode": {
"FinalFields": {
"Account": "rPT1Sjq2YGrBMTttX4GZHjKu9dyfzbpAYe",
"Balance": "99991026734967448",
"Flags": 0,
"OwnerCount": 0,
"Sequence": 2978
},
"LedgerEntryType": "AccountRoot",
"LedgerIndex": "31CCE9D28412FF973E9AB6D0FA219BACF19687D9A2456A0C2ABC3280E9D47E37",
"PreviousFields": {
"Balance": "99991016739967448"
},
"PreviousTxnID": "2737BEDDDA1D7FB523CFB84B891216331CC4CC999349828D81C6C727A1115A44",
"PreviousTxnLgrSeq": 3227049
}
}
],
"DeliveredAmount": "9995000000",
"TransactionIndex": 0,
"TransactionResult": "tesSUCCESS",
"delivered_amount": "9995000000"
},
"validated": true
},
"status": "success",
"type": "response"
}

View File

@@ -553,6 +553,11 @@ export function createMockRippled(port) {
'81B9ECAE7195EB6E8034AEDF44D8415A7A803E14513FDBB34FA984AB37D59563' '81B9ECAE7195EB6E8034AEDF44D8415A7A803E14513FDBB34FA984AB37D59563'
) { ) {
conn.send(createResponse(request, fixtures.tx.PaymentChannelClaim)) conn.send(createResponse(request, fixtures.tx.PaymentChannelClaim))
} else if (
request.transaction ===
'EC2AB14028DC84DE525470AB4DAAA46358B50A8662C63804BFF38244731C0CB9'
) {
conn.send(createResponse(request, fixtures.tx.AccountDelete))
} else if ( } else if (
request.transaction === request.transaction ===
'AFB3ADF22F3C605E23FAEFAA185F3BD763C4692CAC490D9819D117CD33BFAA11' 'AFB3ADF22F3C605E23FAEFAA185F3BD763C4692CAC490D9819D117CD33BFAA11'

View File

@@ -42,7 +42,7 @@ describe('RippleAPI [Test Runner]', function() {
}) })
// Run each test with the newer, x-address style. // Run each test with the newer, x-address style.
if (!config.skipXAddress) { if (!config.skipXAddress) {
describe(`[X-Address]`, () => { describe(`[X-address]`, () => {
for (const [testName, fn] of tests) { for (const [testName, fn] of tests) {
it(testName, function() { it(testName, function() {
return fn(this.api, addresses.ACCOUNT_X) return fn(this.api, addresses.ACCOUNT_X)

View File

@@ -33,7 +33,7 @@ interface LoadedTestSuite {
name: string name: string
tests: [string, TestFn][] tests: [string, TestFn][]
config: { config: {
/** Set to true to skip re-running tests with an X-Address. */ /** Set to true to skip re-running tests with an X-address. */
skipXAddress?: boolean skipXAddress?: boolean
} }
} }

View File

@@ -41,7 +41,7 @@ module.exports = [
function(env, argv) { function(env, argv) {
const config = getDefaultConfiguration(); const config = getDefaultConfiguration();
config.mode = 'production'; config.mode = 'production';
config.output.filename = `ripple-latest.min.js`; config.output.filename = `ripple-latest-min.js`;
if (process.argv.includes('--analyze')) { if (process.argv.includes('--analyze')) {
config.plugins.push(new BundleAnalyzerPlugin()); config.plugins.push(new BundleAnalyzerPlugin());
} }

1918
yarn.lock

File diff suppressed because it is too large Load Diff