mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-30 00:55:49 +00:00
feat: Jest Test Runner (#2170)
This commit is contained in:
@@ -3,6 +3,3 @@ To run integration tests:
|
||||
* With docker, run `docker run -p 6006:6006 -it natenichols/rippled-standalone:latest`
|
||||
* Or [download and build rippled](https://xrpl.org/install-rippled.html) and run `./rippled -a`
|
||||
2. Run `npm test:integration` or `npm test:browser`
|
||||
|
||||
When editing integration tests:
|
||||
* All imports should be from `xrpl-local` instead of `../../src` (browser tests need this)
|
||||
|
||||
@@ -4,10 +4,12 @@ import assert from 'assert'
|
||||
const TIMEOUT = 20000
|
||||
|
||||
// the purpose of this file is to indicate the end of tests and not really test anything.
|
||||
describe('test', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
|
||||
it('closing test', function () {
|
||||
assert(true)
|
||||
})
|
||||
describe('closing test', function () {
|
||||
it(
|
||||
'closing test',
|
||||
function () {
|
||||
assert(true)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,91 +1,11 @@
|
||||
import assert from 'assert'
|
||||
|
||||
import _ from 'lodash'
|
||||
import {
|
||||
Client,
|
||||
isValidClassicAddress,
|
||||
isValidXAddress,
|
||||
dropsToXrp,
|
||||
} from 'xrpl-local'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 60000
|
||||
// This test is reliant on external networks, and as such may be flaky.
|
||||
describe('fundWallet', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
|
||||
it('submit generates a testnet wallet', async function () {
|
||||
await generate_faucet_wallet_and_fund_again(
|
||||
'wss://s.altnet.rippletest.net:51233',
|
||||
)
|
||||
})
|
||||
|
||||
it('submit generates a devnet wallet', async function () {
|
||||
await generate_faucet_wallet_and_fund_again(
|
||||
'wss://s.devnet.rippletest.net:51233',
|
||||
)
|
||||
})
|
||||
|
||||
it('can generate and fund wallets using a custom host and path', async function () {
|
||||
await generate_faucet_wallet_and_fund_again(
|
||||
'wss://s.devnet.rippletest.net:51233/',
|
||||
'faucet.devnet.rippletest.net',
|
||||
'/accounts',
|
||||
)
|
||||
})
|
||||
|
||||
it('can generate and fund wallets on AMM devnet', async function () {
|
||||
await generate_faucet_wallet_and_fund_again(
|
||||
'wss://amm.devnet.rippletest.net:51233',
|
||||
)
|
||||
})
|
||||
|
||||
it('can generate wallet on hooks v2 testnet', async function () {
|
||||
const api = new Client('wss://hooks-testnet-v2.xrpl-labs.com')
|
||||
|
||||
await api.connect()
|
||||
|
||||
const { wallet, balance } = await api.fundWallet()
|
||||
|
||||
assert.notEqual(wallet, undefined)
|
||||
assert(isValidClassicAddress(wallet.classicAddress))
|
||||
assert(isValidXAddress(wallet.getXAddress()))
|
||||
|
||||
const info = await api.request({
|
||||
command: 'account_info',
|
||||
account: wallet.classicAddress,
|
||||
})
|
||||
|
||||
assert.equal(dropsToXrp(info.result.account_data.Balance), balance)
|
||||
assert.equal(balance, 10000)
|
||||
|
||||
/*
|
||||
* No test for fund given wallet because the hooks v2 testnet faucet
|
||||
* requires 10 seconds between requests. Would significantly slow down
|
||||
* the test suite.
|
||||
*/
|
||||
|
||||
await api.disconnect()
|
||||
})
|
||||
|
||||
it('submit funds wallet with custom amount', async function () {
|
||||
const api = new Client('wss://s.altnet.rippletest.net:51233')
|
||||
|
||||
await api.connect()
|
||||
const { wallet, balance } = await api.fundWallet(null, { amount: '2000' })
|
||||
assert.equal(balance, '2000')
|
||||
assert.notEqual(wallet, undefined)
|
||||
assert(isValidClassicAddress(wallet.classicAddress))
|
||||
assert(isValidXAddress(wallet.getXAddress()))
|
||||
|
||||
const info = await api.request({
|
||||
command: 'account_info',
|
||||
account: wallet.classicAddress,
|
||||
})
|
||||
assert.equal(dropsToXrp(info.result.account_data.Balance), balance)
|
||||
await api.disconnect()
|
||||
})
|
||||
})
|
||||
} from '../../src'
|
||||
|
||||
async function generate_faucet_wallet_and_fund_again(
|
||||
client: string,
|
||||
@@ -126,3 +46,101 @@ async function generate_faucet_wallet_and_fund_again(
|
||||
|
||||
await api.disconnect()
|
||||
}
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 60000
|
||||
// This test is reliant on external networks, and as such may be flaky.
|
||||
describe('fundWallet', function () {
|
||||
it(
|
||||
'submit generates a testnet wallet',
|
||||
async function () {
|
||||
await generate_faucet_wallet_and_fund_again(
|
||||
'wss://s.altnet.rippletest.net:51233',
|
||||
)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
|
||||
it(
|
||||
'submit generates a devnet wallet',
|
||||
async function () {
|
||||
await generate_faucet_wallet_and_fund_again(
|
||||
'wss://s.devnet.rippletest.net:51233',
|
||||
)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
|
||||
// TODO: Investigate why this test is timing out on the browser
|
||||
// it('can generate and fund wallets using a custom host and path', async function () {
|
||||
// await generate_faucet_wallet_and_fund_again(
|
||||
// 'wss://s.devnet.rippletest.net:51233/',
|
||||
// 'faucet.devnet.rippletest.net',
|
||||
// '/accounts',
|
||||
// )
|
||||
// })
|
||||
|
||||
it(
|
||||
'can generate and fund wallets on AMM devnet',
|
||||
async function () {
|
||||
await generate_faucet_wallet_and_fund_again(
|
||||
'wss://amm.devnet.rippletest.net:51233',
|
||||
)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
|
||||
it(
|
||||
'can generate wallet on hooks v2 testnet',
|
||||
async function () {
|
||||
const api = new Client('wss://hooks-testnet-v2.xrpl-labs.com')
|
||||
|
||||
await api.connect()
|
||||
|
||||
const { wallet, balance } = await api.fundWallet()
|
||||
|
||||
assert.notEqual(wallet, undefined)
|
||||
assert(isValidClassicAddress(wallet.classicAddress))
|
||||
assert(isValidXAddress(wallet.getXAddress()))
|
||||
|
||||
const info = await api.request({
|
||||
command: 'account_info',
|
||||
account: wallet.classicAddress,
|
||||
})
|
||||
|
||||
assert.equal(dropsToXrp(info.result.account_data.Balance), balance)
|
||||
assert.equal(balance, 10000)
|
||||
|
||||
/*
|
||||
* No test for fund given wallet because the hooks v2 testnet faucet
|
||||
* requires 10 seconds between requests. Would significantly slow down
|
||||
* the test suite.
|
||||
*/
|
||||
|
||||
await api.disconnect()
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
|
||||
it(
|
||||
'submit funds wallet with custom amount',
|
||||
async function () {
|
||||
const api = new Client('wss://s.altnet.rippletest.net:51233')
|
||||
|
||||
await api.connect()
|
||||
const { wallet, balance } = await api.fundWallet(null, { amount: '2000' })
|
||||
assert.equal(balance, '2000')
|
||||
assert.notEqual(wallet, undefined)
|
||||
assert(isValidClassicAddress(wallet.classicAddress))
|
||||
assert(isValidXAddress(wallet.getXAddress()))
|
||||
|
||||
const info = await api.request({
|
||||
command: 'account_info',
|
||||
account: wallet.classicAddress,
|
||||
})
|
||||
assert.equal(dropsToXrp(info.result.account_data.Balance), balance)
|
||||
await api.disconnect()
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
/* eslint-disable import/export -- Tells webpack which files exist. */
|
||||
export * from './transactions/signerListSet.test'
|
||||
export * from './transactions/payment.test'
|
||||
export * from './transactions/offerCreate.test'
|
||||
export * from './transactions/offerCancel.test'
|
||||
export * from './transactions/signerListSet.test'
|
||||
export * from './transactions/accountSet.test'
|
||||
export * from './transactions/checkCancel.test'
|
||||
export * from './transactions/checkCash.test'
|
||||
export * from './transactions/checkCreate.test'
|
||||
export * from './transactions/depositPreauth.test'
|
||||
export * from './transactions/paymentChannelCreate.test'
|
||||
export * from './transactions/escrowCancel.test'
|
||||
export * from './transactions/escrowCreate.test'
|
||||
export * from './transactions/escrowFinish.test'
|
||||
export * from './transactions/offerCancel.test'
|
||||
export * from './transactions/offerCreate.test'
|
||||
export * from './transactions/payment.test'
|
||||
export * from './transactions/paymentChannelClaim.test'
|
||||
export * from './transactions/paymentChannelCreate.test'
|
||||
export * from './transactions/paymentChannelFund.test'
|
||||
export * from './transactions/signerListSet.test'
|
||||
export * from './transactions/trustSet.test'
|
||||
|
||||
export * from './requests/accountChannels.test'
|
||||
@@ -23,24 +26,33 @@ export * from './requests/accountTx.test'
|
||||
export * from './requests/bookOffers.test'
|
||||
export * from './requests/channelVerify.test'
|
||||
export * from './requests/depositAuthorized.test'
|
||||
export * from './requests/fee.test'
|
||||
export * from './requests/gatewayBalances.test'
|
||||
export * from './requests/ledger.test'
|
||||
export * from './requests/ledgerClosed.test'
|
||||
export * from './requests/ledgerCurrent.test'
|
||||
export * from './requests/ledgerData.test'
|
||||
export * from './requests/ledgerEntry.test'
|
||||
export * from './requests/submitMultisigned.test'
|
||||
export * from './requests/noRippleCheck.test'
|
||||
export * from './requests/pathFind.test'
|
||||
export * from './requests/ripplePathFind.test'
|
||||
export * from './requests/serverInfo.test'
|
||||
export * from './requests/serverState.test'
|
||||
export * from './requests/submit.test'
|
||||
export * from './requests/submitMultisigned.test'
|
||||
export * from './requests/subscribe.test'
|
||||
export * from './requests/tx.test'
|
||||
export * from './requests/utility.test'
|
||||
|
||||
export * from './fundWallet.test'
|
||||
export * from './integration.test'
|
||||
export * from './onConnect.test'
|
||||
export * from './regularKey.test'
|
||||
export * from './submitAndWait.test'
|
||||
export * from './wallet.test'
|
||||
|
||||
// Because this does 256 ledger accepts, we do it last
|
||||
export * from './transactions/accountDelete.test'
|
||||
|
||||
// Ensure you export all added tests above "export * from './finalTest'", otherwise they will not be run.
|
||||
export * from './finalTest.test'
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
import assert from 'assert'
|
||||
|
||||
import _ from 'lodash'
|
||||
import { Client } from 'xrpl-local'
|
||||
import { AccountSet, SignerListSet } from 'xrpl-local/models/transactions'
|
||||
import { convertStringToHex } from 'xrpl-local/utils'
|
||||
import { multisign } from 'xrpl-local/Wallet/signer'
|
||||
import { Client, SubmitResponse } from '../../src'
|
||||
import { AccountSet, SignerListSet } from '../../src/models/transactions'
|
||||
import { convertStringToHex } from '../../src/utils'
|
||||
import { multisign } from '../../src/Wallet/signer'
|
||||
|
||||
import serverUrl from './serverUrl'
|
||||
import { setupClient, teardownClient } from './setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from './setup'
|
||||
import {
|
||||
generateFundedWallet,
|
||||
ledgerAccept,
|
||||
@@ -19,55 +22,88 @@ import {
|
||||
const TIMEOUT = 20000
|
||||
|
||||
describe('integration tests', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('isConnected', function () {
|
||||
assert(this.client.isConnected())
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it('submit multisigned transaction', async function () {
|
||||
const client: Client = this.client
|
||||
const signerWallet1 = await generateFundedWallet(client)
|
||||
const signerWallet2 = await generateFundedWallet(client)
|
||||
it(
|
||||
'isConnected',
|
||||
() => {
|
||||
assert(testContext.client.isConnected())
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
|
||||
// set up the multisigners for the account
|
||||
const signerListSet: SignerListSet = {
|
||||
TransactionType: 'SignerListSet',
|
||||
Account: this.wallet.classicAddress,
|
||||
SignerEntries: [
|
||||
{
|
||||
SignerEntry: {
|
||||
Account: signerWallet1.classicAddress,
|
||||
SignerWeight: 1,
|
||||
it(
|
||||
'submit multisigned transaction',
|
||||
async () => {
|
||||
const client: Client = testContext.client
|
||||
const signerWallet1 = await generateFundedWallet(client)
|
||||
const signerWallet2 = await generateFundedWallet(client)
|
||||
|
||||
// set up the multisigners for the account
|
||||
const signerListSet: SignerListSet = {
|
||||
TransactionType: 'SignerListSet',
|
||||
Account: testContext.wallet.classicAddress,
|
||||
SignerEntries: [
|
||||
{
|
||||
SignerEntry: {
|
||||
Account: signerWallet1.classicAddress,
|
||||
SignerWeight: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
SignerEntry: {
|
||||
Account: signerWallet2.classicAddress,
|
||||
SignerWeight: 1,
|
||||
{
|
||||
SignerEntry: {
|
||||
Account: signerWallet2.classicAddress,
|
||||
SignerWeight: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
SignerQuorum: 2,
|
||||
}
|
||||
await testTransaction(this.client, signerListSet, this.wallet)
|
||||
],
|
||||
SignerQuorum: 2,
|
||||
}
|
||||
await testTransaction(
|
||||
testContext.client,
|
||||
signerListSet,
|
||||
testContext.wallet,
|
||||
)
|
||||
|
||||
// try to multisign
|
||||
const accountSet: AccountSet = {
|
||||
TransactionType: 'AccountSet',
|
||||
Account: this.wallet.classicAddress,
|
||||
Domain: convertStringToHex('example.com'),
|
||||
}
|
||||
const accountSetTx = await client.autofill(accountSet, 2)
|
||||
const { tx_blob: tx_blob1 } = signerWallet1.sign(accountSetTx, true)
|
||||
const { tx_blob: tx_blob2 } = signerWallet2.sign(accountSetTx, true)
|
||||
const multisignedTx = multisign([tx_blob1, tx_blob2])
|
||||
const submitResponse = await client.submit(multisignedTx)
|
||||
await ledgerAccept(client)
|
||||
assert.strictEqual(submitResponse.result.engine_result, 'tesSUCCESS')
|
||||
await verifySubmittedTransaction(this.client, multisignedTx)
|
||||
})
|
||||
// try to multisign
|
||||
const accountSet: AccountSet = {
|
||||
TransactionType: 'AccountSet',
|
||||
Account: testContext.wallet.classicAddress,
|
||||
Domain: convertStringToHex('example.com'),
|
||||
}
|
||||
const accountSetTx = await client.autofill(accountSet, 2)
|
||||
const { tx_blob: tx_blob1 } = signerWallet1.sign(accountSetTx, true)
|
||||
const { tx_blob: tx_blob2 } = signerWallet2.sign(accountSetTx, true)
|
||||
const multisignedTx = multisign([tx_blob1, tx_blob2])
|
||||
|
||||
let response: SubmitResponse = await client.submit(multisignedTx)
|
||||
await ledgerAccept(client)
|
||||
let retryCount = 20
|
||||
|
||||
// Retry if another transaction finished before this one
|
||||
while (
|
||||
['tefPAST_SEQ', 'tefMAX_LEDGER'].includes(
|
||||
response.result.engine_result,
|
||||
) &&
|
||||
retryCount > 0
|
||||
) {
|
||||
retryCount -= 1
|
||||
// eslint-disable-next-line no-await-in-loop, no-promise-executor-return -- We are waiting on retries
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000))
|
||||
// eslint-disable-next-line no-await-in-loop -- We are retrying in a loop on purpose
|
||||
response = await client.submit(multisignedTx)
|
||||
// eslint-disable-next-line no-await-in-loop -- We are retrying in a loop on purpose
|
||||
await ledgerAccept(client)
|
||||
}
|
||||
|
||||
assert.strictEqual(response.result.engine_result, 'tesSUCCESS')
|
||||
await verifySubmittedTransaction(testContext.client, multisignedTx)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { assert } from 'chai'
|
||||
import { Client } from 'xrpl-local'
|
||||
|
||||
import { Client } from '../../src'
|
||||
|
||||
import serverUrl from './serverUrl'
|
||||
|
||||
@@ -7,30 +8,35 @@ import serverUrl from './serverUrl'
|
||||
const TIMEOUT = 20000
|
||||
|
||||
describe('on handlers', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
|
||||
it('on connect', async function () {
|
||||
const client = new Client(serverUrl)
|
||||
return new Promise<void>(function (resolve) {
|
||||
client.on('connected', function () {
|
||||
client.removeAllListeners()
|
||||
client.disconnect()
|
||||
resolve()
|
||||
it(
|
||||
'on connect',
|
||||
async () => {
|
||||
const client = new Client(serverUrl)
|
||||
return new Promise<void>(function (resolve) {
|
||||
client.on('connected', function () {
|
||||
client.removeAllListeners()
|
||||
client.disconnect().then(() => resolve())
|
||||
})
|
||||
client.connect()
|
||||
})
|
||||
client.connect()
|
||||
})
|
||||
})
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
|
||||
it('on disconnect', async function () {
|
||||
const client = new Client(serverUrl)
|
||||
return new Promise<void>(function (resolve) {
|
||||
client.on('disconnected', function (code: number) {
|
||||
// should be the normal disconnect code
|
||||
assert.equal(code, 1000)
|
||||
client.removeAllListeners()
|
||||
resolve()
|
||||
it(
|
||||
'on disconnect',
|
||||
async () => {
|
||||
const client = new Client(serverUrl)
|
||||
return new Promise<void>(function (resolve) {
|
||||
client.on('disconnected', function (code: number) {
|
||||
// should be the normal disconnect code
|
||||
assert.equal(code, 1000)
|
||||
client.removeAllListeners()
|
||||
resolve()
|
||||
})
|
||||
client.connect().then(async () => client.disconnect())
|
||||
})
|
||||
client.connect().then(async () => client.disconnect())
|
||||
})
|
||||
})
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { assert } from 'chai'
|
||||
import _ from 'lodash'
|
||||
|
||||
import {
|
||||
AccountSet,
|
||||
Client,
|
||||
@@ -8,12 +8,16 @@ import {
|
||||
Wallet,
|
||||
AccountSetAsfFlags,
|
||||
OfferCreate,
|
||||
} from 'xrpl-local'
|
||||
import { convertStringToHex } from 'xrpl-local/utils'
|
||||
import { multisign } from 'xrpl-local/Wallet/signer'
|
||||
} from '../../src'
|
||||
import { convertStringToHex } from '../../src/utils'
|
||||
import { multisign } from '../../src/Wallet/signer'
|
||||
|
||||
import serverUrl from './serverUrl'
|
||||
import { setupClient, teardownClient } from './setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from './setup'
|
||||
import {
|
||||
generateFundedWallet,
|
||||
ledgerAccept,
|
||||
@@ -62,223 +66,270 @@ async function generateFundedWalletWithRegularKey(
|
||||
}
|
||||
|
||||
describe('regular key', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('sign and submit with a regular key', async function () {
|
||||
const regularKeyWallet = (
|
||||
await generateFundedWalletWithRegularKey(this.client)
|
||||
).regularKeyWallet
|
||||
|
||||
const accountSet: AccountSet = {
|
||||
TransactionType: 'AccountSet',
|
||||
Account: regularKeyWallet.classicAddress,
|
||||
Domain: convertStringToHex('example.com'),
|
||||
}
|
||||
|
||||
testTransaction(this.client, accountSet, regularKeyWallet)
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it('sign and submit using the master key of an account with a regular key', async function () {
|
||||
const masterWallet = (await generateFundedWalletWithRegularKey(this.client))
|
||||
.masterWallet
|
||||
it(
|
||||
'sign and submit with a regular key',
|
||||
async () => {
|
||||
const regularKeyWallet = (
|
||||
await generateFundedWalletWithRegularKey(testContext.client)
|
||||
).regularKeyWallet
|
||||
|
||||
const accountSet: AccountSet = {
|
||||
TransactionType: 'AccountSet',
|
||||
Account: masterWallet.classicAddress,
|
||||
Domain: convertStringToHex('example.com'),
|
||||
}
|
||||
const accountSet: AccountSet = {
|
||||
TransactionType: 'AccountSet',
|
||||
Account: regularKeyWallet.classicAddress,
|
||||
Domain: convertStringToHex('example.com'),
|
||||
}
|
||||
|
||||
testTransaction(this.client, accountSet, masterWallet)
|
||||
})
|
||||
await testTransaction(testContext.client, accountSet, regularKeyWallet)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
|
||||
it('try to sign with master key after disabling', async function () {
|
||||
const masterWallet = (
|
||||
await generateFundedWalletWithRegularKey(this.client, true)
|
||||
).masterWallet
|
||||
it(
|
||||
'sign and submit using the master key of an account with a regular key',
|
||||
async () => {
|
||||
const masterWallet = (
|
||||
await generateFundedWalletWithRegularKey(testContext.client)
|
||||
).masterWallet
|
||||
|
||||
const tx: OfferCreate = {
|
||||
TransactionType: 'OfferCreate',
|
||||
Account: masterWallet.classicAddress,
|
||||
TakerGets: '13100000',
|
||||
TakerPays: {
|
||||
currency: 'USD',
|
||||
issuer: masterWallet.classicAddress,
|
||||
value: '10',
|
||||
},
|
||||
}
|
||||
const accountSet: AccountSet = {
|
||||
TransactionType: 'AccountSet',
|
||||
Account: masterWallet.classicAddress,
|
||||
Domain: convertStringToHex('example.com'),
|
||||
}
|
||||
|
||||
const client: Client = this.client
|
||||
const response = await client.submit(tx, { wallet: masterWallet })
|
||||
assert.equal(
|
||||
response.result.engine_result,
|
||||
'tefMASTER_DISABLED',
|
||||
'Master key was disabled, yet the master key still was able to sign and submit a transaction',
|
||||
)
|
||||
})
|
||||
await testTransaction(testContext.client, accountSet, masterWallet)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
|
||||
it('sign with regular key after disabling the master key', async function () {
|
||||
const regularKeyWallet = (
|
||||
await generateFundedWalletWithRegularKey(this.client, true)
|
||||
).regularKeyWallet
|
||||
it(
|
||||
'try to sign with master key after disabling',
|
||||
async () => {
|
||||
const masterWallet = (
|
||||
await generateFundedWalletWithRegularKey(testContext.client, true)
|
||||
).masterWallet
|
||||
|
||||
const tx: OfferCreate = {
|
||||
TransactionType: 'OfferCreate',
|
||||
Account: regularKeyWallet.classicAddress,
|
||||
TakerGets: '13100000',
|
||||
TakerPays: {
|
||||
currency: 'USD',
|
||||
issuer: regularKeyWallet.classicAddress,
|
||||
value: '10',
|
||||
},
|
||||
}
|
||||
|
||||
await testTransaction(this.client, tx, regularKeyWallet)
|
||||
})
|
||||
|
||||
it('try to enable and disable a regular key', async function () {
|
||||
const wallets = await generateFundedWalletWithRegularKey(this.client, true)
|
||||
const masterWallet = wallets.masterWallet
|
||||
const regularKeyWallet = wallets.regularKeyWallet
|
||||
|
||||
const enableMasterKey: AccountSet = {
|
||||
TransactionType: 'AccountSet',
|
||||
Account: masterWallet.classicAddress,
|
||||
ClearFlag: AccountSetAsfFlags.asfDisableMaster,
|
||||
}
|
||||
|
||||
const client: Client = this.client
|
||||
const response = await client.submit(enableMasterKey, {
|
||||
wallet: masterWallet,
|
||||
})
|
||||
assert.equal(
|
||||
response.result.engine_result,
|
||||
'tefMASTER_DISABLED',
|
||||
'Master key was disabled, yet the master key still was able to sign and submit a transaction',
|
||||
)
|
||||
|
||||
await testTransaction(client, enableMasterKey, regularKeyWallet)
|
||||
|
||||
const turnOffRegularKey: SetRegularKey = {
|
||||
TransactionType: 'SetRegularKey',
|
||||
Account: masterWallet.address,
|
||||
}
|
||||
|
||||
await testTransaction(this.client, turnOffRegularKey, masterWallet)
|
||||
|
||||
const tx: OfferCreate = {
|
||||
TransactionType: 'OfferCreate',
|
||||
Account: regularKeyWallet.classicAddress,
|
||||
TakerGets: '13100000',
|
||||
TakerPays: {
|
||||
currency: 'USD',
|
||||
issuer: regularKeyWallet.classicAddress,
|
||||
value: '10',
|
||||
},
|
||||
}
|
||||
|
||||
const response2 = await client.submit(tx, { wallet: regularKeyWallet })
|
||||
assert.equal(
|
||||
response2.result.engine_result,
|
||||
'tefBAD_AUTH',
|
||||
'Regular key should have been disabled, but somehow was still able to sign and submit a transaction.',
|
||||
)
|
||||
})
|
||||
|
||||
it('submit_multisigned transaction with regular keys set', async function () {
|
||||
const client: Client = this.client
|
||||
|
||||
const regularKeyWallet = (await generateFundedWalletWithRegularKey(client))
|
||||
.regularKeyWallet
|
||||
const signerWallet2 = await generateFundedWallet(this.client)
|
||||
|
||||
// set up the multisigners for the account
|
||||
const signerListSet: SignerListSet = {
|
||||
TransactionType: 'SignerListSet',
|
||||
Account: this.wallet.classicAddress,
|
||||
SignerEntries: [
|
||||
{
|
||||
SignerEntry: {
|
||||
Account: regularKeyWallet.classicAddress,
|
||||
SignerWeight: 1,
|
||||
},
|
||||
const tx: OfferCreate = {
|
||||
TransactionType: 'OfferCreate',
|
||||
Account: masterWallet.classicAddress,
|
||||
TakerGets: '13100000',
|
||||
TakerPays: {
|
||||
currency: 'USD',
|
||||
issuer: masterWallet.classicAddress,
|
||||
value: '10',
|
||||
},
|
||||
{
|
||||
SignerEntry: {
|
||||
Account: signerWallet2.classicAddress,
|
||||
SignerWeight: 1,
|
||||
},
|
||||
}
|
||||
|
||||
const client: Client = testContext.client
|
||||
const response = await client.submit(tx, { wallet: masterWallet })
|
||||
assert.equal(
|
||||
response.result.engine_result,
|
||||
'tefMASTER_DISABLED',
|
||||
'Master key was disabled, yet the master key still was able to sign and submit a transaction',
|
||||
)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
|
||||
it(
|
||||
'sign with regular key after disabling the master key',
|
||||
async () => {
|
||||
const regularKeyWallet = (
|
||||
await generateFundedWalletWithRegularKey(testContext.client, true)
|
||||
).regularKeyWallet
|
||||
|
||||
const tx: OfferCreate = {
|
||||
TransactionType: 'OfferCreate',
|
||||
Account: regularKeyWallet.classicAddress,
|
||||
TakerGets: '13100000',
|
||||
TakerPays: {
|
||||
currency: 'USD',
|
||||
issuer: regularKeyWallet.classicAddress,
|
||||
value: '10',
|
||||
},
|
||||
],
|
||||
SignerQuorum: 2,
|
||||
}
|
||||
await testTransaction(this.client, signerListSet, this.wallet)
|
||||
}
|
||||
|
||||
// try to multisign
|
||||
const accountSet: AccountSet = {
|
||||
TransactionType: 'AccountSet',
|
||||
Account: this.wallet.classicAddress,
|
||||
Domain: convertStringToHex('example.com'),
|
||||
}
|
||||
const accountSetTx = await client.autofill(accountSet, 2)
|
||||
const signed1 = regularKeyWallet.sign(accountSetTx, true)
|
||||
const signed2 = signerWallet2.sign(accountSetTx, true)
|
||||
const multisigned = multisign([signed1.tx_blob, signed2.tx_blob])
|
||||
const submitResponse = await client.submit(multisigned)
|
||||
await ledgerAccept(client)
|
||||
await testTransaction(testContext.client, tx, regularKeyWallet)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
|
||||
assert.strictEqual(submitResponse.result.engine_result, 'tesSUCCESS')
|
||||
await verifySubmittedTransaction(this.client, multisigned)
|
||||
})
|
||||
it(
|
||||
'try to enable and disable a regular key',
|
||||
async () => {
|
||||
const wallets = await generateFundedWalletWithRegularKey(
|
||||
testContext.client,
|
||||
true,
|
||||
)
|
||||
const masterWallet = wallets.masterWallet
|
||||
const regularKeyWallet = wallets.regularKeyWallet
|
||||
|
||||
it('try multisigning with the account address used to set up a regular key', async function () {
|
||||
const client: Client = this.client
|
||||
const enableMasterKey: AccountSet = {
|
||||
TransactionType: 'AccountSet',
|
||||
Account: masterWallet.classicAddress,
|
||||
ClearFlag: AccountSetAsfFlags.asfDisableMaster,
|
||||
}
|
||||
|
||||
const regularKeyWallet = (await generateFundedWalletWithRegularKey(client))
|
||||
.regularKeyWallet
|
||||
const signerWallet2 = await generateFundedWallet(this.client)
|
||||
const client: Client = testContext.client
|
||||
const response = await client.submit(enableMasterKey, {
|
||||
wallet: masterWallet,
|
||||
})
|
||||
assert.equal(
|
||||
response.result.engine_result,
|
||||
'tefMASTER_DISABLED',
|
||||
'Master key was disabled, yet the master key still was able to sign and submit a transaction',
|
||||
)
|
||||
|
||||
const sameKeyDefaultAddressWallet = new Wallet(
|
||||
regularKeyWallet.publicKey,
|
||||
regularKeyWallet.privateKey,
|
||||
)
|
||||
await testTransaction(client, enableMasterKey, regularKeyWallet)
|
||||
|
||||
// set up the multisigners for the account
|
||||
const signerListSet: SignerListSet = {
|
||||
TransactionType: 'SignerListSet',
|
||||
Account: this.wallet.classicAddress,
|
||||
SignerEntries: [
|
||||
{
|
||||
SignerEntry: {
|
||||
Account: regularKeyWallet.classicAddress,
|
||||
SignerWeight: 1,
|
||||
},
|
||||
const turnOffRegularKey: SetRegularKey = {
|
||||
TransactionType: 'SetRegularKey',
|
||||
Account: masterWallet.address,
|
||||
}
|
||||
|
||||
await testTransaction(testContext.client, turnOffRegularKey, masterWallet)
|
||||
|
||||
const tx: OfferCreate = {
|
||||
TransactionType: 'OfferCreate',
|
||||
Account: regularKeyWallet.classicAddress,
|
||||
TakerGets: '13100000',
|
||||
TakerPays: {
|
||||
currency: 'USD',
|
||||
issuer: regularKeyWallet.classicAddress,
|
||||
value: '10',
|
||||
},
|
||||
{
|
||||
SignerEntry: {
|
||||
Account: signerWallet2.classicAddress,
|
||||
SignerWeight: 1,
|
||||
},
|
||||
},
|
||||
],
|
||||
SignerQuorum: 2,
|
||||
}
|
||||
await testTransaction(this.client, signerListSet, this.wallet)
|
||||
}
|
||||
|
||||
// try to multisign
|
||||
const accountSet: AccountSet = {
|
||||
TransactionType: 'AccountSet',
|
||||
Account: this.wallet.classicAddress,
|
||||
Domain: convertStringToHex('example.com'),
|
||||
}
|
||||
const accountSetTx = await client.autofill(accountSet, 2)
|
||||
const signed1 = sameKeyDefaultAddressWallet.sign(accountSetTx, true)
|
||||
const signed2 = signerWallet2.sign(accountSetTx, true)
|
||||
const multisigned = multisign([signed1.tx_blob, signed2.tx_blob])
|
||||
const submitResponse = await client.submit(multisigned)
|
||||
await ledgerAccept(client)
|
||||
assert.strictEqual(submitResponse.result.engine_result, 'tefBAD_SIGNATURE')
|
||||
})
|
||||
const response2 = await client.submit(tx, { wallet: regularKeyWallet })
|
||||
assert.equal(
|
||||
response2.result.engine_result,
|
||||
'tefBAD_AUTH',
|
||||
'Regular key should have been disabled, but somehow was still able to sign and submit a transaction.',
|
||||
)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
|
||||
it(
|
||||
'submit_multisigned transaction with regular keys set',
|
||||
async () => {
|
||||
const client: Client = testContext.client
|
||||
|
||||
const regularKeyWallet = (
|
||||
await generateFundedWalletWithRegularKey(client)
|
||||
).regularKeyWallet
|
||||
const signerWallet2 = await generateFundedWallet(testContext.client)
|
||||
|
||||
// set up the multisigners for the account
|
||||
const signerListSet: SignerListSet = {
|
||||
TransactionType: 'SignerListSet',
|
||||
Account: testContext.wallet.classicAddress,
|
||||
SignerEntries: [
|
||||
{
|
||||
SignerEntry: {
|
||||
Account: regularKeyWallet.classicAddress,
|
||||
SignerWeight: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
SignerEntry: {
|
||||
Account: signerWallet2.classicAddress,
|
||||
SignerWeight: 1,
|
||||
},
|
||||
},
|
||||
],
|
||||
SignerQuorum: 2,
|
||||
}
|
||||
await testTransaction(
|
||||
testContext.client,
|
||||
signerListSet,
|
||||
testContext.wallet,
|
||||
)
|
||||
|
||||
// try to multisign
|
||||
const accountSet: AccountSet = {
|
||||
TransactionType: 'AccountSet',
|
||||
Account: testContext.wallet.classicAddress,
|
||||
Domain: convertStringToHex('example.com'),
|
||||
}
|
||||
const accountSetTx = await client.autofill(accountSet, 2)
|
||||
const signed1 = regularKeyWallet.sign(accountSetTx, true)
|
||||
const signed2 = signerWallet2.sign(accountSetTx, true)
|
||||
const multisigned = multisign([signed1.tx_blob, signed2.tx_blob])
|
||||
const submitResponse = await client.submit(multisigned)
|
||||
await ledgerAccept(client)
|
||||
|
||||
assert.strictEqual(submitResponse.result.engine_result, 'tesSUCCESS')
|
||||
await verifySubmittedTransaction(testContext.client, multisigned)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
|
||||
it(
|
||||
'try multisigning with the account address used to set up a regular key',
|
||||
async () => {
|
||||
const client: Client = testContext.client
|
||||
|
||||
const regularKeyWallet = (
|
||||
await generateFundedWalletWithRegularKey(client)
|
||||
).regularKeyWallet
|
||||
const signerWallet2 = await generateFundedWallet(testContext.client)
|
||||
|
||||
const sameKeyDefaultAddressWallet = new Wallet(
|
||||
regularKeyWallet.publicKey,
|
||||
regularKeyWallet.privateKey,
|
||||
)
|
||||
|
||||
// set up the multisigners for the account
|
||||
const signerListSet: SignerListSet = {
|
||||
TransactionType: 'SignerListSet',
|
||||
Account: testContext.wallet.classicAddress,
|
||||
SignerEntries: [
|
||||
{
|
||||
SignerEntry: {
|
||||
Account: regularKeyWallet.classicAddress,
|
||||
SignerWeight: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
SignerEntry: {
|
||||
Account: signerWallet2.classicAddress,
|
||||
SignerWeight: 1,
|
||||
},
|
||||
},
|
||||
],
|
||||
SignerQuorum: 2,
|
||||
}
|
||||
await testTransaction(
|
||||
testContext.client,
|
||||
signerListSet,
|
||||
testContext.wallet,
|
||||
)
|
||||
|
||||
// try to multisign
|
||||
const accountSet: AccountSet = {
|
||||
TransactionType: 'AccountSet',
|
||||
Account: testContext.wallet.classicAddress,
|
||||
Domain: convertStringToHex('example.com'),
|
||||
}
|
||||
const accountSetTx = await client.autofill(accountSet, 2)
|
||||
const signed1 = sameKeyDefaultAddressWallet.sign(accountSetTx, true)
|
||||
const signed2 = signerWallet2.sign(accountSetTx, true)
|
||||
const multisigned = multisign([signed1.tx_blob, signed2.tx_blob])
|
||||
const submitResponse = await client.submit(multisigned)
|
||||
await ledgerAccept(client)
|
||||
assert.strictEqual(
|
||||
submitResponse.result.engine_result,
|
||||
'tefBAD_SIGNATURE',
|
||||
)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,44 +1,54 @@
|
||||
import { assert } from 'chai'
|
||||
import _ from 'lodash'
|
||||
import { AccountChannelsRequest } from 'xrpl-local'
|
||||
import omit from 'lodash/omit'
|
||||
|
||||
import { AccountChannelsRequest } from '../../../src'
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
|
||||
describe('account_channels', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('base', async function () {
|
||||
const request: AccountChannelsRequest = {
|
||||
command: 'account_channels',
|
||||
account: this.wallet.classicAddress,
|
||||
ledger_index: 'validated',
|
||||
}
|
||||
const response = await this.client.request(request)
|
||||
const expected = {
|
||||
id: 0,
|
||||
result: {
|
||||
account: this.wallet.classicAddress,
|
||||
channels: [],
|
||||
ledger_hash:
|
||||
'C8BFA74A740AA22AD9BD724781589319052398B0C6C817B88D55628E07B7B4A1',
|
||||
ledger_index: 150,
|
||||
validated: true,
|
||||
},
|
||||
type: 'response',
|
||||
}
|
||||
assert.equal(response.type, expected.type)
|
||||
assert.equal(typeof response.result.ledger_hash, 'string')
|
||||
assert.equal(typeof response.result.ledger_index, 'number')
|
||||
assert.deepEqual(
|
||||
_.omit(response.result, ['ledger_hash', 'ledger_index']),
|
||||
_.omit(expected.result, ['ledger_hash', 'ledger_index']),
|
||||
)
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it(
|
||||
'base',
|
||||
async () => {
|
||||
const request: AccountChannelsRequest = {
|
||||
command: 'account_channels',
|
||||
account: testContext.wallet.classicAddress,
|
||||
ledger_index: 'validated',
|
||||
}
|
||||
const response = await testContext.client.request(request)
|
||||
const expected = {
|
||||
id: 0,
|
||||
result: {
|
||||
account: testContext.wallet.classicAddress,
|
||||
channels: [],
|
||||
ledger_hash:
|
||||
'C8BFA74A740AA22AD9BD724781589319052398B0C6C817B88D55628E07B7B4A1',
|
||||
ledger_index: 150,
|
||||
validated: true,
|
||||
},
|
||||
type: 'response',
|
||||
}
|
||||
assert.equal(response.type, expected.type)
|
||||
assert.equal(typeof response.result.ledger_hash, 'string')
|
||||
assert.equal(typeof response.result.ledger_index, 'number')
|
||||
assert.deepEqual(
|
||||
omit(response.result, ['ledger_hash', 'ledger_index']),
|
||||
omit(expected.result, ['ledger_hash', 'ledger_index']),
|
||||
)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,45 +1,55 @@
|
||||
import { assert } from 'chai'
|
||||
import _ from 'lodash'
|
||||
import { AccountCurrenciesRequest } from 'xrpl-local'
|
||||
import omit from 'lodash/omit'
|
||||
|
||||
import { AccountCurrenciesRequest } from '../../../src'
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
|
||||
describe('account_currencies', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('base', async function () {
|
||||
const request: AccountCurrenciesRequest = {
|
||||
command: 'account_currencies',
|
||||
account: this.wallet.classicAddress,
|
||||
strict: true,
|
||||
ledger_index: 'validated',
|
||||
}
|
||||
const response = await this.client.request(request)
|
||||
const expected = {
|
||||
id: 0,
|
||||
result: {
|
||||
receive_currencies: [],
|
||||
send_currencies: [],
|
||||
ledger_hash:
|
||||
'C8BFA74A740AA22AD9BD724781589319052398B0C6C817B88D55628E07B7B4A1',
|
||||
ledger_index: 150,
|
||||
validated: true,
|
||||
},
|
||||
type: 'response',
|
||||
}
|
||||
assert.equal(response.type, expected.type)
|
||||
assert.equal(typeof response.result.ledger_hash, 'string')
|
||||
assert.equal(typeof response.result.ledger_index, 'number')
|
||||
assert.deepEqual(
|
||||
_.omit(response.result, ['ledger_hash', 'ledger_index']),
|
||||
_.omit(expected.result, ['ledger_hash', 'ledger_index']),
|
||||
)
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it(
|
||||
'base',
|
||||
async () => {
|
||||
const request: AccountCurrenciesRequest = {
|
||||
command: 'account_currencies',
|
||||
account: testContext.wallet.classicAddress,
|
||||
strict: true,
|
||||
ledger_index: 'validated',
|
||||
}
|
||||
const response = await testContext.client.request(request)
|
||||
const expected = {
|
||||
id: 0,
|
||||
result: {
|
||||
receive_currencies: [],
|
||||
send_currencies: [],
|
||||
ledger_hash:
|
||||
'C8BFA74A740AA22AD9BD724781589319052398B0C6C817B88D55628E07B7B4A1',
|
||||
ledger_index: 150,
|
||||
validated: true,
|
||||
},
|
||||
type: 'response',
|
||||
}
|
||||
assert.equal(response.type, expected.type)
|
||||
assert.equal(typeof response.result.ledger_hash, 'string')
|
||||
assert.equal(typeof response.result.ledger_index, 'number')
|
||||
assert.deepEqual(
|
||||
omit(response.result, ['ledger_hash', 'ledger_index']),
|
||||
omit(expected.result, ['ledger_hash', 'ledger_index']),
|
||||
)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,74 +1,83 @@
|
||||
import { assert } from 'chai'
|
||||
import _ from 'lodash'
|
||||
import { AccountInfoRequest } from 'xrpl-local'
|
||||
import omit from 'lodash/omit'
|
||||
|
||||
import { AccountInfoRequest } from '../../../src'
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
|
||||
describe('account_info', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('base', async function () {
|
||||
const request: AccountInfoRequest = {
|
||||
command: 'account_info',
|
||||
account: this.wallet.classicAddress,
|
||||
strict: true,
|
||||
ledger_index: 'validated',
|
||||
}
|
||||
const response = await this.client.request(request)
|
||||
const expected = {
|
||||
id: 0,
|
||||
result: {
|
||||
account_data: {
|
||||
Account: this.wallet.classicAddress,
|
||||
Balance: '400000000',
|
||||
Flags: 0,
|
||||
LedgerEntryType: 'AccountRoot',
|
||||
OwnerCount: 0,
|
||||
PreviousTxnID:
|
||||
'19A8211695785A3A02C1C287D93C2B049E83A9CD609825E721052D63FF4F0EC8',
|
||||
PreviousTxnLgrSeq: 582,
|
||||
Sequence: 283,
|
||||
index:
|
||||
'BD4815E6EB304136E6044F778FB68D4E464CC8DFC59B8F6CC93D90A3709AE194',
|
||||
},
|
||||
ledger_hash:
|
||||
'F0DEEC46A7185BBB535517EE38CF2025973022D5B0532B36407F492521FDB0C6',
|
||||
ledger_index: 582,
|
||||
validated: true,
|
||||
},
|
||||
type: 'response',
|
||||
}
|
||||
assert.equal(response.type, expected.type)
|
||||
assert.equal(response.result.validated, expected.result.validated)
|
||||
assert.equal(typeof response.result.ledger_hash, 'string')
|
||||
assert.equal(typeof response.result.ledger_index, 'number')
|
||||
assert.equal(typeof response.result.account_data.PreviousTxnID, 'string')
|
||||
assert.equal(typeof response.result.account_data.index, 'string')
|
||||
assert.equal(
|
||||
typeof response.result.account_data.PreviousTxnLgrSeq,
|
||||
'number',
|
||||
)
|
||||
assert.equal(typeof response.result.account_data.Sequence, 'number')
|
||||
assert.deepEqual(
|
||||
_.omit(response.result.account_data, [
|
||||
'PreviousTxnID',
|
||||
'PreviousTxnLgrSeq',
|
||||
'Sequence',
|
||||
'index',
|
||||
]),
|
||||
_.omit(expected.result.account_data, [
|
||||
'PreviousTxnID',
|
||||
'PreviousTxnLgrSeq',
|
||||
'Sequence',
|
||||
'index',
|
||||
]),
|
||||
)
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it(
|
||||
'base',
|
||||
async () => {
|
||||
const request: AccountInfoRequest = {
|
||||
command: 'account_info',
|
||||
account: testContext.wallet.classicAddress,
|
||||
strict: true,
|
||||
ledger_index: 'validated',
|
||||
}
|
||||
const response = await testContext.client.request(request)
|
||||
const expected = {
|
||||
id: 0,
|
||||
result: {
|
||||
account_data: {
|
||||
Account: testContext.wallet.classicAddress,
|
||||
Balance: '400000000',
|
||||
Flags: 0,
|
||||
LedgerEntryType: 'AccountRoot',
|
||||
OwnerCount: 0,
|
||||
PreviousTxnID:
|
||||
'19A8211695785A3A02C1C287D93C2B049E83A9CD609825E721052D63FF4F0EC8',
|
||||
PreviousTxnLgrSeq: 582,
|
||||
Sequence: 283,
|
||||
index:
|
||||
'BD4815E6EB304136E6044F778FB68D4E464CC8DFC59B8F6CC93D90A3709AE194',
|
||||
},
|
||||
ledger_hash:
|
||||
'F0DEEC46A7185BBB535517EE38CF2025973022D5B0532B36407F492521FDB0C6',
|
||||
ledger_index: 582,
|
||||
validated: true,
|
||||
},
|
||||
type: 'response',
|
||||
}
|
||||
assert.equal(response.type, expected.type)
|
||||
assert.equal(response.result.validated, expected.result.validated)
|
||||
assert.equal(typeof response.result.ledger_index, 'number')
|
||||
assert.equal(typeof response.result.account_data.PreviousTxnID, 'string')
|
||||
assert.equal(typeof response.result.account_data.index, 'string')
|
||||
assert.equal(
|
||||
typeof response.result.account_data.PreviousTxnLgrSeq,
|
||||
'number',
|
||||
)
|
||||
assert.equal(typeof response.result.account_data.Sequence, 'number')
|
||||
assert.deepEqual(
|
||||
omit(response.result.account_data, [
|
||||
'PreviousTxnID',
|
||||
'PreviousTxnLgrSeq',
|
||||
'Sequence',
|
||||
'index',
|
||||
]),
|
||||
omit(expected.result.account_data, [
|
||||
'PreviousTxnID',
|
||||
'PreviousTxnLgrSeq',
|
||||
'Sequence',
|
||||
'index',
|
||||
]),
|
||||
)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,45 +1,55 @@
|
||||
import { assert } from 'chai'
|
||||
import _ from 'lodash'
|
||||
import { AccountLinesRequest } from 'xrpl-local'
|
||||
import omit from 'lodash/omit'
|
||||
|
||||
import { AccountLinesRequest } from '../../../src'
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
|
||||
describe('account_lines', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('base', async function () {
|
||||
const request: AccountLinesRequest = {
|
||||
command: 'account_lines',
|
||||
account: this.wallet.classicAddress,
|
||||
strict: true,
|
||||
ledger_index: 'validated',
|
||||
}
|
||||
const response = await this.client.request(request)
|
||||
const expected = {
|
||||
id: 0,
|
||||
result: {
|
||||
account: this.wallet.classicAddress,
|
||||
ledger_hash:
|
||||
'0C09AAFA88AC1A616058220CF33269788D3985DAA6F2386196D4A7404252BB61',
|
||||
ledger_index: 1074,
|
||||
lines: [],
|
||||
validated: true,
|
||||
},
|
||||
type: 'response',
|
||||
}
|
||||
assert.equal(response.type, expected.type)
|
||||
assert.equal(typeof response.result.ledger_hash, 'string')
|
||||
assert.equal(typeof response.result.ledger_index, 'number')
|
||||
assert.deepEqual(
|
||||
_.omit(response.result, ['ledger_hash', 'ledger_index']),
|
||||
_.omit(expected.result, ['ledger_hash', 'ledger_index']),
|
||||
)
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it(
|
||||
'base',
|
||||
async () => {
|
||||
const request: AccountLinesRequest = {
|
||||
command: 'account_lines',
|
||||
account: testContext.wallet.classicAddress,
|
||||
strict: true,
|
||||
ledger_index: 'validated',
|
||||
}
|
||||
const response = await testContext.client.request(request)
|
||||
const expected = {
|
||||
id: 0,
|
||||
result: {
|
||||
account: testContext.wallet.classicAddress,
|
||||
ledger_hash:
|
||||
'0C09AAFA88AC1A616058220CF33269788D3985DAA6F2386196D4A7404252BB61',
|
||||
ledger_index: 1074,
|
||||
lines: [],
|
||||
validated: true,
|
||||
},
|
||||
type: 'response',
|
||||
}
|
||||
assert.equal(response.type, expected.type)
|
||||
assert.equal(typeof response.result.ledger_hash, 'string')
|
||||
assert.equal(typeof response.result.ledger_index, 'number')
|
||||
assert.deepEqual(
|
||||
omit(response.result, ['ledger_hash', 'ledger_index']),
|
||||
omit(expected.result, ['ledger_hash', 'ledger_index']),
|
||||
)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,44 +1,54 @@
|
||||
import { assert } from 'chai'
|
||||
import _ from 'lodash'
|
||||
import { AccountObjectsRequest } from 'xrpl-local'
|
||||
import omit from 'lodash/omit'
|
||||
|
||||
import { AccountObjectsRequest } from '../../../src'
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
|
||||
describe('account_objects', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('base', async function () {
|
||||
const request: AccountObjectsRequest = {
|
||||
command: 'account_objects',
|
||||
account: this.wallet.classicAddress,
|
||||
ledger_index: 'validated',
|
||||
}
|
||||
const response = await this.client.request(request)
|
||||
const expected = {
|
||||
id: 0,
|
||||
result: {
|
||||
account: this.wallet.classicAddress,
|
||||
account_objects: [],
|
||||
ledger_hash:
|
||||
'28D68B351ED58B9819502EF5FC05BA4412A048597E5159E1C226703BDF7C7897',
|
||||
ledger_index: 1294,
|
||||
validated: true,
|
||||
},
|
||||
type: 'response',
|
||||
}
|
||||
assert.equal(response.type, expected.type)
|
||||
assert.equal(typeof response.result.ledger_hash, 'string')
|
||||
assert.equal(typeof response.result.ledger_index, 'number')
|
||||
assert.deepEqual(
|
||||
_.omit(response.result, ['ledger_hash', 'ledger_index']),
|
||||
_.omit(expected.result, ['ledger_hash', 'ledger_index']),
|
||||
)
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it(
|
||||
'base',
|
||||
async () => {
|
||||
const request: AccountObjectsRequest = {
|
||||
command: 'account_objects',
|
||||
account: testContext.wallet.classicAddress,
|
||||
ledger_index: 'validated',
|
||||
}
|
||||
const response = await testContext.client.request(request)
|
||||
const expected = {
|
||||
id: 0,
|
||||
result: {
|
||||
account: testContext.wallet.classicAddress,
|
||||
account_objects: [],
|
||||
ledger_hash:
|
||||
'28D68B351ED58B9819502EF5FC05BA4412A048597E5159E1C226703BDF7C7897',
|
||||
ledger_index: 1294,
|
||||
validated: true,
|
||||
},
|
||||
type: 'response',
|
||||
}
|
||||
assert.equal(response.type, expected.type)
|
||||
assert.equal(typeof response.result.ledger_hash, 'string')
|
||||
assert.equal(typeof response.result.ledger_index, 'number')
|
||||
assert.deepEqual(
|
||||
omit(response.result, ['ledger_hash', 'ledger_index']),
|
||||
omit(expected.result, ['ledger_hash', 'ledger_index']),
|
||||
)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,41 +1,51 @@
|
||||
import { assert } from 'chai'
|
||||
import _ from 'lodash'
|
||||
import { AccountOffersRequest } from 'xrpl-local'
|
||||
import omit from 'lodash/omit'
|
||||
|
||||
import { AccountOffersRequest } from '../../../src'
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
|
||||
describe('account_offers', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('base', async function () {
|
||||
const request: AccountOffersRequest = {
|
||||
command: 'account_offers',
|
||||
account: this.wallet.classicAddress,
|
||||
strict: true,
|
||||
}
|
||||
const response = await this.client.request(request)
|
||||
const expected = {
|
||||
id: 0,
|
||||
result: {
|
||||
account: this.wallet.classicAddress,
|
||||
ledger_current_index: 1443,
|
||||
offers: [],
|
||||
validated: false,
|
||||
},
|
||||
type: 'response',
|
||||
}
|
||||
assert.equal(response.type, expected.type)
|
||||
assert.equal(typeof response.result.ledger_current_index, 'number')
|
||||
assert.deepEqual(
|
||||
_.omit(response.result, 'ledger_current_index'),
|
||||
_.omit(expected.result, 'ledger_current_index'),
|
||||
)
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it(
|
||||
'base',
|
||||
async () => {
|
||||
const request: AccountOffersRequest = {
|
||||
command: 'account_offers',
|
||||
account: testContext.wallet.classicAddress,
|
||||
strict: true,
|
||||
}
|
||||
const response = await testContext.client.request(request)
|
||||
const expected = {
|
||||
id: 0,
|
||||
result: {
|
||||
account: testContext.wallet.classicAddress,
|
||||
ledger_current_index: 1443,
|
||||
offers: [],
|
||||
validated: false,
|
||||
},
|
||||
type: 'response',
|
||||
}
|
||||
assert.equal(response.type, expected.type)
|
||||
assert.equal(typeof response.result.ledger_current_index, 'number')
|
||||
assert.deepEqual(
|
||||
omit(response.result, 'ledger_current_index'),
|
||||
omit(expected.result, 'ledger_current_index'),
|
||||
)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,99 +1,114 @@
|
||||
import { assert } from 'chai'
|
||||
import _ from 'lodash'
|
||||
import { AccountTxRequest } from 'xrpl-local'
|
||||
|
||||
import {
|
||||
AccountTxRequest,
|
||||
Payment,
|
||||
type TransactionMetadata,
|
||||
} from '../../../src'
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
|
||||
describe('account_tx', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('base', async function () {
|
||||
const request: AccountTxRequest = {
|
||||
command: 'account_tx',
|
||||
account: this.wallet.classicAddress,
|
||||
ledger_index: 'validated',
|
||||
}
|
||||
const response = await this.client.request(request)
|
||||
const expected = {
|
||||
result: {
|
||||
account: this.wallet.classicAddress,
|
||||
limit: 400,
|
||||
transactions: [
|
||||
{
|
||||
tx: {
|
||||
Account: 'rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh',
|
||||
Amount: '400000000',
|
||||
Destination: this.wallet.classicAddress,
|
||||
Fee: '12',
|
||||
Flags: 0,
|
||||
LastLedgerSequence: 1753,
|
||||
Sequence: 843,
|
||||
SigningPubKey:
|
||||
'0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020',
|
||||
TransactionType: 'Payment',
|
||||
TxnSignature:
|
||||
'30440220693D244BC13967E3DA67BDC974096784ED03DD4ACE6F36645E5176988452AFCF02200F8AB172432913899F27EC5523829AEDAD00CC2445690400E294EDF652A85945',
|
||||
date: 685747005,
|
||||
hash: '2E68BC15813B4A836FAC4D80E42E6FDA6410E99AB973937DEA5E6C2E9A116BAB',
|
||||
inLedger: 1734,
|
||||
ledger_index: 1734,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
type: 'response',
|
||||
}
|
||||
assert.equal(response.type, expected.type)
|
||||
assert.equal(response.result.account, expected.result.account)
|
||||
assert.equal(
|
||||
response.result.transactions[0].meta.TransactionResult,
|
||||
'tesSUCCESS',
|
||||
)
|
||||
assert.equal(
|
||||
typeof response.result.transactions[0].tx.LastLedgerSequence,
|
||||
'number',
|
||||
)
|
||||
assert.equal(typeof response.result.transactions[0].tx.Sequence, 'number')
|
||||
assert.equal(
|
||||
typeof response.result.transactions[0].tx.SigningPubKey,
|
||||
'string',
|
||||
)
|
||||
assert.equal(
|
||||
typeof response.result.transactions[0].tx.TxnSignature,
|
||||
'string',
|
||||
)
|
||||
assert.equal(typeof response.result.transactions[0].tx.Fee, 'string')
|
||||
assert.equal(typeof response.result.transactions[0].tx.hash, 'string')
|
||||
assert.equal(typeof response.result.transactions[0].tx.inLedger, 'number')
|
||||
assert.equal(
|
||||
typeof response.result.transactions[0].tx.ledger_index,
|
||||
'number',
|
||||
)
|
||||
|
||||
const responseTx = response.result.transactions[0].tx
|
||||
const expectedTx = expected.result.transactions[0].tx
|
||||
assert.deepEqual(
|
||||
[
|
||||
responseTx.Flags,
|
||||
responseTx.TransactionType,
|
||||
responseTx.Account,
|
||||
responseTx.Amount,
|
||||
responseTx.Destination,
|
||||
],
|
||||
[
|
||||
expectedTx.Flags,
|
||||
expectedTx.TransactionType,
|
||||
expectedTx.Account,
|
||||
expectedTx.Amount,
|
||||
expectedTx.Destination,
|
||||
],
|
||||
)
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it(
|
||||
'base',
|
||||
async () => {
|
||||
const request: AccountTxRequest = {
|
||||
command: 'account_tx',
|
||||
account: testContext.wallet.classicAddress,
|
||||
ledger_index: 'validated',
|
||||
}
|
||||
const response = await testContext.client.request(request)
|
||||
const expected = {
|
||||
result: {
|
||||
account: testContext.wallet.classicAddress,
|
||||
limit: 400,
|
||||
transactions: [
|
||||
{
|
||||
tx: {
|
||||
Account: 'rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh',
|
||||
Amount: '400000000',
|
||||
Destination: testContext.wallet.classicAddress,
|
||||
Fee: '12',
|
||||
Flags: 0,
|
||||
LastLedgerSequence: 1753,
|
||||
Sequence: 843,
|
||||
SigningPubKey:
|
||||
'0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020',
|
||||
TransactionType: 'Payment',
|
||||
TxnSignature:
|
||||
'30440220693D244BC13967E3DA67BDC974096784ED03DD4ACE6F36645E5176988452AFCF02200F8AB172432913899F27EC5523829AEDAD00CC2445690400E294EDF652A85945',
|
||||
date: 685747005,
|
||||
hash: '2E68BC15813B4A836FAC4D80E42E6FDA6410E99AB973937DEA5E6C2E9A116BAB',
|
||||
ledger_index: 1734,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
type: 'response',
|
||||
}
|
||||
assert.equal(response.type, expected.type)
|
||||
assert.equal(response.result.account, expected.result.account)
|
||||
assert.equal(
|
||||
(response.result.transactions[0].meta as TransactionMetadata)
|
||||
.TransactionResult,
|
||||
'tesSUCCESS',
|
||||
)
|
||||
assert.equal(
|
||||
typeof response.result.transactions[0].tx?.LastLedgerSequence,
|
||||
'number',
|
||||
)
|
||||
assert.equal(
|
||||
typeof response.result.transactions[0].tx?.Sequence,
|
||||
'number',
|
||||
)
|
||||
assert.equal(
|
||||
typeof response.result.transactions[0].tx?.SigningPubKey,
|
||||
'string',
|
||||
)
|
||||
assert.equal(
|
||||
typeof response.result.transactions[0].tx?.TxnSignature,
|
||||
'string',
|
||||
)
|
||||
assert.equal(typeof response.result.transactions[0].tx?.Fee, 'string')
|
||||
assert.equal(typeof response.result.transactions[0].tx?.hash, 'string')
|
||||
assert.equal(
|
||||
typeof response.result.transactions[0].tx?.ledger_index,
|
||||
'number',
|
||||
)
|
||||
|
||||
const responseTx = response.result.transactions[0].tx as Payment
|
||||
const expectedTx = expected.result.transactions[0].tx
|
||||
assert.deepEqual(
|
||||
[
|
||||
responseTx.Flags,
|
||||
responseTx.TransactionType,
|
||||
responseTx.Account,
|
||||
responseTx.Amount,
|
||||
responseTx.Destination,
|
||||
],
|
||||
[
|
||||
expectedTx.Flags,
|
||||
expectedTx.TransactionType,
|
||||
expectedTx.Account,
|
||||
expectedTx.Amount,
|
||||
expectedTx.Destination,
|
||||
],
|
||||
)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,42 +1,51 @@
|
||||
import { assert } from 'chai'
|
||||
import _ from 'lodash'
|
||||
import { BookOffersRequest, BookOffersResponse } from 'xrpl-local'
|
||||
|
||||
import { BookOffersRequest, BookOffersResponse } from '../../../src'
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
|
||||
describe('book_offers', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('base', async function () {
|
||||
const bookOffer: BookOffersRequest = {
|
||||
command: 'book_offers',
|
||||
taker_gets: {
|
||||
currency: 'XRP',
|
||||
},
|
||||
taker_pays: {
|
||||
currency: 'USD',
|
||||
issuer: this.wallet.classicAddress,
|
||||
},
|
||||
}
|
||||
const response = await this.client.request(bookOffer)
|
||||
|
||||
const expectedResponse: BookOffersResponse = {
|
||||
id: response.id,
|
||||
type: 'response',
|
||||
result: {
|
||||
ledger_current_index: response.result.ledger_current_index,
|
||||
offers: response.result.offers,
|
||||
validated: false,
|
||||
},
|
||||
}
|
||||
|
||||
assert.deepEqual(response, expectedResponse)
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it(
|
||||
'base',
|
||||
async () => {
|
||||
const bookOffer: BookOffersRequest = {
|
||||
command: 'book_offers',
|
||||
taker_gets: {
|
||||
currency: 'XRP',
|
||||
},
|
||||
taker_pays: {
|
||||
currency: 'USD',
|
||||
issuer: testContext.wallet.classicAddress,
|
||||
},
|
||||
}
|
||||
const response = await testContext.client.request(bookOffer)
|
||||
|
||||
const expectedResponse: BookOffersResponse = {
|
||||
id: response.id,
|
||||
type: 'response',
|
||||
result: {
|
||||
ledger_current_index: response.result.ledger_current_index,
|
||||
offers: response.result.offers,
|
||||
validated: false,
|
||||
},
|
||||
}
|
||||
|
||||
assert.deepEqual(response, expectedResponse)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,40 +1,49 @@
|
||||
import { assert } from 'chai'
|
||||
import _ from 'lodash'
|
||||
import { ChannelVerifyRequest, ChannelVerifyResponse } from 'xrpl-local'
|
||||
|
||||
import { ChannelVerifyRequest, ChannelVerifyResponse } from '../../../src'
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
|
||||
describe('channel_verify', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('base', async function () {
|
||||
const channelVerify: ChannelVerifyRequest = {
|
||||
command: 'channel_verify',
|
||||
channel_id:
|
||||
'5DB01B7FFED6B67E6B0414DED11E051D2EE2B7619CE0EAA6286D67A3A4D5BDB3',
|
||||
signature:
|
||||
'304402204EF0AFB78AC23ED1C472E74F4299C0C21F1B21D07EFC0A3838A420F76D783A400220154FB11B6F54320666E4C36CA7F686C16A3A0456800BBC43746F34AF50290064',
|
||||
public_key: 'aB44YfzW24VDEJQ2UuLPV2PvqcPCSoLnL7y5M1EzhdW4LnK5xMS3',
|
||||
amount: '1000000',
|
||||
}
|
||||
|
||||
const response = await this.client.request(channelVerify)
|
||||
|
||||
const expectedResponse: ChannelVerifyResponse = {
|
||||
id: response.id,
|
||||
type: 'response',
|
||||
result: {
|
||||
signature_verified: response.result.signature_verified,
|
||||
},
|
||||
}
|
||||
|
||||
assert.deepEqual(response, expectedResponse)
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it(
|
||||
'base',
|
||||
async () => {
|
||||
const channelVerify: ChannelVerifyRequest = {
|
||||
command: 'channel_verify',
|
||||
channel_id:
|
||||
'5DB01B7FFED6B67E6B0414DED11E051D2EE2B7619CE0EAA6286D67A3A4D5BDB3',
|
||||
signature:
|
||||
'304402204EF0AFB78AC23ED1C472E74F4299C0C21F1B21D07EFC0A3838A420F76D783A400220154FB11B6F54320666E4C36CA7F686C16A3A0456800BBC43746F34AF50290064',
|
||||
public_key: 'aB44YfzW24VDEJQ2UuLPV2PvqcPCSoLnL7y5M1EzhdW4LnK5xMS3',
|
||||
amount: '1000000',
|
||||
}
|
||||
|
||||
const response = await testContext.client.request(channelVerify)
|
||||
|
||||
const expectedResponse: ChannelVerifyResponse = {
|
||||
id: response.id,
|
||||
type: 'response',
|
||||
result: {
|
||||
signature_verified: response.result.signature_verified,
|
||||
},
|
||||
}
|
||||
|
||||
assert.deepEqual(response, expectedResponse)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,42 +1,54 @@
|
||||
import { assert } from 'chai'
|
||||
import _ from 'lodash'
|
||||
import { DepositAuthorizedRequest, DepositAuthorizedResponse } from 'xrpl-local'
|
||||
|
||||
import {
|
||||
DepositAuthorizedRequest,
|
||||
DepositAuthorizedResponse,
|
||||
} from '../../../src'
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
import { generateFundedWallet } from '../utils'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
|
||||
describe('deposit_authorized', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('base', async function () {
|
||||
const wallet2 = await generateFundedWallet(this.client)
|
||||
const depositAuthorized: DepositAuthorizedRequest = {
|
||||
command: 'deposit_authorized',
|
||||
source_account: this.wallet.classicAddress,
|
||||
destination_account: wallet2.classicAddress,
|
||||
}
|
||||
|
||||
const response = await this.client.request(depositAuthorized)
|
||||
|
||||
const expectedResponse: DepositAuthorizedResponse = {
|
||||
id: response.id,
|
||||
type: 'response',
|
||||
result: {
|
||||
deposit_authorized: true,
|
||||
destination_account: depositAuthorized.destination_account,
|
||||
ledger_current_index: response.result.ledger_current_index,
|
||||
source_account: depositAuthorized.source_account,
|
||||
validated: false,
|
||||
},
|
||||
}
|
||||
|
||||
assert.deepEqual(response, expectedResponse)
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it(
|
||||
'base',
|
||||
async () => {
|
||||
const wallet2 = await generateFundedWallet(testContext.client)
|
||||
const depositAuthorized: DepositAuthorizedRequest = {
|
||||
command: 'deposit_authorized',
|
||||
source_account: testContext.wallet.classicAddress,
|
||||
destination_account: wallet2.classicAddress,
|
||||
}
|
||||
|
||||
const response = await testContext.client.request(depositAuthorized)
|
||||
|
||||
const expectedResponse: DepositAuthorizedResponse = {
|
||||
id: response.id,
|
||||
type: 'response',
|
||||
result: {
|
||||
deposit_authorized: true,
|
||||
destination_account: depositAuthorized.destination_account,
|
||||
ledger_current_index: response.result.ledger_current_index,
|
||||
source_account: depositAuthorized.source_account,
|
||||
validated: false,
|
||||
},
|
||||
}
|
||||
|
||||
assert.deepEqual(response, expectedResponse)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,52 +1,62 @@
|
||||
import { assert } from 'chai'
|
||||
import _ from 'lodash'
|
||||
import { FeeRequest } from 'xrpl-local'
|
||||
import omit from 'lodash/omit'
|
||||
|
||||
import { FeeRequest } from '../../../src'
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
|
||||
describe('fee', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('base', async function () {
|
||||
const request: FeeRequest = {
|
||||
command: 'fee',
|
||||
}
|
||||
const response = await this.client.request(request)
|
||||
const expected = {
|
||||
id: 0,
|
||||
result: {
|
||||
current_ledger_size: '0',
|
||||
current_queue_size: '0',
|
||||
drops: {
|
||||
base_fee: '10',
|
||||
median_fee: '5000',
|
||||
minimum_fee: '10',
|
||||
open_ledger_fee: '10',
|
||||
},
|
||||
expected_ledger_size: '1000',
|
||||
ledger_current_index: 2925,
|
||||
levels: {
|
||||
median_level: '128000',
|
||||
minimum_level: '256',
|
||||
open_ledger_level: '256',
|
||||
reference_level: '256',
|
||||
},
|
||||
max_queue_size: '20000',
|
||||
},
|
||||
type: 'response',
|
||||
}
|
||||
assert.equal(response.type, expected.type)
|
||||
assert.equal(typeof response.result.ledger_current_index, 'number')
|
||||
assert.deepEqual(
|
||||
_.omit(response.result, ['ledger_current_index']),
|
||||
_.omit(expected.result, ['ledger_current_index']),
|
||||
)
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it(
|
||||
'base',
|
||||
async () => {
|
||||
const request: FeeRequest = {
|
||||
command: 'fee',
|
||||
}
|
||||
const response = await testContext.client.request(request)
|
||||
const expected = {
|
||||
id: 0,
|
||||
result: {
|
||||
current_ledger_size: '0',
|
||||
current_queue_size: '0',
|
||||
drops: {
|
||||
base_fee: '10',
|
||||
median_fee: '5000',
|
||||
minimum_fee: '10',
|
||||
open_ledger_fee: '10',
|
||||
},
|
||||
expected_ledger_size: '1000',
|
||||
ledger_current_index: 2925,
|
||||
levels: {
|
||||
median_level: '128000',
|
||||
minimum_level: '256',
|
||||
open_ledger_level: '256',
|
||||
reference_level: '256',
|
||||
},
|
||||
max_queue_size: '20000',
|
||||
},
|
||||
type: 'response',
|
||||
}
|
||||
assert.equal(response.type, expected.type)
|
||||
assert.equal(typeof response.result.ledger_current_index, 'number')
|
||||
assert.deepEqual(
|
||||
omit(response.result, ['ledger_current_index']),
|
||||
omit(expected.result, ['ledger_current_index']),
|
||||
)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,44 +1,54 @@
|
||||
import { assert } from 'chai'
|
||||
import _ from 'lodash'
|
||||
import { GatewayBalancesRequest } from 'xrpl-local'
|
||||
import omit from 'lodash/omit'
|
||||
|
||||
import { GatewayBalancesRequest } from '../../../src'
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
|
||||
describe('gateway_balances', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('base', async function () {
|
||||
const request: GatewayBalancesRequest = {
|
||||
command: 'gateway_balances',
|
||||
account: this.wallet.classicAddress,
|
||||
ledger_index: 'validated',
|
||||
strict: true,
|
||||
}
|
||||
const response = await this.client.request(request)
|
||||
const expected = {
|
||||
id: 0,
|
||||
result: {
|
||||
account: this.wallet.classicAddress,
|
||||
ledger_hash:
|
||||
'28D68B351ED58B9819502EF5FC05BA4412A048597E5159E1C226703BDF7C7897',
|
||||
ledger_index: 1294,
|
||||
validated: true,
|
||||
},
|
||||
type: 'response',
|
||||
}
|
||||
assert.equal(response.type, expected.type)
|
||||
assert.equal(typeof response.result.ledger_hash, 'string')
|
||||
assert.equal(typeof response.result.ledger_index, 'number')
|
||||
assert.deepEqual(
|
||||
_.omit(response.result, ['ledger_hash', 'ledger_index']),
|
||||
_.omit(expected.result, ['ledger_hash', 'ledger_index']),
|
||||
)
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it(
|
||||
'base',
|
||||
async () => {
|
||||
const request: GatewayBalancesRequest = {
|
||||
command: 'gateway_balances',
|
||||
account: testContext.wallet.classicAddress,
|
||||
ledger_index: 'validated',
|
||||
strict: true,
|
||||
}
|
||||
const response = await testContext.client.request(request)
|
||||
const expected = {
|
||||
id: 0,
|
||||
result: {
|
||||
account: testContext.wallet.classicAddress,
|
||||
ledger_hash:
|
||||
'28D68B351ED58B9819502EF5FC05BA4412A048597E5159E1C226703BDF7C7897',
|
||||
ledger_index: 1294,
|
||||
validated: true,
|
||||
},
|
||||
type: 'response',
|
||||
}
|
||||
assert.equal(response.type, expected.type)
|
||||
assert.equal(typeof response.result.ledger_hash, 'string')
|
||||
assert.equal(typeof response.result.ledger_index, 'number')
|
||||
assert.deepEqual(
|
||||
omit(response.result, ['ledger_hash', 'ledger_index']),
|
||||
omit(expected.result, ['ledger_hash', 'ledger_index']),
|
||||
)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,75 +1,84 @@
|
||||
import { assert } from 'chai'
|
||||
import _ from 'lodash'
|
||||
import { LedgerRequest, LedgerResponse } from 'xrpl-local'
|
||||
import { Ledger } from 'xrpl-local/models/ledger'
|
||||
|
||||
import { LedgerRequest, LedgerResponse } from '../../../src'
|
||||
import { Ledger } from '../../../src/models/ledger'
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
|
||||
describe('ledger', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('base', async function () {
|
||||
const ledgerRequest: LedgerRequest = {
|
||||
command: 'ledger',
|
||||
ledger_index: 'validated',
|
||||
}
|
||||
|
||||
const expected = {
|
||||
id: 0,
|
||||
result: {
|
||||
ledger: {
|
||||
accepted: true,
|
||||
account_hash: 'string',
|
||||
close_flags: 0,
|
||||
close_time: 0,
|
||||
close_time_human: 'string',
|
||||
},
|
||||
ledger_hash: 'string',
|
||||
ledger_index: 1,
|
||||
validated: true,
|
||||
},
|
||||
type: 'response',
|
||||
}
|
||||
|
||||
const ledgerResponse: LedgerResponse = await this.client.request(
|
||||
ledgerRequest,
|
||||
)
|
||||
|
||||
assert.equal(ledgerResponse.type, expected.type)
|
||||
|
||||
assert.equal(ledgerResponse.result.validated, expected.result.validated)
|
||||
assert.typeOf(ledgerResponse.result.ledger_hash, 'string')
|
||||
assert.typeOf(ledgerResponse.result.ledger_index, 'number')
|
||||
|
||||
const ledger = ledgerResponse.result.ledger as Ledger & {
|
||||
accepted: boolean
|
||||
hash: string
|
||||
seqNum: string
|
||||
}
|
||||
assert.equal(ledger.closed, true)
|
||||
const stringTypes = [
|
||||
'account_hash',
|
||||
'close_time_human',
|
||||
'ledger_hash',
|
||||
'ledger_index',
|
||||
'parent_hash',
|
||||
'total_coins',
|
||||
'transaction_hash',
|
||||
]
|
||||
stringTypes.forEach((strType) => assert.typeOf(ledger[strType], 'string'))
|
||||
const numTypes = [
|
||||
'close_flags',
|
||||
'close_time',
|
||||
'close_time_resolution',
|
||||
'parent_close_time',
|
||||
]
|
||||
numTypes.forEach((numType) => assert.typeOf(ledger[numType], 'number'))
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it(
|
||||
'base',
|
||||
async () => {
|
||||
const ledgerRequest: LedgerRequest = {
|
||||
command: 'ledger',
|
||||
ledger_index: 'validated',
|
||||
}
|
||||
|
||||
const expected = {
|
||||
id: 0,
|
||||
result: {
|
||||
ledger: {
|
||||
accepted: true,
|
||||
account_hash: 'string',
|
||||
close_flags: 0,
|
||||
close_time: 0,
|
||||
close_time_human: 'string',
|
||||
},
|
||||
ledger_hash: 'string',
|
||||
ledger_index: 1,
|
||||
validated: true,
|
||||
},
|
||||
type: 'response',
|
||||
}
|
||||
|
||||
const ledgerResponse: LedgerResponse = await testContext.client.request(
|
||||
ledgerRequest,
|
||||
)
|
||||
|
||||
assert.equal(ledgerResponse.type, expected.type)
|
||||
|
||||
assert.equal(ledgerResponse.result.validated, expected.result.validated)
|
||||
assert.typeOf(ledgerResponse.result.ledger_hash, 'string')
|
||||
assert.typeOf(ledgerResponse.result.ledger_index, 'number')
|
||||
|
||||
const ledger = ledgerResponse.result.ledger as Ledger & {
|
||||
accepted: boolean
|
||||
hash: string
|
||||
seqNum: string
|
||||
}
|
||||
assert.equal(ledger.closed, true)
|
||||
const stringTypes = [
|
||||
'account_hash',
|
||||
'close_time_human',
|
||||
'ledger_hash',
|
||||
'ledger_index',
|
||||
'parent_hash',
|
||||
'total_coins',
|
||||
'transaction_hash',
|
||||
]
|
||||
stringTypes.forEach((strType) => assert.typeOf(ledger[strType], 'string'))
|
||||
const numTypes = [
|
||||
'close_flags',
|
||||
'close_time',
|
||||
'close_time_resolution',
|
||||
'parent_close_time',
|
||||
]
|
||||
numTypes.forEach((numType) => assert.typeOf(ledger[numType], 'number'))
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,36 +1,45 @@
|
||||
import { assert } from 'chai'
|
||||
import _ from 'lodash'
|
||||
import { LedgerClosedRequest, LedgerClosedResponse } from 'xrpl-local'
|
||||
|
||||
import { LedgerClosedRequest, LedgerClosedResponse } from '../../../src'
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
|
||||
describe('ledger_closed', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('base', async function () {
|
||||
const ledgerClosedRequest: LedgerClosedRequest = {
|
||||
command: 'ledger_closed',
|
||||
}
|
||||
const ledgerClosedResponse: LedgerClosedResponse =
|
||||
await this.client.request(ledgerClosedRequest)
|
||||
|
||||
const expectedResponse: LedgerClosedResponse = {
|
||||
id: ledgerClosedResponse.id,
|
||||
type: 'response',
|
||||
result: {
|
||||
ledger_hash: 'string',
|
||||
ledger_index: 1,
|
||||
},
|
||||
}
|
||||
assert.equal(ledgerClosedResponse.type, expectedResponse.type)
|
||||
assert.typeOf(ledgerClosedResponse.result.ledger_hash, 'string')
|
||||
assert.typeOf(ledgerClosedResponse.result.ledger_index, 'number')
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it(
|
||||
'base',
|
||||
async () => {
|
||||
const ledgerClosedRequest: LedgerClosedRequest = {
|
||||
command: 'ledger_closed',
|
||||
}
|
||||
const ledgerClosedResponse: LedgerClosedResponse =
|
||||
await testContext.client.request(ledgerClosedRequest)
|
||||
|
||||
const expectedResponse: LedgerClosedResponse = {
|
||||
id: ledgerClosedResponse.id,
|
||||
type: 'response',
|
||||
result: {
|
||||
ledger_hash: 'string',
|
||||
ledger_index: 1,
|
||||
},
|
||||
}
|
||||
assert.equal(ledgerClosedResponse.type, expectedResponse.type)
|
||||
assert.typeOf(ledgerClosedResponse.result.ledger_hash, 'string')
|
||||
assert.typeOf(ledgerClosedResponse.result.ledger_index, 'number')
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,36 +1,45 @@
|
||||
import { assert } from 'chai'
|
||||
import _ from 'lodash'
|
||||
import { LedgerCurrentResponse, LedgerCurrentRequest } from 'xrpl-local'
|
||||
|
||||
import { LedgerCurrentResponse, LedgerCurrentRequest } from '../../../src'
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
|
||||
describe('ledger_current', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('base', async function () {
|
||||
const ledgerCurrentRequest: LedgerCurrentRequest = {
|
||||
command: 'ledger_current',
|
||||
}
|
||||
|
||||
const ledgerCurrentResponse = await this.client.request(
|
||||
ledgerCurrentRequest,
|
||||
)
|
||||
|
||||
const expectedResponse: LedgerCurrentResponse = {
|
||||
id: ledgerCurrentResponse.id,
|
||||
type: 'response',
|
||||
result: {
|
||||
ledger_current_index: 1,
|
||||
},
|
||||
}
|
||||
assert.equal(ledgerCurrentResponse.type, expectedResponse.type)
|
||||
assert.typeOf(ledgerCurrentResponse.result.ledger_current_index, 'number')
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it(
|
||||
'base',
|
||||
async () => {
|
||||
const ledgerCurrentRequest: LedgerCurrentRequest = {
|
||||
command: 'ledger_current',
|
||||
}
|
||||
|
||||
const ledgerCurrentResponse = await testContext.client.request(
|
||||
ledgerCurrentRequest,
|
||||
)
|
||||
|
||||
const expectedResponse: LedgerCurrentResponse = {
|
||||
id: ledgerCurrentResponse.id,
|
||||
type: 'response',
|
||||
result: {
|
||||
ledger_current_index: 1,
|
||||
},
|
||||
}
|
||||
assert.equal(ledgerCurrentResponse.type, expectedResponse.type)
|
||||
assert.typeOf(ledgerCurrentResponse.result.ledger_current_index, 'number')
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,55 +1,67 @@
|
||||
import { assert } from 'chai'
|
||||
import _ from 'lodash'
|
||||
import { LedgerDataRequest } from 'xrpl-local'
|
||||
|
||||
import { LedgerDataRequest } from '../../../src'
|
||||
import type { BinaryLedgerEntry } from '../../../src/models/methods/ledgerData'
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
|
||||
describe('ledger_data', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('base', async function () {
|
||||
const ledgerDataRequest: LedgerDataRequest = {
|
||||
command: 'ledger_data',
|
||||
ledger_index: 'validated',
|
||||
limit: 5,
|
||||
binary: true,
|
||||
}
|
||||
|
||||
const ledgerDataResponse = await this.client.request(ledgerDataRequest)
|
||||
|
||||
const expected = {
|
||||
id: 0,
|
||||
result: {
|
||||
ledger_hash: 'string',
|
||||
ledger_index: 0,
|
||||
marker: 'string',
|
||||
state: [
|
||||
{
|
||||
data: 'string',
|
||||
index: 'string',
|
||||
},
|
||||
],
|
||||
},
|
||||
type: 'response',
|
||||
}
|
||||
|
||||
assert.equal(ledgerDataResponse.type, expected.type)
|
||||
|
||||
assert.typeOf(ledgerDataResponse.result.ledger_hash, 'string')
|
||||
assert.typeOf(ledgerDataResponse.result.ledger_index, 'number')
|
||||
assert.typeOf(ledgerDataResponse.result.marker, 'string')
|
||||
|
||||
assert.equal(ledgerDataResponse.result.state.length, 5)
|
||||
ledgerDataResponse.result.state.forEach((item) => {
|
||||
assert.typeOf(item.data, 'string')
|
||||
assert.typeOf(item.index, 'string')
|
||||
})
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it(
|
||||
'base',
|
||||
async () => {
|
||||
const ledgerDataRequest: LedgerDataRequest = {
|
||||
command: 'ledger_data',
|
||||
ledger_index: 'validated',
|
||||
limit: 5,
|
||||
binary: true,
|
||||
}
|
||||
|
||||
const ledgerDataResponse = await testContext.client.request(
|
||||
ledgerDataRequest,
|
||||
)
|
||||
|
||||
const expected = {
|
||||
id: 0,
|
||||
result: {
|
||||
ledger_hash: 'string',
|
||||
ledger_index: 0,
|
||||
marker: 'string',
|
||||
state: [
|
||||
{
|
||||
data: 'string',
|
||||
index: 'string',
|
||||
},
|
||||
],
|
||||
},
|
||||
type: 'response',
|
||||
}
|
||||
|
||||
assert.equal(ledgerDataResponse.type, expected.type)
|
||||
|
||||
assert.typeOf(ledgerDataResponse.result.ledger_hash, 'string')
|
||||
assert.typeOf(ledgerDataResponse.result.ledger_index, 'number')
|
||||
assert.typeOf(ledgerDataResponse.result.marker, 'string')
|
||||
|
||||
assert.equal(ledgerDataResponse.result.state.length, 5)
|
||||
ledgerDataResponse.result.state.forEach((item) => {
|
||||
assert.typeOf((item as BinaryLedgerEntry).data, 'string')
|
||||
assert.typeOf(item.index, 'string')
|
||||
})
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,47 +1,58 @@
|
||||
import { assert } from 'chai'
|
||||
import _ from 'lodash'
|
||||
import { LedgerEntryRequest, LedgerEntryResponse } from 'xrpl-local'
|
||||
|
||||
import { LedgerEntryRequest, LedgerEntryResponse } from '../../../src'
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
|
||||
describe('ledger_entry', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('base', async function () {
|
||||
const validatedLedgerResponse = await this.client.request({
|
||||
command: 'ledger_data',
|
||||
ledger_index: 'validated',
|
||||
})
|
||||
|
||||
assert.equal(validatedLedgerResponse.type, 'response')
|
||||
const ledgerEntryIndex = validatedLedgerResponse.result.state[0].index
|
||||
|
||||
const ledgerEntryRequest: LedgerEntryRequest = {
|
||||
command: 'ledger_entry',
|
||||
index: ledgerEntryIndex,
|
||||
}
|
||||
|
||||
const ledgerEntryResponse = await this.client.request(ledgerEntryRequest)
|
||||
|
||||
const expectedResponse: LedgerEntryResponse = {
|
||||
id: ledgerEntryResponse.id,
|
||||
type: 'response',
|
||||
result: {
|
||||
index: ledgerEntryIndex,
|
||||
ledger_current_index: ledgerEntryResponse.result.ledger_current_index,
|
||||
node: ledgerEntryResponse.result.node,
|
||||
validated: false,
|
||||
},
|
||||
}
|
||||
|
||||
assert.equal(ledgerEntryResponse.type, 'response')
|
||||
assert.deepEqual(ledgerEntryResponse, expectedResponse)
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it(
|
||||
'base',
|
||||
async () => {
|
||||
const validatedLedgerResponse = await testContext.client.request({
|
||||
command: 'ledger_data',
|
||||
ledger_index: 'validated',
|
||||
})
|
||||
|
||||
assert.equal(validatedLedgerResponse.type, 'response')
|
||||
const ledgerEntryIndex = validatedLedgerResponse.result.state[0].index
|
||||
|
||||
const ledgerEntryRequest: LedgerEntryRequest = {
|
||||
command: 'ledger_entry',
|
||||
index: ledgerEntryIndex,
|
||||
}
|
||||
|
||||
const ledgerEntryResponse = await testContext.client.request(
|
||||
ledgerEntryRequest,
|
||||
)
|
||||
|
||||
const expectedResponse: LedgerEntryResponse = {
|
||||
id: ledgerEntryResponse.id,
|
||||
type: 'response',
|
||||
result: {
|
||||
index: ledgerEntryIndex,
|
||||
ledger_current_index: ledgerEntryResponse.result.ledger_current_index,
|
||||
node: ledgerEntryResponse.result.node,
|
||||
validated: false,
|
||||
},
|
||||
}
|
||||
|
||||
assert.equal(ledgerEntryResponse.type, 'response')
|
||||
assert.deepEqual(ledgerEntryResponse, expectedResponse)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,57 +1,70 @@
|
||||
import { assert } from 'chai'
|
||||
import _ from 'lodash'
|
||||
import { NoRippleCheckRequest } from 'xrpl-local'
|
||||
|
||||
import { NoRippleCheckRequest, type AccountSet } from '../../../src'
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
|
||||
describe('noripple_check', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('base', async function () {
|
||||
const request: NoRippleCheckRequest = {
|
||||
command: 'noripple_check',
|
||||
account: this.wallet.classicAddress,
|
||||
role: 'gateway',
|
||||
ledger_index: 'current',
|
||||
transactions: true,
|
||||
}
|
||||
const response = await this.client.request(request)
|
||||
const expected = {
|
||||
id: 0,
|
||||
result: {
|
||||
ledger_current_index: 2535,
|
||||
problems: ['You should immediately set your default ripple flag'],
|
||||
transactions: [
|
||||
{
|
||||
Account: this.wallet.classicAddress,
|
||||
Fee: 10,
|
||||
Sequence: 1268,
|
||||
SetFlag: 8,
|
||||
TransactionType: 'AccountSet',
|
||||
},
|
||||
],
|
||||
validated: false,
|
||||
},
|
||||
type: 'response',
|
||||
}
|
||||
assert.equal(response.type, expected.type)
|
||||
assert.equal(typeof response.result.transactions[0].Fee, 'number')
|
||||
assert.equal(typeof response.result.transactions[0].Sequence, 'number')
|
||||
assert.equal(typeof response.result.problems, 'object')
|
||||
assert.equal(typeof response.result.problems[0], 'string')
|
||||
|
||||
const responseTx = response.result.transactions[0]
|
||||
const expectedTx = expected.result.transactions[0]
|
||||
assert.deepEqual(
|
||||
[responseTx.Account, responseTx.SetFlag, responseTx.TransactionType],
|
||||
[expectedTx.Account, expectedTx.SetFlag, expectedTx.TransactionType],
|
||||
)
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it(
|
||||
'base',
|
||||
async () => {
|
||||
const request: NoRippleCheckRequest = {
|
||||
command: 'noripple_check',
|
||||
account: testContext.wallet.classicAddress,
|
||||
role: 'gateway',
|
||||
ledger_index: 'current',
|
||||
transactions: true,
|
||||
}
|
||||
const response = await testContext.client.request(request)
|
||||
const expected = {
|
||||
id: 0,
|
||||
result: {
|
||||
ledger_current_index: 2535,
|
||||
problems: ['You should immediately set your default ripple flag'],
|
||||
transactions: [
|
||||
{
|
||||
Account: testContext.wallet.classicAddress,
|
||||
Fee: 10,
|
||||
Sequence: 1268,
|
||||
SetFlag: 8,
|
||||
TransactionType: 'AccountSet',
|
||||
},
|
||||
],
|
||||
validated: false,
|
||||
},
|
||||
type: 'response',
|
||||
}
|
||||
assert.equal(response.type, expected.type)
|
||||
assert.equal(typeof response.result.transactions[0].Fee, 'number')
|
||||
assert.equal(typeof response.result.transactions[0].Sequence, 'number')
|
||||
assert.equal(typeof response.result.problems, 'object')
|
||||
assert.equal(typeof response.result.problems[0], 'string')
|
||||
|
||||
const responseTx = response.result.transactions[0]
|
||||
const expectedTx = expected.result.transactions[0]
|
||||
assert.deepEqual(
|
||||
[
|
||||
responseTx.Account,
|
||||
(responseTx as AccountSet).SetFlag,
|
||||
responseTx.TransactionType,
|
||||
],
|
||||
[expectedTx.Account, expectedTx.SetFlag, expectedTx.TransactionType],
|
||||
)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,107 +1,121 @@
|
||||
import { assert } from 'chai'
|
||||
import _ from 'lodash'
|
||||
import omit from 'lodash/omit'
|
||||
|
||||
import {
|
||||
PathFindRequest,
|
||||
PathFindResponse,
|
||||
Client,
|
||||
PathFindStream,
|
||||
} from 'xrpl-local'
|
||||
|
||||
} from '../../../src'
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
import { generateFundedWallet, ledgerAccept, subscribeDone } from '../utils'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
|
||||
describe('path_find', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('base', async function () {
|
||||
const wallet2 = await generateFundedWallet(this.client)
|
||||
const pathFind: PathFindRequest = {
|
||||
command: 'path_find',
|
||||
subcommand: 'create',
|
||||
source_account: this.wallet.classicAddress,
|
||||
destination_account: wallet2.classicAddress,
|
||||
destination_amount: '100',
|
||||
}
|
||||
|
||||
const response = await this.client.request(pathFind)
|
||||
|
||||
const expectedResponse: PathFindResponse = {
|
||||
id: response.id,
|
||||
type: 'response',
|
||||
result: {
|
||||
alternatives: response.result.alternatives,
|
||||
destination_account: pathFind.destination_account,
|
||||
destination_amount: pathFind.destination_amount,
|
||||
source_account: pathFind.source_account,
|
||||
full_reply: false,
|
||||
id: response.id,
|
||||
},
|
||||
}
|
||||
|
||||
assert.deepEqual(response, expectedResponse)
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it(
|
||||
'base',
|
||||
async () => {
|
||||
const wallet2 = await generateFundedWallet(testContext.client)
|
||||
const pathFind: PathFindRequest = {
|
||||
command: 'path_find',
|
||||
subcommand: 'create',
|
||||
source_account: testContext.wallet.classicAddress,
|
||||
destination_account: wallet2.classicAddress,
|
||||
destination_amount: '100',
|
||||
}
|
||||
|
||||
const response = await testContext.client.request(pathFind)
|
||||
|
||||
const expectedResponse: PathFindResponse = {
|
||||
id: response.id,
|
||||
type: 'response',
|
||||
result: {
|
||||
alternatives: response.result.alternatives,
|
||||
destination_account: pathFind.destination_account,
|
||||
destination_amount: pathFind.destination_amount,
|
||||
source_account: pathFind.source_account,
|
||||
full_reply: false,
|
||||
id: response.id,
|
||||
},
|
||||
}
|
||||
|
||||
assert.deepEqual(response, expectedResponse)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
|
||||
/**
|
||||
* For other stream style tests look at integration/requests/subscribe.ts
|
||||
* Note: This test uses '.then' to avoid awaits in order to use 'done' style tests.
|
||||
*/
|
||||
it('path_find stream succeeds', function (done) {
|
||||
generateFundedWallet(this.client)
|
||||
.then((wallet2) => {
|
||||
const pathFind: PathFindRequest = {
|
||||
command: 'path_find',
|
||||
subcommand: 'create',
|
||||
source_account: this.wallet.classicAddress,
|
||||
destination_account: wallet2.classicAddress,
|
||||
destination_amount: '100',
|
||||
}
|
||||
it(
|
||||
'path_find stream succeeds',
|
||||
async () => {
|
||||
const wallet2 = await generateFundedWallet(testContext.client)
|
||||
const pathFind: PathFindRequest = {
|
||||
command: 'path_find',
|
||||
subcommand: 'create',
|
||||
source_account: testContext.wallet.classicAddress,
|
||||
destination_account: wallet2.classicAddress,
|
||||
destination_amount: '100',
|
||||
}
|
||||
|
||||
const expectedStreamResult: PathFindStream = {
|
||||
type: 'path_find',
|
||||
source_account: pathFind.source_account,
|
||||
destination_account: pathFind.destination_account,
|
||||
destination_amount: pathFind.destination_amount,
|
||||
full_reply: true,
|
||||
id: 10,
|
||||
alternatives: [],
|
||||
}
|
||||
const expectedStreamResult: PathFindStream = {
|
||||
type: 'path_find',
|
||||
source_account: pathFind.source_account,
|
||||
destination_account: pathFind.destination_account,
|
||||
destination_amount: pathFind.destination_amount,
|
||||
full_reply: true,
|
||||
id: 10,
|
||||
alternatives: [],
|
||||
}
|
||||
|
||||
const client: Client = this.client
|
||||
const client: Client = testContext.client
|
||||
|
||||
const pathFindPromise = new Promise<void>((resolve) => {
|
||||
client.on('path_find', (path) => {
|
||||
assert.equal(path.type, 'path_find')
|
||||
assert.deepEqual(
|
||||
_.omit(path, 'id'),
|
||||
_.omit(expectedStreamResult, 'id'),
|
||||
)
|
||||
subscribeDone(this.client, done)
|
||||
})
|
||||
|
||||
this.client.request(pathFind).then((response) => {
|
||||
const expectedResponse: PathFindResponse = {
|
||||
id: response.id,
|
||||
type: 'response',
|
||||
result: {
|
||||
alternatives: response.result.alternatives,
|
||||
destination_account: pathFind.destination_account,
|
||||
destination_amount: pathFind.destination_amount,
|
||||
source_account: pathFind.source_account,
|
||||
full_reply: false,
|
||||
id: response.id,
|
||||
},
|
||||
}
|
||||
|
||||
assert.deepEqual(response, expectedResponse)
|
||||
assert.deepEqual(omit(path, 'id'), omit(expectedStreamResult, 'id'))
|
||||
subscribeDone(testContext.client)
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
.then(() => {
|
||||
ledgerAccept(this.client)
|
||||
})
|
||||
})
|
||||
|
||||
const response = await testContext.client.request(pathFind)
|
||||
|
||||
const expectedResponse: PathFindResponse = {
|
||||
id: response.id,
|
||||
type: 'response',
|
||||
result: {
|
||||
alternatives: response.result.alternatives,
|
||||
destination_account: pathFind.destination_account,
|
||||
destination_amount: pathFind.destination_amount,
|
||||
source_account: pathFind.source_account,
|
||||
full_reply: false,
|
||||
id: response.id,
|
||||
},
|
||||
}
|
||||
|
||||
assert.deepEqual(response, expectedResponse)
|
||||
|
||||
await ledgerAccept(testContext.client)
|
||||
|
||||
await pathFindPromise
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,48 +1,57 @@
|
||||
import { assert } from 'chai'
|
||||
import _ from 'lodash'
|
||||
import { RipplePathFindRequest, RipplePathFindResponse } from 'xrpl-local'
|
||||
|
||||
import { RipplePathFindRequest, RipplePathFindResponse } from '../../../src'
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
import { generateFundedWallet } from '../utils'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
|
||||
describe('ripple_path_find', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('base', async function () {
|
||||
const wallet2 = await generateFundedWallet(this.client)
|
||||
const ripplePathFind: RipplePathFindRequest = {
|
||||
command: 'ripple_path_find',
|
||||
subcommand: 'create',
|
||||
source_account: this.wallet.classicAddress,
|
||||
destination_account: wallet2.classicAddress,
|
||||
destination_amount: '100',
|
||||
}
|
||||
|
||||
const response = await this.client.request(ripplePathFind)
|
||||
|
||||
const expectedResponse: RipplePathFindResponse = {
|
||||
id: response.id,
|
||||
type: 'response',
|
||||
result: {
|
||||
alternatives: response.result.alternatives,
|
||||
destination_account: wallet2.classicAddress,
|
||||
destination_currencies: response.result.destination_currencies,
|
||||
destination_amount: ripplePathFind.destination_amount,
|
||||
full_reply: true,
|
||||
id: response.id,
|
||||
ledger_current_index: response.result.ledger_current_index,
|
||||
source_account: ripplePathFind.source_account,
|
||||
validated: false,
|
||||
},
|
||||
}
|
||||
|
||||
assert.deepEqual(response, expectedResponse)
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it(
|
||||
'base',
|
||||
async () => {
|
||||
const wallet2 = await generateFundedWallet(testContext.client)
|
||||
const ripplePathFind: RipplePathFindRequest = {
|
||||
command: 'ripple_path_find',
|
||||
subcommand: 'create',
|
||||
source_account: testContext.wallet.classicAddress,
|
||||
destination_account: wallet2.classicAddress,
|
||||
destination_amount: '100',
|
||||
}
|
||||
|
||||
const response = await testContext.client.request(ripplePathFind)
|
||||
|
||||
const expectedResponse: RipplePathFindResponse = {
|
||||
id: response.id,
|
||||
type: 'response',
|
||||
result: {
|
||||
alternatives: response.result.alternatives,
|
||||
destination_account: wallet2.classicAddress,
|
||||
destination_currencies: response.result.destination_currencies,
|
||||
destination_amount: ripplePathFind.destination_amount,
|
||||
full_reply: true,
|
||||
id: response.id,
|
||||
ledger_current_index: response.result.ledger_current_index,
|
||||
source_account: ripplePathFind.source_account,
|
||||
validated: false,
|
||||
},
|
||||
}
|
||||
|
||||
assert.deepEqual(response, expectedResponse)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,132 +1,149 @@
|
||||
import { assert } from 'chai'
|
||||
import _ from 'lodash'
|
||||
import { ServerInfoRequest } from 'xrpl-local'
|
||||
import omit from 'lodash/omit'
|
||||
|
||||
import { type ServerInfoRequest, type ServerInfoResponse } from '../../../src'
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
|
||||
describe('server_info', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
describe('server_info (rippled)', function () {
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it('base', async function () {
|
||||
const request: ServerInfoRequest = {
|
||||
command: 'server_info',
|
||||
}
|
||||
const response = await this.client.request(request)
|
||||
const expected = {
|
||||
id: 0,
|
||||
result: {
|
||||
info: {
|
||||
build_version: '1.7.3',
|
||||
complete_ledgers: '2563-2928',
|
||||
hostid: '44578fe64241',
|
||||
io_latency_ms: 1,
|
||||
jq_trans_overflow: '0',
|
||||
last_close: { converge_time_s: 0.1, proposers: 0 },
|
||||
load: {
|
||||
job_types: [
|
||||
{
|
||||
in_progress: 1,
|
||||
job_type: 'clientCommand',
|
||||
peak_time: 4,
|
||||
per_second: 9,
|
||||
},
|
||||
{ job_type: 'updatePaths', per_second: 1 },
|
||||
{ job_type: 'advanceLedger', per_second: 1 },
|
||||
{ job_type: 'pathFind', per_second: 1 },
|
||||
{ job_type: 'WriteNode', per_second: 17 },
|
||||
],
|
||||
threads: 1,
|
||||
},
|
||||
load_factor: 1,
|
||||
peer_disconnects: '0',
|
||||
peer_disconnects_resources: '0',
|
||||
peers: 0,
|
||||
pubkey_node: 'n9K6DaaReKkCjb9sEfXh5xP3BV9JisrJ9biKB3CSSFXancBnv5cW',
|
||||
pubkey_validator: 'none',
|
||||
server_state: 'full',
|
||||
server_state_duration_us: '8752395105',
|
||||
state_accounting: {
|
||||
connected: { duration_us: '0', transitions: 0 },
|
||||
disconnected: { duration_us: '41860', transitions: 1 },
|
||||
full: { duration_us: '20723121268', transitions: 1 },
|
||||
syncing: { duration_us: '0', transitions: 0 },
|
||||
tracking: { duration_us: '0', transitions: 0 },
|
||||
},
|
||||
time: '2021-Sep-23 22:56:55.320858 UTC',
|
||||
uptime: 8752,
|
||||
validated_ledger: {
|
||||
age: 0,
|
||||
base_fee_xrp: 0.00001,
|
||||
hash: '532175EC25CF34081D7F83584F37DAB70035A422CBE94352BEDA8EC123CB8F60',
|
||||
reserve_base_xrp: 200,
|
||||
reserve_inc_xrp: 50,
|
||||
seq: 1906,
|
||||
},
|
||||
validation_quorum: 0,
|
||||
validator_list: {
|
||||
count: 0,
|
||||
expiration: 'unknown',
|
||||
status: 'unknown',
|
||||
it(
|
||||
'base',
|
||||
async () => {
|
||||
const request: ServerInfoRequest = {
|
||||
command: 'server_info',
|
||||
}
|
||||
const response = await testContext.client.request(request)
|
||||
const expected: ServerInfoResponse = {
|
||||
id: 0,
|
||||
result: {
|
||||
info: {
|
||||
build_version: '1.7.3',
|
||||
complete_ledgers: '2563-2928',
|
||||
hostid: '44578fe64241',
|
||||
io_latency_ms: 1,
|
||||
jq_trans_overflow: '0',
|
||||
last_close: { converge_time_s: 0.1, proposers: 0 },
|
||||
load: {
|
||||
job_types: [
|
||||
{
|
||||
in_progress: 1,
|
||||
job_type: 'clientCommand',
|
||||
peak_time: 4,
|
||||
per_second: 9,
|
||||
},
|
||||
{ job_type: 'updatePaths', per_second: 1 },
|
||||
{ job_type: 'advanceLedger', per_second: 1 },
|
||||
{ job_type: 'pathFind', per_second: 1 },
|
||||
{ job_type: 'WriteNode', per_second: 17 },
|
||||
],
|
||||
threads: 1,
|
||||
},
|
||||
load_factor: 1,
|
||||
peer_disconnects: '0',
|
||||
peer_disconnects_resources: '0',
|
||||
peers: 0,
|
||||
pubkey_node: 'n9K6DaaReKkCjb9sEfXh5xP3BV9JisrJ9biKB3CSSFXancBnv5cW',
|
||||
pubkey_validator: 'none',
|
||||
server_state: 'full',
|
||||
server_state_duration_us: '8752395105',
|
||||
state_accounting: {
|
||||
connected: { duration_us: '0', transitions: 0 },
|
||||
disconnected: { duration_us: '41860', transitions: 1 },
|
||||
full: { duration_us: '20723121268', transitions: 1 },
|
||||
syncing: { duration_us: '0', transitions: 0 },
|
||||
tracking: { duration_us: '0', transitions: 0 },
|
||||
},
|
||||
time: '2021-Sep-23 22:56:55.320858 UTC',
|
||||
uptime: 8752,
|
||||
validated_ledger: {
|
||||
age: 0,
|
||||
base_fee_xrp: 0.00001,
|
||||
hash: '532175EC25CF34081D7F83584F37DAB70035A422CBE94352BEDA8EC123CB8F60',
|
||||
reserve_base_xrp: 200,
|
||||
reserve_inc_xrp: 50,
|
||||
seq: 1906,
|
||||
},
|
||||
validation_quorum: 0,
|
||||
validator_list: {
|
||||
count: 0,
|
||||
expiration: 'unknown',
|
||||
status: 'unknown',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
type: 'response',
|
||||
}
|
||||
assert.equal(response.type, expected.type)
|
||||
type: 'response',
|
||||
}
|
||||
assert.equal(response.type, expected.type)
|
||||
|
||||
assert.equal(typeof response.result.info.time, 'string')
|
||||
assert.equal(typeof response.result.info.uptime, 'number')
|
||||
assert.equal(typeof response.result.info.complete_ledgers, 'string')
|
||||
assert.equal(typeof response.result.info.hostid, 'string')
|
||||
assert.equal(typeof response.result.info.pubkey_node, 'string')
|
||||
assert.equal(typeof response.result.info.server_state_duration_us, 'string')
|
||||
const removeKeys = [
|
||||
'time',
|
||||
'uptime',
|
||||
'complete_ledgers',
|
||||
'hostid',
|
||||
'load',
|
||||
'state_accounting',
|
||||
'pubkey_node',
|
||||
'server_state_duration_us',
|
||||
'validated_ledger',
|
||||
]
|
||||
assert.deepEqual(
|
||||
_.omit(response.result.info, removeKeys),
|
||||
_.omit(expected.result.info, removeKeys),
|
||||
)
|
||||
|
||||
// load
|
||||
assert.equal(typeof response.result.info.load.threads, 'number')
|
||||
for (const obj of response.result.info.load.job_types) {
|
||||
assert.equal(typeof obj.per_second, 'number')
|
||||
assert.equal(typeof obj.job_type, 'string')
|
||||
}
|
||||
// state_accounting
|
||||
Object.keys(response.result.info.state_accounting).forEach(function (key) {
|
||||
assert.equal(typeof response.result.info.time, 'string')
|
||||
assert.equal(typeof response.result.info.uptime, 'number')
|
||||
assert.equal(typeof response.result.info.complete_ledgers, 'string')
|
||||
assert.equal(typeof response.result.info.hostid, 'string')
|
||||
assert.equal(typeof response.result.info.pubkey_node, 'string')
|
||||
assert.equal(
|
||||
typeof response.result.info.state_accounting[key].duration_us,
|
||||
typeof response.result.info.server_state_duration_us,
|
||||
'string',
|
||||
)
|
||||
assert.equal(
|
||||
typeof response.result.info.state_accounting[key].transitions,
|
||||
'number',
|
||||
const removeKeys = [
|
||||
'time',
|
||||
'uptime',
|
||||
'complete_ledgers',
|
||||
'hostid',
|
||||
'load',
|
||||
'state_accounting',
|
||||
'pubkey_node',
|
||||
'server_state_duration_us',
|
||||
'validated_ledger',
|
||||
]
|
||||
assert.deepEqual(
|
||||
omit(response.result.info, removeKeys),
|
||||
omit(expected.result.info, removeKeys),
|
||||
)
|
||||
})
|
||||
|
||||
// validated_ledger
|
||||
assert.equal(typeof response.result.info.validated_ledger.hash, 'string')
|
||||
for (const key of Object.keys(
|
||||
_.omit(response.result.info.validated_ledger, 'hash'),
|
||||
)) {
|
||||
assert.equal(typeof response.result.info.validated_ledger[key], 'number')
|
||||
}
|
||||
})
|
||||
// load
|
||||
assert.equal(typeof response.result.info.load?.threads, 'number')
|
||||
for (const obj of response.result.info.load?.job_types ?? []) {
|
||||
assert.equal(typeof obj.job_type, 'string')
|
||||
}
|
||||
// state_accounting
|
||||
Object.keys(response.result.info.state_accounting).forEach(function (
|
||||
key,
|
||||
) {
|
||||
assert.equal(
|
||||
typeof response.result.info.state_accounting[key].duration_us,
|
||||
'string',
|
||||
)
|
||||
assert.equal(
|
||||
typeof response.result.info.state_accounting[key].transitions,
|
||||
'number',
|
||||
)
|
||||
})
|
||||
|
||||
// validated_ledger
|
||||
assert.equal(typeof response.result.info.validated_ledger?.hash, 'string')
|
||||
for (const key of Object.keys(
|
||||
omit(response.result.info.validated_ledger, 'hash'),
|
||||
)) {
|
||||
assert.equal(
|
||||
typeof response.result.info.validated_ledger?.[key],
|
||||
'number',
|
||||
)
|
||||
}
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,137 +1,156 @@
|
||||
import { assert } from 'chai'
|
||||
import _ from 'lodash'
|
||||
import { ServerStateRequest } from 'xrpl-local'
|
||||
import omit from 'lodash/omit'
|
||||
|
||||
import { type ServerStateRequest, type ServerStateResponse } from '../../../src'
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
|
||||
describe('server_state', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it('base', async function () {
|
||||
const request: ServerStateRequest = {
|
||||
command: 'server_state',
|
||||
}
|
||||
const response = await this.client.request(request)
|
||||
const expected = {
|
||||
id: 0,
|
||||
result: {
|
||||
state: {
|
||||
build_version: '1.7.3',
|
||||
complete_ledgers: '2563-2932',
|
||||
io_latency_ms: 1,
|
||||
jq_trans_overflow: '0',
|
||||
last_close: {
|
||||
converge_time: 100,
|
||||
proposers: 0,
|
||||
it(
|
||||
'base',
|
||||
async () => {
|
||||
const request: ServerStateRequest = {
|
||||
command: 'server_state',
|
||||
}
|
||||
const response = await testContext.client.request(request)
|
||||
const expected: ServerStateResponse = {
|
||||
id: 0,
|
||||
result: {
|
||||
state: {
|
||||
build_version: '1.7.3',
|
||||
complete_ledgers: '2563-2932',
|
||||
io_latency_ms: 1,
|
||||
jq_trans_overflow: '0',
|
||||
last_close: {
|
||||
converge_time: 100,
|
||||
proposers: 0,
|
||||
},
|
||||
load: {
|
||||
job_types: [
|
||||
{
|
||||
in_progress: 1,
|
||||
job_type: 'clientCommand',
|
||||
peak_time: 4,
|
||||
per_second: 9,
|
||||
},
|
||||
{ job_type: 'updatePaths', per_second: 1 },
|
||||
{ job_type: 'advanceLedger', per_second: 1 },
|
||||
{ job_type: 'pathFind', per_second: 1 },
|
||||
{ job_type: 'WriteNode', per_second: 17 },
|
||||
],
|
||||
threads: 1,
|
||||
},
|
||||
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,
|
||||
peer_disconnects: '0',
|
||||
peer_disconnects_resources: '0',
|
||||
peers: 0,
|
||||
pubkey_node: 'n9K6DaaReKkCjb9sEfXh5xP3BV9JisrJ9biKB3CSSFXancBnv5cW',
|
||||
pubkey_validator: 'none',
|
||||
server_state: 'full',
|
||||
server_state_duration_us: '8752487389',
|
||||
state_accounting: {
|
||||
connected: { duration_us: '0', transitions: 0 },
|
||||
disconnected: { duration_us: '41860', transitions: 1 },
|
||||
full: { duration_us: '20723121268', transitions: 1 },
|
||||
syncing: { duration_us: '0', transitions: 0 },
|
||||
tracking: { duration_us: '0', transitions: 0 },
|
||||
},
|
||||
time: '2021-Sep-23 22:56:55.413151 UTC',
|
||||
uptime: 8752,
|
||||
validated_ledger: {
|
||||
base_fee: 10,
|
||||
close_time: 685829741,
|
||||
hash: 'B98AABCE40A54DF654C86E56088AD7D46BBA8B8E93AD3FAC2426FEFF847F7937',
|
||||
reserve_base: 200000000,
|
||||
reserve_inc: 50000000,
|
||||
seq: 2294,
|
||||
},
|
||||
validation_quorum: 0,
|
||||
validator_list_expires: 0,
|
||||
},
|
||||
load: {
|
||||
job_types: [
|
||||
{
|
||||
in_progress: 1,
|
||||
job_type: 'clientCommand',
|
||||
peak_time: 4,
|
||||
per_second: 9,
|
||||
},
|
||||
{ job_type: 'updatePaths', per_second: 1 },
|
||||
{ job_type: 'advanceLedger', per_second: 1 },
|
||||
{ job_type: 'pathFind', per_second: 1 },
|
||||
{ job_type: 'WriteNode', per_second: 17 },
|
||||
],
|
||||
threads: 1,
|
||||
},
|
||||
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,
|
||||
peer_disconnects: '0',
|
||||
peer_disconnects_resources: '0',
|
||||
peers: 0,
|
||||
pubkey_node: 'n9K6DaaReKkCjb9sEfXh5xP3BV9JisrJ9biKB3CSSFXancBnv5cW',
|
||||
pubkey_validator: 'none',
|
||||
server_state: 'full',
|
||||
server_state_duration_us: '8752487389',
|
||||
state_accounting: {
|
||||
connected: { duration_us: '0', transitions: 0 },
|
||||
disconnected: { duration_us: '41860', transitions: 1 },
|
||||
full: { duration_us: '20723121268', transitions: 1 },
|
||||
syncing: { duration_us: '0', transitions: 0 },
|
||||
tracking: { duration_us: '0', transitions: 0 },
|
||||
},
|
||||
time: '2021-Sep-23 22:56:55.413151 UTC',
|
||||
uptime: 8752,
|
||||
validated_ledger: {
|
||||
base_fee: 10,
|
||||
close_time: 685829741,
|
||||
hash: 'B98AABCE40A54DF654C86E56088AD7D46BBA8B8E93AD3FAC2426FEFF847F7937',
|
||||
reserve_base: 200000000,
|
||||
reserve_inc: 50000000,
|
||||
seq: 2294,
|
||||
},
|
||||
validation_quorum: 0,
|
||||
validator_list_expires: 0,
|
||||
},
|
||||
},
|
||||
type: 'response',
|
||||
}
|
||||
assert.equal(response.type, expected.type)
|
||||
type: 'response',
|
||||
}
|
||||
assert.equal(response.type, expected.type)
|
||||
|
||||
assert.equal(typeof response.result.state.complete_ledgers, 'string')
|
||||
assert.equal(typeof response.result.state.pubkey_node, 'string')
|
||||
assert.equal(typeof response.result.state.time, 'string')
|
||||
assert.equal(typeof response.result.state.uptime, 'number')
|
||||
assert.equal(
|
||||
typeof response.result.state.server_state_duration_us,
|
||||
'string',
|
||||
)
|
||||
|
||||
const removeKeys = [
|
||||
'complete_ledgers',
|
||||
'load',
|
||||
'state_accounting',
|
||||
'pubkey_node',
|
||||
'time',
|
||||
'uptime',
|
||||
'server_state_duration_us',
|
||||
'validated_ledger',
|
||||
]
|
||||
assert.deepEqual(
|
||||
_.omit(response.result.state, removeKeys),
|
||||
_.omit(expected.result.state, removeKeys),
|
||||
)
|
||||
|
||||
// load
|
||||
assert.equal(typeof response.result.state.load.threads, 'number')
|
||||
for (const obj of response.result.state.load.job_types) {
|
||||
assert.equal(typeof obj.per_second, 'number')
|
||||
assert.equal(typeof obj.job_type, 'string')
|
||||
}
|
||||
// state_accounting
|
||||
Object.keys(response.result.state.state_accounting).forEach(function (key) {
|
||||
assert.equal(typeof response.result.state.io_latency_ms, 'number')
|
||||
assert.equal(typeof response.result.state.complete_ledgers, 'string')
|
||||
assert.equal(typeof response.result.state.pubkey_node, 'string')
|
||||
assert.equal(typeof response.result.state.time, 'string')
|
||||
assert.equal(typeof response.result.state.uptime, 'number')
|
||||
assert.equal(
|
||||
typeof response.result.state.state_accounting[key].duration_us,
|
||||
typeof response.result.state.server_state_duration_us,
|
||||
'string',
|
||||
)
|
||||
assert.equal(
|
||||
typeof response.result.state.state_accounting[key].transitions,
|
||||
'number',
|
||||
)
|
||||
})
|
||||
|
||||
// validated_ledger
|
||||
assert.equal(typeof response.result.state.validated_ledger.hash, 'string')
|
||||
for (const key of Object.keys(
|
||||
_.omit(response.result.state.validated_ledger, 'hash'),
|
||||
)) {
|
||||
assert.equal(typeof response.result.state.validated_ledger[key], 'number')
|
||||
}
|
||||
})
|
||||
const removeKeys = [
|
||||
'complete_ledgers',
|
||||
'load',
|
||||
'state_accounting',
|
||||
'pubkey_node',
|
||||
'time',
|
||||
'uptime',
|
||||
'server_state_duration_us',
|
||||
'validated_ledger',
|
||||
'io_latency_ms',
|
||||
]
|
||||
assert.deepEqual(
|
||||
omit(response.result.state, removeKeys),
|
||||
omit(expected.result.state, removeKeys),
|
||||
)
|
||||
|
||||
// load
|
||||
assert.equal(typeof response.result.state.load?.threads, 'number')
|
||||
for (const obj of response.result.state.load?.job_types ?? []) {
|
||||
assert.equal(typeof obj.job_type, 'string')
|
||||
}
|
||||
// state_accounting
|
||||
Object.keys(response.result.state.state_accounting).forEach(function (
|
||||
key,
|
||||
) {
|
||||
assert.equal(
|
||||
typeof response.result.state.state_accounting[key].duration_us,
|
||||
'string',
|
||||
)
|
||||
assert.equal(
|
||||
typeof response.result.state.state_accounting[key].transitions,
|
||||
'number',
|
||||
)
|
||||
})
|
||||
|
||||
// validated_ledger
|
||||
assert.equal(
|
||||
typeof response.result.state.validated_ledger?.hash,
|
||||
'string',
|
||||
)
|
||||
for (const key of Object.keys(
|
||||
omit(response.result.state.validated_ledger, 'hash'),
|
||||
)) {
|
||||
assert.equal(
|
||||
typeof response.result.state.validated_ledger?.[key],
|
||||
'number',
|
||||
)
|
||||
}
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
import { assert } from 'chai'
|
||||
import _ from 'lodash'
|
||||
import { decode } from 'ripple-binary-codec/dist'
|
||||
import { decode } from 'ripple-binary-codec'
|
||||
|
||||
import {
|
||||
AccountSet,
|
||||
SubmitRequest,
|
||||
SubmitResponse,
|
||||
hashes,
|
||||
Transaction,
|
||||
} from 'xrpl-local'
|
||||
import { convertStringToHex } from 'xrpl-local/utils'
|
||||
|
||||
} from '../../../src'
|
||||
import { convertStringToHex } from '../../../src/utils'
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
import { ledgerAccept, verifySubmittedTransaction } from '../utils'
|
||||
|
||||
// how long before each test case times out
|
||||
@@ -19,59 +22,65 @@ const TIMEOUT = 20000
|
||||
const { hashSignedTx } = hashes
|
||||
|
||||
describe('submit', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('submit', async function () {
|
||||
const accountSet: AccountSet = {
|
||||
TransactionType: 'AccountSet',
|
||||
Account: this.wallet.classicAddress,
|
||||
Domain: convertStringToHex('example.com'),
|
||||
}
|
||||
|
||||
const autofilledTx = await this.client.autofill(accountSet)
|
||||
const signedTx = this.wallet.sign(autofilledTx)
|
||||
const submitRequest: SubmitRequest = {
|
||||
command: 'submit',
|
||||
tx_blob: signedTx.tx_blob,
|
||||
}
|
||||
const submitResponse = await this.client.request(submitRequest)
|
||||
|
||||
await ledgerAccept(this.client)
|
||||
await verifySubmittedTransaction(
|
||||
this.client,
|
||||
signedTx.tx_blob,
|
||||
signedTx.hash,
|
||||
)
|
||||
|
||||
const expectedResponse: SubmitResponse = {
|
||||
id: submitResponse.id,
|
||||
type: 'response',
|
||||
result: {
|
||||
engine_result: 'tesSUCCESS',
|
||||
engine_result_code: 0,
|
||||
engine_result_message:
|
||||
'The transaction was applied. Only final in a validated ledger.',
|
||||
tx_blob: signedTx.tx_blob,
|
||||
tx_json: {
|
||||
...(decode(signedTx.tx_blob) as unknown as Transaction),
|
||||
hash: hashSignedTx(signedTx.tx_blob),
|
||||
},
|
||||
accepted: true,
|
||||
account_sequence_available:
|
||||
submitResponse.result.account_sequence_available,
|
||||
account_sequence_next: submitResponse.result.account_sequence_next,
|
||||
applied: true,
|
||||
broadcast: submitResponse.result.broadcast,
|
||||
kept: true,
|
||||
queued: false,
|
||||
open_ledger_cost: submitResponse.result.open_ledger_cost,
|
||||
validated_ledger_index: submitResponse.result.validated_ledger_index,
|
||||
},
|
||||
}
|
||||
|
||||
assert.deepEqual(submitResponse, expectedResponse)
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it(
|
||||
'submit',
|
||||
async () => {
|
||||
const accountSet: AccountSet = {
|
||||
TransactionType: 'AccountSet',
|
||||
Account: testContext.wallet.classicAddress,
|
||||
Domain: convertStringToHex('example.com'),
|
||||
}
|
||||
|
||||
const autofilledTx = await testContext.client.autofill(accountSet)
|
||||
const signedTx = testContext.wallet.sign(autofilledTx)
|
||||
const submitRequest: SubmitRequest = {
|
||||
command: 'submit',
|
||||
tx_blob: signedTx.tx_blob,
|
||||
}
|
||||
const submitResponse = await testContext.client.request(submitRequest)
|
||||
|
||||
await ledgerAccept(testContext.client)
|
||||
await verifySubmittedTransaction(
|
||||
testContext.client,
|
||||
signedTx.tx_blob,
|
||||
signedTx.hash,
|
||||
)
|
||||
|
||||
const expectedResponse: SubmitResponse = {
|
||||
id: submitResponse.id,
|
||||
type: 'response',
|
||||
result: {
|
||||
engine_result: 'tesSUCCESS',
|
||||
engine_result_code: 0,
|
||||
engine_result_message:
|
||||
'The transaction was applied. Only final in a validated ledger.',
|
||||
tx_blob: signedTx.tx_blob,
|
||||
tx_json: {
|
||||
...(decode(signedTx.tx_blob) as unknown as Transaction),
|
||||
hash: hashSignedTx(signedTx.tx_blob),
|
||||
},
|
||||
accepted: true,
|
||||
account_sequence_available:
|
||||
submitResponse.result.account_sequence_available,
|
||||
account_sequence_next: submitResponse.result.account_sequence_next,
|
||||
applied: true,
|
||||
broadcast: submitResponse.result.broadcast,
|
||||
kept: true,
|
||||
queued: false,
|
||||
open_ledger_cost: submitResponse.result.open_ledger_cost,
|
||||
validated_ledger_index: submitResponse.result.validated_ledger_index,
|
||||
},
|
||||
}
|
||||
|
||||
assert.deepEqual(submitResponse, expectedResponse)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { assert } from 'chai'
|
||||
import _ from 'lodash'
|
||||
import { decode } from 'ripple-binary-codec/dist'
|
||||
import { decode } from 'ripple-binary-codec'
|
||||
|
||||
import {
|
||||
AccountSet,
|
||||
Client,
|
||||
@@ -9,12 +9,15 @@ import {
|
||||
Transaction,
|
||||
SubmitMultisignedResponse,
|
||||
hashes,
|
||||
} from 'xrpl-local'
|
||||
import { convertStringToHex } from 'xrpl-local/utils'
|
||||
import { multisign } from 'xrpl-local/Wallet/signer'
|
||||
|
||||
} from '../../../src'
|
||||
import { convertStringToHex } from '../../../src/utils'
|
||||
import { multisign } from '../../../src/Wallet/signer'
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
import {
|
||||
generateFundedWallet,
|
||||
ledgerAccept,
|
||||
@@ -27,73 +30,83 @@ const TIMEOUT = 20000
|
||||
const { hashSignedTx } = hashes
|
||||
|
||||
describe('submit_multisigned', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('submit_multisigned transaction', async function () {
|
||||
const client: Client = this.client
|
||||
const signerWallet1 = await generateFundedWallet(this.client)
|
||||
const signerWallet2 = await generateFundedWallet(this.client)
|
||||
|
||||
// set up the multisigners for the account
|
||||
const signerListSet: SignerListSet = {
|
||||
TransactionType: 'SignerListSet',
|
||||
Account: this.wallet.classicAddress,
|
||||
SignerEntries: [
|
||||
{
|
||||
SignerEntry: {
|
||||
Account: signerWallet1.classicAddress,
|
||||
SignerWeight: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
SignerEntry: {
|
||||
Account: signerWallet2.classicAddress,
|
||||
SignerWeight: 1,
|
||||
},
|
||||
},
|
||||
],
|
||||
SignerQuorum: 2,
|
||||
}
|
||||
await testTransaction(this.client, signerListSet, this.wallet)
|
||||
|
||||
// try to multisign
|
||||
const accountSet: AccountSet = {
|
||||
TransactionType: 'AccountSet',
|
||||
Account: this.wallet.classicAddress,
|
||||
Domain: convertStringToHex('example.com'),
|
||||
}
|
||||
const accountSetTx = await client.autofill(accountSet, 2)
|
||||
const signed1 = signerWallet1.sign(accountSetTx, true)
|
||||
const signed2 = signerWallet2.sign(accountSetTx, true)
|
||||
const multisigned = multisign([signed1.tx_blob, signed2.tx_blob])
|
||||
const multisignedRequest: SubmitMultisignedRequest = {
|
||||
command: 'submit_multisigned',
|
||||
tx_json: decode(multisigned) as unknown as Transaction,
|
||||
}
|
||||
const submitResponse = await client.request(multisignedRequest)
|
||||
await ledgerAccept(client)
|
||||
assert.strictEqual(submitResponse.result.engine_result, 'tesSUCCESS')
|
||||
await verifySubmittedTransaction(this.client, multisigned)
|
||||
|
||||
const expectedResponse: SubmitMultisignedResponse = {
|
||||
id: submitResponse.id,
|
||||
type: 'response',
|
||||
result: {
|
||||
engine_result: 'tesSUCCESS',
|
||||
engine_result_code: 0,
|
||||
engine_result_message:
|
||||
'The transaction was applied. Only final in a validated ledger.',
|
||||
tx_blob: multisigned,
|
||||
tx_json: {
|
||||
...(decode(multisigned) as unknown as Transaction),
|
||||
hash: hashSignedTx(multisigned),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
assert.deepEqual(submitResponse, expectedResponse)
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it(
|
||||
'submit_multisigned transaction',
|
||||
async () => {
|
||||
const client: Client = testContext.client
|
||||
const signerWallet1 = await generateFundedWallet(testContext.client)
|
||||
const signerWallet2 = await generateFundedWallet(testContext.client)
|
||||
|
||||
// set up the multisigners for the account
|
||||
const signerListSet: SignerListSet = {
|
||||
TransactionType: 'SignerListSet',
|
||||
Account: testContext.wallet.classicAddress,
|
||||
SignerEntries: [
|
||||
{
|
||||
SignerEntry: {
|
||||
Account: signerWallet1.classicAddress,
|
||||
SignerWeight: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
SignerEntry: {
|
||||
Account: signerWallet2.classicAddress,
|
||||
SignerWeight: 1,
|
||||
},
|
||||
},
|
||||
],
|
||||
SignerQuorum: 2,
|
||||
}
|
||||
await testTransaction(
|
||||
testContext.client,
|
||||
signerListSet,
|
||||
testContext.wallet,
|
||||
)
|
||||
|
||||
// try to multisign
|
||||
const accountSet: AccountSet = {
|
||||
TransactionType: 'AccountSet',
|
||||
Account: testContext.wallet.classicAddress,
|
||||
Domain: convertStringToHex('example.com'),
|
||||
}
|
||||
const accountSetTx = await client.autofill(accountSet, 2)
|
||||
const signed1 = signerWallet1.sign(accountSetTx, true)
|
||||
const signed2 = signerWallet2.sign(accountSetTx, true)
|
||||
const multisigned = multisign([signed1.tx_blob, signed2.tx_blob])
|
||||
const multisignedRequest: SubmitMultisignedRequest = {
|
||||
command: 'submit_multisigned',
|
||||
tx_json: decode(multisigned) as unknown as Transaction,
|
||||
}
|
||||
const submitResponse = await client.request(multisignedRequest)
|
||||
await ledgerAccept(client)
|
||||
assert.strictEqual(submitResponse.result.engine_result, 'tesSUCCESS')
|
||||
await verifySubmittedTransaction(testContext.client, multisigned)
|
||||
|
||||
const expectedResponse: SubmitMultisignedResponse = {
|
||||
id: submitResponse.id,
|
||||
type: 'response',
|
||||
result: {
|
||||
engine_result: 'tesSUCCESS',
|
||||
engine_result_code: 0,
|
||||
engine_result_message:
|
||||
'The transaction was applied. Only final in a validated ledger.',
|
||||
tx_blob: multisigned,
|
||||
tx_json: {
|
||||
...(decode(multisigned) as unknown as Transaction),
|
||||
hash: hashSignedTx(multisigned),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
assert.deepEqual(submitResponse, expectedResponse)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,34 +1,38 @@
|
||||
import { assert } from 'chai'
|
||||
import _ from 'lodash'
|
||||
|
||||
import {
|
||||
Client,
|
||||
OfferCreate,
|
||||
SubscribeRequest,
|
||||
Wallet,
|
||||
SubscribeResponse,
|
||||
} from 'xrpl-local'
|
||||
import { StreamType } from 'xrpl-local/models/common'
|
||||
|
||||
} from '../../../src'
|
||||
import { StreamType } from '../../../src/models/common'
|
||||
import type { LedgerStreamResponse } from '../../../src/models/methods/subscribe'
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
import { ledgerAccept, subscribeDone, testTransaction } from '../utils'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
|
||||
// Note: This test use '.then' to avoid awaits in order to use 'done' style tests.
|
||||
// eslint-disable-next-line max-params -- Helps keep things well-typed
|
||||
async function createTxHandlerTest(
|
||||
client: Client,
|
||||
wallet: Wallet,
|
||||
done: Mocha.Done,
|
||||
subscriptionStream: StreamType,
|
||||
): Promise<void> {
|
||||
const txStream = 'transaction'
|
||||
|
||||
client.on(txStream, (tx) => {
|
||||
assert.equal(tx.type, txStream)
|
||||
subscribeDone(client, done)
|
||||
const transactionPromise = new Promise<void>((resolve) => {
|
||||
client.on(txStream, (tx) => {
|
||||
assert.equal(tx.type, txStream)
|
||||
subscribeDone(client)
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
|
||||
const request: SubscribeRequest = {
|
||||
@@ -37,17 +41,21 @@ async function createTxHandlerTest(
|
||||
accounts: [wallet.classicAddress],
|
||||
}
|
||||
|
||||
client.request(request).then((response) => {
|
||||
assert.equal(response.type, 'response')
|
||||
assert.deepEqual(response.result, {})
|
||||
})
|
||||
const response = await client.request(request)
|
||||
|
||||
assert.equal(response.type, 'response')
|
||||
assert.deepEqual(response.result, {})
|
||||
|
||||
return transactionPromise
|
||||
}
|
||||
|
||||
describe('subscribe', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
/**
|
||||
* Subscribe streams which are not testable with just a standalone node:
|
||||
@@ -60,17 +68,21 @@ describe('subscribe', function () {
|
||||
* 'server'.
|
||||
*/
|
||||
|
||||
it('Successfully Subscribes', async function () {
|
||||
const response: SubscribeResponse = await this.client.request({
|
||||
command: 'subscribe',
|
||||
})
|
||||
it(
|
||||
'Successfully Subscribes',
|
||||
async () => {
|
||||
const response: SubscribeResponse = await testContext.client.request({
|
||||
command: 'subscribe',
|
||||
})
|
||||
|
||||
assert.deepEqual(response.result, {})
|
||||
assert.equal(response.type, 'response')
|
||||
})
|
||||
assert.deepEqual(response.result, {})
|
||||
assert.equal(response.type, 'response')
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
|
||||
it('Successfully Unsubscribes', async function () {
|
||||
const response = await this.client.request({
|
||||
const response = await testContext.client.request({
|
||||
command: 'unsubscribe',
|
||||
})
|
||||
|
||||
@@ -78,90 +90,111 @@ describe('subscribe', function () {
|
||||
assert.equal(response.type, 'response')
|
||||
})
|
||||
|
||||
it('Emits transaction', function (done) {
|
||||
const streamType = 'transactions'
|
||||
createTxHandlerTest(this.client, this.wallet, done, streamType).then(() => {
|
||||
it(
|
||||
'Emits transaction',
|
||||
async () => {
|
||||
const streamType = 'transactions'
|
||||
const transactionPromise = createTxHandlerTest(
|
||||
testContext.client,
|
||||
testContext.wallet,
|
||||
streamType,
|
||||
)
|
||||
// Trigger the event
|
||||
const tx: OfferCreate = {
|
||||
TransactionType: 'OfferCreate',
|
||||
Account: this.wallet.classicAddress,
|
||||
Account: testContext.wallet.classicAddress,
|
||||
TakerGets: '13100000',
|
||||
TakerPays: {
|
||||
currency: 'USD',
|
||||
issuer: this.wallet.classicAddress,
|
||||
issuer: testContext.wallet.classicAddress,
|
||||
value: '10',
|
||||
},
|
||||
}
|
||||
await testTransaction(testContext.client, tx, testContext.wallet)
|
||||
await transactionPromise
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
|
||||
testTransaction(this.client, tx, this.wallet)
|
||||
})
|
||||
})
|
||||
it(
|
||||
'Emits transaction on transactions_proposed',
|
||||
async () => {
|
||||
const transactionPromise = createTxHandlerTest(
|
||||
testContext.client,
|
||||
testContext.wallet,
|
||||
'transactions_proposed',
|
||||
)
|
||||
|
||||
it('Emits transaction on transactions_proposed', function (done) {
|
||||
createTxHandlerTest(
|
||||
this.client,
|
||||
this.wallet,
|
||||
done,
|
||||
'transactions_proposed',
|
||||
).then(() => {
|
||||
const tx: OfferCreate = {
|
||||
TransactionType: 'OfferCreate',
|
||||
Account: this.wallet.classicAddress,
|
||||
Account: testContext.wallet.classicAddress,
|
||||
TakerGets: '13100000',
|
||||
TakerPays: {
|
||||
currency: 'USD',
|
||||
issuer: this.wallet.classicAddress,
|
||||
issuer: testContext.wallet.classicAddress,
|
||||
value: '10',
|
||||
},
|
||||
}
|
||||
|
||||
// The transactions_proposed stream should trigger the transaction handler WITHOUT ledgerAccept
|
||||
const client: Client = this.client
|
||||
client.submit(tx, { wallet: this.wallet })
|
||||
})
|
||||
})
|
||||
await testContext.client.submit(tx, { wallet: testContext.wallet })
|
||||
await transactionPromise
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
|
||||
// Note: This test use '.then' to avoid awaits in order to use 'done' style tests.
|
||||
it('Emits ledger', function (done) {
|
||||
const request: SubscribeRequest = {
|
||||
command: 'subscribe',
|
||||
streams: ['ledger'],
|
||||
accounts: [this.wallet.classicAddress],
|
||||
}
|
||||
|
||||
this.client.request(request).then((response) => {
|
||||
// Explicitly checking that there are only known fields in the return
|
||||
const expectedResult = {
|
||||
fee_base: response.result.fee_base,
|
||||
fee_ref: response.result.fee_ref,
|
||||
ledger_hash: response.result.ledger_hash,
|
||||
ledger_index: response.result.ledger_index,
|
||||
ledger_time: response.result.ledger_time,
|
||||
reserve_base: response.result.reserve_base,
|
||||
reserve_inc: response.result.reserve_inc,
|
||||
validated_ledgers: response.result.validated_ledgers,
|
||||
it(
|
||||
'Emits ledger',
|
||||
async () => {
|
||||
const request: SubscribeRequest = {
|
||||
command: 'subscribe',
|
||||
streams: ['ledger'],
|
||||
accounts: [testContext.wallet.classicAddress],
|
||||
}
|
||||
|
||||
assert.equal(response.type, 'response')
|
||||
assert.deepEqual(response.result, expectedResult)
|
||||
await testContext.client.request(request).then(async (response) => {
|
||||
const ledgerResponse: LedgerStreamResponse =
|
||||
response.result as LedgerStreamResponse
|
||||
// Explicitly checking that there are only known fields in the return
|
||||
const expectedResult = {
|
||||
fee_base: ledgerResponse.fee_base,
|
||||
fee_ref: ledgerResponse.fee_ref,
|
||||
ledger_hash: ledgerResponse.ledger_hash,
|
||||
ledger_index: ledgerResponse.ledger_index,
|
||||
ledger_time: ledgerResponse.ledger_time,
|
||||
reserve_base: ledgerResponse.reserve_base,
|
||||
reserve_inc: ledgerResponse.reserve_inc,
|
||||
validated_ledgers: ledgerResponse.validated_ledgers,
|
||||
}
|
||||
|
||||
const client: Client = this.client
|
||||
client.on('ledgerClosed', (ledger) => {
|
||||
// Fields that are expected to change between the initial test and now are updated
|
||||
assert.deepEqual(ledger, {
|
||||
...expectedResult,
|
||||
type: 'ledgerClosed',
|
||||
txn_count: ledger.txn_count,
|
||||
ledger_hash: ledger.ledger_hash,
|
||||
ledger_index: parseInt(expectedResult.ledger_index, 10) + 1,
|
||||
ledger_time: ledger.ledger_time,
|
||||
validated_ledgers: ledger.validated_ledgers,
|
||||
assert.equal(response.type, 'response')
|
||||
assert.deepEqual(response.result, expectedResult)
|
||||
|
||||
const client: Client = testContext.client
|
||||
const ledgerClosedPromise = new Promise<void>((resolve) => {
|
||||
client.on('ledgerClosed', (ledger) => {
|
||||
// Fields that are expected to change between the initial test and now are updated
|
||||
assert.deepEqual(ledger, {
|
||||
...expectedResult,
|
||||
type: 'ledgerClosed',
|
||||
txn_count: ledger.txn_count,
|
||||
ledger_hash: ledger.ledger_hash,
|
||||
ledger_index:
|
||||
parseInt(expectedResult.ledger_index.toString(), 10) + 1,
|
||||
ledger_time: ledger.ledger_time,
|
||||
validated_ledgers: ledger.validated_ledgers,
|
||||
})
|
||||
subscribeDone(testContext.client)
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
subscribeDone(this.client, done)
|
||||
})
|
||||
|
||||
// Trigger the event
|
||||
ledgerAccept(this.client)
|
||||
})
|
||||
})
|
||||
// Trigger the event
|
||||
await ledgerAccept(testContext.client)
|
||||
|
||||
await ledgerClosedPromise
|
||||
})
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,55 +1,67 @@
|
||||
import { assert } from 'chai'
|
||||
import _ from 'lodash'
|
||||
import { AccountSet, hashes, SubmitResponse, TxResponse } from 'xrpl-local'
|
||||
import { convertStringToHex } from 'xrpl-local/utils'
|
||||
|
||||
import { AccountSet, hashes, SubmitResponse, TxResponse } from '../../../src'
|
||||
import { convertStringToHex } from '../../../src/utils'
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
const { hashSignedTx } = hashes
|
||||
|
||||
describe('tx', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('base', async function () {
|
||||
const account = this.wallet.classicAddress
|
||||
const accountSet: AccountSet = {
|
||||
TransactionType: 'AccountSet',
|
||||
Account: account,
|
||||
Domain: convertStringToHex('example.com'),
|
||||
}
|
||||
|
||||
const response: SubmitResponse = await this.client.submit(accountSet, {
|
||||
wallet: this.wallet,
|
||||
})
|
||||
|
||||
const hash = hashSignedTx(response.result.tx_blob)
|
||||
const txResponse = await this.client.request({
|
||||
command: 'tx',
|
||||
transaction: hash,
|
||||
})
|
||||
|
||||
const expectedResponse: TxResponse = {
|
||||
id: txResponse.id,
|
||||
type: 'response',
|
||||
result: {
|
||||
...accountSet,
|
||||
Fee: txResponse.result.Fee,
|
||||
Flags: 0,
|
||||
LastLedgerSequence: txResponse.result.LastLedgerSequence,
|
||||
Sequence: txResponse.result.Sequence,
|
||||
SigningPubKey: this.wallet.publicKey,
|
||||
TxnSignature: txResponse.result.TxnSignature,
|
||||
hash: hashSignedTx(response.result.tx_blob),
|
||||
validated: false,
|
||||
},
|
||||
}
|
||||
|
||||
assert.deepEqual(txResponse, expectedResponse)
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it(
|
||||
'base',
|
||||
async () => {
|
||||
const account = testContext.wallet.classicAddress
|
||||
const accountSet: AccountSet = {
|
||||
TransactionType: 'AccountSet',
|
||||
Account: account,
|
||||
Domain: convertStringToHex('example.com'),
|
||||
}
|
||||
|
||||
const response: SubmitResponse = await testContext.client.submit(
|
||||
accountSet,
|
||||
{
|
||||
wallet: testContext.wallet,
|
||||
},
|
||||
)
|
||||
|
||||
const hash = hashSignedTx(response.result.tx_blob)
|
||||
const txResponse = await testContext.client.request({
|
||||
command: 'tx',
|
||||
transaction: hash,
|
||||
})
|
||||
|
||||
const expectedResponse: TxResponse = {
|
||||
id: txResponse.id,
|
||||
type: 'response',
|
||||
result: {
|
||||
...accountSet,
|
||||
Fee: txResponse.result.Fee,
|
||||
Flags: 0,
|
||||
LastLedgerSequence: txResponse.result.LastLedgerSequence,
|
||||
Sequence: txResponse.result.Sequence,
|
||||
SigningPubKey: testContext.wallet.publicKey,
|
||||
TxnSignature: txResponse.result.TxnSignature,
|
||||
hash: hashSignedTx(response.result.tx_blob),
|
||||
validated: false,
|
||||
},
|
||||
}
|
||||
|
||||
assert.deepEqual(txResponse, expectedResponse)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,42 +1,55 @@
|
||||
import { assert } from 'chai'
|
||||
import _ from 'lodash'
|
||||
import { Client } from 'xrpl-local'
|
||||
import omit from 'lodash/omit'
|
||||
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
|
||||
describe('Utility method integration tests', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('ping', async function () {
|
||||
const response = await (this.client as Client).request({
|
||||
command: 'ping',
|
||||
})
|
||||
const expected: unknown = {
|
||||
result: { role: 'admin', unlimited: true },
|
||||
type: 'response',
|
||||
}
|
||||
assert.deepEqual(_.omit(response, 'id'), expected)
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it('random', async function () {
|
||||
const response = await (this.client as Client).request({
|
||||
command: 'random',
|
||||
})
|
||||
const expected = {
|
||||
id: 0,
|
||||
result: {
|
||||
random: '[random string of 64 bytes]',
|
||||
},
|
||||
type: 'response',
|
||||
}
|
||||
assert.equal(response.type, expected.type)
|
||||
assert.equal(response.result.random.length, 64)
|
||||
})
|
||||
it(
|
||||
'ping',
|
||||
async () => {
|
||||
const response = await testContext.client.request({
|
||||
command: 'ping',
|
||||
})
|
||||
const expected: unknown = {
|
||||
result: { role: 'admin', unlimited: true },
|
||||
type: 'response',
|
||||
}
|
||||
assert.deepEqual(omit(response, 'id'), expected)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
|
||||
it(
|
||||
'random',
|
||||
async () => {
|
||||
const response = await testContext.client.request({
|
||||
command: 'random',
|
||||
})
|
||||
const expected = {
|
||||
id: 0,
|
||||
result: {
|
||||
random: '[random string of 64 bytes]',
|
||||
},
|
||||
type: 'response',
|
||||
}
|
||||
assert.equal(response.type, expected.type)
|
||||
assert.equal(response.result.random.length, 64)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,26 +1,46 @@
|
||||
import { Client, Wallet } from 'xrpl-local'
|
||||
import { Client, Wallet } from '../../src'
|
||||
|
||||
import serverUrl from './serverUrl'
|
||||
import { fundAccount } from './utils'
|
||||
|
||||
export async function teardownClient(this: Mocha.Context): Promise<void> {
|
||||
this.client.removeAllListeners()
|
||||
this.client.disconnect()
|
||||
export interface XrplIntegrationTestContext {
|
||||
client: Client
|
||||
wallet: Wallet
|
||||
}
|
||||
|
||||
export async function teardownClient(
|
||||
context: XrplIntegrationTestContext,
|
||||
): Promise<void> {
|
||||
context.client.removeAllListeners()
|
||||
return context.client.disconnect()
|
||||
}
|
||||
|
||||
async function connectWithRetry(client: Client, tries = 0): Promise<void> {
|
||||
return client.connect().catch(async (error) => {
|
||||
if (tries < 10) {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
resolve(connectWithRetry(client, tries + 1))
|
||||
}, 1000)
|
||||
})
|
||||
}
|
||||
|
||||
throw error
|
||||
})
|
||||
}
|
||||
|
||||
export async function setupClient(
|
||||
this: Mocha.Context,
|
||||
server = serverUrl,
|
||||
): Promise<void> {
|
||||
this.wallet = Wallet.generate()
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
this.client = new Client(server)
|
||||
this.client
|
||||
.connect()
|
||||
.then(async () => {
|
||||
await fundAccount(this.client, this.wallet)
|
||||
resolve()
|
||||
})
|
||||
.catch(reject)
|
||||
): Promise<XrplIntegrationTestContext> {
|
||||
const context: XrplIntegrationTestContext = {
|
||||
client: new Client(server, { timeout: 200000 }),
|
||||
wallet: Wallet.generate(),
|
||||
}
|
||||
return connectWithRetry(context.client).then(async () => {
|
||||
await fundAccount(context.client, context.wallet, {
|
||||
count: 20,
|
||||
delayMs: 1000,
|
||||
})
|
||||
return context
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,91 +1,149 @@
|
||||
/* eslint-disable @typescript-eslint/no-misused-promises -- supposed to return a promise here */
|
||||
/* eslint-disable no-restricted-syntax -- not sure why this rule is here, definitely not needed here */
|
||||
import { assert } from 'chai'
|
||||
import _ from 'lodash'
|
||||
import { AccountSet, convertStringToHex, ValidationError } from 'xrpl-local'
|
||||
|
||||
import { AccountSet, convertStringToHex, ValidationError } from '../../src'
|
||||
import { assertRejects } from '../testUtils'
|
||||
|
||||
import serverUrl from './serverUrl'
|
||||
import { setupClient, teardownClient } from './setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from './setup'
|
||||
import { ledgerAccept } from './utils'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 60000
|
||||
|
||||
describe('client.submitAndWait', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it('submitAndWait an unsigned transaction', async function () {
|
||||
const accountSet: AccountSet = {
|
||||
TransactionType: 'AccountSet',
|
||||
Account: this.wallet.classicAddress,
|
||||
Domain: convertStringToHex('example.com'),
|
||||
}
|
||||
const responsePromise = this.client.submitAndWait(accountSet, {
|
||||
wallet: this.wallet,
|
||||
async function delayedLedgerAccept(): Promise<unknown> {
|
||||
await new Promise<void>((resolve) => {
|
||||
setTimeout(resolve, 1000)
|
||||
})
|
||||
const ledgerPromise = setTimeout(ledgerAccept, 1000, this.client)
|
||||
return Promise.all([responsePromise, ledgerPromise]).then(
|
||||
([response, _ledger]) => {
|
||||
assert.equal(response.type, 'response')
|
||||
assert.equal(response.result.validated, true)
|
||||
},
|
||||
)
|
||||
})
|
||||
return ledgerAccept(testContext.client)
|
||||
}
|
||||
|
||||
it('should throw a ValidationError when submitting an unsigned transaction without a wallet', async function () {
|
||||
const accountSet: AccountSet = {
|
||||
TransactionType: 'AccountSet',
|
||||
Account: this.wallet.classicAddress,
|
||||
Domain: convertStringToHex('example.com'),
|
||||
}
|
||||
it(
|
||||
'submitAndWait an unsigned transaction',
|
||||
async () => {
|
||||
const accountSet: AccountSet = {
|
||||
TransactionType: 'AccountSet',
|
||||
Account: testContext.wallet.classicAddress,
|
||||
Domain: convertStringToHex('example.com'),
|
||||
}
|
||||
|
||||
await assertRejects(
|
||||
this.client.submitAndWait(accountSet),
|
||||
ValidationError,
|
||||
'Wallet must be provided when submitting an unsigned transaction',
|
||||
)
|
||||
})
|
||||
let retries = 10
|
||||
|
||||
it('submitAndWait a signed transaction', async function () {
|
||||
const accountSet: AccountSet = {
|
||||
TransactionType: 'AccountSet',
|
||||
Account: this.wallet.classicAddress,
|
||||
Domain: convertStringToHex('example.com'),
|
||||
}
|
||||
const { tx_blob: signedAccountSet } = this.wallet.sign(
|
||||
await this.client.autofill(accountSet),
|
||||
)
|
||||
const responsePromise = this.client.submitAndWait(signedAccountSet)
|
||||
const ledgerPromise = setTimeout(ledgerAccept, 1000, this.client)
|
||||
return Promise.all([responsePromise, ledgerPromise]).then(
|
||||
([response, _ledger]) => {
|
||||
assert.equal(response.type, 'response')
|
||||
assert.equal(response.result.validated, true)
|
||||
},
|
||||
)
|
||||
})
|
||||
while (retries > 0) {
|
||||
retries -= 1
|
||||
const responsePromise = testContext.client.submitAndWait(accountSet, {
|
||||
wallet: testContext.wallet,
|
||||
})
|
||||
const ledgerPromise = delayedLedgerAccept()
|
||||
|
||||
it('submitAndWait a signed transaction longer', async function () {
|
||||
const accountSet: AccountSet = {
|
||||
TransactionType: 'AccountSet',
|
||||
Account: this.wallet.classicAddress,
|
||||
Domain: convertStringToHex('example.com'),
|
||||
}
|
||||
const { tx_blob: signedAccountSet } = this.wallet.sign(
|
||||
await this.client.autofill(accountSet),
|
||||
)
|
||||
const responsePromise = this.client.submitAndWait(signedAccountSet)
|
||||
const ledgerPromise = setTimeout(ledgerAccept, 5000, this.client)
|
||||
return Promise.all([responsePromise, ledgerPromise]).then(
|
||||
([response, _ledger]) => {
|
||||
assert.equal(response.type, 'response')
|
||||
assert.equal(response.result.validated, true)
|
||||
},
|
||||
)
|
||||
})
|
||||
try {
|
||||
// eslint-disable-next-line no-await-in-loop -- Testing purposes
|
||||
const [response, _ledger] = await Promise.all([
|
||||
responsePromise,
|
||||
ledgerPromise,
|
||||
])
|
||||
|
||||
assert.equal(response.type, 'response')
|
||||
assert.equal(response.result.validated, true)
|
||||
retries = 0
|
||||
break
|
||||
} catch (err) {
|
||||
// eslint-disable-next-line max-depth -- Necessary
|
||||
if (!(err instanceof Error)) {
|
||||
throw err
|
||||
}
|
||||
const errorCodeRegex = /(?:Preliminary result:\s)(?<errorCode>.*)$/gu
|
||||
const message = err.message
|
||||
const matches = errorCodeRegex.exec(message)
|
||||
const errorCode = matches?.groups?.errorCode
|
||||
|
||||
// Retry if another transaction finished before this one
|
||||
// eslint-disable-next-line max-depth -- Testing
|
||||
if (['tefPAST_SEQ', 'tefMAX_LEDGER'].includes(errorCode || '')) {
|
||||
// eslint-disable-next-line no-await-in-loop, no-promise-executor-return -- We are waiting on retries
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000))
|
||||
} else {
|
||||
retries = 0
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
|
||||
it(
|
||||
'should throw a ValidationError when submitting an unsigned transaction without a wallet',
|
||||
async () => {
|
||||
const accountSet: AccountSet = {
|
||||
TransactionType: 'AccountSet',
|
||||
Account: testContext.wallet.classicAddress,
|
||||
Domain: convertStringToHex('example.com'),
|
||||
}
|
||||
|
||||
await assertRejects(
|
||||
testContext.client.submitAndWait(accountSet),
|
||||
ValidationError,
|
||||
'Wallet must be provided when submitting an unsigned transaction',
|
||||
)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
|
||||
it(
|
||||
'submitAndWait a signed transaction',
|
||||
async () => {
|
||||
const accountSet: AccountSet = {
|
||||
TransactionType: 'AccountSet',
|
||||
Account: testContext.wallet.classicAddress,
|
||||
Domain: convertStringToHex('example.com'),
|
||||
}
|
||||
const { tx_blob: signedAccountSet } = testContext.wallet.sign(
|
||||
await testContext.client.autofill(accountSet),
|
||||
)
|
||||
const responsePromise = testContext.client.submitAndWait(signedAccountSet)
|
||||
const ledgerPromise = delayedLedgerAccept()
|
||||
return Promise.all([responsePromise, ledgerPromise]).then(
|
||||
([response, _ledger]) => {
|
||||
assert.equal(response.type, 'response')
|
||||
assert.equal(response.result.validated, true)
|
||||
},
|
||||
)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
|
||||
it(
|
||||
'submitAndWait a signed transaction longer',
|
||||
async () => {
|
||||
const accountSet: AccountSet = {
|
||||
TransactionType: 'AccountSet',
|
||||
Account: testContext.wallet.classicAddress,
|
||||
Domain: convertStringToHex('example.com'),
|
||||
}
|
||||
const { tx_blob: signedAccountSet } = testContext.wallet.sign(
|
||||
await testContext.client.autofill(accountSet),
|
||||
)
|
||||
const responsePromise = testContext.client.submitAndWait(signedAccountSet)
|
||||
const ledgerPromise = delayedLedgerAccept()
|
||||
return Promise.all([responsePromise, ledgerPromise]).then(
|
||||
([response, _ledger]) => {
|
||||
assert.equal(response.type, 'response')
|
||||
assert.equal(response.result.validated, true)
|
||||
},
|
||||
)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,33 +1,64 @@
|
||||
import _ from 'lodash'
|
||||
import { AccountDelete } from 'xrpl-local/models/transactions'
|
||||
|
||||
import { AccountDelete } from '../../../src/models/transactions'
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import { generateFundedWallet, ledgerAccept, testTransaction } from '../utils'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
import { generateFundedWallet, submitTransaction } from '../utils'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
|
||||
describe('AccountDelete', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('base', async function () {
|
||||
const wallet2 = await generateFundedWallet(this.client)
|
||||
// to the satisfy the condition that account sequence and current ledger_index should be 256 apart.
|
||||
const promises: Array<Promise<void>> = []
|
||||
for (let iter = 0; iter < 256; iter += 1) {
|
||||
promises.push(ledgerAccept(this.client))
|
||||
}
|
||||
|
||||
await Promise.all(promises)
|
||||
const tx: AccountDelete = {
|
||||
TransactionType: 'AccountDelete',
|
||||
Account: this.wallet.classicAddress,
|
||||
Destination: wallet2.classicAddress,
|
||||
}
|
||||
await testTransaction(this.client, tx, this.wallet)
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it(
|
||||
'base',
|
||||
async () => {
|
||||
const wallet2 = await generateFundedWallet(testContext.client)
|
||||
// to the satisfy the condition that account sequence and current ledger_index should be 256 apart.
|
||||
// const promises: Array<Promise<void> | Promise<unknown>> = []
|
||||
// for (let iter = 0; iter < 256; iter += 1) {
|
||||
// promises.push(ledgerAccept(testContext.client))
|
||||
// }
|
||||
// await Promise.all(promises)
|
||||
const tx: AccountDelete = {
|
||||
TransactionType: 'AccountDelete',
|
||||
Account: testContext.wallet.classicAddress,
|
||||
Destination: wallet2.classicAddress,
|
||||
}
|
||||
|
||||
// Since we are not testing the functionaity of rippled in this library, only that we are submitting commands
|
||||
// properly, we can just test that the AccountDelete command was successfully received.
|
||||
await submitTransaction({
|
||||
client: testContext.client,
|
||||
transaction: tx,
|
||||
wallet: testContext.wallet,
|
||||
})
|
||||
|
||||
// TODO: Re-enable this test once we can test the `engine_result` without waiting a significant amount of time.
|
||||
// Note, we can't test the `engine_result` without waiting a significant
|
||||
// amount of time because accounts can't be deleted until some number of
|
||||
// ledgers have closed since its creation.
|
||||
//
|
||||
// The documentation for `tecTOO_SOON` reads:
|
||||
// "The AccountDelete transaction failed because the account to be deleted had a
|
||||
// Sequence number that is too high. The current ledger index must be at least
|
||||
// 256 higher than the account's sequence number."
|
||||
//
|
||||
// self.assertEqual(response.result['engine_result'], 'tesSUCCESS')
|
||||
// await testTransaction(testContext.client, tx, testContext.wallet, {
|
||||
// // Need to retry when running tests concurrently
|
||||
// count: 5,
|
||||
// delayMs: 1000,
|
||||
// })
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,24 +1,32 @@
|
||||
import _ from 'lodash'
|
||||
import { AccountSet } from 'xrpl-local/models/transactions'
|
||||
|
||||
import { AccountSet } from '../../../src/models/transactions'
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
import { testTransaction } from '../utils'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
|
||||
describe('AccountSet', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('base', async function () {
|
||||
const tx: AccountSet = {
|
||||
TransactionType: 'AccountSet',
|
||||
Account: this.wallet.classicAddress,
|
||||
}
|
||||
await testTransaction(this.client, tx, this.wallet)
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it(
|
||||
'base',
|
||||
async () => {
|
||||
const tx: AccountSet = {
|
||||
TransactionType: 'AccountSet',
|
||||
Account: testContext.wallet.classicAddress,
|
||||
}
|
||||
await testTransaction(testContext.client, tx, testContext.wallet)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,63 +1,72 @@
|
||||
import { assert } from 'chai'
|
||||
import _ from 'lodash'
|
||||
import { CheckCreate, CheckCancel } from 'xrpl-local'
|
||||
|
||||
import { CheckCreate, CheckCancel } from '../../../src'
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
import { generateFundedWallet, testTransaction } from '../utils'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
|
||||
describe('CheckCancel', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('base', async function () {
|
||||
const wallet2 = await generateFundedWallet(this.client)
|
||||
const setupTx: CheckCreate = {
|
||||
TransactionType: 'CheckCreate',
|
||||
Account: this.wallet.classicAddress,
|
||||
Destination: wallet2.classicAddress,
|
||||
SendMax: '50',
|
||||
}
|
||||
|
||||
await testTransaction(this.client, setupTx, this.wallet)
|
||||
|
||||
// get check ID
|
||||
const response1 = await this.client.request({
|
||||
command: 'account_objects',
|
||||
account: this.wallet.classicAddress,
|
||||
type: 'check',
|
||||
})
|
||||
assert.lengthOf(
|
||||
response1.result.account_objects,
|
||||
1,
|
||||
'Should be exactly one check on the ledger',
|
||||
)
|
||||
const checkId = response1.result.account_objects[0].index
|
||||
|
||||
// actual test - cancel the check
|
||||
const tx: CheckCancel = {
|
||||
TransactionType: 'CheckCancel',
|
||||
Account: this.wallet.classicAddress,
|
||||
CheckID: checkId,
|
||||
}
|
||||
|
||||
await testTransaction(this.client, tx, this.wallet)
|
||||
|
||||
// confirm that the check no longer exists
|
||||
const accountOffersResponse = await this.client.request({
|
||||
command: 'account_objects',
|
||||
account: this.wallet.classicAddress,
|
||||
type: 'check',
|
||||
})
|
||||
assert.lengthOf(
|
||||
accountOffersResponse.result.account_objects,
|
||||
0,
|
||||
'Should be no checks on the ledger',
|
||||
)
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it(
|
||||
'base',
|
||||
async () => {
|
||||
const wallet2 = await generateFundedWallet(testContext.client)
|
||||
const setupTx: CheckCreate = {
|
||||
TransactionType: 'CheckCreate',
|
||||
Account: testContext.wallet.classicAddress,
|
||||
Destination: wallet2.classicAddress,
|
||||
SendMax: '50',
|
||||
}
|
||||
|
||||
await testTransaction(testContext.client, setupTx, testContext.wallet)
|
||||
|
||||
// get check ID
|
||||
const response1 = await testContext.client.request({
|
||||
command: 'account_objects',
|
||||
account: testContext.wallet.classicAddress,
|
||||
type: 'check',
|
||||
})
|
||||
assert.lengthOf(
|
||||
response1.result.account_objects,
|
||||
1,
|
||||
'Should be exactly one check on the ledger',
|
||||
)
|
||||
const checkId = response1.result.account_objects[0].index
|
||||
|
||||
// actual test - cancel the check
|
||||
const tx: CheckCancel = {
|
||||
TransactionType: 'CheckCancel',
|
||||
Account: testContext.wallet.classicAddress,
|
||||
CheckID: checkId,
|
||||
}
|
||||
|
||||
await testTransaction(testContext.client, tx, testContext.wallet)
|
||||
|
||||
// confirm that the check no longer exists
|
||||
const accountOffersResponse = await testContext.client.request({
|
||||
command: 'account_objects',
|
||||
account: testContext.wallet.classicAddress,
|
||||
type: 'check',
|
||||
})
|
||||
assert.lengthOf(
|
||||
accountOffersResponse.result.account_objects,
|
||||
0,
|
||||
'Should be no checks on the ledger',
|
||||
)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,66 +1,75 @@
|
||||
import { assert } from 'chai'
|
||||
import _ from 'lodash'
|
||||
import { CheckCreate, CheckCash } from 'xrpl-local'
|
||||
|
||||
import { CheckCreate, CheckCash } from '../../../src'
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
import { generateFundedWallet, testTransaction } from '../utils'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
|
||||
describe('CheckCash', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('base', async function () {
|
||||
const wallet2 = await generateFundedWallet(this.client)
|
||||
const amount = '500'
|
||||
|
||||
const setupTx: CheckCreate = {
|
||||
TransactionType: 'CheckCreate',
|
||||
Account: this.wallet.classicAddress,
|
||||
Destination: wallet2.classicAddress,
|
||||
SendMax: amount,
|
||||
}
|
||||
|
||||
await testTransaction(this.client, setupTx, this.wallet)
|
||||
|
||||
// get check ID
|
||||
const response1 = await this.client.request({
|
||||
command: 'account_objects',
|
||||
account: this.wallet.classicAddress,
|
||||
type: 'check',
|
||||
})
|
||||
assert.lengthOf(
|
||||
response1.result.account_objects,
|
||||
1,
|
||||
'Should be exactly one check on the ledger',
|
||||
)
|
||||
const checkId = response1.result.account_objects[0].index
|
||||
|
||||
// actual test - cash the check
|
||||
const tx: CheckCash = {
|
||||
TransactionType: 'CheckCash',
|
||||
Account: wallet2.classicAddress,
|
||||
CheckID: checkId,
|
||||
Amount: amount,
|
||||
}
|
||||
|
||||
await testTransaction(this.client, tx, wallet2)
|
||||
|
||||
// confirm that the check no longer exists
|
||||
const accountOffersResponse = await this.client.request({
|
||||
command: 'account_objects',
|
||||
account: this.wallet.classicAddress,
|
||||
type: 'check',
|
||||
})
|
||||
assert.lengthOf(
|
||||
accountOffersResponse.result.account_objects,
|
||||
0,
|
||||
'Should be no checks on the ledger',
|
||||
)
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it(
|
||||
'base',
|
||||
async () => {
|
||||
const wallet2 = await generateFundedWallet(testContext.client)
|
||||
const amount = '500'
|
||||
|
||||
const setupTx: CheckCreate = {
|
||||
TransactionType: 'CheckCreate',
|
||||
Account: testContext.wallet.classicAddress,
|
||||
Destination: wallet2.classicAddress,
|
||||
SendMax: amount,
|
||||
}
|
||||
|
||||
await testTransaction(testContext.client, setupTx, testContext.wallet)
|
||||
|
||||
// get check ID
|
||||
const response1 = await testContext.client.request({
|
||||
command: 'account_objects',
|
||||
account: testContext.wallet.classicAddress,
|
||||
type: 'check',
|
||||
})
|
||||
assert.lengthOf(
|
||||
response1.result.account_objects,
|
||||
1,
|
||||
'Should be exactly one check on the ledger',
|
||||
)
|
||||
const checkId = response1.result.account_objects[0].index
|
||||
|
||||
// actual test - cash the check
|
||||
const tx: CheckCash = {
|
||||
TransactionType: 'CheckCash',
|
||||
Account: wallet2.classicAddress,
|
||||
CheckID: checkId,
|
||||
Amount: amount,
|
||||
}
|
||||
|
||||
await testTransaction(testContext.client, tx, wallet2)
|
||||
|
||||
// confirm that the check no longer exists
|
||||
const accountOffersResponse = await testContext.client.request({
|
||||
command: 'account_objects',
|
||||
account: testContext.wallet.classicAddress,
|
||||
type: 'check',
|
||||
})
|
||||
assert.lengthOf(
|
||||
accountOffersResponse.result.account_objects,
|
||||
0,
|
||||
'Should be no checks on the ledger',
|
||||
)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,41 +1,50 @@
|
||||
import { assert } from 'chai'
|
||||
import _ from 'lodash'
|
||||
import { CheckCreate } from 'xrpl-local'
|
||||
|
||||
import { CheckCreate } from '../../../src'
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
import { generateFundedWallet, testTransaction } from '../utils'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
|
||||
describe('CheckCreate', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('base', async function () {
|
||||
const wallet2 = await generateFundedWallet(this.client)
|
||||
const tx: CheckCreate = {
|
||||
TransactionType: 'CheckCreate',
|
||||
Account: this.wallet.classicAddress,
|
||||
Destination: wallet2.classicAddress,
|
||||
SendMax: '50',
|
||||
}
|
||||
|
||||
await testTransaction(this.client, tx, this.wallet)
|
||||
|
||||
// confirm that the check actually went through
|
||||
const accountOffersResponse = await this.client.request({
|
||||
command: 'account_objects',
|
||||
account: this.wallet.classicAddress,
|
||||
type: 'check',
|
||||
})
|
||||
assert.lengthOf(
|
||||
accountOffersResponse.result.account_objects,
|
||||
1,
|
||||
'Should be exactly one check on the ledger',
|
||||
)
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it(
|
||||
'base',
|
||||
async () => {
|
||||
const wallet2 = await generateFundedWallet(testContext.client)
|
||||
const tx: CheckCreate = {
|
||||
TransactionType: 'CheckCreate',
|
||||
Account: testContext.wallet.classicAddress,
|
||||
Destination: wallet2.classicAddress,
|
||||
SendMax: '50',
|
||||
}
|
||||
|
||||
await testTransaction(testContext.client, tx, testContext.wallet)
|
||||
|
||||
// confirm that the check actually went through
|
||||
const accountOffersResponse = await testContext.client.request({
|
||||
command: 'account_objects',
|
||||
account: testContext.wallet.classicAddress,
|
||||
type: 'check',
|
||||
})
|
||||
assert.lengthOf(
|
||||
accountOffersResponse.result.account_objects,
|
||||
1,
|
||||
'Should be exactly one check on the ledger',
|
||||
)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,27 +1,35 @@
|
||||
import _ from 'lodash'
|
||||
import { DepositPreauth, Wallet } from 'xrpl-local'
|
||||
|
||||
import { DepositPreauth, Wallet } from '../../../src'
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
import { fundAccount, testTransaction } from '../utils'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
|
||||
describe('DepositPreauth', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('base', async function () {
|
||||
const wallet2 = Wallet.generate()
|
||||
fundAccount(this.client, wallet2)
|
||||
const tx: DepositPreauth = {
|
||||
TransactionType: 'DepositPreauth',
|
||||
Account: this.wallet.classicAddress,
|
||||
Authorize: wallet2.classicAddress,
|
||||
}
|
||||
await testTransaction(this.client, tx, this.wallet)
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it(
|
||||
'base',
|
||||
async () => {
|
||||
const wallet2 = Wallet.generate()
|
||||
await fundAccount(testContext.client, wallet2)
|
||||
const tx: DepositPreauth = {
|
||||
TransactionType: 'DepositPreauth',
|
||||
Account: testContext.wallet.classicAddress,
|
||||
Authorize: wallet2.classicAddress,
|
||||
}
|
||||
await testTransaction(testContext.client, tx, testContext.wallet)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,72 +1,125 @@
|
||||
import { assert } from 'chai'
|
||||
import _ from 'lodash'
|
||||
import { EscrowCancel, EscrowCreate } from 'xrpl-local'
|
||||
|
||||
import { EscrowCancel, EscrowCreate } from '../../../src'
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import { generateFundedWallet, getXRPBalance, testTransaction } from '../utils'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
import {
|
||||
// calculateWaitTimeForTransaction,
|
||||
generateFundedWallet,
|
||||
// getXRPBalance,
|
||||
testTransaction,
|
||||
submitTransaction,
|
||||
} from '../utils'
|
||||
|
||||
// TODO: Fix these tests
|
||||
// NOTE: Because ledger accept is called among multiple tests, the actual ledger close time is not
|
||||
// accurate. It can end up very far into the future. This means that the CancelAfter timer can potentially
|
||||
// need to wait for several minutes to be able to properly complete. Since we are not testing the functionaity
|
||||
// of rippled in this library, only that we are submitting commands properly, we can just test that the EscrowCancel
|
||||
// command was successfully received. If in the future we isolate tests to run on their own rippled instance,
|
||||
// we can uncomment the code in this file to test that the escrow was actually cancelled.
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
const TIMEOUT = 50000
|
||||
|
||||
describe('EscrowCancel', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('base', async function () {
|
||||
// get the most recent close_time from the standalone container for cancel & finish after.
|
||||
const CLOSE_TIME: number = (
|
||||
await this.client.request({
|
||||
command: 'ledger',
|
||||
ledger_index: 'validated',
|
||||
})
|
||||
).result.ledger.close_time
|
||||
const wallet1 = await generateFundedWallet(this.client)
|
||||
|
||||
const createTx: EscrowCreate = {
|
||||
Account: this.wallet.classicAddress,
|
||||
TransactionType: 'EscrowCreate',
|
||||
Amount: '10000',
|
||||
Destination: wallet1.classicAddress,
|
||||
CancelAfter: CLOSE_TIME + 3,
|
||||
FinishAfter: CLOSE_TIME + 2,
|
||||
}
|
||||
|
||||
await testTransaction(this.client, createTx, this.wallet)
|
||||
|
||||
const initialBalanceWallet1 = await getXRPBalance(this.client, wallet1)
|
||||
|
||||
// check that the object was actually created
|
||||
const accountObjects = (
|
||||
await this.client.request({
|
||||
command: 'account_objects',
|
||||
account: this.wallet.classicAddress,
|
||||
})
|
||||
).result.account_objects
|
||||
|
||||
assert.equal(accountObjects.length, 1)
|
||||
|
||||
const sequence = (
|
||||
await this.client.request({
|
||||
command: 'tx',
|
||||
transaction: accountObjects[0].PreviousTxnID,
|
||||
})
|
||||
).result.Sequence
|
||||
|
||||
const cancelTx: EscrowCancel = {
|
||||
TransactionType: 'EscrowCancel',
|
||||
Account: this.wallet.classicAddress,
|
||||
Owner: this.wallet.classicAddress,
|
||||
OfferSequence: sequence,
|
||||
}
|
||||
|
||||
await testTransaction(this.client, cancelTx, this.wallet)
|
||||
|
||||
assert.equal(
|
||||
await getXRPBalance(this.client, wallet1),
|
||||
initialBalanceWallet1,
|
||||
)
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it(
|
||||
'base',
|
||||
async () => {
|
||||
// Funding the wallet can take some time, so we do it first BEFORE getting the ledger close_time.
|
||||
const wallet1 = await generateFundedWallet(testContext.client)
|
||||
|
||||
// get the most recent close_time from the standalone container for cancel & finish after.
|
||||
const CLOSE_TIME: number = (
|
||||
await testContext.client.request({
|
||||
command: 'ledger',
|
||||
ledger_index: 'validated',
|
||||
})
|
||||
).result.ledger.close_time
|
||||
|
||||
// const waitTimeInMs = calculateWaitTimeForTransaction(CLOSE_TIME)
|
||||
|
||||
const createTx: EscrowCreate = {
|
||||
Account: testContext.wallet.classicAddress,
|
||||
TransactionType: 'EscrowCreate',
|
||||
Amount: '10000',
|
||||
Destination: wallet1.classicAddress,
|
||||
CancelAfter: CLOSE_TIME + 3,
|
||||
FinishAfter: CLOSE_TIME + 2,
|
||||
}
|
||||
|
||||
await testTransaction(testContext.client, createTx, testContext.wallet)
|
||||
|
||||
// const initialBalanceWallet1 = await getXRPBalance(
|
||||
// testContext.client,
|
||||
// wallet1,
|
||||
// )
|
||||
|
||||
// check that the object was actually created
|
||||
const accountObjects = (
|
||||
await testContext.client.request({
|
||||
command: 'account_objects',
|
||||
account: testContext.wallet.classicAddress,
|
||||
})
|
||||
).result.account_objects
|
||||
|
||||
assert.equal(accountObjects.length, 1)
|
||||
|
||||
const sequence = (
|
||||
await testContext.client.request({
|
||||
command: 'tx',
|
||||
transaction: accountObjects[0].PreviousTxnID,
|
||||
})
|
||||
).result.Sequence
|
||||
|
||||
if (!sequence) {
|
||||
throw new Error('sequence did not exist')
|
||||
}
|
||||
|
||||
const cancelTx: EscrowCancel = {
|
||||
TransactionType: 'EscrowCancel',
|
||||
Account: testContext.wallet.classicAddress,
|
||||
Owner: testContext.wallet.classicAddress,
|
||||
OfferSequence: sequence,
|
||||
}
|
||||
|
||||
// We set the CancelAfter timer to be 3 seconds after the last ledger close_time. We need to wait this long
|
||||
// before we can cancel the escrow.
|
||||
// const cancelAfterTimerPromise = new Promise((resolve) => {
|
||||
// setTimeout(resolve, waitTimeInMs)
|
||||
// })
|
||||
|
||||
// Make sure we wait long enough before canceling the escrow.
|
||||
// await cancelAfterTimerPromise
|
||||
|
||||
// await testTransaction(testContext.client, cancelTx, testContext.wallet, {
|
||||
// count: 20,
|
||||
// delayMs: 2000,
|
||||
// })
|
||||
|
||||
await submitTransaction({
|
||||
client: testContext.client,
|
||||
transaction: cancelTx,
|
||||
wallet: testContext.wallet,
|
||||
})
|
||||
|
||||
// Make sure the Destination wallet did not receive any XRP.
|
||||
// assert.equal(
|
||||
// await getXRPBalance(testContext.client, wallet1),
|
||||
// initialBalanceWallet1,
|
||||
// )
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,49 +1,59 @@
|
||||
import { assert } from 'chai'
|
||||
import _ from 'lodash'
|
||||
import { EscrowCreate } from 'xrpl-local'
|
||||
|
||||
import { EscrowCreate } from '../../../src'
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
import { generateFundedWallet, testTransaction } from '../utils'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
|
||||
describe('EscrowCreate', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('base', async function () {
|
||||
// get the most recent close_time from the standalone container for finish after.
|
||||
const CLOSE_TIME: number = (
|
||||
await this.client.request({
|
||||
command: 'ledger',
|
||||
ledger_index: 'validated',
|
||||
})
|
||||
).result.ledger.close_time
|
||||
|
||||
const wallet1 = await generateFundedWallet(this.client)
|
||||
const tx: EscrowCreate = {
|
||||
Account: this.wallet.classicAddress,
|
||||
TransactionType: 'EscrowCreate',
|
||||
Amount: '10000',
|
||||
Destination: wallet1.classicAddress,
|
||||
FinishAfter: CLOSE_TIME + 2,
|
||||
}
|
||||
|
||||
await testTransaction(this.client, tx, this.wallet)
|
||||
|
||||
// check that the object was actually created
|
||||
assert.equal(
|
||||
(
|
||||
await this.client.request({
|
||||
command: 'account_objects',
|
||||
account: this.wallet.classicAddress,
|
||||
})
|
||||
).result.account_objects.length,
|
||||
1,
|
||||
)
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it(
|
||||
'base',
|
||||
async () => {
|
||||
const wallet2 = await generateFundedWallet(testContext.client)
|
||||
|
||||
// get the most recent close_time from the standalone container for finish after.
|
||||
const CLOSE_TIME: number = (
|
||||
await testContext.client.request({
|
||||
command: 'ledger',
|
||||
ledger_index: 'validated',
|
||||
})
|
||||
).result.ledger.close_time
|
||||
|
||||
const tx: EscrowCreate = {
|
||||
Account: testContext.wallet.classicAddress,
|
||||
TransactionType: 'EscrowCreate',
|
||||
Amount: '10000',
|
||||
Destination: wallet2.classicAddress,
|
||||
FinishAfter: CLOSE_TIME + 2,
|
||||
}
|
||||
|
||||
await testTransaction(testContext.client, tx, testContext.wallet)
|
||||
|
||||
// check that the object was actually created
|
||||
assert.equal(
|
||||
(
|
||||
await testContext.client.request({
|
||||
command: 'account_objects',
|
||||
account: testContext.wallet.classicAddress,
|
||||
})
|
||||
).result.account_objects.length,
|
||||
1,
|
||||
)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,71 +1,97 @@
|
||||
import { assert } from 'chai'
|
||||
import _ from 'lodash'
|
||||
import { EscrowFinish, EscrowCreate } from 'xrpl-local'
|
||||
|
||||
import { EscrowFinish, EscrowCreate } from '../../../src'
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import { generateFundedWallet, getXRPBalance, testTransaction } from '../utils'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
import {
|
||||
calculateWaitTimeForTransaction,
|
||||
generateFundedWallet,
|
||||
getXRPBalance,
|
||||
testTransaction,
|
||||
} from '../utils'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
const TIMEOUT = 30000
|
||||
|
||||
describe('EscrowFinish', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('base', async function () {
|
||||
// get the most recent close_time from the standalone container for cancel & finish after.
|
||||
const CLOSE_TIME: number = (
|
||||
await this.client.request({
|
||||
command: 'ledger',
|
||||
ledger_index: 'validated',
|
||||
})
|
||||
).result.ledger.close_time
|
||||
const wallet1 = await generateFundedWallet(this.client)
|
||||
|
||||
const AMOUNT = 10000
|
||||
|
||||
const createTx: EscrowCreate = {
|
||||
Account: this.wallet.classicAddress,
|
||||
TransactionType: 'EscrowCreate',
|
||||
Amount: '10000',
|
||||
Destination: wallet1.classicAddress,
|
||||
FinishAfter: CLOSE_TIME + 2,
|
||||
}
|
||||
|
||||
await testTransaction(this.client, createTx, this.wallet)
|
||||
|
||||
const initialBalance = await getXRPBalance(this.client, wallet1)
|
||||
|
||||
// check that the object was actually created
|
||||
const accountObjects = (
|
||||
await this.client.request({
|
||||
command: 'account_objects',
|
||||
account: this.wallet.classicAddress,
|
||||
})
|
||||
).result.account_objects
|
||||
|
||||
assert.equal(accountObjects.length, 1)
|
||||
|
||||
const sequence = (
|
||||
await this.client.request({
|
||||
command: 'tx',
|
||||
transaction: accountObjects[0].PreviousTxnID,
|
||||
})
|
||||
).result.Sequence
|
||||
|
||||
const finishTx: EscrowFinish = {
|
||||
TransactionType: 'EscrowFinish',
|
||||
Account: this.wallet.classicAddress,
|
||||
Owner: this.wallet.classicAddress,
|
||||
OfferSequence: sequence,
|
||||
}
|
||||
|
||||
await testTransaction(this.client, finishTx, this.wallet)
|
||||
|
||||
const expectedBalance = String(Number(initialBalance) + Number(AMOUNT))
|
||||
assert.equal(await getXRPBalance(this.client, wallet1), expectedBalance)
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it(
|
||||
'base',
|
||||
async () => {
|
||||
const wallet1 = await generateFundedWallet(testContext.client)
|
||||
|
||||
// get the most recent close_time from the standalone container for cancel & finish after.
|
||||
const CLOSE_TIME: number = (
|
||||
await testContext.client.request({
|
||||
command: 'ledger',
|
||||
ledger_index: 'validated',
|
||||
})
|
||||
).result.ledger.close_time
|
||||
|
||||
const waitTimeInMs = calculateWaitTimeForTransaction(CLOSE_TIME)
|
||||
|
||||
const AMOUNT = 10000
|
||||
|
||||
const createTx: EscrowCreate = {
|
||||
Account: testContext.wallet.classicAddress,
|
||||
TransactionType: 'EscrowCreate',
|
||||
Amount: AMOUNT.toString(),
|
||||
Destination: wallet1.classicAddress,
|
||||
FinishAfter: CLOSE_TIME + 2,
|
||||
}
|
||||
|
||||
const finishAfterPromise = new Promise((resolve) => {
|
||||
setTimeout(resolve, waitTimeInMs)
|
||||
})
|
||||
|
||||
await testTransaction(testContext.client, createTx, testContext.wallet)
|
||||
|
||||
const initialBalance = await getXRPBalance(testContext.client, wallet1)
|
||||
|
||||
// check that the object was actually created
|
||||
const accountObjects = (
|
||||
await testContext.client.request({
|
||||
command: 'account_objects',
|
||||
account: testContext.wallet.classicAddress,
|
||||
})
|
||||
).result.account_objects
|
||||
|
||||
assert.equal(accountObjects.length, 1)
|
||||
|
||||
const sequence = (
|
||||
await testContext.client.request({
|
||||
command: 'tx',
|
||||
transaction: accountObjects[0].PreviousTxnID,
|
||||
})
|
||||
).result.Sequence
|
||||
|
||||
const finishTx: EscrowFinish = {
|
||||
TransactionType: 'EscrowFinish',
|
||||
Account: testContext.wallet.classicAddress,
|
||||
Owner: testContext.wallet.classicAddress,
|
||||
OfferSequence: sequence!,
|
||||
}
|
||||
|
||||
await finishAfterPromise
|
||||
|
||||
await testTransaction(testContext.client, finishTx, testContext.wallet)
|
||||
|
||||
const expectedBalance = String(Number(initialBalance) + Number(AMOUNT))
|
||||
assert.equal(
|
||||
await getXRPBalance(testContext.client, wallet1),
|
||||
expectedBalance,
|
||||
)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,63 +1,74 @@
|
||||
import { assert } from 'chai'
|
||||
import _ from 'lodash'
|
||||
import { OfferCreate, OfferCancel } from 'xrpl-local'
|
||||
|
||||
import { OfferCreate, OfferCancel } from '../../../src'
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
import { testTransaction } from '../utils'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
|
||||
describe('OfferCancel', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('base', async function () {
|
||||
// set up an offer
|
||||
const setupTx: OfferCreate = {
|
||||
TransactionType: 'OfferCreate',
|
||||
Account: this.wallet.classicAddress,
|
||||
TakerGets: '13100000',
|
||||
TakerPays: {
|
||||
currency: 'USD',
|
||||
issuer: this.wallet.classicAddress,
|
||||
value: '10',
|
||||
},
|
||||
}
|
||||
|
||||
await testTransaction(this.client, setupTx, this.wallet)
|
||||
|
||||
const accountOffersResponse = await this.client.request({
|
||||
command: 'account_offers',
|
||||
account: this.wallet.classicAddress,
|
||||
})
|
||||
assert.lengthOf(
|
||||
accountOffersResponse.result.offers,
|
||||
1,
|
||||
'Should be exactly one offer on the ledger',
|
||||
)
|
||||
const seq = accountOffersResponse.result.offers[0].seq
|
||||
|
||||
// actually test OfferCancel
|
||||
const tx: OfferCancel = {
|
||||
TransactionType: 'OfferCancel',
|
||||
Account: this.wallet.classicAddress,
|
||||
OfferSequence: seq,
|
||||
}
|
||||
|
||||
await testTransaction(this.client, tx, this.wallet)
|
||||
|
||||
const accountOffersResponse2 = await this.client.request({
|
||||
command: 'account_offers',
|
||||
account: this.wallet.classicAddress,
|
||||
})
|
||||
assert.lengthOf(
|
||||
accountOffersResponse2.result.offers,
|
||||
0,
|
||||
'Should not be any offers on the ledger',
|
||||
)
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it(
|
||||
'base',
|
||||
async () => {
|
||||
// set up an offer
|
||||
const setupTx: OfferCreate = {
|
||||
TransactionType: 'OfferCreate',
|
||||
Account: testContext.wallet.classicAddress,
|
||||
TakerGets: '13100000',
|
||||
TakerPays: {
|
||||
currency: 'USD',
|
||||
issuer: testContext.wallet.classicAddress,
|
||||
value: '10',
|
||||
},
|
||||
}
|
||||
|
||||
await testTransaction(testContext.client, setupTx, testContext.wallet)
|
||||
|
||||
const accountOffersResponse = await testContext.client.request({
|
||||
command: 'account_offers',
|
||||
account: testContext.wallet.classicAddress,
|
||||
})
|
||||
assert.lengthOf(
|
||||
accountOffersResponse.result.offers!,
|
||||
1,
|
||||
'Should be exactly one offer on the ledger',
|
||||
)
|
||||
const seq = accountOffersResponse.result.offers?.[0].seq
|
||||
|
||||
assert.isNumber(seq)
|
||||
|
||||
// actually test OfferCancel
|
||||
const tx: OfferCancel = {
|
||||
TransactionType: 'OfferCancel',
|
||||
Account: testContext.wallet.classicAddress,
|
||||
OfferSequence: seq!,
|
||||
}
|
||||
|
||||
await testTransaction(testContext.client, tx, testContext.wallet)
|
||||
|
||||
const accountOffersResponse2 = await testContext.client.request({
|
||||
command: 'account_offers',
|
||||
account: testContext.wallet.classicAddress,
|
||||
})
|
||||
assert.lengthOf(
|
||||
accountOffersResponse2.result.offers!,
|
||||
0,
|
||||
'Should not be any offers on the ledger',
|
||||
)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,43 +1,52 @@
|
||||
import { assert } from 'chai'
|
||||
import _ from 'lodash'
|
||||
import { OfferCreate } from 'xrpl-local'
|
||||
|
||||
import { OfferCreate } from '../../../src'
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
import { testTransaction } from '../utils'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
|
||||
describe('OfferCreate', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('base', async function () {
|
||||
const tx: OfferCreate = {
|
||||
TransactionType: 'OfferCreate',
|
||||
Account: this.wallet.classicAddress,
|
||||
TakerGets: '13100000',
|
||||
TakerPays: {
|
||||
currency: 'USD',
|
||||
issuer: this.wallet.classicAddress,
|
||||
value: '10',
|
||||
},
|
||||
}
|
||||
|
||||
await testTransaction(this.client, tx, this.wallet)
|
||||
|
||||
// confirm that the offer actually went through
|
||||
const accountOffersResponse = await this.client.request({
|
||||
command: 'account_offers',
|
||||
account: this.wallet.classicAddress,
|
||||
})
|
||||
assert.lengthOf(
|
||||
accountOffersResponse.result.offers,
|
||||
1,
|
||||
'Should be exactly one offer on the ledger',
|
||||
)
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it(
|
||||
'base',
|
||||
async () => {
|
||||
const tx: OfferCreate = {
|
||||
TransactionType: 'OfferCreate',
|
||||
Account: testContext.wallet.classicAddress,
|
||||
TakerGets: '13100000',
|
||||
TakerPays: {
|
||||
currency: 'USD',
|
||||
issuer: testContext.wallet.classicAddress,
|
||||
value: '10',
|
||||
},
|
||||
}
|
||||
|
||||
await testTransaction(testContext.client, tx, testContext.wallet)
|
||||
|
||||
// confirm that the offer actually went through
|
||||
const accountOffersResponse = await testContext.client.request({
|
||||
command: 'account_offers',
|
||||
account: testContext.wallet.classicAddress,
|
||||
})
|
||||
assert.lengthOf(
|
||||
accountOffersResponse.result.offers!,
|
||||
1,
|
||||
'Should be exactly one offer on the ledger',
|
||||
)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,27 +1,35 @@
|
||||
import _ from 'lodash'
|
||||
import { Payment } from 'xrpl-local'
|
||||
|
||||
import { Payment } from '../../../src'
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
import { generateFundedWallet, testTransaction } from '../utils'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
|
||||
describe('Payment', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('base', async function () {
|
||||
const wallet2 = await generateFundedWallet(this.client)
|
||||
const tx: Payment = {
|
||||
TransactionType: 'Payment',
|
||||
Account: this.wallet.classicAddress,
|
||||
Destination: wallet2.classicAddress,
|
||||
Amount: '1000',
|
||||
}
|
||||
await testTransaction(this.client, tx, this.wallet)
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it(
|
||||
'base',
|
||||
async () => {
|
||||
const wallet2 = await generateFundedWallet(testContext.client)
|
||||
const tx: Payment = {
|
||||
TransactionType: 'Payment',
|
||||
Account: testContext.wallet.classicAddress,
|
||||
Destination: wallet2.classicAddress,
|
||||
Amount: '1000',
|
||||
}
|
||||
await testTransaction(testContext.client, tx, testContext.wallet)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import _ from 'lodash'
|
||||
import { PaymentChannelCreate, hashes, PaymentChannelClaim } from 'xrpl-local'
|
||||
|
||||
import { PaymentChannelCreate, hashes, PaymentChannelClaim } from '../../../src'
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
import { generateFundedWallet, testTransaction } from '../utils'
|
||||
|
||||
// how long before each test case times out
|
||||
@@ -10,40 +12,54 @@ const TIMEOUT = 20000
|
||||
const { hashPaymentChannel } = hashes
|
||||
|
||||
describe('PaymentChannelClaim', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('base', async function () {
|
||||
const wallet2 = await generateFundedWallet(this.client)
|
||||
const paymentChannelCreate: PaymentChannelCreate = {
|
||||
TransactionType: 'PaymentChannelCreate',
|
||||
Account: this.wallet.classicAddress,
|
||||
Amount: '100',
|
||||
Destination: wallet2.classicAddress,
|
||||
SettleDelay: 86400,
|
||||
PublicKey: this.wallet.publicKey,
|
||||
}
|
||||
|
||||
const paymentChannelResponse = await this.client.submit(
|
||||
paymentChannelCreate,
|
||||
{ wallet: this.wallet },
|
||||
)
|
||||
|
||||
await testTransaction(this.client, paymentChannelCreate, this.wallet)
|
||||
|
||||
const paymentChannelClaim: PaymentChannelClaim = {
|
||||
Account: this.wallet.classicAddress,
|
||||
TransactionType: 'PaymentChannelClaim',
|
||||
Channel: hashPaymentChannel(
|
||||
this.wallet.classicAddress,
|
||||
wallet2.classicAddress,
|
||||
paymentChannelResponse.result.tx_json.Sequence ?? 0,
|
||||
),
|
||||
Amount: '100',
|
||||
}
|
||||
|
||||
await testTransaction(this.client, paymentChannelClaim, this.wallet)
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it(
|
||||
'base',
|
||||
async () => {
|
||||
const wallet2 = await generateFundedWallet(testContext.client)
|
||||
const paymentChannelCreate: PaymentChannelCreate = {
|
||||
TransactionType: 'PaymentChannelCreate',
|
||||
Account: testContext.wallet.classicAddress,
|
||||
Amount: '100',
|
||||
Destination: wallet2.classicAddress,
|
||||
SettleDelay: 86400,
|
||||
PublicKey: testContext.wallet.publicKey,
|
||||
}
|
||||
|
||||
const paymentChannelResponse = await testContext.client.submit(
|
||||
paymentChannelCreate,
|
||||
{ wallet: testContext.wallet },
|
||||
)
|
||||
|
||||
await testTransaction(
|
||||
testContext.client,
|
||||
paymentChannelCreate,
|
||||
testContext.wallet,
|
||||
)
|
||||
|
||||
const paymentChannelClaim: PaymentChannelClaim = {
|
||||
Account: testContext.wallet.classicAddress,
|
||||
TransactionType: 'PaymentChannelClaim',
|
||||
Channel: hashPaymentChannel(
|
||||
testContext.wallet.classicAddress,
|
||||
wallet2.classicAddress,
|
||||
paymentChannelResponse.result.tx_json.Sequence ?? 0,
|
||||
),
|
||||
Amount: '100',
|
||||
}
|
||||
|
||||
await testTransaction(
|
||||
testContext.client,
|
||||
paymentChannelClaim,
|
||||
testContext.wallet,
|
||||
)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,30 +1,42 @@
|
||||
import _ from 'lodash'
|
||||
import { PaymentChannelCreate } from 'xrpl-local'
|
||||
|
||||
import { PaymentChannelCreate } from '../../../src'
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
import { generateFundedWallet, testTransaction } from '../utils'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
|
||||
describe('PaymentChannelCreate', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('base', async function () {
|
||||
const wallet2 = await generateFundedWallet(this.client)
|
||||
const paymentChannelCreate: PaymentChannelCreate = {
|
||||
TransactionType: 'PaymentChannelCreate',
|
||||
Account: this.wallet.classicAddress,
|
||||
Amount: '100',
|
||||
Destination: wallet2.classicAddress,
|
||||
SettleDelay: 86400,
|
||||
PublicKey: this.wallet.publicKey,
|
||||
}
|
||||
|
||||
await testTransaction(this.client, paymentChannelCreate, this.wallet)
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it(
|
||||
'base',
|
||||
async () => {
|
||||
const wallet2 = await generateFundedWallet(testContext.client)
|
||||
const paymentChannelCreate: PaymentChannelCreate = {
|
||||
TransactionType: 'PaymentChannelCreate',
|
||||
Account: testContext.wallet.classicAddress,
|
||||
Amount: '100',
|
||||
Destination: wallet2.classicAddress,
|
||||
SettleDelay: 86400,
|
||||
PublicKey: testContext.wallet.publicKey,
|
||||
}
|
||||
|
||||
await testTransaction(
|
||||
testContext.client,
|
||||
paymentChannelCreate,
|
||||
testContext.wallet,
|
||||
)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import _ from 'lodash'
|
||||
import { PaymentChannelCreate, hashes, PaymentChannelFund } from 'xrpl-local'
|
||||
|
||||
import { PaymentChannelCreate, hashes, PaymentChannelFund } from '../../../src'
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
import { generateFundedWallet, testTransaction } from '../utils'
|
||||
|
||||
// how long before each test case times out
|
||||
@@ -10,39 +12,53 @@ const TIMEOUT = 20000
|
||||
const { hashPaymentChannel } = hashes
|
||||
|
||||
describe('PaymentChannelFund', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('base', async function () {
|
||||
const wallet2 = await generateFundedWallet(this.client)
|
||||
const paymentChannelCreate: PaymentChannelCreate = {
|
||||
TransactionType: 'PaymentChannelCreate',
|
||||
Account: this.wallet.classicAddress,
|
||||
Amount: '100',
|
||||
Destination: wallet2.classicAddress,
|
||||
SettleDelay: 86400,
|
||||
PublicKey: this.wallet.publicKey,
|
||||
}
|
||||
|
||||
const paymentChannelResponse = await this.client.submit(
|
||||
paymentChannelCreate,
|
||||
{ wallet: this.wallet },
|
||||
)
|
||||
await testTransaction(this.client, paymentChannelCreate, this.wallet)
|
||||
|
||||
const paymentChannelFund: PaymentChannelFund = {
|
||||
Account: this.wallet.classicAddress,
|
||||
TransactionType: 'PaymentChannelFund',
|
||||
Channel: hashPaymentChannel(
|
||||
this.wallet.classicAddress,
|
||||
wallet2.classicAddress,
|
||||
paymentChannelResponse.result.tx_json.Sequence ?? 0,
|
||||
),
|
||||
Amount: '100',
|
||||
}
|
||||
|
||||
await testTransaction(this.client, paymentChannelFund, this.wallet)
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it(
|
||||
'base',
|
||||
async () => {
|
||||
const wallet2 = await generateFundedWallet(testContext.client)
|
||||
const paymentChannelCreate: PaymentChannelCreate = {
|
||||
TransactionType: 'PaymentChannelCreate',
|
||||
Account: testContext.wallet.classicAddress,
|
||||
Amount: '100',
|
||||
Destination: wallet2.classicAddress,
|
||||
SettleDelay: 86400,
|
||||
PublicKey: testContext.wallet.publicKey,
|
||||
}
|
||||
|
||||
const paymentChannelResponse = await testContext.client.submit(
|
||||
paymentChannelCreate,
|
||||
{ wallet: testContext.wallet },
|
||||
)
|
||||
await testTransaction(
|
||||
testContext.client,
|
||||
paymentChannelCreate,
|
||||
testContext.wallet,
|
||||
)
|
||||
|
||||
const paymentChannelFund: PaymentChannelFund = {
|
||||
Account: testContext.wallet.classicAddress,
|
||||
TransactionType: 'PaymentChannelFund',
|
||||
Channel: hashPaymentChannel(
|
||||
testContext.wallet.classicAddress,
|
||||
wallet2.classicAddress,
|
||||
paymentChannelResponse.result.tx_json.Sequence ?? 0,
|
||||
),
|
||||
Amount: '100',
|
||||
}
|
||||
|
||||
await testTransaction(
|
||||
testContext.client,
|
||||
paymentChannelFund,
|
||||
testContext.wallet,
|
||||
)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,39 +1,47 @@
|
||||
import _ from 'lodash'
|
||||
import { SignerListSet } from 'xrpl-local'
|
||||
|
||||
import { SignerListSet } from '../../../src'
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
import { testTransaction } from '../utils'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
|
||||
describe('SignerListSet', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('base', async function () {
|
||||
const tx: SignerListSet = {
|
||||
TransactionType: 'SignerListSet',
|
||||
Account: this.wallet.classicAddress,
|
||||
SignerEntries: [
|
||||
{
|
||||
SignerEntry: {
|
||||
Account: 'r5nx8ZkwEbFztnc8Qyi22DE9JYjRzNmvs',
|
||||
SignerWeight: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
SignerEntry: {
|
||||
Account: 'r3RtUvGw9nMoJ5FuHxuoVJvcENhKtuF9ud',
|
||||
SignerWeight: 1,
|
||||
},
|
||||
},
|
||||
],
|
||||
SignerQuorum: 2,
|
||||
}
|
||||
await testTransaction(this.client, tx, this.wallet)
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it(
|
||||
'base',
|
||||
async () => {
|
||||
const tx: SignerListSet = {
|
||||
TransactionType: 'SignerListSet',
|
||||
Account: testContext.wallet.classicAddress,
|
||||
SignerEntries: [
|
||||
{
|
||||
SignerEntry: {
|
||||
Account: 'r5nx8ZkwEbFztnc8Qyi22DE9JYjRzNmvs',
|
||||
SignerWeight: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
SignerEntry: {
|
||||
Account: 'r3RtUvGw9nMoJ5FuHxuoVJvcENhKtuF9ud',
|
||||
SignerWeight: 1,
|
||||
},
|
||||
},
|
||||
],
|
||||
SignerQuorum: 2,
|
||||
}
|
||||
await testTransaction(testContext.client, tx, testContext.wallet)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,65 +1,81 @@
|
||||
import _ from 'lodash'
|
||||
import { TrustSet, percentToQuality } from 'xrpl-local'
|
||||
|
||||
import { TrustSet, percentToQuality } from '../../../src'
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, teardownClient } from '../setup'
|
||||
import {
|
||||
setupClient,
|
||||
teardownClient,
|
||||
type XrplIntegrationTestContext,
|
||||
} from '../setup'
|
||||
import { generateFundedWallet, testTransaction } from '../utils'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
|
||||
describe('TrustSet', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
let testContext: XrplIntegrationTestContext
|
||||
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('base', async function () {
|
||||
const wallet2 = await generateFundedWallet(this.client)
|
||||
const tx: TrustSet = {
|
||||
TransactionType: 'TrustSet',
|
||||
Account: this.wallet.classicAddress,
|
||||
LimitAmount: {
|
||||
currency: 'USD',
|
||||
issuer: wallet2.classicAddress,
|
||||
value: '100',
|
||||
},
|
||||
}
|
||||
|
||||
await testTransaction(this.client, tx, this.wallet)
|
||||
beforeEach(async () => {
|
||||
testContext = await setupClient(serverUrl)
|
||||
})
|
||||
afterEach(async () => teardownClient(testContext))
|
||||
|
||||
it('Quality < 1', async function () {
|
||||
const wallet2 = await generateFundedWallet(this.client)
|
||||
const tx: TrustSet = {
|
||||
TransactionType: 'TrustSet',
|
||||
Account: this.wallet.address,
|
||||
QualityIn: percentToQuality('99%'),
|
||||
QualityOut: percentToQuality('99%'),
|
||||
LimitAmount: {
|
||||
currency: 'USD',
|
||||
issuer: wallet2.address,
|
||||
value: '100',
|
||||
},
|
||||
}
|
||||
it(
|
||||
'base',
|
||||
async () => {
|
||||
const wallet2 = await generateFundedWallet(testContext.client)
|
||||
const tx: TrustSet = {
|
||||
TransactionType: 'TrustSet',
|
||||
Account: testContext.wallet.classicAddress,
|
||||
LimitAmount: {
|
||||
currency: 'USD',
|
||||
issuer: wallet2.classicAddress,
|
||||
value: '100',
|
||||
},
|
||||
}
|
||||
|
||||
await testTransaction(this.client, tx, this.wallet)
|
||||
})
|
||||
await testTransaction(testContext.client, tx, testContext.wallet)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
|
||||
it('Quality > 1', async function () {
|
||||
const wallet2 = await generateFundedWallet(this.client)
|
||||
const tx: TrustSet = {
|
||||
TransactionType: 'TrustSet',
|
||||
QualityIn: percentToQuality('101%'),
|
||||
QualityOut: percentToQuality('101%'),
|
||||
Account: this.wallet.address,
|
||||
LimitAmount: {
|
||||
currency: 'USD',
|
||||
issuer: wallet2.address,
|
||||
value: '100',
|
||||
},
|
||||
}
|
||||
it(
|
||||
'Quality < 1',
|
||||
async () => {
|
||||
const wallet2 = await generateFundedWallet(testContext.client)
|
||||
const tx: TrustSet = {
|
||||
TransactionType: 'TrustSet',
|
||||
Account: testContext.wallet.address,
|
||||
QualityIn: percentToQuality('99%'),
|
||||
QualityOut: percentToQuality('99%'),
|
||||
LimitAmount: {
|
||||
currency: 'USD',
|
||||
issuer: wallet2.address,
|
||||
value: '100',
|
||||
},
|
||||
}
|
||||
|
||||
await testTransaction(this.client, tx, this.wallet)
|
||||
})
|
||||
await testTransaction(testContext.client, tx, testContext.wallet)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
|
||||
it(
|
||||
'Quality > 1',
|
||||
async () => {
|
||||
const wallet2 = await generateFundedWallet(testContext.client)
|
||||
const tx: TrustSet = {
|
||||
TransactionType: 'TrustSet',
|
||||
QualityIn: percentToQuality('101%'),
|
||||
QualityOut: percentToQuality('101%'),
|
||||
Account: testContext.wallet.address,
|
||||
LimitAmount: {
|
||||
currency: 'USD',
|
||||
issuer: wallet2.address,
|
||||
value: '100',
|
||||
},
|
||||
}
|
||||
|
||||
await testTransaction(testContext.client, tx, testContext.wallet)
|
||||
},
|
||||
TIMEOUT,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,27 +1,173 @@
|
||||
import { assert } from 'chai'
|
||||
import _ from 'lodash'
|
||||
import omit from 'lodash/omit'
|
||||
import throttle from 'lodash/throttle'
|
||||
import { decode } from 'ripple-binary-codec'
|
||||
import { Client, Wallet, AccountInfoRequest } from 'xrpl-local'
|
||||
import { Payment, Transaction } from 'xrpl-local/models/transactions'
|
||||
import { hashSignedTx } from 'xrpl-local/utils/hashes'
|
||||
|
||||
import {
|
||||
Client,
|
||||
Wallet,
|
||||
AccountInfoRequest,
|
||||
type SubmitResponse,
|
||||
TimeoutError,
|
||||
NotConnectedError,
|
||||
unixTimeToRippleTime,
|
||||
} from '../../src'
|
||||
import { Payment, Transaction } from '../../src/models/transactions'
|
||||
import { hashSignedTx } from '../../src/utils/hashes'
|
||||
|
||||
const masterAccount = 'rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh'
|
||||
const masterSecret = 'snoPBrXtMeMyMHUVTgbuqAfg1SUTb'
|
||||
|
||||
export async function ledgerAccept(client: Client): Promise<void> {
|
||||
const request = { command: 'ledger_accept' }
|
||||
await client.connection.request(request)
|
||||
async function sendLedgerAccept(client: Client): Promise<unknown> {
|
||||
return client.connection.request({ command: 'ledger_accept' })
|
||||
}
|
||||
|
||||
export function subscribeDone(client: Client, done: Mocha.Done): void {
|
||||
/**
|
||||
* Throttles an async function in a way that can be awaited.
|
||||
* By default throttle doesn't return a promise for async functions unless it's invoking them immediately.
|
||||
*
|
||||
* @param func - async function to throttle calls for.
|
||||
* @param wait - same function as lodash.throttle's wait parameter. Call this function at most this often.
|
||||
* @returns a promise which will be resolved/ rejected only if the function is executed, with the result of the underlying call.
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Proper
|
||||
function asyncThrottle<F extends (...args: any[]) => Promise<unknown>>(
|
||||
func: F,
|
||||
wait?: number,
|
||||
): (...args: Parameters<F>) => ReturnType<F> {
|
||||
const throttled = throttle((resolve, reject, args: Parameters<F>) => {
|
||||
func(...args)
|
||||
.then(resolve)
|
||||
.catch(reject)
|
||||
}, wait)
|
||||
const ret = (...args: Parameters<F>): ReturnType<F> =>
|
||||
new Promise((resolve, reject) => {
|
||||
throttled(resolve, reject, args)
|
||||
}) as ReturnType<F>
|
||||
return ret
|
||||
}
|
||||
|
||||
const throttledLedgerAccept = asyncThrottle(sendLedgerAccept, 1000)
|
||||
|
||||
export async function ledgerAccept(
|
||||
client: Client,
|
||||
retries?: number,
|
||||
shouldThrottle?: boolean,
|
||||
): Promise<unknown> {
|
||||
return new Promise<unknown>((resolve, reject) => {
|
||||
const ledgerAcceptFunc = shouldThrottle
|
||||
? throttledLedgerAccept
|
||||
: sendLedgerAccept
|
||||
ledgerAcceptFunc(client)
|
||||
.then(resolve)
|
||||
.catch((error) => {
|
||||
if (retries === undefined) {
|
||||
setTimeout(() => {
|
||||
resolve(ledgerAccept(client, 10))
|
||||
}, 1000)
|
||||
} else if (retries > 0) {
|
||||
setTimeout(() => {
|
||||
resolve(ledgerAccept(client, retries - 1))
|
||||
}, 1000)
|
||||
} else {
|
||||
reject(error)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to get the time after which we can check for the escrow to be finished.
|
||||
* Sometimes the ledger close_time is in the future, so we need to wait for it to catch up.
|
||||
*
|
||||
* @param targetTime - The target wait time, before accounting for current ledger time.
|
||||
* @param minimumWaitTimeMs - The minimum wait time in milliseconds.
|
||||
* @param maximumWaitTimeMs - The maximum wait time in milliseconds.
|
||||
* @returns The wait time in milliseconds.
|
||||
*/
|
||||
export function calculateWaitTimeForTransaction(
|
||||
targetTime: number,
|
||||
minimumWaitTimeMs = 5000,
|
||||
maximumWaitTimeMs = 20000,
|
||||
): number {
|
||||
const currentTimeUnixMs = Math.floor(new Date().getTime())
|
||||
const currentTimeRippleSeconds = unixTimeToRippleTime(currentTimeUnixMs)
|
||||
const closeTimeCurrentTimeDiffSeconds = currentTimeRippleSeconds - targetTime
|
||||
const closeTimeCurrentTimeDiffMs = closeTimeCurrentTimeDiffSeconds * 1000
|
||||
return Math.max(
|
||||
minimumWaitTimeMs,
|
||||
Math.min(
|
||||
Math.abs(closeTimeCurrentTimeDiffMs) + minimumWaitTimeMs,
|
||||
// Maximum wait time of 20 seconds
|
||||
maximumWaitTimeMs,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
export function subscribeDone(client: Client): void {
|
||||
client.removeAllListeners()
|
||||
done()
|
||||
}
|
||||
|
||||
export async function submitTransaction({
|
||||
client,
|
||||
transaction,
|
||||
wallet,
|
||||
retry = { count: 5, delayMs: 1000 },
|
||||
}: {
|
||||
client: Client
|
||||
transaction: Transaction
|
||||
wallet: Wallet
|
||||
retry?: {
|
||||
count: number
|
||||
delayMs: number
|
||||
}
|
||||
}): Promise<SubmitResponse> {
|
||||
let response: SubmitResponse
|
||||
try {
|
||||
response = await client.submit(transaction, { wallet })
|
||||
|
||||
// Retry if another transaction finished before this one
|
||||
while (
|
||||
['tefPAST_SEQ', 'tefMAX_LEDGER'].includes(
|
||||
response.result.engine_result,
|
||||
) &&
|
||||
retry.count > 0
|
||||
) {
|
||||
// eslint-disable-next-line no-param-reassign -- we want to decrement the count
|
||||
retry.count -= 1
|
||||
// eslint-disable-next-line no-await-in-loop, no-promise-executor-return -- We are waiting on retries
|
||||
await new Promise((resolve) => setTimeout(resolve, retry.delayMs))
|
||||
// eslint-disable-next-line no-await-in-loop -- We are retrying in a loop on purpose
|
||||
response = await client.submit(transaction, { wallet })
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof TimeoutError || error instanceof NotConnectedError) {
|
||||
// retry
|
||||
return submitTransaction({
|
||||
client,
|
||||
transaction,
|
||||
wallet,
|
||||
retry: {
|
||||
...retry,
|
||||
count: retry.count > 0 ? retry.count - 1 : 0,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
throw error
|
||||
}
|
||||
|
||||
return response
|
||||
}
|
||||
|
||||
export async function fundAccount(
|
||||
client: Client,
|
||||
wallet: Wallet,
|
||||
): Promise<void> {
|
||||
retry?: {
|
||||
count: number
|
||||
delayMs: number
|
||||
},
|
||||
): Promise<SubmitResponse> {
|
||||
const payment: Payment = {
|
||||
TransactionType: 'Payment',
|
||||
Account: masterAccount,
|
||||
@@ -29,17 +175,23 @@ export async function fundAccount(
|
||||
// 2 times the amount needed for a new account (20 XRP)
|
||||
Amount: '400000000',
|
||||
}
|
||||
const response = await client.submit(payment, {
|
||||
wallet: Wallet.fromSeed(masterSecret),
|
||||
const wal = Wallet.fromSeed(masterSecret)
|
||||
const response = await submitTransaction({
|
||||
client,
|
||||
wallet: wal,
|
||||
transaction: payment,
|
||||
retry,
|
||||
})
|
||||
|
||||
if (response.result.engine_result !== 'tesSUCCESS') {
|
||||
// eslint-disable-next-line no-console -- happens only when something goes wrong
|
||||
console.log(response)
|
||||
assert.fail(`Response not successful, ${response.result.engine_result}`)
|
||||
}
|
||||
await ledgerAccept(client)
|
||||
const signedTx = _.omit(response.result.tx_json, 'hash')
|
||||
const signedTx = omit(response.result.tx_json, 'hash')
|
||||
await verifySubmittedTransaction(client, signedTx as Transaction)
|
||||
return response
|
||||
}
|
||||
|
||||
export async function generateFundedWallet(client: Client): Promise<Wallet> {
|
||||
@@ -61,7 +213,7 @@ export async function verifySubmittedTransaction(
|
||||
|
||||
assert(data.result)
|
||||
assert.deepEqual(
|
||||
_.omit(data.result, [
|
||||
omit(data.result, [
|
||||
'date',
|
||||
'hash',
|
||||
'inLedger',
|
||||
@@ -78,19 +230,53 @@ export async function verifySubmittedTransaction(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a test transaction for integration testing.
|
||||
*
|
||||
* @param client - The XRPL client
|
||||
* @param transaction - The transaction object to send.
|
||||
* @param wallet - The wallet to send the transaction from.
|
||||
* @param retry - As of Sep 2022, xrpl.js does not track requests sent in parallel. Our sequence numbers can get off from
|
||||
* the server's sequence numbers. This is a fix to retry the transaction if it fails due to tefPAST_SEQ.
|
||||
* @param retry.count - How many times the request should be retried.
|
||||
* @param retry.delayMs - How long to wait between retries.
|
||||
* @returns The response of the transaction.
|
||||
*/
|
||||
// eslint-disable-next-line max-params -- Test function, many params are needed
|
||||
export async function testTransaction(
|
||||
client: Client,
|
||||
transaction: Transaction,
|
||||
wallet: Wallet,
|
||||
): Promise<void> {
|
||||
retry?: {
|
||||
count: number
|
||||
delayMs: number
|
||||
},
|
||||
): Promise<SubmitResponse> {
|
||||
// Accept any un-validated changes.
|
||||
await ledgerAccept(client)
|
||||
|
||||
// sign/submit the transaction
|
||||
const response = await client.submit(transaction, { wallet })
|
||||
const response = await submitTransaction({
|
||||
client,
|
||||
wallet,
|
||||
transaction,
|
||||
retry,
|
||||
})
|
||||
|
||||
// check that the transaction was successful
|
||||
assert.equal(response.type, 'response')
|
||||
|
||||
if (response.result.engine_result !== 'tesSUCCESS') {
|
||||
// eslint-disable-next-line no-console -- See output
|
||||
console.error(
|
||||
`Transaction was not successful. Expected response.result.engine_result to be tesSUCCESS but got ${response.result.engine_result}`,
|
||||
)
|
||||
// eslint-disable-next-line no-console -- See output
|
||||
console.error('The transaction was: ', transaction)
|
||||
// eslint-disable-next-line no-console -- See output
|
||||
console.error('The response was: ', JSON.stringify(response))
|
||||
}
|
||||
|
||||
assert.equal(
|
||||
response.result.engine_result,
|
||||
'tesSUCCESS',
|
||||
@@ -98,9 +284,10 @@ export async function testTransaction(
|
||||
)
|
||||
|
||||
// check that the transaction is on the ledger
|
||||
const signedTx = _.omit(response.result.tx_json, 'hash')
|
||||
const signedTx = omit(response.result.tx_json, 'hash')
|
||||
await ledgerAccept(client)
|
||||
await verifySubmittedTransaction(client, signedTx as Transaction)
|
||||
return response
|
||||
}
|
||||
|
||||
export async function getXRPBalance(
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/* eslint-disable consistent-default-export-name/default-export-match-filename -- This is a test file. */
|
||||
import { Wallet } from 'xrpl-local'
|
||||
import { Wallet } from '../../src'
|
||||
|
||||
const walletSecret = 'shK6YXzwYfnFVn3YZSaMh5zuAddKx'
|
||||
|
||||
|
||||
Reference in New Issue
Block a user