Skip to content

Implement session call digest for v3 sessions#362

Open
Agusx1211 wants to merge 1 commit into
masterfrom
v3-session-call-digest
Open

Implement session call digest for v3 sessions#362
Agusx1211 wants to merge 1 commit into
masterfrom
v3-session-call-digest

Conversation

@Agusx1211

@Agusx1211 Agusx1211 commented Jul 10, 2026

Copy link
Copy Markdown
Member

This implements the digest that a session key has to sign for each call of a v3 payload, needed for waas smart-sessions (7193). The old hashCallWithReplayProtection was a leftover stub, unexported and with no callers, so I replaced it with an exported HashCallWithReplayProtection that matches SessionSig.hashPayloadCallIdx in wallet-contracts-v3: keccak256(Payload.hashFor(payload, wallet) ++ uint256(callIdx)).

Note that the digest scheme the stub hinted at (chainId ++ space ++ nonce ++ callHash) is no longer what the contracts verify, it was removed in the audit fix for partial payload replay (0xsequence/wallet-contracts-v3#89), so implementing it as described would produce signatures that never pass on-chain.

The test vectors in session_digest_test.go were generated from SessionSig.hashPayloadCallIdx itself, with a forge test constructing identical payloads, so the test asserts parity with the on-chain verification. I also checked that a signature produced over this digest recovers to the right signer through plain ecrecover, which is the exact path the contract uses (no EIP-191 prefix).

@ScreamingHawk ScreamingHawk left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The old hashCallWithReplayProtection was replaced with hashPayloadCallIdx in the contract as per the PR text. I suggest renaming this function to match the new name too.

Otherwise LGTM!

Comment thread core/v3/session.go
// payload hash is the EIP-712 digest with the wallet as verifying contract.
// The session signature is recovered with plain ecrecover over this digest,
// without an EIP-191 prefix.
func HashCallWithReplayProtection(payload CallsPayload, callIdx int) (common.Hash, error) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename to match HashPayloadCallIdx in contract?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants