@ledgerhq/coin-framework 2.5.0 → 2.6.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.
- package/CHANGELOG.md +26 -0
- package/jest.config.js +1 -0
- package/lib/account/balanceHistoryCache.d.ts +14 -0
- package/lib/account/balanceHistoryCache.d.ts.map +1 -1
- package/lib/account/balanceHistoryCache.js +5 -3
- package/lib/account/balanceHistoryCache.js.map +1 -1
- package/lib/account/helpers.d.ts.map +1 -1
- package/lib/account/helpers.js +0 -13
- package/lib/account/helpers.js.map +1 -1
- package/lib/account/index.d.ts +1 -1
- package/lib/account/index.d.ts.map +1 -1
- package/lib/account/index.js +2 -1
- package/lib/account/index.js.map +1 -1
- package/lib/account/index.test.d.ts +2 -0
- package/lib/account/index.test.d.ts.map +1 -0
- package/lib/{account.test.js → account/index.test.js} +31 -31
- package/lib/account/index.test.js.map +1 -0
- package/lib/api/types.d.ts +3 -3
- package/lib/api/types.d.ts.map +1 -1
- package/lib/bridge/jsHelpers.d.ts +2 -2
- package/lib/bridge/jsHelpers.d.ts.map +1 -1
- package/lib/bridge/jsHelpers.js +1 -1
- package/lib/bridge/jsHelpers.js.map +1 -1
- package/lib/bridge/jsHelpers.test.js +348 -102
- package/lib/bridge/jsHelpers.test.js.map +1 -1
- package/lib/derivation.d.ts +1 -2
- package/lib/derivation.d.ts.map +1 -1
- package/lib/derivation.js +48 -32
- package/lib/derivation.js.map +1 -1
- package/lib/derivation.test.js +168 -62
- package/lib/derivation.test.js.map +1 -1
- package/lib/mocks/account.d.ts +1 -0
- package/lib/mocks/account.d.ts.map +1 -1
- package/lib/mocks/account.js.map +1 -1
- package/lib/nft/support.d.ts +4 -7
- package/lib/nft/support.d.ts.map +1 -1
- package/lib/nft/support.js +3 -6
- package/lib/nft/support.js.map +1 -1
- package/lib/operation.d.ts.map +1 -1
- package/lib/operation.js +3 -0
- package/lib/operation.js.map +1 -1
- package/lib/utils.js +1 -1
- package/lib/utils.js.map +1 -1
- package/lib/utils.test.js +6 -0
- package/lib/utils.test.js.map +1 -1
- package/lib-es/account/balanceHistoryCache.d.ts +14 -0
- package/lib-es/account/balanceHistoryCache.d.ts.map +1 -1
- package/lib-es/account/balanceHistoryCache.js +3 -2
- package/lib-es/account/balanceHistoryCache.js.map +1 -1
- package/lib-es/account/helpers.d.ts.map +1 -1
- package/lib-es/account/helpers.js +0 -13
- package/lib-es/account/helpers.js.map +1 -1
- package/lib-es/account/index.d.ts +1 -1
- package/lib-es/account/index.d.ts.map +1 -1
- package/lib-es/account/index.js +1 -1
- package/lib-es/account/index.js.map +1 -1
- package/lib-es/account/index.test.d.ts +2 -0
- package/lib-es/account/index.test.d.ts.map +1 -0
- package/lib-es/{account.test.js → account/index.test.js} +6 -6
- package/lib-es/account/index.test.js.map +1 -0
- package/lib-es/api/types.d.ts +3 -3
- package/lib-es/api/types.d.ts.map +1 -1
- package/lib-es/bridge/jsHelpers.d.ts +2 -2
- package/lib-es/bridge/jsHelpers.d.ts.map +1 -1
- package/lib-es/bridge/jsHelpers.js +1 -1
- package/lib-es/bridge/jsHelpers.js.map +1 -1
- package/lib-es/bridge/jsHelpers.test.js +349 -103
- package/lib-es/bridge/jsHelpers.test.js.map +1 -1
- package/lib-es/derivation.d.ts +1 -2
- package/lib-es/derivation.d.ts.map +1 -1
- package/lib-es/derivation.js +42 -22
- package/lib-es/derivation.js.map +1 -1
- package/lib-es/derivation.test.js +169 -63
- package/lib-es/derivation.test.js.map +1 -1
- package/lib-es/mocks/account.d.ts +1 -0
- package/lib-es/mocks/account.d.ts.map +1 -1
- package/lib-es/mocks/account.js.map +1 -1
- package/lib-es/nft/support.d.ts +4 -7
- package/lib-es/nft/support.d.ts.map +1 -1
- package/lib-es/nft/support.js +3 -6
- package/lib-es/nft/support.js.map +1 -1
- package/lib-es/operation.d.ts.map +1 -1
- package/lib-es/operation.js +3 -0
- package/lib-es/operation.js.map +1 -1
- package/lib-es/utils.js +1 -1
- package/lib-es/utils.js.map +1 -1
- package/lib-es/utils.test.js +6 -0
- package/lib-es/utils.test.js.map +1 -1
- package/package.json +5 -5
- package/src/account/balanceHistoryCache.ts +4 -2
- package/src/account/helpers.ts +0 -15
- package/src/{account.test.ts → account/index.test.ts} +7 -7
- package/src/account/index.ts +5 -1
- package/src/api/types.ts +6 -3
- package/src/bridge/jsHelpers.test.ts +401 -104
- package/src/bridge/jsHelpers.ts +3 -2
- package/src/derivation.test.ts +188 -70
- package/src/derivation.ts +55 -27
- package/src/mocks/account.ts +1 -0
- package/src/nft/support.ts +8 -14
- package/src/operation.ts +3 -0
- package/src/utils.test.ts +6 -0
- package/src/utils.ts +1 -1
- package/lib/account.test.d.ts +0 -2
- package/lib/account.test.d.ts.map +0 -1
- package/lib/account.test.js.map +0 -1
- package/lib-es/account.test.d.ts +0 -2
- package/lib-es/account.test.d.ts.map +0 -1
- package/lib-es/account.test.js.map +0 -1
- /package/src/{__snapshots__/account.test.ts.snap → account/__snapshots__/index.test.ts.snap} +0 -0
|
@@ -1,138 +1,435 @@
|
|
|
1
|
+
import { getCryptoCurrencyById, listCryptoCurrencies } from "@ledgerhq/cryptoassets/currencies";
|
|
2
|
+
import type {
|
|
3
|
+
Account,
|
|
4
|
+
Operation,
|
|
5
|
+
SyncConfig,
|
|
6
|
+
TokenAccount,
|
|
7
|
+
TransactionCommon,
|
|
8
|
+
} from "@ledgerhq/types-live";
|
|
1
9
|
import BigNumber from "bignumber.js";
|
|
2
10
|
import { firstValueFrom } from "rxjs";
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
recipient: "0x17733CAb76d9A2112576443F21735789733B1ca3",
|
|
12
|
-
amount: new BigNumber("10000000000000"),
|
|
13
|
-
};
|
|
11
|
+
import {
|
|
12
|
+
AccountShapeInfo,
|
|
13
|
+
bip32asBuffer,
|
|
14
|
+
makeScanAccounts,
|
|
15
|
+
makeSync,
|
|
16
|
+
updateTransaction,
|
|
17
|
+
} from "./jsHelpers";
|
|
18
|
+
import { createEmptyHistoryCache } from "../account/balanceHistoryCache";
|
|
14
19
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
20
|
+
describe("updateTransaction", () => {
|
|
21
|
+
it("should not update the transaction object", () => {
|
|
22
|
+
const transaction: TransactionCommon = {
|
|
23
|
+
recipient: "0x17733CAb76d9A2112576443F21735789733B1ca3",
|
|
24
|
+
amount: new BigNumber("10000000000000"),
|
|
25
|
+
};
|
|
19
26
|
|
|
20
|
-
|
|
27
|
+
const updatedTransaction = updateTransaction(transaction, {
|
|
28
|
+
recipient: "0x17733CAb76d9A2112576443F21735789733B1ca3",
|
|
29
|
+
amount: new BigNumber("10000000000000"),
|
|
21
30
|
});
|
|
22
31
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
recipient: "0x17733CAb76d9A2112576443F21735789733B1ca3",
|
|
26
|
-
amount: new BigNumber("10000000000000"),
|
|
27
|
-
};
|
|
32
|
+
expect(transaction).toBe(updatedTransaction);
|
|
33
|
+
});
|
|
28
34
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
35
|
+
it("should update the transaction object", () => {
|
|
36
|
+
const transaction: TransactionCommon = {
|
|
37
|
+
recipient: "0x17733CAb76d9A2112576443F21735789733B1ca3",
|
|
38
|
+
amount: new BigNumber("10000000000000"),
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const updatedTransaction = updateTransaction(transaction, {
|
|
42
|
+
recipient: "0x17733CAb76d9A2112576443F21735789733B1ca3",
|
|
43
|
+
amount: new BigNumber("20000000000000"),
|
|
44
|
+
});
|
|
33
45
|
|
|
34
|
-
|
|
46
|
+
expect(transaction).not.toBe(updatedTransaction);
|
|
35
47
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
});
|
|
48
|
+
expect(updatedTransaction).toEqual({
|
|
49
|
+
...transaction,
|
|
50
|
+
amount: new BigNumber("20000000000000"),
|
|
40
51
|
});
|
|
41
52
|
});
|
|
53
|
+
});
|
|
42
54
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
55
|
+
describe("makeSync", () => {
|
|
56
|
+
it("returns a function to update account that give a new instance of account", async () => {
|
|
57
|
+
// Given
|
|
58
|
+
const account = createAccount({
|
|
59
|
+
id: "12",
|
|
60
|
+
creationDate: new Date("2024-05-12T17:04:12"),
|
|
61
|
+
lastSyncDate: new Date("2024-05-12T17:04:12"),
|
|
62
|
+
});
|
|
51
63
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
64
|
+
// When
|
|
65
|
+
const accountUpdater = makeSync({
|
|
66
|
+
getAccountShape: (_accountShape: AccountShapeInfo) => Promise.resolve({} as Account),
|
|
67
|
+
})(account, {} as SyncConfig);
|
|
68
|
+
const updater = await firstValueFrom(accountUpdater);
|
|
69
|
+
const newAccount = updater(account);
|
|
58
70
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
71
|
+
// Then
|
|
72
|
+
const nonUpdatedFields = {
|
|
73
|
+
...account,
|
|
74
|
+
id: expect.any(String),
|
|
75
|
+
creationDate: expect.any(Date),
|
|
76
|
+
lastSyncDate: expect.any(Date),
|
|
77
|
+
subAccounts: [],
|
|
78
|
+
};
|
|
79
|
+
expect(newAccount).toEqual(nonUpdatedFields);
|
|
80
|
+
expect(newAccount.id).not.toEqual(account.id);
|
|
81
|
+
expect(newAccount.creationDate).not.toEqual(account.creationDate);
|
|
82
|
+
expect(newAccount.lastSyncDate).not.toEqual(account.lastSyncDate);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it("returns a account with a corrected formatted id", async () => {
|
|
86
|
+
// Given
|
|
87
|
+
const account = createAccount({
|
|
88
|
+
id: "12",
|
|
89
|
+
creationDate: new Date("2024-05-12T17:04:12"),
|
|
90
|
+
lastSyncDate: new Date("2024-05-12T17:04:12"),
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
// When
|
|
94
|
+
const accountUpdater = makeSync({
|
|
95
|
+
getAccountShape: (_accountShape: AccountShapeInfo) => Promise.resolve({} as Account),
|
|
96
|
+
})(account, {} as SyncConfig);
|
|
97
|
+
const updater = await firstValueFrom(accountUpdater);
|
|
98
|
+
const newAccount = updater(account);
|
|
99
|
+
|
|
100
|
+
// Then
|
|
101
|
+
const expectedAccount = {
|
|
102
|
+
...account,
|
|
103
|
+
id: "js:2:bitcoin::",
|
|
104
|
+
subAccounts: undefined,
|
|
105
|
+
};
|
|
106
|
+
expect(newAccount.id).toEqual(expectedAccount.id);
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
describe("makeScanAccounts", () => {
|
|
111
|
+
it("returns the first account found when there is no one used previously", async () => {
|
|
112
|
+
// Given
|
|
113
|
+
const addressResolver = {
|
|
114
|
+
address: "address",
|
|
115
|
+
path: "path",
|
|
116
|
+
publicKey: "publicKey",
|
|
117
|
+
};
|
|
118
|
+
const syncConfig = {
|
|
119
|
+
paginationConfig: {},
|
|
120
|
+
};
|
|
121
|
+
const deviceId = "deviceId";
|
|
122
|
+
const currency = getCryptoCurrencyById("algorand");
|
|
123
|
+
|
|
124
|
+
// When
|
|
125
|
+
const scanAccounts = makeScanAccounts({
|
|
126
|
+
getAccountShape: (accountShape, config) => {
|
|
127
|
+
expect(config).toBe(syncConfig);
|
|
128
|
+
expect(accountShape.currency).toBe(currency);
|
|
129
|
+
expect(accountShape.address).toBe(addressResolver.address);
|
|
130
|
+
expect(accountShape.derivationPath).toBe(addressResolver.path);
|
|
131
|
+
expect(accountShape.deviceId).toBe(deviceId);
|
|
132
|
+
return Promise.resolve({
|
|
133
|
+
id: "1234",
|
|
134
|
+
balanceHistoryCache: createEmptyHistoryCache(),
|
|
135
|
+
});
|
|
136
|
+
},
|
|
137
|
+
getAddressFn: (_deviceId, _addressOpt) => Promise.resolve(addressResolver),
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
// Then
|
|
141
|
+
const result = await firstValueFrom(
|
|
142
|
+
scanAccounts({
|
|
143
|
+
currency,
|
|
144
|
+
deviceId,
|
|
145
|
+
syncConfig,
|
|
146
|
+
}),
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
expect(result).toEqual({
|
|
150
|
+
account: {
|
|
151
|
+
id: "1234",
|
|
152
|
+
balance: new BigNumber("0"),
|
|
153
|
+
balanceHistoryCache: createEmptyHistoryCache(),
|
|
154
|
+
blockHeight: 0,
|
|
63
155
|
creationDate: expect.any(Date),
|
|
156
|
+
currency,
|
|
157
|
+
derivationMode: "",
|
|
158
|
+
freshAddress: addressResolver.address,
|
|
159
|
+
freshAddressPath: addressResolver.path,
|
|
160
|
+
index: 0,
|
|
64
161
|
lastSyncDate: expect.any(Date),
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
162
|
+
operations: [],
|
|
163
|
+
operationsCount: 0,
|
|
164
|
+
pendingOperations: [],
|
|
165
|
+
seedIdentifier: addressResolver.publicKey,
|
|
166
|
+
spendableBalance: new BigNumber("0"),
|
|
167
|
+
swapHistory: [],
|
|
168
|
+
type: "Account",
|
|
169
|
+
used: false,
|
|
170
|
+
},
|
|
171
|
+
type: "discovered",
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
it("throws an error when the GetAccountShape does not return an id", async () => {
|
|
176
|
+
// Given
|
|
177
|
+
const addressResolver = {
|
|
178
|
+
address: "address",
|
|
179
|
+
path: "path",
|
|
180
|
+
publicKey: "publicKey",
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
// When
|
|
184
|
+
const scanAccounts = makeScanAccounts({
|
|
185
|
+
getAccountShape: () =>
|
|
186
|
+
Promise.resolve({
|
|
187
|
+
balanceHistoryCache: createEmptyHistoryCache(),
|
|
188
|
+
}),
|
|
189
|
+
getAddressFn: (_deviceId, _addressOpt) => Promise.resolve(addressResolver),
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
// Then
|
|
193
|
+
expect(
|
|
194
|
+
firstValueFrom(
|
|
195
|
+
scanAccounts({
|
|
196
|
+
currency: getCryptoCurrencyById("algorand"),
|
|
197
|
+
deviceId: "deviceId",
|
|
198
|
+
syncConfig: {
|
|
199
|
+
paginationConfig: {},
|
|
200
|
+
},
|
|
201
|
+
}),
|
|
202
|
+
),
|
|
203
|
+
).rejects.toThrow("account ID must be provided");
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
it("throws an error when the GetAccountShape returns an incorrect balance", async () => {
|
|
207
|
+
// Given
|
|
208
|
+
const addressResolver = {
|
|
209
|
+
address: "address",
|
|
210
|
+
path: "path",
|
|
211
|
+
publicKey: "publicKey",
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
// When
|
|
215
|
+
const scanAccounts = makeScanAccounts({
|
|
216
|
+
getAccountShape: () =>
|
|
217
|
+
Promise.resolve({
|
|
218
|
+
id: "1234",
|
|
219
|
+
balance: new BigNumber("NULL"),
|
|
220
|
+
balanceHistoryCache: createEmptyHistoryCache(),
|
|
221
|
+
}),
|
|
222
|
+
getAddressFn: (_deviceId, _addressOpt) => Promise.resolve(addressResolver),
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
// Then
|
|
226
|
+
expect(
|
|
227
|
+
firstValueFrom(
|
|
228
|
+
scanAccounts({
|
|
229
|
+
currency: getCryptoCurrencyById("algorand"),
|
|
230
|
+
deviceId: "deviceId",
|
|
231
|
+
syncConfig: {
|
|
232
|
+
paginationConfig: {},
|
|
233
|
+
},
|
|
234
|
+
}),
|
|
235
|
+
),
|
|
236
|
+
).rejects.toThrow("invalid balance NaN");
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
it.each([
|
|
240
|
+
{
|
|
241
|
+
balance: new BigNumber(1_000_000),
|
|
242
|
+
operationsCount: 0,
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
balance: new BigNumber(0),
|
|
246
|
+
operationsCount: 1,
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
balance: new BigNumber(0),
|
|
250
|
+
operations: [{}] as Operation[],
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
balance: new BigNumber(0),
|
|
254
|
+
operationsCount: 0,
|
|
255
|
+
subAccounts: [{}] as TokenAccount[],
|
|
256
|
+
},
|
|
257
|
+
])("returns an account flag as used", async account => {
|
|
258
|
+
// Given
|
|
259
|
+
const addressResolver = {
|
|
260
|
+
address: "address",
|
|
261
|
+
path: "path",
|
|
262
|
+
publicKey: "publicKey",
|
|
263
|
+
};
|
|
264
|
+
const currency = getCryptoCurrencyById("algorand");
|
|
265
|
+
|
|
266
|
+
// When
|
|
267
|
+
const scanAccounts = makeScanAccounts({
|
|
268
|
+
getAccountShape: () =>
|
|
269
|
+
Promise.resolve({
|
|
270
|
+
...account,
|
|
271
|
+
id: "1234",
|
|
272
|
+
balanceHistoryCache: createEmptyHistoryCache(),
|
|
273
|
+
}),
|
|
274
|
+
getAddressFn: (_deviceId, _addressOpt) => Promise.resolve(addressResolver),
|
|
71
275
|
});
|
|
72
276
|
|
|
73
|
-
|
|
277
|
+
// Then
|
|
278
|
+
const result = await firstValueFrom(
|
|
279
|
+
scanAccounts({
|
|
280
|
+
currency,
|
|
281
|
+
deviceId: "deviceId",
|
|
282
|
+
syncConfig: {
|
|
283
|
+
paginationConfig: {},
|
|
284
|
+
},
|
|
285
|
+
}),
|
|
286
|
+
);
|
|
287
|
+
|
|
288
|
+
expect(result.account.used).toBe(true);
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
it.each([
|
|
292
|
+
{
|
|
293
|
+
account: {
|
|
294
|
+
balance: new BigNumber(0),
|
|
295
|
+
},
|
|
296
|
+
expectedUsed: false,
|
|
297
|
+
},
|
|
298
|
+
{
|
|
299
|
+
account: {
|
|
300
|
+
balance: new BigNumber(0),
|
|
301
|
+
used: true,
|
|
302
|
+
},
|
|
303
|
+
expectedUsed: true,
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
account: {
|
|
307
|
+
balance: new BigNumber(1_000_000),
|
|
308
|
+
used: false,
|
|
309
|
+
},
|
|
310
|
+
expectedUsed: false,
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
account: {
|
|
314
|
+
balance: new BigNumber(1_000_000),
|
|
315
|
+
},
|
|
316
|
+
expectedUsed: true,
|
|
317
|
+
},
|
|
318
|
+
])(
|
|
319
|
+
"overrides the used flag only if not returned by the getAccountShape",
|
|
320
|
+
async ({ account, expectedUsed }) => {
|
|
74
321
|
// Given
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
}
|
|
322
|
+
const addressResolver = {
|
|
323
|
+
address: "address",
|
|
324
|
+
path: "path",
|
|
325
|
+
publicKey: "publicKey",
|
|
326
|
+
};
|
|
327
|
+
const currency = getCryptoCurrencyById("algorand");
|
|
80
328
|
|
|
81
329
|
// When
|
|
82
|
-
const
|
|
83
|
-
getAccountShape: (
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
330
|
+
const scanAccounts = makeScanAccounts({
|
|
331
|
+
getAccountShape: () =>
|
|
332
|
+
Promise.resolve({
|
|
333
|
+
...account,
|
|
334
|
+
id: "1234",
|
|
335
|
+
balanceHistoryCache: createEmptyHistoryCache(),
|
|
336
|
+
}),
|
|
337
|
+
getAddressFn: (_deviceId, _addressOpt) => Promise.resolve(addressResolver),
|
|
338
|
+
});
|
|
87
339
|
|
|
88
340
|
// Then
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
341
|
+
const result = await firstValueFrom(
|
|
342
|
+
scanAccounts({
|
|
343
|
+
currency,
|
|
344
|
+
deviceId: "deviceId",
|
|
345
|
+
syncConfig: {
|
|
346
|
+
paginationConfig: {},
|
|
347
|
+
},
|
|
348
|
+
}),
|
|
349
|
+
);
|
|
350
|
+
|
|
351
|
+
expect(result.account.used).toEqual(expectedUsed);
|
|
352
|
+
},
|
|
353
|
+
);
|
|
354
|
+
|
|
355
|
+
it("returns all accounts found until the first not used yet", done => {
|
|
356
|
+
// Given
|
|
357
|
+
const addressResolver = {
|
|
358
|
+
address: "address",
|
|
359
|
+
path: "path",
|
|
360
|
+
publicKey: "publicKey",
|
|
361
|
+
};
|
|
362
|
+
|
|
363
|
+
const USED_ACCOUNT_NUMN = 2;
|
|
364
|
+
let scanCall = 0;
|
|
365
|
+
const scanAccounts = makeScanAccounts({
|
|
366
|
+
getAccountShape: () => {
|
|
367
|
+
scanCall++;
|
|
368
|
+
const used = scanCall > USED_ACCOUNT_NUMN ? false : true;
|
|
369
|
+
return Promise.resolve({
|
|
370
|
+
used,
|
|
371
|
+
id: `1234${scanCall}`,
|
|
372
|
+
balanceHistoryCache: createEmptyHistoryCache(),
|
|
373
|
+
});
|
|
374
|
+
},
|
|
375
|
+
getAddressFn: (_deviceId, _addressOpt) => Promise.resolve(addressResolver),
|
|
95
376
|
});
|
|
96
|
-
});
|
|
97
377
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
378
|
+
// When
|
|
379
|
+
let subscribeCalled = 0;
|
|
380
|
+
scanAccounts({
|
|
381
|
+
currency: getCryptoCurrencyById("algorand"),
|
|
382
|
+
deviceId: "deviceId",
|
|
383
|
+
syncConfig: {
|
|
384
|
+
paginationConfig: {},
|
|
104
385
|
},
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
386
|
+
}).subscribe({
|
|
387
|
+
// Then
|
|
388
|
+
next: ({ account, type }) => {
|
|
389
|
+
subscribeCalled++;
|
|
390
|
+
expect(type).toEqual("discovered");
|
|
391
|
+
expect(["12341", "12342", "12343"]).toContain(account.id);
|
|
392
|
+
if (account.id === "12343") {
|
|
393
|
+
expect(account.used).toBeFalsy();
|
|
394
|
+
} else {
|
|
395
|
+
expect(account.used).toBeTruthy();
|
|
396
|
+
}
|
|
109
397
|
},
|
|
110
|
-
{
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
398
|
+
complete: () => {
|
|
399
|
+
try {
|
|
400
|
+
// Expect that the 3 account have been found, 2 existing one + the usuned one
|
|
401
|
+
expect(subscribeCalled).toEqual(USED_ACCOUNT_NUMN + 1);
|
|
402
|
+
done();
|
|
403
|
+
} catch (e) {
|
|
404
|
+
done(e);
|
|
405
|
+
}
|
|
114
406
|
},
|
|
115
|
-
])("converts path for AppCoins with $name case", ({ derivationPath, expectedResult }) => {
|
|
116
|
-
const path = bip32asBuffer(derivationPath);
|
|
117
|
-
expect(path).toEqual(Buffer.from(expectedResult, "hex"));
|
|
118
407
|
});
|
|
119
408
|
});
|
|
120
409
|
});
|
|
121
410
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
411
|
+
describe("bip32asBuffer", () => {
|
|
412
|
+
it.each([
|
|
413
|
+
{
|
|
414
|
+
name: "Simple",
|
|
415
|
+
derivationPath: "m/44'/1/1/0",
|
|
416
|
+
expectedResult: "048000002c000000010000000100000000",
|
|
417
|
+
},
|
|
418
|
+
{
|
|
419
|
+
name: "Hardened coin type",
|
|
420
|
+
derivationPath: "m/44'/1'/1/0",
|
|
421
|
+
expectedResult: "048000002c800000010000000100000000",
|
|
422
|
+
},
|
|
423
|
+
{
|
|
424
|
+
name: "Hardened account",
|
|
425
|
+
derivationPath: "m/44'/1'/1'/0",
|
|
426
|
+
expectedResult: "048000002c800000018000000100000000",
|
|
427
|
+
},
|
|
428
|
+
])("converts path for AppCoins with $name case", ({ derivationPath, expectedResult }) => {
|
|
429
|
+
const path = bip32asBuffer(derivationPath);
|
|
430
|
+
expect(path).toEqual(Buffer.from(expectedResult, "hex"));
|
|
431
|
+
});
|
|
432
|
+
});
|
|
136
433
|
|
|
137
434
|
// Call once for all tests the currencies. Relies on real implementation to check also consistency.
|
|
138
435
|
const bitcoinCurrency = listCryptoCurrencies(true).find(c => c.id === "bitcoin")!;
|
|
@@ -158,7 +455,7 @@ function createAccount(init: Partial<Account>): Account {
|
|
|
158
455
|
pendingOperations: [],
|
|
159
456
|
lastSyncDate: new Date(),
|
|
160
457
|
// subAccounts: [],
|
|
161
|
-
balanceHistoryCache:
|
|
458
|
+
balanceHistoryCache: createEmptyHistoryCache(),
|
|
162
459
|
swapHistory: [],
|
|
163
460
|
};
|
|
164
461
|
}
|
package/src/bridge/jsHelpers.ts
CHANGED
|
@@ -180,6 +180,7 @@ export const makeSync =
|
|
|
180
180
|
T extends TransactionCommon = TransactionCommon,
|
|
181
181
|
A extends Account = Account,
|
|
182
182
|
U extends TransactionStatusCommon = TransactionStatusCommon,
|
|
183
|
+
O extends Operation = Operation,
|
|
183
184
|
R extends AccountRaw = AccountRaw,
|
|
184
185
|
>({
|
|
185
186
|
getAccountShape,
|
|
@@ -189,7 +190,7 @@ export const makeSync =
|
|
|
189
190
|
getAccountShape: GetAccountShape<A>;
|
|
190
191
|
postSync?: (initial: A, synced: A) => A;
|
|
191
192
|
shouldMergeOps?: boolean;
|
|
192
|
-
}): AccountBridge<T, A, U, R>["sync"] =>
|
|
193
|
+
}): AccountBridge<T, A, U, O, R>["sync"] =>
|
|
193
194
|
(initial, syncConfig): Observable<AccountUpdater<A>> =>
|
|
194
195
|
new Observable((o: Observer<(acc: A) => A>) => {
|
|
195
196
|
async function main() {
|
|
@@ -384,7 +385,7 @@ export const makeScanAccounts =
|
|
|
384
385
|
account.balanceHistoryCache = generateHistoryFromOperations(account);
|
|
385
386
|
}
|
|
386
387
|
|
|
387
|
-
if (
|
|
388
|
+
if (accountShape.used === undefined) {
|
|
388
389
|
account.used = !isAccountEmpty(account);
|
|
389
390
|
}
|
|
390
391
|
|