test: removes the use of TestSuite (#1566)* switch all methods to new format* clean up rippleClient* rename files to remove ripple from name* additional cleanup

This commit is contained in:
Mayukha Vadari
2021-08-30 18:04:06 -04:00
parent 43802f9e22
commit 6268b9ea26
41 changed files with 3880 additions and 3699 deletions

View File

@@ -1,14 +1,19 @@
import { fromSeed } from 'bip32'; import { fromSeed } from "bip32";
import { mnemonicToSeedSync } from 'bip39'; import { mnemonicToSeedSync } from "bip39";
import { classicAddressToXAddress } from 'ripple-address-codec' import { classicAddressToXAddress } from "ripple-address-codec";
import { decode, encodeForSigning } from 'ripple-binary-codec'; import { decode, encodeForSigning } from "ripple-binary-codec";
import { deriveAddress, deriveKeypair, generateSeed, verify } from 'ripple-keypairs'; import {
deriveAddress,
deriveKeypair,
generateSeed,
verify,
} from "ripple-keypairs";
import ECDSA from './common/ecdsa'; import ECDSA from "./common/ecdsa";
import { ValidationError } from './common/errors'; import { ValidationError } from "./common/errors";
import { SignedTransaction } from './common/types/objects'; import { SignedTransaction } from "./common/types/objects";
import { signOffline } from './transaction/sign'; import { signOffline } from "./transaction/sign";
import { SignOptions } from './transaction/types'; import { SignOptions } from "./transaction/types";
/** /**
* A utility for deriving a wallet composed of a keypair (publicKey/privateKey). * A utility for deriving a wallet composed of a keypair (publicKey/privateKey).
@@ -125,16 +130,13 @@ class Wallet {
/** /**
* Gets an X-address in Testnet/Mainnet format. * Gets an X-address in Testnet/Mainnet format.
* @param {number} tag A tag to be included within the X-address. *
* @param {boolean} test A boolean to indicate if X-address should be in Testnet (true) or Mainnet (false) format. * @param tag - A tag to be included within the X-address.
* @returns {string} An X-address. * @param test - A boolean to indicate if X-address should be in Testnet (true) or Mainnet (false) format.
* @returns An X-address.
*/ */
getXAddress(tag: number, test: boolean = false): string { getXAddress(tag: number, test = false): string {
return classicAddressToXAddress( return classicAddressToXAddress(deriveAddress(this.publicKey), tag, test);
deriveAddress(this.publicKey),
tag,
test,
)
} }
} }

View File

@@ -3,29 +3,28 @@ import binary from "ripple-binary-codec";
import requests from "../fixtures/requests"; import requests from "../fixtures/requests";
import responses from "../fixtures/responses"; import responses from "../fixtures/responses";
import { assertResultMatch, TestSuite } from "../testUtils"; import setupClient from "../setupClient";
import { assertResultMatch } from "../testUtils";
const { combine: REQUEST_FIXTURES } = requests; const { combine: REQUEST_FIXTURES } = requests;
const { combine: RESPONSE_FIXTURES } = responses; const { combine: RESPONSE_FIXTURES } = responses;
/** describe("client.combine", function () {
* Every test suite exports their tests in the default object. beforeEach(setupClient.setup);
* - Check out the "TestSuite" type for documentation on the interface. afterEach(setupClient.teardown);
* - Check out "test/client/index.ts" for more information about the test runner.
*/
export default <TestSuite>{
async combine(client, address) {
const combined = client.combine(REQUEST_FIXTURES.setDomain);
assertResultMatch(combined, RESPONSE_FIXTURES.single, "sign");
},
"combine - different transactions": async (client, address) => { it("combine", async function () {
const combined = this.client.combine(REQUEST_FIXTURES.setDomain);
assertResultMatch(combined, RESPONSE_FIXTURES.single, "sign");
});
it("combine - different transactions", async function () {
const request = [REQUEST_FIXTURES.setDomain[0]]; const request = [REQUEST_FIXTURES.setDomain[0]];
const tx = binary.decode(REQUEST_FIXTURES.setDomain[0]); const tx = binary.decode(REQUEST_FIXTURES.setDomain[0]);
tx.Flags = 0; tx.Flags = 0;
request.push(binary.encode(tx)); request.push(binary.encode(tx));
assert.throws(() => { assert.throws(() => {
client.combine(request); this.client.combine(request);
}, /txJSON is not the same for all signedTransactions/); }, /txJSON is not the same for all signedTransactions/);
}, });
}; });

View File

@@ -2,30 +2,23 @@ import { assert } from "chai";
import { Client } from "xrpl-local"; import { Client } from "xrpl-local";
import { TestSuite } from "../testUtils"; describe("client constructor", function () {
it("Client - implicit server port", function () {
/**
* Every test suite exports their tests in the default object.
* - Check out the "TestSuite" type for documentation on the interface.
* - Check out "test/client/index.ts" for more information about the test runner.
*/
export default <TestSuite>{
"Client - implicit server port": () => {
new Client("wss://s1.ripple.com"); new Client("wss://s1.ripple.com");
}, });
"Client invalid options": () => { it("Client invalid options", function () {
// @ts-expect-error - This is intentionally invalid // @ts-expect-error - This is intentionally invalid
assert.throws(() => new Client({ invalid: true })); assert.throws(() => new Client({ invalid: true }));
}, });
"Client valid options": () => { it("Client valid options", function () {
const client = new Client("wss://s:1"); const client = new Client("wss://s:1");
const privateConnectionUrl = (client.connection as any)._url; const privateConnectionUrl = (client.connection as any)._url;
assert.deepEqual(privateConnectionUrl, "wss://s:1"); assert.deepEqual(privateConnectionUrl, "wss://s:1");
}, });
"Client invalid server uri": () => { it("Client invalid server uri", function () {
assert.throws(() => new Client("wss//s:1")); assert.throws(() => new Client("wss//s:1"));
}, });
}; });

View File

@@ -1,15 +1,9 @@
import { assert } from "chai"; import { assert } from "chai";
import { Client } from "../../src"; import { Client } from "../../src";
import { TestSuite } from "../testUtils";
/** describe("client.deriveXAddress", function () {
* Every test suite exports their tests in the default object. it("returns address for public key", function () {
* - Check out the "TestSuite" type for documentation on the interface.
* - Check out "test/client/index.ts" for more information about the test runner.
*/
export default <TestSuite>{
"returns address for public key": async (client, address) => {
assert.equal( assert.equal(
Client.deriveXAddress({ Client.deriveXAddress({
publicKey: publicKey:
@@ -28,5 +22,5 @@ export default <TestSuite>{
}), }),
"TVVrSWtmQQssgVcmoMBcFQZKKf56QscyWLKnUyiuZW8ALU4" "TVVrSWtmQQssgVcmoMBcFQZKKf56QscyWLKnUyiuZW8ALU4"
); );
}, });
}; });

View File

@@ -1,20 +1,18 @@
import { assert } from "chai"; import { assert } from "chai";
import { TestSuite } from "../testUtils"; import setupClient from "../setupClient";
/** describe("client errors", function () {
* Every test suite exports their tests in the default object. beforeEach(setupClient.setup);
* - Check out the "TestSuite" type for documentation on the interface. afterEach(setupClient.teardown);
* - Check out "test/client/index.ts" for more information about the test runner.
*/ it("RippleError with data", async function () {
export default <TestSuite>{ const error = new this.client.errors.RippleError("_message_", "_data_");
"RippleError with data": async (client, address) => {
const error = new client.errors.RippleError("_message_", "_data_");
assert.strictEqual(error.toString(), "[RippleError(_message_, '_data_')]"); assert.strictEqual(error.toString(), "[RippleError(_message_, '_data_')]");
}, });
"NotFoundError default message": async (client, address) => { it("NotFoundError default message", async function () {
const error = new client.errors.NotFoundError(); const error = new this.client.errors.NotFoundError();
assert.strictEqual(error.toString(), "[NotFoundError(Not found)]"); assert.strictEqual(error.toString(), "[NotFoundError(Not found)]");
}, });
}; });

View File

@@ -3,7 +3,6 @@
// import {Client} from 'xrpl-local' // import {Client} from 'xrpl-local'
// import requests from '../fixtures/requests' // import requests from '../fixtures/requests'
// import responses from '../fixtures/responses' // import responses from '../fixtures/responses'
import { TestSuite } from "../testUtils";
// function checkSortingOfOrders(orders) { // function checkSortingOfOrders(orders) {
// let previousRate = '0' // let previousRate = '0'
@@ -39,12 +38,7 @@ import { TestSuite } from "../testUtils";
// return true // return true
// } // }
/** describe("client.formatBidsAndAsks", function () {
* Every test suite exports their tests in the default object.
* - Check out the "TestSuite" type for documentation on the interface.
* - Check out "test/client/index.ts" for more information about the test runner.
*/
export default <TestSuite>{
// 'normal': async (client, address) => { // 'normal': async (client, address) => {
// const orderbookInfo = { // const orderbookInfo = {
// base: { // base: {
@@ -365,4 +359,4 @@ export default <TestSuite>{
// ) // )
// }) // })
// } // }
}; });

View File

@@ -1,66 +1,94 @@
import responses from "../fixtures/responses"; import responses from "../fixtures/responses";
import rippled from "../fixtures/rippled"; import rippled from "../fixtures/rippled";
import rippledAccountLines from "../fixtures/rippled/accountLines"; import rippledAccountLines from "../fixtures/rippled/accountLines";
import { assertResultMatch, TestSuite } from "../testUtils"; import setupClient from "../setupClient";
import { assertResultMatch, addressTests } from "../testUtils";
/** /**
* Every test suite exports their tests in the default object. * Every test suite exports their tests in the default object.
* - Check out the "TestSuite" type for documentation on the interface. * - Check out the "TestSuite" type for documentation on the interface.
* - Check out "test/client/index.ts" for more information about the test runner. * - Check out "test/client/index.ts" for more information about the test runner.
*/ */
export default <TestSuite>{ describe("getBalances", function () {
async getBalances(client, address, mockRippled) { beforeEach(setupClient.setup);
mockRippled.addResponse("account_info", rippled.account_info.normal); afterEach(setupClient.teardown);
mockRippled.addResponse("account_lines", rippledAccountLines.normal);
mockRippled.addResponse("ledger", rippled.ledger.normal);
const result = await client.getBalances(address);
assertResultMatch(result, responses.getBalances, "getBalances");
},
"getBalances - limit": async (client, address, mockRippled) => { addressTests.forEach(function (test) {
const options = { limit: 3, ledgerVersion: 123456 }; describe(test.type, function () {
mockRippled.addResponse("account_info", rippled.account_info.normal); it("getBalances", async function () {
mockRippled.addResponse("account_lines", rippledAccountLines.normal); this.mockRippled.addResponse(
mockRippled.addResponse("ledger", rippled.ledger.normal); "account_info",
const expectedResponse = responses.getBalances.slice(0, 3); rippled.account_info.normal
const result = await client.getBalances(address, options); );
assertResultMatch(result, expectedResponse, "getBalances"); this.mockRippled.addResponse(
}, "account_lines",
rippledAccountLines.normal
);
this.mockRippled.addResponse("ledger", rippled.ledger.normal);
const result = await this.client.getBalances(test.address);
assertResultMatch(result, responses.getBalances, "getBalances");
});
"getBalances - limit & currency": async (client, address, mockRippled) => { it("getBalances - limit", async function () {
const options = { currency: "USD", limit: 3 }; const options = { limit: 3, ledgerVersion: 123456 };
mockRippled.addResponse("account_info", rippled.account_info.normal); this.mockRippled.addResponse(
mockRippled.addResponse("account_lines", rippledAccountLines.normal); "account_info",
mockRippled.addResponse("ledger", rippled.ledger.normal); rippled.account_info.normal
const expectedResponse = responses.getBalances );
.filter((item) => item.currency === "USD") this.mockRippled.addResponse(
.slice(0, 3); "account_lines",
const result = await client.getBalances(address, options); rippledAccountLines.normal
assertResultMatch(result, expectedResponse, "getBalances"); );
}, this.mockRippled.addResponse("ledger", rippled.ledger.normal);
const expectedResponse = responses.getBalances.slice(0, 3);
const result = await this.client.getBalances(test.address, options);
assertResultMatch(result, expectedResponse, "getBalances");
});
"getBalances - limit & currency & issuer": async ( it("getBalances - limit & currency", async function () {
client, const options = { currency: "USD", limit: 3 };
address, this.mockRippled.addResponse(
mockRippled "account_info",
) => { rippled.account_info.normal
const options = { );
currency: "USD", this.mockRippled.addResponse(
counterparty: "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", "account_lines",
limit: 3, rippledAccountLines.normal
}; );
mockRippled.addResponse("account_info", rippled.account_info.normal); this.mockRippled.addResponse("ledger", rippled.ledger.normal);
mockRippled.addResponse("account_lines", rippledAccountLines.normal); const expectedResponse = responses.getBalances
mockRippled.addResponse("ledger", rippled.ledger.normal); .filter((item) => item.currency === "USD")
.slice(0, 3);
const result = await this.client.getBalances(test.address, options);
assertResultMatch(result, expectedResponse, "getBalances");
});
const expectedResponse = responses.getBalances it("getBalances - limit & currency & issuer", async function () {
.filter( const options = {
(item) => currency: "USD",
item.currency === "USD" && counterparty: "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B",
item.counterparty === "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B" limit: 3,
) };
.slice(0, 3); this.mockRippled.addResponse(
const result = await client.getBalances(address, options); "account_info",
assertResultMatch(result, expectedResponse, "getBalances"); rippled.account_info.normal
}, );
}; this.mockRippled.addResponse(
"account_lines",
rippledAccountLines.normal
);
this.mockRippled.addResponse("ledger", rippled.ledger.normal);
const expectedResponse = responses.getBalances
.filter(
(item) =>
item.currency === "USD" &&
item.counterparty === "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B"
)
.slice(0, 3);
const result = await this.client.getBalances(test.address, options);
assertResultMatch(result, expectedResponse, "getBalances");
});
});
});
});

View File

@@ -1,65 +1,70 @@
import { assert } from "chai"; import { assert } from "chai";
import rippled from "../fixtures/rippled"; import rippled from "../fixtures/rippled";
import { TestSuite } from "../testUtils"; import setupClient from "../setupClient";
import { addressTests } from "../testUtils";
/** describe("client.getFee", function () {
* Every test suite exports their tests in the default object. beforeEach(setupClient.setup);
* - Check out the "TestSuite" type for documentation on the interface. afterEach(setupClient.teardown);
* - Check out "test/client/index.ts" for more information about the test runner.
*/
export default <TestSuite>{
async getFee(client, address, mockRippled) {
mockRippled.addResponse("server_info", rippled.server_info.normal);
const fee = await client.getFee();
assert.strictEqual(fee, "0.000012");
},
"getFee default": async (client, address, mockRippled) => { addressTests.forEach(function (test) {
mockRippled.addResponse("server_info", rippled.server_info.normal); describe(test.type, function () {
client._feeCushion = undefined as unknown as number; it("getFee", async function () {
const fee = await client.getFee(); this.mockRippled.addResponse("server_info", rippled.server_info.normal);
assert.strictEqual(fee, "0.000012"); const fee = await this.client.getFee();
}, assert.strictEqual(fee, "0.000012");
});
"getFee - high load_factor": async (client, address, mockRippled) => { it("getFee default", async function () {
mockRippled.addResponse("server_info", rippled.server_info.highLoadFactor); this.mockRippled.addResponse("server_info", rippled.server_info.normal);
const fee = await client.getFee(); this.client._feeCushion = undefined as unknown as number;
assert.strictEqual(fee, "2"); const fee = await this.client.getFee();
}, assert.strictEqual(fee, "0.000012");
});
"getFee - high load_factor with custom maxFeeXRP": async ( it("getFee - high load_factor", async function () {
client, this.mockRippled.addResponse(
address, "server_info",
mockRippled rippled.server_info.highLoadFactor
) => { );
mockRippled.addResponse("server_info", rippled.server_info.highLoadFactor); const fee = await this.client.getFee();
// Ensure that overriding with high maxFeeXRP of '51540' causes no errors. assert.strictEqual(fee, "2");
// (fee will actually be 51539.607552) });
client._maxFeeXRP = "51540";
const fee = await client.getFee();
assert.strictEqual(fee, "51539.607552");
},
"getFee custom cushion": async (client, address, mockRippled) => { it("getFee - high load_factor with custom maxFeeXRP", async function () {
mockRippled.addResponse("server_info", rippled.server_info.normal); this.mockRippled.addResponse(
client._feeCushion = 1.4; "server_info",
const fee = await client.getFee(); rippled.server_info.highLoadFactor
assert.strictEqual(fee, "0.000014"); );
}, // Ensure that overriding with high maxFeeXRP of '51540' causes no errors.
// (fee will actually be 51539.607552)
this.client._maxFeeXRP = "51540";
const fee = await this.client.getFee();
assert.strictEqual(fee, "51539.607552");
});
// This is not recommended since it may result in attempting to pay it("getFee custom cushion", async function () {
// less than the base fee. However, this test verifies the existing behavior. this.mockRippled.addResponse("server_info", rippled.server_info.normal);
"getFee cushion less than 1.0": async (client, address, mockRippled) => { this.client._feeCushion = 1.4;
mockRippled.addResponse("server_info", rippled.server_info.normal); const fee = await this.client.getFee();
client._feeCushion = 0.9; assert.strictEqual(fee, "0.000014");
const fee = await client.getFee(); });
assert.strictEqual(fee, "0.000009");
},
"getFee reporting": async (client, address, mockRippled) => { // This is not recommended since it may result in attempting to pay
mockRippled.addResponse("server_info", rippled.server_info.normal); // less than the base fee. However, this test verifies the existing behavior.
const fee = await client.getFee(); it("getFee cushion less than 1.0", async function () {
assert.strictEqual(fee, "0.000012"); this.mockRippled.addResponse("server_info", rippled.server_info.normal);
}, this.client._feeCushion = 0.9;
}; const fee = await this.client.getFee();
assert.strictEqual(fee, "0.000009");
});
it("getFee reporting", async function () {
this.mockRippled.addResponse("server_info", rippled.server_info.normal);
const fee = await this.client.getFee();
assert.strictEqual(fee, "0.000012");
});
});
});
});

View File

@@ -4,7 +4,8 @@ import { BookOffersRequest } from "../../src";
import requests from "../fixtures/requests"; import requests from "../fixtures/requests";
import responses from "../fixtures/responses"; import responses from "../fixtures/responses";
import rippled from "../fixtures/rippled"; import rippled from "../fixtures/rippled";
import { TestSuite, assertResultMatch, assertRejects } from "../testUtils"; import setupClient from "../setupClient";
import { addressTests, assertResultMatch, assertRejects } from "../testUtils";
// import BigNumber from 'bignumber.js' // import BigNumber from 'bignumber.js'
// function checkSortingOfOrders(orders) { // function checkSortingOfOrders(orders) {
@@ -81,137 +82,136 @@ function xrpRippledResponse(request: BookOffersRequest): object {
throw new Error("unexpected end"); throw new Error("unexpected end");
} }
/** describe("client.getOrderbook", function () {
* Every test suite exports their tests in the default object. beforeEach(setupClient.setup);
* - Check out the "TestSuite" type for documentation on the interface. afterEach(setupClient.teardown);
* - Check out "test/client/index.ts" for more information about the test runner.
*/
export default <TestSuite>{
async normal(client, address, mockRippled) {
mockRippled.addResponse("book_offers", normalRippledResponse);
const response = await client.getOrderbook(
address,
requests.getOrderbook.normal,
{ limit: 20 }
);
assertResultMatch(response, responses.getOrderbook.normal, "getOrderbook");
},
"invalid options": async (client, address, mockRippled) => { addressTests.forEach(function (test) {
mockRippled.addResponse("book_offers", normalRippledResponse); describe(test.type, function () {
assertRejects( it("normal", async function () {
client.getOrderbook(address, requests.getOrderbook.normal, { this.mockRippled.addResponse("book_offers", normalRippledResponse);
// @ts-expect-error const response = await this.client.getOrderbook(
invalid: "options", test.address,
}), requests.getOrderbook.normal,
client.errors.ValidationError { limit: 20 }
); );
}, assertResultMatch(
response,
responses.getOrderbook.normal,
"getOrderbook"
);
});
"with XRP": async (client, address, mockRippled) => { it("invalid options", async function () {
mockRippled.addResponse("book_offers", xrpRippledResponse); this.mockRippled.addResponse("book_offers", normalRippledResponse);
const response = await client.getOrderbook( assertRejects(
address, this.client.getOrderbook(test.address, requests.getOrderbook.normal, {
requests.getOrderbook.withXRP invalid: "options",
); }),
assertResultMatch(response, responses.getOrderbook.withXRP, "getOrderbook"); this.client.errors.ValidationError
}, );
});
// 'sample XRP/JPY book has orders sorted correctly': async (client, address, mockRippled) => { it("with XRP", async function () {
// const orderbookInfo = { this.mockRippled.addResponse("book_offers", xrpRippledResponse);
// base: { const response = await this.client.getOrderbook(
// // the first currency in pair test.address,
// currency: 'XRP' requests.getOrderbook.withXRP
// }, );
// counter: { assertResultMatch(
// currency: 'JPY', response,
// counterparty: 'rB3gZey7VWHYRqJHLoHDEJXJ2pEPNieKiS' responses.getOrderbook.withXRP,
// } "getOrderbook"
// } );
// const myAddress = 'rE9qNjzJXpiUbVomdv7R4xhrXVeH2oVmGR' });
// const response = await client.getOrderbook(myAddress, orderbookInfo)
// assert.deepStrictEqual([], response.bids)
// checkSortingOfOrders(response.asks)
// },
// 'sample USD/XRP book has orders sorted correctly': async (client, address, mockRippled) => { // 'sample XRP/JPY book has orders sorted correctly', async function () {
// const orderbookInfo = { // const orderbookInfo = {
// counter: {currency: 'XRP'}, // base: {
// base: { // // the first currency in pair
// currency: 'USD', // currency: 'XRP'
// counterparty: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B' // },
// } // counter: {
// } // currency: 'JPY',
// const myAddress = 'rE9qNjzJXpiUbVomdv7R4xhrXVeH2oVmGR' // counterparty: 'rB3gZey7VWHYRqJHLoHDEJXJ2pEPNieKiS'
// const response = await client.getOrderbook(myAddress, orderbookInfo) // }
// checkSortingOfOrders(response.bids) // }
// checkSortingOfOrders(response.asks) // const myAddress = 'rE9qNjzJXpiUbVomdv7R4xhrXVeH2oVmGR'
// }, // const response = await this.client.getOrderbook(myAddress, orderbookInfo)
// assert.deepStrictEqual([], response.bids)
// checkSortingOfOrders(response.asks)
// },
// WARNING: This test fails to catch the sorting bug, issue #766 // 'sample USD/XRP book has orders sorted correctly', async function () {
"sorted so that best deals come first [bad test]": async ( // const orderbookInfo = {
client, // counter: {currency: 'XRP'},
address, // base: {
mockRippled // currency: 'USD',
) => { // counterparty: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B'
mockRippled.addResponse("book_offers", normalRippledResponse); // }
const response = await client.getOrderbook( // }
address, // const myAddress = 'rE9qNjzJXpiUbVomdv7R4xhrXVeH2oVmGR'
requests.getOrderbook.normal // const response = await this.client.getOrderbook(myAddress, orderbookInfo)
); // checkSortingOfOrders(response.bids)
const bidRates = response.bids.map( // checkSortingOfOrders(response.asks)
(bid) => bid.properties.makerExchangeRate // },
);
const askRates = response.asks.map(
(ask) => ask.properties.makerExchangeRate
);
// makerExchangeRate = quality = takerPays.value/takerGets.value
// so the best deal for the taker is the lowest makerExchangeRate
// bids and asks should be sorted so that the best deals come first
assert.deepEqual(
bidRates.sort((x) => Number(x)),
bidRates
);
assert.deepEqual(
askRates.sort((x) => Number(x)),
askRates
);
},
"currency & counterparty are correct": async ( // WARNING: This test fails to catch the sorting bug, issue #766
client, it("sorted so that best deals come first [bad test]", async function () {
address, this.mockRippled.addResponse("book_offers", normalRippledResponse);
mockRippled const response = await this.client.getOrderbook(
) => { test.address,
mockRippled.addResponse("book_offers", normalRippledResponse); requests.getOrderbook.normal
const response = await client.getOrderbook( );
address, const bidRates = response.bids.map(
requests.getOrderbook.normal (bid) => bid.properties.makerExchangeRate
); );
[...response.bids, ...response.asks].forEach((order) => { const askRates = response.asks.map(
const quantity = order.specification.quantity; (ask) => ask.properties.makerExchangeRate
const totalPrice = order.specification.totalPrice; );
const { base, counter } = requests.getOrderbook.normal; // makerExchangeRate = quality = takerPays.value/takerGets.value
assert.strictEqual(quantity.currency, base.currency); // so the best deal for the taker is the lowest makerExchangeRate
assert.strictEqual(quantity.counterparty, base.counterparty); // bids and asks should be sorted so that the best deals come first
assert.strictEqual(totalPrice.currency, counter.currency); assert.deepEqual(
assert.strictEqual(totalPrice.counterparty, counter.counterparty); bidRates.sort((x) => Number(x)),
bidRates
);
assert.deepEqual(
askRates.sort((x) => Number(x)),
askRates
);
});
it("currency & counterparty are correct", async function () {
this.mockRippled.addResponse("book_offers", normalRippledResponse);
const response = await this.client.getOrderbook(
test.address,
requests.getOrderbook.normal
);
[...response.bids, ...response.asks].forEach((order) => {
const quantity = order.specification.quantity;
const totalPrice = order.specification.totalPrice;
const { base, counter } = requests.getOrderbook.normal;
assert.strictEqual(quantity.currency, base.currency);
assert.strictEqual(quantity.counterparty, base.counterparty);
assert.strictEqual(totalPrice.currency, counter.currency);
assert.strictEqual(totalPrice.counterparty, counter.counterparty);
});
});
it("direction is correct for bids and asks", async function () {
this.mockRippled.addResponse("book_offers", normalRippledResponse);
const response = await this.client.getOrderbook(
test.address,
requests.getOrderbook.normal
);
assert(
response.bids.every((bid) => bid.specification.direction === "buy")
);
assert(
response.asks.every((ask) => ask.specification.direction === "sell")
);
});
}); });
}, });
});
"direction is correct for bids and asks": async (
client,
address,
mockRippled
) => {
mockRippled.addResponse("book_offers", normalRippledResponse);
const response = await client.getOrderbook(
address,
requests.getOrderbook.normal
);
assert(response.bids.every((bid) => bid.specification.direction === "buy"));
assert(
response.asks.every((ask) => ask.specification.direction === "sell")
);
},
};

