@ledgerhq/coin-canton 0.12.0-nightly.20251211024123 → 0.12.0-nightly.20251212024049
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 +15 -9
- package/lib/bridge/buildSubAccounts.d.ts +23 -0
- package/lib/bridge/buildSubAccounts.d.ts.map +1 -0
- package/lib/bridge/buildSubAccounts.js +80 -0
- package/lib/bridge/buildSubAccounts.js.map +1 -0
- package/lib/bridge/getTransactionStatus.d.ts.map +1 -1
- package/lib/bridge/getTransactionStatus.js +45 -24
- package/lib/bridge/getTransactionStatus.js.map +1 -1
- package/lib/bridge/index.d.ts.map +1 -1
- package/lib/bridge/index.js +2 -0
- package/lib/bridge/index.js.map +1 -1
- package/lib/bridge/prepareTransaction.d.ts.map +1 -1
- package/lib/bridge/prepareTransaction.js +19 -3
- package/lib/bridge/prepareTransaction.js.map +1 -1
- package/lib/bridge/signOperation.d.ts.map +1 -1
- package/lib/bridge/signOperation.js +3 -0
- package/lib/bridge/signOperation.js.map +1 -1
- package/lib/bridge/sync.d.ts +3 -0
- package/lib/bridge/sync.d.ts.map +1 -1
- package/lib/bridge/sync.js +115 -19
- package/lib/bridge/sync.js.map +1 -1
- package/lib/bridge/validateAddress.d.ts +3 -0
- package/lib/bridge/validateAddress.d.ts.map +1 -0
- package/lib/bridge/validateAddress.js +8 -0
- package/lib/bridge/validateAddress.js.map +1 -0
- package/lib/common-logic/account/getBalance.d.ts +1 -0
- package/lib/common-logic/account/getBalance.d.ts.map +1 -1
- package/lib/common-logic/account/getBalance.js +1 -0
- package/lib/common-logic/account/getBalance.js.map +1 -1
- package/lib/common-logic/transaction/craftTransaction.d.ts +1 -0
- package/lib/common-logic/transaction/craftTransaction.d.ts.map +1 -1
- package/lib/common-logic/transaction/craftTransaction.js +3 -0
- package/lib/common-logic/transaction/craftTransaction.js.map +1 -1
- package/lib/network/gateway.d.ts +30 -12
- package/lib/network/gateway.d.ts.map +1 -1
- package/lib/network/gateway.js +44 -1
- package/lib/network/gateway.js.map +1 -1
- package/lib/types/bridge.d.ts +2 -0
- package/lib/types/bridge.d.ts.map +1 -1
- package/lib-es/bridge/buildSubAccounts.d.ts +23 -0
- package/lib-es/bridge/buildSubAccounts.d.ts.map +1 -0
- package/lib-es/bridge/buildSubAccounts.js +74 -0
- package/lib-es/bridge/buildSubAccounts.js.map +1 -0
- package/lib-es/bridge/getTransactionStatus.d.ts.map +1 -1
- package/lib-es/bridge/getTransactionStatus.js +46 -25
- package/lib-es/bridge/getTransactionStatus.js.map +1 -1
- package/lib-es/bridge/index.d.ts.map +1 -1
- package/lib-es/bridge/index.js +2 -0
- package/lib-es/bridge/index.js.map +1 -1
- package/lib-es/bridge/prepareTransaction.d.ts.map +1 -1
- package/lib-es/bridge/prepareTransaction.js +19 -3
- package/lib-es/bridge/prepareTransaction.js.map +1 -1
- package/lib-es/bridge/signOperation.d.ts.map +1 -1
- package/lib-es/bridge/signOperation.js +3 -0
- package/lib-es/bridge/signOperation.js.map +1 -1
- package/lib-es/bridge/sync.d.ts +3 -0
- package/lib-es/bridge/sync.d.ts.map +1 -1
- package/lib-es/bridge/sync.js +115 -20
- package/lib-es/bridge/sync.js.map +1 -1
- package/lib-es/bridge/validateAddress.d.ts +3 -0
- package/lib-es/bridge/validateAddress.d.ts.map +1 -0
- package/lib-es/bridge/validateAddress.js +5 -0
- package/lib-es/bridge/validateAddress.js.map +1 -0
- package/lib-es/common-logic/account/getBalance.d.ts +1 -0
- package/lib-es/common-logic/account/getBalance.d.ts.map +1 -1
- package/lib-es/common-logic/account/getBalance.js +1 -0
- package/lib-es/common-logic/account/getBalance.js.map +1 -1
- package/lib-es/common-logic/transaction/craftTransaction.d.ts +1 -0
- package/lib-es/common-logic/transaction/craftTransaction.d.ts.map +1 -1
- package/lib-es/common-logic/transaction/craftTransaction.js +3 -0
- package/lib-es/common-logic/transaction/craftTransaction.js.map +1 -1
- package/lib-es/network/gateway.d.ts +30 -12
- package/lib-es/network/gateway.d.ts.map +1 -1
- package/lib-es/network/gateway.js +41 -0
- package/lib-es/network/gateway.js.map +1 -1
- package/lib-es/types/bridge.d.ts +2 -0
- package/lib-es/types/bridge.d.ts.map +1 -1
- package/package.json +9 -9
- package/src/bridge/buildSubAccounts.test.ts +120 -0
- package/src/bridge/buildSubAccounts.ts +132 -0
- package/src/bridge/getTransactionStatus.ts +53 -22
- package/src/bridge/index.ts +2 -0
- package/src/bridge/prepareTransaction.ts +29 -4
- package/src/bridge/signOperation.ts +4 -0
- package/src/bridge/sync.test.ts +237 -191
- package/src/bridge/sync.ts +154 -24
- package/src/bridge/validateAddress.test.ts +25 -0
- package/src/bridge/validateAddress.ts +9 -0
- package/src/common-logic/account/getBalance.ts +2 -0
- package/src/common-logic/transaction/craftTransaction.ts +5 -0
- package/src/network/gateway.test.ts +169 -0
- package/src/network/gateway.ts +83 -12
- package/src/types/bridge.ts +2 -0
- package/tsconfig.json +7 -2
package/src/bridge/sync.test.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { makeGetAccountShape } from "./sync";
|
|
2
|
-
import { OperationInfo
|
|
1
|
+
import { makeGetAccountShape, filterDisabledTokenAccounts } from "./sync";
|
|
2
|
+
import { OperationInfo } from "../network/gateway";
|
|
3
3
|
import * as gateway from "../network/gateway";
|
|
4
4
|
import * as onboard from "./onboard";
|
|
5
5
|
import * as config from "../config";
|
|
6
|
+
import * as accountBalance from "../common-logic/account/getBalance";
|
|
6
7
|
import resolver from "../signer";
|
|
7
8
|
import { AccountShapeInfo } from "@ledgerhq/coin-framework/bridge/jsHelpers";
|
|
8
|
-
import { Account } from "@ledgerhq/types-live";
|
|
9
|
+
import { Account, TokenAccount } from "@ledgerhq/types-live";
|
|
9
10
|
import BigNumber from "bignumber.js";
|
|
10
11
|
import { CantonAccount } from "../types";
|
|
11
12
|
import { createMockCantonCurrency } from "../test/fixtures";
|
|
@@ -14,34 +15,76 @@ jest.mock("../network/gateway");
|
|
|
14
15
|
jest.mock("../signer");
|
|
15
16
|
jest.mock("../config");
|
|
16
17
|
jest.mock("./onboard");
|
|
18
|
+
jest.mock("../common-logic/account/getBalance");
|
|
19
|
+
jest.mock("@ledgerhq/cryptoassets/state", () => {
|
|
20
|
+
const store = {
|
|
21
|
+
findTokenByAddressInCurrency: jest.fn().mockResolvedValue(undefined),
|
|
22
|
+
};
|
|
23
|
+
return {
|
|
24
|
+
getCryptoAssetsStore: jest.fn(() => store),
|
|
25
|
+
};
|
|
26
|
+
});
|
|
17
27
|
|
|
18
|
-
const mockedGetBalance =
|
|
28
|
+
const mockedGetBalance = accountBalance.getBalance as jest.Mock;
|
|
19
29
|
const mockedGetLedgerEnd = gateway.getLedgerEnd as jest.Mock;
|
|
20
30
|
const mockedGetOperations = gateway.getOperations as jest.Mock;
|
|
31
|
+
const mockedGetPendingTransferProposals = gateway.getPendingTransferProposals as jest.Mock;
|
|
32
|
+
const mockedGetCalTokensCached = gateway.getCalTokensCached as unknown as jest.Mock;
|
|
33
|
+
const mockedGetEnabledInstrumentsCached =
|
|
34
|
+
gateway.getEnabledInstrumentsCached as unknown as jest.Mock;
|
|
21
35
|
const mockedResolver = resolver as jest.Mock;
|
|
22
36
|
const mockedIsOnboarded = onboard.isAccountOnboarded as jest.Mock;
|
|
23
37
|
const mockedIsAuthorized = onboard.isCantonCoinPreapproved as jest.Mock;
|
|
24
38
|
const mockedCoinConfig = config.default.getCoinConfig as jest.Mock;
|
|
25
39
|
|
|
26
|
-
const sampleCurrency =
|
|
27
|
-
|
|
40
|
+
const sampleCurrency = createMockCantonCurrency();
|
|
41
|
+
|
|
42
|
+
type CantonBalance = {
|
|
43
|
+
value: bigint;
|
|
44
|
+
locked: bigint;
|
|
45
|
+
asset: { type: "native" } | { type: "token"; assetReference: string };
|
|
46
|
+
utxoCount: number;
|
|
47
|
+
instrumentId: string;
|
|
48
|
+
adminId: string;
|
|
28
49
|
};
|
|
29
50
|
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
51
|
+
const createMockNativeBalance = (amount: string, locked = false): CantonBalance => ({
|
|
52
|
+
value: BigInt(amount),
|
|
53
|
+
locked: locked ? BigInt(amount) : BigInt(0),
|
|
54
|
+
asset: { type: "native" },
|
|
55
|
+
utxoCount: 1,
|
|
56
|
+
instrumentId: "Amulet",
|
|
57
|
+
adminId: "native-admin",
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const createMockTokenBalance = (
|
|
61
|
+
instrumentId: string,
|
|
62
|
+
amount: string,
|
|
63
|
+
locked = false,
|
|
64
|
+
): CantonBalance => ({
|
|
65
|
+
value: BigInt(amount),
|
|
66
|
+
locked: locked ? BigInt(amount) : BigInt(0),
|
|
67
|
+
asset: { type: "token", assetReference: instrumentId },
|
|
68
|
+
utxoCount: 1,
|
|
69
|
+
instrumentId,
|
|
70
|
+
adminId: `admin-${instrumentId}`,
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
const createMockOperationView = (
|
|
74
|
+
overrides: {
|
|
75
|
+
instrumentId?: string;
|
|
76
|
+
instrumentAdmin?: string | null;
|
|
77
|
+
txHash?: string;
|
|
78
|
+
uid?: string;
|
|
79
|
+
type?: string;
|
|
80
|
+
value?: string;
|
|
81
|
+
operationType?: string;
|
|
82
|
+
} = {},
|
|
83
|
+
): OperationInfo =>
|
|
41
84
|
({
|
|
42
|
-
transaction_hash: "tx-test",
|
|
43
|
-
uid: "uid-test",
|
|
44
|
-
type: "Send",
|
|
85
|
+
transaction_hash: overrides.txHash ?? "tx-test",
|
|
86
|
+
uid: overrides.uid ?? "uid-test",
|
|
87
|
+
type: overrides.type ?? "Send",
|
|
45
88
|
status: "Success",
|
|
46
89
|
fee: {
|
|
47
90
|
value: "5",
|
|
@@ -57,10 +100,10 @@ const createMockOperationView = (): OperationInfo =>
|
|
|
57
100
|
{
|
|
58
101
|
address: "party123",
|
|
59
102
|
type: "Send",
|
|
60
|
-
value: "100",
|
|
61
|
-
asset: "
|
|
103
|
+
value: overrides.value ?? "100",
|
|
104
|
+
asset: overrides.instrumentId ?? "Amulet",
|
|
62
105
|
details: {
|
|
63
|
-
operationType: "transfer",
|
|
106
|
+
operationType: overrides.operationType ?? "transfer",
|
|
64
107
|
metadata: {
|
|
65
108
|
reason: "test transfer",
|
|
66
109
|
},
|
|
@@ -76,11 +119,11 @@ const createMockOperationView = (): OperationInfo =>
|
|
|
76
119
|
hash: "blockhash1",
|
|
77
120
|
},
|
|
78
121
|
asset: {
|
|
79
|
-
|
|
80
|
-
|
|
122
|
+
instrumentId: overrides.instrumentId ?? "Amulet",
|
|
123
|
+
instrumentAdmin: overrides.instrumentAdmin ?? null,
|
|
81
124
|
},
|
|
82
125
|
details: {
|
|
83
|
-
operationType: "transfer",
|
|
126
|
+
operationType: overrides.operationType ?? "transfer",
|
|
84
127
|
},
|
|
85
128
|
}) as OperationInfo;
|
|
86
129
|
|
|
@@ -125,49 +168,27 @@ describe("makeGetAccountShape", () => {
|
|
|
125
168
|
});
|
|
126
169
|
|
|
127
170
|
mockedCoinConfig.mockReturnValue({
|
|
128
|
-
nativeInstrumentId: "
|
|
171
|
+
nativeInstrumentId: "Amulet",
|
|
129
172
|
minReserve: "0",
|
|
130
173
|
useGateway: true,
|
|
131
174
|
});
|
|
132
175
|
|
|
133
176
|
mockedIsAuthorized.mockResolvedValue(true);
|
|
134
177
|
mockedGetLedgerEnd.mockResolvedValue(12345);
|
|
178
|
+
mockedGetPendingTransferProposals.mockResolvedValue([]);
|
|
179
|
+
mockedGetCalTokensCached.mockResolvedValue(new Map());
|
|
135
180
|
});
|
|
136
181
|
|
|
137
182
|
it("should return a valid account shape with correct balances and operations", async () => {
|
|
138
|
-
mockedGetBalance.mockResolvedValue([
|
|
139
|
-
{
|
|
140
|
-
instrument_id: "Native",
|
|
141
|
-
amount: "1000",
|
|
142
|
-
locked: false,
|
|
143
|
-
utxo_count: 1,
|
|
144
|
-
},
|
|
145
|
-
]);
|
|
183
|
+
mockedGetBalance.mockResolvedValue([createMockNativeBalance("1000")]);
|
|
146
184
|
mockedGetOperations.mockResolvedValue({
|
|
147
185
|
operations: [
|
|
148
|
-
{
|
|
149
|
-
|
|
186
|
+
createMockOperationView({
|
|
187
|
+
txHash: "tx1",
|
|
150
188
|
uid: "uid1",
|
|
151
189
|
type: "Send",
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
{
|
|
155
|
-
value: "100",
|
|
156
|
-
details: {
|
|
157
|
-
metadata: {
|
|
158
|
-
reason: "test transfer",
|
|
159
|
-
},
|
|
160
|
-
},
|
|
161
|
-
},
|
|
162
|
-
],
|
|
163
|
-
transaction_timestamp: new Date().toISOString(),
|
|
164
|
-
senders: ["party123"],
|
|
165
|
-
recipients: ["party456"],
|
|
166
|
-
block: {
|
|
167
|
-
height: 1,
|
|
168
|
-
hash: "blockhash1",
|
|
169
|
-
},
|
|
170
|
-
} as OperationInfo,
|
|
190
|
+
value: "100",
|
|
191
|
+
}),
|
|
171
192
|
],
|
|
172
193
|
});
|
|
173
194
|
const getAccountShape = makeGetAccountShape(fakeSignerContext);
|
|
@@ -186,18 +207,8 @@ describe("makeGetAccountShape", () => {
|
|
|
186
207
|
|
|
187
208
|
it("should handle locked balances correctly", async () => {
|
|
188
209
|
mockedGetBalance.mockResolvedValue([
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
amount: "1000",
|
|
192
|
-
locked: true,
|
|
193
|
-
utxo_count: 1,
|
|
194
|
-
},
|
|
195
|
-
{
|
|
196
|
-
instrument_id: "Native",
|
|
197
|
-
amount: "10",
|
|
198
|
-
locked: false,
|
|
199
|
-
utxo_count: 1,
|
|
200
|
-
},
|
|
210
|
+
createMockNativeBalance("1000", true),
|
|
211
|
+
createMockNativeBalance("10", false),
|
|
201
212
|
]);
|
|
202
213
|
|
|
203
214
|
const getAccountShape = makeGetAccountShape(fakeSignerContext);
|
|
@@ -207,7 +218,7 @@ describe("makeGetAccountShape", () => {
|
|
|
207
218
|
|
|
208
219
|
expect(shape).toBeDefined();
|
|
209
220
|
expect(shape.balance).toEqual(BigNumber(1010));
|
|
210
|
-
expect(shape.spendableBalance).toEqual(BigNumber(
|
|
221
|
+
expect(shape.spendableBalance).toEqual(BigNumber(10));
|
|
211
222
|
});
|
|
212
223
|
|
|
213
224
|
it("should handle empty balances correctly", async () => {
|
|
@@ -224,39 +235,15 @@ describe("makeGetAccountShape", () => {
|
|
|
224
235
|
});
|
|
225
236
|
|
|
226
237
|
it("should default to FEES operation type when transferValue is 0", async () => {
|
|
227
|
-
mockedGetBalance.mockResolvedValue([
|
|
228
|
-
{
|
|
229
|
-
instrument_id: "Native",
|
|
230
|
-
amount: "1000",
|
|
231
|
-
locked: false,
|
|
232
|
-
utxo_count: 1,
|
|
233
|
-
},
|
|
234
|
-
]);
|
|
238
|
+
mockedGetBalance.mockResolvedValue([createMockNativeBalance("1000")]);
|
|
235
239
|
mockedGetOperations.mockResolvedValue({
|
|
236
240
|
operations: [
|
|
237
|
-
{
|
|
238
|
-
|
|
241
|
+
createMockOperationView({
|
|
242
|
+
txHash: "tx2",
|
|
239
243
|
uid: "uid2",
|
|
240
244
|
type: "Send",
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
{
|
|
244
|
-
value: "0",
|
|
245
|
-
details: {
|
|
246
|
-
metadata: {
|
|
247
|
-
reason: "fee only",
|
|
248
|
-
},
|
|
249
|
-
},
|
|
250
|
-
},
|
|
251
|
-
],
|
|
252
|
-
transaction_timestamp: new Date().toISOString(),
|
|
253
|
-
senders: ["party123"],
|
|
254
|
-
recipients: ["party456"],
|
|
255
|
-
block: {
|
|
256
|
-
height: 2,
|
|
257
|
-
hash: "blockhash2",
|
|
258
|
-
},
|
|
259
|
-
} as OperationInfo,
|
|
245
|
+
value: "0",
|
|
246
|
+
}),
|
|
260
247
|
],
|
|
261
248
|
});
|
|
262
249
|
|
|
@@ -267,44 +254,20 @@ describe("makeGetAccountShape", () => {
|
|
|
267
254
|
expect(shape).toBeDefined();
|
|
268
255
|
expect(shape.operations[0].type).toBe("FEES");
|
|
269
256
|
// In this case, value should equal the fee
|
|
270
|
-
expect(shape.operations[0].value).toEqual(BigNumber(
|
|
257
|
+
expect(shape.operations[0].value).toEqual(BigNumber(5)); // fee is 5 in createMockOperationView
|
|
271
258
|
});
|
|
272
259
|
|
|
273
260
|
it("should set operation type to TRANSFER_PROPOSAL when operationType is transfer-proposal", async () => {
|
|
274
|
-
mockedGetBalance.mockResolvedValue([
|
|
275
|
-
{
|
|
276
|
-
instrument_id: "Native",
|
|
277
|
-
amount: "1000",
|
|
278
|
-
locked: false,
|
|
279
|
-
utxo_count: 1,
|
|
280
|
-
},
|
|
281
|
-
]);
|
|
261
|
+
mockedGetBalance.mockResolvedValue([createMockNativeBalance("1000")]);
|
|
282
262
|
mockedGetOperations.mockResolvedValue({
|
|
283
263
|
operations: [
|
|
284
|
-
{
|
|
285
|
-
|
|
264
|
+
createMockOperationView({
|
|
265
|
+
txHash: "tx3",
|
|
286
266
|
uid: "uid3",
|
|
287
267
|
type: "Send",
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
value: "200",
|
|
292
|
-
details: {
|
|
293
|
-
operationType: "transfer-proposal",
|
|
294
|
-
metadata: {
|
|
295
|
-
reason: "transfer proposal",
|
|
296
|
-
},
|
|
297
|
-
},
|
|
298
|
-
},
|
|
299
|
-
],
|
|
300
|
-
transaction_timestamp: new Date().toISOString(),
|
|
301
|
-
senders: ["party123"],
|
|
302
|
-
recipients: ["party456"],
|
|
303
|
-
block: {
|
|
304
|
-
height: 3,
|
|
305
|
-
hash: "blockhash3",
|
|
306
|
-
},
|
|
307
|
-
} as OperationInfo,
|
|
268
|
+
value: "200",
|
|
269
|
+
operationType: "transfer-proposal",
|
|
270
|
+
}),
|
|
308
271
|
],
|
|
309
272
|
});
|
|
310
273
|
|
|
@@ -318,40 +281,16 @@ describe("makeGetAccountShape", () => {
|
|
|
318
281
|
});
|
|
319
282
|
|
|
320
283
|
it("should set operation type to TRANSFER_REJECTED when operationType is transfer-rejected", async () => {
|
|
321
|
-
mockedGetBalance.mockResolvedValue([
|
|
322
|
-
{
|
|
323
|
-
instrument_id: "Native",
|
|
324
|
-
amount: "1000",
|
|
325
|
-
locked: false,
|
|
326
|
-
utxo_count: 1,
|
|
327
|
-
},
|
|
328
|
-
]);
|
|
284
|
+
mockedGetBalance.mockResolvedValue([createMockNativeBalance("1000")]);
|
|
329
285
|
mockedGetOperations.mockResolvedValue({
|
|
330
286
|
operations: [
|
|
331
|
-
{
|
|
332
|
-
|
|
287
|
+
createMockOperationView({
|
|
288
|
+
txHash: "tx4",
|
|
333
289
|
uid: "uid4",
|
|
334
290
|
type: "Send",
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
value: "150",
|
|
339
|
-
details: {
|
|
340
|
-
operationType: "transfer-rejected",
|
|
341
|
-
metadata: {
|
|
342
|
-
reason: "transfer rejected",
|
|
343
|
-
},
|
|
344
|
-
},
|
|
345
|
-
},
|
|
346
|
-
],
|
|
347
|
-
transaction_timestamp: new Date().toISOString(),
|
|
348
|
-
senders: ["party123"],
|
|
349
|
-
recipients: ["party456"],
|
|
350
|
-
block: {
|
|
351
|
-
height: 4,
|
|
352
|
-
hash: "blockhash4",
|
|
353
|
-
},
|
|
354
|
-
} as OperationInfo,
|
|
291
|
+
value: "150",
|
|
292
|
+
operationType: "transfer-rejected",
|
|
293
|
+
}),
|
|
355
294
|
],
|
|
356
295
|
});
|
|
357
296
|
|
|
@@ -365,40 +304,16 @@ describe("makeGetAccountShape", () => {
|
|
|
365
304
|
});
|
|
366
305
|
|
|
367
306
|
it("should set operation type to TRANSFER_WITHDRAWN when operationType is transfer-withdrawn", async () => {
|
|
368
|
-
mockedGetBalance.mockResolvedValue([
|
|
369
|
-
{
|
|
370
|
-
instrument_id: "Native",
|
|
371
|
-
amount: "1000",
|
|
372
|
-
locked: false,
|
|
373
|
-
utxo_count: 1,
|
|
374
|
-
},
|
|
375
|
-
]);
|
|
307
|
+
mockedGetBalance.mockResolvedValue([createMockNativeBalance("1000")]);
|
|
376
308
|
mockedGetOperations.mockResolvedValue({
|
|
377
309
|
operations: [
|
|
378
|
-
{
|
|
379
|
-
|
|
310
|
+
createMockOperationView({
|
|
311
|
+
txHash: "tx5",
|
|
380
312
|
uid: "uid5",
|
|
381
313
|
type: "Send",
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
value: "50",
|
|
386
|
-
details: {
|
|
387
|
-
operationType: "transfer-withdrawn",
|
|
388
|
-
metadata: {
|
|
389
|
-
reason: "transfer withdrawn",
|
|
390
|
-
},
|
|
391
|
-
},
|
|
392
|
-
},
|
|
393
|
-
],
|
|
394
|
-
transaction_timestamp: new Date().toISOString(),
|
|
395
|
-
senders: ["party123"],
|
|
396
|
-
recipients: ["party456"],
|
|
397
|
-
block: {
|
|
398
|
-
height: 5,
|
|
399
|
-
hash: "blockhash5",
|
|
400
|
-
},
|
|
401
|
-
} as OperationInfo,
|
|
314
|
+
value: "50",
|
|
315
|
+
operationType: "transfer-withdrawn",
|
|
316
|
+
}),
|
|
402
317
|
],
|
|
403
318
|
});
|
|
404
319
|
|
|
@@ -412,7 +327,7 @@ describe("makeGetAccountShape", () => {
|
|
|
412
327
|
});
|
|
413
328
|
|
|
414
329
|
it("should sync without device when account has xpub but no publicKey", async () => {
|
|
415
|
-
mockedGetBalance.mockResolvedValue(
|
|
330
|
+
mockedGetBalance.mockResolvedValue([createMockNativeBalance("1000")]);
|
|
416
331
|
mockedGetOperations.mockResolvedValue({
|
|
417
332
|
operations: [createMockOperationView()],
|
|
418
333
|
});
|
|
@@ -465,7 +380,7 @@ describe("makeGetAccountShape", () => {
|
|
|
465
380
|
});
|
|
466
381
|
|
|
467
382
|
it("should sync without device when account has both xpub and publicKey", async () => {
|
|
468
|
-
mockedGetBalance.mockResolvedValue(
|
|
383
|
+
mockedGetBalance.mockResolvedValue([createMockNativeBalance("1000")]);
|
|
469
384
|
mockedGetOperations.mockResolvedValue({
|
|
470
385
|
operations: [createMockOperationView()],
|
|
471
386
|
});
|
|
@@ -491,3 +406,134 @@ describe("makeGetAccountShape", () => {
|
|
|
491
406
|
expect(mockedResolver).not.toHaveBeenCalled();
|
|
492
407
|
});
|
|
493
408
|
});
|
|
409
|
+
|
|
410
|
+
describe("filterDisabledTokenAccounts", () => {
|
|
411
|
+
const currency = createMockCantonCurrency();
|
|
412
|
+
|
|
413
|
+
const createMockTokenAccount = (contractAddress: string): TokenAccount => ({
|
|
414
|
+
type: "TokenAccount",
|
|
415
|
+
id: `token-account-${contractAddress}`,
|
|
416
|
+
parentId: "parent-account-id",
|
|
417
|
+
token: {
|
|
418
|
+
type: "TokenCurrency",
|
|
419
|
+
id: `token-id-${contractAddress}`,
|
|
420
|
+
contractAddress,
|
|
421
|
+
name: "Test Token",
|
|
422
|
+
ticker: "TEST",
|
|
423
|
+
decimals: 18,
|
|
424
|
+
parentCurrency: currency,
|
|
425
|
+
} as any,
|
|
426
|
+
balance: new BigNumber(100),
|
|
427
|
+
spendableBalance: new BigNumber(100),
|
|
428
|
+
operationsCount: 0,
|
|
429
|
+
operations: [],
|
|
430
|
+
pendingOperations: [],
|
|
431
|
+
balanceHistoryCache: {
|
|
432
|
+
HOUR: { latestDate: null, balances: [] },
|
|
433
|
+
DAY: { latestDate: null, balances: [] },
|
|
434
|
+
WEEK: { latestDate: null, balances: [] },
|
|
435
|
+
},
|
|
436
|
+
swapHistory: [],
|
|
437
|
+
creationDate: new Date(),
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
beforeEach(() => {
|
|
441
|
+
jest.clearAllMocks();
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
it("should return empty array when subAccounts is undefined", async () => {
|
|
445
|
+
const result = await filterDisabledTokenAccounts(currency, undefined);
|
|
446
|
+
expect(result).toEqual([]);
|
|
447
|
+
expect(mockedGetEnabledInstrumentsCached).not.toHaveBeenCalled();
|
|
448
|
+
});
|
|
449
|
+
|
|
450
|
+
it("should return empty array when subAccounts is empty", async () => {
|
|
451
|
+
const result = await filterDisabledTokenAccounts(currency, []);
|
|
452
|
+
expect(result).toEqual([]);
|
|
453
|
+
expect(mockedGetEnabledInstrumentsCached).not.toHaveBeenCalled();
|
|
454
|
+
});
|
|
455
|
+
|
|
456
|
+
it("should filter out disabled token accounts", async () => {
|
|
457
|
+
const enabledTokenId = "0xenabled";
|
|
458
|
+
const disabledTokenId = "0xdisabled";
|
|
459
|
+
const enabledTokenAccount = createMockTokenAccount(enabledTokenId);
|
|
460
|
+
const disabledTokenAccount = createMockTokenAccount(disabledTokenId);
|
|
461
|
+
|
|
462
|
+
mockedGetEnabledInstrumentsCached.mockResolvedValue([enabledTokenId]);
|
|
463
|
+
|
|
464
|
+
const result = await filterDisabledTokenAccounts(currency, [
|
|
465
|
+
enabledTokenAccount,
|
|
466
|
+
disabledTokenAccount,
|
|
467
|
+
]);
|
|
468
|
+
|
|
469
|
+
expect(result).toHaveLength(1);
|
|
470
|
+
expect(result[0]).toBe(enabledTokenAccount);
|
|
471
|
+
expect(mockedGetEnabledInstrumentsCached).toHaveBeenCalledWith(currency);
|
|
472
|
+
});
|
|
473
|
+
|
|
474
|
+
it("should keep enabled token accounts", async () => {
|
|
475
|
+
const enabledTokenId1 = "0xenabled1";
|
|
476
|
+
const enabledTokenId2 = "0xenabled2";
|
|
477
|
+
const enabledTokenAccount1 = createMockTokenAccount(enabledTokenId1);
|
|
478
|
+
const enabledTokenAccount2 = createMockTokenAccount(enabledTokenId2);
|
|
479
|
+
|
|
480
|
+
mockedGetEnabledInstrumentsCached.mockResolvedValue([enabledTokenId1, enabledTokenId2]);
|
|
481
|
+
|
|
482
|
+
const result = await filterDisabledTokenAccounts(currency, [
|
|
483
|
+
enabledTokenAccount1,
|
|
484
|
+
enabledTokenAccount2,
|
|
485
|
+
]);
|
|
486
|
+
|
|
487
|
+
expect(result).toHaveLength(2);
|
|
488
|
+
expect(result).toContain(enabledTokenAccount1);
|
|
489
|
+
expect(result).toContain(enabledTokenAccount2);
|
|
490
|
+
});
|
|
491
|
+
|
|
492
|
+
it("should not keep token accounts without contractAddress", async () => {
|
|
493
|
+
const tokenAccountWithoutAddress = {
|
|
494
|
+
...createMockTokenAccount("0xtest"),
|
|
495
|
+
token: {
|
|
496
|
+
...createMockTokenAccount("0xtest").token,
|
|
497
|
+
contractAddress: "",
|
|
498
|
+
},
|
|
499
|
+
};
|
|
500
|
+
const enabledTokenAccount = createMockTokenAccount("0xenabled");
|
|
501
|
+
|
|
502
|
+
mockedGetEnabledInstrumentsCached.mockResolvedValue(["0xenabled"]);
|
|
503
|
+
|
|
504
|
+
const result = await filterDisabledTokenAccounts(currency, [
|
|
505
|
+
tokenAccountWithoutAddress,
|
|
506
|
+
enabledTokenAccount,
|
|
507
|
+
]);
|
|
508
|
+
|
|
509
|
+
expect(result).toHaveLength(1);
|
|
510
|
+
expect(result[0]).toBe(enabledTokenAccount);
|
|
511
|
+
expect(result).not.toContain(tokenAccountWithoutAddress);
|
|
512
|
+
});
|
|
513
|
+
|
|
514
|
+
it("should return empty array when API fails", async () => {
|
|
515
|
+
const enabledTokenAccount = createMockTokenAccount("0xenabled");
|
|
516
|
+
const disabledTokenAccount = createMockTokenAccount("0xdisabled");
|
|
517
|
+
|
|
518
|
+
mockedGetEnabledInstrumentsCached.mockRejectedValue(new Error("Network error"));
|
|
519
|
+
|
|
520
|
+
const result = await filterDisabledTokenAccounts(currency, [
|
|
521
|
+
enabledTokenAccount,
|
|
522
|
+
disabledTokenAccount,
|
|
523
|
+
]);
|
|
524
|
+
|
|
525
|
+
expect(result).toEqual([]);
|
|
526
|
+
expect(mockedGetEnabledInstrumentsCached).toHaveBeenCalledWith(currency);
|
|
527
|
+
});
|
|
528
|
+
|
|
529
|
+
it("should handle empty enabled instruments list", async () => {
|
|
530
|
+
const tokenAccount1 = createMockTokenAccount("0xtoken1");
|
|
531
|
+
const tokenAccount2 = createMockTokenAccount("0xtoken2");
|
|
532
|
+
|
|
533
|
+
mockedGetEnabledInstrumentsCached.mockResolvedValue([]);
|
|
534
|
+
|
|
535
|
+
const result = await filterDisabledTokenAccounts(currency, [tokenAccount1, tokenAccount2]);
|
|
536
|
+
|
|
537
|
+
expect(result).toEqual([]);
|
|
538
|
+
});
|
|
539
|
+
});
|