Skip to content

Commit 02ae58f

Browse files
committed
feat: update to new signatures
for audited contracts there were some small changes
1 parent 5733e21 commit 02ae58f

File tree

9 files changed

+72
-19
lines changed

9 files changed

+72
-19
lines changed

examples/demo-app/components/SessionCreator.vue

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,10 @@
7171

7272
<script setup lang="ts">
7373
import { ref, computed } from "vue";
74-
import { createPublicClient, http, parseEther, type Chain, type Address } from "viem";
74+
import { createPublicClient, http, parseEther, type Address, type Chain } from "viem";
7575
import { createBundlerClient } from "viem/account-abstraction";
76-
import { createSession, toEcdsaSmartAccount, LimitType } from "zksync-sso-4337/client";
76+
import { privateKeyToAccount } from "viem/accounts";
77+
import { createSession, toEcdsaSmartAccount, LimitType, getSessionHash } from "zksync-sso-4337/client";
7778
7879
interface SessionConfig {
7980
enabled: boolean;
@@ -234,18 +235,28 @@ async function createSessionOnChain() {
234235
235236
// eslint-disable-next-line no-console
236237
console.log("Session spec created:", sessionSpec);
238+
239+
// Generate proof
240+
const sessionHash = getSessionHash(sessionSpec);
241+
const sessionSignerAccount = privateKeyToAccount(props.sessionConfig.sessionPrivateKey as `0x${string}`);
242+
const proof = await sessionSignerAccount.sign({
243+
hash: sessionHash,
244+
});
245+
237246
// eslint-disable-next-line no-console
238247
console.log("Calling createSession with:", {
239248
bundlerClient: !!bundlerClient,
240249
sessionSpec: !!sessionSpec,
241250
sessionValidator: props.sessionConfig.validatorAddress,
251+
proof,
242252
});
243253
244254
// Create the session on-chain
245255
let sessionResult;
246256
try {
247257
sessionResult = await createSession(bundlerClient, {
248258
sessionSpec,
259+
proof,
249260
contracts: {
250261
sessionValidator: props.sessionConfig.validatorAddress as Address,
251262
},

packages/sdk-4337/src/abi/SessionKeyValidator.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,10 @@ export const SessionKeyValidatorAbi = [{
129129
}],
130130
}],
131131
}],
132+
}, {
133+
name: "proof",
134+
type: "bytes",
135+
internalType: "bytes",
132136
}],
133137
outputs: [],
134138
stateMutability: "nonpayable",