View File

@@ -3,7 +3,8 @@ import { assert } from "chai";
import addresses from "../fixtures/addresses.json"; import addresses from "../fixtures/addresses.json";
import requests from "../fixtures/requests"; import requests from "../fixtures/requests";
import rippled from "../fixtures/rippled"; import rippled from "../fixtures/rippled";
import { assertRejects, TestSuite } from "../testUtils"; import setupClient from "../setupClient";
import { assertRejects } from "../testUtils";
// import responses from '../fixtures/responses' // import responses from '../fixtures/responses'
const { getPaths: REQUEST_FIXTURES } = requests; const { getPaths: REQUEST_FIXTURES } = requests;
// const {getPaths: RESPONSE_FIXTURES} = responses // const {getPaths: RESPONSE_FIXTURES} = responses
@@ -15,97 +16,94 @@ const rippledResponse = rippled.path_find.generate.generateIOUPaymentPaths(
REQUEST_FIXTURES.normal.destination.amount REQUEST_FIXTURES.normal.destination.amount
); );
/** describe("client.getPaths", function () {
* Every test suite exports their tests in the default object. beforeEach(setupClient.setup);
* - Check out the "TestSuite" type for documentation on the interface. afterEach(setupClient.teardown);
* - Check out "test/client/index.ts" for more information about the test runner. // 'simple test', function () {
*/ // const response = await this.client.getPaths(REQUEST_FIXTURES.normal)
export default <TestSuite>{
// 'simple test': async (client) => {
// const response = await client.getPaths(REQUEST_FIXTURES.normal)
// assertResultMatch(response, RESPONSE_FIXTURES.XrpToUsd, 'getPaths') // assertResultMatch(response, RESPONSE_FIXTURES.XrpToUsd, 'getPaths')
// }, // })
// 'queuing': async (client) => { // 'queuing', function () {
// const [normalResult, usdOnlyResult, xrpOnlyResult] = await Promise.all([ // const [normalResult, usdOnlyResult, xrpOnlyResult] = await Promise.all([
// client.getPaths(REQUEST_FIXTURES.normal), // this.client.getPaths(REQUEST_FIXTURES.normal),
// client.getPaths(REQUEST_FIXTURES.UsdToUsd), // this.client.getPaths(REQUEST_FIXTURES.UsdToUsd),
// client.getPaths(REQUEST_FIXTURES.XrpToXrp) // this.client.getPaths(REQUEST_FIXTURES.XrpToXrp)
// ]) // ])
// assertResultMatch(normalResult, RESPONSE_FIXTURES.XrpToUsd, 'getPaths') // assertResultMatch(normalResult, RESPONSE_FIXTURES.XrpToUsd, 'getPaths')
// assertResultMatch(usdOnlyResult, RESPONSE_FIXTURES.UsdToUsd, 'getPaths') // assertResultMatch(usdOnlyResult, RESPONSE_FIXTURES.UsdToUsd, 'getPaths')
// assertResultMatch(xrpOnlyResult, RESPONSE_FIXTURES.XrpToXrp, 'getPaths') // assertResultMatch(xrpOnlyResult, RESPONSE_FIXTURES.XrpToXrp, 'getPaths')
// }, // })
// // @TODO // // @TODO
// // need decide what to do with currencies/XRP: // // need decide what to do with currencies/XRP:
// // if add 'XRP' in currencies, then there will be exception in // // if add 'XRP' in currencies, then there will be exception in
// // xrpToDrops function (called from toRippledAmount) // // xrpToDrops function (called from toRippledAmount)
// 'getPaths USD 2 USD': async (client) => { // 'getPaths USD 2 USD', function () {
// const response = await client.getPaths(REQUEST_FIXTURES.UsdToUsd) // const response = await this.client.getPaths(REQUEST_FIXTURES.UsdToUsd)
// assertResultMatch(response, RESPONSE_FIXTURES.UsdToUsd, 'getPaths') // assertResultMatch(response, RESPONSE_FIXTURES.UsdToUsd, 'getPaths')
// }, // })
// 'getPaths XRP 2 XRP': async (client) => { // 'getPaths XRP 2 XRP', function () {
// const response = await client.getPaths(REQUEST_FIXTURES.XrpToXrp) // const response = await this.client.getPaths(REQUEST_FIXTURES.XrpToXrp)
// assertResultMatch(response, RESPONSE_FIXTURES.XrpToXrp, 'getPaths') // assertResultMatch(response, RESPONSE_FIXTURES.XrpToXrp, 'getPaths')
// }, // })
"source with issuer": async (client, _, mockRippled) => { it("source with issuer", function () {
mockRippled.addResponse("ripple_path_find", rippledResponse); this.mockRippled.addResponse("ripple_path_find", rippledResponse);
return assertRejects( return assertRejects(
client.getPaths(REQUEST_FIXTURES.issuer), this.client.getPaths(REQUEST_FIXTURES.issuer),
client.errors.NotFoundError this.client.errors.NotFoundError
); );
}, });
// 'XRP 2 XRP - not enough': async (client) => { // 'XRP 2 XRP - not enough', function () {
// return assertRejects( // return assertRejects(
// client.getPaths(REQUEST_FIXTURES.XrpToXrpNotEnough), // this.client.getPaths(REQUEST_FIXTURES.XrpToXrpNotEnough),
// client.errors.NotFoundError // this.client.errors.NotFoundError
// ) // )
// }, // })
"invalid PathFind": async (client, _, mockRippled) => { it("invalid PathFind", function () {
mockRippled.addResponse("ripple_path_find", rippledResponse); this.mockRippled.addResponse("ripple_path_find", rippledResponse);
assert.throws(() => { assert.throws(() => {
client.getPaths(REQUEST_FIXTURES.invalid); this.client.getPaths(REQUEST_FIXTURES.invalid);
}, /Cannot specify both source.amount/); }, /Cannot specify both source.amount/);
}, });
"does not accept currency": async (client, _, mockRippled) => { it("does not accept currency", function () {
mockRippled.addResponse("ripple_path_find", rippledResponse); this.mockRippled.addResponse("ripple_path_find", rippledResponse);
return assertRejects( return assertRejects(
client.getPaths(REQUEST_FIXTURES.NotAcceptCurrency), this.client.getPaths(REQUEST_FIXTURES.NotAcceptCurrency),
client.errors.NotFoundError this.client.errors.NotFoundError
); );
}, });
"no paths": async (client, _, mockRippled) => { it("no paths", function () {
mockRippled.addResponse("ripple_path_find", rippledResponse); this.mockRippled.addResponse("ripple_path_find", rippledResponse);
return assertRejects( return assertRejects(
client.getPaths(REQUEST_FIXTURES.NoPaths), this.client.getPaths(REQUEST_FIXTURES.NoPaths),
client.errors.NotFoundError this.client.errors.NotFoundError
); );
}, });
"no paths source amount": async (client, _, mockRippled) => { it("no paths source amount", function () {
mockRippled.addResponse("ripple_path_find", rippledResponse); this.mockRippled.addResponse("ripple_path_find", rippledResponse);
return assertRejects( return assertRejects(
client.getPaths(REQUEST_FIXTURES.NoPathsSource), this.client.getPaths(REQUEST_FIXTURES.NoPathsSource),
client.errors.NotFoundError this.client.errors.NotFoundError
); );
}, });
"no paths with source currencies": async (client, _, mockRippled) => { it("no paths with source currencies", function () {
mockRippled.addResponse("ripple_path_find", rippledResponse); this.mockRippled.addResponse("ripple_path_find", rippledResponse);
return assertRejects( return assertRejects(
client.getPaths(REQUEST_FIXTURES.NoPathsWithCurrencies), this.client.getPaths(REQUEST_FIXTURES.NoPathsWithCurrencies),
client.errors.NotFoundError this.client.errors.NotFoundError
); );
}, });
"error: srcActNotFound": async (client, _, mockRippled) => { it("error: srcActNotFound", function () {
mockRippled.addResponse("ripple_path_find", rippledResponse); this.mockRippled.addResponse("ripple_path_find", rippledResponse);
return assertRejects( return assertRejects(
client.getPaths({ this.client.getPaths({
...REQUEST_FIXTURES.normal, ...REQUEST_FIXTURES.normal,
source: { address: addresses.NOTFOUND }, source: { address: addresses.NOTFOUND },
}), }),
client.errors.RippleError this.client.errors.RippleError
); );
}, });
// 'send all': async (client) => { // 'send all', function () {
// const response = await client.getPaths(REQUEST_FIXTURES.sendAll) // const response = await this.client.getPaths(REQUEST_FIXTURES.sendAll)
// assertResultMatch(response, RESPONSE_FIXTURES.sendAll, 'getPaths') // assertResultMatch(response, RESPONSE_FIXTURES.sendAll, 'getPaths')
// } // })
}; });

View File

@@ -1,70 +1,60 @@
import addresses from "../fixtures/addresses.json";
import responses from "../fixtures/responses"; import responses from "../fixtures/responses";
import rippled from "../fixtures/rippled/accountLines"; import rippled from "../fixtures/rippled/accountLines";
import { assertResultMatch, TestSuite } from "../testUtils"; import setupClient from "../setupClient";
import { assertResultMatch, addressTests } from "../testUtils";
const { getTrustlines: RESPONSE_FIXTURES } = responses; const { getTrustlines: RESPONSE_FIXTURES } = responses;
/** describe("client.getTrustlines", function () {
* Every test suite exports their tests in the default object. beforeEach(setupClient.setup);
* - Check out the "TestSuite" type for documentation on the interface. afterEach(setupClient.teardown);
* - Check out "test/client/index.ts" for more information about the test runner.
*/
export default <TestSuite>{
"getTrustlines - filtered": async (client, address, mockRippled) => {
mockRippled.addResponse("account_lines", rippled.normal);
const options = { currency: "USD" };
const result = await client.getTrustlines(address, options);
assertResultMatch(result, RESPONSE_FIXTURES.filtered, "getTrustlines");
},
"getTrustlines - more than 400 items": async ( addressTests.forEach(function (test) {
client, describe(test.type, function () {
address, it("getTrustlines - filtered", async function () {
mockRippled this.mockRippled.addResponse("account_lines", rippled.normal);
) => { const options = { currency: "USD" };
mockRippled.addResponse("account_lines", rippled.manyItems); const result = await this.client.getTrustlines(test.address, options);
const options = { limit: 401 }; assertResultMatch(result, RESPONSE_FIXTURES.filtered, "getTrustlines");
const result = await client.getTrustlines(address, options); });
assertResultMatch(
result,
RESPONSE_FIXTURES.moreThan400Items,
"getTrustlines"
);
},
"getTrustlines - no options": async (client, address, mockRippled) => { it("getTrustlines - more than 400 items", async function () {
mockRippled.addResponse("account_lines", rippled.normal); this.mockRippled.addResponse("account_lines", rippled.manyItems);
await client.getTrustlines(address); const options = { limit: 401 };
}, const result = await this.client.getTrustlines(test.address, options);
assertResultMatch(
result,
RESPONSE_FIXTURES.moreThan400Items,
"getTrustlines"
);
});
"getTrustlines - ripplingDisabled works properly": async ( it("getTrustlines - no options", async function () {
client, this.mockRippled.addResponse("account_lines", rippled.normal);
address, await this.client.getTrustlines(test.address);
mockRippled });
) => {
mockRippled.addResponse("account_lines", rippled.ripplingDisabled);
const result = await client.getTrustlines(address);
assertResultMatch(
result,
RESPONSE_FIXTURES.ripplingDisabled,
"getTrustlines"
);
},
"getTrustlines - ledger version option": async ( it("getTrustlines - ripplingDisabled works properly", async function () {
client, this.mockRippled.addResponse("account_lines", rippled.ripplingDisabled);
address, const result = await this.client.getTrustlines(test.address);
mockRippled assertResultMatch(
) => { result,
mockRippled.addResponse("account_lines", rippled.manyItems); RESPONSE_FIXTURES.ripplingDisabled,
const result = await client.getTrustlines(addresses.FOURTH_ACCOUNT, { "getTrustlines"
ledgerVersion: 5, );
});
it("getTrustlines - ledger version option", async function () {
this.mockRippled.addResponse("account_lines", rippled.manyItems);
const result = await this.client.getTrustlines(test.address, {
ledgerVersion: 5,
});
assertResultMatch(
result,
RESPONSE_FIXTURES.moreThan400Items,
"getTrustlines"
);
});
}); });
assertResultMatch( });
result, });
RESPONSE_FIXTURES.moreThan400Items,
"getTrustlines"
);
},
};

View File

@@ -1,41 +1,31 @@
import { assert } from "chai"; import { assert } from "chai";
import rippled from "../fixtures/rippled"; import rippled from "../fixtures/rippled";
import { TestSuite } from "../testUtils"; import setupClient from "../setupClient";
/** describe("client.hasNextPage", function () {
* Every test suite exports their tests in the default object. beforeEach(setupClient.setup);
* - Check out the "TestSuite" type for documentation on the interface. afterEach(setupClient.teardown);
* - Check out "test/client/index.ts" for more information about the test runner.
*/
export default <TestSuite>{
"returns true when there is another page": async (
client,
address,
mockRippled
) => {
mockRippled.addResponse("ledger_data", rippled.ledger_data.first_page);
const response = await client.request({ command: "ledger_data" });
assert(client.hasNextPage(response));
},
"returns false when there are no more pages": async ( it("returns true when there is another page", async function () {
client, this.mockRippled.addResponse("ledger_data", rippled.ledger_data.first_page);
address, const response = await this.client.request({ command: "ledger_data" });
mockRippled assert(this.client.hasNextPage(response));
) => { });
it("returns false when there are no more pages", async function () {
const rippledResponse = function (request: Request): object { const rippledResponse = function (request: Request): object {
if ("marker" in request) { if ("marker" in request) {
return rippled.ledger_data.last_page; return rippled.ledger_data.last_page;
} }
return rippled.ledger_data.first_page; return rippled.ledger_data.first_page;
}; };
mockRippled.addResponse("ledger_data", rippledResponse); this.mockRippled.addResponse("ledger_data", rippledResponse);
const response = await client.request({ command: "ledger_data" }); const response = await this.client.request({ command: "ledger_data" });
const responseNextPage = await client.requestNextPage( const responseNextPage = await this.client.requestNextPage(
{ command: "ledger_data" }, { command: "ledger_data" },
response response
); );
assert(!client.hasNextPage(responseNextPage)); assert(!this.client.hasNextPage(responseNextPage));
}, });
}; });

View File

@@ -1,16 +1,14 @@
import { assert } from "chai"; import { assert } from "chai";
import { TestSuite } from "../testUtils"; import setupClient from "../setupClient";
/** describe("client.isConnected", function () {
* Every test suite exports their tests in the default object. beforeEach(setupClient.setup);
* - Check out the "TestSuite" type for documentation on the interface. afterEach(setupClient.teardown);
* - Check out "test/client/index.ts" for more information about the test runner.
*/ it("disconnect & isConnected", async function () {
export default <TestSuite>{ assert.strictEqual(this.client.isConnected(), true);
"disconnect & isConnected": async (client, address) => { await this.client.disconnect();
assert.strictEqual(client.isConnected(), true); assert.strictEqual(this.client.isConnected(), false);
await client.disconnect(); });
assert.strictEqual(client.isConnected(), false); });
},
};

View File

@@ -1,18 +1,21 @@
import { assert } from "chai"; import { assert } from "chai";
import addresses from "../fixtures/addresses.json"; import addresses from "../fixtures/addresses.json";
import { TestSuite } from "../testUtils"; import setupClient from "../setupClient";
export default <TestSuite>{ describe("isValidAddress", function () {
"returns true for valid address": async (client, address) => { beforeEach(setupClient.setup);
assert(client.isValidAddress("rLczgQHxPhWtjkaQqn3Q6UM8AbRbbRvs5K")); afterEach(setupClient.teardown);
assert(client.isValidAddress(addresses.ACCOUNT_X));
assert(client.isValidAddress(addresses.ACCOUNT_T));
},
"returns false for invalid address": async (client, address) => { it("returns true for valid address", async function () {
assert(!client.isValidAddress("foobar")); assert(this.client.isValidAddress("rLczgQHxPhWtjkaQqn3Q6UM8AbRbbRvs5K"));
assert(!client.isValidAddress(addresses.ACCOUNT_X.slice(0, -1))); assert(this.client.isValidAddress(addresses.ACCOUNT_X));
assert(!client.isValidAddress(addresses.ACCOUNT_T.slice(1))); assert(this.client.isValidAddress(addresses.ACCOUNT_T));
}, });
};
it("returns false for invalid address", async function () {
assert(!this.client.isValidAddress("foobar"));
assert(!this.client.isValidAddress(addresses.ACCOUNT_X.slice(0, -1)));
assert(!this.client.isValidAddress(addresses.ACCOUNT_T.slice(1)));
});
});

View File

@@ -1,13 +1,16 @@
import { assert } from "chai"; import { assert } from "chai";
import { TestSuite } from "../testUtils"; import setupClient from "../setupClient";
export default <TestSuite>{ describe("isValidSecret", function () {
"returns true for valid secret": async (client, address) => { beforeEach(setupClient.setup);
assert(client.isValidSecret("snsakdSrZSLkYpCXxfRkS4Sh96PMK")); afterEach(setupClient.teardown);
},
"returns false for invalid secret": async (client, address) => { it("returns true for valid secret", async function () {
assert(!client.isValidSecret("foobar")); assert(this.client.isValidSecret("snsakdSrZSLkYpCXxfRkS4Sh96PMK"));
}, });
};
it("returns false for invalid secret", async function () {
assert(!this.client.isValidSecret("foobar"));
});
});

View File

