Skip to content

Commit 9d7c607

Browse files
fix: use decodeAuthorizationSignature util from transaction-controller (#29717)
## **Description** Replace local EIP-7702 authorization signature decoding with the `decodeAuthorizationSignature` util from `@metamask/transaction-controller` (added in [core#8656](MetaMask/core#8656)). The util produces RLP-canonical hex (no leading zero nibbles, `0x0` for zero), which the Sentinel relay and public RPCs require. The local copies under-canonicalised: `delegation.ts` did nothing, `delegation-7702-publish.ts` only stripped a single leading zero. ## **Changelog** CHANGELOG entry: Fixed an issue where EIP-7702 authorization signatures with leading zero bytes in `r` or `s` could be rejected by relays and public RPCs. ## **Related issues** Fixes: [CONF-1133](https://consensyssoftware.atlassian.net/browse/CONF-1133) <!-- ## **Manual testing steps** ## **Screenshots/Recordings** ### **Before** ### **After** --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. [CONF-1133]: https://consensyssoftware.atlassian.net/browse/CONF-1133?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Touches EIP-7702 authorization encoding used for relay/RPC submission; small change but in a transaction-critical path and could affect signature validity if the upstream util behavior differs. > > **Overview** > Replaces two local EIP-7702 authorization signature parsing implementations with `decodeAuthorizationSignature` from `@metamask/transaction-controller`. > > This removes custom `r`/`s`/`yParity` slicing/normalization (and related helpers/imports) so authorization lists use the shared, canonical decoding expected by relays and public RPCs. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 8202337. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent 1c7df7f commit 9d7c607

2 files changed

Lines changed: 6 additions & 31 deletions

File tree

app/util/transactions/delegation.ts

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {
22
AuthorizationList,
33
TransactionMeta,
4+
decodeAuthorizationSignature,
45
} from '@metamask/transaction-controller';
56
import {
67
BATCH_DEFAULT_MODE,
@@ -19,7 +20,7 @@ import {
1920
createDelegation,
2021
encodeRedeemDelegations,
2122
} from '../../core/Delegation/delegation';
22-
import { Hex, add0x, createProjectLogger } from '@metamask/utils';
23+
import { Hex, createProjectLogger } from '@metamask/utils';
2324
import { limitedCalls } from '../../core/Delegation/caveatBuilder/limitedCallsBuilder';
2425
import { Messenger } from '@metamask/messenger';
2526
import { DelegationControllerSignDelegationAction } from '@metamask/delegation-controller';
@@ -271,16 +272,3 @@ function buildCaveats(
271272

272273
return caveatBuilder.build();
273274
}
274-
275-
function decodeAuthorizationSignature(signature: Hex) {
276-
const r = signature.slice(0, 66) as Hex;
277-
const s = add0x(signature.slice(66, 130));
278-
const v = parseInt(signature.slice(130, 132), 16);
279-
const yParity = toHex(v - 27 === 0 ? 0 : 1);
280-
281-
return {
282-
r,
283-
s,
284-
yParity,
285-
};
286-
}

app/util/transactions/hooks/delegation-7702-publish.ts

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ import {
88
PublishHook,
99
PublishHookResult,
1010
TransactionMeta,
11+
decodeAuthorizationSignature,
1112
} from '@metamask/transaction-controller';
12-
import { Hex, add0x, createProjectLogger } from '@metamask/utils';
13+
import { Hex, createProjectLogger } from '@metamask/utils';
1314
import {
1415
ANY_BENEFICIARY,
1516
BATCH_DEFAULT_MODE,
@@ -38,8 +39,7 @@ import {
3839
waitForRelayResult,
3940
} from '../transaction-relay';
4041
import { NetworkClientId } from '@metamask/network-controller';
41-
import { toHex } from '@metamask/controller-utils';
42-
import { isE2ETest, stripSingleLeadingZero } from '../util';
42+
import { isE2ETest } from '../util';
4343
import {
4444
getClientForTransactionMetadata,
4545
sanitizeOrigin,
@@ -433,7 +433,7 @@ export class Delegation7702PublishHook {
433433
},
434434
)) as Hex;
435435

436-
const { r, s, yParity } = this.#decodeAuthorizationSignature(
436+
const { r, s, yParity } = decodeAuthorizationSignature(
437437
authorizationSignature,
438438
);
439439

@@ -458,19 +458,6 @@ export class Delegation7702PublishHook {
458458
]) as Hex;
459459
}
460460

461-
#decodeAuthorizationSignature(signature: Hex) {
462-
const r = stripSingleLeadingZero(signature.slice(0, 66)) as Hex;
463-
const s = stripSingleLeadingZero(add0x(signature.slice(66, 130))) as Hex;
464-
const v = parseInt(signature.slice(130, 132), 16);
465-
const yParity = toHex(v - 27 === 0 ? 0 : 1);
466-
467-
return {
468-
r,
469-
s,
470-
yParity,
471-
};
472-
}
473-
474461
#normalizeCallData(data: unknown): Hex {
475462
if (typeof data !== 'string' || data.length === 0) {
476463
return EMPTY_HEX;

0 commit comments

Comments
 (0)