@ledgerhq/coin-xrp 0.9.2 → 1.0.0-nightly.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +2 -2
- package/CHANGELOG.md +11 -10
- package/lib/api/index.d.ts.map +1 -1
- package/lib/api/index.integ.test.js +35 -36
- package/lib/api/index.integ.test.js.map +1 -1
- package/lib/api/index.js +65 -50
- package/lib/api/index.js.map +1 -1
- package/lib/api/index.test.js +66 -44
- package/lib/api/index.test.js.map +1 -1
- package/lib/bridge/broadcast.js +3 -12
- package/lib/bridge/broadcast.js.map +1 -1
- package/lib/bridge/estimateMaxSpendable.js +9 -14
- package/lib/bridge/estimateMaxSpendable.js.map +1 -1
- package/lib/bridge/getTransactionStatus.js +4 -13
- package/lib/bridge/getTransactionStatus.js.map +1 -1
- package/lib/bridge/prepareTransaction.js +4 -13
- package/lib/bridge/prepareTransaction.js.map +1 -1
- package/lib/bridge/signOperation.js +60 -68
- package/lib/bridge/signOperation.js.map +1 -1
- package/lib/bridge/synchronization.js +32 -45
- package/lib/bridge/synchronization.js.map +1 -1
- package/lib/bridge/synchronization.test.js +21 -17
- package/lib/bridge/synchronization.test.js.map +1 -1
- package/lib/bridge/transaction.js +16 -4
- package/lib/bridge/transaction.js.map +1 -1
- package/lib/logic/broadcast.js +8 -19
- package/lib/logic/broadcast.js.map +1 -1
- package/lib/logic/broadcast.test.js +6 -15
- package/lib/logic/broadcast.test.js.map +1 -1
- package/lib/logic/combine.js +2 -2
- package/lib/logic/combine.js.map +1 -1
- package/lib/logic/craftTransaction.js +28 -34
- package/lib/logic/craftTransaction.js.map +1 -1
- package/lib/logic/craftTransaction.test.js +8 -17
- package/lib/logic/craftTransaction.test.js.map +1 -1
- package/lib/logic/estimateFees.js +17 -28
- package/lib/logic/estimateFees.js.map +1 -1
- package/lib/logic/estimateFees.test.js +10 -19
- package/lib/logic/estimateFees.test.js.map +1 -1
- package/lib/logic/getBalance.js +3 -14
- package/lib/logic/getBalance.js.map +1 -1
- package/lib/logic/getBalance.test.js +4 -13
- package/lib/logic/getBalance.test.js.map +1 -1
- package/lib/logic/lastBlock.js +7 -18
- package/lib/logic/lastBlock.js.map +1 -1
- package/lib/logic/listOperations.d.ts +15 -5
- package/lib/logic/listOperations.d.ts.map +1 -1
- package/lib/logic/listOperations.js +84 -71
- package/lib/logic/listOperations.js.map +1 -1
- package/lib/logic/listOperations.test.js +66 -62
- package/lib/logic/listOperations.test.js.map +1 -1
- package/lib/logic/utils.js +9 -18
- package/lib/logic/utils.js.map +1 -1
- package/lib/logic/utils.test.js +9 -18
- package/lib/logic/utils.test.js.map +1 -1
- package/lib/network/index.d.ts +6 -3
- package/lib/network/index.d.ts.map +1 -1
- package/lib/network/index.js +40 -48
- package/lib/network/index.js.map +1 -1
- package/lib/network/index.test.js +9 -18
- package/lib/network/index.test.js.map +1 -1
- package/lib/network/types.d.ts +5 -0
- package/lib/network/types.d.ts.map +1 -1
- package/lib/network/types.js.map +1 -1
- package/lib/signer/getAddress.js +3 -12
- package/lib/signer/getAddress.js.map +1 -1
- package/lib/test/cli.js +5 -1
- package/lib/test/cli.js.map +1 -1
- package/lib-es/api/index.d.ts.map +1 -1
- package/lib-es/api/index.integ.test.js +35 -36
- package/lib-es/api/index.integ.test.js.map +1 -1
- package/lib-es/api/index.js +65 -50
- package/lib-es/api/index.js.map +1 -1
- package/lib-es/api/index.test.js +66 -44
- package/lib-es/api/index.test.js.map +1 -1
- package/lib-es/bridge/broadcast.js +3 -12
- package/lib-es/bridge/broadcast.js.map +1 -1
- package/lib-es/bridge/estimateMaxSpendable.js +9 -14
- package/lib-es/bridge/estimateMaxSpendable.js.map +1 -1
- package/lib-es/bridge/getTransactionStatus.js +4 -13
- package/lib-es/bridge/getTransactionStatus.js.map +1 -1
- package/lib-es/bridge/prepareTransaction.js +4 -13
- package/lib-es/bridge/prepareTransaction.js.map +1 -1
- package/lib-es/bridge/signOperation.js +60 -68
- package/lib-es/bridge/signOperation.js.map +1 -1
- package/lib-es/bridge/synchronization.js +32 -45
- package/lib-es/bridge/synchronization.js.map +1 -1
- package/lib-es/bridge/synchronization.test.js +21 -17
- package/lib-es/bridge/synchronization.test.js.map +1 -1
- package/lib-es/bridge/transaction.js +16 -4
- package/lib-es/bridge/transaction.js.map +1 -1
- package/lib-es/logic/broadcast.js +8 -19
- package/lib-es/logic/broadcast.js.map +1 -1
- package/lib-es/logic/broadcast.test.js +6 -15
- package/lib-es/logic/broadcast.test.js.map +1 -1
- package/lib-es/logic/combine.js +2 -2
- package/lib-es/logic/combine.js.map +1 -1
- package/lib-es/logic/craftTransaction.js +28 -34
- package/lib-es/logic/craftTransaction.js.map +1 -1
- package/lib-es/logic/craftTransaction.test.js +8 -17
- package/lib-es/logic/craftTransaction.test.js.map +1 -1
- package/lib-es/logic/estimateFees.js +17 -28
- package/lib-es/logic/estimateFees.js.map +1 -1
- package/lib-es/logic/estimateFees.test.js +10 -19
- package/lib-es/logic/estimateFees.test.js.map +1 -1
- package/lib-es/logic/getBalance.js +3 -14
- package/lib-es/logic/getBalance.js.map +1 -1
- package/lib-es/logic/getBalance.test.js +4 -13
- package/lib-es/logic/getBalance.test.js.map +1 -1
- package/lib-es/logic/lastBlock.js +7 -18
- package/lib-es/logic/lastBlock.js.map +1 -1
- package/lib-es/logic/listOperations.d.ts +15 -5
- package/lib-es/logic/listOperations.d.ts.map +1 -1
- package/lib-es/logic/listOperations.js +84 -71
- package/lib-es/logic/listOperations.js.map +1 -1
- package/lib-es/logic/listOperations.test.js +66 -62
- package/lib-es/logic/listOperations.test.js.map +1 -1
- package/lib-es/logic/utils.js +9 -18
- package/lib-es/logic/utils.js.map +1 -1
- package/lib-es/logic/utils.test.js +9 -18
- package/lib-es/logic/utils.test.js.map +1 -1
- package/lib-es/network/index.d.ts +6 -3
- package/lib-es/network/index.d.ts.map +1 -1
- package/lib-es/network/index.js +39 -47
- package/lib-es/network/index.js.map +1 -1
- package/lib-es/network/index.test.js +9 -18
- package/lib-es/network/index.test.js.map +1 -1
- package/lib-es/network/types.d.ts +5 -0
- package/lib-es/network/types.d.ts.map +1 -1
- package/lib-es/network/types.js.map +1 -1
- package/lib-es/signer/getAddress.js +3 -12
- package/lib-es/signer/getAddress.js.map +1 -1
- package/lib-es/test/cli.js +5 -1
- package/lib-es/test/cli.js.map +1 -1
- package/package.json +7 -6
- package/src/api/index.integ.test.ts +12 -6
- package/src/api/index.test.ts +119 -75
- package/src/api/index.ts +62 -10
- package/src/bridge/synchronization.test.ts +31 -15
- package/src/logic/listOperations.test.ts +104 -85
- package/src/logic/listOperations.ts +47 -34
- package/src/network/index.ts +21 -8
- package/src/network/types.ts +6 -0
- package/tsconfig.json +0 -1
|
@@ -1,74 +1,79 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
1
|
import { getServerInfos, getTransactions } from "../network";
|
|
11
2
|
import { RIPPLE_EPOCH } from "./utils";
|
|
12
3
|
/**
|
|
13
4
|
* Returns list of "Payment" Operations associated to an account.
|
|
14
5
|
* @param address Account address
|
|
15
|
-
* @param
|
|
16
|
-
*
|
|
6
|
+
* @param minHeight retrieve operations from a specific block height until top most (inclusive)
|
|
7
|
+
* if not provided, it will start from the oldest possible history.
|
|
8
|
+
* The result is not guaranteed to contain all operations until top height (it depends of the underlying explorer),
|
|
9
|
+
* so you might need to call this function multiple times to get all operations.
|
|
10
|
+
* @param order whether to return operations from the top block or from the oldest block
|
|
11
|
+
* it defaults to "desc" (newest first)
|
|
12
|
+
* it doesn't control the order of the operations in the result list.
|
|
13
|
+
* this parameter is added as a workaround for the issue LIVE-16705
|
|
14
|
+
* @returns a list of operations is descending order and a token to be used for pagination
|
|
17
15
|
*/
|
|
18
|
-
export function listOperations(
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
16
|
+
export async function listOperations(address, { limit, minHeight, token, order, }) {
|
|
17
|
+
const serverInfo = await getServerInfos();
|
|
18
|
+
const ledgers = serverInfo.info.complete_ledgers.split("-");
|
|
19
|
+
const minLedgerVersion = Number(ledgers[0]);
|
|
20
|
+
// by default the explorer queries the transactions in descending order (newest first)
|
|
21
|
+
let forward = false;
|
|
22
|
+
if (order && order === "asc") {
|
|
23
|
+
forward = true;
|
|
24
|
+
}
|
|
25
|
+
let options = {
|
|
26
|
+
forward: forward,
|
|
27
|
+
};
|
|
28
|
+
if (limit) {
|
|
29
|
+
options = {
|
|
30
|
+
...options,
|
|
31
|
+
limit,
|
|
27
32
|
};
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
// then user misses some txs that doesn't fit the page size limit
|
|
55
|
-
// because the "next token" is a block height (solution is to use an opaque token instead)
|
|
56
|
-
let [txShortage, nextOptions, transactions] = yield getPaymentTransactions(address, options);
|
|
57
|
-
const isEnough = () => txShortage || (limit && transactions.length >= limit);
|
|
58
|
-
// We need to call the node RPC multiple times to get the desired number of transactions by the limiter.
|
|
59
|
-
while (nextOptions.limit && !isEnough()) {
|
|
60
|
-
const [newTxShortage, newNextOptions, newTransactions] = yield getPaymentTransactions(address, nextOptions);
|
|
61
|
-
txShortage = newTxShortage;
|
|
62
|
-
nextOptions = newNextOptions;
|
|
63
|
-
transactions = transactions.concat(newTransactions);
|
|
33
|
+
}
|
|
34
|
+
if (token) {
|
|
35
|
+
options = {
|
|
36
|
+
...options,
|
|
37
|
+
marker: JSON.parse(token),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
if (minHeight !== undefined) {
|
|
41
|
+
options = {
|
|
42
|
+
...options,
|
|
43
|
+
// if there is no ops, it might be after a clear and we prefer to pull from the oldest possible history
|
|
44
|
+
ledger_index_min: Math.max(minHeight, minLedgerVersion),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
async function getPaymentTransactions(address, options) {
|
|
48
|
+
const response = await getTransactions(address, options);
|
|
49
|
+
const txs = response.transactions;
|
|
50
|
+
const marker = response.marker;
|
|
51
|
+
// Filter out the transactions that are not "Payment" type because the filter on "tx_type" of the node RPC is not working as expected.
|
|
52
|
+
const paymentTxs = txs.filter(tx => tx.tx_json.TransactionType === "Payment");
|
|
53
|
+
const shortage = (options.limit && txs.length < options.limit) || false;
|
|
54
|
+
const nextOptions = { ...options };
|
|
55
|
+
if (marker) {
|
|
56
|
+
nextOptions.marker = marker;
|
|
57
|
+
if (nextOptions.limit)
|
|
58
|
+
nextOptions.limit -= paymentTxs.length;
|
|
64
59
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
60
|
+
return [shortage, nextOptions, paymentTxs];
|
|
61
|
+
}
|
|
62
|
+
let [txShortage, nextOptions, transactions] = await getPaymentTransactions(address, options);
|
|
63
|
+
const isEnough = () => txShortage || (limit && transactions.length >= limit);
|
|
64
|
+
// We need to call the node RPC multiple times to get the desired number of transactions by the limiter.
|
|
65
|
+
while (nextOptions.limit && !isEnough()) {
|
|
66
|
+
const [newTxShortage, newNextOptions, newTransactions] = await getPaymentTransactions(address, nextOptions);
|
|
67
|
+
txShortage = newTxShortage;
|
|
68
|
+
nextOptions = newNextOptions;
|
|
69
|
+
transactions = transactions.concat(newTransactions);
|
|
70
|
+
}
|
|
71
|
+
// the order is reversed so that the results are always sorted by newest tx first element of the list
|
|
72
|
+
if (order === "asc")
|
|
73
|
+
transactions.reverse();
|
|
74
|
+
// the next index to start the pagination from
|
|
75
|
+
const next = nextOptions.marker ? JSON.stringify(nextOptions.marker) : "";
|
|
76
|
+
return [transactions.map(convertToCoreOperation(address)), next];
|
|
72
77
|
}
|
|
73
78
|
const convertToCoreOperation = (address) => (operation) => {
|
|
74
79
|
const { ledger_hash, hash, close_time_iso, meta: { delivered_amount }, tx_json: { TransactionType, Fee, date, Account, Destination, DestinationTag, Sequence, Memos, ledger_index, }, } = operation;
|
|
@@ -85,20 +90,25 @@ const convertToCoreOperation = (address) => (operation) => {
|
|
|
85
90
|
const toEpochDate = (RIPPLE_EPOCH + date) * 1000;
|
|
86
91
|
let details = {};
|
|
87
92
|
if (DestinationTag) {
|
|
88
|
-
details =
|
|
93
|
+
details = {
|
|
94
|
+
...details,
|
|
95
|
+
destinationTag: DestinationTag,
|
|
96
|
+
};
|
|
89
97
|
}
|
|
90
|
-
const memos = Memos
|
|
91
|
-
var _a, _b, _c;
|
|
98
|
+
const memos = Memos?.map(m => {
|
|
92
99
|
const memo = {
|
|
93
|
-
data:
|
|
94
|
-
format:
|
|
95
|
-
type:
|
|
100
|
+
data: m?.Memo?.MemoData,
|
|
101
|
+
format: m?.Memo?.MemoFormat,
|
|
102
|
+
type: m?.Memo?.MemoType,
|
|
96
103
|
};
|
|
97
104
|
// Remove `undefined` properties
|
|
98
105
|
return Object.fromEntries(Object.entries(memo).filter(([, v]) => v));
|
|
99
106
|
});
|
|
100
107
|
if (memos) {
|
|
101
|
-
details =
|
|
108
|
+
details = {
|
|
109
|
+
...details,
|
|
110
|
+
memos,
|
|
111
|
+
};
|
|
102
112
|
}
|
|
103
113
|
let op = {
|
|
104
114
|
blockTime: new Date(close_time_iso),
|
|
@@ -116,7 +126,10 @@ const convertToCoreOperation = (address) => (operation) => {
|
|
|
116
126
|
transactionSequenceNumber: Sequence,
|
|
117
127
|
};
|
|
118
128
|
if (Object.keys(details).length != 0) {
|
|
119
|
-
op =
|
|
129
|
+
op = {
|
|
130
|
+
...op,
|
|
131
|
+
details,
|
|
132
|
+
};
|
|
120
133
|
}
|
|
121
134
|
return op;
|
|
122
135
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"listOperations.js","sourceRoot":"","sources":["../../src/logic/listOperations.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"listOperations.js","sourceRoot":"","sources":["../../src/logic/listOperations.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
1
|
import { assert } from "console";
|
|
11
2
|
import { listOperations } from "./listOperations";
|
|
12
3
|
import { RIPPLE_EPOCH } from "./utils";
|
|
@@ -17,41 +8,55 @@ const mockGetServerInfos = jest.fn().mockResolvedValue({
|
|
|
17
8
|
complete_ledgers: `${minHeight}-${maxHeight}`,
|
|
18
9
|
},
|
|
19
10
|
});
|
|
20
|
-
const
|
|
11
|
+
const mockNetworkGetTransactions = jest.fn();
|
|
21
12
|
jest.mock("../network", () => ({
|
|
22
13
|
getServerInfos: () => mockGetServerInfos(),
|
|
23
|
-
getTransactions: () =>
|
|
14
|
+
getTransactions: () => mockNetworkGetTransactions(),
|
|
24
15
|
}));
|
|
25
16
|
describe("listOperations", () => {
|
|
26
17
|
afterEach(() => {
|
|
27
18
|
mockGetServerInfos.mockClear();
|
|
28
|
-
|
|
19
|
+
mockNetworkGetTransactions.mockClear();
|
|
29
20
|
});
|
|
30
|
-
|
|
21
|
+
const someMarker = { ledger: 1, seq: 1 };
|
|
22
|
+
function mockNetworkTxs(txs) {
|
|
23
|
+
return {
|
|
24
|
+
account: "account",
|
|
25
|
+
ledger_index_max: 1,
|
|
26
|
+
ledger_index_min: 1,
|
|
27
|
+
limit: 1,
|
|
28
|
+
validated: false,
|
|
29
|
+
transactions: txs,
|
|
30
|
+
marker: someMarker,
|
|
31
|
+
error: "",
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
it("when there are no transactions then the result is empty", async () => {
|
|
31
35
|
// Given
|
|
32
|
-
|
|
36
|
+
mockNetworkGetTransactions.mockResolvedValue(mockNetworkTxs([]));
|
|
33
37
|
// When
|
|
34
|
-
const [results, token] =
|
|
38
|
+
const [results, token] = await listOperations("any address", { minHeight: 0 });
|
|
35
39
|
// Then
|
|
36
40
|
expect(mockGetServerInfos).toHaveBeenCalledTimes(1);
|
|
37
|
-
expect(
|
|
41
|
+
expect(mockNetworkGetTransactions).toHaveBeenCalledTimes(1);
|
|
38
42
|
expect(results).toEqual([]);
|
|
39
|
-
expect(token).toEqual(
|
|
40
|
-
})
|
|
41
|
-
it("when there are no transactions and a limit then the result is empty", () =>
|
|
43
|
+
expect(JSON.parse(token)).toEqual(someMarker);
|
|
44
|
+
});
|
|
45
|
+
it("when there are no transactions and a limit then the result is empty", async () => {
|
|
42
46
|
// Given
|
|
43
|
-
|
|
47
|
+
mockNetworkGetTransactions.mockResolvedValue(mockNetworkTxs([]));
|
|
44
48
|
// When
|
|
45
|
-
const [results, token] =
|
|
49
|
+
const [results, token] = await listOperations("any address", { minHeight: 0, limit: 1 });
|
|
46
50
|
// Then
|
|
47
51
|
expect(mockGetServerInfos).toHaveBeenCalledTimes(1);
|
|
48
|
-
expect(
|
|
52
|
+
expect(mockNetworkGetTransactions).toHaveBeenCalledTimes(1);
|
|
49
53
|
expect(results).toEqual([]);
|
|
50
|
-
expect(token).toEqual(
|
|
51
|
-
})
|
|
54
|
+
expect(JSON.parse(token)).toEqual(someMarker);
|
|
55
|
+
});
|
|
52
56
|
const paymentTx = {
|
|
53
57
|
ledger_hash: "HASH_VALUE_BLOCK",
|
|
54
58
|
hash: "HASH_VALUE",
|
|
59
|
+
validated: true,
|
|
55
60
|
close_time_iso: "2000-01-01T00:00:01Z",
|
|
56
61
|
meta: { delivered_amount: "100" },
|
|
57
62
|
tx_json: {
|
|
@@ -64,45 +69,44 @@ describe("listOperations", () => {
|
|
|
64
69
|
Sequence: 1,
|
|
65
70
|
},
|
|
66
71
|
};
|
|
67
|
-
const otherTx =
|
|
68
|
-
it("should only list operations of type payment", () =>
|
|
72
|
+
const otherTx = { ...paymentTx, tx_json: { ...paymentTx.tx_json, TransactionType: "Other" } };
|
|
73
|
+
it("should only list operations of type payment", async () => {
|
|
69
74
|
// Given
|
|
70
75
|
const lastTransaction = paymentTx;
|
|
71
|
-
|
|
72
|
-
|
|
76
|
+
const txs = [paymentTx, otherTx, lastTransaction];
|
|
77
|
+
mockNetworkGetTransactions.mockResolvedValueOnce(mockNetworkTxs(txs));
|
|
78
|
+
mockNetworkGetTransactions.mockResolvedValue(mockNetworkTxs([])); // subsequent calls
|
|
73
79
|
// When
|
|
74
|
-
const [results, token] =
|
|
80
|
+
const [results, token] = await listOperations("any address", { minHeight: 0, limit: 3 });
|
|
75
81
|
// Then
|
|
76
82
|
expect(mockGetServerInfos).toHaveBeenCalledTimes(1);
|
|
77
83
|
// it's called twice because first call yields only 2 transactions, and 3 are asked
|
|
78
|
-
expect(
|
|
84
|
+
expect(mockNetworkGetTransactions).toHaveBeenCalledTimes(2);
|
|
79
85
|
expect(results.length).toEqual(2);
|
|
80
|
-
expect(token).toEqual(
|
|
81
|
-
})
|
|
82
|
-
it("should make enough calls so that the limit requested is satified", () =>
|
|
83
|
-
const lastTransaction = otherTx;
|
|
86
|
+
expect(JSON.parse(token)).toEqual(someMarker);
|
|
87
|
+
});
|
|
88
|
+
it("should make enough calls so that the limit requested is satified", async () => {
|
|
84
89
|
const txs = [paymentTx, paymentTx, otherTx, otherTx, otherTx, otherTx, otherTx, otherTx];
|
|
85
90
|
assert(txs.length === 8);
|
|
86
|
-
|
|
87
|
-
const [results, token] =
|
|
91
|
+
mockNetworkGetTransactions.mockResolvedValue(mockNetworkTxs(txs));
|
|
92
|
+
const [results, token] = await listOperations("any address", { minHeight: 0, limit: 8 });
|
|
88
93
|
expect(mockGetServerInfos).toHaveBeenCalledTimes(1);
|
|
89
94
|
// it's called 4 times because each call yields only 2 transactions, and 8 are asked
|
|
90
|
-
expect(
|
|
95
|
+
expect(mockNetworkGetTransactions).toHaveBeenCalledTimes(4);
|
|
91
96
|
expect(results.length).toEqual(8);
|
|
92
|
-
expect(token).toEqual(
|
|
93
|
-
})
|
|
94
|
-
it("should make enough calls, even if there is not enough txs to satisfy the limit", () =>
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
const
|
|
99
|
-
const [results, token] = yield listOperations("any address", { minHeight: 0, limit: 4 });
|
|
97
|
+
expect(JSON.parse(token)).toEqual(someMarker);
|
|
98
|
+
});
|
|
99
|
+
it("should make enough calls, even if there is not enough txs to satisfy the limit", async () => {
|
|
100
|
+
mockNetworkGetTransactions.mockResolvedValueOnce(mockNetworkTxs([otherTx, otherTx, otherTx, otherTx]));
|
|
101
|
+
mockNetworkGetTransactions.mockResolvedValueOnce(mockNetworkTxs([paymentTx, paymentTx]));
|
|
102
|
+
mockNetworkGetTransactions.mockResolvedValue([]); // subsequent calls
|
|
103
|
+
const [results, token] = await listOperations("any address", { minHeight: 0, limit: 4 });
|
|
100
104
|
expect(mockGetServerInfos).toHaveBeenCalledTimes(1);
|
|
101
105
|
// it's called 2 times because the second call is a shortage of txs
|
|
102
|
-
expect(
|
|
106
|
+
expect(mockNetworkGetTransactions).toHaveBeenCalledTimes(2);
|
|
103
107
|
expect(results.length).toEqual(2);
|
|
104
|
-
expect(token).toEqual(
|
|
105
|
-
})
|
|
108
|
+
expect(JSON.parse(token)).toEqual(someMarker);
|
|
109
|
+
});
|
|
106
110
|
it.each([
|
|
107
111
|
{
|
|
108
112
|
address: "WHATEVER_ADDRESS",
|
|
@@ -116,11 +120,11 @@ describe("listOperations", () => {
|
|
|
116
120
|
opDestination: "destination_addr",
|
|
117
121
|
expectedType: "OUT",
|
|
118
122
|
},
|
|
119
|
-
])("should return the list of operations associated to an account",
|
|
123
|
+
])("should return the list of operations associated to an account", async ({ address, opSender, opDestination, expectedType }) => {
|
|
120
124
|
// Given
|
|
121
125
|
const deliveredAmount = 100;
|
|
122
126
|
const fee = 10;
|
|
123
|
-
|
|
127
|
+
mockNetworkGetTransactions.mockResolvedValue(mockNetworkTxs([
|
|
124
128
|
{
|
|
125
129
|
ledger_hash: "HASH_VALUE_BLOCK",
|
|
126
130
|
hash: "HASH_VALUE",
|
|
@@ -175,12 +179,12 @@ describe("listOperations", () => {
|
|
|
175
179
|
Sequence: 1,
|
|
176
180
|
},
|
|
177
181
|
},
|
|
178
|
-
]);
|
|
182
|
+
]));
|
|
179
183
|
// When
|
|
180
|
-
const [results, _] =
|
|
184
|
+
const [results, _] = await listOperations(address, { minHeight: 0, order: "asc" });
|
|
181
185
|
// Then
|
|
182
186
|
expect(mockGetServerInfos).toHaveBeenCalledTimes(1);
|
|
183
|
-
expect(
|
|
187
|
+
expect(mockNetworkGetTransactions).toHaveBeenCalledTimes(1);
|
|
184
188
|
// if expectedType is "OUT", compute value with fees (i.e. delivered_amount + Fee)
|
|
185
189
|
const expectedValue = expectedType === "IN" ? BigInt(deliveredAmount) : BigInt(deliveredAmount + fee);
|
|
186
190
|
expect(results).toEqual([
|
|
@@ -198,6 +202,14 @@ describe("listOperations", () => {
|
|
|
198
202
|
recipients: [opDestination],
|
|
199
203
|
date: new Date(1000000 + RIPPLE_EPOCH * 1000),
|
|
200
204
|
transactionSequenceNumber: 1,
|
|
205
|
+
details: {
|
|
206
|
+
memos: [
|
|
207
|
+
{
|
|
208
|
+
type: "687474703a2f2f6578616d706c652e636f6d2f6d656d6f2f67656e65726963",
|
|
209
|
+
data: "72656e74",
|
|
210
|
+
},
|
|
211
|
+
],
|
|
212
|
+
},
|
|
201
213
|
},
|
|
202
214
|
{
|
|
203
215
|
hash: "HASH_VALUE",
|
|
@@ -231,16 +243,8 @@ describe("listOperations", () => {
|
|
|
231
243
|
recipients: [opDestination],
|
|
232
244
|
date: new Date(1000000 + RIPPLE_EPOCH * 1000),
|
|
233
245
|
transactionSequenceNumber: 1,
|
|
234
|
-
details: {
|
|
235
|
-
memos: [
|
|
236
|
-
{
|
|
237
|
-
type: "687474703a2f2f6578616d706c652e636f6d2f6d656d6f2f67656e65726963",
|
|
238
|
-
data: "72656e74",
|
|
239
|
-
},
|
|
240
|
-
],
|
|
241
|
-
},
|
|
242
246
|
},
|
|
243
247
|
]);
|
|
244
|
-
})
|
|
248
|
+
});
|
|
245
249
|
});
|
|
246
250
|
//# sourceMappingURL=listOperations.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"listOperations.test.js","sourceRoot":"","sources":["../../src/logic/listOperations.test.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"listOperations.test.js","sourceRoot":"","sources":["../../src/logic/listOperations.test.ts"],"names":[],"mappings":"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"}
|
package/lib-es/logic/utils.js
CHANGED
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
1
|
import BigNumber from "bignumber.js";
|
|
11
2
|
import { isValidClassicAddress } from "ripple-address-codec";
|
|
12
3
|
import { getAccountInfo } from "../network";
|
|
@@ -16,26 +7,26 @@ export const RIPPLE_EPOCH = 946684800;
|
|
|
16
7
|
export const validateTag = (tag) => {
|
|
17
8
|
return (!tag.isNaN() && tag.isFinite() && tag.isInteger() && tag.isPositive() && tag.lte(UINT32_MAX));
|
|
18
9
|
};
|
|
19
|
-
export const getNextValidSequence = (address) =>
|
|
20
|
-
const accInfo =
|
|
10
|
+
export const getNextValidSequence = async (address) => {
|
|
11
|
+
const accInfo = await getAccountInfo(address, true);
|
|
21
12
|
return accInfo.sequence;
|
|
22
|
-
}
|
|
13
|
+
};
|
|
23
14
|
function isRecipientValid(recipient) {
|
|
24
15
|
return isValidClassicAddress(recipient);
|
|
25
16
|
}
|
|
26
|
-
const recipientIsNew = (recipient) =>
|
|
17
|
+
const recipientIsNew = async (recipient) => {
|
|
27
18
|
if (!isRecipientValid(recipient))
|
|
28
19
|
return false;
|
|
29
|
-
const info =
|
|
20
|
+
const info = await getAccountInfo(recipient);
|
|
30
21
|
return info.isNewAccount;
|
|
31
|
-
}
|
|
22
|
+
};
|
|
32
23
|
const cacheRecipientsNew = {};
|
|
33
|
-
export const cachedRecipientIsNew = (recipient) =>
|
|
24
|
+
export const cachedRecipientIsNew = async (recipient) => {
|
|
34
25
|
if (recipient in cacheRecipientsNew)
|
|
35
26
|
return cacheRecipientsNew[recipient];
|
|
36
|
-
cacheRecipientsNew[recipient] =
|
|
27
|
+
cacheRecipientsNew[recipient] = await recipientIsNew(recipient);
|
|
37
28
|
return cacheRecipientsNew[recipient];
|
|
38
|
-
}
|
|
29
|
+
};
|
|
39
30
|
export const removeCachedRecipientIsNew = (recipient) => {
|
|
40
31
|
delete cacheRecipientsNew[recipient];
|
|
41
32
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/logic/utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/logic/utils.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,cAAc,CAAC;AACrC,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5C,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAE5D,kEAAkE;AAClE,MAAM,CAAC,MAAM,YAAY,GAAG,SAAS,CAAC;AAEtC,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,GAAc,EAAE,EAAE;IAC5C,OAAO,CACL,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,GAAG,CAAC,QAAQ,EAAE,IAAI,GAAG,CAAC,SAAS,EAAE,IAAI,GAAG,CAAC,UAAU,EAAE,IAAI,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAC7F,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,EAAE,OAAe,EAAE,EAAE;IAC5D,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACpD,OAAO,OAAO,CAAC,QAAQ,CAAC;AAC1B,CAAC,CAAC;AAEF,SAAS,gBAAgB,CAAC,SAAiB;IACzC,OAAO,qBAAqB,CAAC,SAAS,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,cAAc,GAAG,KAAK,EAAE,SAAiB,EAAoB,EAAE;IACnE,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC;QAAE,OAAO,KAAK,CAAC;IAE/C,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,SAAS,CAAC,CAAC;IAC7C,OAAO,IAAI,CAAC,YAAY,CAAC;AAC3B,CAAC,CAAC;AAEF,MAAM,kBAAkB,GAA4B,EAAE,CAAC;AACvD,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,EAAE,SAAiB,EAAE,EAAE;IAC9D,IAAI,SAAS,IAAI,kBAAkB;QAAE,OAAO,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAC1E,kBAAkB,CAAC,SAAS,CAAC,GAAG,MAAM,cAAc,CAAC,SAAS,CAAC,CAAC;IAChE,OAAO,kBAAkB,CAAC,SAAS,CAAC,CAAC;AACvC,CAAC,CAAC;AACF,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,SAAiB,EAAE,EAAE;IAC9D,OAAO,kBAAkB,CAAC,SAAS,CAAC,CAAC;AACvC,CAAC,CAAC"}
|
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
1
|
import { cachedRecipientIsNew } from "./utils";
|
|
11
2
|
jest.mock("ripple-address-codec", () => ({
|
|
12
3
|
isValidClassicAddress: () => true,
|
|
@@ -19,7 +10,7 @@ describe("cachedRecipientIsNew", () => {
|
|
|
19
10
|
afterEach(() => {
|
|
20
11
|
mockGetAccountInfo.mockClear();
|
|
21
12
|
});
|
|
22
|
-
it("returns true when network returns a new empty account", () =>
|
|
13
|
+
it("returns true when network returns a new empty account", async () => {
|
|
23
14
|
// Given
|
|
24
15
|
mockGetAccountInfo.mockResolvedValueOnce({
|
|
25
16
|
isNewAccount: true,
|
|
@@ -28,12 +19,12 @@ describe("cachedRecipientIsNew", () => {
|
|
|
28
19
|
sequence: 0,
|
|
29
20
|
});
|
|
30
21
|
// When
|
|
31
|
-
const result =
|
|
22
|
+
const result = await cachedRecipientIsNew("address1");
|
|
32
23
|
// Then
|
|
33
24
|
expect(mockGetAccountInfo).toHaveBeenCalledTimes(1);
|
|
34
25
|
expect(result).toBeTruthy();
|
|
35
|
-
})
|
|
36
|
-
it("returns false when network a valid AccountInfo", () =>
|
|
26
|
+
});
|
|
27
|
+
it("returns false when network a valid AccountInfo", async () => {
|
|
37
28
|
// Given
|
|
38
29
|
mockGetAccountInfo.mockResolvedValueOnce({
|
|
39
30
|
isNewAccount: false,
|
|
@@ -42,19 +33,19 @@ describe("cachedRecipientIsNew", () => {
|
|
|
42
33
|
sequence: 999441667919804,
|
|
43
34
|
});
|
|
44
35
|
// When
|
|
45
|
-
const result =
|
|
36
|
+
const result = await cachedRecipientIsNew("address2");
|
|
46
37
|
// Then
|
|
47
38
|
expect(mockGetAccountInfo).toHaveBeenCalledTimes(1);
|
|
48
39
|
expect(result).toBeFalsy();
|
|
49
|
-
})
|
|
50
|
-
it("throws an error when network throws an error", () =>
|
|
40
|
+
});
|
|
41
|
+
it("throws an error when network throws an error", async () => {
|
|
51
42
|
// Given
|
|
52
43
|
mockGetAccountInfo.mockImplementationOnce(() => {
|
|
53
44
|
throw new Error("Malformed address");
|
|
54
45
|
});
|
|
55
46
|
// When & Then
|
|
56
|
-
|
|
47
|
+
await expect(cachedRecipientIsNew("address3")).rejects.toThrow("Malformed address");
|
|
57
48
|
expect(mockGetAccountInfo).toHaveBeenCalledTimes(1);
|
|
58
|
-
})
|
|
49
|
+
});
|
|
59
50
|
});
|
|
60
51
|
//# sourceMappingURL=utils.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.test.js","sourceRoot":"","sources":["../../src/logic/utils.test.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"utils.test.js","sourceRoot":"","sources":["../../src/logic/utils.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAE/C,IAAI,CAAC,IAAI,CAAC,sBAAsB,EAAE,GAAG,EAAE,CAAC,CAAC;IACvC,qBAAqB,EAAE,GAAG,EAAE,CAAC,IAAI;CAClC,CAAC,CAAC,CAAC;AACJ,MAAM,kBAAkB,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;AACrC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,GAAG,EAAE,CAAC,CAAC;IAC7B,cAAc,EAAE,CAAC,OAAe,EAAE,EAAE,CAAC,kBAAkB,CAAC,OAAO,CAAC;CACjE,CAAC,CAAC,CAAC;AAEJ,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACpC,SAAS,CAAC,GAAG,EAAE;QACb,kBAAkB,CAAC,SAAS,EAAE,CAAC;IACjC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;QACrE,QAAQ;QACR,kBAAkB,CAAC,qBAAqB,CAAC;YACvC,YAAY,EAAE,IAAI;YAClB,OAAO,EAAE,GAAG;YACZ,UAAU,EAAE,CAAC;YACb,QAAQ,EAAE,CAAC;SACZ,CAAC,CAAC;QAEH,OAAO;QACP,MAAM,MAAM,GAAG,MAAM,oBAAoB,CAAC,UAAU,CAAC,CAAC;QAEtD,OAAO;QACP,MAAM,CAAC,kBAAkB,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QACpD,MAAM,CAAC,MAAM,CAAC,CAAC,UAAU,EAAE,CAAC;IAC9B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;QAC9D,QAAQ;QACR,kBAAkB,CAAC,qBAAqB,CAAC;YACvC,YAAY,EAAE,KAAK;YACnB,OAAO,EAAE,iBAAiB;YAC1B,UAAU,EAAE,CAAC;YACb,QAAQ,EAAE,eAAe;SAC1B,CAAC,CAAC;QAEH,OAAO;QACP,MAAM,MAAM,GAAG,MAAM,oBAAoB,CAAC,UAAU,CAAC,CAAC;QAEtD,OAAO;QACP,MAAM,CAAC,kBAAkB,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QACpD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;QAC5D,QAAQ;QACR,kBAAkB,CAAC,sBAAsB,CAAC,GAAG,EAAE;YAC7C,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,cAAc;QACd,MAAM,MAAM,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;QACpF,MAAM,CAAC,kBAAkB,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|