@@ -1,43 +1,60 @@
import requests from "../fixtures/requests"; import requests from "../fixtures/requests";
import responses from "../fixtures/responses"; import responses from "../fixtures/responses";
import rippled from "../fixtures/rippled"; import rippled from "../fixtures/rippled";
import { assertResultMatch, TestSuite } from "../testUtils"; import setupClient from "../setupClient";
import { assertResultMatch, addressTests } from "../testUtils";
const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 }; const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 };
/** describe("client.prepareCheckCancel", function () {
* Every test suite exports their tests in the default object. beforeEach(setupClient.setup);
* - Check out the "TestSuite" type for documentation on the interface. afterEach(setupClient.teardown);
* - Check out "test/client/index.ts" for more information about the test runner.
*/
export default <TestSuite>{
async prepareCheckCancel(client, address, mockRippled) {
mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal);
const result = await client.prepareCheckCancel(
address,
requests.prepareCheckCancel.normal
);
assertResultMatch(result, responses.prepareCheckCancel.normal, "prepare");
},
"with ticket": async (client, address, mockRippled) => { addressTests.forEach(function (test) {
mockRippled.addResponse("server_info", rippled.server_info.normal); describe(test.type, function () {
mockRippled.addResponse("fee", rippled.fee); it("prepareCheckCancel", async function () {
mockRippled.addResponse("ledger_current", rippled.ledger_current); this.mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("account_info", rippled.account_info.normal); this.mockRippled.addResponse("fee", rippled.fee);
const localInstructions = { this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
...instructionsWithMaxLedgerVersionOffset, this.mockRippled.addResponse(
maxFee: "0.000012", "account_info",
ticketSequence: 23, rippled.account_info.normal
}; );
const result = await client.prepareCheckCancel( const result = await this.client.prepareCheckCancel(
address, test.address,
requests.prepareCheckCancel.normal, requests.prepareCheckCancel.normal
localInstructions );
); assertResultMatch(
assertResultMatch(result, responses.prepareCheckCancel.ticket, "prepare"); result,
}, responses.prepareCheckCancel.normal,
}; "prepare"
);
});
it("with ticket", async function () {
this.mockRippled.addResponse("server_info", rippled.server_info.normal);
this.mockRippled.addResponse("fee", rippled.fee);
this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
this.mockRippled.addResponse(
"account_info",
rippled.account_info.normal
);
const localInstructions = {
...instructionsWithMaxLedgerVersionOffset,
maxFee: "0.000012",
ticketSequence: 23,
};
const result = await this.client.prepareCheckCancel(
test.address,
requests.prepareCheckCancel.normal,
localInstructions
);
assertResultMatch(
result,
responses.prepareCheckCancel.ticket,
"prepare"
);
});
});
});
});

View File

@@ -1,55 +1,71 @@
import requests from "../fixtures/requests"; import requests from "../fixtures/requests";
import responses from "../fixtures/responses"; import responses from "../fixtures/responses";
import rippled from "../fixtures/rippled"; import rippled from "../fixtures/rippled";
import { assertResultMatch, TestSuite } from "../testUtils"; import setupClient from "../setupClient";
import { assertResultMatch, addressTests } from "../testUtils";
const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 }; const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 };
/** describe("client.prepareCheckCash", function () {
* Every test suite exports their tests in the default object. beforeEach(setupClient.setup);
* - Check out the "TestSuite" type for documentation on the interface. afterEach(setupClient.teardown);
* - Check out "test/client/index.ts" for more information about the test runner.
*/
export default <TestSuite>{
"prepareCheckCash amount": async (client, address, mockRippled) => {
mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal);
const result = await client.prepareCheckCash(
address,
requests.prepareCheckCash.amount
);
assertResultMatch(result, responses.prepareCheckCash.amount, "prepare");
},
"prepareCheckCash deliverMin": async (client, address, mockRippled) => { addressTests.forEach(function (test) {
mockRippled.addResponse("server_info", rippled.server_info.normal); describe(test.type, function () {
mockRippled.addResponse("fee", rippled.fee); it("prepareCheckCash amount", async function () {
mockRippled.addResponse("ledger_current", rippled.ledger_current); this.mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("account_info", rippled.account_info.normal); this.mockRippled.addResponse("fee", rippled.fee);
const result = await client.prepareCheckCash( this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
address, this.mockRippled.addResponse(
requests.prepareCheckCash.deliverMin "account_info",
); rippled.account_info.normal
assertResultMatch(result, responses.prepareCheckCash.deliverMin, "prepare"); );
}, const result = await this.client.prepareCheckCash(
test.address,
requests.prepareCheckCash.amount
);
assertResultMatch(result, responses.prepareCheckCash.amount, "prepare");
});
"with ticket": async (client, address, mockRippled) => { it("prepareCheckCash deliverMin", async function () {
mockRippled.addResponse("server_info", rippled.server_info.normal); this.mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee); this.mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current); this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal); this.mockRippled.addResponse(
const localInstructions = { "account_info",
...instructionsWithMaxLedgerVersionOffset, rippled.account_info.normal
maxFee: "0.000012", );
ticketSequence: 23, const result = await this.client.prepareCheckCash(
}; test.address,
const result = await client.prepareCheckCash( requests.prepareCheckCash.deliverMin
address, );
requests.prepareCheckCash.amount, assertResultMatch(
localInstructions result,
); responses.prepareCheckCash.deliverMin,
assertResultMatch(result, responses.prepareCheckCash.ticket, "prepare"); "prepare"
}, );
}; });
it("with ticket", async function () {
this.mockRippled.addResponse("server_info", rippled.server_info.normal);
this.mockRippled.addResponse("fee", rippled.fee);
this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
this.mockRippled.addResponse(
"account_info",
rippled.account_info.normal
);
const localInstructions = {
...instructionsWithMaxLedgerVersionOffset,
maxFee: "0.000012",
ticketSequence: 23,
};
const result = await this.client.prepareCheckCash(
test.address,
requests.prepareCheckCash.amount,
localInstructions
);
assertResultMatch(result, responses.prepareCheckCash.ticket, "prepare");
});
});
});
});

View File

@@ -1,60 +1,80 @@
import requests from "../fixtures/requests"; import requests from "../fixtures/requests";
import responses from "../fixtures/responses"; import responses from "../fixtures/responses";
import rippled from "../fixtures/rippled"; import rippled from "../fixtures/rippled";
import { assertResultMatch, TestSuite } from "../testUtils"; import setupClient from "../setupClient";
import { assertResultMatch, addressTests } from "../testUtils";
const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 }; const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 };
/** describe("client.prepareCheckCreate", function () {
* Every test suite exports their tests in the default object. beforeEach(setupClient.setup);
* - Check out the "TestSuite" type for documentation on the interface. afterEach(setupClient.teardown);
* - Check out "test/client/index.ts" for more information about the test runner.
*/
export default <TestSuite>{
async prepareCheckCreate(client, address, mockRippled) {
mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal);
const localInstructions = {
...instructionsWithMaxLedgerVersionOffset,
maxFee: "0.000012",
};
const result = await client.prepareCheckCreate(
address,
requests.prepareCheckCreate.normal,
localInstructions
);
assertResultMatch(result, responses.prepareCheckCreate.normal, "prepare");
},
"prepareCheckCreate full": async (client, address, mockRippled) => { addressTests.forEach(function (test) {
mockRippled.addResponse("server_info", rippled.server_info.normal); describe(test.type, function () {
mockRippled.addResponse("fee", rippled.fee); it("prepareCheckCreate", async function () {
mockRippled.addResponse("ledger_current", rippled.ledger_current); this.mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("account_info", rippled.account_info.normal); this.mockRippled.addResponse("fee", rippled.fee);
const result = await client.prepareCheckCreate( this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
address, this.mockRippled.addResponse(
requests.prepareCheckCreate.full "account_info",
); rippled.account_info.normal
assertResultMatch(result, responses.prepareCheckCreate.full, "prepare"); );
}, const localInstructions = {
...instructionsWithMaxLedgerVersionOffset,
maxFee: "0.000012",
};
const result = await this.client.prepareCheckCreate(
test.address,
requests.prepareCheckCreate.normal,
localInstructions
);
assertResultMatch(
result,
responses.prepareCheckCreate.normal,
"prepare"
);
});
"prepareCheckCreate with ticket": async (client, address, mockRippled) => { it("prepareCheckCreate full", async function () {
mockRippled.addResponse("server_info", rippled.server_info.normal); this.mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee); this.mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current); this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal); this.mockRippled.addResponse(
const localInstructions = { "account_info",
...instructionsWithMaxLedgerVersionOffset, rippled.account_info.normal
maxFee: "0.000012", );
ticketSequence: 23, const result = await this.client.prepareCheckCreate(
}; test.address,
const result = await client.prepareCheckCreate( requests.prepareCheckCreate.full
address, );
requests.prepareCheckCreate.normal, assertResultMatch(result, responses.prepareCheckCreate.full, "prepare");
localInstructions });
);
assertResultMatch(result, responses.prepareCheckCreate.ticket, "prepare"); it("prepareCheckCreate with ticket", async function () {
}, this.mockRippled.addResponse("server_info", rippled.server_info.normal);
}; this.mockRippled.addResponse("fee", rippled.fee);
this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
this.mockRippled.addResponse(
"account_info",
rippled.account_info.normal
);
const localInstructions = {
...instructionsWithMaxLedgerVersionOffset,
maxFee: "0.000012",
ticketSequence: 23,
};
const result = await this.client.prepareCheckCreate(
test.address,
requests.prepareCheckCreate.normal,
localInstructions
);
assertResultMatch(
result,
responses.prepareCheckCreate.ticket,
"prepare"
);
});
});
});
});

View File

@@ -1,72 +1,80 @@
import requests from "../fixtures/requests"; import requests from "../fixtures/requests";
import responses from "../fixtures/responses"; import responses from "../fixtures/responses";
import rippled from "../fixtures/rippled"; import rippled from "../fixtures/rippled";
import { assertResultMatch, TestSuite } from "../testUtils"; import setupClient from "../setupClient";
import { assertResultMatch, addressTests } from "../testUtils";
const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 }; const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 };
/** describe("client.prepareEscrowCancellation", function () {
* Every test suite exports their tests in the default object. beforeEach(setupClient.setup);
* - Check out the "TestSuite" type for documentation on the interface. afterEach(setupClient.teardown);
* - Check out "test/client/index.ts" for more information about the test runner.
*/
export default <TestSuite>{
async prepareEscrowCancellation(client, address, mockRippled) {
mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal);
const result = await client.prepareEscrowCancellation(
address,
requests.prepareEscrowCancellation.normal,
instructionsWithMaxLedgerVersionOffset
);
assertResultMatch(
result,
responses.prepareEscrowCancellation.normal,
"prepare"
);
},
"prepareEscrowCancellation with memos": async ( addressTests.forEach(function (test) {
client, describe(test.type, function () {
address, it("prepareEscrowCancellation", async function () {
mockRippled this.mockRippled.addResponse("server_info", rippled.server_info.normal);
) => { this.mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("server_info", rippled.server_info.normal); this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("fee", rippled.fee); this.mockRippled.addResponse(
mockRippled.addResponse("ledger_current", rippled.ledger_current); "account_info",
mockRippled.addResponse("account_info", rippled.account_info.normal); rippled.account_info.normal
const result = await client.prepareEscrowCancellation( );
address, const result = await this.client.prepareEscrowCancellation(
requests.prepareEscrowCancellation.memos test.address,
); requests.prepareEscrowCancellation.normal,
assertResultMatch( instructionsWithMaxLedgerVersionOffset
result, );
responses.prepareEscrowCancellation.memos, assertResultMatch(
"prepare" result,
); responses.prepareEscrowCancellation.normal,
}, "prepare"
);
});
"with ticket": async (client, address, mockRippled) => { it("prepareEscrowCancellation with memos", async function () {
mockRippled.addResponse("server_info", rippled.server_info.normal); this.mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee); this.mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current); this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal); this.mockRippled.addResponse(
const localInstructions = { "account_info",
...instructionsWithMaxLedgerVersionOffset, rippled.account_info.normal
maxFee: "0.000012", );
ticketSequence: 23, const result = await this.client.prepareEscrowCancellation(
}; test.address,
const result = await client.prepareEscrowCancellation( requests.prepareEscrowCancellation.memos
address, );
requests.prepareEscrowCancellation.normal, assertResultMatch(
localInstructions result,
); responses.prepareEscrowCancellation.memos,
assertResultMatch( "prepare"
result, );
responses.prepareEscrowCancellation.ticket, });
"prepare"
); it("with ticket", async function () {
}, this.mockRippled.addResponse("server_info", rippled.server_info.normal);
}; this.mockRippled.addResponse("fee", rippled.fee);
this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
this.mockRippled.addResponse(
"account_info",
rippled.account_info.normal
);
const localInstructions = {
...instructionsWithMaxLedgerVersionOffset,
maxFee: "0.000012",
ticketSequence: 23,
};
const result = await this.client.prepareEscrowCancellation(
test.address,
requests.prepareEscrowCancellation.normal,
localInstructions
);
assertResultMatch(
result,
responses.prepareEscrowCancellation.ticket,
"prepare"
);
});
});
});
});

View File

@@ -1,7 +1,9 @@
import addresses from "../fixtures/addresses.json";
import requests from "../fixtures/requests"; import requests from "../fixtures/requests";
import responses from "../fixtures/responses"; import responses from "../fixtures/responses";
import rippled from "../fixtures/rippled"; import rippled from "../fixtures/rippled";
import { assertRejects, assertResultMatch, TestSuite } from "../testUtils"; import setupClient from "../setupClient";
import { assertRejects, assertResultMatch } from "../testUtils";
const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 }; const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 };
@@ -12,23 +14,21 @@ export const config = {
skipXAddress: true, skipXAddress: true,
}; };
/** describe("client.prepareEscrowCreation", function () {
* Every test suite exports their tests in the default object. beforeEach(setupClient.setup);
* - Check out the "TestSuite" type for documentation on the interface. afterEach(setupClient.teardown);
* - Check out "test/client/index.ts" for more information about the test runner.
*/ it("prepareEscrowCreation", async function () {
export default <TestSuite>{ this.mockRippled.addResponse("server_info", rippled.server_info.normal);
async prepareEscrowCreation(client, address, mockRippled) { this.mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("server_info", rippled.server_info.normal); this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("fee", rippled.fee); this.mockRippled.addResponse("account_info", rippled.account_info.normal);
mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal);
const localInstructions = { const localInstructions = {
...instructionsWithMaxLedgerVersionOffset, ...instructionsWithMaxLedgerVersionOffset,
maxFee: "0.000012", maxFee: "0.000012",
}; };
const result = await client.prepareEscrowCreation( const result = await this.client.prepareEscrowCreation(
address, addresses.ACCOUNT,
requests.prepareEscrowCreation.normal, requests.prepareEscrowCreation.normal,
localInstructions localInstructions
); );
@@ -37,46 +37,46 @@ export default <TestSuite>{
responses.prepareEscrowCreation.normal, responses.prepareEscrowCreation.normal,
"prepare" "prepare"
); );
}, });
"prepareEscrowCreation full": async (client, address, mockRippled) => { it("prepareEscrowCreation full", async function () {
mockRippled.addResponse("server_info", rippled.server_info.normal); this.mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee); this.mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current); this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal); this.mockRippled.addResponse("account_info", rippled.account_info.normal);
const result = await client.prepareEscrowCreation( const result = await this.client.prepareEscrowCreation(
address, addresses.ACCOUNT,
requests.prepareEscrowCreation.full requests.prepareEscrowCreation.full
); );
assertResultMatch(result, responses.prepareEscrowCreation.full, "prepare"); assertResultMatch(result, responses.prepareEscrowCreation.full, "prepare");
}, });
"prepareEscrowCreation - invalid": async (client, address, mockRippled) => { it("prepareEscrowCreation - invalid", async function () {
mockRippled.addResponse("server_info", rippled.server_info.normal); this.mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee); this.mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current); this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal); this.mockRippled.addResponse("account_info", rippled.account_info.normal);
const escrow = { ...requests.prepareEscrowCreation.full }; const escrow = { ...requests.prepareEscrowCreation.full };
delete escrow.amount; // Make invalid delete escrow.amount; // Make invalid
await assertRejects( await assertRejects(
client.prepareEscrowCreation(address, escrow), this.client.prepareEscrowCreation(addresses.ACCOUNT, escrow),
client.errors.ValidationError, this.client.errors.ValidationError,
'instance.escrowCreation requires property "amount"' 'instance.escrowCreation requires property "amount"'
); );
}, });
"with ticket": async (client, address, mockRippled) => { it("with ticket", async function () {
mockRippled.addResponse("server_info", rippled.server_info.normal); this.mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee); this.mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current); this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal); this.mockRippled.addResponse("account_info", rippled.account_info.normal);
const localInstructions = { const localInstructions = {
...instructionsWithMaxLedgerVersionOffset, ...instructionsWithMaxLedgerVersionOffset,
maxFee: "0.000396", maxFee: "0.000396",
ticketSequence: 23, ticketSequence: 23,
}; };
const result = await client.prepareEscrowCreation( const result = await this.client.prepareEscrowCreation(
address, addresses.ACCOUNT,
requests.prepareEscrowCreation.normal, requests.prepareEscrowCreation.normal,
localInstructions localInstructions
); );
@@ -85,5 +85,5 @@ export default <TestSuite>{
responses.prepareEscrowCreation.ticket, responses.prepareEscrowCreation.ticket,
"prepare" "prepare"
); );
}, });
}; });

View File

@@ -1,108 +1,118 @@
import requests from "../fixtures/requests"; import requests from "../fixtures/requests";
import responses from "../fixtures/responses"; import responses from "../fixtures/responses";
import rippled from "../fixtures/rippled"; import rippled from "../fixtures/rippled";
import { TestSuite, assertRejects, assertResultMatch } from "../testUtils"; import setupClient from "../setupClient";
import { addressTests, assertRejects, assertResultMatch } from "../testUtils";
const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 }; const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 };
/** describe("client.prepareEscrowExecution", function () {
* Every test suite exports their tests in the default object. beforeEach(setupClient.setup);
* - Check out the "TestSuite" type for documentation on the interface. afterEach(setupClient.teardown);
* - Check out "test/client/index.ts" for more information about the test runner.
*/
export default <TestSuite>{
async prepareEscrowExecution(client, address, mockRippled) {
mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal);
const result = await client.prepareEscrowExecution(
address,
requests.prepareEscrowExecution.normal,
instructionsWithMaxLedgerVersionOffset
);
assertResultMatch(
result,
responses.prepareEscrowExecution.normal,
"prepare"
);
},
"prepareEscrowExecution - simple": async (client, address, mockRippled) => { addressTests.forEach(function (test) {
mockRippled.addResponse("server_info", rippled.server_info.normal); describe(test.type, function () {
mockRippled.addResponse("fee", rippled.fee); it("prepareEscrowExecution", async function () {
mockRippled.addResponse("ledger_current", rippled.ledger_current); this.mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("account_info", rippled.account_info.normal); this.mockRippled.addResponse("fee", rippled.fee);
const result = await client.prepareEscrowExecution( this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
address, this.mockRippled.addResponse(
requests.prepareEscrowExecution.simple "account_info",
); rippled.account_info.normal
assertResultMatch( );
result, const result = await this.client.prepareEscrowExecution(
responses.prepareEscrowExecution.simple, test.address,
"prepare" requests.prepareEscrowExecution.normal,
); instructionsWithMaxLedgerVersionOffset
}, );
assertResultMatch(
result,
responses.prepareEscrowExecution.normal,
"prepare"
);
});
"prepareEscrowExecution - no condition": async ( it("prepareEscrowExecution - simple", async function () {
client, this.mockRippled.addResponse("server_info", rippled.server_info.normal);
address, this.mockRippled.addResponse("fee", rippled.fee);
mockRippled this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
) => { this.mockRippled.addResponse(
mockRippled.addResponse("server_info", rippled.server_info.normal); "account_info",
mockRippled.addResponse("fee", rippled.fee); rippled.account_info.normal
mockRippled.addResponse("ledger_current", rippled.ledger_current); );
mockRippled.addResponse("account_info", rippled.account_info.normal); const result = await this.client.prepareEscrowExecution(
await assertRejects( test.address,
client.prepareEscrowExecution( requests.prepareEscrowExecution.simple
address, );
requests.prepareEscrowExecution.noCondition, assertResultMatch(
instructionsWithMaxLedgerVersionOffset result,
), responses.prepareEscrowExecution.simple,
client.errors.ValidationError, "prepare"
'"condition" and "fulfillment" fields on EscrowFinish must only be specified together.' );
); });
},
"prepareEscrowExecution - no fulfillment": async ( it("prepareEscrowExecution - no condition", async function () {
client, this.mockRippled.addResponse("server_info", rippled.server_info.normal);
address, this.mockRippled.addResponse("fee", rippled.fee);
mockRippled this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
) => { this.mockRippled.addResponse(
mockRippled.addResponse("server_info", rippled.server_info.normal); "account_info",
mockRippled.addResponse("fee", rippled.fee); rippled.account_info.normal
mockRippled.addResponse("ledger_current", rippled.ledger_current); );
mockRippled.addResponse("account_info", rippled.account_info.normal); await assertRejects(
await assertRejects( this.client.prepareEscrowExecution(
client.prepareEscrowExecution( test.address,
address, requests.prepareEscrowExecution.noCondition,
requests.prepareEscrowExecution.noFulfillment, instructionsWithMaxLedgerVersionOffset
instructionsWithMaxLedgerVersionOffset ),
), this.client.errors.ValidationError,
client.errors.ValidationError, '"condition" and "fulfillment" fields on EscrowFinish must only be specified together.'
'"condition" and "fulfillment" fields on EscrowFinish must only be specified together.' );
); });
},
"with ticket": async (client, address, mockRippled) => { it("prepareEscrowExecution - no fulfillment", async function () {
mockRippled.addResponse("server_info", rippled.server_info.normal); this.mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee); this.mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current); this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal); this.mockRippled.addResponse(
const localInstructions = { "account_info",
...instructionsWithMaxLedgerVersionOffset, rippled.account_info.normal
maxFee: "0.000396", );
ticketSequence: 23, await assertRejects(
}; this.client.prepareEscrowExecution(
const result = await client.prepareEscrowExecution( test.address,
address, requests.prepareEscrowExecution.noFulfillment,
requests.prepareEscrowExecution.normal, instructionsWithMaxLedgerVersionOffset
localInstructions ),
); this.client.errors.ValidationError,
assertResultMatch( '"condition" and "fulfillment" fields on EscrowFinish must only be specified together.'
result, );
responses.prepareEscrowExecution.ticket, });
"prepare"
); it("with ticket", async function () {
}, this.mockRippled.addResponse("server_info", rippled.server_info.normal);
}; this.mockRippled.addResponse("fee", rippled.fee);
this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
this.mockRippled.addResponse(
"account_info",
rippled.account_info.normal
);
const localInstructions = {
...instructionsWithMaxLedgerVersionOffset,
maxFee: "0.000396",
ticketSequence: 23,
};
const result = await this.client.prepareEscrowExecution(
test.address,
requests.prepareEscrowExecution.normal,
localInstructions
);
assertResultMatch(
result,
responses.prepareEscrowExecution.ticket,
"prepare"
);
});
});
});
});

View File

