From c8a2a6690be4b077aeb71bdaf134d80ccb445ffe Mon Sep 17 00:00:00 2001 From: Nathan Nichols Date: Tue, 7 Sep 2021 10:11:25 -0700 Subject: [PATCH] feat: Add typescript types to subscribe (#1576) feat: Add typescript types to subscribe (#1576) --- .eslintignore | 2 + src/client/broadcastClient.ts | 6 +- src/client/index.ts | 57 ++++++++ src/models/methods/index.ts | 2 + src/models/methods/subscribe.ts | 19 ++- test/client/subscribe.ts | 103 ++++++++++++++ test/fixtures/rippled/index.ts | 118 +++++++++------- .../rippled/streams/consensusPhase.json | 4 + test/fixtures/rippled/streams/ledger.json | 12 ++ test/fixtures/rippled/streams/manifest.json | 3 + test/fixtures/rippled/streams/pathFind.json | 65 +++++++++ .../rippled/streams/peerStatusChange.json | 9 ++ .../rippled/streams/serverStatus.json | 11 ++ .../fixtures/rippled/streams/transaction.json | 132 ++++++++++++++++++ test/fixtures/rippled/streams/validation.json | 22 +++ 15 files changed, 513 insertions(+), 52 deletions(-) create mode 100644 test/client/subscribe.ts create mode 100644 test/fixtures/rippled/streams/consensusPhase.json create mode 100644 test/fixtures/rippled/streams/ledger.json create mode 100644 test/fixtures/rippled/streams/manifest.json create mode 100644 test/fixtures/rippled/streams/pathFind.json create mode 100644 test/fixtures/rippled/streams/peerStatusChange.json create mode 100644 test/fixtures/rippled/streams/serverStatus.json create mode 100644 test/fixtures/rippled/streams/transaction.json create mode 100644 test/fixtures/rippled/streams/validation.json diff --git a/.eslintignore b/.eslintignore index de4d1f00..1d39d000 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,2 +1,4 @@ dist node_modules +.github +.vscode diff --git a/src/client/broadcastClient.ts b/src/client/broadcastClient.ts index 18633382..6bebf0bf 100644 --- a/src/client/broadcastClient.ts +++ b/src/client/broadcastClient.ts @@ -58,7 +58,11 @@ export default class BroadcastClient extends Client { ...Object.getOwnPropertyNames(Object.getPrototypeOf(firstClient)), ) for (const name of methods) { - if (typeof firstClient[name] === 'function' && name !== 'constructor') { + if ( + typeof firstClient[name] === 'function' && + name !== 'constructor' && + name !== 'on' + ) { methodNames.push(name) } } diff --git a/src/client/index.ts b/src/client/index.ts index 9481453b..4866f3fc 100644 --- a/src/client/index.ts +++ b/src/client/index.ts @@ -94,6 +94,16 @@ import { PingResponse, RandomRequest, RandomResponse, + LedgerStream, + ValidationStream, + TransactionStream, + PathFindStream, + PeerStatusStream, + ConsensusStream, + SubscribeRequest, + SubscribeResponse, + UnsubscribeRequest, + UnsubscribeResponse, } from '../models/methods' import { BaseRequest, BaseResponse } from '../models/methods/baseMethod' import prepareCheckCancel from '../transaction/check-cancel' @@ -211,6 +221,34 @@ class Client extends EventEmitter { this.emit('error', errorCode, errorMessage, data) }) + this.connection.on('ledgerClosed', (ledger) => { + this.emit('ledgerClosed', ledger) + }) + + this.connection.on('transaction', (tx) => { + this.emit('transaction', tx) + }) + + this.connection.on('validationReceived', (validation) => { + this.emit('validationReceived', validation) + }) + + this.connection.on('manifestReceived', (manifest) => { + this.emit('manifestReceived', manifest) + }) + + this.connection.on('peerStatusChange', (status) => { + this.emit('peerStatusChange', status) + }) + + this.connection.on('consensusPhase', (consensus) => { + this.emit('consensusPhase', consensus) + }) + + this.connection.on('path_find', (path) => { + this.emit('path_find', path) + }) + this.connection.on('connected', () => { this.emit('connected') }) @@ -282,6 +320,8 @@ class Client extends EventEmitter { public async request( r: SubmitMultisignedRequest, ): Promise + public request(r: SubscribeRequest): Promise + public request(r: UnsubscribeRequest): Promise public async request( r: TransactionEntryRequest, ): Promise @@ -351,6 +391,23 @@ class Client extends EventEmitter { return this.connection.request(nextPageRequest) as unknown as U } + public on(event: 'ledgerClosed', listener: (ledger: LedgerStream) => void) + public on( + event: 'validationReceived', + listener: (validation: ValidationStream) => void, + ) + public on(event: 'transaction', listener: (tx: TransactionStream) => void) + public on( + event: 'peerStatusChange', + listener: (status: PeerStatusStream) => void, + ) + public on(event: 'consensusPhase', listener: (phase: ConsensusStream) => void) + public on(event: 'path_find', listener: (path: PathFindStream) => void) + public on(event: string, listener: (...args: any[]) => void) + public on(eventName: string, listener: (...args: any[]) => void) { + return super.on(eventName, listener) + } + /** * Prepare a transaction. * diff --git a/src/models/methods/index.ts b/src/models/methods/index.ts index 015a16dc..0bb2bfaf 100644 --- a/src/models/methods/index.ts +++ b/src/models/methods/index.ts @@ -46,6 +46,7 @@ import { ConsensusStream, LedgerStream, OrderBookStream, + PathFindStream, PeerStatusStream, Stream, SubscribeRequest, @@ -203,6 +204,7 @@ export { LedgerStream, ValidationStream, TransactionStream, + PathFindStream, PeerStatusStream, OrderBookStream, ConsensusStream, diff --git a/src/models/methods/subscribe.ts b/src/models/methods/subscribe.ts index d3a3c6d7..fbb3c2df 100644 --- a/src/models/methods/subscribe.ts +++ b/src/models/methods/subscribe.ts @@ -1,9 +1,9 @@ import { OfferCreateTransaction } from '../../common/types/objects' -import { Currency, StreamType } from '../common' +import type { Amount, Currency, Path, StreamType } from '../common' import { Transaction } from '../transactions' import TransactionMetadata from '../transactions/metadata' -import { BaseRequest, BaseResponse } from './baseMethod' +import type { BaseRequest, BaseResponse } from './baseMethod' interface Book { taker_gets: Currency @@ -111,10 +111,25 @@ export interface ConsensusStream extends BaseStream { consensus: 'open' | 'establish' | 'accepted' } +export interface PathFindStream extends BaseStream { + type: 'path_find' + source_account: string + destination_account: string + destination_amount: Amount + full_reply: boolean + id: number | string + send_max?: Amount + alternatives: { + paths_computed: Path[] + source_amount: Amount + } +} + export type Stream = | LedgerStream | ValidationStream | TransactionStream + | PathFindStream | PeerStatusStream | OrderBookStream | ConsensusStream diff --git a/test/client/subscribe.ts b/test/client/subscribe.ts new file mode 100644 index 00000000..54e548d5 --- /dev/null +++ b/test/client/subscribe.ts @@ -0,0 +1,103 @@ +import { assert } from 'chai' + +import rippled from '../fixtures/rippled' +import setupClient from '../setupClient' + +describe('Subscription', function () { + beforeEach(setupClient.setup) + afterEach(setupClient.teardown) + + it('Successfully Subscribes', async function () { + this.mockRippled.addResponse('subscribe', rippled.subscribe.success) + + const result = await this.client.request({ + command: 'subscribe', + }) + + assert.equal(result.status, 'success') + }) + + it('Successfully Unsubscribes', async function () { + this.mockRippled.addResponse('unsubscribe', rippled.unsubscribe) + + const result = await this.client.request({ + command: 'unsubscribe', + }) + + assert.equal(result.status, 'success') + }) + + it('Emits transaction', async function (done) { + this.client.on('transaction', (tx) => { + assert(tx.type === 'transaction') + done() + }) + + this.client.connection.onMessage( + JSON.stringify(rippled.streams.transaction), + ) + }) + + it('Emits ledger', async function (done) { + this.client.on('ledgerClosed', (ledger) => { + assert(ledger.type === 'ledgerClosed') + done() + }) + + this.client.connection.onMessage(JSON.stringify(rippled.streams.ledger)) + }) + + it('Emits peerStatusChange', async function (done) { + this.client.on('peerStatusChange', (status) => { + assert(status.type === 'peerStatusChange') + done() + }) + + this.client.connection.onMessage(JSON.stringify(rippled.streams.peerStatus)) + }) + + it('Emits consensusPhase', async function (done) { + this.client.on('consensusPhase', (phase) => { + assert(phase.type === 'consensusPhase') + done() + }) + + this.client.connection.onMessage(JSON.stringify(rippled.streams.consensus)) + }) + + it('Emits path_find', async function (done) { + this.client.on('path_find', (path) => { + assert(path.type === 'path_find') + done() + }) + + this.client.connection.onMessage(JSON.stringify(rippled.streams.pathFind)) + }) + + it('Emits peerStatusChange', async function (done) { + this.client.on('peerStatusChange', (path) => { + assert(path.type === 'peerStatusChange') + done() + }) + + this.client.connection.onMessage(JSON.stringify(rippled.streams.peerStatus)) + }) + + it('Emits validationReceived', async function (done) { + this.client.on('validationReceived', (path) => { + assert(path.type === 'validationReceived') + done() + }) + + this.client.connection.onMessage(JSON.stringify(rippled.streams.validation)) + }) + + it('Emits manifestReceived', async function (done) { + this.client.on('manifestReceived', (path) => { + assert(path.type === 'manifestReceived') + done() + }) + + this.client.connection.onMessage(JSON.stringify(rippled.streams.manifest)) + }) +}) diff --git a/test/fixtures/rippled/index.ts b/test/fixtures/rippled/index.ts index 7853c4f2..3ae8b986 100644 --- a/test/fixtures/rippled/index.ts +++ b/test/fixtures/rippled/index.ts @@ -20,76 +20,84 @@ import errorLedgerEntry from './ledgerEntryError.json' import notFound from './ledgerNotFound.json' import pre2014withPartial from './ledgerPre2014WithPartial.json' import withoutCloseTime from './ledgerWithoutCloseTime.json' -import withPartialPayment from "./ledgerWithPartialPayment.json"; -import withSettingsTx from "./ledgerWithSettingsTx.json"; -import withStateAsHashes from "./ledgerWithStateAsHashes.json"; +import withPartialPayment from './ledgerWithPartialPayment.json' +import withSettingsTx from './ledgerWithSettingsTx.json' +import withStateAsHashes from './ledgerWithStateAsHashes.json' +import generate from './pathFind' +import sendAll from './pathFindSendAll.json' +import sendUSD from './pathFindSendUsd.json' +import srcActNotFound from './pathFindSrcActNotFound.json' +import sourceAmountLow from './pathFindSrcAmtLow.json' +import XrpToXrp from './pathFindXrpToXrp.json' +import normalPayChan from './paymentChannel.json' +import fullPayChan from './paymentChannelFull.json' import normalServerInfo from './serverInfo.json' import errorServerInfo from './serverInfoError.json' import highLoadFactor from './serverInfoHighLoadFactor.json' -import noValidated from "./serverInfoNoValidated.json"; -import successSubscribe from "./subscribe.json"; -import errorSubscribe from "./subscribeError.json"; -import unsubscribe from "./unsubscribe.json"; -import Payment from './tx/payment.json' +import noValidated from './serverInfoNoValidated.json' +import reporting from './serverInfoReporting.json' +import syncing from './serverInfoSyncing.json' +import consensusStream from './streams/consensusPhase.json' +import ledgerStream from './streams/ledger.json' +import manifestStream from './streams/manifest.json' +import pathFindStream from './streams/pathFind.json' +import peerStatusStream from './streams/peerStatusChange.json' +import serverStatusStream from './streams/serverStatus.json' +import transactionStream from './streams/transaction.json' +import validationStream from './streams/validation.json' +import successSubmit from './submit.json' +import failureSubmit from './submitFailed.json' +import successSubscribe from './subscribe.json' +import errorSubscribe from './subscribeError.json' +import AccountDelete from './tx/accountDelete.json' +import AccountDeleteWithMemo from './tx/accountDeleteWithMemo.json' import AccountSet from './tx/accountSet.json' -import AccountSetTrackingOn from './tx/accountSetTrackingOn.json' import AccountSetTrackingOff from './tx/accountSetTrackingOff.json' -import RegularKey from './tx/setRegularKey.json' -import OfferCreate from './tx/offerCreate.json' -import OfferCreateWithMemo from './tx/offerCreateWithMemo.json' -import OfferCreateSell from './tx/offerCreateSell.json' -import OfferCancel from './tx/offerCancel.json' -import OfferCancelWithMemo from './tx/offerCancelWithMemo.json' -import TrustSet from './tx/trustSet.json' -import TrustSetFrozenOff from './tx/trustSetFrozenOff.json' -import TrustSetNoQuality from './tx/trustSetNoQuality.json' -import TrustSetAddMemo from './tx/trustSetAddMemo.json' -import NotFound from './tx/notFound.json' -import NoLedgerIndex from './tx/noLedgerIndex.json' -import NoLedgerFound from './tx/noLedgerFound.json' -import LedgerWithoutTime from './tx/ledgerWithoutTime.json' -import NotValidated from './tx/notValidated.json' -import OfferWithExpiration from './tx/orderWithExpiration.json' -import CheckCreate from './tx/checkCreate.json' -import CheckCreateWithMemo from './tx/checkCreateWithMemo.json' +import AccountSetTrackingOn from './tx/accountSetTrackingOn.json' +import Amendment from './tx/amendment.json' import CheckCancel from './tx/checkCancel.json' import CheckCancelWithMemo from './tx/checkCancelWithMemo.json' import CheckCash from './tx/checkCash.json' import CheckCashWithMemo from './tx/checkCashWithMemo.json' -import EscrowCreation from './tx/escrowCreation.json' +import CheckCreate from './tx/checkCreate.json' +import CheckCreateWithMemo from './tx/checkCreateWithMemo.json' +import DepositPreauthWithMemo from './tx/depositPreauthWithMemo.json' import EscrowCancellation from './tx/escrowCancellation.json' +import EscrowCreation from './tx/escrowCreation.json' import EscrowExecution from './tx/escrowExecution.json' import EscrowExecutionSimple from './tx/escrowExecutionSimple.json' +import LedgerWithoutTime from './tx/ledgerWithoutTime.json' +import LedgerZero from './tx/ledgerZero.json' +import NoLedgerFound from './tx/noLedgerFound.json' +import NoLedgerIndex from './tx/noLedgerIndex.json' +import NoMeta from './tx/noMeta.json' +import NotFound from './tx/notFound.json' +import NotValidated from './tx/notValidated.json' +import OfferCancel from './tx/offerCancel.json' +import OfferCancelWithMemo from './tx/offerCancelWithMemo.json' +import OfferCreate from './tx/offerCreate.json' +import OfferCreateSell from './tx/offerCreateSell.json' +import OfferCreateWithMemo from './tx/offerCreateWithMemo.json' +import OfferWithExpiration from './tx/orderWithExpiration.json' +import Payment from './tx/payment.json' +import PaymentChannelClaim from './tx/paymentChannelClaim.json' +import PaymentChannelClaimWithMemo from './tx/paymentChannelClaimWithMemo.json' import PaymentChannelCreate from './tx/paymentChannelCreate.json' import PaymentChannelCreateWithMemo from './tx/paymentChannelCreateWithMemo.json' import PaymentChannelFund from './tx/paymentChannelFund.json' import PaymentChannelFundWithMemo from './tx/paymentChannelFundWithMemo.json' -import PaymentChannelClaim from './tx/paymentChannelClaim.json' -import PaymentChannelClaimWithMemo from './tx/paymentChannelClaimWithMemo.json' -import Unrecognized from './tx/unrecognized.json' -import NoMeta from './tx/noMeta.json' -import LedgerZero from './tx/ledgerZero.json' -import Amendment from './tx/amendment.json' import SetFee from './tx/setFee.json' import SetFeeWithMemo from './tx/setFeeWithMemo.json' +import RegularKey from './tx/setRegularKey.json' import TicketCreateWithMemo from './tx/ticketCreateWithMemo.json' -import DepositPreauthWithMemo from './tx/depositPreauthWithMemo.json' -import AccountDelete from './tx/accountDelete.json' -import AccountDeleteWithMemo from './tx/accountDeleteWithMemo.json' +import TrustSet from './tx/trustSet.json' +import TrustSetAddMemo from './tx/trustSetAddMemo.json' +import TrustSetFrozenOff from './tx/trustSetFrozenOff.json' +import TrustSetNoQuality from './tx/trustSetNoQuality.json' +import Unrecognized from './tx/unrecognized.json' import WithMemo from './tx/withMemo.json' import WithMemos from './tx/withMemos.json' -import syncing from './serverInfoSyncing.json' -import reporting from './serverInfoReporting.json' -import normalPayChan from './paymentChannel.json' -import fullPayChan from './paymentChannelFull.json' -import generate from './pathFind' -import sendUSD from './pathFindSendUsd.json' -import sendAll from './pathFindSendAll.json' -import XrpToXrp from './pathFindXrpToXrp.json' -import srcActNotFound from './pathFindSrcActNotFound.json' -import sourceAmountLow from './pathFindSrcAmtLow.json' -import successSubmit from './submit.json' -import failureSubmit from './submitFailed.json' +import unsubscribe from './unsubscribe.json' const submit = { success: successSubmit, @@ -112,6 +120,17 @@ const subscribe = { error: errorSubscribe, } +const streams = { + ledger: ledgerStream, + transaction: transactionStream, + consensus: consensusStream, + pathFind: pathFindStream, + peerStatus: peerStatusStream, + serverStatus: serverStatusStream, + validation: validationStream, + manifest: manifestStream, +} + const account_objects = { normal: normalAccountObjects, // notfound: notfoundAccountObjects @@ -233,6 +252,7 @@ const rippled = { path_find, payment_channel, server_info, + streams, submit, subscribe, tx, diff --git a/test/fixtures/rippled/streams/consensusPhase.json b/test/fixtures/rippled/streams/consensusPhase.json new file mode 100644 index 00000000..b76c423f --- /dev/null +++ b/test/fixtures/rippled/streams/consensusPhase.json @@ -0,0 +1,4 @@ +{ + "type": "consensusPhase", + "consensus": "accepted" +} diff --git a/test/fixtures/rippled/streams/ledger.json b/test/fixtures/rippled/streams/ledger.json new file mode 100644 index 00000000..05a382ec --- /dev/null +++ b/test/fixtures/rippled/streams/ledger.json @@ -0,0 +1,12 @@ +{ + "fee_base": 10, + "fee_ref": 10, + "ledger_hash": "B3980C722D71873D6708723E71B7A28C826BC66C58712ADCEC61603415305CD1", + "ledger_index": 66093872, + "ledger_time": 683942720, + "reserve_base": 20000000, + "reserve_inc": 5000000, + "txn_count": 70, + "type": "ledgerClosed", + "validated_ledgers": "65201743-66093872" +} diff --git a/test/fixtures/rippled/streams/manifest.json b/test/fixtures/rippled/streams/manifest.json new file mode 100644 index 00000000..65b1e87f --- /dev/null +++ b/test/fixtures/rippled/streams/manifest.json @@ -0,0 +1,3 @@ +{ + "type": "manifestReceived" +} diff --git a/test/fixtures/rippled/streams/pathFind.json b/test/fixtures/rippled/streams/pathFind.json new file mode 100644 index 00000000..3732cfe5 --- /dev/null +++ b/test/fixtures/rippled/streams/pathFind.json @@ -0,0 +1,65 @@ +{ + "alternatives": [ + { + "paths_computed": [ + [ + { + "currency": "USD", + "issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", + "type": 48 + } + ], + [ + { + "currency": "USD", + "issuer": "rhub8VRN55s94qWKDv6jmDy1pUykJzF3wq", + "type": 48 + }, + { + "currency": "USD", + "issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", + "type": 48 + } + ], + [ + { + "currency": "USD", + "issuer": "rhub8VRN55s94qWKDv6jmDy1pUykJzF3wq", + "type": 48 + }, + { + "account": "rhub8VRN55s94qWKDv6jmDy1pUykJzF3wq", + "type": 1 + }, + { + "account": "rpix35SSFEukMTm64NB4k4BPBS7fXJrLJM", + "type": 1 + } + ], + [ + { + "currency": "CNY", + "issuer": "rKiCet8SdvWxPXnAgYarFUXMh1zCPz432Y", + "type": 48 + }, + { + "currency": "USD", + "issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", + "type": 48 + } + ] + ], + "source_amount": "786" + } + ], + "destination_account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn", + "destination_amount": { + "currency": "USD", + "issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", + "value": "0.001" + }, + "full_reply": true, + "id": 8, + "source_account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn", + "type": "path_find" +} diff --git a/test/fixtures/rippled/streams/peerStatusChange.json b/test/fixtures/rippled/streams/peerStatusChange.json new file mode 100644 index 00000000..54e05f7f --- /dev/null +++ b/test/fixtures/rippled/streams/peerStatusChange.json @@ -0,0 +1,9 @@ +{ + "action": "CLOSING_LEDGER", + "date": 508546525, + "ledger_hash": "4D4CD9CD543F0C1EF023CC457F5BEFEA59EEF73E4552542D40E7C4FA08D3C320", + "ledger_index": 18853106, + "ledger_index_max": 18853106, + "ledger_index_min": 18852082, + "type": "peerStatusChange" +} diff --git a/test/fixtures/rippled/streams/serverStatus.json b/test/fixtures/rippled/streams/serverStatus.json new file mode 100644 index 00000000..1450ae02 --- /dev/null +++ b/test/fixtures/rippled/streams/serverStatus.json @@ -0,0 +1,11 @@ +{ + "base_fee": 10, + "load_base": 256, + "load_factor": 256, + "load_factor_fee_escalation": 256, + "load_factor_fee_queue": 256, + "load_factor_fee_reference": 256, + "load_factor_server": 256, + "server_status": "full", + "type": "serverStatus" +} diff --git a/test/fixtures/rippled/streams/transaction.json b/test/fixtures/rippled/streams/transaction.json new file mode 100644 index 00000000..9c6caf9d --- /dev/null +++ b/test/fixtures/rippled/streams/transaction.json @@ -0,0 +1,132 @@ +{ + "engine_result": "tesSUCCESS", + "engine_result_code": 0, + "engine_result_message": "The transaction was applied. Only final in a validated ledger.", + "ledger_hash": "922099A5528EFDF820ABFAB0CAAB8647DF6E7103B3BA8CDD3A6D56EAF1B39B3B", + "ledger_index": 66093882, + "meta": { + "AffectedNodes": [ + { + "DeletedNode": { + "FinalFields": { + "Account": "rnruxxLTbJUMNtFNBJ7X2xSiy1KE7ajUuH", + "BookDirectory": "623C4C4AD65873DA787AC85A0A1385FE6233B6DE100799474F1E3E58B40BAC52", + "BookNode": "0", + "Flags": 0, + "OwnerNode": "0", + "PreviousTxnID": "E3E2E94FE181C5F5E03E2FE5347C4E8E27E18290FF3B7FA6BA9B124AD54F147D", + "PreviousTxnLgrSeq": 66093873, + "Sequence": 18466973, + "TakerGets": "9416365482", + "TakerPays": { + "currency": "CNY", + "issuer": "rJ1adrpGS3xsnQMb9Cw54tWJVFPuSdZHK", + "value": "80159.63607543072" + } + }, + "LedgerEntryType": "Offer", + "LedgerIndex": "3A93F99B4CB2F4FB0F4F5182E85C37855611E6470262DF63896B6E0AA4231AE0" + } + }, + { + "CreatedNode": { + "LedgerEntryType": "DirectoryNode", + "LedgerIndex": "623C4C4AD65873DA787AC85A0A1385FE6233B6DE100799474F1E2BD6998872D5", + "NewFields": { + "ExchangeRate": "4f1e2bd6998872d5", + "RootIndex": "623C4C4AD65873DA787AC85A0A1385FE6233B6DE100799474F1E2BD6998872D5", + "TakerPaysCurrency": "000000000000000000000000434E590000000000", + "TakerPaysIssuer": "0360E3E0751BD9A566CD03FA6CAFC78118B82BA0" + } + } + }, + { + "DeletedNode": { + "FinalFields": { + "ExchangeRate": "4f1e3e58b40bac52", + "Flags": 0, + "RootIndex": "623C4C4AD65873DA787AC85A0A1385FE6233B6DE100799474F1E3E58B40BAC52", + "TakerGetsCurrency": "0000000000000000000000000000000000000000", + "TakerGetsIssuer": "0000000000000000000000000000000000000000", + "TakerPaysCurrency": "000000000000000000000000434E590000000000", + "TakerPaysIssuer": "0360E3E0751BD9A566CD03FA6CAFC78118B82BA0" + }, + "LedgerEntryType": "DirectoryNode", + "LedgerIndex": "623C4C4AD65873DA787AC85A0A1385FE6233B6DE100799474F1E3E58B40BAC52" + } + }, + { + "CreatedNode": { + "LedgerEntryType": "Offer", + "LedgerIndex": "8934A20864E420B7D0F6CDC61F5D8D2E609DEB8E25D3CB26A1B595032483A4C8", + "NewFields": { + "Account": "rnruxxLTbJUMNtFNBJ7X2xSiy1KE7ajUuH", + "BookDirectory": "623C4C4AD65873DA787AC85A0A1385FE6233B6DE100799474F1E2BD6998872D5", + "Sequence": 18466977, + "TakerGets": "8221180253", + "TakerPays": { + "currency": "CNY", + "issuer": "rJ1adrpGS3xsnQMb9Cw54tWJVFPuSdZHK", + "value": "69817.9622410017" + } + } + } + }, + { + "ModifiedNode": { + "FinalFields": { + "Account": "rnruxxLTbJUMNtFNBJ7X2xSiy1KE7ajUuH", + "Balance": "5116214416", + "Flags": 0, + "OwnerCount": 5, + "Sequence": 18466978 + }, + "LedgerEntryType": "AccountRoot", + "LedgerIndex": "9AC13F682F58D555C134D098EEEE1A14BECB904C65ACBBB0046B35B405E66A75", + "PreviousFields": { + "Balance": "5116214428", + "Sequence": 18466977 + }, + "PreviousTxnID": "48DF68A5C9D50C2CB2FE750E3D3A40B041FDD12FD2185DF4F97B2A0CA379DCB0", + "PreviousTxnLgrSeq": 66093873 + } + }, + { + "ModifiedNode": { + "FinalFields": { + "Flags": 0, + "Owner": "rnruxxLTbJUMNtFNBJ7X2xSiy1KE7ajUuH", + "RootIndex": "FBD0BC6A9DCBC5AEFB9C773EE6351AF11E244DBD1370EDF6801FD607F01D3DF8" + }, + "LedgerEntryType": "DirectoryNode", + "LedgerIndex": "FBD0BC6A9DCBC5AEFB9C773EE6351AF11E244DBD1370EDF6801FD607F01D3DF8" + } + } + ], + "TransactionIndex": 40, + "TransactionResult": "tesSUCCESS" + }, + "status": "closed", + "transaction": { + "Account": "rnruxxLTbJUMNtFNBJ7X2xSiy1KE7ajUuH", + "Fee": "12", + "Flags": 0, + "LastLedgerSequence": 66093884, + "OfferSequence": 18466973, + "Sequence": 18466977, + "SigningPubKey": "026B8A4318970123B0BB3DC528C4DA62C874AD4A01F399DBEF21D621DDC32F6C81", + "TakerGets": "8221180253", + "TakerPays": { + "currency": "CNY", + "issuer": "rJ1adrpGS3xsnQMb9Cw54tWJVFPuSdZHK", + "value": "69817.9622410017" + }, + "TransactionType": "OfferCreate", + "TxnSignature": "304402200E0821A9FC8A0A7CA72DC0CEC3BD2AC1317A8DCFAAE1F27EB7C69C79EB475DD3022046BBFA7DFAD9B7186CAEA798358C0959014B27B2B1EF3D6CCEF5EC0EA346D692", + "date": 683942752, + "hash": "775266C42CED11D5FC6DB61686177FCEA689E7A79E6B0017586E95FA3E9EDD10", + "owner_funds": "5071214380" + }, + "type": "transaction", + "validated": true +} diff --git a/test/fixtures/rippled/streams/validation.json b/test/fixtures/rippled/streams/validation.json new file mode 100644 index 00000000..1d3b9f44 --- /dev/null +++ b/test/fixtures/rippled/streams/validation.json @@ -0,0 +1,22 @@ +{ + "type": "validationReceived", + "amendments":[ + "42426C4D4F1009EE67080A9B7965B44656D7714D104A72F9B4369F97ABF044EE", + "4C97EBA926031A7CF7D7B36FDE3ED66DDA5421192D63DE53FFB46E43B9DC8373", + "6781F8368C4771B83E8B821D88F580202BCB4228075297B19E4FDC5233F1EFDC", + "C1B8D934087225F509BEB5A8EC24447854713EE447D277F69545ABFA0E0FD490", + "DA1BD556B42D85EA9C84066D028D355B52416734D3283F85E216EA5DA6DB7E13" + ], + "base_fee":10, + "flags":2147483649, + "full":true, + "ledger_hash":"EC02890710AAA2B71221B0D560CFB22D64317C07B7406B02959AD84BAD33E602", + "ledger_index":"6", + "load_fee":256000, + "master_key": "nHUon2tpyJEHHYGmxqeGu37cvPYHzrMtUNQFVdCgGNvEkjmCpTqK", + "reserve_base":20000000, + "reserve_inc":5000000, + "signature":"3045022100E199B55643F66BC6B37DBC5E185321CF952FD35D13D9E8001EB2564FFB94A07602201746C9A4F7A93647131A2DEB03B76F05E426EC67A5A27D77F4FF2603B9A528E6", + "signing_time":515115322, + "validation_public_key":"n94Gnc6svmaPPRHUAyyib1gQUov8sYbjLoEwUBYPH39qHZXuo8ZT" +}