@ledgerhq/coin-xrp 3.2.0 → 4.0.0-next.0

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.
Files changed (82) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/lib/api/index.d.ts +7 -1
  3. package/lib/api/index.d.ts.map +1 -1
  4. package/lib/api/index.integ.test.js +7 -2
  5. package/lib/api/index.integ.test.js.map +1 -1
  6. package/lib/api/index.js +2 -0
  7. package/lib/api/index.js.map +1 -1
  8. package/lib/api/index.test.js +19 -0
  9. package/lib/api/index.test.js.map +1 -1
  10. package/lib/bridge/synchronization.js.map +1 -1
  11. package/lib/logic/craftTransaction.d.ts +1 -1
  12. package/lib/logic/craftTransaction.d.ts.map +1 -1
  13. package/lib/logic/getBalance.d.ts +3 -1
  14. package/lib/logic/getBalance.d.ts.map +1 -1
  15. package/lib/logic/getBalance.js +1 -1
  16. package/lib/logic/getBalance.js.map +1 -1
  17. package/lib/logic/getBalance.test.js +1 -1
  18. package/lib/logic/getBalance.test.js.map +1 -1
  19. package/lib/logic/index.d.ts +1 -0
  20. package/lib/logic/index.d.ts.map +1 -1
  21. package/lib/logic/index.js.map +1 -1
  22. package/lib/logic/listOperations.d.ts +2 -2
  23. package/lib/logic/listOperations.d.ts.map +1 -1
  24. package/lib/logic/listOperations.js +3 -1
  25. package/lib/logic/listOperations.js.map +1 -1
  26. package/lib/logic/listOperations.test.js +11 -1
  27. package/lib/logic/listOperations.test.js.map +1 -1
  28. package/lib/types/assets.d.ts +3 -0
  29. package/lib/types/assets.d.ts.map +1 -0
  30. package/lib/types/assets.js +3 -0
  31. package/lib/types/assets.js.map +1 -0
  32. package/lib/types/index.d.ts +1 -0
  33. package/lib/types/index.d.ts.map +1 -1
  34. package/lib/types/index.js +1 -0
  35. package/lib/types/index.js.map +1 -1
  36. package/lib-es/api/index.d.ts +7 -1
  37. package/lib-es/api/index.d.ts.map +1 -1
  38. package/lib-es/api/index.integ.test.js +7 -2
  39. package/lib-es/api/index.integ.test.js.map +1 -1
  40. package/lib-es/api/index.js +2 -0
  41. package/lib-es/api/index.js.map +1 -1
  42. package/lib-es/api/index.test.js +19 -0
  43. package/lib-es/api/index.test.js.map +1 -1
  44. package/lib-es/bridge/synchronization.js.map +1 -1
  45. package/lib-es/logic/craftTransaction.d.ts +1 -1
  46. package/lib-es/logic/craftTransaction.d.ts.map +1 -1
  47. package/lib-es/logic/getBalance.d.ts +3 -1
  48. package/lib-es/logic/getBalance.d.ts.map +1 -1
  49. package/lib-es/logic/getBalance.js +1 -1
  50. package/lib-es/logic/getBalance.js.map +1 -1
  51. package/lib-es/logic/getBalance.test.js +1 -1
  52. package/lib-es/logic/getBalance.test.js.map +1 -1
  53. package/lib-es/logic/index.d.ts +1 -0
  54. package/lib-es/logic/index.d.ts.map +1 -1
  55. package/lib-es/logic/index.js.map +1 -1
  56. package/lib-es/logic/listOperations.d.ts +2 -2
  57. package/lib-es/logic/listOperations.d.ts.map +1 -1
  58. package/lib-es/logic/listOperations.js +3 -1
  59. package/lib-es/logic/listOperations.js.map +1 -1
  60. package/lib-es/logic/listOperations.test.js +11 -1
  61. package/lib-es/logic/listOperations.test.js.map +1 -1
  62. package/lib-es/types/assets.d.ts +3 -0
  63. package/lib-es/types/assets.d.ts.map +1 -0
  64. package/lib-es/types/assets.js +2 -0
  65. package/lib-es/types/assets.js.map +1 -0
  66. package/lib-es/types/index.d.ts +1 -0
  67. package/lib-es/types/index.d.ts.map +1 -1
  68. package/lib-es/types/index.js +1 -0
  69. package/lib-es/types/index.js.map +1 -1
  70. package/package.json +5 -5
  71. package/src/api/index.integ.test.ts +7 -2
  72. package/src/api/index.test.ts +34 -5
  73. package/src/api/index.ts +14 -6
  74. package/src/bridge/synchronization.ts +5 -2
  75. package/src/logic/craftTransaction.ts +1 -1
  76. package/src/logic/getBalance.test.ts +1 -1
  77. package/src/logic/getBalance.ts +4 -2
  78. package/src/logic/index.ts +1 -0
  79. package/src/logic/listOperations.test.ts +13 -2
  80. package/src/logic/listOperations.ts +7 -4
  81. package/src/types/assets.ts +3 -0
  82. package/src/types/index.ts +1 -0