@@ -1,89 +1,107 @@
import requests from "../fixtures/requests"; import requests from "../fixtures/requests";
import responses from "../fixtures/responses"; import responses from "../fixtures/responses";
import rippled from "../fixtures/rippled"; import rippled from "../fixtures/rippled";
import { assertRejects, assertResultMatch, TestSuite } from "../testUtils"; import setupClient from "../setupClient";
import { assertRejects, assertResultMatch, addressTests } from "../testUtils";
const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 }; const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 };
/** describe("client.prepareOrder", function () {
* Every test suite exports their tests in the default object. beforeEach(setupClient.setup);
* - Check out the "TestSuite" type for documentation on the interface. afterEach(setupClient.teardown);
* - Check out "test/client/index.ts" for more information about the test runner.
*/
export default <TestSuite>{
"buy order": async (client, address, mockRippled) => {
mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal);
const request = requests.prepareOrder.buy;
const result = await client.prepareOrder(address, request);
assertResultMatch(result, responses.prepareOrder.buy, "prepare");
},
"buy order with expiration": async (client, address, mockRippled) => { addressTests.forEach(function (test) {
mockRippled.addResponse("server_info", rippled.server_info.normal); describe(test.type, function () {
mockRippled.addResponse("fee", rippled.fee); it("buy order", async function () {
mockRippled.addResponse("ledger_current", rippled.ledger_current); this.mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("account_info", rippled.account_info.normal); this.mockRippled.addResponse("fee", rippled.fee);
const request = requests.prepareOrder.expiration; this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
const response = responses.prepareOrder.expiration; this.mockRippled.addResponse(
const result = await client.prepareOrder( "account_info",
address, rippled.account_info.normal
request, );
instructionsWithMaxLedgerVersionOffset const request = requests.prepareOrder.buy;
); const result = await this.client.prepareOrder(test.address, request);
assertResultMatch(result, response, "prepare"); assertResultMatch(result, responses.prepareOrder.buy, "prepare");
}, });
"sell order": async (client, address, mockRippled) => { it("buy order with expiration", async function () {
mockRippled.addResponse("server_info", rippled.server_info.normal); this.mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee); this.mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current); this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal); this.mockRippled.addResponse(
const request = requests.prepareOrder.sell; "account_info",
const result = await client.prepareOrder( rippled.account_info.normal
address, );
request, const request = requests.prepareOrder.expiration;
instructionsWithMaxLedgerVersionOffset const response = responses.prepareOrder.expiration;
); const result = await this.client.prepareOrder(
assertResultMatch(result, responses.prepareOrder.sell, "prepare"); test.address,
}, request,
instructionsWithMaxLedgerVersionOffset
);
assertResultMatch(result, response, "prepare");
});
async invalid(client, address, mockRippled) { it("sell order", async function () {
mockRippled.addResponse("server_info", rippled.server_info.normal); this.mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee); this.mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current); this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal); this.mockRippled.addResponse(
const request = { ...requests.prepareOrder.sell }; "account_info",
delete request.direction; // Make invalid rippled.account_info.normal
await assertRejects( );
client.prepareOrder( const request = requests.prepareOrder.sell;
address, const result = await this.client.prepareOrder(
request, test.address,
instructionsWithMaxLedgerVersionOffset request,
), instructionsWithMaxLedgerVersionOffset
client.errors.ValidationError, );
'instance.order requires property "direction"' assertResultMatch(result, responses.prepareOrder.sell, "prepare");
); });
},
"with ticket": async (client, address, mockRippled) => { it("invalid", async function () {
mockRippled.addResponse("server_info", rippled.server_info.normal); this.mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee); this.mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current); this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal); this.mockRippled.addResponse(
const request = requests.prepareOrder.sell; "account_info",
const localInstructions = { rippled.account_info.normal
...instructionsWithMaxLedgerVersionOffset, );
maxFee: "0.000012", const request = { ...requests.prepareOrder.sell };
ticketSequence: 23, delete request.direction; // Make invalid
}; await assertRejects(
const result = await client.prepareOrder( this.client.prepareOrder(
address, test.address,
request, request,
localInstructions instructionsWithMaxLedgerVersionOffset
); ),
assertResultMatch(result, responses.prepareOrder.ticket, "prepare"); this.client.errors.ValidationError,
}, 'instance.order requires property "direction"'
}; );
});
it("with ticket", async function () {
this.mockRippled.addResponse("server_info", rippled.server_info.normal);
this.mockRippled.addResponse("fee", rippled.fee);
this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
this.mockRippled.addResponse(
"account_info",
rippled.account_info.normal
);
const request = requests.prepareOrder.sell;
const localInstructions = {
...instructionsWithMaxLedgerVersionOffset,
maxFee: "0.000012",
ticketSequence: 23,
};
const result = await this.client.prepareOrder(
test.address,
request,
localInstructions
);
assertResultMatch(result, responses.prepareOrder.ticket, "prepare");
});
});
});
});

View File

@@ -1,99 +1,123 @@
import requests from "../fixtures/requests"; import requests from "../fixtures/requests";
import responses from "../fixtures/responses"; import responses from "../fixtures/responses";
import rippled from "../fixtures/rippled"; import rippled from "../fixtures/rippled";
import { assertRejects, assertResultMatch, TestSuite } from "../testUtils"; import setupClient from "../setupClient";
import { assertRejects, assertResultMatch, addressTests } from "../testUtils";
const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 }; const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 };
/** describe("client.prepareOrderCancellation", function () {
* Every test suite exports their tests in the default object. beforeEach(setupClient.setup);
* - Check out the "TestSuite" type for documentation on the interface. afterEach(setupClient.teardown);
* - Check out "test/client/index.ts" for more information about the test runner.
*/
export default <TestSuite>{
async prepareOrderCancellation(client, address, mockRippled) {
mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal);
const request = requests.prepareOrderCancellation.simple;
const result = await client.prepareOrderCancellation(
address,
request,
instructionsWithMaxLedgerVersionOffset
);
assertResultMatch(
result,
responses.prepareOrderCancellation.normal,
"prepare"
);
},
"no instructions": async (client, address, mockRippled) => { addressTests.forEach(function (test) {
mockRippled.addResponse("server_info", rippled.server_info.normal); describe(test.type, function () {
mockRippled.addResponse("fee", rippled.fee); it("prepareOrderCancellation", async function () {
mockRippled.addResponse("ledger_current", rippled.ledger_current); this.mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("account_info", rippled.account_info.normal); this.mockRippled.addResponse("fee", rippled.fee);
const request = requests.prepareOrderCancellation.simple; this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
const result = await client.prepareOrderCancellation(address, request); this.mockRippled.addResponse(
assertResultMatch( "account_info",
result, rippled.account_info.normal
responses.prepareOrderCancellation.noInstructions, );
"prepare" const request = requests.prepareOrderCancellation.simple;
); const result = await this.client.prepareOrderCancellation(
}, test.address,
request,
instructionsWithMaxLedgerVersionOffset
);
assertResultMatch(
result,
responses.prepareOrderCancellation.normal,
"prepare"
);
});
"with memos": async (client, address, mockRippled) => { it("no instructions", async function () {
mockRippled.addResponse("server_info", rippled.server_info.normal); this.mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee); this.mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current); this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal); this.mockRippled.addResponse(
const request = requests.prepareOrderCancellation.withMemos; "account_info",
const result = await client.prepareOrderCancellation(address, request); rippled.account_info.normal
assertResultMatch( );
result, const request = requests.prepareOrderCancellation.simple;
responses.prepareOrderCancellation.withMemos, const result = await this.client.prepareOrderCancellation(
"prepare" test.address,
); request
}, );
assertResultMatch(
result,
responses.prepareOrderCancellation.noInstructions,
"prepare"
);
});
async invalid(client, address, mockRippled) { it("with memos", async function () {
mockRippled.addResponse("server_info", rippled.server_info.normal); this.mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee); this.mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current); this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal); this.mockRippled.addResponse(
const request = { "account_info",
...requests.prepareOrderCancellation.withMemos, rippled.account_info.normal
}; );
delete request.orderSequence; // Make invalid const request = requests.prepareOrderCancellation.withMemos;
const result = await this.client.prepareOrderCancellation(
test.address,
request
);
assertResultMatch(
result,
responses.prepareOrderCancellation.withMemos,
"prepare"
);
});
await assertRejects( it("invalid", async function () {
client.prepareOrderCancellation(address, request), this.mockRippled.addResponse("server_info", rippled.server_info.normal);
client.errors.ValidationError, this.mockRippled.addResponse("fee", rippled.fee);
'instance.orderCancellation requires property "orderSequence"' this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
); this.mockRippled.addResponse(
}, "account_info",
rippled.account_info.normal
);
const request = {
...requests.prepareOrderCancellation.withMemos,
};
delete request.orderSequence; // Make invalid
"with ticket": async (client, address, mockRippled) => { await assertRejects(
mockRippled.addResponse("server_info", rippled.server_info.normal); this.client.prepareOrderCancellation(test.address, request),
mockRippled.addResponse("fee", rippled.fee); this.client.errors.ValidationError,
mockRippled.addResponse("ledger_current", rippled.ledger_current); 'instance.orderCancellation requires property "orderSequence"'
mockRippled.addResponse("account_info", rippled.account_info.normal); );
const request = requests.prepareOrderCancellation.simple; });
const localInstructions = {
...instructionsWithMaxLedgerVersionOffset, it("with ticket", async function () {
maxFee: "0.000012", this.mockRippled.addResponse("server_info", rippled.server_info.normal);
ticketSequence: 23, this.mockRippled.addResponse("fee", rippled.fee);
}; this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
const result = await client.prepareOrderCancellation( this.mockRippled.addResponse(
address, "account_info",
request, rippled.account_info.normal
localInstructions );
); const request = requests.prepareOrderCancellation.simple;
assertResultMatch( const localInstructions = {
result, ...instructionsWithMaxLedgerVersionOffset,
responses.prepareOrderCancellation.ticket, maxFee: "0.000012",
"prepare" ticketSequence: 23,
); };
}, const result = await this.client.prepareOrderCancellation(
}; test.address,
request,
localInstructions
);
assertResultMatch(
result,
responses.prepareOrderCancellation.ticket,
"prepare"
);
});
});
});
});

File diff suppressed because it is too large Load Diff

View File

@@ -3,140 +3,153 @@ import { assert } from "chai";
import requests from "../fixtures/requests"; import requests from "../fixtures/requests";
import responses from "../fixtures/responses"; import responses from "../fixtures/responses";
import rippled from "../fixtures/rippled"; import rippled from "../fixtures/rippled";
import { assertResultMatch, TestSuite } from "../testUtils"; import setupClient from "../setupClient";
import { assertResultMatch, addressTests } from "../testUtils";
const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 }; const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 };
const { preparePaymentChannelClaim: REQUEST_FIXTURES } = requests; const { preparePaymentChannelClaim: REQUEST_FIXTURES } = requests;
const { preparePaymentChannelClaim: RESPONSE_FIXTURES } = responses; const { preparePaymentChannelClaim: RESPONSE_FIXTURES } = responses;
/** describe("client.preparePaymentChannelClaim", function () {
* Every test suite exports their tests in the default object. beforeEach(setupClient.setup);
* - Check out the "TestSuite" type for documentation on the interface. afterEach(setupClient.teardown);
* - Check out "test/client/index.ts" for more information about the test runner.
*/
export default <TestSuite>{
async default(client, address, mockRippled) {
mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal);
const localInstructions = {
...instructionsWithMaxLedgerVersionOffset,
maxFee: "0.000012",
};
const response = await client.preparePaymentChannelClaim(
address,
REQUEST_FIXTURES.normal,
localInstructions
);
assertResultMatch(response, RESPONSE_FIXTURES.normal, "prepare");
},
"with renew": async (client, address, mockRippled) => { addressTests.forEach(function (test) {
mockRippled.addResponse("server_info", rippled.server_info.normal); describe(test.type, function () {
mockRippled.addResponse("fee", rippled.fee); it("default", async function () {
mockRippled.addResponse("ledger_current", rippled.ledger_current); this.mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("account_info", rippled.account_info.normal); this.mockRippled.addResponse("fee", rippled.fee);
const localInstructions = { this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
...instructionsWithMaxLedgerVersionOffset, this.mockRippled.addResponse(
maxFee: "0.000012", "account_info",
}; rippled.account_info.normal
const response = await client.preparePaymentChannelClaim( );
address, const localInstructions = {
REQUEST_FIXTURES.renew, ...instructionsWithMaxLedgerVersionOffset,
localInstructions maxFee: "0.000012",
); };
assertResultMatch(response, RESPONSE_FIXTURES.renew, "prepare"); const response = await this.client.preparePaymentChannelClaim(
}, test.address,
REQUEST_FIXTURES.normal,
localInstructions
);
assertResultMatch(response, RESPONSE_FIXTURES.normal, "prepare");
});
"with close": async (client, address, mockRippled) => { it("with renew", async function () {
mockRippled.addResponse("server_info", rippled.server_info.normal); this.mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee); this.mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current); this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal); this.mockRippled.addResponse(
const localInstructions = { "account_info",
...instructionsWithMaxLedgerVersionOffset, rippled.account_info.normal
maxFee: "0.000012", );
}; const localInstructions = {
const response = await client.preparePaymentChannelClaim( ...instructionsWithMaxLedgerVersionOffset,
address, maxFee: "0.000012",
REQUEST_FIXTURES.close, };
localInstructions const response = await this.client.preparePaymentChannelClaim(
); test.address,
assertResultMatch(response, RESPONSE_FIXTURES.close, "prepare"); REQUEST_FIXTURES.renew,
}, localInstructions
);
assertResultMatch(response, RESPONSE_FIXTURES.renew, "prepare");
});
"with ticket": async (client, address, mockRippled) => { it("with close", async function () {
mockRippled.addResponse("server_info", rippled.server_info.normal); this.mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee); this.mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current); this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal); this.mockRippled.addResponse(
const localInstructions = { "account_info",
...instructionsWithMaxLedgerVersionOffset, rippled.account_info.normal
maxFee: "0.000012", );
ticketSequence: 23, const localInstructions = {
}; ...instructionsWithMaxLedgerVersionOffset,
const response = await client.preparePaymentChannelClaim( maxFee: "0.000012",
address, };
REQUEST_FIXTURES.normal, const response = await this.client.preparePaymentChannelClaim(
localInstructions test.address,
); REQUEST_FIXTURES.close,
assertResultMatch(response, RESPONSE_FIXTURES.ticket, "prepare"); localInstructions
}, );
assertResultMatch(response, RESPONSE_FIXTURES.close, "prepare");
});
"rejects Promise on preparePaymentChannelClaim with renew and close": async ( it("with ticket", async function () {
client, this.mockRippled.addResponse("server_info", rippled.server_info.normal);
address, this.mockRippled.addResponse("fee", rippled.fee);
mockRippled this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
) => { this.mockRippled.addResponse(
mockRippled.addResponse("server_info", rippled.server_info.normal); "account_info",
mockRippled.addResponse("fee", rippled.fee); rippled.account_info.normal
mockRippled.addResponse("ledger_current", rippled.ledger_current); );
mockRippled.addResponse("account_info", rippled.account_info.normal); const localInstructions = {
try { ...instructionsWithMaxLedgerVersionOffset,
const prepared = await client.preparePaymentChannelClaim( maxFee: "0.000012",
address, ticketSequence: 23,
REQUEST_FIXTURES.full };
); const response = await this.client.preparePaymentChannelClaim(
throw new Error( test.address,
`Expected method to reject. Prepared transaction: ${JSON.stringify( REQUEST_FIXTURES.normal,
prepared localInstructions
)}` );
); assertResultMatch(response, RESPONSE_FIXTURES.ticket, "prepare");
} catch (err) { });
assert.strictEqual(err.name, "ValidationError");
assert.strictEqual(
err.message,
'"renew" and "close" flags on PaymentChannelClaim are mutually exclusive'
);
}
},
"rejects Promise on preparePaymentChannelClaim with no signature": async ( it("rejects Promise on preparePaymentChannelClaim with renew and close", async function () {
client, this.mockRippled.addResponse("server_info", rippled.server_info.normal);
address, this.mockRippled.addResponse("fee", rippled.fee);
mockRippled this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
) => { this.mockRippled.addResponse(
mockRippled.addResponse("server_info", rippled.server_info.normal); "account_info",
mockRippled.addResponse("fee", rippled.fee); rippled.account_info.normal
mockRippled.addResponse("ledger_current", rippled.ledger_current); );
mockRippled.addResponse("account_info", rippled.account_info.normal); try {
try { const prepared = await this.client.preparePaymentChannelClaim(
const prepared = await client.preparePaymentChannelClaim( test.address,
address, REQUEST_FIXTURES.full
REQUEST_FIXTURES.noSignature );
); throw new Error(
throw new Error( `Expected method to reject. Prepared transaction: ${JSON.stringify(
`Expected method to reject. Prepared transaction: ${JSON.stringify( prepared
prepared )}`
)}` );
); } catch (err) {
} catch (err) { assert.strictEqual(err.name, "ValidationError");
assert.strictEqual(err.name, "ValidationError"); assert.strictEqual(
assert.strictEqual( err.message,
err.message, '"renew" and "close" flags on PaymentChannelClaim are mutually exclusive'
'"signature" and "publicKey" fields on PaymentChannelClaim must only be specified together.' );
); }
} });
},
}; it("rejects Promise on preparePaymentChannelClaim with no signature", async function () {
this.mockRippled.addResponse("server_info", rippled.server_info.normal);
this.mockRippled.addResponse("fee", rippled.fee);
this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
this.mockRippled.addResponse(
"account_info",
rippled.account_info.normal
);
try {
const prepared = await this.client.preparePaymentChannelClaim(
test.address,
REQUEST_FIXTURES.noSignature
);
throw new Error(
`Expected method to reject. Prepared transaction: ${JSON.stringify(
prepared
)}`
);
} catch (err) {
assert.strictEqual(err.name, "ValidationError");
assert.strictEqual(
err.message,
'"signature" and "publicKey" fields on PaymentChannelClaim must only be specified together.'
);
}
});
});
});
});

View File

@@ -1,7 +1,9 @@
import addresses from "../fixtures/addresses.json";
import requests from "../fixtures/requests"; import requests from "../fixtures/requests";
import responses from "../fixtures/responses"; import responses from "../fixtures/responses";
import rippled from "../fixtures/rippled"; import rippled from "../fixtures/rippled";
import { assertResultMatch, TestSuite } from "../testUtils"; import setupClient from "../setupClient";
import { assertResultMatch } from "../testUtils";
const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 }; const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 };
@@ -12,23 +14,21 @@ export const config = {
skipXAddress: true, skipXAddress: true,
}; };
/** describe("client.preparePaymentChannelCreate", function () {
* Every test suite exports their tests in the default object. beforeEach(setupClient.setup);
* - Check out the "TestSuite" type for documentation on the interface. afterEach(setupClient.teardown);
* - Check out "test/client/index.ts" for more information about the test runner.
*/ it("preparePaymentChannelCreate", async function () {
export default <TestSuite>{ this.mockRippled.addResponse("server_info", rippled.server_info.normal);
async preparePaymentChannelCreate(client, address, mockRippled) { this.mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("server_info", rippled.server_info.normal); this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("fee", rippled.fee); this.mockRippled.addResponse("account_info", rippled.account_info.normal);
mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal);
const localInstructions = { const localInstructions = {
...instructionsWithMaxLedgerVersionOffset, ...instructionsWithMaxLedgerVersionOffset,
maxFee: "0.000012", maxFee: "0.000012",
}; };
const result = await client.preparePaymentChannelCreate( const result = await this.client.preparePaymentChannelCreate(
address, addresses.ACCOUNT,
requests.preparePaymentChannelCreate.normal, requests.preparePaymentChannelCreate.normal,
localInstructions localInstructions
); );
@@ -37,15 +37,15 @@ export default <TestSuite>{
responses.preparePaymentChannelCreate.normal, responses.preparePaymentChannelCreate.normal,
"prepare" "prepare"
); );
}, });
"preparePaymentChannelCreate full": async (client, address, mockRippled) => { it("preparePaymentChannelCreate full", async function () {
mockRippled.addResponse("server_info", rippled.server_info.normal); this.mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee); this.mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current); this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal); this.mockRippled.addResponse("account_info", rippled.account_info.normal);
const result = await client.preparePaymentChannelCreate( const result = await this.client.preparePaymentChannelCreate(
address, addresses.ACCOUNT,
requests.preparePaymentChannelCreate.full requests.preparePaymentChannelCreate.full
); );
assertResultMatch( assertResultMatch(
@@ -53,24 +53,20 @@ export default <TestSuite>{
responses.preparePaymentChannelCreate.full, responses.preparePaymentChannelCreate.full,
"prepare" "prepare"
); );
}, });
"preparePaymentChannelCreate with ticket": async ( it("preparePaymentChannelCreate with ticket", async function () {
client, this.mockRippled.addResponse("server_info", rippled.server_info.normal);
address, this.mockRippled.addResponse("fee", rippled.fee);
mockRippled this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
) => { this.mockRippled.addResponse("account_info", rippled.account_info.normal);
mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal);
const localInstructions = { const localInstructions = {
...instructionsWithMaxLedgerVersionOffset, ...instructionsWithMaxLedgerVersionOffset,
maxFee: "0.000012", maxFee: "0.000012",
ticketSequence: 23, ticketSequence: 23,
}; };
const result = await client.preparePaymentChannelCreate( const result = await this.client.preparePaymentChannelCreate(
address, addresses.ACCOUNT,
requests.preparePaymentChannelCreate.normal, requests.preparePaymentChannelCreate.normal,
localInstructions localInstructions
); );
@@ -79,5 +75,5 @@ export default <TestSuite>{
responses.preparePaymentChannelCreate.ticket, responses.preparePaymentChannelCreate.ticket,
"prepare" "prepare"
); );
}, });
}; });

View File

