@ledgerhq/coin-xrp 7.24.0 → 7.25.2
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/CHANGELOG.md +24 -0
- package/lib/api/craftRawTransaction.d.ts.map +1 -1
- package/lib/api/craftRawTransaction.js +2 -1
- package/lib/api/craftRawTransaction.js.map +1 -1
- package/lib/api/index.d.ts.map +1 -1
- package/lib/api/index.js +5 -1
- package/lib/api/index.js.map +1 -1
- package/lib/api/listOperations.js +1 -1
- package/lib/api/listOperations.js.map +1 -1
- package/lib/network/index.d.ts +1 -1
- package/lib/network/index.d.ts.map +1 -1
- package/lib/network/index.js +4 -5
- package/lib/network/index.js.map +1 -1
- package/lib/network/types.d.ts +0 -1
- package/lib/network/types.d.ts.map +1 -1
- package/lib/network/types.js +0 -4
- package/lib/network/types.js.map +1 -1
- package/lib/utils/predicates.d.ts +5 -0
- package/lib/utils/predicates.d.ts.map +1 -0
- package/lib/utils/predicates.js +23 -0
- package/lib/utils/predicates.js.map +1 -0
- package/lib-es/api/craftRawTransaction.d.ts.map +1 -1
- package/lib-es/api/craftRawTransaction.js +2 -1
- package/lib-es/api/craftRawTransaction.js.map +1 -1
- package/lib-es/api/index.d.ts.map +1 -1
- package/lib-es/api/index.js +5 -1
- package/lib-es/api/index.js.map +1 -1
- package/lib-es/api/listOperations.js +1 -1
- package/lib-es/api/listOperations.js.map +1 -1
- package/lib-es/network/index.d.ts +1 -1
- package/lib-es/network/index.d.ts.map +1 -1
- package/lib-es/network/index.js +3 -4
- package/lib-es/network/index.js.map +1 -1
- package/lib-es/network/types.d.ts +0 -1
- package/lib-es/network/types.d.ts.map +1 -1
- package/lib-es/network/types.js +0 -3
- package/lib-es/network/types.js.map +1 -1
- package/lib-es/utils/predicates.d.ts +5 -0
- package/lib-es/utils/predicates.d.ts.map +1 -0
- package/lib-es/utils/predicates.js +19 -0
- package/lib-es/utils/predicates.js.map +1 -0
- package/package.json +9 -4
- package/src/api/combine.test.ts +18 -27
- package/src/api/craftRawTransaction.test.ts +5 -6
- package/src/api/craftRawTransaction.ts +4 -1
- package/src/api/getBalance.test.ts +2 -4
- package/src/api/getBlock.integ.test.ts +5 -7
- package/src/api/getBlockInfo.integ.test.ts +5 -7
- package/src/api/index.integ.test.ts +65 -42
- package/src/api/index.test.ts +56 -45
- package/src/api/index.ts +7 -2
- package/src/api/listOperations.test.ts +4 -2
- package/src/api/listOperations.ts +3 -5
- package/src/api/validateIntent.test.ts +56 -128
- package/src/network/index.test.ts +23 -28
- package/src/network/index.ts +13 -16
- package/src/network/types.ts +0 -3
- package/src/utils/predicates.ts +25 -0
- package/jest.config.js +0 -32
- package/jest.integ.config.js +0 -21
- package/knip.json +0 -11
- package/tsconfig.build.json +0 -22
- package/tsconfig.json +0 -23
|
@@ -248,9 +248,7 @@ function findXrpBalanceDiff(
|
|
|
248
248
|
typeof data.FinalFields?.Balance === 'string' &&
|
|
249
249
|
typeof data.PreviousFields?.Balance === 'string'
|
|
250
250
|
) {
|
|
251
|
-
return (
|
|
252
|
-
BigInt(data.FinalFields.Balance as string) - BigInt(data.PreviousFields.Balance as string)
|
|
253
|
-
)
|
|
251
|
+
return BigInt(data.FinalFields.Balance) - BigInt(data.PreviousFields.Balance)
|
|
254
252
|
}
|
|
255
253
|
} else if ('CreatedNode' in node) {
|
|
256
254
|
const data = node.CreatedNode
|
|
@@ -259,7 +257,7 @@ function findXrpBalanceDiff(
|
|
|
259
257
|
data.NewFields?.Account === address &&
|
|
260
258
|
typeof data.NewFields?.Balance === 'string'
|
|
261
259
|
) {
|
|
262
|
-
return BigInt(data.NewFields.Balance
|
|
260
|
+
return BigInt(data.NewFields.Balance)
|
|
263
261
|
}
|
|
264
262
|
} else if ('DeletedNode' in node) {
|
|
265
263
|
const data = node.DeletedNode
|
|
@@ -271,7 +269,7 @@ function findXrpBalanceDiff(
|
|
|
271
269
|
data.FinalFields?.Account === address &&
|
|
272
270
|
typeof data.FinalFields?.Balance === 'string'
|
|
273
271
|
) {
|
|
274
|
-
const balance = BigInt(data.FinalFields.Balance
|
|
272
|
+
const balance = BigInt(data.FinalFields.Balance)
|
|
275
273
|
// Include the fee in the diff so the caller's adjustedDiff = (-balance - fee) + fee = -balance
|
|
276
274
|
return -(balance + fee)
|
|
277
275
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: © 2024 LEDGER SAS
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { createSendTransactionIntentMockData } from '@ledgerhq/coin-module-framework/test-utils'
|
|
5
5
|
import { XrpMapMemo } from '../types'
|
|
6
6
|
import { XrpDestinationTagRequired, XrpInvalidMemoError } from '../utils/errors'
|
|
7
7
|
import * as logicValidateMemo from '../utils/validateMemo'
|
|
@@ -41,7 +41,7 @@ const SENDER = 'rPSCfmnX3t9jQJG5RNcZtSaP5UhExZDue4'
|
|
|
41
41
|
const RECIPIENT = 'rPT1Sjq2YGrBMTttX4GZHjKu9dyfzbpAYe'
|
|
42
42
|
|
|
43
43
|
describe('validateIntent', () => {
|
|
44
|
-
const spiedValidateMemo = logicValidateMemo.validateMemo
|
|
44
|
+
const spiedValidateMemo = jest.mocked(logicValidateMemo.validateMemo)
|
|
45
45
|
|
|
46
46
|
afterEach(() => {
|
|
47
47
|
jest.clearAllMocks()
|
|
@@ -57,18 +57,13 @@ describe('validateIntent', () => {
|
|
|
57
57
|
})
|
|
58
58
|
|
|
59
59
|
const result = await validateIntent(
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
intentType: 'transaction',
|
|
60
|
+
createSendTransactionIntentMockData<XrpMapMemo>({
|
|
61
|
+
type: 'Payment',
|
|
63
62
|
sender: SENDER,
|
|
64
63
|
amount: 20_000_000n,
|
|
65
64
|
recipient: RECIPIENT,
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
type: '',
|
|
69
|
-
memos: new Map<string, Record<string, unknown>>(),
|
|
70
|
-
},
|
|
71
|
-
} as any,
|
|
65
|
+
memo: { type: 'map', memos: new Map() },
|
|
66
|
+
}),
|
|
72
67
|
[
|
|
73
68
|
{
|
|
74
69
|
value: 50_000_000n,
|
|
@@ -96,18 +91,13 @@ describe('validateIntent', () => {
|
|
|
96
91
|
})
|
|
97
92
|
|
|
98
93
|
const result = await validateIntent(
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
intentType: 'transaction',
|
|
94
|
+
createSendTransactionIntentMockData<XrpMapMemo>({
|
|
95
|
+
type: 'Payment',
|
|
102
96
|
sender: SENDER,
|
|
103
97
|
amount: 1_000_000n,
|
|
104
98
|
recipient: RECIPIENT,
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
type: '',
|
|
108
|
-
memos: new Map<string, Record<string, unknown>>(),
|
|
109
|
-
},
|
|
110
|
-
} as any,
|
|
99
|
+
memo: { type: 'map', memos: new Map() },
|
|
100
|
+
}),
|
|
111
101
|
[
|
|
112
102
|
{
|
|
113
103
|
value: 50_000_000n,
|
|
@@ -134,18 +124,13 @@ describe('validateIntent', () => {
|
|
|
134
124
|
})
|
|
135
125
|
|
|
136
126
|
const result = await validateIntent(
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
intentType: 'transaction',
|
|
127
|
+
createSendTransactionIntentMockData<XrpMapMemo>({
|
|
128
|
+
type: 'Payment',
|
|
140
129
|
sender: SENDER,
|
|
141
130
|
amount: 10_000_000n,
|
|
142
131
|
recipient: RECIPIENT,
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
type: '',
|
|
146
|
-
memos: new Map<string, Record<string, unknown>>(),
|
|
147
|
-
},
|
|
148
|
-
} as any,
|
|
132
|
+
memo: { type: 'map', memos: new Map() },
|
|
133
|
+
}),
|
|
149
134
|
[
|
|
150
135
|
{
|
|
151
136
|
value: 30_000_000n,
|
|
@@ -168,18 +153,13 @@ describe('validateIntent', () => {
|
|
|
168
153
|
})
|
|
169
154
|
|
|
170
155
|
const result = await validateIntent(
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
intentType: 'transaction',
|
|
156
|
+
createSendTransactionIntentMockData<XrpMapMemo>({
|
|
157
|
+
type: 'Payment',
|
|
174
158
|
sender: SENDER,
|
|
175
159
|
amount: 10_000_000n,
|
|
176
160
|
recipient: SENDER,
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
type: '',
|
|
180
|
-
memos: new Map<string, Record<string, unknown>>(),
|
|
181
|
-
},
|
|
182
|
-
} as any,
|
|
161
|
+
memo: { type: 'map', memos: new Map() },
|
|
162
|
+
}),
|
|
183
163
|
[
|
|
184
164
|
{
|
|
185
165
|
value: 50_000_000n,
|
|
@@ -203,18 +183,13 @@ describe('validateIntent', () => {
|
|
|
203
183
|
})
|
|
204
184
|
|
|
205
185
|
const result = await validateIntent(
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
intentType: 'transaction',
|
|
186
|
+
createSendTransactionIntentMockData<XrpMapMemo>({
|
|
187
|
+
type: 'Payment',
|
|
209
188
|
sender: SENDER,
|
|
210
189
|
amount: 5_000_000n,
|
|
211
190
|
recipient: RECIPIENT_NEW,
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
type: '',
|
|
215
|
-
memos: new Map<string, Record<string, unknown>>(),
|
|
216
|
-
},
|
|
217
|
-
} as any,
|
|
191
|
+
memo: { type: 'map', memos: new Map() },
|
|
192
|
+
}),
|
|
218
193
|
[
|
|
219
194
|
{
|
|
220
195
|
value: 50_000_000n,
|
|
@@ -238,18 +213,13 @@ describe('validateIntent', () => {
|
|
|
238
213
|
})
|
|
239
214
|
|
|
240
215
|
const result = await validateIntent(
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
intentType: 'transaction',
|
|
216
|
+
createSendTransactionIntentMockData<XrpMapMemo>({
|
|
217
|
+
type: 'Payment',
|
|
244
218
|
sender: SENDER,
|
|
245
219
|
amount: 0n,
|
|
246
220
|
recipient: RECIPIENT,
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
type: '',
|
|
250
|
-
memos: new Map<string, Record<string, unknown>>(),
|
|
251
|
-
},
|
|
252
|
-
} as any,
|
|
221
|
+
memo: { type: 'map', memos: new Map() },
|
|
222
|
+
}),
|
|
253
223
|
[
|
|
254
224
|
{
|
|
255
225
|
value: 50_000_000n,
|
|
@@ -273,18 +243,13 @@ describe('validateIntent', () => {
|
|
|
273
243
|
})
|
|
274
244
|
|
|
275
245
|
const result = await validateIntent(
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
intentType: 'transaction',
|
|
246
|
+
createSendTransactionIntentMockData<XrpMapMemo>({
|
|
247
|
+
type: 'Payment',
|
|
279
248
|
sender: SENDER,
|
|
280
|
-
asset: { unit: { code: 'XRP', magnitude: 6 } },
|
|
281
249
|
amount: 1_000_000n,
|
|
282
250
|
recipient: 'not-an-address',
|
|
283
|
-
memo: {
|
|
284
|
-
|
|
285
|
-
memos: new Map<string, Record<string, unknown>>(),
|
|
286
|
-
},
|
|
287
|
-
} as any,
|
|
251
|
+
memo: { type: 'map', memos: new Map() },
|
|
252
|
+
}),
|
|
288
253
|
[
|
|
289
254
|
{
|
|
290
255
|
value: 50_000_000n,
|
|
@@ -308,18 +273,13 @@ describe('validateIntent', () => {
|
|
|
308
273
|
})
|
|
309
274
|
|
|
310
275
|
const result = await validateIntent(
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
intentType: 'transaction',
|
|
276
|
+
createSendTransactionIntentMockData<XrpMapMemo>({
|
|
277
|
+
type: 'Payment',
|
|
314
278
|
sender: SENDER,
|
|
315
|
-
asset: { unit: { code: 'XRP', magnitude: 6 } },
|
|
316
279
|
amount: 1_000_000n,
|
|
317
280
|
recipient: '',
|
|
318
|
-
memo: {
|
|
319
|
-
|
|
320
|
-
memos: new Map<string, Record<string, unknown>>(),
|
|
321
|
-
},
|
|
322
|
-
} as any,
|
|
281
|
+
memo: { type: 'map', memos: new Map() },
|
|
282
|
+
}),
|
|
323
283
|
[
|
|
324
284
|
{
|
|
325
285
|
value: 50_000_000n,
|
|
@@ -352,26 +312,19 @@ describe('validateIntent', () => {
|
|
|
352
312
|
|
|
353
313
|
spiedValidateMemo.mockReturnValueOnce(true)
|
|
354
314
|
|
|
355
|
-
const memos = new Map<string, string | string[]>()
|
|
356
|
-
memos.set('destinationTag', 'random memo for unit test')
|
|
357
|
-
|
|
358
315
|
const status = await validateIntent(
|
|
359
|
-
{
|
|
360
|
-
|
|
316
|
+
createSendTransactionIntentMockData<XrpMapMemo>({
|
|
317
|
+
type: 'Payment',
|
|
361
318
|
sender: SENDER,
|
|
362
|
-
asset: { unit: { code: 'XRP', magnitude: 6 } },
|
|
363
319
|
amount: 1_000_000n,
|
|
364
320
|
recipient: '',
|
|
365
|
-
memo: {
|
|
366
|
-
|
|
367
|
-
memos,
|
|
368
|
-
},
|
|
369
|
-
} as TransactionIntent<XrpMapMemo>,
|
|
321
|
+
memo: { type: 'map', memos: new Map([['destinationTag', 'random memo for unit test']]) },
|
|
322
|
+
}),
|
|
370
323
|
[{ value: 10_000n, asset: { type: 'native' }, locked: 0n }]
|
|
371
324
|
)
|
|
372
325
|
expect(status.errors.transaction).not.toBeDefined()
|
|
373
326
|
|
|
374
|
-
expect(spiedValidateMemo).toHaveBeenCalledWith(
|
|
327
|
+
expect(spiedValidateMemo).toHaveBeenCalledWith('random memo for unit test')
|
|
375
328
|
})
|
|
376
329
|
|
|
377
330
|
it('should set error on transaction when memo is invalidated', async () => {
|
|
@@ -393,21 +346,14 @@ describe('validateIntent', () => {
|
|
|
393
346
|
|
|
394
347
|
spiedValidateMemo.mockReturnValueOnce(false)
|
|
395
348
|
|
|
396
|
-
const memos = new Map<string, string | string[]>()
|
|
397
|
-
memos.set('destinationTag', 'random memo for unit test')
|
|
398
|
-
|
|
399
349
|
const status = await validateIntent(
|
|
400
|
-
{
|
|
401
|
-
|
|
350
|
+
createSendTransactionIntentMockData<XrpMapMemo>({
|
|
351
|
+
type: 'Payment',
|
|
402
352
|
sender: SENDER,
|
|
403
|
-
asset: { unit: { code: 'XRP', magnitude: 6 } },
|
|
404
353
|
amount: 1_000_000n,
|
|
405
354
|
recipient: '',
|
|
406
|
-
memo: {
|
|
407
|
-
|
|
408
|
-
memos,
|
|
409
|
-
},
|
|
410
|
-
} as TransactionIntent<XrpMapMemo>,
|
|
355
|
+
memo: { type: 'map', memos: new Map([['destinationTag', 'random memo for unit test']]) },
|
|
356
|
+
}),
|
|
411
357
|
[
|
|
412
358
|
{
|
|
413
359
|
value: 10_000n,
|
|
@@ -418,7 +364,7 @@ describe('validateIntent', () => {
|
|
|
418
364
|
)
|
|
419
365
|
expect(status.errors.transaction).toBeInstanceOf(XrpInvalidMemoError)
|
|
420
366
|
|
|
421
|
-
expect(spiedValidateMemo).toHaveBeenCalledWith(
|
|
367
|
+
expect(spiedValidateMemo).toHaveBeenCalledWith('random memo for unit test')
|
|
422
368
|
})
|
|
423
369
|
|
|
424
370
|
it('errors when destinationTag is not a single string value', async () => {
|
|
@@ -430,21 +376,14 @@ describe('validateIntent', () => {
|
|
|
430
376
|
},
|
|
431
377
|
})
|
|
432
378
|
|
|
433
|
-
const memos = new Map<string, string | string[]>()
|
|
434
|
-
memos.set('destinationTag', ['12345', '67890'])
|
|
435
|
-
|
|
436
379
|
const status = await validateIntent(
|
|
437
|
-
{
|
|
438
|
-
|
|
380
|
+
createSendTransactionIntentMockData<XrpMapMemo>({
|
|
381
|
+
type: 'Payment',
|
|
439
382
|
sender: SENDER,
|
|
440
|
-
asset: { unit: { code: 'XRP', magnitude: 6 } },
|
|
441
383
|
amount: 1_000_000n,
|
|
442
384
|
recipient: RECIPIENT,
|
|
443
|
-
memo: {
|
|
444
|
-
|
|
445
|
-
memos,
|
|
446
|
-
},
|
|
447
|
-
} as TransactionIntent<XrpMapMemo>,
|
|
385
|
+
memo: { type: 'map', memos: new Map([['destinationTag', ['12345', '67890']]]) },
|
|
386
|
+
}),
|
|
448
387
|
[{ value: 50_000_000n, asset: { type: 'native' }, locked: 0n }],
|
|
449
388
|
{ value: 10_000n } // fees
|
|
450
389
|
)
|
|
@@ -462,17 +401,13 @@ describe('validateIntent', () => {
|
|
|
462
401
|
})
|
|
463
402
|
|
|
464
403
|
const status = await validateIntent(
|
|
465
|
-
{
|
|
466
|
-
|
|
404
|
+
createSendTransactionIntentMockData<XrpMapMemo>({
|
|
405
|
+
type: 'Payment',
|
|
467
406
|
sender: SENDER,
|
|
468
|
-
asset: { unit: { code: 'XRP', magnitude: 6 } },
|
|
469
407
|
amount: 20_000_000n,
|
|
470
408
|
recipient: RECIPIENT_TAG_REQUIRED,
|
|
471
|
-
memo: {
|
|
472
|
-
|
|
473
|
-
memos: new Map<string, string | string[]>(),
|
|
474
|
-
},
|
|
475
|
-
} as TransactionIntent<XrpMapMemo>,
|
|
409
|
+
memo: { type: 'map', memos: new Map() },
|
|
410
|
+
}),
|
|
476
411
|
[{ value: 50_000_000n, asset: { type: 'native' }, locked: 0n }],
|
|
477
412
|
{ value: 10_000n } // fees
|
|
478
413
|
)
|
|
@@ -491,21 +426,14 @@ describe('validateIntent', () => {
|
|
|
491
426
|
|
|
492
427
|
spiedValidateMemo.mockReturnValueOnce(true)
|
|
493
428
|
|
|
494
|
-
const memos = new Map<string, string | string[]>()
|
|
495
|
-
memos.set('destinationTag', '12345')
|
|
496
|
-
|
|
497
429
|
const status = await validateIntent(
|
|
498
|
-
{
|
|
499
|
-
|
|
430
|
+
createSendTransactionIntentMockData<XrpMapMemo>({
|
|
431
|
+
type: 'Payment',
|
|
500
432
|
sender: SENDER,
|
|
501
|
-
asset: { unit: { code: 'XRP', magnitude: 6 } },
|
|
502
433
|
amount: 20_000_000n,
|
|
503
434
|
recipient: RECIPIENT_TAG_REQUIRED,
|
|
504
|
-
memo: {
|
|
505
|
-
|
|
506
|
-
memos,
|
|
507
|
-
},
|
|
508
|
-
} as TransactionIntent<XrpMapMemo>,
|
|
435
|
+
memo: { type: 'map', memos: new Map([['destinationTag', '12345']]) },
|
|
436
|
+
}),
|
|
509
437
|
[{ value: 50_000_000n, asset: { type: 'native' }, locked: 0n }],
|
|
510
438
|
{ value: 10_000n } // fees
|
|
511
439
|
)
|
|
@@ -2,25 +2,21 @@
|
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
4
|
import network from '@ledgerhq/live-network'
|
|
5
|
-
import coinConfig
|
|
5
|
+
import coinConfig from '../config'
|
|
6
6
|
import { getAccountInfo, getLedgerIndex, getLedgerByIndex, getLedgerInfoByIndex } from '.'
|
|
7
7
|
|
|
8
8
|
jest.mock('@ledgerhq/live-network')
|
|
9
9
|
|
|
10
10
|
beforeAll(() => {
|
|
11
|
-
coinConfig.setCoinConfig(
|
|
12
|
-
() =>
|
|
13
|
-
({
|
|
14
|
-
node: '',
|
|
15
|
-
}) as XrpCoinConfig
|
|
16
|
-
)
|
|
11
|
+
coinConfig.setCoinConfig(() => ({ node: '', status: { type: 'active' } }))
|
|
17
12
|
})
|
|
18
13
|
|
|
19
14
|
describe('getAccountInfo', () => {
|
|
20
15
|
it("returns an empty AccountInfo when returns an error 'actNotFound'", async () => {
|
|
21
16
|
// Given
|
|
22
17
|
const emptyAddress = 'rNCgVpHinUDjXP2vHDFDMjm7ssBwpveHya'
|
|
23
|
-
|
|
18
|
+
jest.mocked(network).mockResolvedValue({
|
|
19
|
+
status: 200,
|
|
24
20
|
data: {
|
|
25
21
|
result: {
|
|
26
22
|
account: emptyAddress,
|
|
@@ -56,7 +52,8 @@ describe('getAccountInfo', () => {
|
|
|
56
52
|
it('returns a valid AccountInfo when return a correct AccountInfo', async () => {
|
|
57
53
|
// Given
|
|
58
54
|
const address = 'rh1HPuRVsYYvThxG2Bs1MfjmrVC73S16Fb'
|
|
59
|
-
|
|
55
|
+
jest.mocked(network).mockResolvedValue({
|
|
56
|
+
status: 200,
|
|
60
57
|
data: {
|
|
61
58
|
result: {
|
|
62
59
|
account_data: {
|
|
@@ -93,7 +90,8 @@ describe('getAccountInfo', () => {
|
|
|
93
90
|
|
|
94
91
|
it('returns requireDestinationTag true when the account_flags flag is set', async () => {
|
|
95
92
|
const address = 'rwnYLUsoBQX3ECa1A5bSKLdbPoHKnqf63J'
|
|
96
|
-
|
|
93
|
+
jest.mocked(network).mockResolvedValue({
|
|
94
|
+
status: 200,
|
|
97
95
|
data: {
|
|
98
96
|
result: {
|
|
99
97
|
account_data: {
|
|
@@ -124,33 +122,27 @@ describe('getAccountInfo', () => {
|
|
|
124
122
|
it('throws an error when backend returns any other error', async () => {
|
|
125
123
|
// Given
|
|
126
124
|
const invalidAddress = 'rNCgVpHinUDjXP2vHDFDMjm7ssBwpveHyaa'
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
ledger_index: 91772741,
|
|
134
|
-
request: {
|
|
135
|
-
account: invalidAddress,
|
|
136
|
-
command: 'account_info',
|
|
137
|
-
ledger_index: 'validated',
|
|
125
|
+
jest.mocked(network).mockResolvedValue({
|
|
126
|
+
status: 200,
|
|
127
|
+
data: {
|
|
128
|
+
result: {
|
|
129
|
+
error: 'tooBusy',
|
|
130
|
+
status: 'error',
|
|
138
131
|
},
|
|
139
|
-
status: 'error',
|
|
140
|
-
validated: true,
|
|
141
132
|
},
|
|
142
133
|
})
|
|
143
134
|
|
|
144
135
|
// When & Then
|
|
145
136
|
await expect(getAccountInfo(invalidAddress)).rejects.toThrow(
|
|
146
|
-
|
|
137
|
+
`couldn't fetch account info ${invalidAddress}`
|
|
147
138
|
)
|
|
148
139
|
})
|
|
149
140
|
})
|
|
150
141
|
|
|
151
142
|
describe('getLedgerIndex', () => {
|
|
152
143
|
it('returns error_message from rpc call errors', async () => {
|
|
153
|
-
|
|
144
|
+
jest.mocked(network).mockResolvedValue({
|
|
145
|
+
status: 200,
|
|
154
146
|
data: {
|
|
155
147
|
result: {
|
|
156
148
|
error: 'issou',
|
|
@@ -165,7 +157,8 @@ describe('getLedgerIndex', () => {
|
|
|
165
157
|
})
|
|
166
158
|
|
|
167
159
|
it('returns error if there is no error_message', async () => {
|
|
168
|
-
|
|
160
|
+
jest.mocked(network).mockResolvedValue({
|
|
161
|
+
status: 200,
|
|
169
162
|
data: {
|
|
170
163
|
result: {
|
|
171
164
|
error: 'issou',
|
|
@@ -178,7 +171,8 @@ describe('getLedgerIndex', () => {
|
|
|
178
171
|
})
|
|
179
172
|
|
|
180
173
|
it("returns error code if it's the only thing available", async () => {
|
|
181
|
-
|
|
174
|
+
jest.mocked(network).mockResolvedValue({
|
|
175
|
+
status: 200,
|
|
182
176
|
data: {
|
|
183
177
|
result: {
|
|
184
178
|
error_code: 42,
|
|
@@ -197,7 +191,8 @@ describe('getLedgerByIndex', () => {
|
|
|
197
191
|
const blockIndex = 101665314
|
|
198
192
|
const mockLedgerHash = 'ABC123DEF456'
|
|
199
193
|
const mockTxHash = 'TXHASH1'
|
|
200
|
-
|
|
194
|
+
jest.mocked(network).mockResolvedValue({
|
|
195
|
+
status: 200,
|
|
201
196
|
data: {
|
|
202
197
|
result: {
|
|
203
198
|
status: 'success',
|
package/src/network/index.ts
CHANGED
|
@@ -2,21 +2,20 @@
|
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
4
|
import type { AccountInfo } from '../types/model'
|
|
5
|
-
import
|
|
6
|
-
import { makeLRUCache, minutes } from '@ledgerhq/live-network/cache'
|
|
7
|
-
import coinConfig from '../config'
|
|
8
|
-
import {
|
|
5
|
+
import type {
|
|
9
6
|
LedgerTxResponse,
|
|
10
|
-
isErrorResponse,
|
|
11
|
-
isResponseStatus,
|
|
12
7
|
Marker,
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
8
|
+
AccountInfoResponse,
|
|
9
|
+
AccountTxResponse,
|
|
10
|
+
ErrorResponse,
|
|
11
|
+
LedgerResponse,
|
|
12
|
+
ServerInfoResponse,
|
|
13
|
+
SubmitReponse,
|
|
19
14
|
} from './types'
|
|
15
|
+
import network from '@ledgerhq/live-network'
|
|
16
|
+
import { makeLRUCache, minutes } from '@ledgerhq/live-network/cache'
|
|
17
|
+
import coinConfig from '../config'
|
|
18
|
+
import { isErrorResponse } from '../utils/predicates'
|
|
20
19
|
|
|
21
20
|
const getNodeUrl = () => coinConfig.getCoinConfig().node
|
|
22
21
|
|
|
@@ -165,10 +164,8 @@ async function rpcCall<T extends object>(
|
|
|
165
164
|
},
|
|
166
165
|
})
|
|
167
166
|
|
|
168
|
-
if (
|
|
169
|
-
const
|
|
170
|
-
const parsedError =
|
|
171
|
-
errResponse.error_message ?? errResponse.error ?? `error code ${errResponse.error_code}`
|
|
167
|
+
if (isErrorResponse(result)) {
|
|
168
|
+
const parsedError = result.error_message ?? result.error ?? `error code ${result.error_code}`
|
|
172
169
|
throw new Error(
|
|
173
170
|
`couldn't fetch ${method} with params ${JSON.stringify(params)}: ${parsedError}`
|
|
174
171
|
)
|
package/src/network/types.ts
CHANGED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: © 2024 LEDGER SAS
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import type { ErrorResponse } from '../network/types'
|
|
5
|
+
import type { SignerEntry } from '../types'
|
|
6
|
+
|
|
7
|
+
export function isSignerEntry(obj: unknown): obj is SignerEntry {
|
|
8
|
+
return (
|
|
9
|
+
typeof obj === 'object' &&
|
|
10
|
+
obj !== null &&
|
|
11
|
+
'Signer' in obj &&
|
|
12
|
+
typeof obj.Signer === 'object' &&
|
|
13
|
+
obj.Signer !== null &&
|
|
14
|
+
'Account' in obj.Signer &&
|
|
15
|
+
typeof obj.Signer.Account === 'string' &&
|
|
16
|
+
'SigningPubKey' in obj.Signer &&
|
|
17
|
+
typeof obj.Signer.SigningPubKey === 'string' &&
|
|
18
|
+
'TxnSignature' in obj.Signer &&
|
|
19
|
+
typeof obj.Signer.TxnSignature === 'string'
|
|
20
|
+
)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function isErrorResponse(obj: object): obj is ErrorResponse {
|
|
24
|
+
return 'status' in obj && obj.status === 'error'
|
|
25
|
+
}
|
package/jest.config.js
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
// SPDX-FileCopyrightText: © 2024 LEDGER SAS
|
|
2
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
|
|
4
|
-
// `workerThreads: true` is required for validating object with `bigint` values
|
|
5
|
-
module.exports = {
|
|
6
|
-
testEnvironment: "node",
|
|
7
|
-
transform: {
|
|
8
|
-
"^.+\\.(ts|tsx)$": [
|
|
9
|
-
"@swc/jest",
|
|
10
|
-
{
|
|
11
|
-
jsc: {
|
|
12
|
-
target: "esnext",
|
|
13
|
-
},
|
|
14
|
-
},
|
|
15
|
-
],
|
|
16
|
-
},
|
|
17
|
-
passWithNoTests: true,
|
|
18
|
-
testPathIgnorePatterns: ["lib/", "lib-es/", ".*\\.(integ|integration)\\.test\\.[tj]s"],
|
|
19
|
-
collectCoverageFrom: [
|
|
20
|
-
"src/**/*.ts",
|
|
21
|
-
"!src/**/*.test.ts",
|
|
22
|
-
"!src/**/*.spec.ts",
|
|
23
|
-
"!src/test/**/*.ts",
|
|
24
|
-
],
|
|
25
|
-
coverageReporters: ["json", ["lcov", { file: "lcov.info", projectRoot: "../../../" }], "text"],
|
|
26
|
-
workerThreads: true,
|
|
27
|
-
reporters: [
|
|
28
|
-
"default",
|
|
29
|
-
["jest-sonar", { outputName: "sonar-executionTests-report.xml", reportedFilePath: "absolute" }],
|
|
30
|
-
],
|
|
31
|
-
setupFilesAfterEnv: [/* "@ledgerhq/disable-network-setup" */],
|
|
32
|
-
};
|
package/jest.integ.config.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
// SPDX-FileCopyrightText: © 2024 LEDGER SAS
|
|
2
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
|
|
4
|
-
/** @type {import('jest').Config} */
|
|
5
|
-
module.exports = {
|
|
6
|
-
testEnvironment: "node",
|
|
7
|
-
testRegex: ".integ.test.ts$",
|
|
8
|
-
testPathIgnorePatterns: ["lib/", "lib-es/"],
|
|
9
|
-
testTimeout: 60_000,
|
|
10
|
-
forceExit: true,
|
|
11
|
-
transform: {
|
|
12
|
-
"^.+\\.(t|j)sx?$": [
|
|
13
|
-
"@swc/jest",
|
|
14
|
-
{
|
|
15
|
-
jsc: {
|
|
16
|
-
target: "esnext",
|
|
17
|
-
},
|
|
18
|
-
},
|
|
19
|
-
],
|
|
20
|
-
},
|
|
21
|
-
};
|
package/knip.json
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://unpkg.com/knip@5.34.1/schema.json",
|
|
3
|
-
"entry": [
|
|
4
|
-
"src/api/index.ts",
|
|
5
|
-
"src/index.ts",
|
|
6
|
-
"src/api/validateAddress.ts",
|
|
7
|
-
"src/supportedFeatures.ts"
|
|
8
|
-
],
|
|
9
|
-
"project": ["src/**/*.ts"],
|
|
10
|
-
"ignoreDependencies": ["@ledgerhq/coin-module-framework"]
|
|
11
|
-
}
|
package/tsconfig.build.json
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extends": "./tsconfig.json",
|
|
3
|
-
"compilerOptions": {
|
|
4
|
-
"customConditions": [],
|
|
5
|
-
"types": [
|
|
6
|
-
"node"
|
|
7
|
-
]
|
|
8
|
-
},
|
|
9
|
-
"exclude": [
|
|
10
|
-
"**/*.test.ts",
|
|
11
|
-
"**/*.test.tsx",
|
|
12
|
-
"**/*.spec.ts",
|
|
13
|
-
"**/*.spec.tsx",
|
|
14
|
-
"**/__tests__/**/*",
|
|
15
|
-
"**/tests/**/*",
|
|
16
|
-
"**/__mocks__/**/*",
|
|
17
|
-
"**/*.test.js",
|
|
18
|
-
"**/*.test.jsx",
|
|
19
|
-
"**/*.spec.js",
|
|
20
|
-
"**/*.spec.jsx"
|
|
21
|
-
]
|
|
22
|
-
}
|