Skip to content

Commit 49fd761

Browse files
committed
πŸ› (signer-eth): Fix duplicate proxy info send in EIP-712 flow
Skip the clearSignContext proxy when it was already provided via additionalContexts (which uses a fresh challenge). When no proxy exists in additionalContexts, the clearSignContext proxy is still sent as before. Made-with: Cursor
1 parent 4113eff commit 49fd761

3 files changed

Lines changed: 67 additions & 3 deletions

File tree

β€Ž.changeset/long-flies-try.mdβ€Ž

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@ledgerhq/device-signer-kit-ethereum": patch
3+
---
4+
5+
Fix duplicate PROXY_INFO send in EIP-712 typed data signing that caused a challenge mismatch error on the device

β€Žpackages/signer/signer-eth/src/internal/app-binder/task/ProvideEIP712ContextTask.test.tsβ€Ž

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1088,7 +1088,7 @@ describe("ProvideEIP712ContextTask", () => {
10881088
);
10891089
});
10901090

1091-
it("Provide proxy", async () => {
1091+
it("Provide proxy from clearSignContext when not in additionalContexts", async () => {
10921092
// GIVEN
10931093
const proxy: ClearSignContextSuccess<ClearSignContextType.PROXY_INFO> = {
10941094
type: ClearSignContextType.PROXY_INFO,
@@ -1131,6 +1131,61 @@ describe("ProvideEIP712ContextTask", () => {
11311131
);
11321132
});
11331133

1134+
it("Skip duplicate proxy from clearSignContext when already in additionalContexts", async () => {
1135+
// GIVEN
1136+
const proxy: ClearSignContextSuccess<ClearSignContextType.PROXY_INFO> = {
1137+
type: ClearSignContextType.PROXY_INFO,
1138+
payload: "0x010203",
1139+
};
1140+
const additionalProxy: ClearSignContextSuccess<ClearSignContextType.PROXY_INFO> =
1141+
{
1142+
type: ClearSignContextType.PROXY_INFO,
1143+
payload: "0xaabbcc",
1144+
};
1145+
const clearSignContext: TypedDataClearSignContextSuccess = {
1146+
...TEST_CLEAR_SIGN_CONTEXT,
1147+
proxy,
1148+
};
1149+
const args: ProvideEIP712ContextTaskArgs = {
1150+
deviceModelId: DeviceModelId.STAX,
1151+
derivationPath: "44'/60'/0'/0/0",
1152+
types: TEST_TYPES,
1153+
domain: TEST_DOMAIN_VALUES,
1154+
message: TEST_MESSAGE_VALUES,
1155+
clearSignContext: Just(clearSignContext),
1156+
calldatasPreContexts: {},
1157+
calldatasPostContexts: {},
1158+
additionalContexts: [additionalProxy],
1159+
loggerFactory: mockLoggerFactory,
1160+
};
1161+
1162+
// WHEN
1163+
apiMock.sendCommand.mockResolvedValue(
1164+
CommandResultFactory({ data: { tokenIndex: 4 } }),
1165+
);
1166+
await new ProvideEIP712ContextTask(
1167+
apiMock,
1168+
contextModuleMock,
1169+
args,
1170+
provideContextFactoryMock,
1171+
).run();
1172+
1173+
// THEN β€” the clearSignContext proxy (0x010203) should NOT be sent
1174+
expect(apiMock.sendCommand).not.toHaveBeenCalledWith(
1175+
new ProvideProxyInfoCommand({
1176+
data: hexaStringToBuffer("0x0003010203")!,
1177+
isFirstChunk: true,
1178+
}),
1179+
);
1180+
// β€” the additionalContexts proxy (0xaabbcc) should have been sent
1181+
expect(apiMock.sendCommand).toHaveBeenCalledWith(
1182+
new ProvideProxyInfoCommand({
1183+
data: hexaStringToBuffer("0x0003aabbcc")!,
1184+
isFirstChunk: true,
1185+
}),
1186+
);
1187+
});
1188+
11341189
it("Send certificate from clearSignContext", async () => {
11351190
// GIVEN
11361191
const certificatePayload = new Uint8Array([0x01, 0x02, 0x03, 0x04, 0x05]);

β€Žpackages/signer/signer-eth/src/internal/app-binder/task/ProvideEIP712ContextTask.tsβ€Ž

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,11 +137,15 @@ export class ProvideEIP712ContextTask {
137137
await this.provideContext(context);
138138
}
139139

140-
// Send proxy descriptor first if required
140+
// Send proxy descriptor from clear sign context only if not already
141+
// provided via additionalContexts (which uses a fresh challenge).
142+
const alreadyProvidedProxy = this.args.additionalContexts.some(
143+
(c) => c.type === ClearSignContextType.PROXY_INFO,
144+
);
141145
const proxyContext:
142146
| ClearSignContextSuccess<ClearSignContextType.PROXY_INFO>
143147
| undefined = this.args.clearSignContext.extract()?.proxy;
144-
if (proxyContext !== undefined) {
148+
if (proxyContext !== undefined && !alreadyProvidedProxy) {
145149
await this.provideContext(proxyContext);
146150
}
147151

0 commit comments

Comments
Β (0)