@@ -1,72 +1,84 @@
import requests from "../fixtures/requests"; import requests from "../fixtures/requests";
import responses from "../fixtures/responses"; import responses from "../fixtures/responses";
import rippled from "../fixtures/rippled"; import rippled from "../fixtures/rippled";
import { assertResultMatch, TestSuite } from "../testUtils"; import setupClient from "../setupClient";
import { assertResultMatch, addressTests } from "../testUtils";
const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 }; const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 };
/** describe("client.preparePaymentChannelFund", function () {
* Every test suite exports their tests in the default object. beforeEach(setupClient.setup);
* - Check out the "TestSuite" type for documentation on the interface. afterEach(setupClient.teardown);
* - Check out "test/client/index.ts" for more information about the test runner.
*/
export default <TestSuite>{
async preparePaymentChannelFund(client, address, mockRippled) {
mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal);
const localInstructions = {
...instructionsWithMaxLedgerVersionOffset,
maxFee: "0.000012",
};
const result = await client.preparePaymentChannelFund(
address,
requests.preparePaymentChannelFund.normal,
localInstructions
);
assertResultMatch(
result,
responses.preparePaymentChannelFund.normal,
"prepare"
);
},
"preparePaymentChannelFund full": async (client, address, mockRippled) => { addressTests.forEach(function (test) {
mockRippled.addResponse("server_info", rippled.server_info.normal); describe(test.type, function () {
mockRippled.addResponse("fee", rippled.fee); it("preparePaymentChannelFund", async function () {
mockRippled.addResponse("ledger_current", rippled.ledger_current); this.mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("account_info", rippled.account_info.normal); this.mockRippled.addResponse("fee", rippled.fee);
const result = await client.preparePaymentChannelFund( this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
address, this.mockRippled.addResponse(
requests.preparePaymentChannelFund.full "account_info",
); rippled.account_info.normal
assertResultMatch( );
result, const localInstructions = {
responses.preparePaymentChannelFund.full, ...instructionsWithMaxLedgerVersionOffset,
"prepare" maxFee: "0.000012",
); };
}, const result = await this.client.preparePaymentChannelFund(
test.address,
requests.preparePaymentChannelFund.normal,
localInstructions
);
assertResultMatch(
result,
responses.preparePaymentChannelFund.normal,
"prepare"
);
});
"with ticket": async (client, address, mockRippled) => { it("preparePaymentChannelFund full", async function () {
mockRippled.addResponse("server_info", rippled.server_info.normal); this.mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee); this.mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current); this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal); this.mockRippled.addResponse(
const localInstructions = { "account_info",
...instructionsWithMaxLedgerVersionOffset, rippled.account_info.normal
maxFee: "0.000012", );
ticketSequence: 23, const result = await this.client.preparePaymentChannelFund(
}; test.address,
const result = await client.preparePaymentChannelFund( requests.preparePaymentChannelFund.full
address, );
requests.preparePaymentChannelFund.normal, assertResultMatch(
localInstructions result,
); responses.preparePaymentChannelFund.full,
assertResultMatch( "prepare"
result, );
responses.preparePaymentChannelFund.ticket, });
"prepare"
); it("with ticket", async function () {
}, this.mockRippled.addResponse("server_info", rippled.server_info.normal);
}; this.mockRippled.addResponse("fee", rippled.fee);
this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
this.mockRippled.addResponse(
"account_info",
rippled.account_info.normal
);
const localInstructions = {
...instructionsWithMaxLedgerVersionOffset,
maxFee: "0.000012",
ticketSequence: 23,
};
const result = await this.client.preparePaymentChannelFund(
test.address,
requests.preparePaymentChannelFund.normal,
localInstructions
);
assertResultMatch(
result,
responses.preparePaymentChannelFund.ticket,
"prepare"
);
});
});
});
});

View File

@@ -4,352 +4,432 @@ import { FormattedSettings } from "../../src/common/types/objects";
import requests from "../fixtures/requests"; import requests from "../fixtures/requests";
import responses from "../fixtures/responses"; import responses from "../fixtures/responses";
import rippled from "../fixtures/rippled"; import rippled from "../fixtures/rippled";
import { assertResultMatch, TestSuite } from "../testUtils"; import setupClient from "../setupClient";
import { assertResultMatch, addressTests } from "../testUtils";
const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 }; const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 };
/** describe("client.prepareSettings", function () {
* Every test suite exports their tests in the default object. beforeEach(setupClient.setup);
* - Check out the "TestSuite" type for documentation on the interface. afterEach(setupClient.teardown);
* - Check out "test/client/index.ts" for more information about the test runner.
*/
export default <TestSuite>{
"simple test": async (client, address, mockRippled) => {
mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal);
const response = await client.prepareSettings(
address,
requests.prepareSettings.domain,
instructionsWithMaxLedgerVersionOffset
);
assertResultMatch(response, responses.prepareSettings.flags, "prepare");
},
"no maxLedgerVersion": async (client, address, mockRippled) => {
mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal);
const response = await client.prepareSettings(
address,
requests.prepareSettings.domain,
{
maxLedgerVersion: null as unknown as undefined,
}
);
assertResultMatch(
response,
responses.prepareSettings.noMaxLedgerVersion,
"prepare"
);
},
"no instructions": async (client, address, mockRippled) => {
mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal);
const response = await client.prepareSettings(
address,
requests.prepareSettings.domain
);
assertResultMatch(
response,
responses.prepareSettings.noInstructions,
"prepare"
);
},
async regularKey(client, address, mockRippled) {
mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal);
const regularKey = { regularKey: "rAR8rR8sUkBoCZFawhkWzY4Y5YoyuznwD" };
const response = await client.prepareSettings(
address,
regularKey,
instructionsWithMaxLedgerVersionOffset
);
assertResultMatch(
response,
responses.prepareSettings.regularKey,
"prepare"
);
},
"remove regularKey": async (client, address, mockRippled) => {
mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal);
const regularKey = { regularKey: null };
const response = await client.prepareSettings(
address,
regularKey as unknown as FormattedSettings,
instructionsWithMaxLedgerVersionOffset
);
assertResultMatch(
response,
responses.prepareSettings.removeRegularKey,
"prepare"
);
},
"flag set": async (client, address, mockRippled) => {
mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal);
const settings = { requireDestinationTag: true };
const response = await client.prepareSettings(
address,
settings,
instructionsWithMaxLedgerVersionOffset
);
assertResultMatch(response, responses.prepareSettings.flagSet, "prepare");
},
"flag clear": async (client, address, mockRippled) => {
mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal);
const settings = { requireDestinationTag: false };
const response = await client.prepareSettings(
address,
settings,
instructionsWithMaxLedgerVersionOffset
);
assertResultMatch(response, responses.prepareSettings.flagClear, "prepare");
},
"set depositAuth flag": async (client, address, mockRippled) => {
mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal);
const settings = { depositAuth: true };
const response = await client.prepareSettings(
address,
settings,
instructionsWithMaxLedgerVersionOffset
);
assertResultMatch(
response,
responses.prepareSettings.flagSetDepositAuth,
"prepare"
);
},
"clear depositAuth flag": async (client, address, mockRippled) => {
mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal);
const settings = { depositAuth: false };
const response = await client.prepareSettings(
address,
settings,
instructionsWithMaxLedgerVersionOffset
);
assertResultMatch(
response,
responses.prepareSettings.flagClearDepositAuth,
"prepare"
);
},
"integer field clear": async (client, address, mockRippled) => {
mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal);
const settings = { transferRate: null };
const response = await client.prepareSettings(
address,
settings,
instructionsWithMaxLedgerVersionOffset
);
assert(response);
assert.strictEqual(JSON.parse(response.txJSON).TransferRate, 0);
},
"set transferRate": async (client, address, mockRippled) => {
mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal);
const settings = { transferRate: 1 };
const response = await client.prepareSettings(
address,
settings,
instructionsWithMaxLedgerVersionOffset
);
assertResultMatch(
response,
responses.prepareSettings.setTransferRate,
"prepare"
);
},
"set signers": async (client, address, mockRippled) => {
mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal);
const settings = requests.prepareSettings.signers.normal;
const response = await client.prepareSettings(
address,
settings,
instructionsWithMaxLedgerVersionOffset
);
assertResultMatch(response, responses.prepareSettings.signers, "prepare");
},
"signers no threshold": async (client, address, mockRippled) => {
mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal);
const settings = requests.prepareSettings.signers.noThreshold;
try {
const response = await client.prepareSettings(
address,
settings,
instructionsWithMaxLedgerVersionOffset
);
throw new Error(
`Expected method to reject. Prepared transaction: ${JSON.stringify(
response
)}`
);
} catch (err) {
assert.strictEqual(
err.message,
'instance.settings.signers requires property "threshold"'
);
assert.strictEqual(err.name, "ValidationError");
}
},
"signers no weights": async (client, address, mockRippled) => {
mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal);
const settings = requests.prepareSettings.signers.noWeights;
const localInstructions = {
signersCount: 1,
...instructionsWithMaxLedgerVersionOffset,
};
const response = await client.prepareSettings(
address,
settings,
localInstructions
);
assertResultMatch(response, responses.prepareSettings.noWeights, "prepare");
},
"fee for multisign": async (client, address, mockRippled) => {
mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal);
const localInstructions = {
signersCount: 4,
...instructionsWithMaxLedgerVersionOffset,
};
const response = await client.prepareSettings(
address,
requests.prepareSettings.domain,
localInstructions
);
assertResultMatch(
response,
responses.prepareSettings.flagsMultisign,
"prepare"
);
},
"no signer list": async (client, address, mockRippled) => {
mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal);
const settings = requests.prepareSettings.noSignerEntries;
const localInstructions = {
signersCount: 1,
...instructionsWithMaxLedgerVersionOffset,
};
const response = await client.prepareSettings(
address,
settings,
localInstructions
);
assertResultMatch(
response,
responses.prepareSettings.noSignerList,
"prepare"
);
},
async invalid(client, address, mockRippled) {
mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal);
// domain must be a string
const settings = { ...requests.prepareSettings.domain, domain: 123 };
const localInstructions = {
signersCount: 4,
...instructionsWithMaxLedgerVersionOffset,
};
try { addressTests.forEach(function (test) {
const response = await client.prepareSettings( describe(test.type, function () {
address, it("simple test", async function () {
settings, this.mockRippled.addResponse("server_info", rippled.server_info.normal);
localInstructions this.mockRippled.addResponse("fee", rippled.fee);
); this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
throw new Error( this.mockRippled.addResponse(
`Expected method to reject. Prepared transaction: ${JSON.stringify( "account_info",
response rippled.account_info.normal
)}` );
); const response = await this.client.prepareSettings(
} catch (err) { test.address,
assert.strictEqual( requests.prepareSettings.domain,
err.message, instructionsWithMaxLedgerVersionOffset
"instance.settings.domain is not of a type(s) string" );
); assertResultMatch(response, responses.prepareSettings.flags, "prepare");
assert.strictEqual(err.name, "ValidationError"); });
} it("no maxLedgerVersion", async function () {
}, this.mockRippled.addResponse("server_info", rippled.server_info.normal);
async offline(client, address, mockRippled) { this.mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("server_info", rippled.server_info.normal); this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("fee", rippled.fee); this.mockRippled.addResponse(
mockRippled.addResponse("ledger_current", rippled.ledger_current); "account_info",
mockRippled.addResponse("account_info", rippled.account_info.normal); rippled.account_info.normal
const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV"; );
const response = await this.client.prepareSettings(
test.address,
requests.prepareSettings.domain,
{
maxLedgerVersion: null as unknown as undefined,
}
);
assertResultMatch(
response,
responses.prepareSettings.noMaxLedgerVersion,
"prepare"
);
});
it("no instructions", async function () {
this.mockRippled.addResponse("server_info", rippled.server_info.normal);
this.mockRippled.addResponse("fee", rippled.fee);
this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
this.mockRippled.addResponse(
"account_info",
rippled.account_info.normal
);
const response = await this.client.prepareSettings(
test.address,
requests.prepareSettings.domain
);
assertResultMatch(
response,
responses.prepareSettings.noInstructions,
"prepare"
);
});
it("regularKey", async function () {
this.mockRippled.addResponse("server_info", rippled.server_info.normal);
this.mockRippled.addResponse("fee", rippled.fee);
this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
this.mockRippled.addResponse(
"account_info",
rippled.account_info.normal
);
const regularKey = { regularKey: "rAR8rR8sUkBoCZFawhkWzY4Y5YoyuznwD" };
const response = await this.client.prepareSettings(
test.address,
regularKey,
instructionsWithMaxLedgerVersionOffset
);
assertResultMatch(
response,
responses.prepareSettings.regularKey,
"prepare"
);
});
it("remove regularKey", async function () {
this.mockRippled.addResponse("server_info", rippled.server_info.normal);
this.mockRippled.addResponse("fee", rippled.fee);
this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
this.mockRippled.addResponse(
"account_info",
rippled.account_info.normal
);
const regularKey = { regularKey: null };
const response = await this.client.prepareSettings(
test.address,
regularKey as unknown as FormattedSettings,
instructionsWithMaxLedgerVersionOffset
);
assertResultMatch(
response,
responses.prepareSettings.removeRegularKey,
"prepare"
);
});
it("flag set", async function () {
this.mockRippled.addResponse("server_info", rippled.server_info.normal);
this.mockRippled.addResponse("fee", rippled.fee);
this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
this.mockRippled.addResponse(
"account_info",
rippled.account_info.normal
);
const settings = { requireDestinationTag: true };
const response = await this.client.prepareSettings(
test.address,
settings,
instructionsWithMaxLedgerVersionOffset
);
assertResultMatch(
response,
responses.prepareSettings.flagSet,
"prepare"
);
});
it("flag clear", async function () {
this.mockRippled.addResponse("server_info", rippled.server_info.normal);
this.mockRippled.addResponse("fee", rippled.fee);
this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
this.mockRippled.addResponse(
"account_info",
rippled.account_info.normal
);
const settings = { requireDestinationTag: false };
const response = await this.client.prepareSettings(
test.address,
settings,
instructionsWithMaxLedgerVersionOffset
);
assertResultMatch(
response,
responses.prepareSettings.flagClear,
"prepare"
);
});
it("set depositAuth flag", async function () {
this.mockRippled.addResponse("server_info", rippled.server_info.normal);
this.mockRippled.addResponse("fee", rippled.fee);
this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
this.mockRippled.addResponse(
"account_info",
rippled.account_info.normal
);
const settings = { depositAuth: true };
const response = await this.client.prepareSettings(
test.address,
settings,
instructionsWithMaxLedgerVersionOffset
);
assertResultMatch(
response,
responses.prepareSettings.flagSetDepositAuth,
"prepare"
);
});
it("clear depositAuth flag", async function () {
this.mockRippled.addResponse("server_info", rippled.server_info.normal);
this.mockRippled.addResponse("fee", rippled.fee);
this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
this.mockRippled.addResponse(
"account_info",
rippled.account_info.normal
);
const settings = { depositAuth: false };
const response = await this.client.prepareSettings(
test.address,
settings,
instructionsWithMaxLedgerVersionOffset
);
assertResultMatch(
response,
responses.prepareSettings.flagClearDepositAuth,
"prepare"
);
});
it("integer field clear", async function () {
this.mockRippled.addResponse("server_info", rippled.server_info.normal);
this.mockRippled.addResponse("fee", rippled.fee);
this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
this.mockRippled.addResponse(
"account_info",
rippled.account_info.normal
);
const settings = { transferRate: null };
const response = await this.client.prepareSettings(
test.address,
settings,
instructionsWithMaxLedgerVersionOffset
);
assert(response);
assert.strictEqual(JSON.parse(response.txJSON).TransferRate, 0);
});
it("set transferRate", async function () {
this.mockRippled.addResponse("server_info", rippled.server_info.normal);
this.mockRippled.addResponse("fee", rippled.fee);
this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
this.mockRippled.addResponse(
"account_info",
rippled.account_info.normal
);
const settings = { transferRate: 1 };
const response = await this.client.prepareSettings(
test.address,
settings,
instructionsWithMaxLedgerVersionOffset
);
assertResultMatch(
response,
responses.prepareSettings.setTransferRate,
"prepare"
);
});
it("set signers", async function () {
this.mockRippled.addResponse("server_info", rippled.server_info.normal);
this.mockRippled.addResponse("fee", rippled.fee);
this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
this.mockRippled.addResponse(
"account_info",
rippled.account_info.normal
);
const settings = requests.prepareSettings.signers.normal;
const response = await this.client.prepareSettings(
test.address,
settings,
instructionsWithMaxLedgerVersionOffset
);
assertResultMatch(
response,
responses.prepareSettings.signers,
"prepare"
);
});
it("signers no threshold", async function () {
this.mockRippled.addResponse("server_info", rippled.server_info.normal);
this.mockRippled.addResponse("fee", rippled.fee);
this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
this.mockRippled.addResponse(
"account_info",
rippled.account_info.normal
);
const settings = requests.prepareSettings.signers.noThreshold;
try {
const response = await this.client.prepareSettings(
test.address,
settings,
instructionsWithMaxLedgerVersionOffset
);
throw new Error(
`Expected method to reject. Prepared transaction: ${JSON.stringify(
response
)}`
);
} catch (err) {
assert.strictEqual(
err.message,
'instance.settings.signers requires property "threshold"'
);
assert.strictEqual(err.name, "ValidationError");
}
});
it("signers no weights", async function () {
this.mockRippled.addResponse("server_info", rippled.server_info.normal);
this.mockRippled.addResponse("fee", rippled.fee);
this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
this.mockRippled.addResponse(
"account_info",
rippled.account_info.normal
);
const settings = requests.prepareSettings.signers.noWeights;
const localInstructions = {
signersCount: 1,
...instructionsWithMaxLedgerVersionOffset,
};
const response = await this.client.prepareSettings(
test.address,
settings,
localInstructions
);
assertResultMatch(
response,
responses.prepareSettings.noWeights,
"prepare"
);
});
it("fee for multisign", async function () {
this.mockRippled.addResponse("server_info", rippled.server_info.normal);
this.mockRippled.addResponse("fee", rippled.fee);
this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
this.mockRippled.addResponse(
"account_info",
rippled.account_info.normal
);
const localInstructions = {
signersCount: 4,
...instructionsWithMaxLedgerVersionOffset,
};
const response = await this.client.prepareSettings(
test.address,
requests.prepareSettings.domain,
localInstructions
);
assertResultMatch(
response,
responses.prepareSettings.flagsMultisign,
"prepare"
);
});
it("no signer list", async function () {
this.mockRippled.addResponse("server_info", rippled.server_info.normal);
this.mockRippled.addResponse("fee", rippled.fee);
this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
this.mockRippled.addResponse(
"account_info",
rippled.account_info.normal
);
const settings = requests.prepareSettings.noSignerEntries;
const localInstructions = {
signersCount: 1,
...instructionsWithMaxLedgerVersionOffset,
};
const response = await this.client.prepareSettings(
test.address,
settings,
localInstructions
);
assertResultMatch(
response,
responses.prepareSettings.noSignerList,
"prepare"
);
});
it("invalid", async function () {
this.mockRippled.addResponse("server_info", rippled.server_info.normal);
this.mockRippled.addResponse("fee", rippled.fee);
this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
this.mockRippled.addResponse(
"account_info",
rippled.account_info.normal
);
// domain must be a string
const settings = { ...requests.prepareSettings.domain, domain: 123 };
const localInstructions = {
signersCount: 4,
...instructionsWithMaxLedgerVersionOffset,
};
const settings = requests.prepareSettings.domain; try {
const instructions = { const response = await this.client.prepareSettings(
sequence: 23, test.address,
maxLedgerVersion: 8820051, settings,
fee: "0.000012", localInstructions
}; );
const result = await client.prepareSettings( throw new Error(
address, `Expected method to reject. Prepared transaction: ${JSON.stringify(
settings, response
instructions )}`
); );
assertResultMatch(result, responses.prepareSettings.flags, "prepare"); } catch (err) {
assert.deepEqual( assert.strictEqual(
client.sign(result.txJSON, secret), err.message,
responses.prepareSettings.signed "instance.settings.domain is not of a type(s) string"
); );
}, assert.strictEqual(err.name, "ValidationError");
"prepare settings with ticket": async (client, address, mockRippled) => { }
mockRippled.addResponse("server_info", rippled.server_info.normal); });
mockRippled.addResponse("fee", rippled.fee); it("offline", async function () {
mockRippled.addResponse("ledger_current", rippled.ledger_current); this.mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("account_info", rippled.account_info.normal); this.mockRippled.addResponse("fee", rippled.fee);
const instructions = { this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
ticketSequence: 23, this.mockRippled.addResponse(
maxLedgerVersion: 8820051, "account_info",
fee: "0.000012", rippled.account_info.normal
}; );
const response = await client.prepareSettings( const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV";
address,
requests.prepareSettings.domain, const settings = requests.prepareSettings.domain;
instructions const instructions = {
); sequence: 23,
assertResultMatch(response, responses.prepareSettings.ticket, "prepare"); maxLedgerVersion: 8820051,
}, fee: "0.000012",
}; };
const result = await this.client.prepareSettings(
test.address,
settings,
instructions
);
assertResultMatch(result, responses.prepareSettings.flags, "prepare");
assert.deepEqual(
this.client.sign(result.txJSON, secret),
responses.prepareSettings.signed
);
});
it("prepare settings with ticket", async function () {
this.mockRippled.addResponse("server_info", rippled.server_info.normal);
this.mockRippled.addResponse("fee", rippled.fee);
this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
this.mockRippled.addResponse(
"account_info",
rippled.account_info.normal
);
const instructions = {
ticketSequence: 23,
maxLedgerVersion: 8820051,
fee: "0.000012",
};
const response = await this.client.prepareSettings(
test.address,
requests.prepareSettings.domain,
instructions
);
assertResultMatch(
response,
responses.prepareSettings.ticket,
"prepare"
);
});
});
});
});

View File

@@ -1,5 +1,6 @@
import rippled from "../fixtures/rippled"; import rippled from "../fixtures/rippled";
import { assertResultMatch, TestSuite } from "../testUtils"; import setupClient from "../setupClient";
import { assertResultMatch, addressTests } from "../testUtils";
// import responses from '../fixtures/responses' // import responses from '../fixtures/responses'
// import requests from '../fixtures/requests' // import requests from '../fixtures/requests'
// import {ValidationError} from 'xrpl-local/common/errors' // import {ValidationError} from 'xrpl-local/common/errors'
@@ -13,58 +14,62 @@ import { assertResultMatch, TestSuite } from "../testUtils";
// const {preparePayment: RESPONSE_FIXTURES} = responses // const {preparePayment: RESPONSE_FIXTURES} = responses
// const ADDRESS = 'rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo' // const ADDRESS = 'rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo'
/** describe("client.prepareTicket", function () {
* Every test suite exports their tests in the default object. beforeEach(setupClient.setup);
* - Check out the "TestSuite" type for documentation on the interface. afterEach(setupClient.teardown);
* - Check out "test/client/index.ts" for more information about the test runner.
*/
export default <TestSuite>{
"creates a ticket successfully with a sequence number": async (
client,
address,
mockRippled
) => {
mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal);
const expected = {
txJSON:
'{"TransactionType":"TicketCreate", "TicketCount": 2, "Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Flags":2147483648,"LastLedgerSequence":8819954,"Sequence":23,"Fee":"12"}',
instructions: {
maxLedgerVersion: 8819954,
sequence: 23,
fee: "0.000012",
},
};
const response = await client.prepareTicketCreate(address, 2);
assertResultMatch(response, expected, "prepare");
},
"creates a ticket successfully with another ticket": async ( addressTests.forEach(function (test) {
client, describe(test.type, function () {
address, it("creates a ticket successfully with a sequence number", async function () {
mockRippled this.mockRippled.addResponse("server_info", rippled.server_info.normal);
) => { this.mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("server_info", rippled.server_info.normal); this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("fee", rippled.fee); this.mockRippled.addResponse(
mockRippled.addResponse("ledger_current", rippled.ledger_current); "account_info",
mockRippled.addResponse("account_info", rippled.account_info.normal); rippled.account_info.normal
const expected = { );
txJSON: const expected = {
'{"TransactionType":"TicketCreate", "TicketCount": 1, "Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Flags":2147483648,"LastLedgerSequence":8819954,"Sequence": 0,"TicketSequence":23,"Fee":"12"}', txJSON:
instructions: { '{"TransactionType":"TicketCreate", "TicketCount": 2, "Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Flags":2147483648,"LastLedgerSequence":8819954,"Sequence":23,"Fee":"12"}',
maxLedgerVersion: 8819954, instructions: {
ticketSequence: 23, maxLedgerVersion: 8819954,
fee: "0.000012", sequence: 23,
}, fee: "0.000012",
}; },
const instructions = { };
maxLedgerVersion: 8819954, const response = await this.client.prepareTicketCreate(test.address, 2);
ticketSequence: 23, assertResultMatch(response, expected, "prepare");
fee: "0.000012", });
};
const response = await client.prepareTicketCreate(address, 1, instructions); it("creates a ticket successfully with another ticket", async function () {
assertResultMatch(response, expected, "prepare"); this.mockRippled.addResponse("server_info", rippled.server_info.normal);
}, this.mockRippled.addResponse("fee", rippled.fee);
}; this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
this.mockRippled.addResponse(
"account_info",
rippled.account_info.normal
);
const expected = {
txJSON:
'{"TransactionType":"TicketCreate", "TicketCount": 1, "Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Flags":2147483648,"LastLedgerSequence":8819954,"Sequence": 0,"TicketSequence":23,"Fee":"12"}',
instructions: {
maxLedgerVersion: 8819954,
ticketSequence: 23,
fee: "0.000012",
},
};
const instructions = {
maxLedgerVersion: 8819954,
ticketSequence: 23,
fee: "0.000012",
};
const response = await this.client.prepareTicketCreate(
test.address,
1,
instructions
);
assertResultMatch(response, expected, "prepare");
});
});
});
});