packages/sdk-4337/src/client/actions/sessions.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ export type CreateSessionParams = {
2323
*/
2424
sessionSpec: SessionSpec;
2525

26+
/**
27+
* Proof of session key ownership (signature of session hash by session key)
28+
*/
29+
proof: Hex;
30+
2631
/**
2732
* Contract addresses
2833
*/
@@ -82,6 +87,7 @@ export type CreateSessionReturnType = {
8287
* ],
8388
* transferPolicies: [],
8489
* },
90+
* proof: "0x...", // Signature of session hash by session key
8591
* contracts: {
8692
* sessionValidator: "0x...", // SessionKeyValidator module address
8793
* },
@@ -96,15 +102,15 @@ export async function createSession<
96102
client: Client<TTransport, TChain, TAccount>,
97103
params: CreateSessionParams,
98104
): Promise<CreateSessionReturnType> {
99-
const { sessionSpec, contracts } = params;
105+
const { sessionSpec, proof, contracts } = params;
100106

101107
if (!client.account) {
102108
throw new Error("Client must have an account");
103109
}
104110

105111
// Convert SessionSpec into JSON string expected by wasm helper
106112
const sessionSpecJSON = sessionSpecToJSON(sessionSpec);
107-
const callData = encode_create_session_call_data(sessionSpecJSON) as Hex;
113+
const callData = encode_create_session_call_data(sessionSpecJSON, proof) as Hex;
108114
// Send the UserOperation to create the session using the bundler client method.
109115
// Note: We explicitly pass the account for broader viem compatibility.
110116
const bundler = client as unknown as {

packages/sdk-4337/src/client/passkey/client-actions.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export type PasskeyClientActions<TChain extends Chain = Chain, TAccount extends
5050
/**
5151
* Create a session on-chain using the provided specification
5252
*/
53-
createSession: (params: { sessionSpec: SessionSpec; contracts: { sessionValidator: Address } }) => Promise<Hash>;
53+
createSession: (params: { sessionSpec: SessionSpec; proof: Hex; contracts: { sessionValidator: Address } }) => Promise<Hash>;
5454
};
5555

5656
/**
@@ -93,11 +93,11 @@ export function passkeyClientActions<
9393
},
9494

9595
// Create a session on-chain using the provided specification
96-
createSession: async (params: { sessionSpec: SessionSpec; contracts: { sessionValidator: Address } }) => {
96+
createSession: async (params: { sessionSpec: SessionSpec; proof: Hex; contracts: { sessionValidator: Address } }) => {
9797
// Build smart account instance (lazy, not cached here; acceptable overhead for now)
9898
const smartAccount = await toPasskeySmartAccount(config.passkeyAccount);
9999
const sessionSpecJSON = sessionSpecToJSON(params.sessionSpec);
100-
const callData = encode_create_session_call_data(sessionSpecJSON) as unknown as `0x${string}`;
100+
const callData = encode_create_session_call_data(sessionSpecJSON, params.proof) as unknown as `0x${string}`;
101101
const userOpHash = await config.bundler.sendUserOperation({
102102
account: smartAccount,
103103
calls: [

packages/sdk-4337/src/client/session/utils.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import type { Address, Hex } from "viem";
1+
import { type Address, encodeAbiParameters, type Hex, keccak256 } from "viem";
22

3+
import { SessionKeyValidatorAbi } from "../../abi/SessionKeyValidator.js";
34
import type { SessionSpec, UsageLimit } from "./types.js";
45

56
/**
@@ -130,3 +131,23 @@ export function isSessionExpired(
130131
export function getSessionExpiryDate(spec: SessionSpec): Date {
131132
return new Date(Number(spec.expiresAt) * 1000);
132133
}
134+
135+
/**
136+
* Computes the hash of a session specification.
137+
* This hash is signed by the session key to prove ownership.
138+
*/
139+
export function getSessionHash(spec: SessionSpec): Hex {
140+
const createSessionFunction = SessionKeyValidatorAbi.find(
141+
(x) => x.type === "function" && x.name === "createSession",
142+
);
143+
if (!createSessionFunction) throw new Error("createSession function not found in ABI");
144+
145+
const sessionSpecParam = createSessionFunction.inputs.find((x) => x.name === "sessionSpec");
146+
if (!sessionSpecParam) throw new Error("sessionSpec param not found in createSession ABI");
147+
148+
const encoded = encodeAbiParameters(
149+
[sessionSpecParam],
150+
[spec as any],
151+
);
152+
return keccak256(encoded);
153+
}

packages/sdk-platforms/rust/zksync-sso-erc4337/crates/zksync-sso-erc4337-core/src/erc4337/account/modular_smart_account/guardian/recovery/finalize.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
use crate::erc4337::account::modular_smart_account::guardian::contract::GuardianExecutor;
22
use alloy::{
3-
primitives::Address, providers::Provider, rpc::types::TransactionReceipt,
3+
primitives::{Address, Bytes}, providers::Provider, rpc::types::TransactionReceipt,
44
};
55

66
#[derive(Clone)]
77
pub struct FinalizeRecoveryParams<P: Provider + Send + Sync + Clone> {
88
pub guardian_executor: Address,
99
pub account: Address,
10+
pub data: Bytes,
1011
pub guardian_provider: P,
1112
}
1213

@@ -19,14 +20,15 @@ where
1920
let FinalizeRecoveryParams {
2021
guardian_executor,
2122
account,
23+
data,
2224
guardian_provider,
2325
} = params;
2426

2527
let guardian_executor_instance =
2628
GuardianExecutor::new(guardian_executor, guardian_provider);
2729

2830
let receipt = guardian_executor_instance
29-
.finalizeRecovery(account)
31+
.finalizeRecovery(account, data)
3032
.send()
3133
.await?
3234
.get_receipt()
@@ -197,14 +199,14 @@ mod tests {
197199
address!("0x14dC79964da2C08b23698B3D3cc7Ca32193d9955");
198200

199201
// Initialize recovery directly
202+
let initialize_recovery_data: Bytes =
203+
new_owner_address.abi_encode().into();
200204
{
201-
let initialize_recovery_data =
202-
new_owner_address.abi_encode().into();
203205
initialize_recovery(InitializeRecoveryParams {
204206
guardian_executor: guardian_module,
205207
account: account_address,
206208
recovery_type: RecoveryType::EOA,
207-
data: initialize_recovery_data,
209+
data: initialize_recovery_data.clone(),
208210
guardian_provider: guardian_provider.clone(),
209211
})
210212
.await?;
@@ -223,6 +225,7 @@ mod tests {
223225
finalize_recovery(FinalizeRecoveryParams {
224226
guardian_executor: guardian_module,
225227
account: account_address,
228+
data: initialize_recovery_data,
226229
guardian_provider: guardian_provider.clone(),
227230
})
228231
.await?;

packages/sdk-platforms/rust/zksync-sso-erc4337/crates/zksync-sso-erc4337-core/src/erc4337/account/modular_smart_account/session/create.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use alloy::{
2323
pub struct CreateSessionParams<P: Provider + Send + Sync + Clone> {
2424
pub account_address: Address,
2525
pub spec: SessionSpec,
26+
pub proof: Bytes,
2627
pub entry_point_address: Address,
2728
pub session_key_validator: Address,
2829
pub paymaster: Option<PaymasterParams>,
@@ -40,6 +41,7 @@ where
4041
let CreateSessionParams {
4142
account_address,
4243
spec,
44+
proof,
4345
entry_point_address,
4446
session_key_validator,
4547
paymaster,
@@ -48,7 +50,7 @@ where
4850
signer,
4951
} = params;
5052

51-
let call_data = add_session_call_data(spec, session_key_validator);
53+
let call_data = add_session_call_data(spec, proof, session_key_validator);
5254

5355
send_user_op(SendUserOpParams {
5456
account: account_address,
@@ -66,17 +68,18 @@ where
6668
Ok(())
6769
}
6870

69-
pub fn create_session_call_data(spec: SessionSpec) -> Bytes {
70-
SessionKeyValidator::createSessionCall { sessionSpec: spec.into() }
71+
pub fn create_session_call_data(spec: SessionSpec, proof: Bytes) -> Bytes {
72+
SessionKeyValidator::createSessionCall { sessionSpec: spec.into(), proof }
7173
.abi_encode()
7274
.into()
7375
}
7476

7577
fn add_session_call_data(
7678
spec: SessionSpec,
79+
proof: Bytes,
7780
session_key_validator: Address,
7881
) -> Bytes {
79-
let calldata = create_session_call_data(spec);
82+
let calldata = create_session_call_data(spec, proof);
8083
encoded_call_with_target_and_data(session_key_validator, calldata)
8184
}
8285

packages/sdk-platforms/rust/zksync-sso-erc4337/crates/zksync-sso-erc4337-ffi-web/src/lib.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1685,15 +1685,20 @@ pub fn generate_session_stub_signature_wasm(
16851685
#[wasm_bindgen]
16861686
pub fn encode_create_session_call_data(
16871687
session_spec_json: String,
1688+
proof: String,
16881689
) -> Result<String, JsValue> {
16891690
// Parse SessionSpec from JSON
16901691
let spec: SessionSpec =
16911692
serde_json::from_str(&session_spec_json).map_err(|e| {
16921693
JsValue::from_str(&format!("Invalid SessionSpec JSON: {}", e))
16931694
})?;
16941695

1696+
let proof_bytes = hex::decode(proof.trim_start_matches("0x")).map_err(|e| {
1697+
JsValue::from_str(&format!("Invalid proof hex: {}", e))
1698+
})?;
1699+
16951700
// Build createSession call and ABI encode
1696-
let create_session_calldata = create_session_call_data_core(spec);
1701+
let create_session_calldata = create_session_call_data_core(spec, proof_bytes.into());
16971702

16981703
Ok(format!("0x{}", hex::encode(create_session_calldata)))
16991704
}

0 commit comments

Comments
 (0)