@ledgerhq/hw-app-eth 6.38.2 → 7.0.0-nightly.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 +18 -0
- package/lib/modules/EIP712/index.d.ts.map +1 -1
- package/lib/modules/EIP712/index.js +44 -8
- package/lib/modules/EIP712/index.js.map +1 -1
- package/lib/modules/EIP712/types.d.ts +4 -0
- package/lib/modules/EIP712/types.d.ts.map +1 -1
- package/lib/services/ledger/erc20.js +1 -1
- package/lib/services/ledger/erc20.js.map +1 -1
- package/lib-es/modules/EIP712/index.d.ts.map +1 -1
- package/lib-es/modules/EIP712/index.js +44 -8
- package/lib-es/modules/EIP712/index.js.map +1 -1
- package/lib-es/modules/EIP712/types.d.ts +4 -0
- package/lib-es/modules/EIP712/types.d.ts.map +1 -1
- package/lib-es/services/ledger/erc20.js +1 -1
- package/lib-es/services/ledger/erc20.js.map +1 -1
- package/package.json +5 -5
- package/src/modules/EIP712/index.ts +63 -8
- package/src/modules/EIP712/types.ts +4 -0
- package/src/services/ledger/erc20.ts +1 -1
- package/tests/EIP712/filtered-signMessage.unit.test.ts +226 -138
- package/tests/EIP712/noFilter-signMessage.unit.test.ts +20 -20
- package/tests/ERC20/ERC20-CAL-KO.unit.test.ts +14 -4
- package/tests/ERC20/ERC20-CAL-OK.unit.test.ts +14 -3
- package/tests/Eth.unit.test.ts +6 -2
- package/tests/fixtures/CAL.ts +301 -208
- package/tests/fixtures/apdus/{0-filtered.apdus → 0-filtered-v1.apdus} +5 -5
- package/tests/fixtures/apdus/1-filtered-empty-array-1-level-v2.apdus +72 -0
- package/tests/fixtures/apdus/1-filtered-empty-array-2-levels-v2.apdus +68 -0
- package/tests/fixtures/apdus/{1-filtered.apdus → 1-filtered-v1.apdus} +8 -8
- package/tests/fixtures/apdus/{10-filtered.apdus → 10-filtered-v1.apdus} +4 -4
- package/tests/fixtures/apdus/{11-filtered.apdus → 11-filtered-v1.apdus} +9 -9
- package/tests/fixtures/apdus/12-filtered-v1.apdus +38 -0
- package/tests/fixtures/apdus/13-filtered-v1.apdus +108 -0
- package/tests/fixtures/apdus/14-filtered-v1.apdus +28 -0
- package/tests/fixtures/apdus/15-filtered-v1.apdus +6 -6
- package/tests/fixtures/apdus/15-filtered-v2.apdus +7 -7
- package/tests/fixtures/apdus/16-filtered-v1.apdus +6 -6
- package/tests/fixtures/apdus/16-filtered-v2.apdus +7 -7
- package/tests/fixtures/apdus/17-filtered-v1.apdus +164 -0
- package/tests/fixtures/apdus/17-filtered-v2.apdus +168 -0
- package/tests/fixtures/apdus/18-filtered-v1.apdus +8 -8
- package/tests/fixtures/apdus/18-filtered-v2.apdus +10 -10
- package/tests/fixtures/apdus/{2-filtered.apdus → 2-filtered-v1.apdus} +7 -7
- package/tests/fixtures/apdus/3-filtered-v1.apdus +60 -0
- package/tests/fixtures/apdus/{4-filtered.apdus → 4-filtered-v1.apdus} +5 -5
- package/tests/fixtures/apdus/5-filtered-v1.apdus +176 -0
- package/tests/fixtures/apdus/{6-filtered.apdus → 6-filtered-v1.apdus} +9 -9
- package/tests/fixtures/apdus/{7-filtered.apdus → 7-filtered-v1.apdus} +7 -7
- package/tests/fixtures/apdus/{8-filtered.apdus → 8-filtered-v1.apdus} +8 -8
- package/tests/fixtures/apdus/{9-filtered.apdus → 9-filtered-v1.apdus} +8 -8
- package/tests/fixtures/apdus/ERC20-KO.apdus +1 -1
- package/tests/fixtures/apdus/ERC20-OK.apdus +3 -3
- package/tests/fixtures/apdus/version-1.12.0.apdus +2 -0
- package/tests/fixtures/messages/1-empty-array-1-level.json +79 -0
- package/tests/fixtures/messages/1-empty-array-2-levels.json +74 -0
- package/tests/fixtures/apdus/12-filtered.apdus +0 -38
- package/tests/fixtures/apdus/13-filtered.apdus +0 -108
- package/tests/fixtures/apdus/17-filtered.apdus +0 -0
- package/tests/fixtures/apdus/3-filtered.apdus +0 -60
- package/tests/fixtures/apdus/5-filtered.apdus +0 -176
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
makeTypeEntryStructBuffer,
|
|
27
27
|
} from "./utils";
|
|
28
28
|
import {
|
|
29
|
+
FilteringInfoDiscardField,
|
|
29
30
|
FilteringInfoContractName,
|
|
30
31
|
FilteringInfoShowField,
|
|
31
32
|
StructImplemData,
|
|
@@ -40,6 +41,7 @@ type MakeRecursiveFieldStructImplemParams = {
|
|
|
40
41
|
types: EIP712MessageTypes;
|
|
41
42
|
filters: MessageFilters | undefined;
|
|
42
43
|
shouldUseV1Filters: boolean;
|
|
44
|
+
shouldUseDiscardedFields: boolean;
|
|
43
45
|
coinRefsTokensMap: Record<number, { token: string; coinRefMemorySlot?: number }>;
|
|
44
46
|
};
|
|
45
47
|
|
|
@@ -61,6 +63,7 @@ const makeRecursiveFieldStructImplem = ({
|
|
|
61
63
|
types,
|
|
62
64
|
filters,
|
|
63
65
|
shouldUseV1Filters,
|
|
66
|
+
shouldUseDiscardedFields,
|
|
64
67
|
coinRefsTokensMap,
|
|
65
68
|
}: MakeRecursiveFieldStructImplemParams): ((
|
|
66
69
|
destructedType: ReturnType<typeof destructTypeFromString>,
|
|
@@ -88,8 +91,33 @@ const makeRecursiveFieldStructImplem = ({
|
|
|
88
91
|
structType: "array",
|
|
89
92
|
value: data.length,
|
|
90
93
|
});
|
|
94
|
+
|
|
95
|
+
const entryPath = `${path}.[]`;
|
|
96
|
+
if (!data.length) {
|
|
97
|
+
// If the array is empty and a filter exists, we need to let the app know that the filter can be discarded
|
|
98
|
+
const entryFilters = filters?.fields.filter(f => f.path.startsWith(entryPath));
|
|
99
|
+
if (entryFilters && shouldUseDiscardedFields) {
|
|
100
|
+
for (const entryFilter of entryFilters) {
|
|
101
|
+
await sendFilteringInfo(transport, "discardField", loadConfig, {
|
|
102
|
+
path: entryFilter.path,
|
|
103
|
+
});
|
|
104
|
+
await sendFilteringInfo(transport, "showField", loadConfig, {
|
|
105
|
+
displayName: entryFilter.label,
|
|
106
|
+
sig: entryFilter.signature,
|
|
107
|
+
format: entryFilter.format,
|
|
108
|
+
coinRef: entryFilter.coin_ref,
|
|
109
|
+
chainId,
|
|
110
|
+
erc20SignaturesBlob,
|
|
111
|
+
shouldUseV1Filters,
|
|
112
|
+
coinRefsTokensMap,
|
|
113
|
+
isDiscarded: true,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// If the array is not empty, we need to send the struct implementation for each entry
|
|
91
119
|
for (const entry of data) {
|
|
92
|
-
await recursiveFieldStructImplem([typeDescription, restSizes], entry,
|
|
120
|
+
await recursiveFieldStructImplem([typeDescription, restSizes], entry, entryPath);
|
|
93
121
|
}
|
|
94
122
|
} else if (isCustomType) {
|
|
95
123
|
for (const [fieldName, fieldValue] of Object.entries(data as EIP712Message["message"])) {
|
|
@@ -116,6 +144,7 @@ const makeRecursiveFieldStructImplem = ({
|
|
|
116
144
|
erc20SignaturesBlob,
|
|
117
145
|
shouldUseV1Filters,
|
|
118
146
|
coinRefsTokensMap,
|
|
147
|
+
isDiscarded: false,
|
|
119
148
|
});
|
|
120
149
|
}
|
|
121
150
|
|
|
@@ -282,15 +311,23 @@ async function sendFilteringInfo(
|
|
|
282
311
|
): Promise<Buffer>;
|
|
283
312
|
async function sendFilteringInfo(
|
|
284
313
|
transport: Transport,
|
|
285
|
-
type: "
|
|
314
|
+
type: "discardField",
|
|
286
315
|
loadConfig: LoadConfig,
|
|
287
|
-
data
|
|
316
|
+
data: FilteringInfoDiscardField,
|
|
317
|
+
): Promise<Buffer>;
|
|
318
|
+
async function sendFilteringInfo(
|
|
319
|
+
transport: Transport,
|
|
320
|
+
type: "activate" | "contractName" | "showField" | "discardField",
|
|
321
|
+
loadConfig: LoadConfig,
|
|
322
|
+
data?: FilteringInfoContractName | FilteringInfoShowField | FilteringInfoDiscardField,
|
|
288
323
|
): Promise<Buffer | void> {
|
|
289
324
|
enum APDU_FIELDS {
|
|
290
325
|
CLA = 0xe0,
|
|
291
326
|
INS = 0x1e,
|
|
292
|
-
|
|
327
|
+
P1_standard = 0x00,
|
|
328
|
+
P1_discarded = 0x01,
|
|
293
329
|
P2_activate = 0x00,
|
|
330
|
+
P2_discarded = 0x01,
|
|
294
331
|
P2_show_field = 0xff, // for v1 of filters
|
|
295
332
|
P2_message_info = 0x0f,
|
|
296
333
|
P2_datetime = 0xfc,
|
|
@@ -304,7 +341,7 @@ async function sendFilteringInfo(
|
|
|
304
341
|
return transport.send(
|
|
305
342
|
APDU_FIELDS.CLA,
|
|
306
343
|
APDU_FIELDS.INS,
|
|
307
|
-
APDU_FIELDS.
|
|
344
|
+
APDU_FIELDS.P1_discarded,
|
|
308
345
|
APDU_FIELDS.P2_activate,
|
|
309
346
|
);
|
|
310
347
|
|
|
@@ -317,7 +354,7 @@ async function sendFilteringInfo(
|
|
|
317
354
|
return transport.send(
|
|
318
355
|
APDU_FIELDS.CLA,
|
|
319
356
|
APDU_FIELDS.INS,
|
|
320
|
-
APDU_FIELDS.
|
|
357
|
+
APDU_FIELDS.P1_standard,
|
|
321
358
|
APDU_FIELDS.P2_message_info,
|
|
322
359
|
payload,
|
|
323
360
|
);
|
|
@@ -333,6 +370,7 @@ async function sendFilteringInfo(
|
|
|
333
370
|
coinRefsTokensMap,
|
|
334
371
|
shouldUseV1Filters,
|
|
335
372
|
erc20SignaturesBlob,
|
|
373
|
+
isDiscarded,
|
|
336
374
|
} = data as FilteringInfoShowField;
|
|
337
375
|
const { displayNameBuffer, sigBuffer } = getFilterDisplayNameAndSigBuffers(displayName, sig);
|
|
338
376
|
|
|
@@ -341,7 +379,7 @@ async function sendFilteringInfo(
|
|
|
341
379
|
return transport.send(
|
|
342
380
|
APDU_FIELDS.CLA,
|
|
343
381
|
APDU_FIELDS.INS,
|
|
344
|
-
APDU_FIELDS.
|
|
382
|
+
APDU_FIELDS.P1_standard,
|
|
345
383
|
APDU_FIELDS.P2_show_field,
|
|
346
384
|
payload,
|
|
347
385
|
);
|
|
@@ -408,11 +446,26 @@ async function sendFilteringInfo(
|
|
|
408
446
|
return transport.send(
|
|
409
447
|
APDU_FIELDS.CLA,
|
|
410
448
|
APDU_FIELDS.INS,
|
|
411
|
-
APDU_FIELDS.
|
|
449
|
+
isDiscarded ? APDU_FIELDS.P1_discarded : APDU_FIELDS.P1_standard,
|
|
412
450
|
P2FormatMap[format],
|
|
413
451
|
payload,
|
|
414
452
|
);
|
|
415
453
|
}
|
|
454
|
+
|
|
455
|
+
case "discardField": {
|
|
456
|
+
const { path } = data as FilteringInfoDiscardField;
|
|
457
|
+
const pathBuffer = Buffer.from(path);
|
|
458
|
+
const pathLengthBuffer = Buffer.from(intAsHexBytes(pathBuffer.length, 1), "hex");
|
|
459
|
+
|
|
460
|
+
const payload = Buffer.concat([pathLengthBuffer, pathBuffer]);
|
|
461
|
+
return transport.send(
|
|
462
|
+
APDU_FIELDS.CLA,
|
|
463
|
+
APDU_FIELDS.INS,
|
|
464
|
+
APDU_FIELDS.P1_standard,
|
|
465
|
+
APDU_FIELDS.P2_discarded,
|
|
466
|
+
payload,
|
|
467
|
+
);
|
|
468
|
+
}
|
|
416
469
|
}
|
|
417
470
|
}
|
|
418
471
|
|
|
@@ -474,6 +527,7 @@ export const signEIP712Message = async (
|
|
|
474
527
|
|
|
475
528
|
const { version } = await getAppAndVersion(transport);
|
|
476
529
|
const shouldUseV1Filters = !semver.gte(version, "1.11.1-0", { includePrerelease: true });
|
|
530
|
+
const shouldUseDiscardedFields = semver.gte(version, "1.12.0-0", { includePrerelease: true });
|
|
477
531
|
const filters = await getFiltersForMessage(typedMessage, shouldUseV1Filters, calServiceURL);
|
|
478
532
|
const coinRefsTokensMap = getCoinRefTokensMap(filters, shouldUseV1Filters, typedMessage);
|
|
479
533
|
|
|
@@ -514,6 +568,7 @@ export const signEIP712Message = async (
|
|
|
514
568
|
types,
|
|
515
569
|
filters,
|
|
516
570
|
shouldUseV1Filters,
|
|
571
|
+
shouldUseDiscardedFields,
|
|
517
572
|
coinRefsTokensMap,
|
|
518
573
|
});
|
|
519
574
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import axios from "axios";
|
|
2
2
|
import { log } from "@ledgerhq/logs";
|
|
3
|
-
import { signatures as signaturesByChainId } from "@ledgerhq/cryptoassets/data/evm/index";
|
|
3
|
+
import { signatures as signaturesByChainId } from "@ledgerhq/cryptoassets-evm-signatures/data/evm/index";
|
|
4
4
|
import { getLoadConfig } from "./loadConfig";
|
|
5
5
|
import { LoadConfig } from "../types";
|
|
6
6
|
|