File diff suppressed because it is too large Load Diff

View File

@@ -1,105 +1,130 @@
import requests from "../fixtures/requests"; import requests from "../fixtures/requests";
import responses from "../fixtures/responses"; import responses from "../fixtures/responses";
import rippled from "../fixtures/rippled"; import rippled from "../fixtures/rippled";
import { assertRejects, assertResultMatch, TestSuite } from "../testUtils"; import setupClient from "../setupClient";
import { assertRejects, assertResultMatch, addressTests } from "../testUtils";
const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 }; const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 };
/** describe("client.prepareTrustline", function () {
* Every test suite exports their tests in the default object. beforeEach(setupClient.setup);
* - Check out the "TestSuite" type for documentation on the interface. afterEach(setupClient.teardown);
* - Check out "test/client/index.ts" for more information about the test runner.
*/
export default <TestSuite>{
async simple(client, address, mockRippled) {
mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal);
const result = await client.prepareTrustline(
address,
requests.prepareTrustline.simple,
instructionsWithMaxLedgerVersionOffset
);
assertResultMatch(result, responses.prepareTrustline.simple, "prepare");
},
async frozen(client, address, mockRippled) { addressTests.forEach(function (test) {
mockRippled.addResponse("server_info", rippled.server_info.normal); describe(test.type, function () {
mockRippled.addResponse("fee", rippled.fee); it("simple", async function () {
mockRippled.addResponse("ledger_current", rippled.ledger_current); this.mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("account_info", rippled.account_info.normal); this.mockRippled.addResponse("fee", rippled.fee);
const result = await client.prepareTrustline( this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
address, this.mockRippled.addResponse(
requests.prepareTrustline.frozen "account_info",
); rippled.account_info.normal
assertResultMatch(result, responses.prepareTrustline.frozen, "prepare"); );
}, const result = await this.client.prepareTrustline(
test.address,
requests.prepareTrustline.simple,
instructionsWithMaxLedgerVersionOffset
);
assertResultMatch(result, responses.prepareTrustline.simple, "prepare");
});
async complex(client, address, mockRippled) { it("frozen", async function () {
mockRippled.addResponse("server_info", rippled.server_info.normal); this.mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee); this.mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current); this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal); this.mockRippled.addResponse(
const result = await client.prepareTrustline( "account_info",
address, rippled.account_info.normal
requests.prepareTrustline.complex, );
instructionsWithMaxLedgerVersionOffset const result = await this.client.prepareTrustline(
); test.address,
assertResultMatch(result, responses.prepareTrustline.complex, "prepare"); requests.prepareTrustline.frozen
}, );
assertResultMatch(result, responses.prepareTrustline.frozen, "prepare");
});
async invalid(client, address, mockRippled) { it("complex", async function () {
mockRippled.addResponse("server_info", rippled.server_info.normal); this.mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee); this.mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current); this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal); this.mockRippled.addResponse(
const trustline = { ...requests.prepareTrustline.complex }; "account_info",
delete trustline.limit; // Make invalid rippled.account_info.normal
);
const result = await this.client.prepareTrustline(
test.address,
requests.prepareTrustline.complex,
instructionsWithMaxLedgerVersionOffset
);
assertResultMatch(
result,
responses.prepareTrustline.complex,
"prepare"
);
});
await assertRejects( it("invalid", async function () {
client.prepareTrustline( this.mockRippled.addResponse("server_info", rippled.server_info.normal);
address, this.mockRippled.addResponse("fee", rippled.fee);
trustline, this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
instructionsWithMaxLedgerVersionOffset this.mockRippled.addResponse(
), "account_info",
client.errors.ValidationError, rippled.account_info.normal
'instance.trustline requires property "limit"' );
); const trustline = { ...requests.prepareTrustline.complex };
}, delete trustline.limit; // Make invalid
"xaddress-issuer": async (client, address, mockRippled) => { await assertRejects(
mockRippled.addResponse("server_info", rippled.server_info.normal); this.client.prepareTrustline(
mockRippled.addResponse("fee", rippled.fee); test.address,
mockRippled.addResponse("ledger_current", rippled.ledger_current); trustline,
mockRippled.addResponse("account_info", rippled.account_info.normal); instructionsWithMaxLedgerVersionOffset
const result = await client.prepareTrustline( ),
address, this.client.errors.ValidationError,
requests.prepareTrustline.issuedXAddress, 'instance.trustline requires property "limit"'
instructionsWithMaxLedgerVersionOffset );
); });
assertResultMatch(
result,
responses.prepareTrustline.issuedXAddress,
"prepare"
);
},
"with ticket": async (client, address, mockRippled) => { it("xtest.address-issuer", async function () {
mockRippled.addResponse("server_info", rippled.server_info.normal); this.mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee); this.mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current); this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal); this.mockRippled.addResponse(
const localInstructions = { "account_info",
...instructionsWithMaxLedgerVersionOffset, rippled.account_info.normal
maxFee: "0.000012", );
ticketSequence: 23, const result = await this.client.prepareTrustline(
}; test.address,
const result = await client.prepareTrustline( requests.prepareTrustline.issuedXAddress,
address, instructionsWithMaxLedgerVersionOffset
requests.prepareTrustline.simple, );
localInstructions assertResultMatch(
); result,
assertResultMatch(result, responses.prepareTrustline.ticket, "prepare"); responses.prepareTrustline.issuedXAddress,
}, "prepare"
}; );
});
it("with ticket", async function () {
this.mockRippled.addResponse("server_info", rippled.server_info.normal);
this.mockRippled.addResponse("fee", rippled.fee);
this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
this.mockRippled.addResponse(
"account_info",
rippled.account_info.normal
);
const localInstructions = {
...instructionsWithMaxLedgerVersionOffset,
maxFee: "0.000012",
ticketSequence: 23,
};
const result = await this.client.prepareTrustline(
test.address,
requests.prepareTrustline.simple,
localInstructions
);
assertResultMatch(result, responses.prepareTrustline.ticket, "prepare");
});
});
});
});

View File

@@ -1,42 +1,47 @@
import responses from "../fixtures/responses"; import responses from "../fixtures/responses";
import rippled from "../fixtures/rippled"; import rippled from "../fixtures/rippled";
import { TestSuite, assertResultMatch } from "../testUtils"; import setupClient from "../setupClient";
import { addressTests, assertResultMatch } from "../testUtils";
/** describe("client.request", function () {
* Every test suite exports their tests in the default object. beforeEach(setupClient.setup);
* - Check out the "TestSuite" type for documentation on the interface. afterEach(setupClient.teardown);
* - Check out "test/client/index.ts" for more information about the test runner.
*/ addressTests.forEach(function (test) {
export default <TestSuite>{ describe(test.type, function () {
"request account_objects": async (client, address, mockRippled) => { it("request account_objects", async function () {
mockRippled.addResponse("account_objects", rippled.account_objects.normal); this.mockRippled.addResponse(
const result = await client.request({ "account_objects",
command: "account_objects", rippled.account_objects.normal
account: address, );
const result = await this.client.request({
command: "account_objects",
account: test.address,
});
assertResultMatch(
result.result,
responses.getAccountObjects,
"AccountObjectsResponse"
);
});
it("request account_objects - invalid options", async function () {
this.mockRippled.addResponse(
"account_objects",
rippled.account_objects.normal
);
const result = await this.client.request({
command: "account_objects",
account: test.address,
});
assertResultMatch(
result.result,
responses.getAccountObjects,
"AccountObjectsResponse"
);
});
}); });
});
assertResultMatch( });
result.result,
responses.getAccountObjects,
"AccountObjectsResponse"
);
},
"request account_objects - invalid options": async (
client,
address,
mockRippled
) => {
mockRippled.addResponse("account_objects", rippled.account_objects.normal);
const result = await client.request({
command: "account_objects",
account: address,
});
assertResultMatch(
result.result,
responses.getAccountObjects,
"AccountObjectsResponse"
);
},
};

View File

@@ -1,7 +1,8 @@
import { assert } from "chai"; import { assert } from "chai";
import rippled from "../fixtures/rippled"; import rippled from "../fixtures/rippled";
import { assertRejects, TestSuite } from "../testUtils"; import setupClient from "../setupClient";
import { assertRejects } from "../testUtils";
const rippledResponse = function (request: Request): object { const rippledResponse = function (request: Request): object {
if ("marker" in request) { if ("marker" in request) {
@@ -10,16 +11,13 @@ const rippledResponse = function (request: Request): object {
return rippled.ledger_data.first_page; return rippled.ledger_data.first_page;
}; };
/** describe("client.requestNextPage", function () {
* Every test suite exports their tests in the default object. beforeEach(setupClient.setup);
* - Check out the "TestSuite" type for documentation on the interface. afterEach(setupClient.teardown);
* - Check out "test/client/index.ts" for more information about the test runner. it("requests the next page", async function () {
*/ this.mockRippled.addResponse("ledger_data", rippledResponse);
export default <TestSuite>{ const response = await this.client.request({ command: "ledger_data" });
"requests the next page": async (client, address, mockRippled) => { const responseNextPage = await this.client.requestNextPage(
mockRippled.addResponse("ledger_data", rippledResponse);
const response = await client.request({ command: "ledger_data" });
const responseNextPage = await client.requestNextPage(
{ command: "ledger_data" }, { command: "ledger_data" },
response response
); );
@@ -27,24 +25,20 @@ export default <TestSuite>{
responseNextPage.result.state[0].index, responseNextPage.result.state[0].index,
"000B714B790C3C79FEE00D17C4DEB436B375466F29679447BA64F265FD63D731" "000B714B790C3C79FEE00D17C4DEB436B375466F29679447BA64F265FD63D731"
); );
}, });
"rejects when there are no more pages": async ( it("rejects when there are no more pages", async function () {
client, this.mockRippled.addResponse("ledger_data", rippledResponse);
address, const response = await this.client.request({ command: "ledger_data" });
mockRippled const responseNextPage = await this.client.requestNextPage(
) => {
mockRippled.addResponse("ledger_data", rippledResponse);
const response = await client.request({ command: "ledger_data" });
const responseNextPage = await client.requestNextPage(
{ command: "ledger_data" }, { command: "ledger_data" },
response response
); );
assert(!client.hasNextPage(responseNextPage)); assert(!this.client.hasNextPage(responseNextPage));
await assertRejects( await assertRejects(
client.requestNextPage({ command: "ledger_data" }, responseNextPage), this.client.requestNextPage({ command: "ledger_data" }, responseNextPage),
Error, Error,
"response does not have a next page" "response does not have a next page"
); );
}, });
}; });

View File

