@ledgerhq/coin-xrp 7.3.0 → 7.4.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 +1 -1
- package/CHANGELOG.md +20 -0
- package/lib/api/index.d.ts.map +1 -1
- package/lib/api/index.integ.test.js +165 -8
- package/lib/api/index.integ.test.js.map +1 -1
- package/lib/api/index.js +14 -53
- package/lib/api/index.js.map +1 -1
- package/lib/api/index.test.js +16 -20
- package/lib/api/index.test.js.map +1 -1
- package/lib/logic/listOperations.js +1 -6
- package/lib/logic/listOperations.js.map +1 -1
- package/lib/logic/listOperations.test.js +2 -3
- package/lib/logic/listOperations.test.js.map +1 -1
- package/lib/types/model.d.ts +1 -2
- package/lib/types/model.d.ts.map +1 -1
- package/lib-es/api/index.d.ts.map +1 -1
- package/lib-es/api/index.integ.test.js +165 -8
- package/lib-es/api/index.integ.test.js.map +1 -1
- package/lib-es/api/index.js +14 -53
- package/lib-es/api/index.js.map +1 -1
- package/lib-es/api/index.test.js +16 -20
- package/lib-es/api/index.test.js.map +1 -1
- package/lib-es/logic/listOperations.js +1 -6
- package/lib-es/logic/listOperations.js.map +1 -1
- package/lib-es/logic/listOperations.test.js +2 -3
- package/lib-es/logic/listOperations.test.js.map +1 -1
- package/lib-es/types/model.d.ts +1 -2
- package/lib-es/types/model.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/api/index.integ.test.ts +190 -8
- package/src/api/index.test.ts +16 -20
- package/src/api/index.ts +16 -70
- package/src/logic/listOperations.test.ts +2 -4
- package/src/logic/listOperations.ts +1 -6
- package/src/types/model.ts +1 -1
|
@@ -35,7 +35,7 @@ describe("listOperations", () => {
|
|
|
35
35
|
// Given
|
|
36
36
|
mockNetworkGetTransactions.mockResolvedValue(mockNetworkTxs([]));
|
|
37
37
|
// When
|
|
38
|
-
const [results, token] = await listOperations("any address", { minHeight: 0 });
|
|
38
|
+
const [results, token] = await listOperations("any address", { minHeight: 0, order: "asc" });
|
|
39
39
|
// Then
|
|
40
40
|
expect(mockGetServerInfos).toHaveBeenCalledTimes(1);
|
|
41
41
|
expect(mockNetworkGetTransactions).toHaveBeenCalledTimes(1);
|
|
@@ -189,8 +189,7 @@ describe("listOperations", () => {
|
|
|
189
189
|
// Then
|
|
190
190
|
expect(mockGetServerInfos).toHaveBeenCalledTimes(1);
|
|
191
191
|
expect(mockNetworkGetTransactions).toHaveBeenCalledTimes(1);
|
|
192
|
-
|
|
193
|
-
const expectedValue = expectedType === "IN" ? BigInt(deliveredAmount) : BigInt(deliveredAmount + fees);
|
|
192
|
+
const expectedValue = BigInt(deliveredAmount);
|
|
194
193
|
expect(results).toEqual([
|
|
195
194
|
{
|
|
196
195
|
id: "HASH_VALUE",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"listOperations.test.js","sourceRoot":"","sources":["../../src/logic/listOperations.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAIvC,MAAM,SAAS,GAAG,CAAC,CAAC;AACpB,MAAM,SAAS,GAAG,CAAC,CAAC;AACpB,MAAM,kBAAkB,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC;IACrD,IAAI,EAAE;QACJ,gBAAgB,EAAE,GAAG,SAAS,IAAI,SAAS,EAAE;KAC9C;CACF,CAAC,CAAC;AACH,MAAM,0BAA0B,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;AAC7C,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,GAAG,EAAE,CAAC,CAAC;IAC7B,cAAc,EAAE,GAAG,EAAE,CAAC,kBAAkB,EAAE;IAC1C,eAAe,EAAE,GAAG,EAAE,CAAC,0BAA0B,EAAE;CACpD,CAAC,CAAC,CAAC;AAEJ,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,SAAS,CAAC,GAAG,EAAE;QACb,kBAAkB,CAAC,SAAS,EAAE,CAAC;QAC/B,0BAA0B,CAAC,SAAS,EAAE,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,MAAM,UAAU,GAAW,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;IACjD,SAAS,cAAc,CAAC,GAAY;QAClC,OAAO;YACL,OAAO,EAAE,SAAS;YAClB,gBAAgB,EAAE,CAAC;YACnB,gBAAgB,EAAE,CAAC;YACnB,KAAK,EAAE,CAAC;YACR,SAAS,EAAE,KAAK;YAChB,YAAY,EAAE,GAAG;YACjB,MAAM,EAAE,UAAU;YAClB,KAAK,EAAE,EAAE;SACV,CAAC;IACJ,CAAC;IAED,EAAE,CAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;QACvE,QAAQ;QACR,0BAA0B,CAAC,iBAAiB,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC,CAAC;QACjE,OAAO;QACP,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,GAAG,MAAM,cAAc,CAAC,aAAa,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"listOperations.test.js","sourceRoot":"","sources":["../../src/logic/listOperations.test.ts"],"names":[],"mappings":"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"}
|
package/lib-es/types/model.d.ts
CHANGED
|
@@ -16,12 +16,11 @@ export type XrpMemoValueMap = {
|
|
|
16
16
|
memos: string[];
|
|
17
17
|
};
|
|
18
18
|
export type XrpMapMemo = TypedMapMemo<XrpMemoValueMap>;
|
|
19
|
-
type Order = "asc" | "desc";
|
|
19
|
+
export type Order = "asc" | "desc";
|
|
20
20
|
export type ListOperationsOptions = {
|
|
21
21
|
limit?: number;
|
|
22
22
|
token?: string;
|
|
23
23
|
order?: Order;
|
|
24
24
|
minHeight?: number;
|
|
25
25
|
};
|
|
26
|
-
export {};
|
|
27
26
|
//# sourceMappingURL=model.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/types/model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAElE,MAAM,MAAM,WAAW,GAAG;IACxB,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,gBAAgB,GAAG,MAAM,CAAC;AAEpD,MAAM,MAAM,eAAe,GAAG;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB,CAAC;AACF,MAAM,MAAM,UAAU,GAAG,YAAY,CAAC,eAAe,CAAC,CAAC;AAEvD,
|
|
1
|
+
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/types/model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAElE,MAAM,MAAM,WAAW,GAAG;IACxB,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,gBAAgB,GAAG,MAAM,CAAC;AAEpD,MAAM,MAAM,eAAe,GAAG;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB,CAAC;AACF,MAAM,MAAM,UAAU,GAAG,YAAY,CAAC,eAAe,CAAC,CAAC;AAEvD,MAAM,MAAM,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;AAEnC,MAAM,MAAM,qBAAqB,GAAG;IAElC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,KAAK,CAAC;IAEd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ledgerhq/coin-xrp",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.4.0-nightly.1",
|
|
4
4
|
"description": "Ledger XRP Coin integration",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Ledger",
|
|
@@ -103,11 +103,11 @@
|
|
|
103
103
|
"invariant": "^2.2.4",
|
|
104
104
|
"ripple-address-codec": "^5.0.0",
|
|
105
105
|
"ripple-binary-codec": "^1.3.0",
|
|
106
|
-
"@ledgerhq/coin-framework": "^6.
|
|
107
|
-
"@ledgerhq/cryptoassets": "^13.
|
|
106
|
+
"@ledgerhq/coin-framework": "^6.4.0-nightly.1",
|
|
107
|
+
"@ledgerhq/cryptoassets": "^13.28.0-nightly.0",
|
|
108
108
|
"@ledgerhq/devices": "8.5.1",
|
|
109
109
|
"@ledgerhq/errors": "^6.25.0",
|
|
110
|
-
"@ledgerhq/live-network": "^2.0.
|
|
110
|
+
"@ledgerhq/live-network": "^2.0.17-nightly.0",
|
|
111
111
|
"@ledgerhq/types-live": "^6.83.0",
|
|
112
112
|
"@ledgerhq/logs": "^6.13.0"
|
|
113
113
|
},
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { decode } from "ripple-binary-codec";
|
|
2
2
|
import { createApi } from ".";
|
|
3
|
+
import { Operation } from "@ledgerhq/coin-framework/api/types";
|
|
3
4
|
//import { decode, encodeForSigning } from "ripple-binary-codec";
|
|
4
5
|
//import { sign } from "ripple-keypairs";
|
|
5
6
|
|
|
6
|
-
describe("Xrp Api", () => {
|
|
7
|
+
describe("Xrp Api (testnet)", () => {
|
|
7
8
|
const SENDER = "rh1HPuRVsYYvThxG2Bs1MfjmrVC73S16Fb";
|
|
8
9
|
const api = createApi({ node: "https://s.altnet.rippletest.net:51234" });
|
|
9
10
|
|
|
@@ -33,7 +34,7 @@ describe("Xrp Api", () => {
|
|
|
33
34
|
describe("listOperations", () => {
|
|
34
35
|
it.skip("returns a list regarding address parameter", async () => {
|
|
35
36
|
// When
|
|
36
|
-
const [tx, _] = await api.listOperations(SENDER, { minHeight: 200 });
|
|
37
|
+
const [tx, _] = await api.listOperations(SENDER, { minHeight: 200, order: "asc" });
|
|
37
38
|
|
|
38
39
|
// https://blockexplorer.one/xrp/testnet/address/rh1HPuRVsYYvThxG2Bs1MfjmrVC73S16Fb
|
|
39
40
|
// as of 2025-03-18, the address has 287 transactions
|
|
@@ -51,7 +52,10 @@ describe("Xrp Api", () => {
|
|
|
51
52
|
const SENDER_WITH_TRANSACTIONS = "rUxSkt6hQpWxXQwTNRUCYYRQ7BC2yRA3F8";
|
|
52
53
|
|
|
53
54
|
// When
|
|
54
|
-
const [ops, _] = await api.listOperations(SENDER_WITH_TRANSACTIONS, {
|
|
55
|
+
const [ops, _] = await api.listOperations(SENDER_WITH_TRANSACTIONS, {
|
|
56
|
+
minHeight: 0,
|
|
57
|
+
order: "asc",
|
|
58
|
+
});
|
|
55
59
|
// Then
|
|
56
60
|
const checkSet = new Set(ops.map(elt => elt.tx.hash));
|
|
57
61
|
expect(checkSet.size).toEqual(ops.length);
|
|
@@ -64,6 +68,21 @@ describe("Xrp Api", () => {
|
|
|
64
68
|
// so here we are checking that this limit is bypassed
|
|
65
69
|
expect(ops.length).toBeGreaterThan(200);
|
|
66
70
|
});
|
|
71
|
+
|
|
72
|
+
it("returns operations from latest, but in asc order", async () => {
|
|
73
|
+
// When
|
|
74
|
+
const SENDER_WITH_TRANSACTIONS = "rUxSkt6hQpWxXQwTNRUCYYRQ7BC2yRA3F8";
|
|
75
|
+
const [txDesc] = await api.listOperations(SENDER_WITH_TRANSACTIONS, {
|
|
76
|
+
minHeight: 200,
|
|
77
|
+
order: "desc",
|
|
78
|
+
});
|
|
79
|
+
expect(txDesc.length).toBeGreaterThanOrEqual(200);
|
|
80
|
+
// Then
|
|
81
|
+
// Check if the result is sorted in ascending order
|
|
82
|
+
expect(txDesc[0].tx.block.height).toBeGreaterThanOrEqual(
|
|
83
|
+
txDesc[txDesc.length - 1].tx.block.height,
|
|
84
|
+
);
|
|
85
|
+
});
|
|
67
86
|
});
|
|
68
87
|
|
|
69
88
|
describe("lastBlock", () => {
|
|
@@ -82,13 +101,13 @@ describe("Xrp Api", () => {
|
|
|
82
101
|
// Account with no transaction (at the time of this writing)
|
|
83
102
|
const SENDER_WITH_NO_TRANSACTION = "rKtXXTVno77jhu6tto1MAXjepyuaKaLcqB";
|
|
84
103
|
|
|
85
|
-
it("returns
|
|
104
|
+
it("returns a balance", async () => {
|
|
86
105
|
// When
|
|
87
106
|
const result = await api.getBalance(SENDER);
|
|
88
107
|
|
|
89
108
|
// Then
|
|
90
109
|
expect(result[0].asset).toEqual({ type: "native" });
|
|
91
|
-
expect(result[0].value).
|
|
110
|
+
expect(result[0].value).toBeGreaterThanOrEqual(BigInt(0));
|
|
92
111
|
});
|
|
93
112
|
|
|
94
113
|
it("returns 0 when address has no transaction", async () => {
|
|
@@ -105,7 +124,7 @@ describe("Xrp Api", () => {
|
|
|
105
124
|
|
|
106
125
|
it("returns a raw transaction", async () => {
|
|
107
126
|
// When
|
|
108
|
-
const result = await api.craftTransaction({
|
|
127
|
+
const { transaction: result } = await api.craftTransaction({
|
|
109
128
|
asset: { type: "native" },
|
|
110
129
|
type: "send",
|
|
111
130
|
sender: SENDER,
|
|
@@ -121,7 +140,170 @@ describe("Xrp Api", () => {
|
|
|
121
140
|
});
|
|
122
141
|
|
|
123
142
|
it("should use default fees when user does not provide them for crafting a transaction", async () => {
|
|
124
|
-
const result = await api.craftTransaction({
|
|
143
|
+
const { transaction: result } = await api.craftTransaction({
|
|
144
|
+
asset: { type: "native" },
|
|
145
|
+
type: "send",
|
|
146
|
+
sender: SENDER,
|
|
147
|
+
recipient: RECIPIENT,
|
|
148
|
+
amount: BigInt(10),
|
|
149
|
+
memo: {
|
|
150
|
+
type: "map",
|
|
151
|
+
memos: new Map(),
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
expect(decode(result)).toMatchObject({
|
|
156
|
+
Fee: "10",
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
it("should use custom user fees when user provides it for crafting a transaction", async () => {
|
|
161
|
+
const customFees = 99n;
|
|
162
|
+
const { transaction: result } = await api.craftTransaction(
|
|
163
|
+
{
|
|
164
|
+
asset: { type: "native" },
|
|
165
|
+
type: "send",
|
|
166
|
+
sender: SENDER,
|
|
167
|
+
recipient: RECIPIENT,
|
|
168
|
+
amount: BigInt(10),
|
|
169
|
+
memo: {
|
|
170
|
+
type: "map",
|
|
171
|
+
memos: new Map(),
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
{ value: customFees },
|
|
175
|
+
);
|
|
176
|
+
|
|
177
|
+
expect(decode(result)).toMatchObject({
|
|
178
|
+
Fee: customFees.toString(),
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
describe("Xrp Api (mainnet)", () => {
|
|
185
|
+
const SENDER = "rn5BQvhksnPfbo277LtFks4iyYStPKGrnJ";
|
|
186
|
+
const api = createApi({ node: "https://xrp.coin.ledger.com" });
|
|
187
|
+
|
|
188
|
+
describe("estimateFees", () => {
|
|
189
|
+
it("returns a default value", async () => {
|
|
190
|
+
// Given
|
|
191
|
+
const amount = BigInt(100);
|
|
192
|
+
|
|
193
|
+
// When
|
|
194
|
+
const result = await api.estimateFees({
|
|
195
|
+
asset: { type: "native" },
|
|
196
|
+
type: "send",
|
|
197
|
+
sender: SENDER,
|
|
198
|
+
amount,
|
|
199
|
+
recipient: "r9m6MwViR4GnUNqoGXGa8eroBrZ9FAPHFS",
|
|
200
|
+
memo: {
|
|
201
|
+
type: "map",
|
|
202
|
+
memos: new Map(),
|
|
203
|
+
},
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
// Then
|
|
207
|
+
expect(result.value).toEqual(BigInt(10));
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
describe("listOperations", () => {
|
|
212
|
+
let ops: Operation[];
|
|
213
|
+
|
|
214
|
+
beforeAll(async () => {
|
|
215
|
+
const resp = await api.listOperations(SENDER, { minHeight: 0 });
|
|
216
|
+
ops = resp[0];
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
it("returns operations", async () => {
|
|
220
|
+
// https://xrpscan.com/account/rn5BQvhksnPfbo277LtFks4iyYStPKGrnJ
|
|
221
|
+
expect(ops.length).toBeGreaterThanOrEqual(200);
|
|
222
|
+
const checkSet = new Set(ops.map(elt => elt.tx.hash));
|
|
223
|
+
expect(checkSet.size).toEqual(ops.length);
|
|
224
|
+
ops.forEach(operation => {
|
|
225
|
+
const isSenderOrReceipt =
|
|
226
|
+
operation.senders.includes(SENDER) || operation.recipients.includes(SENDER);
|
|
227
|
+
expect(isSenderOrReceipt).toBeTruthy();
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
it("returns IN operation", async () => {
|
|
232
|
+
// https://xrpscan.com/tx/805E371FDA0223E8910F831802EE93DBA1A4CA40AC8C1337F26F566CD67788F5
|
|
233
|
+
const inTx = {
|
|
234
|
+
hash: "9E5141DCAE8158E51ED612333FF3EC2D60A3D2DCD2F6DD5E4F92E4A6704C3CE9",
|
|
235
|
+
amount: 7.5,
|
|
236
|
+
recipient: SENDER,
|
|
237
|
+
sender: "rnXQmrXk9HSKdNwkut1k9dpAMVYuBsJV49",
|
|
238
|
+
type: "IN",
|
|
239
|
+
fees: 0.00001,
|
|
240
|
+
};
|
|
241
|
+
const op = ops.find(o => o.tx.hash === inTx.hash) as Operation;
|
|
242
|
+
expect(op.tx.hash).toEqual(inTx.hash);
|
|
243
|
+
expect(op.value).toEqual(BigInt(inTx.amount * 1e6));
|
|
244
|
+
expect(op.recipients).toContain(inTx.recipient);
|
|
245
|
+
expect(op.senders).toContain(inTx.sender);
|
|
246
|
+
expect(op.type).toEqual(inTx.type);
|
|
247
|
+
expect(op.tx.fees).toEqual(BigInt(inTx.fees * 1e6));
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
it("returns OUT operation", async () => {
|
|
251
|
+
// https://xrpscan.com/tx/8D13FD7EE0D28B615905903D033A3DC3839FBAA2F545417E3DE51A1A745C1688
|
|
252
|
+
const outTx = {
|
|
253
|
+
hash: "8D13FD7EE0D28B615905903D033A3DC3839FBAA2F545417E3DE51A1A745C1688",
|
|
254
|
+
amount: 0.1,
|
|
255
|
+
recipient: "r3XzsqzQCC6r4ZzifWnwa32sFR2H9exkew",
|
|
256
|
+
sender: SENDER,
|
|
257
|
+
type: "OUT",
|
|
258
|
+
fees: 0.00001,
|
|
259
|
+
};
|
|
260
|
+
const op = ops.find(o => o.tx.hash === outTx.hash) as Operation;
|
|
261
|
+
expect(op.tx.hash).toEqual(outTx.hash);
|
|
262
|
+
expect(op.value).toEqual(BigInt(outTx.amount * 1e6));
|
|
263
|
+
expect(op.recipients).toContain(outTx.recipient);
|
|
264
|
+
expect(op.senders).toContain(outTx.sender);
|
|
265
|
+
expect(op.type).toEqual(outTx.type);
|
|
266
|
+
expect(op.tx.fees).toEqual(BigInt(outTx.fees * 1e6));
|
|
267
|
+
});
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
describe("lastBlock", () => {
|
|
271
|
+
it("returns last block info", async () => {
|
|
272
|
+
const result = await api.lastBlock();
|
|
273
|
+
expect(result.hash).toBeDefined();
|
|
274
|
+
expect(result.height).toBeDefined();
|
|
275
|
+
expect(result.time).toBeInstanceOf(Date);
|
|
276
|
+
});
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
describe("getBalance", () => {
|
|
280
|
+
it("returns an amount", async () => {
|
|
281
|
+
const result = await api.getBalance(SENDER);
|
|
282
|
+
expect(result[0].asset).toEqual({ type: "native" });
|
|
283
|
+
expect(result[0].value).toBeGreaterThanOrEqual(BigInt(0));
|
|
284
|
+
});
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
describe("craftTransaction", () => {
|
|
288
|
+
const RECIPIENT = "r9m6MwViR4GnUNqoGXGa8eroBrZ9FAPHFS";
|
|
289
|
+
|
|
290
|
+
it("returns a raw transaction", async () => {
|
|
291
|
+
const { transaction: result } = await api.craftTransaction({
|
|
292
|
+
asset: { type: "native" },
|
|
293
|
+
type: "send",
|
|
294
|
+
sender: SENDER,
|
|
295
|
+
recipient: RECIPIENT,
|
|
296
|
+
amount: BigInt(10),
|
|
297
|
+
memo: {
|
|
298
|
+
type: "map",
|
|
299
|
+
memos: new Map([["memos", ["testdata"]]]),
|
|
300
|
+
},
|
|
301
|
+
});
|
|
302
|
+
expect(result.length).toEqual(178);
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
it("should use default fees when user does not provide them for crafting a transaction", async () => {
|
|
306
|
+
const { transaction: result } = await api.craftTransaction({
|
|
125
307
|
asset: { type: "native" },
|
|
126
308
|
type: "send",
|
|
127
309
|
sender: SENDER,
|
|
@@ -140,7 +322,7 @@ describe("Xrp Api", () => {
|
|
|
140
322
|
|
|
141
323
|
it("should use custom user fees when user provides it for crafting a transaction", async () => {
|
|
142
324
|
const customFees = 99n;
|
|
143
|
-
const result = await api.craftTransaction(
|
|
325
|
+
const { transaction: result } = await api.craftTransaction(
|
|
144
326
|
{
|
|
145
327
|
asset: { type: "native" },
|
|
146
328
|
type: "send",
|
package/src/api/index.test.ts
CHANGED
|
@@ -106,14 +106,13 @@ describe("listOperations", () => {
|
|
|
106
106
|
const txs = givenTxs(BigInt(10), BigInt(10), "src", "dest");
|
|
107
107
|
// each time it's called it returns a marker, so in theory it would loop forever
|
|
108
108
|
mockGetTransactions.mockResolvedValue(mockNetworkTxs(txs, defaultMarker));
|
|
109
|
-
const [results, _] = await api.listOperations("src", { minHeight: 0 });
|
|
109
|
+
const [results, _] = await api.listOperations("src", { minHeight: 0, order: "asc" });
|
|
110
110
|
|
|
111
|
-
// called
|
|
112
|
-
|
|
113
|
-
expect(
|
|
114
|
-
expect(mockGetTransactions).toHaveBeenCalledTimes(10);
|
|
111
|
+
// called 1 times because the client is expected to do the pagination itself
|
|
112
|
+
expect(mockGetServerInfos).toHaveBeenCalledTimes(1);
|
|
113
|
+
expect(mockGetTransactions).toHaveBeenCalledTimes(1);
|
|
115
114
|
|
|
116
|
-
expect(results.length).toBe(txs.length
|
|
115
|
+
expect(results.length).toBe(txs.length);
|
|
117
116
|
});
|
|
118
117
|
|
|
119
118
|
it("should pass the token returned by previous calls", async () => {
|
|
@@ -122,11 +121,10 @@ describe("listOperations", () => {
|
|
|
122
121
|
.mockReturnValueOnce(mockNetworkTxs(txs, defaultMarker))
|
|
123
122
|
.mockReturnValueOnce(mockNetworkTxs(txs, undefined));
|
|
124
123
|
|
|
125
|
-
const [results,
|
|
124
|
+
const [results, token] = await api.listOperations("src", { minHeight: 0, order: "asc" });
|
|
126
125
|
|
|
127
|
-
|
|
128
|
-
expect(
|
|
129
|
-
expect(mockGetTransactions).toHaveBeenCalledTimes(2);
|
|
126
|
+
expect(mockGetServerInfos).toHaveBeenCalledTimes(1);
|
|
127
|
+
expect(mockGetTransactions).toHaveBeenCalledTimes(1);
|
|
130
128
|
|
|
131
129
|
// check tokens are passed
|
|
132
130
|
const baseOptions = {
|
|
@@ -135,13 +133,14 @@ describe("listOperations", () => {
|
|
|
135
133
|
forward: true,
|
|
136
134
|
};
|
|
137
135
|
expect(mockGetTransactions).toHaveBeenNthCalledWith(1, "src", baseOptions);
|
|
136
|
+
await api.listOperations("src", { minHeight: 0, order: "asc", lastPagingToken: token });
|
|
138
137
|
const optionsWithToken = {
|
|
139
138
|
...baseOptions,
|
|
140
139
|
marker: defaultMarker,
|
|
141
140
|
};
|
|
142
141
|
expect(mockGetTransactions).toHaveBeenNthCalledWith(2, "src", optionsWithToken);
|
|
143
142
|
|
|
144
|
-
expect(results.length).toBe(txs.length
|
|
143
|
+
expect(results.length).toBe(txs.length);
|
|
145
144
|
});
|
|
146
145
|
|
|
147
146
|
it.each([
|
|
@@ -171,15 +170,12 @@ describe("listOperations", () => {
|
|
|
171
170
|
mockGetTransactions.mockResolvedValue(mockNetworkTxs([], undefined));
|
|
172
171
|
|
|
173
172
|
// When
|
|
174
|
-
const [results, _] = await api.listOperations(address, { minHeight: 0 });
|
|
173
|
+
const [results, _] = await api.listOperations(address, { minHeight: 0, order: "asc" });
|
|
175
174
|
|
|
176
175
|
// Then
|
|
177
|
-
|
|
178
|
-
expect(
|
|
179
|
-
expect(mockGetTransactions).toHaveBeenCalledTimes(2);
|
|
176
|
+
expect(mockGetServerInfos).toHaveBeenCalledTimes(1);
|
|
177
|
+
expect(mockGetTransactions).toHaveBeenCalledTimes(1);
|
|
180
178
|
|
|
181
|
-
// if expectedType is "OUT", compute value with fees (i.e. delivered_amount + Fee)
|
|
182
|
-
const expectedValue = expectedType === "IN" ? deliveredAmount : deliveredAmount + fee;
|
|
183
179
|
// the order is reversed so that the result is always sorted by newest tx first element of the list
|
|
184
180
|
expect(results).toEqual([
|
|
185
181
|
{
|
|
@@ -196,7 +192,7 @@ describe("listOperations", () => {
|
|
|
196
192
|
},
|
|
197
193
|
},
|
|
198
194
|
type: expectedType,
|
|
199
|
-
value:
|
|
195
|
+
value: deliveredAmount,
|
|
200
196
|
senders: [opSender],
|
|
201
197
|
recipients: [opDestination],
|
|
202
198
|
details: {
|
|
@@ -224,7 +220,7 @@ describe("listOperations", () => {
|
|
|
224
220
|
},
|
|
225
221
|
},
|
|
226
222
|
type: expectedType,
|
|
227
|
-
value:
|
|
223
|
+
value: deliveredAmount,
|
|
228
224
|
senders: [opSender],
|
|
229
225
|
recipients: [opDestination],
|
|
230
226
|
details: {
|
|
@@ -247,7 +243,7 @@ describe("listOperations", () => {
|
|
|
247
243
|
},
|
|
248
244
|
},
|
|
249
245
|
type: expectedType,
|
|
250
|
-
value:
|
|
246
|
+
value: deliveredAmount,
|
|
251
247
|
senders: [opSender],
|
|
252
248
|
recipients: [opDestination],
|
|
253
249
|
details: {
|
package/src/api/index.ts
CHANGED
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
Reward,
|
|
11
11
|
Stake,
|
|
12
12
|
TransactionIntent,
|
|
13
|
+
CraftedTransaction,
|
|
13
14
|
} from "@ledgerhq/coin-framework/api/index";
|
|
14
15
|
import { log } from "@ledgerhq/logs";
|
|
15
16
|
import coinConfig, { type XrpConfig } from "../config";
|
|
@@ -62,7 +63,7 @@ export function createApi(config: XrpConfig): Api<XrpMapMemo> {
|
|
|
62
63
|
async function craft(
|
|
63
64
|
transactionIntent: TransactionIntent<XrpMapMemo>,
|
|
64
65
|
customFees?: FeeEstimation,
|
|
65
|
-
): Promise<
|
|
66
|
+
): Promise<CraftedTransaction> {
|
|
66
67
|
const nextSequenceNumber = await getNextValidSequence(transactionIntent.sender);
|
|
67
68
|
const estimatedFees = customFees?.value ?? (await estimateFees()).fees;
|
|
68
69
|
|
|
@@ -94,7 +95,7 @@ async function craft(
|
|
|
94
95
|
transactionIntent.senderPublicKey,
|
|
95
96
|
);
|
|
96
97
|
|
|
97
|
-
return tx.serializedTransaction;
|
|
98
|
+
return { transaction: tx.serializedTransaction };
|
|
98
99
|
}
|
|
99
100
|
|
|
100
101
|
async function estimate(): Promise<FeeEstimation> {
|
|
@@ -102,75 +103,20 @@ async function estimate(): Promise<FeeEstimation> {
|
|
|
102
103
|
return { value: estimation.fees };
|
|
103
104
|
}
|
|
104
105
|
|
|
105
|
-
type PaginationState = {
|
|
106
|
-
readonly pageSize: number; // must be large enough to avoid unnecessary calls to the underlying explorer
|
|
107
|
-
readonly maxIterations: number; // a security to avoid infinite loop
|
|
108
|
-
currentIteration: number;
|
|
109
|
-
readonly minHeight: number;
|
|
110
|
-
continueIterations: boolean;
|
|
111
|
-
apiNextCursor?: string;
|
|
112
|
-
accumulator: Operation[];
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
async function operationsFromHeight(
|
|
116
|
-
address: string,
|
|
117
|
-
minHeight: number,
|
|
118
|
-
): Promise<[Operation[], string]> {
|
|
119
|
-
async function fetchNextPage(state: PaginationState): Promise<PaginationState> {
|
|
120
|
-
const options: ListOperationsOptions = {
|
|
121
|
-
limit: state.pageSize,
|
|
122
|
-
minHeight: state.minHeight,
|
|
123
|
-
order: "asc",
|
|
124
|
-
};
|
|
125
|
-
if (state.apiNextCursor) {
|
|
126
|
-
options.token = state.apiNextCursor;
|
|
127
|
-
}
|
|
128
|
-
const [operations, apiNextCursor] = await listOperations(address, options);
|
|
129
|
-
const newCurrentIteration = state.currentIteration + 1;
|
|
130
|
-
let continueIteration = true;
|
|
131
|
-
if (apiNextCursor === "") {
|
|
132
|
-
continueIteration = false;
|
|
133
|
-
} else if (newCurrentIteration >= state.maxIterations) {
|
|
134
|
-
log("coin:xrp", "(api/operations): max iterations reached", state.maxIterations);
|
|
135
|
-
continueIteration = false;
|
|
136
|
-
}
|
|
137
|
-
const accumulated = state.accumulator.concat(operations);
|
|
138
|
-
return {
|
|
139
|
-
...state,
|
|
140
|
-
currentIteration: newCurrentIteration,
|
|
141
|
-
continueIterations: continueIteration,
|
|
142
|
-
apiNextCursor: apiNextCursor,
|
|
143
|
-
accumulator: accumulated,
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
const firstState: PaginationState = {
|
|
148
|
-
pageSize: 200,
|
|
149
|
-
maxIterations: 10,
|
|
150
|
-
currentIteration: 0,
|
|
151
|
-
minHeight: minHeight,
|
|
152
|
-
continueIterations: true,
|
|
153
|
-
accumulator: [],
|
|
154
|
-
};
|
|
155
|
-
|
|
156
|
-
let state = await fetchNextPage(firstState);
|
|
157
|
-
while (state.continueIterations) {
|
|
158
|
-
state = await fetchNextPage(state);
|
|
159
|
-
}
|
|
160
|
-
return [state.accumulator, state.apiNextCursor ?? ""];
|
|
161
|
-
}
|
|
162
|
-
|
|
163
106
|
// NOTE: double check
|
|
164
107
|
async function operations(address: string, pagination: Pagination): Promise<[Operation[], string]> {
|
|
165
|
-
const { minHeight, lastPagingToken } = pagination;
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
const newPagination = {
|
|
172
|
-
minHeight: isInitSync ? 0 : parseInt(lastPagingToken || "0", 10),
|
|
108
|
+
const { minHeight, lastPagingToken, order } = pagination;
|
|
109
|
+
const options: ListOperationsOptions = {
|
|
110
|
+
limit: 200,
|
|
111
|
+
minHeight: minHeight,
|
|
112
|
+
order: order ?? "asc",
|
|
173
113
|
};
|
|
174
|
-
|
|
175
|
-
|
|
114
|
+
if (lastPagingToken) {
|
|
115
|
+
const token = lastPagingToken.split("-");
|
|
116
|
+
options.token = JSON.stringify({ ledger: Number(token[0]), seq: Number(token[1]) });
|
|
117
|
+
log(options.token);
|
|
118
|
+
}
|
|
119
|
+
const [operations, apiNextCursor] = await listOperations(address, options);
|
|
120
|
+
const next = apiNextCursor ? JSON.parse(apiNextCursor) : null;
|
|
121
|
+
return [operations, next ? next.ledger + "-" + next.seq : ""];
|
|
176
122
|
}
|
|
@@ -41,7 +41,7 @@ describe("listOperations", () => {
|
|
|
41
41
|
// Given
|
|
42
42
|
mockNetworkGetTransactions.mockResolvedValue(mockNetworkTxs([]));
|
|
43
43
|
// When
|
|
44
|
-
const [results, token] = await listOperations("any address", { minHeight: 0 });
|
|
44
|
+
const [results, token] = await listOperations("any address", { minHeight: 0, order: "asc" });
|
|
45
45
|
// Then
|
|
46
46
|
expect(mockGetServerInfos).toHaveBeenCalledTimes(1);
|
|
47
47
|
expect(mockNetworkGetTransactions).toHaveBeenCalledTimes(1);
|
|
@@ -215,9 +215,7 @@ describe("listOperations", () => {
|
|
|
215
215
|
// Then
|
|
216
216
|
expect(mockGetServerInfos).toHaveBeenCalledTimes(1);
|
|
217
217
|
expect(mockNetworkGetTransactions).toHaveBeenCalledTimes(1);
|
|
218
|
-
|
|
219
|
-
const expectedValue =
|
|
220
|
-
expectedType === "IN" ? BigInt(deliveredAmount) : BigInt(deliveredAmount + fees);
|
|
218
|
+
const expectedValue = BigInt(deliveredAmount);
|
|
221
219
|
expect(results).toEqual([
|
|
222
220
|
{
|
|
223
221
|
id: "HASH_VALUE",
|
|
@@ -120,17 +120,12 @@ const convertToCoreOperation =
|
|
|
120
120
|
} = operation;
|
|
121
121
|
|
|
122
122
|
const type = Account === address ? "OUT" : "IN";
|
|
123
|
-
|
|
123
|
+
const value =
|
|
124
124
|
delivered_amount && typeof delivered_amount === "string"
|
|
125
125
|
? BigInt(delivered_amount)
|
|
126
126
|
: BigInt(0);
|
|
127
127
|
|
|
128
128
|
const fees = BigInt(Fee);
|
|
129
|
-
if (type === "OUT") {
|
|
130
|
-
if (!Number.isNaN(fees)) {
|
|
131
|
-
value = value + fees;
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
129
|
|
|
135
130
|
const toEpochDate = (RIPPLE_EPOCH + date) * 1000;
|
|
136
131
|
|
package/src/types/model.ts
CHANGED