@@ -1,8 +1,8 @@
1
1
  import { Operation, TransactionIntent } from "@ledgerhq/coin-framework/api/types";
2
2
  import * as LogicFunctions from "../logic";
3
3
  import { GetTransactionsOptions } from "../network";
4
- import { NetworkInfo } from "../types";
5
- import { createApi } from "./index";
4
+ import { NetworkInfo, XrpAsset } from "../types";
5
+ import { createApi, TransactionIntentExtra } from "./index";
6
6
 
7
7
  const mockGetServerInfos = jest.fn().mockResolvedValue({
8
8
  info: {
@@ -183,6 +183,7 @@ describe("listOperations", () => {
183
183
  // the order is reversed so that the result is always sorted by newest tx first element of the list
184
184
  expect(results).toEqual([
185
185
  {
186
+ asset: { type: "native" },
186
187
  operationIndex: 0,
187
188
  tx: {
188
189
  hash: "HASH_VALUE",
@@ -210,6 +211,7 @@ describe("listOperations", () => {
210
211
  },
211
212
  },
212
213
  {
214
+ asset: { type: "native" },
213
215
  operationIndex: 0,
214
216
  tx: {
215
217
  hash: "HASH_VALUE",
@@ -232,6 +234,7 @@ describe("listOperations", () => {
232
234
  },
233
235
  },
234
236
  {
237
+ asset: { type: "native" },
235
238
  operationIndex: 0,
236
239
  tx: {
237
240
  hash: "HASH_VALUE",
@@ -252,7 +255,7 @@ describe("listOperations", () => {
252
255
  sequence: 1,
253
256
  },
254
257
  },
255
- ] satisfies Operation<void>[]);
258
+ ] satisfies Operation<XrpAsset>[]);
256
259
  },
257
260
  );
258
261
  });
@@ -281,7 +284,7 @@ describe("Testing craftTransaction function", () => {
281
284
 
282
285
  it("should use custom user fees when user provides it for crafting a transaction", async () => {
283
286
  const customFees = 99n;
284
- await api.craftTransaction({} as TransactionIntent<void>, customFees);
287
+ await api.craftTransaction({} as TransactionIntent<XrpAsset>, customFees);
285
288
 
286
289
  expect(logicCraftTransactionSpy).toHaveBeenCalledWith(
287
290
  expect.any(Object),
@@ -292,7 +295,7 @@ describe("Testing craftTransaction function", () => {
292
295
  });
293
296
 
294
297
  it("should use default fees when user does not provide them for crafting a transaction", async () => {
295
- await api.craftTransaction({} as TransactionIntent<void>);
298
+ await api.craftTransaction({} as TransactionIntent<XrpAsset>);
296
299
 
297
300
  expect(logicCraftTransactionSpy).toHaveBeenCalledWith(
298
301
  expect.any(Object),
@@ -301,4 +304,30 @@ describe("Testing craftTransaction function", () => {
301
304
  }),
302
305
  );
303
306
  });
307
+
308
+ it("should pass memos when user provides it for crafting a transaction", async () => {
309
+ await api.craftTransaction({
310
+ memos: [{ data: "testdata", format: "testformat", type: "testtype" }],
311
+ } as TransactionIntent<XrpAsset, TransactionIntentExtra>);
312
+
313
+ expect(logicCraftTransactionSpy).toHaveBeenCalledWith(
314
+ expect.any(Object),
315
+ expect.objectContaining({
316
+ memos: [{ data: "testdata", format: "testformat", type: "testtype" }],
317
+ }),
318
+ );
319
+ });
320
+
321
+ it("should pass destination tag when user provides it for crafting a transaction", async () => {
322
+ await api.craftTransaction({
323
+ destinationTag: 1337,
324
+ } as TransactionIntent<XrpAsset, TransactionIntentExtra>);
325
+
326
+ expect(logicCraftTransactionSpy).toHaveBeenCalledWith(
327
+ expect.any(Object),
328
+ expect.objectContaining({
329
+ destinationTag: 1337,
330
+ }),
331
+ );
332
+ });
304
333
  });
package/src/api/index.ts CHANGED
@@ -15,10 +15,11 @@ import {
15
15
  getNextValidSequence,
16
16
  lastBlock,
17
17
  listOperations,
18
+ MemoInput,
18
19
  } from "../logic";
19
- import { ListOperationsOptions } from "../types";
20
+ import { ListOperationsOptions, XrpAsset } from "../types";
20
21
 
21
- export function createApi(config: XrpConfig): Api<void> {
22
+ export function createApi(config: XrpConfig): Api<XrpAsset> {
22
23
  coinConfig.setCoinConfig(() => ({ ...config, status: { type: "active" } }));
23
24
 
24
25
  return {
@@ -32,8 +33,13 @@ export function createApi(config: XrpConfig): Api<void> {
32
33
  };
33
34
  }
34
35
 
36
+ export type TransactionIntentExtra = {
37
+ destinationTag?: number | null | undefined;
38
+ memos?: MemoInput[];
39
+ };
40
+
35
41
  async function craft(
36
- transactionIntent: TransactionIntent<void>,
42
+ transactionIntent: TransactionIntent<XrpAsset, TransactionIntentExtra>,
37
43
  customFees?: bigint,
38
44
  ): Promise<string> {
39
45
  const nextSequenceNumber = await getNextValidSequence(transactionIntent.sender);
@@ -44,6 +50,8 @@ async function craft(
44
50
  recipient: transactionIntent.recipient,
45
51
  amount: transactionIntent.amount,
46
52
  fee: estimatedFees,
53
+ destinationTag: transactionIntent.destinationTag,
54
+ memos: transactionIntent.memos ?? [],
47
55
  },
48
56
  );
49
57
  return tx.serializedTransaction;
@@ -56,13 +64,13 @@ type PaginationState = {
56
64
  readonly minHeight: number;
57
65
  continueIterations: boolean;
58
66
  apiNextCursor?: string;
59
- accumulator: Operation<void>[];
67
+ accumulator: Operation<XrpAsset>[];
60
68
  };
61
69
 
62
70
  async function operationsFromHeight(
63
71
  address: string,
64
72
  minHeight: number,
65
- ): Promise<[Operation<void>[], string]> {
73
+ ): Promise<[Operation<XrpAsset>[], string]> {
66
74
  async function fetchNextPage(state: PaginationState): Promise<PaginationState> {
67
75
  const options: ListOperationsOptions = {
68
76
  limit: state.pageSize,
@@ -110,7 +118,7 @@ async function operationsFromHeight(
110
118
  async function operations(
111
119
  address: string,
112
120
  { minHeight }: Pagination,
113
- ): Promise<[Operation<void>[], string]> {
121
+ ): Promise<[Operation<XrpAsset>[], string]> {
114
122
  // TODO token must be implemented properly (waiting ack from the design document)
115
123
  return await operationsFromHeight(address, minHeight);
116
124
  }
@@ -7,7 +7,7 @@ import BigNumber from "bignumber.js";
7
7
  import { listOperations, parseAPIValue } from "../logic";
8
8
  import { getAccountInfo, getServerInfos } from "../network";
9
9
  import { ServerInfoResponse } from "../network/types";
10
- import { AccountInfo } from "../types";
10
+ import { AccountInfo, XrpAsset } from "../types";
11
11
 
12
12
  export const getAccountShape: GetAccountShape = async info => {
13
13
  const { address, initialAccount, currency, derivationMode } = info;
@@ -69,7 +69,10 @@ async function filterOperations(
69
69
  return operations.map(op => adaptCoreOperationToLiveOperation(accountId, op) satisfies Operation);
70
70
  }
71
71
 
72
- function adaptCoreOperationToLiveOperation(accountId: string, op: CoreOperation<void>): Operation {
72
+ function adaptCoreOperationToLiveOperation(
73
+ accountId: string,
74
+ op: CoreOperation<XrpAsset>,
75
+ ): Operation {
73
76
  return {
74
77
  id: encodeOperationId(accountId, op.tx.hash, op.type),
75
78
  hash: op.tx.hash,
@@ -31,7 +31,7 @@ type XrplTransaction = {
31
31
  Memos?: MemoWrapper[];
32
32
  };
33
33
 
34
- type MemoInput = {
34
+ export type MemoInput = {
35
35
  data?: string;
36
36
  format?: string;
37
37
  type?: string;
@@ -25,6 +25,6 @@ describe("getBalance", () => {
25
25
  // Then
26
26
  expect(mockGetAccountInfo).toHaveBeenCalledTimes(1);
27
27
  expect(mockGetAccountInfo.mock.lastCall[0]).toEqual(address);
28
- expect(result).toEqual(balance);
28
+ expect(result).toEqual([{ value: balance, asset: { type: "native" } }]);
29
29
  });
30
30
  });
@@ -1,6 +1,8 @@
1
+ import { Balance } from "@ledgerhq/coin-framework/api/types";
1
2
  import { getAccountInfo } from "../network";
3
+ import { XrpAsset } from "../types";
2
4
 
3
- export async function getBalance(address: string): Promise<bigint> {
5
+ export async function getBalance(address: string): Promise<Balance<XrpAsset>[]> {
4
6
  const accountInfo = await getAccountInfo(address);
5
- return BigInt(accountInfo.balance);
7
+ return [{ value: BigInt(accountInfo.balance), asset: { type: "native" } }];
6
8
  }
@@ -1,6 +1,7 @@
1
1
  export { broadcast } from "./broadcast";
2
2
  export { combine } from "./combine";
3
3
  export { craftTransaction } from "./craftTransaction";
4
+ export type { MemoInput } from "./craftTransaction";
4
5
  export { estimateFees } from "./estimateFees";
5
6
  export { getBalance } from "./getBalance";
6
7
  export { lastBlock } from "./lastBlock";
@@ -3,6 +3,7 @@ import { listOperations } from "./listOperations";
3
3
  import { RIPPLE_EPOCH } from "./utils";
4
4
  import { Marker } from "../network/types";
5
5
  import { Operation } from "@ledgerhq/coin-framework/api/types";
6
+ import { XrpAsset } from "../types";
6
7
 
7
8
  const maxHeight = 2;
8
9
  const minHeight = 1;
@@ -75,6 +76,7 @@ describe("listOperations", () => {
75
76
  Account: "sender",
76
77
  Destination: "dest",
77
78
  Sequence: 1,
79
+ SigningPubKey: "DEADBEEF",
78
80
  },
79
81
  };
80
82
  const otherTx = { ...paymentTx, tx_json: { ...paymentTx.tx_json, TransactionType: "Other" } };
@@ -97,7 +99,7 @@ describe("listOperations", () => {
97
99
  expect(JSON.parse(token)).toEqual(someMarker);
98
100
  });
99
101
 
100
- it("should make enough calls so that the limit requested is satified", async () => {
102
+ it("should make enough calls so that the limit requested is satisfied", async () => {
101
103
  const txs = [paymentTx, paymentTx, otherTx, otherTx, otherTx, otherTx, otherTx, otherTx];
102
104
  assert(txs.length === 8);
103
105
  mockNetworkGetTransactions.mockResolvedValue(mockNetworkTxs(txs));
@@ -161,6 +163,7 @@ describe("listOperations", () => {
161
163
  Account: opSender,
162
164
  Destination: opDestination,
163
165
  Sequence: 1,
166
+ SigningPubKey: "DEADBEEF",
164
167
  },
165
168
  },
166
169
  {
@@ -177,6 +180,7 @@ describe("listOperations", () => {
177
180
  Destination: opDestination,
178
181
  DestinationTag: 509555,
179
182
  Sequence: 1,
183
+ SigningPubKey: "DEADBEEF",
180
184
  },
181
185
  },
182
186
  {
@@ -200,6 +204,7 @@ describe("listOperations", () => {
200
204
  },
201
205
  ],
202
206
  Sequence: 1,
207
+ SigningPubKey: "DEADBEEF",
203
208
  },
204
209
  },
205
210
  ]),
@@ -216,6 +221,7 @@ describe("listOperations", () => {
216
221
  expectedType === "IN" ? BigInt(deliveredAmount) : BigInt(deliveredAmount + fee);
217
222
  expect(results).toEqual([
218
223
  {
224
+ asset: { type: "native" },
219
225
  operationIndex: 0,
220
226
  tx: {
221
227
  fees: BigInt(10),
@@ -240,9 +246,11 @@ describe("listOperations", () => {
240
246
  data: "72656e74",
241
247
  },
242
248
  ],
249
+ signingPubKey: "DEADBEEF",
243
250
  },
244
251
  },
245
252
  {
253
+ asset: { type: "native" },
246
254
  operationIndex: 0,
247
255
  tx: {
248
256
  hash: "HASH_VALUE",
@@ -262,9 +270,11 @@ describe("listOperations", () => {
262
270
  sequence: 1,
263
271
  destinationTag: 509555,
264
272
  xrpTxType: "Payment",
273
+ signingPubKey: "DEADBEEF",
265
274
  },
266
275
  },
267
276
  {
277
+ asset: { type: "native" },
268
278
  tx: {
269
279
  hash: "HASH_VALUE",
270
280
  fees: BigInt(10),
@@ -278,6 +288,7 @@ describe("listOperations", () => {
278
288
  details: {
279
289
  sequence: 1,
280
290
  xrpTxType: "Payment",
291
+ signingPubKey: "DEADBEEF",
281
292
  },
282
293
  type: expectedType,
283
294
  value: expectedValue,
@@ -285,7 +296,7 @@ describe("listOperations", () => {
285
296
  recipients: [opDestination],
286
297
  operationIndex: 0,
287
298
  },
288
- ] satisfies Operation<void>[]);
299
+ ] satisfies Operation<XrpAsset>[]);
289
300
  },
290
301
  );
291
302
  });
@@ -1,7 +1,7 @@
1
1
  import { Operation } from "@ledgerhq/coin-framework/api/types";
2
2
  import { getServerInfos, getTransactions, GetTransactionsOptions } from "../network";
3
3
  import type { XrplOperation } from "../network/types";
4
- import { ListOperationsOptions, XrpMemo } from "../types";
4
+ import { ListOperationsOptions, XrpAsset, XrpMemo } from "../types";
5
5
  import { RIPPLE_EPOCH } from "./utils";
6
6
 
7
7
  /**
@@ -20,7 +20,7 @@ import { RIPPLE_EPOCH } from "./utils";
20
20
  export async function listOperations(
21
21
  address: string,
22
22
  { limit, minHeight, token, order }: ListOperationsOptions,
23
- ): Promise<[Operation<void>[], string]> {
23
+ ): Promise<[Operation<XrpAsset>[], string]> {
24
24
  const serverInfo = await getServerInfos();
25
25
  const ledgers = serverInfo.info.complete_ledgers.split("-");
26
26
  const minLedgerVersion = Number(ledgers[0]);
@@ -99,7 +99,7 @@ export async function listOperations(
99
99
 
100
100
  const convertToCoreOperation =
101
101
  (address: string) =>
102
- (operation: XrplOperation): Operation<void> => {
102
+ (operation: XrplOperation): Operation<XrpAsset> => {
103
103
  const {
104
104
  ledger_hash,
105
105
  hash,
@@ -115,6 +115,7 @@ const convertToCoreOperation =
115
115
  Memos,
116
116
  ledger_index,
117
117
  Sequence,
118
+ SigningPubKey,
118
119
  },
119
120
  } = operation;
120
121
 
@@ -161,9 +162,11 @@ const convertToCoreOperation =
161
162
  ...details,
162
163
  xrpTxType: TransactionType,
163
164
  sequence: Sequence,
165
+ signingPubKey: SigningPubKey,
164
166
  };
165
167
 
166
- let op: Operation<void> = {
168
+ let op: Operation<XrpAsset> = {
169
+ asset: { type: "native" },
167
170
  operationIndex: 0,
168
171
  tx: {
169
172
  hash: hash,
@@ -0,0 +1,3 @@
1
+ import { Asset } from "@ledgerhq/coin-framework/api/types";
2
+
3
+ export type XrpAsset = Asset;
@@ -1,3 +1,4 @@
1
+ export * from "./assets";
1
2
  export * from "./bridge";
2
3
  export * from "./model";
3
4
  export * from "./signer";