@@ -6,161 +6,110 @@ import * as schemaValidator from "xrpl-local/common/schema-validator";
import requests from "../fixtures/requests"; import requests from "../fixtures/requests";
import responses from "../fixtures/responses"; import responses from "../fixtures/responses";
import rippled from "../fixtures/rippled"; import rippled from "../fixtures/rippled";
import { TestSuite } from "../testUtils"; import setupClient from "../setupClient";
import { addressTests } from "../testUtils";
const { sign: REQUEST_FIXTURES } = requests; const { sign: REQUEST_FIXTURES } = requests;
const { sign: RESPONSE_FIXTURES } = responses; const { sign: RESPONSE_FIXTURES } = responses;
/** describe("client.sign", function () {
* Every test suite exports their tests in the default object. beforeEach(setupClient.setup);
* - Check out the "TestSuite" type for documentation on the interface. afterEach(setupClient.teardown);
* - Check out "test/client/index.ts" for more information about the test runner. it("sign", async function () {
*/
export default <TestSuite>{
async sign(client, address) {
const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV"; const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV";
const result = client.sign(REQUEST_FIXTURES.normal.txJSON, secret); const result = this.client.sign(REQUEST_FIXTURES.normal.txJSON, secret);
assert.deepEqual(result, RESPONSE_FIXTURES.normal); assert.deepEqual(result, RESPONSE_FIXTURES.normal);
schemaValidator.schemaValidate("sign", result); schemaValidator.schemaValidate("sign", result);
}, });
"sign with lowercase hex data in memo (hex should be case insensitive)": it("sign with lowercase hex data in memo (hex should be case insensitive)", async function () {
async (client, address) => { const secret = "shd2nxpFD6iBRKWsRss2P4tKMWyy9";
const secret = "shd2nxpFD6iBRKWsRss2P4tKMWyy9"; const lowercaseMemoTxJson = {
const lowercaseMemoTxJson = { TransactionType: "Payment",
TransactionType: "Payment", Flags: 2147483648,
Flags: 2147483648, Account: "rwiZ3q3D3QuG4Ga2HyGdq3kPKJRGctVG8a",
Account: "rwiZ3q3D3QuG4Ga2HyGdq3kPKJRGctVG8a", Amount: "10000000",
Amount: "10000000", LastLedgerSequence: 14000999,
LastLedgerSequence: 14000999, Destination: "rUeEBYXHo8vF86Rqir3zWGRQ84W9efdAQd",
Destination: "rUeEBYXHo8vF86Rqir3zWGRQ84W9efdAQd", Fee: "12",
Fee: "12", Sequence: 12,
Sequence: 12, SourceTag: 8888,
SourceTag: 8888, DestinationTag: 9999,
DestinationTag: 9999, Memos: [
Memos: [ {
{ Memo: {
Memo: { MemoType:
MemoType: "687474703a2f2f6578616d706c652e636f6d2f6d656d6f2f67656e65726963",
"687474703a2f2f6578616d706c652e636f6d2f6d656d6f2f67656e65726963", MemoData: "72656e74",
MemoData: "72656e74",
},
}, },
],
};
const txParams = JSON.stringify(lowercaseMemoTxJson);
const result = client.sign(txParams, secret);
assert.deepEqual(result, {
signedTransaction:
"120000228000000023000022B8240000000C2E0000270F201B00D5A36761400000000098968068400000000000000C73210305E09ED602D40AB1AF65646A4007C2DAC17CB6CDACDE301E74FB2D728EA057CF744730450221009C00E8439E017CA622A5A1EE7643E26B4DE9C808DE2ABE45D33479D49A4CEC66022062175BE8733442FA2A4D9A35F85A57D58252AE7B19A66401FE238B36FA28E5A081146C1856D0E36019EA75C56D7E8CBA6E35F9B3F71583147FB49CD110A1C46838788CD12764E3B0F837E0DDF9EA7C1F687474703A2F2F6578616D706C652E636F6D2F6D656D6F2F67656E657269637D0472656E74E1F1",
id: "41B9CB78D8E18A796CDD4B0BC6FB0EA19F64C4F25FDE23049197852CAB71D10D",
});
},
"sign with paths": async (client, address, mockRippled) => {
mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal);
const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV";
const payment = {
source: {
address,
amount: {
currency: "drops",
value: "100",
}, },
}, ],
destination: {
address: "rKT4JX4cCof6LcDYRz8o3rGRu7qxzZ2Zwj",
minAmount: {
currency: "USD",
value: "0.00004579644712312366",
counterparty: "rVnYNK9yuxBz4uP8zC8LEFokM2nqH3poc",
},
},
// eslint-disable-next-line no-useless-escape
paths:
'[[{"currency":"USD","issuer":"rVnYNK9yuxBz4uP8zC8LEFokM2nqH3poc"}]]',
}; };
const ret = await client.preparePayment(address, payment, {
sequence: 1, const txParams = JSON.stringify(lowercaseMemoTxJson);
maxLedgerVersion: 15696358, const result = this.client.sign(txParams, secret);
});
const result = client.sign(ret.txJSON, secret);
assert.deepEqual(result, { assert.deepEqual(result, {
signedTransaction: signedTransaction:
"12000022800200002400000001201B00EF81E661EC6386F26FC0FFFF0000000000000000000000005553440000000000054F6F784A58F9EFB0A9EB90B83464F9D166461968400000000000000C6940000000000000646AD3504529A0465E2E0000000000000000000000005553440000000000054F6F784A58F9EFB0A9EB90B83464F9D1664619732102F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D87446304402200A693FB5CA6B21250EBDFD8CFF526EE0DF7C9E4E31EB0660692E75E6A93BF5F802203CC39463DDA21386898CA31E18AD1A6828647D65741DD637BAD71BC83E29DB9481145E7B112523F68D2F5E879DB4EAC51C6698A693048314CA6EDC7A28252DAEA6F2045B24F4D7C333E146170112300000000000000000000000005553440000000000054F6F784A58F9EFB0A9EB90B83464F9D166461900", "120000228000000023000022B8240000000C2E0000270F201B00D5A36761400000000098968068400000000000000C73210305E09ED602D40AB1AF65646A4007C2DAC17CB6CDACDE301E74FB2D728EA057CF744730450221009C00E8439E017CA622A5A1EE7643E26B4DE9C808DE2ABE45D33479D49A4CEC66022062175BE8733442FA2A4D9A35F85A57D58252AE7B19A66401FE238B36FA28E5A081146C1856D0E36019EA75C56D7E8CBA6E35F9B3F71583147FB49CD110A1C46838788CD12764E3B0F837E0DDF9EA7C1F687474703A2F2F6578616D706C652E636F6D2F6D656D6F2F67656E657269637D0472656E74E1F1",
id: "78874FE5F5299FEE3EA85D3CF6C1FB1F1D46BB08F716662A3E3D1F0ADE4EF796", id: "41B9CB78D8E18A796CDD4B0BC6FB0EA19F64C4F25FDE23049197852CAB71D10D",
}); });
schemaValidator.schemaValidate("sign", result); });
},
"already signed": async (client, address) => { it("EscrowExecution", async function () {
const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV";
const result = client.sign(REQUEST_FIXTURES.normal.txJSON, secret);
assert.throws(() => {
const tx = JSON.stringify(binary.decode(result.signedTransaction));
client.sign(tx, secret);
}, /txJSON must not contain "TxnSignature" or "Signers" properties/);
},
async EscrowExecution(client, address) {
const secret = "snoPBrXtMeMyMHUVTgbuqAfg1SUTb"; const secret = "snoPBrXtMeMyMHUVTgbuqAfg1SUTb";
const result = client.sign(REQUEST_FIXTURES.escrow.txJSON, secret); const result = this.client.sign(REQUEST_FIXTURES.escrow.txJSON, secret);
assert.deepEqual(result, RESPONSE_FIXTURES.escrow); assert.deepEqual(result, RESPONSE_FIXTURES.escrow);
schemaValidator.schemaValidate("sign", result); schemaValidator.schemaValidate("sign", result);
}, });
async signAs(client, address) { it("signAs", async function () {
const txJSON = REQUEST_FIXTURES.signAs; const txJSON = REQUEST_FIXTURES.signAs;
const secret = "snoPBrXtMeMyMHUVTgbuqAfg1SUTb"; const secret = "snoPBrXtMeMyMHUVTgbuqAfg1SUTb";
const signature = client.sign(JSON.stringify(txJSON), secret, { const signature = this.client.sign(JSON.stringify(txJSON), secret, {
signAs: "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", signAs: "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
}); });
assert.deepEqual(signature, RESPONSE_FIXTURES.signAs); assert.deepEqual(signature, RESPONSE_FIXTURES.signAs);
}, });
async withKeypair(client, address) { it("withKeypair", async function () {
const keypair = { const keypair = {
privateKey: privateKey:
"00ACCD3309DB14D1A4FC9B1DAE608031F4408C85C73EE05E035B7DC8B25840107A", "00ACCD3309DB14D1A4FC9B1DAE608031F4408C85C73EE05E035B7DC8B25840107A",
publicKey: publicKey:
"02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8", "02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8",
}; };
const result = client.sign(REQUEST_FIXTURES.normal.txJSON, keypair); const result = this.client.sign(REQUEST_FIXTURES.normal.txJSON, keypair);
assert.deepEqual(result, RESPONSE_FIXTURES.normal); assert.deepEqual(result, RESPONSE_FIXTURES.normal);
schemaValidator.schemaValidate("sign", result); schemaValidator.schemaValidate("sign", result);
}, });
"withKeypair already signed": async (client, address) => { it("withKeypair already signed", async function () {
const keypair = { const keypair = {
privateKey: privateKey:
"00ACCD3309DB14D1A4FC9B1DAE608031F4408C85C73EE05E035B7DC8B25840107A", "00ACCD3309DB14D1A4FC9B1DAE608031F4408C85C73EE05E035B7DC8B25840107A",
publicKey: publicKey:
"02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8", "02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8",
}; };
const result = client.sign(REQUEST_FIXTURES.normal.txJSON, keypair); const result = this.client.sign(REQUEST_FIXTURES.normal.txJSON, keypair);
assert.throws(() => { assert.throws(() => {
const tx = JSON.stringify(binary.decode(result.signedTransaction)); const tx = JSON.stringify(binary.decode(result.signedTransaction));
client.sign(tx, keypair); this.client.sign(tx, keypair);
}, /txJSON must not contain "TxnSignature" or "Signers" properties/); }, /txJSON must not contain "TxnSignature" or "Signers" properties/);
}, });
"withKeypair EscrowExecution": async (client, address) => { it("withKeypair EscrowExecution", async function () {
const keypair = { const keypair = {
privateKey: privateKey:
"001ACAAEDECE405B2A958212629E16F2EB46B153EEE94CDD350FDEFF52795525B7", "001ACAAEDECE405B2A958212629E16F2EB46B153EEE94CDD350FDEFF52795525B7",
publicKey: publicKey:
"0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020", "0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020",
}; };
const result = client.sign(REQUEST_FIXTURES.escrow.txJSON, keypair); const result = this.client.sign(REQUEST_FIXTURES.escrow.txJSON, keypair);
assert.deepEqual(result, RESPONSE_FIXTURES.escrow); assert.deepEqual(result, RESPONSE_FIXTURES.escrow);
schemaValidator.schemaValidate("sign", result); schemaValidator.schemaValidate("sign", result);
}, });
"withKeypair signAs": async (client, address) => { it("withKeypair signAs", async function () {
const txJSON = REQUEST_FIXTURES.signAs; const txJSON = REQUEST_FIXTURES.signAs;
const keypair = { const keypair = {
privateKey: privateKey:
@@ -168,49 +117,26 @@ export default <TestSuite>{
publicKey: publicKey:
"0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020", "0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020",
}; };
const signature = client.sign(JSON.stringify(txJSON), keypair, { const signature = this.client.sign(JSON.stringify(txJSON), keypair, {
signAs: "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", signAs: "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
}); });
assert.deepEqual(signature, RESPONSE_FIXTURES.signAs); assert.deepEqual(signature, RESPONSE_FIXTURES.signAs);
}, });
"succeeds - prepared payment": async (client, address, mockRippled) => { it("already signed", async function () {
mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal);
const payment = await client.preparePayment(address, {
source: {
address,
maxAmount: {
value: "1",
currency: "drops",
},
},
destination: {
address: "rQ3PTWGLCbPz8ZCicV5tCX3xuymojTng5r",
amount: {
value: "1",
currency: "drops",
},
},
});
const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV"; const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV";
const result = client.sign(payment.txJSON, secret); const result = this.client.sign(REQUEST_FIXTURES.normal.txJSON, secret);
const expectedResult = { assert.throws(() => {
signedTransaction: const tx = JSON.stringify(binary.decode(result.signedTransaction));
"12000022800000002400000017201B008694F261400000000000000168400000000000000C732102F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D874473045022100A9C91D4CFAE45686146EE0B56D4C53A2E7C2D672FB834D43E0BE2D2E9106519A022075DDA2F92DE552B0C45D83D4E6D35889B3FBF51BFBBD9B25EBF70DE3C96D0D6681145E7B112523F68D2F5E879DB4EAC51C6698A693048314FDB08D07AAA0EB711793A3027304D688E10C3648", this.client.sign(tx, secret);
id: "88D6B913C66279EA31ADC25C5806C48B2D4E5680261666790A736E1961217700", }, /txJSON must not contain "TxnSignature" or "Signers" properties/);
}; });
assert.deepEqual(result, expectedResult);
schemaValidator.schemaValidate("sign", result);
},
"succeeds - no flags": async (client, address) => { it("succeeds - no flags", async function () {
const txJSON = const txJSON =
'{"TransactionType":"Payment","Account":"r45Rev1EXGxy2hAUmJPCne97KUE7qyrD3j","Destination":"rQ3PTWGLCbPz8ZCicV5tCX3xuymojTng5r","Amount":"20000000","Sequence":1,"Fee":"12"}'; '{"TransactionType":"Payment","Account":"r45Rev1EXGxy2hAUmJPCne97KUE7qyrD3j","Destination":"rQ3PTWGLCbPz8ZCicV5tCX3xuymojTng5r","Amount":"20000000","Sequence":1,"Fee":"12"}';
const secret = "shotKgaEotpcYsshSE39vmSnBDRim"; const secret = "shotKgaEotpcYsshSE39vmSnBDRim";
const result = client.sign(txJSON, secret); const result = this.client.sign(txJSON, secret);
const expectedResult = { const expectedResult = {
signedTransaction: signedTransaction:
"1200002400000001614000000001312D0068400000000000000C7321022B05847086686F9D0499B13136B94AD4323EE1B67D4C429ECC987AB35ACFA34574473045022100C104B7B97C31FACA4597E7D6FCF13BD85BD11375963A62A0AC45B0061236E39802207784F157F6A98DFC85B051CDDF61CC3084C4F5750B82674801C8E9950280D1998114EE3046A5DDF8422C40DDB93F1D522BB4FE6419158314FDB08D07AAA0EB711793A3027304D688E10C3648", "1200002400000001614000000001312D0068400000000000000C7321022B05847086686F9D0499B13136B94AD4323EE1B67D4C429ECC987AB35ACFA34574473045022100C104B7B97C31FACA4597E7D6FCF13BD85BD11375963A62A0AC45B0061236E39802207784F157F6A98DFC85B051CDDF61CC3084C4F5750B82674801C8E9950280D1998114EE3046A5DDF8422C40DDB93F1D522BB4FE6419158314FDB08D07AAA0EB711793A3027304D688E10C3648",
@@ -223,18 +149,15 @@ export default <TestSuite>{
); );
assert.deepEqual(result, expectedResult); assert.deepEqual(result, expectedResult);
schemaValidator.schemaValidate("sign", result); schemaValidator.schemaValidate("sign", result);
}, });
"sign succeeds with source.amount/destination.minAmount": async ( it("sign succeeds with source.amount/destination.minAmount", async function () {
client,
address
) => {
// See also: 'preparePayment with source.amount/destination.minAmount' // See also: 'preparePayment with source.amount/destination.minAmount'
const txJSON = const txJSON =
'{"TransactionType":"Payment","Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Destination":"rEX4LtGJubaUcMWCJULcy4NVxGT9ZEMVRq","Amount":{"currency":"USD","issuer":"rMaa8VLBTjwTJWA2kSme4Sqgphhr6Lr6FH","value":"999999999999999900000000000000000000000000000000000000000000000000000000000000000000000000000000"},"Flags":2147614720,"SendMax":{"currency":"GBP","issuer":"rpat5TmYjDsnFSStmgTumFgXCM9eqsWPro","value":"0.1"},"DeliverMin":{"currency":"USD","issuer":"rMaa8VLBTjwTJWA2kSme4Sqgphhr6Lr6FH","value":"0.1248548562296331"},"Sequence":23,"LastLedgerSequence":8820051,"Fee":"12"}'; '{"TransactionType":"Payment","Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Destination":"rEX4LtGJubaUcMWCJULcy4NVxGT9ZEMVRq","Amount":{"currency":"USD","issuer":"rMaa8VLBTjwTJWA2kSme4Sqgphhr6Lr6FH","value":"999999999999999900000000000000000000000000000000000000000000000000000000000000000000000000000000"},"Flags":2147614720,"SendMax":{"currency":"GBP","issuer":"rpat5TmYjDsnFSStmgTumFgXCM9eqsWPro","value":"0.1"},"DeliverMin":{"currency":"USD","issuer":"rMaa8VLBTjwTJWA2kSme4Sqgphhr6Lr6FH","value":"0.1248548562296331"},"Sequence":23,"LastLedgerSequence":8820051,"Fee":"12"}';
const secret = "shotKgaEotpcYsshSE39vmSnBDRim"; const secret = "shotKgaEotpcYsshSE39vmSnBDRim";
const result = client.sign(txJSON, secret); const result = this.client.sign(txJSON, secret);
const expectedResult = { const expectedResult = {
signedTransaction: signedTransaction:
"12000022800200002400000017201B0086955361EC6386F26FC0FFFF0000000000000000000000005553440000000000DC596C88BCDE4E818D416FCDEEBF2C8656BADC9A68400000000000000C69D4438D7EA4C6800000000000000000000000000047425000000000000C155FFE99C8C91F67083CEFFDB69EBFE76348CA6AD4446F8C5D8A5E0B0000000000000000000000005553440000000000DC596C88BCDE4E818D416FCDEEBF2C8656BADC9A7321022B05847086686F9D0499B13136B94AD4323EE1B67D4C429ECC987AB35ACFA34574473045022100D9634523D8E232D4A7807A71856023D82AC928FA29848571B820867898413B5F022041AC00EC1F81A26A6504EBF844A38CC3204694EF2CC1A97A87632721631F93DA81145E7B112523F68D2F5E879DB4EAC51C6698A6930483149F500E50C2F016CA01945E5A1E5846B61EF2D376", "12000022800200002400000017201B0086955361EC6386F26FC0FFFF0000000000000000000000005553440000000000DC596C88BCDE4E818D416FCDEEBF2C8656BADC9A68400000000000000C69D4438D7EA4C6800000000000000000000000000047425000000000000C155FFE99C8C91F67083CEFFDB69EBFE76348CA6AD4446F8C5D8A5E0B0000000000000000000000005553440000000000DC596C88BCDE4E818D416FCDEEBF2C8656BADC9A7321022B05847086686F9D0499B13136B94AD4323EE1B67D4C429ECC987AB35ACFA34574473045022100D9634523D8E232D4A7807A71856023D82AC928FA29848571B820867898413B5F022041AC00EC1F81A26A6504EBF844A38CC3204694EF2CC1A97A87632721631F93DA81145E7B112523F68D2F5E879DB4EAC51C6698A6930483149F500E50C2F016CA01945E5A1E5846B61EF2D376",
@@ -247,85 +170,9 @@ export default <TestSuite>{
); );
assert.deepEqual(result, expectedResult); assert.deepEqual(result, expectedResult);
schemaValidator.schemaValidate("sign", result); schemaValidator.schemaValidate("sign", result);
}, });
"throws when encoded tx does not match decoded tx - prepared payment": async ( it("throws when encoded tx does not match decoded tx - AccountSet", async function () {
client,
address,
mockRippled
) => {
mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal);
const payment = await client.preparePayment(address, {
source: {
address,
maxAmount: {
value: "1.1234567",
currency: "drops",
},
},
destination: {
address: "rQ3PTWGLCbPz8ZCicV5tCX3xuymojTng5r",
amount: {
value: "1.1234567",
currency: "drops",
},
},
});
const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV";
assert.throws(() => {
client.sign(payment.txJSON, secret);
}, /^1.1234567 is an illegal amount/);
},
"throws when encoded tx does not match decoded tx - prepared order": async (
client,
address,
mockRippled
) => {
mockRippled.addResponse("server_info", rippled.server_info.normal);
mockRippled.addResponse("fee", rippled.fee);
mockRippled.addResponse("ledger_current", rippled.ledger_current);
mockRippled.addResponse("account_info", rippled.account_info.normal);
const order = {
direction: "sell",
quantity: {
currency: "USD",
counterparty: "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B",
value: "3.140000",
},
totalPrice: {
currency: "XRP",
value: "31415",
},
};
const prepared = await client.prepareOrder(address, order, {
sequence: 123,
});
const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV";
try {
client.sign(prepared.txJSON, secret);
return await Promise.reject(new Error("client.sign should have thrown"));
} catch (error) {
assert.equal(error.name, "ValidationError");
assert.equal(
error.message,
"Serialized transaction does not match original txJSON. See `error.data`"
);
assert.deepEqual(error.data.diff, {
TakerGets: {
value: "3.14",
},
});
}
},
"throws when encoded tx does not match decoded tx - AccountSet": async (
client,
address
) => {
const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV"; const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV";
const request = { const request = {
// TODO: This fails when address is X-address // TODO: This fails when address is X-address
@@ -338,14 +185,11 @@ export default <TestSuite>{
}; };
assert.throws(() => { assert.throws(() => {
client.sign(request.txJSON, secret); this.client.sign(request.txJSON, secret);
}, /1\.2 is an illegal amount/); }, /1\.2 is an illegal amount/);
}, });
"throws when encoded tx does not match decoded tx - higher fee": async ( it("throws when encoded tx does not match decoded tx - higher fee", async function () {
client,
address
) => {
const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV"; const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV";
const request = { const request = {
// TODO: This fails when address is X-address // TODO: This fails when address is X-address
@@ -358,14 +202,16 @@ export default <TestSuite>{
}; };
assert.throws(() => { assert.throws(() => {
client.sign(request.txJSON, secret); this.client.sign(request.txJSON, secret);
}, /1123456\.7 is an illegal amount/); }, /1123456\.7 is an illegal amount/);
}, });
"throws when Fee exceeds maxFeeXRP (in drops)": async (client, address) => { it("permits fee exceeding 2000000 drops when maxFeeXRP is higher than 2 XRP", async function () {
this.client._maxFeeXRP = "2.1";
const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV"; const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV";
const request = { const request = {
txJSON: `{"Flags":2147483648,"TransactionType":"AccountSet","Account":"${address}","Domain":"6578616D706C652E636F6D","LastLedgerSequence":8820051,"Fee":"2010000","Sequence":23,"SigningPubKey":"02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8"}`, // TODO: This fails when address is X-address
txJSON: `{"Flags":2147483648,"TransactionType":"AccountSet","Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","LastLedgerSequence":8820051,"Fee":"2010000","Sequence":23,"SigningPubKey":"02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8"}`,
instructions: { instructions: {
fee: "2.01", fee: "2.01",
sequence: 23, sequence: 23,
@@ -373,61 +219,209 @@ export default <TestSuite>{
}, },
}; };
assert.throws(() => { const result = this.client.sign(request.txJSON, secret);
client.sign(request.txJSON, secret);
}, /Fee" should not exceed "2000000"\. To use a higher fee, set `maxFeeXRP` in the Client constructor\./);
},
"throws when Fee exceeds maxFeeXRP (in drops) - custom maxFeeXRP": async ( const expectedResponse = {
client, signedTransaction:
address "12000322800000002400000017201B008695536840000000001EAB90732102F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D87446304402200203F219F5371D2C6506888B1B02B27E74998F7A42D412C32FE319AC1A5B8DEF02205959A1B02253ACCCE542759E9886466C56D16B04676FA492AD34AA0E877E91F381145E7B112523F68D2F5E879DB4EAC51C6698A69304",
) => { id: "061D5593E0A117F389826419CAC049A73C7CFCA65A20B788781D41240143D864",
client._maxFeeXRP = "1.9";
const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV";
const request = {
txJSON: `{"Flags":2147483648,"TransactionType":"AccountSet","Account":"${address}","Domain":"6578616D706C652E636F6D","LastLedgerSequence":8820051,"Fee":"2010000","Sequence":23,"SigningPubKey":"02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8"}`,
instructions: {
fee: "2.01",
sequence: 23,
maxLedgerVersion: 8820051,
},
}; };
assert.throws(() => { assert.deepEqual(result, expectedResponse);
client.sign(request.txJSON, secret); schemaValidator.schemaValidate("sign", result);
}, /Fee" should not exceed "1900000"\. To use a higher fee, set `maxFeeXRP` in the Client constructor\./); });
},
"permits fee exceeding 2000000 drops when maxFeeXRP is higher than 2 XRP": it("sign with ticket", async function () {
async (client, address) => {
client._maxFeeXRP = "2.1";
const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV";
const request = {
// TODO: This fails when address is X-address
txJSON: `{"Flags":2147483648,"TransactionType":"AccountSet","Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","LastLedgerSequence":8820051,"Fee":"2010000","Sequence":23,"SigningPubKey":"02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8"}`,
instructions: {
fee: "2.01",
sequence: 23,
maxLedgerVersion: 8820051,
},
};
const result = client.sign(request.txJSON, secret);
const expectedResponse = {
signedTransaction:
"12000322800000002400000017201B008695536840000000001EAB90732102F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D87446304402200203F219F5371D2C6506888B1B02B27E74998F7A42D412C32FE319AC1A5B8DEF02205959A1B02253ACCCE542759E9886466C56D16B04676FA492AD34AA0E877E91F381145E7B112523F68D2F5E879DB4EAC51C6698A69304",
id: "061D5593E0A117F389826419CAC049A73C7CFCA65A20B788781D41240143D864",
};
assert.deepEqual(result, expectedResponse);
schemaValidator.schemaValidate("sign", result);
},
"sign with ticket": async (client, address) => {
const secret = "sn7n5R1cR5Y3fRFkuWXA94Ts1frVJ"; const secret = "sn7n5R1cR5Y3fRFkuWXA94Ts1frVJ";
const result = client.sign(REQUEST_FIXTURES.ticket.txJSON, secret); const result = this.client.sign(REQUEST_FIXTURES.ticket.txJSON, secret);
assert.deepEqual(result, RESPONSE_FIXTURES.ticket); assert.deepEqual(result, RESPONSE_FIXTURES.ticket);
schemaValidator.schemaValidate("sign", result); schemaValidator.schemaValidate("sign", result);
}, });
};
addressTests.forEach(function (test) {
describe(test.type, function () {
it("throws when Fee exceeds maxFeeXRP (in drops)", async function () {
const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV";
const request = {
txJSON: `{"Flags":2147483648,"TransactionType":"AccountSet","Account":"${test.address}","Domain":"6578616D706C652E636F6D","LastLedgerSequence":8820051,"Fee":"2010000","Sequence":23,"SigningPubKey":"02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8"}`,
instructions: {
fee: "2.01",
sequence: 23,
maxLedgerVersion: 8820051,
},
};
assert.throws(() => {
this.client.sign(request.txJSON, secret);
}, /Fee" should not exceed "2000000"\. To use a higher fee, set `maxFeeXRP` in the Client constructor\./);
});
it("throws when Fee exceeds maxFeeXRP (in drops) - custom maxFeeXRP", async function () {
this.client._maxFeeXRP = "1.9";
const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV";
const request = {
txJSON: `{"Flags":2147483648,"TransactionType":"AccountSet","Account":"${test.address}","Domain":"6578616D706C652E636F6D","LastLedgerSequence":8820051,"Fee":"2010000","Sequence":23,"SigningPubKey":"02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8"}`,
instructions: {
fee: "2.01",
sequence: 23,
maxLedgerVersion: 8820051,
},
};
assert.throws(() => {
this.client.sign(request.txJSON, secret);
}, /Fee" should not exceed "1900000"\. To use a higher fee, set `maxFeeXRP` in the Client constructor\./);
});
it("sign with paths", async function () {
this.mockRippled.addResponse("server_info", rippled.server_info.normal);
this.mockRippled.addResponse("fee", rippled.fee);
this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
this.mockRippled.addResponse(
"account_info",
rippled.account_info.normal
);
const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV";
const payment = {
source: {
address: test.address,
amount: {
currency: "drops",
value: "100",
},
},
destination: {
address: "rKT4JX4cCof6LcDYRz8o3rGRu7qxzZ2Zwj",
minAmount: {
currency: "USD",
value: "0.00004579644712312366",
counterparty: "rVnYNK9yuxBz4uP8zC8LEFokM2nqH3poc",
},
},
// eslint-disable-next-line no-useless-escape
paths:
'[[{"currency":"USD","issuer":"rVnYNK9yuxBz4uP8zC8LEFokM2nqH3poc"}]]',
};
const ret = await this.client.preparePayment(test.address, payment, {
sequence: 1,
maxLedgerVersion: 15696358,
});
const result = this.client.sign(ret.txJSON, secret);
assert.deepEqual(result, {
signedTransaction:
"12000022800200002400000001201B00EF81E661EC6386F26FC0FFFF0000000000000000000000005553440000000000054F6F784A58F9EFB0A9EB90B83464F9D166461968400000000000000C6940000000000000646AD3504529A0465E2E0000000000000000000000005553440000000000054F6F784A58F9EFB0A9EB90B83464F9D1664619732102F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D87446304402200A693FB5CA6B21250EBDFD8CFF526EE0DF7C9E4E31EB0660692E75E6A93BF5F802203CC39463DDA21386898CA31E18AD1A6828647D65741DD637BAD71BC83E29DB9481145E7B112523F68D2F5E879DB4EAC51C6698A693048314CA6EDC7A28252DAEA6F2045B24F4D7C333E146170112300000000000000000000000005553440000000000054F6F784A58F9EFB0A9EB90B83464F9D166461900",
id: "78874FE5F5299FEE3EA85D3CF6C1FB1F1D46BB08F716662A3E3D1F0ADE4EF796",
});
schemaValidator.schemaValidate("sign", result);
});
it("succeeds - prepared payment", async function () {
this.mockRippled.addResponse("server_info", rippled.server_info.normal);
this.mockRippled.addResponse("fee", rippled.fee);
this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
this.mockRippled.addResponse(
"account_info",
rippled.account_info.normal
);
const payment = await this.client.preparePayment(test.address, {
source: {
address: test.address,
maxAmount: {
value: "1",
currency: "drops",
},
},
destination: {
address: "rQ3PTWGLCbPz8ZCicV5tCX3xuymojTng5r",
amount: {
value: "1",
currency: "drops",
},
},
});
const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV";
const result = this.client.sign(payment.txJSON, secret);
const expectedResult = {
signedTransaction:
"12000022800000002400000017201B008694F261400000000000000168400000000000000C732102F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D874473045022100A9C91D4CFAE45686146EE0B56D4C53A2E7C2D672FB834D43E0BE2D2E9106519A022075DDA2F92DE552B0C45D83D4E6D35889B3FBF51BFBBD9B25EBF70DE3C96D0D6681145E7B112523F68D2F5E879DB4EAC51C6698A693048314FDB08D07AAA0EB711793A3027304D688E10C3648",
id: "88D6B913C66279EA31ADC25C5806C48B2D4E5680261666790A736E1961217700",
};
assert.deepEqual(result, expectedResult);
schemaValidator.schemaValidate("sign", result);
});
it("throws when encoded tx does not match decoded tx - prepared payment", async function () {
this.mockRippled.addResponse("server_info", rippled.server_info.normal);
this.mockRippled.addResponse("fee", rippled.fee);
this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
this.mockRippled.addResponse(
"account_info",
rippled.account_info.normal
);
const payment = await this.client.preparePayment(test.address, {
source: {
address: test.address,
maxAmount: {
value: "1.1234567",
currency: "drops",
},
},
destination: {
address: "rQ3PTWGLCbPz8ZCicV5tCX3xuymojTng5r",
amount: {
value: "1.1234567",
currency: "drops",
},
},
});
const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV";
assert.throws(() => {
this.client.sign(payment.txJSON, secret);
}, /^1.1234567 is an illegal amount/);
});
it("throws when encoded tx does not match decoded tx - prepared order", async function () {
this.mockRippled.addResponse("server_info", rippled.server_info.normal);
this.mockRippled.addResponse("fee", rippled.fee);
this.mockRippled.addResponse("ledger_current", rippled.ledger_current);
this.mockRippled.addResponse(
"account_info",
rippled.account_info.normal
);
const order = {
direction: "sell",
quantity: {
currency: "USD",
counterparty: "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B",
value: "3.140000",
},
totalPrice: {
currency: "XRP",
value: "31415",
},
};
const prepared = await this.client.prepareOrder(test.address, order, {
sequence: 123,
});
const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV";
try {
this.client.sign(prepared.txJSON, secret);
return await Promise.reject(
new Error("this.client.sign should have thrown")
);
} catch (error) {
assert.equal(error.name, "ValidationError");
assert.equal(
error.message,
"Serialized transaction does not match original txJSON. See `error.data`"
);
assert.deepEqual(error.data.diff, {
TakerGets: {
value: "3.14",
},
});
}
});
});
});
});

View File

@@ -18,7 +18,7 @@
mocha.ui('bdd') mocha.ui('bdd')
</script> </script>
<script src="../testCompiledForWeb/rippleClient.js"></script> <script src="../testCompiledForWeb/runClientTests.js"></script>
<script src="../testCompiledForWeb/broadcastClient.js"></script> <script src="../testCompiledForWeb/broadcastClient.js"></script>

View File

@@ -18,7 +18,7 @@
mocha.ui('bdd') mocha.ui('bdd')
</script> </script>
<script src="../testCompiledForWeb/rippleClient.js"></script> <script src="../testCompiledForWeb/runClientTests.js"></script>
<script src="../testCompiledForWeb/broadcastClient.js"></script> <script src="../testCompiledForWeb/broadcastClient.js"></script>

View File

@@ -1,83 +0,0 @@
import { Client } from "xrpl-local";
import addresses from "./fixtures/addresses.json";
import setupClient from "./setupClient";
import { getAllPublicMethods, loadTestSuites } from "./testUtils";
/**
* Client Test Runner.
*
* Background: "test/api-test.ts" had hit 4000+ lines of test code and 300+
* individual tests. Additionally, a new address format was added which
* forced us to copy-paste duplicate the test file to test both the old forms
* of address. This added a significant maintenance burden.
*
* This test runner allows us to split our tests by Client method, and
* automatically load, validate, and run them. Each tests accepts arguments to
* test with, which allows us to re-run tests across different data
* (ex: different address styles).
*
* Additional benefits:
* - Throw errors when we detect the absence of tests.
* - Type the Client object under test and catch typing issues (currently untyped).
* - Sets the stage for more cleanup, like moving test-specific fixtures closer to their tests.
*/
describe("Client [Test Runner]", function () {
beforeEach(setupClient.setup);
afterEach(setupClient.teardown);
// Collect all the tests:
const allPublicMethods = getAllPublicMethods(new Client("wss://"));
// doesn't need the client, just needs to instantiate to get public methods
const allTestSuites = loadTestSuites();
// Run all the tests:
for (const { name: methodName, tests, config } of allTestSuites) {
describe(`${methodName}`, function () {
// Run each test that does not use an address.
for (const [testName, fn] of tests) {
if (fn.length === 1) {
it(testName, function () {
return fn(this.client, addresses.ACCOUNT, this.mockRippled);
});
}
}
// Run each test with a classic address.
describe(`[Classic Address]`, function () {
for (const [testName, fn] of tests) {
if (fn.length >= 2) {
it(testName, function () {
return fn(this.client, addresses.ACCOUNT, this.mockRippled);
});
}
}
});
// Run each test with an X-address.
if (!config.skipXAddress) {
describe(`[X-address]`, function () {
for (const [testName, fn] of tests) {
if (fn.length >= 2) {
it(testName, function () {
return fn(this.client, addresses.ACCOUNT_X, this.mockRippled);
});
}
}
});
}
});
}
// Report any missing tests.
const allTestedMethods = new Set(allTestSuites.map((s) => s.name));
for (const methodName of allPublicMethods) {
if (!allTestedMethods.has(methodName)) {
// TODO: Once migration is complete, remove `.skip()` so that missing tests are reported as failures.
it.skip(`${methodName} - no test suite found`, function () {
throw new Error(
`Test file not found! Create file "test/client/${methodName}/index.ts".`
);
});
}
}
});

73
test/runClientTests.ts Normal file
View File

@@ -0,0 +1,73 @@
import fs from "fs";
import path from "path";
import { Client } from "xrpl-local";
/**
* Client Test Runner.
*
* Throws errors when we detect the absence of tests.
* Puts all the client methods under one "describe" umbrella.
*/
describe("Client [Test Runner]", function () {
// doesn't need a functional client, just needs to instantiate to get a list of public methods
// (to determine what methods are missing from )
const allPublicMethods = getAllPublicMethods(new Client("wss://"));
const allTestSuites = loadTestSuites();
// Report any missing tests.
const allTestedMethods = new Set(allTestSuites.map((s) => s.name));
for (const methodName of allPublicMethods) {
if (!allTestedMethods.has(methodName)) {
// TODO: Once migration is complete, remove `.skip()` so that missing tests are reported as failures.
it.skip(`${methodName} - no test suite found`, function () {
throw new Error(
`Test file not found! Create file "test/client/${methodName}.ts".`
);
});
}
}
});
function getAllPublicMethods(client: Client) {
return Array.from(
new Set([
...Object.getOwnPropertyNames(client),
...Object.getOwnPropertyNames(Client.prototype),
])
).filter((key) => !key.startsWith("_")); // removes private methods
}
/**
* When the test suite is loaded, we represent it with the following
* data structure containing tests and metadata about the suite.
* If no test suite exists, we return this object with `isMissing: true`
* so that we can report it.
*/
interface LoadedTestSuite {
name: string;
tests: Array<[string, () => void | PromiseLike<void>]>;
}
function loadTestSuites(): LoadedTestSuite[] {
const allTests: any[] = fs.readdirSync(path.join(__dirname, "client"), {
encoding: "utf8",
});
return allTests
.map((methodName) => {
if (methodName.startsWith(".DS_Store")) {
return null;
}
if (methodName.endsWith(".ts")) {
methodName = methodName.slice(0, -3);
}
const testSuite = require(`./client/${methodName}`);
return {
name: methodName,
config: testSuite.config || {},
tests: Object.entries(testSuite.default || {}),
} as LoadedTestSuite;
})
.filter(Boolean) as LoadedTestSuite[];
}

View File

@@ -1,44 +1,17 @@
import fs from "fs";
import net from "net"; import net from "net";
import path from "path";
import { assert } from "chai"; import { assert } from "chai";
import _ from "lodash"; import _ from "lodash";
import { Client } from "xrpl-local"; import addresses from "./fixtures/addresses.json";
/** /**
* The test function. It takes a Client object and then some other data to * Setup to run tests on both classic addresses and X-addresses.
* test (currently: an address). May be called multiple times with different
* arguments, to test different types of data.
*/ */
export type TestFn = ( export const addressTests = [
client: Client, { type: "Classic Address", address: addresses.ACCOUNT },
address: string, { type: "X-Address", address: addresses.ACCOUNT_X },
mockRippled?: any ];
) => void | PromiseLike<void>;
/**
* A suite of tests to run. Maps the test name to the test function.
*/
export interface TestSuite {
[testName: string]: TestFn;
}
/**
* When the test suite is loaded, we represent it with the following
* data structure containing tests and metadata about the suite.
* If no test suite exists, we return this object with `isMissing: true`
* so that we can report it.
*/
interface LoadedTestSuite {
name: string;
tests: Array<[string, TestFn]>;
config: {
/** Set to true to skip re-running tests with an X-address. */
skipXAddress?: boolean;
};
}
/** /**
* Check the response against the expected result. Optionally validate * Check the response against the expected result. Optionally validate
@@ -119,37 +92,6 @@ export function getFreePort() {
}); });
} }
export function getAllPublicMethods(client: Client) {
return Array.from(
new Set([
...Object.getOwnPropertyNames(client),
...Object.getOwnPropertyNames(Client.prototype),
])
).filter((key) => !key.startsWith("_"));
}
export function loadTestSuites(): LoadedTestSuite[] {
const allTests: any[] = fs.readdirSync(path.join(__dirname, "client"), {
encoding: "utf8",
});
return allTests
.map((methodName) => {
if (methodName.startsWith(".DS_Store")) {
return null;
}
if (methodName.endsWith(".ts")) {
methodName = methodName.slice(0, -3);
}
const testSuite = require(`./client/${methodName}`);
return {
name: methodName,
config: testSuite.config || {},
tests: Object.entries(testSuite.default || {}),
} as LoadedTestSuite;
})
.filter(Boolean) as LoadedTestSuite[];
}
/** /**
* Ignore WebSocket DisconnectErrors. Useful for making requests where we don't * Ignore WebSocket DisconnectErrors. Useful for making requests where we don't
* care about the response and plan to teardown the test before the response * care about the response and plan to teardown the test before the response

View File

@@ -1,183 +1,188 @@
import {assert} from 'chai' import { assert } from "chai";
import ECDSA from '../../src/common/ecdsa'
import Wallet from '../../src/Wallet' import ECDSA from "../../src/common/ecdsa";
import Wallet from "../../src/Wallet";
/** /**
* Wallet testing * Wallet testing.
* *
* Provides tests for Wallet class * Provides tests for Wallet class.
*/ */
describe('Wallet', () => { describe("Wallet", function () {
describe('fromSeed', () => { describe("fromSeed", function () {
const seed = 'ssL9dv2W5RK8L3tuzQxYY6EaZhSxW' const seed = "ssL9dv2W5RK8L3tuzQxYY6EaZhSxW";
const publicKey = const publicKey =
'030E58CDD076E798C84755590AAF6237CA8FAE821070A59F648B517A30DC6F589D' "030E58CDD076E798C84755590AAF6237CA8FAE821070A59F648B517A30DC6F589D";
const privateKey = const privateKey =
'00141BA006D3363D2FB2785E8DF4E44D3A49908780CB4FB51F6D217C08C021429F' "00141BA006D3363D2FB2785E8DF4E44D3A49908780CB4FB51F6D217C08C021429F";
it('derives a wallet using default algorithm', () => {
const wallet = Wallet.fromSeed(seed)
assert.equal(wallet.publicKey, publicKey)
assert.equal(wallet.privateKey, privateKey)
})
it('derives a wallet using algorithm ecdsa-secp256k1', () => { it("derives a wallet using default algorithm", function () {
const algorithm = ECDSA.secp256k1 const wallet = Wallet.fromSeed(seed);
const wallet = Wallet.fromSeed(seed, algorithm)
assert.equal(wallet.publicKey, publicKey)
assert.equal(wallet.privateKey, privateKey)
})
it('derives a wallet using algorithm ed25519', () => { assert.equal(wallet.publicKey, publicKey);
const algorithm = ECDSA.ed25519 assert.equal(wallet.privateKey, privateKey);
const wallet = Wallet.fromSeed(seed, algorithm) });
assert.equal(wallet.publicKey, publicKey)
assert.equal(wallet.privateKey, privateKey)
})
})
describe('fromMnemonic', () => { it("derives a wallet using algorithm ecdsa-secp256k1", function () {
const mnemonic = const algorithm = ECDSA.secp256k1;
'try milk link drift aware pass obtain again music stick pluck fold' const wallet = Wallet.fromSeed(seed, algorithm);
const publicKey =
'0257B550BA2FDCCF0ADDA3DEB2A5411700F3ADFDCC7C68E1DCD1E2B63E6B0C63E6'
const privateKey =
'008F942B6E229C0E9CEE47E7A94253DABB6A9855F4BA2D8A741FA31851A1D423C3'
it('derives a wallet using default derivation path', () => {
const wallet = Wallet.fromMnemonic(mnemonic)
assert.equal(wallet.publicKey, publicKey)
assert.equal(wallet.privateKey, privateKey)
})
it('derives a wallet using an input derivation path', () => { assert.equal(wallet.publicKey, publicKey);
const derivationPath = "m/44'/144'/0'/0/0" assert.equal(wallet.privateKey, privateKey);
const wallet = Wallet.fromMnemonic(mnemonic, derivationPath) });
assert.equal(wallet.publicKey, publicKey)
assert.equal(wallet.privateKey, privateKey)
})
})
describe('fromEntropy', () => { it("derives a wallet using algorithm ed25519", function () {
const entropy: number[] = new Array(16).fill(0) const algorithm = ECDSA.ed25519;
const publicKey: string = const wallet = Wallet.fromSeed(seed, algorithm);
'0390A196799EE412284A5D80BF78C3E84CBB80E1437A0AECD9ADF94D7FEAAFA284'
const privateKey: string =
'002512BBDFDBB77510883B7DCCBEF270B86DEAC8B64AC762873D75A1BEE6298665'
const publicKeyED25519: string =
'ED1A7C082846CFF58FF9A892BA4BA2593151CCF1DBA59F37714CC9ED39824AF85F'
const privateKeyED25519: string =
'ED0B6CBAC838DFE7F47EA1BD0DF00EC282FDF45510C92161072CCFB84035390C4D'
it('derives a wallet using entropy', () => { assert.equal(wallet.publicKey, publicKey);
const wallet = Wallet.fromEntropy(entropy) assert.equal(wallet.privateKey, privateKey);
});
assert.equal(wallet.publicKey, publicKeyED25519) });
assert.equal(wallet.privateKey, privateKeyED25519)
})
it('derives a wallet using algorithm ecdsa-secp256k1', () => { describe("fromMnemonic", function () {
const algorithm = ECDSA.secp256k1 const mnemonic =
const wallet = Wallet.fromEntropy(entropy, algorithm) "try milk link drift aware pass obtain again music stick pluck fold";
const publicKey =
assert.equal(wallet.publicKey, publicKey) "0257B550BA2FDCCF0ADDA3DEB2A5411700F3ADFDCC7C68E1DCD1E2B63E6B0C63E6";
assert.equal(wallet.privateKey, privateKey) const privateKey =
}) "008F942B6E229C0E9CEE47E7A94253DABB6A9855F4BA2D8A741FA31851A1D423C3";
it('derives a wallet using algorithm ed25519', () => { it("derives a wallet using default derivation path", function () {
const algorithm = ECDSA.ed25519 const wallet = Wallet.fromMnemonic(mnemonic);
const wallet = Wallet.fromEntropy(entropy, algorithm)
assert.equal(wallet.publicKey, publicKeyED25519)
assert.equal(wallet.privateKey, privateKeyED25519)
})
})
describe('signTransaction', () => { assert.equal(wallet.publicKey, publicKey);
const publicKey = assert.equal(wallet.privateKey, privateKey);
'030E58CDD076E798C84755590AAF6237CA8FAE821070A59F648B517A30DC6F589D' });
const privateKey =
'00141BA006D3363D2FB2785E8DF4E44D3A49908780CB4FB51F6D217C08C021429F'
const address = 'rhvh5SrgBL5V8oeV9EpDuVszeJSSCEkbPc'
it('signs a transaction offline', () => {
const txJSON = {
TransactionType: 'Payment',
Account: address,
Destination: 'rQ3PTWGLCbPz8ZCicV5tCX3xuymojTng5r',
Amount: '20000000',
Sequence: 1,
Fee: '12',
SigningPubKey: publicKey
}
const wallet = new Wallet(publicKey, privateKey)
const signedTx: {signedTransaction: string; id: string} =
wallet.signTransaction(txJSON)
assert.hasAllKeys(signedTx, ['id', 'signedTransaction']) it("derives a wallet using an input derivation path", function () {
assert.isString(signedTx.id) const derivationPath = "m/44'/144'/0'/0/0";
assert.isString(signedTx.signedTransaction) const wallet = Wallet.fromMnemonic(mnemonic, derivationPath);
})
})
describe('verifyTransaction', () => { assert.equal(wallet.publicKey, publicKey);
const publicKey = assert.equal(wallet.privateKey, privateKey);
'030E58CDD076E798C84755590AAF6237CA8FAE821070A59F648B517A30DC6F589D' });
const privateKey = });
'00141BA006D3363D2FB2785E8DF4E44D3A49908780CB4FB51F6D217C08C021429F'
const prepared = {
signedTransaction:
'1200002400000001614000000001312D0068400000000000000C7321030E58CDD076E798C84755590AAF6237CA8FAE821070A59F648B517A30DC6F589D74473045022100CAF99A63B241F5F62B456C68A593D2835397101533BB5D0C4DC17362AC22046F022016A2CA2CF56E777B10E43B56541A4C2FB553E7E298CDD39F7A8A844DA491E51D81142AF1861DEC1316AEEC995C94FF9E2165B1B784608314FDB08D07AAA0EB711793A3027304D688E10C3648',
id: '30D9ECA2A7FB568C5A8607E5850D9567572A9E7C6094C26BEFD4DC4C2CF2657A'
}
it('returns true when verifying a transaction signed by the same wallet', () => {
const wallet = new Wallet(publicKey, privateKey)
const isVerified: boolean = wallet.verifyTransaction(prepared.signedTransaction)
assert.equal(isVerified, true)
})
it('returns false when verifying a transaction signed by a different wallet', () => { describe("fromEntropy", function () {
const diffPublicKey = const entropy: number[] = new Array(16).fill(0);
'02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8' const publicKey =
const diffPrivateKey = "0390A196799EE412284A5D80BF78C3E84CBB80E1437A0AECD9ADF94D7FEAAFA284";
'00ACCD3309DB14D1A4FC9B1DAE608031F4408C85C73EE05E035B7DC8B25840107A' const privateKey =
const wallet = new Wallet(diffPublicKey, diffPrivateKey) "002512BBDFDBB77510883B7DCCBEF270B86DEAC8B64AC762873D75A1BEE6298665";
const isVerified: boolean = wallet.verifyTransaction(prepared.signedTransaction) const publicKeyED25519 =
"ED1A7C082846CFF58FF9A892BA4BA2593151CCF1DBA59F37714CC9ED39824AF85F";
assert.equal(isVerified, false) const privateKeyED25519 =
}) "ED0B6CBAC838DFE7F47EA1BD0DF00EC282FDF45510C92161072CCFB84035390C4D";
})
describe('getXAddress', () => { it("derives a wallet using entropy", function () {
const publicKey = const wallet = Wallet.fromEntropy(entropy);
'030E58CDD076E798C84755590AAF6237CA8FAE821070A59F648B517A30DC6F589D'
const privateKey =
'00141BA006D3363D2FB2785E8DF4E44D3A49908780CB4FB51F6D217C08C021429F'
const wallet = new Wallet(publicKey, privateKey)
const tag = 1337
const mainnetXAddress = 'X7gJ5YK8abHf2eTPWPFHAAot8Knck11QGqmQ7a6a3Z8PJvk'
const testnetXAddress = 'T7bq3e7kxYq9pwDz8UZhqAZoEkcRGTXSNr5immvcj3DYRaV'
it('returns a Testnet X-address when test is true', () => {
const result = wallet.getXAddress(tag, true)
assert.equal(result, testnetXAddress)
})
it('returns a Mainnet X-address when test is false', () => {
const result = wallet.getXAddress(tag, false)
assert.equal(result, mainnetXAddress)
})
it("returns a Mainnet X-address when test isn't provided", () => { assert.equal(wallet.publicKey, publicKeyED25519);
const result = wallet.getXAddress(tag) assert.equal(wallet.privateKey, privateKeyED25519);
assert.equal(result, mainnetXAddress) });
})
}) it("derives a wallet using algorithm ecdsa-secp256k1", function () {
}) const algorithm = ECDSA.secp256k1;
const wallet = Wallet.fromEntropy(entropy, algorithm);
assert.equal(wallet.publicKey, publicKey);
assert.equal(wallet.privateKey, privateKey);
});
it("derives a wallet using algorithm ed25519", function () {
const algorithm = ECDSA.ed25519;
const wallet = Wallet.fromEntropy(entropy, algorithm);
assert.equal(wallet.publicKey, publicKeyED25519);
assert.equal(wallet.privateKey, privateKeyED25519);
});
});
describe("signTransaction", function () {
const publicKey =
"030E58CDD076E798C84755590AAF6237CA8FAE821070A59F648B517A30DC6F589D";
const privateKey =
"00141BA006D3363D2FB2785E8DF4E44D3A49908780CB4FB51F6D217C08C021429F";
const address = "rhvh5SrgBL5V8oeV9EpDuVszeJSSCEkbPc";
it("signs a transaction offline", function () {
const txJSON = {
TransactionType: "Payment",
Account: address,
Destination: "rQ3PTWGLCbPz8ZCicV5tCX3xuymojTng5r",
Amount: "20000000",
Sequence: 1,
Fee: "12",
SigningPubKey: publicKey,
};
const wallet = new Wallet(publicKey, privateKey);
const signedTx: { signedTransaction: string; id: string } =
wallet.signTransaction(txJSON);
assert.hasAllKeys(signedTx, ["id", "signedTransaction"]);
assert.isString(signedTx.id);
assert.isString(signedTx.signedTransaction);
});
});
describe("verifyTransaction", function () {
const publicKey =
"030E58CDD076E798C84755590AAF6237CA8FAE821070A59F648B517A30DC6F589D";
const privateKey =
"00141BA006D3363D2FB2785E8DF4E44D3A49908780CB4FB51F6D217C08C021429F";
const prepared = {
signedTransaction:
"1200002400000001614000000001312D0068400000000000000C7321030E58CDD076E798C84755590AAF6237CA8FAE821070A59F648B517A30DC6F589D74473045022100CAF99A63B241F5F62B456C68A593D2835397101533BB5D0C4DC17362AC22046F022016A2CA2CF56E777B10E43B56541A4C2FB553E7E298CDD39F7A8A844DA491E51D81142AF1861DEC1316AEEC995C94FF9E2165B1B784608314FDB08D07AAA0EB711793A3027304D688E10C3648",
id: "30D9ECA2A7FB568C5A8607E5850D9567572A9E7C6094C26BEFD4DC4C2CF2657A",
};
it("returns true when verifying a transaction signed by the same wallet", function () {
const wallet = new Wallet(publicKey, privateKey);
const isVerified: boolean = wallet.verifyTransaction(
prepared.signedTransaction
);
assert.equal(isVerified, true);
});
it("returns false when verifying a transaction signed by a different wallet", function () {
const diffPublicKey =
"02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8";
const diffPrivateKey =
"00ACCD3309DB14D1A4FC9B1DAE608031F4408C85C73EE05E035B7DC8B25840107A";
const wallet = new Wallet(diffPublicKey, diffPrivateKey);
const isVerified: boolean = wallet.verifyTransaction(
prepared.signedTransaction
);
assert.equal(isVerified, false);
});
});
describe("getXAddress", function () {
const publicKey =
"030E58CDD076E798C84755590AAF6237CA8FAE821070A59F648B517A30DC6F589D";
const privateKey =
"00141BA006D3363D2FB2785E8DF4E44D3A49908780CB4FB51F6D217C08C021429F";
const wallet = new Wallet(publicKey, privateKey);
const tag = 1337;
const mainnetXAddress = "X7gJ5YK8abHf2eTPWPFHAAot8Knck11QGqmQ7a6a3Z8PJvk";
const testnetXAddress = "T7bq3e7kxYq9pwDz8UZhqAZoEkcRGTXSNr5immvcj3DYRaV";
it("returns a Testnet X-address when test is true", function () {
const result = wallet.getXAddress(tag, true);
assert.equal(result, testnetXAddress);
});
it("returns a Mainnet X-address when test is false", function () {
const result = wallet.getXAddress(tag, false);
assert.equal(result, mainnetXAddress);
});
it("returns a Mainnet X-address when test isn't provided", function () {
const result = wallet.getXAddress(tag);
assert.equal(result, mainnetXAddress);
});
});
});