mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-13 09:05:49 +00:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
90be539b09 | ||
|
|
43c08e5ea7 | ||
|
|
3f22b12216 | ||
|
|
a72041a321 | ||
|
|
71a0c16fec | ||
|
|
27ab98160a | ||
|
|
4eaaa8188d | ||
|
|
187154a2b0 | ||
|
|
c175e3f58e | ||
|
|
2ea22a099e |
@@ -7,3 +7,4 @@ script:
|
||||
- yarn compile
|
||||
- yarn test
|
||||
- yarn build
|
||||
- yarn lint
|
||||
|
||||
10
Gulpfile.js
10
Gulpfile.js
@@ -50,10 +50,12 @@ function getWebpackConfig(extension, overrides) {
|
||||
use: 'null',
|
||||
}, {
|
||||
test: /\.ts$/,
|
||||
use: 'ts-loader',
|
||||
include: [
|
||||
path.resolve(__dirname, 'src')
|
||||
]
|
||||
use: [{
|
||||
loader: 'ts-loader',
|
||||
options: {
|
||||
compilerOptions: {declaration: false}
|
||||
},
|
||||
}],
|
||||
}, {
|
||||
test: /\.json/,
|
||||
use: 'json-loader',
|
||||
|
||||
16
HISTORY.md
16
HISTORY.md
@@ -1,5 +1,21 @@
|
||||
# ripple-lib Release History
|
||||
|
||||
## 0.19.1 (2018-03-22)
|
||||
|
||||
+ [Fix: Include TypeScript declarations in npm package](https://github.com/ripple/ripple-lib/pull/863)
|
||||
+ [Fix: Documentation link to checkCash](https://github.com/ripple/ripple-lib/pull/871)
|
||||
+ [Internal: Clean up types and migrate more APIs to new request method](https://github.com/ripple/ripple-lib/pull/857)
|
||||
+ [Internal: Fix Payment source and destination types](https://github.com/ripple/ripple-lib/pull/870)
|
||||
|
||||
The SHA-256 checksums for the browser version of this release can be found
|
||||
below.
|
||||
```
|
||||
% shasum -a 256 *
|
||||
3ed5332aa035c07bae6c1abfdfc8ca77cdbb05cc4b88878f544f1ea4cb793f4d ripple-0.19.1-debug.js
|
||||
2f5507aa00a40ab6a94de1822af87db5e927edef3885aef5d9b39ccb623ccb54 ripple-0.19.1-min.js
|
||||
1e439aee1b220242d56ea687a9b55a67b8614212c1ddbd70a4fcf34503fc487a ripple-0.19.1.js
|
||||
```
|
||||
|
||||
## 0.19.0 (2018-03-02)
|
||||
|
||||
+ [Add support for Checks](https://github.com/ripple/ripple-lib/pull/853)
|
||||
|
||||
@@ -274,7 +274,7 @@ Type | Description
|
||||
[escrowExecution](#escrow-execution) | An `escrowExecution` transaction unlocks the funds in an escrow and sends them to the destination of the escrow, but it will only work if the cryptographic condition is provided.
|
||||
[checkCreate](#check-create) | A `checkCreate` transaction creates a check on the ledger, which is a deferred payment that can be cashed by its intended destination.
|
||||
[checkCancel](#check-cancel) | A `checkCancel` transaction cancels an unreedemed Check, removing it from the ledger without sending any money.
|
||||
[checkCash](#checkCash) | A `checkCash` transaction redeems a Check to receive up to the amount authorized by the corresponding `checkCreate` transaction. Only the `destination` address of a Check can cash it.
|
||||
[checkCash](#check-cash) | A `checkCash` transaction redeems a Check to receive up to the amount authorized by the corresponding `checkCreate` transaction. Only the `destination` address of a Check can cash it.
|
||||
|
||||
## Transaction Flow
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ Type | Description
|
||||
[escrowExecution](#escrow-execution) | An `escrowExecution` transaction unlocks the funds in an escrow and sends them to the destination of the escrow, but it will only work if the cryptographic condition is provided.
|
||||
[checkCreate](#check-create) | A `checkCreate` transaction creates a check on the ledger, which is a deferred payment that can be cashed by its intended destination.
|
||||
[checkCancel](#check-cancel) | A `checkCancel` transaction cancels an unreedemed Check, removing it from the ledger without sending any money.
|
||||
[checkCash](#checkCash) | A `checkCash` transaction redeems a Check to receive up to the amount authorized by the corresponding `checkCreate` transaction. Only the `destination` address of a Check can cash it.
|
||||
[checkCash](#check-cash) | A `checkCash` transaction redeems a Check to receive up to the amount authorized by the corresponding `checkCreate` transaction. Only the `destination` address of a Check can cash it.
|
||||
|
||||
## Transaction Flow
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ripple-lib",
|
||||
"version": "0.19.0",
|
||||
"version": "0.19.1",
|
||||
"license": "ISC",
|
||||
"description": "A JavaScript API for interacting with Ripple in Node.js and the browser",
|
||||
"files": [
|
||||
@@ -8,6 +8,7 @@
|
||||
"build/*"
|
||||
],
|
||||
"main": "dist/npm/",
|
||||
"types": "dist/npm/index.d.ts",
|
||||
"browser": {
|
||||
"ws": "./dist/npm/common/wswrapper.js"
|
||||
},
|
||||
|
||||
@@ -49,7 +49,9 @@ import {
|
||||
AccountInfoRequest, AccountInfoResponse,
|
||||
AccountLinesRequest, AccountLinesResponse,
|
||||
BookOffersRequest, BookOffersResponse,
|
||||
GatewayBalancesRequest, GatewayBalancesResponse
|
||||
GatewayBalancesRequest, GatewayBalancesResponse,
|
||||
LedgerRequest, LedgerResponse,
|
||||
LedgerEntryRequest, LedgerEntryResponse
|
||||
} from './common/types/commands'
|
||||
|
||||
|
||||
@@ -154,6 +156,10 @@ class RippleAPI extends EventEmitter {
|
||||
Promise<BookOffersResponse>
|
||||
async _request(command: 'gateway_balances', params: GatewayBalancesRequest):
|
||||
Promise<GatewayBalancesResponse>
|
||||
async _request(command: 'ledger', params: LedgerRequest):
|
||||
Promise<LedgerResponse>
|
||||
async _request(command: 'ledger_entry', params: LedgerEntryRequest):
|
||||
Promise<LedgerEntryResponse>
|
||||
async _request(command: string, params: any = {}) {
|
||||
return this.connection.request({
|
||||
...params,
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import {AccountRoot, SignerList} from '../objects'
|
||||
import {
|
||||
AccountRootLedgerEntry,
|
||||
SignerListLedgerEntry,
|
||||
QueueData
|
||||
} from '../objects'
|
||||
|
||||
export interface AccountInfoRequest {
|
||||
account: string,
|
||||
@@ -10,27 +14,10 @@ export interface AccountInfoRequest {
|
||||
}
|
||||
|
||||
export interface AccountInfoResponse {
|
||||
account_data: AccountRoot,
|
||||
signer_lists?: SignerList[],
|
||||
account_data: AccountRootLedgerEntry,
|
||||
signer_lists?: SignerListLedgerEntry[],
|
||||
ledger_current_index?: number,
|
||||
ledger_index?: number,
|
||||
queue_data?: QueueData,
|
||||
validated?: boolean
|
||||
}
|
||||
|
||||
export interface QueueData {
|
||||
txn_count: number,
|
||||
auth_change_queued?: boolean,
|
||||
lowest_sequence?: number,
|
||||
highest_sequence?: number,
|
||||
max_spend_drops_total?: string,
|
||||
transactions?: TransactionData[]
|
||||
}
|
||||
|
||||
export interface TransactionData {
|
||||
auth_change?: boolean,
|
||||
fee?: string,
|
||||
fee_level?: string,
|
||||
max_spend_drops?: string,
|
||||
seq?: number
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {
|
||||
TakerRequestAmount,
|
||||
OfferCreateTransaction,
|
||||
RippledAmount
|
||||
RippledAmount,
|
||||
OfferCreateTransaction
|
||||
} from '../objects'
|
||||
|
||||
export interface BookOffersRequest {
|
||||
@@ -15,15 +15,15 @@ export interface BookOffersRequest {
|
||||
}
|
||||
|
||||
export interface BookOffersResponse {
|
||||
offers: OrderBookOffer[],
|
||||
offers: BookOffer[],
|
||||
ledger_hash?: string,
|
||||
ledger_current_index?: number,
|
||||
ledger_index?: number,
|
||||
marker?: any
|
||||
}
|
||||
|
||||
export interface OrderBookOffer extends OfferCreateTransaction {
|
||||
quality?: number
|
||||
export interface BookOffer extends OfferCreateTransaction {
|
||||
quality?: string
|
||||
owner_funds?: string,
|
||||
taker_gets_funded?: RippledAmount,
|
||||
taker_pays_funded?: RippledAmount
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import {Amount} from '../objects'
|
||||
|
||||
|
||||
export interface GatewayBalancesRequest {
|
||||
account: string,
|
||||
strict?: boolean,
|
||||
|
||||
@@ -3,3 +3,5 @@ export * from './account_lines'
|
||||
export * from './account_offers'
|
||||
export * from './book_offers'
|
||||
export * from './gateway_balances'
|
||||
export * from './ledger'
|
||||
export * from './ledger_entry'
|
||||
|
||||
20
src/common/types/commands/ledger.ts
Normal file
20
src/common/types/commands/ledger.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import {Ledger, QueueData} from '../objects'
|
||||
|
||||
export interface LedgerRequest {
|
||||
ledger_hash?: string
|
||||
ledger_index?: number | ('validated' | 'closed' | 'current')
|
||||
full?: boolean
|
||||
accounts?: boolean
|
||||
transactions?: boolean
|
||||
expand?: boolean
|
||||
owner_funds?: boolean
|
||||
binary?: boolean
|
||||
queue?: boolean
|
||||
}
|
||||
|
||||
export interface LedgerResponse {
|
||||
ledger_index: number
|
||||
ledger_hash: string
|
||||
ledger: Ledger
|
||||
queue_data?: QueueData
|
||||
}
|
||||
31
src/common/types/commands/ledger_entry.ts
Normal file
31
src/common/types/commands/ledger_entry.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import {LedgerEntry} from '../objects'
|
||||
|
||||
export interface LedgerEntryRequest {
|
||||
ledger_hash?: string
|
||||
ledger_index?: number | ('validated' | 'closed' | 'current')
|
||||
index?: string,
|
||||
account_root?: string,
|
||||
directory?: string | {
|
||||
sub_index?: number,
|
||||
dir_root: string
|
||||
} | {
|
||||
sub_index?: number,
|
||||
owner: string
|
||||
},
|
||||
offer?: string | {
|
||||
account: string,
|
||||
seq: number
|
||||
},
|
||||
ripple_state?: {
|
||||
accounts: [string, string],
|
||||
currency: string
|
||||
},
|
||||
binary?: boolean
|
||||
}
|
||||
|
||||
export interface LedgerEntryResponse {
|
||||
index: string,
|
||||
ledger_index: number,
|
||||
node_binary?: string,
|
||||
node?: LedgerEntry,
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
export interface AccountRoot {
|
||||
LedgerEntryType: string,
|
||||
Account: string,
|
||||
Flags: number,
|
||||
Sequence: number,
|
||||
Balance: string,
|
||||
OwnerCount: number,
|
||||
PreviousTxnID: string,
|
||||
PreviousTxnLgrSeq: number,
|
||||
AccountTxnID?: string,
|
||||
RegularKey?: string,
|
||||
EmailHash?: string,
|
||||
MessageKey?: string
|
||||
TickSize?: number,
|
||||
TransferRate?: number,
|
||||
Domain?: string
|
||||
}
|
||||
@@ -1,7 +1,11 @@
|
||||
export * from './accounts'
|
||||
export * from './adjustments'
|
||||
export * from './amounts'
|
||||
export * from './ledger'
|
||||
export * from './ledger_entries'
|
||||
export * from './memos'
|
||||
export * from './orders'
|
||||
export * from './queue_data'
|
||||
export * from './settings'
|
||||
export * from './signers'
|
||||
export * from './transactions'
|
||||
export * from './trustlines'
|
||||
|
||||
22
src/common/types/objects/ledger.ts
Normal file
22
src/common/types/objects/ledger.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
export interface Ledger {
|
||||
account_hash: string,
|
||||
close_time: number,
|
||||
close_time_human: string,
|
||||
close_time_resolution: number,
|
||||
closed: boolean,
|
||||
ledger_hash: string,
|
||||
ledger_index: string,
|
||||
parent_hash: string,
|
||||
total_coins: string,
|
||||
transaction_hash: string,
|
||||
transactions: string[] | object[],
|
||||
// @deprecated
|
||||
seqNum?: string,
|
||||
// @deprecated
|
||||
totalCoins?: string,
|
||||
// @deprecated
|
||||
hash?: string,
|
||||
close_flags?: number,
|
||||
parent_close_time?: number,
|
||||
accountState?: any[]
|
||||
}
|
||||
56
src/common/types/objects/ledger_entries.ts
Normal file
56
src/common/types/objects/ledger_entries.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import {SignerEntry} from './index'
|
||||
|
||||
export interface PayChannelLedgerEntry {
|
||||
LedgerEntryType: 'PayChannel',
|
||||
Sequence: number,
|
||||
Account: string,
|
||||
Amount: string,
|
||||
Balance: string,
|
||||
PublicKey: string,
|
||||
Destination: string,
|
||||
SettleDelay: number,
|
||||
Expiration?: number,
|
||||
CancelAfter?: number,
|
||||
SourceTag?: number,
|
||||
DestinationTag?: number,
|
||||
OwnerNode: string,
|
||||
PreviousTxnID: string,
|
||||
PreviousTxnLgrSeq: number,
|
||||
index: string
|
||||
}
|
||||
|
||||
export interface AccountRootLedgerEntry {
|
||||
LedgerEntryType: 'AccountRoot',
|
||||
Account: string,
|
||||
Flags: number,
|
||||
Sequence: number,
|
||||
Balance: string,
|
||||
OwnerCount: number,
|
||||
PreviousTxnID: string,
|
||||
PreviousTxnLgrSeq: number,
|
||||
AccountTxnID?: string,
|
||||
RegularKey?: string,
|
||||
EmailHash?: string,
|
||||
MessageKey?: string
|
||||
TickSize?: number,
|
||||
TransferRate?: number,
|
||||
Domain?: string
|
||||
}
|
||||
|
||||
export interface SignerListLedgerEntry {
|
||||
LedgerEntryType: 'SignerList',
|
||||
OwnerNode: string,
|
||||
SignerQuorum: number,
|
||||
SignerEntries: SignerEntry[],
|
||||
SignerListID: number,
|
||||
PreviousTxnID: string,
|
||||
PreviousTxnLgrSeq: number
|
||||
}
|
||||
|
||||
// TODO: Add the other ledger entry types, then remove the `any` fallback
|
||||
// see https://ripple.com/build/ledger-format/#ledger-object-types
|
||||
export type LedgerEntry =
|
||||
PayChannelLedgerEntry |
|
||||
AccountRootLedgerEntry |
|
||||
SignerListLedgerEntry |
|
||||
any
|
||||
17
src/common/types/objects/orders.ts
Normal file
17
src/common/types/objects/orders.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import {Amount} from './amounts'
|
||||
import {Memo} from './memos'
|
||||
|
||||
export type FormattedOrderSpecification = {
|
||||
direction: string,
|
||||
quantity: Amount,
|
||||
totalPrice: Amount,
|
||||
immediateOrCancel?: boolean,
|
||||
fillOrKill?: boolean,
|
||||
expirationTime?: string,
|
||||
orderToReplace?: number,
|
||||
memos?: Memo[],
|
||||
// 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.
|
||||
passive?: boolean
|
||||
}
|
||||
16
src/common/types/objects/queue_data.ts
Normal file
16
src/common/types/objects/queue_data.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
export interface QueueTransaction {
|
||||
auth_change: boolean,
|
||||
fee: string,
|
||||
fee_level: string,
|
||||
max_spend_drops: string,
|
||||
seq: number
|
||||
}
|
||||
|
||||
export interface QueueData {
|
||||
txn_count: number,
|
||||
auth_change_queued?: boolean,
|
||||
lowest_sequence?: number,
|
||||
highest_sequence?: number,
|
||||
max_spend_drops_total?: string,
|
||||
transactions?: QueueTransaction[]
|
||||
}
|
||||
30
src/common/types/objects/settings.ts
Normal file
30
src/common/types/objects/settings.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import {Memo} from './memos'
|
||||
|
||||
export type WeightedSigner = {
|
||||
address: string,
|
||||
weight: number
|
||||
}
|
||||
|
||||
export type Signers = {
|
||||
threshold?: number,
|
||||
weights: WeightedSigner[]
|
||||
}
|
||||
|
||||
export type FormattedSettings = {
|
||||
passwordSpent?: boolean,
|
||||
requireDestinationTag?: boolean,
|
||||
requireAuthorization?: boolean,
|
||||
disallowIncomingXRP?: boolean,
|
||||
disableMasterKey?: boolean,
|
||||
enableTransactionIDTracking?: boolean,
|
||||
noFreeze?: boolean,
|
||||
globalFreeze?: boolean,
|
||||
defaultRipple?: boolean,
|
||||
emailHash?: string|null,
|
||||
messageKey?: string,
|
||||
domain?: string,
|
||||
transferRate?: number|null,
|
||||
regularKey?: string,
|
||||
signers?: Signers,
|
||||
memos?: Memo[]
|
||||
}
|
||||
@@ -1,13 +1,3 @@
|
||||
export interface SignerList {
|
||||
LedgerEntryType: string,
|
||||
OwnerNode: string,
|
||||
SignerQuorum: number,
|
||||
SignerEntries: SignerEntry[],
|
||||
SignerListID: number,
|
||||
PreviousTxnID: string,
|
||||
PreviousTxnLgrSeq: number
|
||||
}
|
||||
|
||||
export interface SignerEntry {
|
||||
Account: string,
|
||||
SignerWeight: number
|
||||
|
||||
@@ -1,28 +1,29 @@
|
||||
import {validate} from '../common'
|
||||
import parseLedger from './parse/ledger'
|
||||
import {GetLedger} from './types'
|
||||
import {FormattedLedger, parseLedger} from './parse/ledger'
|
||||
import {RippleAPI} from '../api'
|
||||
|
||||
export type LedgerOptions = {
|
||||
export type GetLedgerOptions = {
|
||||
ledgerVersion?: number,
|
||||
includeAllData?: boolean,
|
||||
includeTransactions?: boolean,
|
||||
includeState?: boolean
|
||||
}
|
||||
|
||||
|
||||
function getLedger(options: LedgerOptions = {}): Promise<GetLedger> {
|
||||
async function getLedger(
|
||||
this: RippleAPI, options: GetLedgerOptions = {}
|
||||
): Promise<FormattedLedger> {
|
||||
// 1. Validate
|
||||
validate.getLedger({options})
|
||||
|
||||
const request = {
|
||||
command: 'ledger',
|
||||
// 2. Make Request
|
||||
const response = await this._request('ledger', {
|
||||
ledger_index: options.ledgerVersion || 'validated',
|
||||
expand: options.includeAllData,
|
||||
transactions: options.includeTransactions,
|
||||
accounts: options.includeState
|
||||
}
|
||||
|
||||
return this.connection.request(request).then(response =>
|
||||
parseLedger(response.ledger))
|
||||
})
|
||||
// 3. Return Formatted Response
|
||||
return parseLedger(response.ledger)
|
||||
}
|
||||
|
||||
|
||||
export default getLedger
|
||||
|
||||
@@ -1,51 +1,28 @@
|
||||
import * as _ from 'lodash'
|
||||
import * as utils from './utils'
|
||||
import parseOrderbookOrder from './parse/orderbook-order'
|
||||
import {
|
||||
parseOrderbookOrder,
|
||||
FormattedOrderbookOrder
|
||||
} from './parse/orderbook-order'
|
||||
import {validate} from '../common'
|
||||
import {OrderSpecification} from './types'
|
||||
import {Amount, Issue} from '../common/types/objects'
|
||||
import {BookOffer} from '../common/types/commands'
|
||||
import {RippleAPI} from '../api'
|
||||
import {OfferCreateTransaction} from '../common/types/objects'
|
||||
|
||||
export type OrdersOptions = {
|
||||
limit?: number,
|
||||
ledgerVersion?: number
|
||||
}
|
||||
|
||||
export type Orderbook = {
|
||||
base: Issue,
|
||||
counter: Issue
|
||||
}
|
||||
|
||||
export type OrderbookItem = {
|
||||
specification: OrderSpecification,
|
||||
properties: {
|
||||
maker: string,
|
||||
sequence: number,
|
||||
makerExchangeRate: string
|
||||
},
|
||||
state?: {
|
||||
fundedAmount: Amount,
|
||||
priceOfFundedAmount: Amount
|
||||
}
|
||||
}
|
||||
|
||||
export type OrderbookOrders = Array<OrderbookItem>
|
||||
|
||||
export type GetOrderbook = {
|
||||
bids: OrderbookOrders,
|
||||
asks: OrderbookOrders
|
||||
export type FormattedOrderbook = {
|
||||
bids: FormattedOrderbookOrder[],
|
||||
asks: FormattedOrderbookOrder[]
|
||||
}
|
||||
|
||||
function isSameIssue(a: Amount, b: Amount) {
|
||||
return a.currency === b.currency && a.counterparty === b.counterparty
|
||||
}
|
||||
|
||||
function directionFilter(direction: string, order: OrderbookItem) {
|
||||
function directionFilter(direction: string, order: FormattedOrderbookOrder) {
|
||||
return order.specification.direction === direction
|
||||
}
|
||||
|
||||
function flipOrder(order: OrderbookItem) {
|
||||
function flipOrder(order: FormattedOrderbookOrder) {
|
||||
const specification = order.specification
|
||||
const flippedSpecification = {
|
||||
quantity: specification.totalPrice,
|
||||
@@ -56,13 +33,13 @@ function flipOrder(order: OrderbookItem) {
|
||||
return _.merge({}, order, {specification: newSpecification})
|
||||
}
|
||||
|
||||
function alignOrder(base: Amount, order: OrderbookItem) {
|
||||
function alignOrder(base: Amount, order: FormattedOrderbookOrder) {
|
||||
const quantity = order.specification.quantity
|
||||
return isSameIssue(quantity, base) ? order : flipOrder(order)
|
||||
}
|
||||
|
||||
function formatBidsAndAsks(
|
||||
orderbook: Orderbook, offers: OfferCreateTransaction[]) {
|
||||
orderbook: OrderbookInfo, offers: BookOffer[]) {
|
||||
// the "base" currency is the currency that you are buying or selling
|
||||
// the "counter" is the currency that the "base" is priced in
|
||||
// a "bid"/"ask" is an order to buy/sell the base, respectively
|
||||
@@ -83,7 +60,7 @@ function formatBidsAndAsks(
|
||||
// account is to specify a "perspective", which affects which unfunded offers
|
||||
// are returned
|
||||
async function makeRequest(
|
||||
api: RippleAPI, taker: string, options: OrdersOptions,
|
||||
api: RippleAPI, taker: string, options: GetOrderbookOptions,
|
||||
takerGets: Issue, takerPays: Issue
|
||||
) {
|
||||
const orderData = utils.renameCounterpartyToIssuerInOrder({
|
||||
@@ -99,12 +76,23 @@ async function makeRequest(
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
export type GetOrderbookOptions = {
|
||||
limit?: number,
|
||||
ledgerVersion?: number
|
||||
}
|
||||
|
||||
export type OrderbookInfo = {
|
||||
base: Issue,
|
||||
counter: Issue
|
||||
}
|
||||
|
||||
export default async function getOrderbook(
|
||||
this: RippleAPI,
|
||||
address: string,
|
||||
orderbook: Orderbook,
|
||||
options: OrdersOptions = {}
|
||||
): Promise<GetOrderbook> {
|
||||
orderbook: OrderbookInfo,
|
||||
options: GetOrderbookOptions = {}
|
||||
): Promise<FormattedOrderbook> {
|
||||
// 1. Validate
|
||||
validate.getOrderbook({address, orderbook, options})
|
||||
// 2. Make Request
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import * as _ from 'lodash'
|
||||
import {validate} from '../common'
|
||||
import parseAccountOrder from './parse/account-order'
|
||||
import {Order} from './types'
|
||||
import {FormattedAccountOrder, parseAccountOrder} from './parse/account-order'
|
||||
import {RippleAPI} from '../api'
|
||||
import {AccountOffersResponse} from '../common/types/commands/account_offers'
|
||||
import {AccountOffersResponse} from '../common/types/commands'
|
||||
|
||||
export type GetOrdersOptions = {
|
||||
limit?: number,
|
||||
@@ -12,8 +11,8 @@ export type GetOrdersOptions = {
|
||||
|
||||
function formatResponse(
|
||||
address: string, responses: AccountOffersResponse[]
|
||||
): Order[] {
|
||||
let orders: Order[] = []
|
||||
): FormattedAccountOrder[] {
|
||||
let orders: FormattedAccountOrder[] = []
|
||||
for (const response of responses) {
|
||||
const offers = response.offers.map(offer => {
|
||||
return parseAccountOrder(address, offer)
|
||||
@@ -25,7 +24,7 @@ function formatResponse(
|
||||
|
||||
export default async function getOrders(
|
||||
this: RippleAPI, address: string, options: GetOrdersOptions = {}
|
||||
): Promise<Order[]> {
|
||||
): Promise<FormattedAccountOrder[]> {
|
||||
// 1. Validate
|
||||
validate.getOrders({address, options})
|
||||
// 2. Make Request
|
||||
|
||||
@@ -3,7 +3,16 @@ import parseAmount from './amount'
|
||||
import {parseTimestamp, adjustQualityForXRP} from './utils'
|
||||
import {removeUndefined} from '../../common'
|
||||
import {orderFlags} from './flags'
|
||||
import {Order} from '../types'
|
||||
import {FormattedOrderSpecification} from '../../common/types/objects'
|
||||
|
||||
export type FormattedAccountOrder = {
|
||||
specification: FormattedOrderSpecification,
|
||||
properties: {
|
||||
maker: string,
|
||||
sequence: number,
|
||||
makerExchangeRate: string
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: remove this function once rippled provides quality directly
|
||||
function computeQuality(takerGets, takerPays) {
|
||||
@@ -13,7 +22,9 @@ function computeQuality(takerGets, takerPays) {
|
||||
|
||||
// rippled 'account_offers' returns a different format for orders than 'tx'
|
||||
// the flags are also different
|
||||
function parseAccountOrder(address: string, order: any): Order {
|
||||
export function parseAccountOrder(
|
||||
address: string, order: any
|
||||
): FormattedAccountOrder {
|
||||
const direction = (order.flags & orderFlags.Sell) === 0 ? 'buy' : 'sell'
|
||||
const takerGetsAmount = parseAmount(order.taker_gets)
|
||||
const takerPaysAmount = parseAmount(order.taker_pays)
|
||||
@@ -43,5 +54,3 @@ function parseAccountOrder(address: string, order: any): Order {
|
||||
|
||||
return {specification, properties}
|
||||
}
|
||||
|
||||
export default parseAccountOrder
|
||||
|
||||
@@ -1,7 +1,28 @@
|
||||
import * as _ from 'lodash'
|
||||
import {removeUndefined, rippleTimeToISO8601} from '../../common'
|
||||
import parseTransaction from './transaction'
|
||||
import {GetLedger} from '../types'
|
||||
import {Ledger} from '../../common/types/objects'
|
||||
|
||||
export type FormattedLedger = {
|
||||
// TODO: properties in type don't match response object. Fix!
|
||||
// accepted: boolean,
|
||||
// closed: boolean,
|
||||
stateHash: string,
|
||||
closeTime: string,
|
||||
closeTimeResolution: number,
|
||||
closeFlags: number,
|
||||
ledgerHash: string,
|
||||
ledgerVersion: number,
|
||||
parentLedgerHash: string,
|
||||
parentCloseTime: string,
|
||||
totalDrops: string,
|
||||
transactionHash: string,
|
||||
transactions?: Array<Object>,
|
||||
rawTransactions?: string,
|
||||
transactionHashes?: Array<string>,
|
||||
rawState?: string,
|
||||
stateHashes?: Array<string>
|
||||
}
|
||||
|
||||
function parseTransactionWrapper(ledgerVersion, tx) {
|
||||
const transaction = _.assign({}, _.omit(tx, 'metaData'), {
|
||||
@@ -39,7 +60,7 @@ function parseState(state) {
|
||||
return {rawState: JSON.stringify(state)}
|
||||
}
|
||||
|
||||
function parseLedger(ledger: any): GetLedger {
|
||||
export function parseLedger(ledger: Ledger): FormattedLedger {
|
||||
const ledgerVersion = parseInt(ledger.ledger_index || ledger.seqNum, 10)
|
||||
return removeUndefined(Object.assign({
|
||||
stateHash: ledger.account_hash,
|
||||
@@ -57,5 +78,3 @@ function parseLedger(ledger: any): GetLedger {
|
||||
parseState(ledger.accountState)
|
||||
))
|
||||
}
|
||||
|
||||
export default parseLedger
|
||||
|
||||
@@ -2,9 +2,14 @@ import * as assert from 'assert'
|
||||
import {parseTimestamp} from './utils'
|
||||
import parseAmount from './amount'
|
||||
import {removeUndefined, txFlags} from '../../common'
|
||||
import {
|
||||
FormattedOrderSpecification,
|
||||
OfferCreateTransaction
|
||||
} from '../../common/types/objects/index'
|
||||
|
||||
const flags = txFlags.OfferCreate
|
||||
|
||||
function parseOrder(tx: any): Object {
|
||||
function parseOrder(tx: OfferCreateTransaction): FormattedOrderSpecification {
|
||||
assert(tx.TransactionType === 'OfferCreate')
|
||||
|
||||
const direction = (tx.Flags & flags.Sell) === 0 ? 'buy' : 'sell'
|
||||
|
||||
@@ -4,8 +4,25 @@ import {removeUndefined} from '../../common'
|
||||
|
||||
import {orderFlags} from './flags'
|
||||
import parseAmount from './amount'
|
||||
import {BookOffer} from '../../common/types/commands'
|
||||
import {Amount, FormattedOrderSpecification} from '../../common/types/objects'
|
||||
|
||||
function parseOrderbookOrder(order: any): Object {
|
||||
export type FormattedOrderbookOrder = {
|
||||
specification: FormattedOrderSpecification,
|
||||
properties: {
|
||||
maker: string,
|
||||
sequence: number,
|
||||
makerExchangeRate: string
|
||||
},
|
||||
state?: {
|
||||
fundedAmount: Amount,
|
||||
priceOfFundedAmount: Amount
|
||||
}
|
||||
}
|
||||
|
||||
export function parseOrderbookOrder(
|
||||
order: BookOffer
|
||||
): FormattedOrderbookOrder {
|
||||
const direction = (order.Flags & orderFlags.Sell) === 0 ? 'buy' : 'sell'
|
||||
const takerGetsAmount = parseAmount(order.TakerGets)
|
||||
const takerPaysAmount = parseAmount(order.TakerPays)
|
||||
@@ -14,7 +31,7 @@ function parseOrderbookOrder(order: any): Object {
|
||||
|
||||
// note: immediateOrCancel and fillOrKill orders cannot enter the order book
|
||||
// so we can omit those flags here
|
||||
const specification = removeUndefined({
|
||||
const specification: FormattedOrderSpecification = removeUndefined({
|
||||
direction: direction,
|
||||
quantity: quantity,
|
||||
totalPrice: totalPrice,
|
||||
@@ -40,5 +57,3 @@ function parseOrderbookOrder(order: any): Object {
|
||||
const state = _.isEmpty(available) ? undefined : available
|
||||
return removeUndefined({specification, properties, state})
|
||||
}
|
||||
|
||||
export default parseOrderbookOrder
|
||||
|
||||
@@ -1,35 +1,8 @@
|
||||
import {parseTimestamp} from './utils'
|
||||
import {removeUndefined, dropsToXrp} from '../../common'
|
||||
import {PayChannelLedgerEntry} from '../../common/types/objects'
|
||||
|
||||
|
||||
export type PaymentChannel = {
|
||||
Sequence: number,
|
||||
Account: string,
|
||||
Amount: string,
|
||||
Balance: string,
|
||||
PublicKey: string,
|
||||
Destination: string,
|
||||
SettleDelay: number,
|
||||
Expiration?: number,
|
||||
CancelAfter?: number,
|
||||
SourceTag?: number,
|
||||
DestinationTag?: number,
|
||||
OwnerNode: string,
|
||||
LedgerEntryType: string,
|
||||
PreviousTxnID: string,
|
||||
PreviousTxnLgrSeq: number,
|
||||
index: string
|
||||
}
|
||||
|
||||
export type LedgerEntryResponse = {
|
||||
node: PaymentChannel,
|
||||
ledger_current_index?: number,
|
||||
ledger_hash?: string,
|
||||
ledger_index: number,
|
||||
validated: boolean
|
||||
}
|
||||
|
||||
export type PaymentChannelResponse = {
|
||||
export type FormattedPaymentChannel = {
|
||||
account: string,
|
||||
balance: string,
|
||||
publicKey: string,
|
||||
@@ -43,7 +16,9 @@ export type PaymentChannelResponse = {
|
||||
previousAffectingTransactionLedgerVersion: number
|
||||
}
|
||||
|
||||
function parsePaymentChannel(data: PaymentChannel): PaymentChannelResponse {
|
||||
export function parsePaymentChannel(
|
||||
data: PayChannelLedgerEntry
|
||||
): FormattedPaymentChannel {
|
||||
return removeUndefined({
|
||||
account: data.Account,
|
||||
amount: dropsToXrp(data.Amount),
|
||||
@@ -59,5 +34,3 @@ function parsePaymentChannel(data: PaymentChannel): PaymentChannelResponse {
|
||||
previousAffectingTransactionLedgerVersion: data.PreviousTxnLgrSeq
|
||||
})
|
||||
}
|
||||
|
||||
export default parsePaymentChannel
|
||||
|
||||
@@ -1,29 +1,35 @@
|
||||
import parsePaymentChannel, {
|
||||
LedgerEntryResponse, PaymentChannel
|
||||
import {
|
||||
parsePaymentChannel,
|
||||
FormattedPaymentChannel
|
||||
} from './parse/payment-channel'
|
||||
import {validate, errors} from '../common'
|
||||
import {RippleAPI} from '../api'
|
||||
import {LedgerEntryResponse} from '../common/types/commands'
|
||||
const NotFoundError = errors.NotFoundError
|
||||
|
||||
function formatResponse(response: LedgerEntryResponse) {
|
||||
if (response.node !== undefined &&
|
||||
response.node.LedgerEntryType === 'PayChannel') {
|
||||
return parsePaymentChannel(response.node)
|
||||
} else {
|
||||
function formatResponse(
|
||||
response: LedgerEntryResponse
|
||||
): FormattedPaymentChannel {
|
||||
if (response.node === undefined ||
|
||||
response.node.LedgerEntryType !== 'PayChannel') {
|
||||
throw new NotFoundError('Payment channel ledger entry not found')
|
||||
}
|
||||
return parsePaymentChannel(response.node)
|
||||
}
|
||||
|
||||
function getPaymentChannel(id: string): Promise<PaymentChannel> {
|
||||
async function getPaymentChannel(
|
||||
this: RippleAPI, id: string
|
||||
): Promise<FormattedPaymentChannel> {
|
||||
// 1. Validate
|
||||
validate.getPaymentChannel({id})
|
||||
|
||||
const request = {
|
||||
command: 'ledger_entry',
|
||||
// 2. Make Request
|
||||
const response = await this._request('ledger_entry', {
|
||||
index: id,
|
||||
binary: false,
|
||||
ledger_index: 'validated'
|
||||
}
|
||||
|
||||
return this.connection.request(request).then(formatResponse)
|
||||
})
|
||||
// 3. Return Formatted Response
|
||||
return formatResponse(response)
|
||||
}
|
||||
|
||||
export default getPaymentChannel
|
||||
|
||||
@@ -1,31 +1,15 @@
|
||||
import * as _ from 'lodash'
|
||||
import parseFields from './parse/fields'
|
||||
import {validate, constants} from '../common'
|
||||
import {FormattedSettings} from '../common/types/objects'
|
||||
import {AccountInfoResponse} from '../common/types/commands'
|
||||
import {RippleAPI} from '../api'
|
||||
const AccountFlags = constants.AccountFlags
|
||||
|
||||
export type SettingsOptions = {
|
||||
ledgerVersion?: number
|
||||
}
|
||||
|
||||
export type GetSettings = {
|
||||
passwordSpent?: boolean,
|
||||
requireDestinationTag?: boolean,
|
||||
requireAuthorization?: boolean,
|
||||
depositAuthorization?: boolean,
|
||||
disallowIncomingXRP?: boolean,
|
||||
disableMasterKey?: boolean,
|
||||
enableTransactionIDTracking?: boolean,
|
||||
noFreeze?: boolean,
|
||||
globalFreeze?: boolean,
|
||||
defaultRipple?: boolean,
|
||||
emailHash?: string|null,
|
||||
messageKey?: string,
|
||||
domain?: string,
|
||||
transferRate?: number|null,
|
||||
regularKey?: string
|
||||
}
|
||||
|
||||
|
||||
function parseFlags(value) {
|
||||
const settings = {}
|
||||
for (const flagName in AccountFlags) {
|
||||
@@ -36,25 +20,26 @@ function parseFlags(value) {
|
||||
return settings
|
||||
}
|
||||
|
||||
function formatSettings(response) {
|
||||
function formatSettings(response: AccountInfoResponse) {
|
||||
const data = response.account_data
|
||||
const parsedFlags = parseFlags(data.Flags)
|
||||
const parsedFields = parseFields(data)
|
||||
return _.assign({}, parsedFlags, parsedFields)
|
||||
}
|
||||
|
||||
function getSettings(address: string, options: SettingsOptions = {}
|
||||
): Promise<GetSettings> {
|
||||
async function getSettings(
|
||||
this: RippleAPI, address: string, options: SettingsOptions = {}
|
||||
): Promise<FormattedSettings> {
|
||||
// 1. Validate
|
||||
validate.getSettings({address, options})
|
||||
|
||||
const request = {
|
||||
command: 'account_info',
|
||||
// 2. Make Request
|
||||
const response = await this._request('account_info', {
|
||||
account: address,
|
||||
ledger_index: options.ledgerVersion || 'validated',
|
||||
signer_lists: true
|
||||
}
|
||||
|
||||
return this.connection.request(request).then(formatSettings)
|
||||
})
|
||||
// 3. Return Formatted Response
|
||||
return formatSettings(response)
|
||||
}
|
||||
|
||||
export default getSettings
|
||||
|
||||
@@ -1,144 +0,0 @@
|
||||
|
||||
import {Amount, Memo} from '../common/types/objects'
|
||||
|
||||
export type Outcome = {
|
||||
result: string,
|
||||
ledgerVersion: number,
|
||||
indexInLedger: number,
|
||||
fee: string,
|
||||
balanceChanges: {
|
||||
[key: string]: [{
|
||||
currency: string,
|
||||
counterparty?: string,
|
||||
value: string
|
||||
}]
|
||||
},
|
||||
orderbookChanges: Object,
|
||||
timestamp?: string
|
||||
}
|
||||
|
||||
export type Adjustment = {
|
||||
address: string,
|
||||
amount: {
|
||||
currency: string,
|
||||
counterparty?: string,
|
||||
value: string
|
||||
},
|
||||
tag?: number
|
||||
}
|
||||
|
||||
export type Trustline = {
|
||||
currency: string,
|
||||
counterparty: string,
|
||||
limit: string,
|
||||
qualityIn?: number,
|
||||
qualityOut?: number,
|
||||
ripplingDisabled?: boolean,
|
||||
authorized?: boolean,
|
||||
frozen?: boolean
|
||||
}
|
||||
|
||||
export type Settings = {
|
||||
passwordSpent?: boolean,
|
||||
requireDestinationTag?: boolean,
|
||||
requireAuthorization?: boolean,
|
||||
depositAuthorization?: boolean,
|
||||
disallowIncomingXRP?: boolean,
|
||||
disableMasterKey?: boolean,
|
||||
enableTransactionIDTracking?: boolean,
|
||||
noFreeze?: boolean,
|
||||
globalFreeze?: boolean,
|
||||
defaultRipple?: boolean,
|
||||
emailHash?: string,
|
||||
messageKey?: string,
|
||||
domain?: string,
|
||||
transferRate?: number,
|
||||
regularKey?: string
|
||||
}
|
||||
|
||||
export type OrderCancellation = {
|
||||
orderSequence: number
|
||||
}
|
||||
|
||||
export type Payment = {
|
||||
source: Adjustment,
|
||||
destination: Adjustment,
|
||||
paths?: string,
|
||||
memos?: Array<Memo>,
|
||||
invoiceID?: string,
|
||||
allowPartialPayment?: boolean,
|
||||
noDirectRipple?: boolean,
|
||||
limitQuality?: boolean
|
||||
}
|
||||
|
||||
export type PaymentTransaction = {
|
||||
type: string,
|
||||
specification: Payment,
|
||||
outcome: Outcome,
|
||||
id: string,
|
||||
address: string,
|
||||
sequence: number
|
||||
}
|
||||
|
||||
export type Order = {
|
||||
direction: string,
|
||||
quantity: Amount,
|
||||
totalPrice: Amount,
|
||||
immediateOrCancel?: boolean,
|
||||
fillOrKill?: boolean,
|
||||
passive?: boolean,
|
||||
expirationTime?: string,
|
||||
orderToReplace?: number,
|
||||
memos?: Memo[]
|
||||
}
|
||||
|
||||
export type OrderTransaction = {
|
||||
type: string,
|
||||
specification: Order,
|
||||
outcome: Outcome,
|
||||
id: string,
|
||||
address: string,
|
||||
sequence: number
|
||||
}
|
||||
|
||||
export type OrderCancellationTransaction = {
|
||||
type: string,
|
||||
specification: OrderCancellation,
|
||||
outcome: Outcome,
|
||||
id: string,
|
||||
address: string,
|
||||
sequence: number
|
||||
}
|
||||
|
||||
export type TrustlineTransaction = {
|
||||
type: string,
|
||||
specification: Trustline,
|
||||
outcome: Outcome,
|
||||
id: string,
|
||||
address: string,
|
||||
sequence: number
|
||||
}
|
||||
|
||||
export type SettingsTransaction = {
|
||||
type: string,
|
||||
specification: Settings,
|
||||
outcome: Outcome,
|
||||
id: string,
|
||||
address: string,
|
||||
sequence: number
|
||||
}
|
||||
|
||||
export type TransactionOptions = {
|
||||
minLedgerVersion?: number,
|
||||
maxLedgerVersion?: number
|
||||
}
|
||||
|
||||
export type TransactionType = PaymentTransaction | OrderTransaction |
|
||||
OrderCancellationTransaction | TrustlineTransaction | SettingsTransaction
|
||||
|
||||
export type TransactionResponse = TransactionType & {
|
||||
hash: string,
|
||||
ledger_index: number,
|
||||
meta: any,
|
||||
validated?: boolean
|
||||
}
|
||||
|
||||
@@ -3,12 +3,22 @@ import * as utils from './utils'
|
||||
import parseTransaction from './parse/transaction'
|
||||
import {validate, errors} from '../common'
|
||||
import {Connection} from '../common'
|
||||
import {
|
||||
TransactionType, TransactionResponse, TransactionOptions
|
||||
} from './transaction-types'
|
||||
import {FormattedTransactionType} from '../transaction/types'
|
||||
|
||||
export type TransactionOptions = {
|
||||
minLedgerVersion?: number,
|
||||
maxLedgerVersion?: number
|
||||
}
|
||||
type TransactionResponse = FormattedTransactionType & {
|
||||
hash: string,
|
||||
ledger_index: number,
|
||||
meta: any,
|
||||
validated?: boolean
|
||||
}
|
||||
|
||||
|
||||
function attachTransactionDate(connection: Connection, tx: any
|
||||
): Promise<TransactionType> {
|
||||
): Promise<FormattedTransactionType> {
|
||||
if (tx.date) {
|
||||
return Promise.resolve(tx)
|
||||
}
|
||||
@@ -71,7 +81,7 @@ function convertError(connection: Connection, options: TransactionOptions,
|
||||
}
|
||||
|
||||
function formatResponse(options: TransactionOptions, tx: TransactionResponse
|
||||
): TransactionType {
|
||||
): FormattedTransactionType {
|
||||
if (tx.validated !== true || !isTransactionInRange(tx, options)) {
|
||||
throw new errors.NotFoundError('Transaction not found')
|
||||
}
|
||||
@@ -79,7 +89,7 @@ function formatResponse(options: TransactionOptions, tx: TransactionResponse
|
||||
}
|
||||
|
||||
function getTransaction(id: string, options: TransactionOptions = {}
|
||||
): Promise<TransactionType> {
|
||||
): Promise<FormattedTransactionType> {
|
||||
validate.getTransaction({id, options})
|
||||
|
||||
const request = {
|
||||
|
||||
@@ -4,9 +4,8 @@ const {computeTransactionHash} = require('ripple-hashes')
|
||||
import * as utils from './utils'
|
||||
import parseTransaction from './parse/transaction'
|
||||
import getTransaction from './transaction'
|
||||
import {validate, errors} from '../common'
|
||||
import {Connection} from '../common'
|
||||
import {TransactionType} from './transaction-types'
|
||||
import {validate, errors, Connection} from '../common'
|
||||
import {FormattedTransactionType} from '../transaction/types'
|
||||
|
||||
|
||||
export type TransactionsOptions = {
|
||||
@@ -20,10 +19,10 @@ export type TransactionsOptions = {
|
||||
counterparty?: string,
|
||||
types?: Array<string>,
|
||||
binary?: boolean,
|
||||
startTx?: TransactionType
|
||||
startTx?: FormattedTransactionType
|
||||
}
|
||||
|
||||
export type GetTransactionsResponse = Array<TransactionType>
|
||||
export type GetTransactionsResponse = Array<FormattedTransactionType>
|
||||
|
||||
function parseBinaryTransaction(transaction) {
|
||||
const tx = binary.decode(transaction.tx_blob)
|
||||
@@ -43,7 +42,7 @@ function parseAccountTxTransaction(tx) {
|
||||
{meta: _tx.meta, validated: _tx.validated}))
|
||||
}
|
||||
|
||||
function counterpartyFilter(filters, tx: TransactionType) {
|
||||
function counterpartyFilter(filters, tx: FormattedTransactionType) {
|
||||
if (tx.address === filters.counterparty) {
|
||||
return true
|
||||
}
|
||||
@@ -57,7 +56,7 @@ function counterpartyFilter(filters, tx: TransactionType) {
|
||||
}
|
||||
|
||||
function transactionFilter(address: string, filters: TransactionsOptions,
|
||||
tx: TransactionType
|
||||
tx: FormattedTransactionType
|
||||
) {
|
||||
if (filters.excludeFailures && tx.outcome.result !== 'tesSUCCESS') {
|
||||
return false
|
||||
@@ -77,7 +76,9 @@ function transactionFilter(address: string, filters: TransactionsOptions,
|
||||
return true
|
||||
}
|
||||
|
||||
function orderFilter(options: TransactionsOptions, tx: TransactionType) {
|
||||
function orderFilter(
|
||||
options: TransactionsOptions, tx: FormattedTransactionType
|
||||
) {
|
||||
return !options.startTx || (options.earliestFirst ?
|
||||
utils.compareTransactions(tx, options.startTx) > 0 :
|
||||
utils.compareTransactions(tx, options.startTx) < 0)
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
|
||||
import {Amount} from '../common/types/objects'
|
||||
|
||||
export type OrderSpecification = {
|
||||
direction: string,
|
||||
quantity: Amount,
|
||||
totalPrice: Amount,
|
||||
immediateOrCancel?: boolean,
|
||||
fillOrKill?: boolean,
|
||||
// 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.
|
||||
passive?: boolean
|
||||
}
|
||||
|
||||
export type Order = {
|
||||
specification: OrderSpecification,
|
||||
properties: {
|
||||
maker: string,
|
||||
sequence: number,
|
||||
makerExchangeRate: string
|
||||
}
|
||||
}
|
||||
|
||||
export type GetLedger = {
|
||||
// TODO: properties in type don't match response object. Fix!
|
||||
// accepted: boolean,
|
||||
// closed: boolean,
|
||||
stateHash: string,
|
||||
closeTime: string,
|
||||
closeTimeResolution: number,
|
||||
closeFlags: number,
|
||||
ledgerHash: string,
|
||||
ledgerVersion: number,
|
||||
parentLedgerHash: string,
|
||||
parentCloseTime: string,
|
||||
totalDrops: string,
|
||||
transactionHash: string,
|
||||
transactions?: Array<Object>,
|
||||
rawTransactions?: string,
|
||||
transactionHashes?: Array<string>,
|
||||
rawState?: string,
|
||||
stateHashes?: Array<string>
|
||||
}
|
||||
@@ -2,7 +2,7 @@ import * as _ from 'lodash'
|
||||
import * as assert from 'assert'
|
||||
import * as common from '../common'
|
||||
import {Connection} from '../common'
|
||||
import {TransactionType} from './transaction-types'
|
||||
import {FormattedTransactionType} from '../transaction/types'
|
||||
import {Issue} from '../common/types/objects'
|
||||
|
||||
export type RecursiveData = {
|
||||
@@ -78,7 +78,8 @@ function signum(num) {
|
||||
* them based on TransactionIndex
|
||||
* See: https://ripple.com/build/transactions/
|
||||
*/
|
||||
function compareTransactions(first: TransactionType, second: TransactionType
|
||||
function compareTransactions(
|
||||
first: FormattedTransactionType, second: FormattedTransactionType
|
||||
): number {
|
||||
if (!first.outcome || !second.outcome) {
|
||||
return 0
|
||||
|
||||
@@ -2,16 +2,18 @@ import * as _ from 'lodash'
|
||||
import * as utils from './utils'
|
||||
const offerFlags = utils.common.txFlags.OfferCreate
|
||||
import {validate, iso8601ToRippleTime} from '../common'
|
||||
import {Instructions, Prepare} from './types'
|
||||
import {Order} from '../ledger/transaction-types'
|
||||
import {Instructions, Prepare, OfferCreateTransaction} from './types'
|
||||
import {FormattedOrderSpecification} from '../common/types/objects/index'
|
||||
|
||||
function createOrderTransaction(account: string, order: Order): Object {
|
||||
function createOrderTransaction(
|
||||
account: string, order: FormattedOrderSpecification
|
||||
): OfferCreateTransaction {
|
||||
const takerPays = utils.common.toRippledAmount(order.direction === 'buy' ?
|
||||
order.quantity : order.totalPrice)
|
||||
const takerGets = utils.common.toRippledAmount(order.direction === 'buy' ?
|
||||
order.totalPrice : order.quantity)
|
||||
|
||||
const txJSON: any = {
|
||||
const txJSON: Partial<OfferCreateTransaction> = {
|
||||
TransactionType: 'OfferCreate',
|
||||
Account: account,
|
||||
TakerGets: takerGets,
|
||||
@@ -39,10 +41,10 @@ function createOrderTransaction(account: string, order: Order): Object {
|
||||
if (order.memos !== undefined) {
|
||||
txJSON.Memos = _.map(order.memos, utils.convertMemo)
|
||||
}
|
||||
return txJSON
|
||||
return txJSON as OfferCreateTransaction
|
||||
}
|
||||
|
||||
function prepareOrder(address: string, order: Order,
|
||||
function prepareOrder(address: string, order: FormattedOrderSpecification,
|
||||
instructions: Instructions = {}
|
||||
): Promise<Prepare> {
|
||||
validate.prepareOrder({address, order, instructions})
|
||||
|
||||
@@ -9,9 +9,9 @@ import {Amount, Adjustment, MaxAdjustment,
|
||||
MinAdjustment, Memo} from '../common/types/objects'
|
||||
|
||||
|
||||
export type Payment = {
|
||||
source: Adjustment & MaxAdjustment,
|
||||
destination: Adjustment & MinAdjustment,
|
||||
export interface Payment {
|
||||
source: Adjustment | MaxAdjustment,
|
||||
destination: Adjustment | MinAdjustment,
|
||||
paths?: string,
|
||||
memos?: Array<Memo>,
|
||||
// A 256-bit hash that can be used to identify a particular payment
|
||||
@@ -30,11 +30,22 @@ import {Amount, Adjustment, MaxAdjustment,
|
||||
limitQuality?: boolean
|
||||
}
|
||||
|
||||
function isMaxAdjustment(
|
||||
source: Adjustment | MaxAdjustment): source is MaxAdjustment {
|
||||
return (source as MaxAdjustment).maxAmount !== undefined
|
||||
}
|
||||
|
||||
function isMinAdjustment(
|
||||
destination: Adjustment | MinAdjustment): destination is MinAdjustment {
|
||||
return (destination as MinAdjustment).minAmount !== undefined
|
||||
}
|
||||
|
||||
function isXRPToXRPPayment(payment: Payment): boolean {
|
||||
const sourceCurrency = _.get(payment, 'source.maxAmount.currency',
|
||||
_.get(payment, 'source.amount.currency'))
|
||||
const destinationCurrency = _.get(payment, 'destination.amount.currency',
|
||||
_.get(payment, 'destination.minAmount.currency'))
|
||||
const {source, destination} = payment
|
||||
const sourceCurrency = isMaxAdjustment(source)
|
||||
? source.maxAmount.currency : source.amount.currency
|
||||
const destinationCurrency = isMinAdjustment(destination)
|
||||
? destination.minAmount.currency : destination.amount.currency
|
||||
return sourceCurrency === 'XRP' && destinationCurrency === 'XRP'
|
||||
}
|
||||
|
||||
@@ -74,21 +85,29 @@ function createPaymentTransaction(address: string, paymentArgument: Payment
|
||||
throw new ValidationError('address must match payment.source.address')
|
||||
}
|
||||
|
||||
if ((payment.source.maxAmount && payment.destination.minAmount) ||
|
||||
(payment.source.amount && payment.destination.amount)) {
|
||||
if (
|
||||
(isMaxAdjustment(payment.source) && isMinAdjustment(payment.destination))
|
||||
||
|
||||
(!isMaxAdjustment(payment.source) && !isMinAdjustment(payment.destination))
|
||||
) {
|
||||
throw new ValidationError('payment must specify either (source.maxAmount '
|
||||
+ 'and destination.amount) or (source.amount and destination.minAmount)')
|
||||
}
|
||||
|
||||
const destinationAmount = isMinAdjustment(payment.destination)
|
||||
? payment.destination.minAmount : payment.destination.amount
|
||||
const sourceAmount = isMaxAdjustment(payment.source)
|
||||
? payment.source.maxAmount : payment.source.amount
|
||||
|
||||
// when using destination.minAmount, rippled still requires that we set
|
||||
// a destination amount in addition to DeliverMin. the destination amount
|
||||
// is interpreted as the maximum amount to send. we want to be sure to
|
||||
// send the whole source amount, so we set the destination amount to the
|
||||
// maximum possible amount. otherwise it's possible that the destination
|
||||
// cap could be hit before the source cap.
|
||||
const amount = payment.destination.minAmount && !isXRPToXRPPayment(payment) ?
|
||||
createMaximalAmount(payment.destination.minAmount) :
|
||||
(payment.destination.amount || payment.destination.minAmount)
|
||||
const amount =
|
||||
(isMinAdjustment(payment.destination) && !isXRPToXRPPayment(payment))
|
||||
? createMaximalAmount(destinationAmount) : destinationAmount
|
||||
|
||||
const txJSON: any = {
|
||||
TransactionType: 'Payment',
|
||||
@@ -121,16 +140,14 @@ function createPaymentTransaction(address: string, paymentArgument: Payment
|
||||
// temREDUNDANT_SEND_MAX removed in:
|
||||
// https://github.com/ripple/rippled/commit/
|
||||
// c522ffa6db2648f1d8a987843e7feabf1a0b7de8/
|
||||
if (payment.allowPartialPayment === true
|
||||
|| payment.destination.minAmount !== undefined) {
|
||||
if (payment.allowPartialPayment || isMinAdjustment(payment.destination)) {
|
||||
txJSON.Flags |= paymentFlags.PartialPayment
|
||||
}
|
||||
|
||||
txJSON.SendMax = toRippledAmount(
|
||||
payment.source.maxAmount || payment.source.amount)
|
||||
txJSON.SendMax = toRippledAmount(sourceAmount)
|
||||
|
||||
if (payment.destination.minAmount !== undefined) {
|
||||
txJSON.DeliverMin = toRippledAmount(payment.destination.minAmount)
|
||||
if (isMinAdjustment(payment.destination)) {
|
||||
txJSON.DeliverMin = toRippledAmount(destinationAmount)
|
||||
}
|
||||
|
||||
if (payment.paths !== undefined) {
|
||||
|
||||
@@ -6,36 +6,12 @@ const validate = utils.common.validate
|
||||
const AccountFlagIndices = utils.common.constants.AccountFlagIndices
|
||||
const AccountFields = utils.common.constants.AccountFields
|
||||
import {Instructions, Prepare} from './types'
|
||||
import {Memo} from '../common/types/objects'
|
||||
|
||||
export type WeightedSigner = {address: string, weight: number}
|
||||
export type SettingsSigners = {
|
||||
threshold?: number,
|
||||
weights: WeightedSigner[]
|
||||
}
|
||||
export type Settings = {
|
||||
passwordSpent?: boolean,
|
||||
requireDestinationTag?: boolean,
|
||||
requireAuthorization?: boolean,
|
||||
disallowIncomingXRP?: boolean,
|
||||
disableMasterKey?: boolean,
|
||||
enableTransactionIDTracking?: boolean,
|
||||
noFreeze?: boolean,
|
||||
globalFreeze?: boolean,
|
||||
defaultRipple?: boolean,
|
||||
emailHash?: string,
|
||||
messageKey?: string,
|
||||
domain?: string,
|
||||
transferRate?: number,
|
||||
regularKey?: string,
|
||||
signers?: SettingsSigners,
|
||||
memos?: Memo[]
|
||||
}
|
||||
import {FormattedSettings, WeightedSigner} from '../common/types/objects'
|
||||
|
||||
// Emptry string passed to setting will clear it
|
||||
const CLEAR_SETTING = null
|
||||
|
||||
function setTransactionFlags(txJSON: any, values: Settings) {
|
||||
function setTransactionFlags(txJSON: any, values: FormattedSettings) {
|
||||
const keys = Object.keys(values)
|
||||
assert(keys.length === 1, 'ERROR: can only set one setting per transaction')
|
||||
const flagName = keys[0]
|
||||
@@ -50,7 +26,7 @@ function setTransactionFlags(txJSON: any, values: Settings) {
|
||||
}
|
||||
}
|
||||
|
||||
function setTransactionFields(txJSON: Object, input: Settings) {
|
||||
function setTransactionFields(txJSON: Object, input: FormattedSettings) {
|
||||
const fieldSchema = AccountFields
|
||||
for (const fieldName in fieldSchema) {
|
||||
const field = fieldSchema[fieldName]
|
||||
@@ -101,7 +77,7 @@ function formatSignerEntry(signer: WeightedSigner): Object {
|
||||
}
|
||||
|
||||
function createSettingsTransactionWithoutMemos(
|
||||
account: string, settings: Settings
|
||||
account: string, settings: FormattedSettings
|
||||
): any {
|
||||
if (settings.regularKey !== undefined) {
|
||||
const removeRegularKey = {
|
||||
@@ -137,7 +113,7 @@ function createSettingsTransactionWithoutMemos(
|
||||
return txJSON
|
||||
}
|
||||
|
||||
function createSettingsTransaction(account: string, settings: Settings
|
||||
function createSettingsTransaction(account: string, settings: FormattedSettings
|
||||
): Object {
|
||||
const txJSON = createSettingsTransactionWithoutMemos(account, settings)
|
||||
if (settings.memos !== undefined) {
|
||||
@@ -146,7 +122,7 @@ function createSettingsTransaction(account: string, settings: Settings
|
||||
return txJSON
|
||||
}
|
||||
|
||||
function prepareSettings(address: string, settings: Settings,
|
||||
function prepareSettings(address: string, settings: FormattedSettings,
|
||||
instructions: Instructions = {}
|
||||
): Promise<Prepare> {
|
||||
validate.prepareSettings({address, settings, instructions})
|
||||
|
||||
@@ -1,4 +1,14 @@
|
||||
|
||||
import {
|
||||
FormattedOrderSpecification,
|
||||
FormattedTrustline,
|
||||
Adjustment,
|
||||
RippledAmount,
|
||||
Memo,
|
||||
FormattedSettings
|
||||
} from '../common/types/objects'
|
||||
import {ApiMemo} from './utils'
|
||||
|
||||
export type Instructions = {
|
||||
sequence?: number,
|
||||
fee?: string,
|
||||
@@ -25,3 +35,100 @@ export type Submit = {
|
||||
txBlob?: string,
|
||||
txJson?: Object
|
||||
}
|
||||
|
||||
export interface OfferCreateTransaction {
|
||||
TransactionType: 'OfferCreate',
|
||||
Account: string,
|
||||
Fee: string,
|
||||
Flags: number,
|
||||
LastLedgerSequence: number,
|
||||
Sequence: number,
|
||||
TakerGets: RippledAmount,
|
||||
TakerPays: RippledAmount,
|
||||
Expiration?: number,
|
||||
OfferSequence?: number,
|
||||
Memos: {Memo: ApiMemo}[]
|
||||
}
|
||||
|
||||
export type Outcome = {
|
||||
result: string,
|
||||
ledgerVersion: number,
|
||||
indexInLedger: number,
|
||||
fee: string,
|
||||
balanceChanges: {
|
||||
[key: string]: [{
|
||||
currency: string,
|
||||
counterparty?: string,
|
||||
value: string
|
||||
}]
|
||||
},
|
||||
orderbookChanges: Object,
|
||||
timestamp?: string
|
||||
}
|
||||
|
||||
export type FormattedOrderCancellation = {
|
||||
orderSequence: number
|
||||
}
|
||||
|
||||
export type FormattedPayment = {
|
||||
source: Adjustment,
|
||||
destination: Adjustment,
|
||||
paths?: string,
|
||||
memos?: Array<Memo>,
|
||||
invoiceID?: string,
|
||||
allowPartialPayment?: boolean,
|
||||
noDirectRipple?: boolean,
|
||||
limitQuality?: boolean
|
||||
}
|
||||
|
||||
export type FormattedPaymentTransaction = {
|
||||
type: string,
|
||||
specification: FormattedPayment,
|
||||
outcome: Outcome,
|
||||
id: string,
|
||||
address: string,
|
||||
sequence: number
|
||||
}
|
||||
|
||||
export type FormattedOrderTransaction = {
|
||||
type: string,
|
||||
specification: FormattedOrderSpecification,
|
||||
outcome: Outcome,
|
||||
id: string,
|
||||
address: string,
|
||||
sequence: number
|
||||
}
|
||||
|
||||
export type FormattedOrderCancellationTransaction = {
|
||||
type: string,
|
||||
specification: FormattedOrderCancellation,
|
||||
outcome: Outcome,
|
||||
id: string,
|
||||
address: string,
|
||||
sequence: number
|
||||
}
|
||||
|
||||
export type FormattedTrustlineTransaction = {
|
||||
type: string,
|
||||
specification: FormattedTrustline,
|
||||
outcome: Outcome,
|
||||
id: string,
|
||||
address: string,
|
||||
sequence: number
|
||||
}
|
||||
|
||||
export type FormattedSettingsTransaction = {
|
||||
type: string,
|
||||
specification: FormattedSettings,
|
||||
outcome: Outcome,
|
||||
id: string,
|
||||
address: string,
|
||||
sequence: number
|
||||
}
|
||||
|
||||
export type FormattedTransactionType =
|
||||
FormattedPaymentTransaction |
|
||||
FormattedOrderTransaction |
|
||||
FormattedOrderCancellationTransaction |
|
||||
FormattedTrustlineTransaction |
|
||||
FormattedSettingsTransaction
|
||||
|
||||
@@ -1124,9 +1124,11 @@ describe('RippleAPI', function () {
|
||||
});
|
||||
|
||||
it('getSettings - invalid options', function () {
|
||||
assert.throws(() => {
|
||||
this.api.getSettings(address, { invalid: 'options' });
|
||||
}, this.api.errors.ValidationError);
|
||||
return this.api.getSettings(address, { invalid: 'options' }).then(() => {
|
||||
assert(false, 'Should throw ValidationError');
|
||||
}).catch(error => {
|
||||
assert(error instanceof this.api.errors.ValidationError);
|
||||
});
|
||||
});
|
||||
|
||||
it('getAccountInfo', function () {
|
||||
|
||||
Reference in New Issue
Block a user