Skip to content

Commit 7a7405c

Browse files
committed
Session key's Secp256k1 blob verification
1 parent 113e2ca commit 7a7405c

File tree

11 files changed

+186
-81
lines changed

11 files changed

+186
-81
lines changed

Cargo.lock

Lines changed: 0 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ members = ["contracts", "contracts/wallet", "server"]
77
# client-sdk = { default-features = false, package = "hyle-client-sdk", version = "0.13.0-rc.4" }
88
# hyle = { version = "0.13.0-rc.4" }
99

10-
sdk = { git = "https://github.com/Hyle-org/hyle.git", package = "hyle-contract-sdk", branch = "main" }
11-
client-sdk = { git = "https://github.com/Hyle-org/hyle.git", default-features = false, package = "hyle-client-sdk", branch = "main" }
12-
hyle-hyllar = { git = "https://github.com/Hyle-org/hyle.git", package = "hyle-hyllar", branch = "main" }
13-
hyle-modules = { git = "https://github.com/Hyle-org/hyle.git", package = "hyle-modules", branch = "main" }
10+
sdk = { path = "../hyle/crates/contract-sdk", package = "hyle-contract-sdk" }
11+
client-sdk = { path = "../hyle/crates/client-sdk", default-features = false, package = "hyle-client-sdk" }
12+
hyle-hyllar = { path = "../hyle/crates/contracts/hyllar", package = "hyle-hyllar" }
13+
hyle-modules = { path = "../hyle/crates/hyle-modules", package = "hyle-modules" }
1414

1515
contracts = { path = "contracts", default-features = false, package = "contracts" }
1616
wallet = { path = "contracts/wallet", package = "wallet" }

contracts/wallet/src/client/indexer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ pub async fn get_account_info(
184184
.session_keys
185185
.iter()
186186
.map(|sk| SessionKey {
187-
key: sk.key.clone(),
187+
key: sk.public_key.clone(),
188188
expiration_date: sk.expiration_date.0,
189189
nonce: sk.nonce,
190190
})

contracts/wallet/src/lib.rs

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::collections::BTreeMap;
33
use borsh::{io::Error, BorshDeserialize, BorshSerialize};
44
#[cfg(feature = "client")]
55
use client_sdk::contract_indexer::utoipa;
6-
use sdk::{hyle_model_utils::TimestampMs, RunResult, TxContext};
6+
use sdk::{hyle_model_utils::TimestampMs, secp256k1::CheckSecp256k1, RunResult, TxContext};
77
use serde::{Deserialize, Serialize};
88

99
#[cfg(feature = "client")]
@@ -19,8 +19,8 @@ impl sdk::ZkContract for Wallet {
1919
nonce,
2020
auth_method,
2121
} => self.handle_registration(account, nonce, auth_method, calldata)?,
22-
WalletAction::UseSessionKey { account, key } => {
23-
self.handle_session_key_usage(account, key, &calldata.tx_ctx)?
22+
WalletAction::UseSessionKey { account, message } => {
23+
self.handle_session_key_usage(account, message, calldata)?
2424
}
2525
_ => self.handle_authenticated_action(action, calldata)?,
2626
};
@@ -58,7 +58,7 @@ pub struct AccountInfo {
5858
derive(client_sdk::contract_indexer::utoipa::ToSchema)
5959
)]
6060
pub struct SessionKey {
61-
pub key: String,
61+
pub public_key: String,
6262
pub expiration_date: TimestampMs,
6363
pub nonce: u128,
6464
}
@@ -111,10 +111,12 @@ impl Wallet {
111111
fn handle_session_key_usage(
112112
&mut self,
113113
account: String,
114-
key: String,
115-
tx_ctx: &Option<TxContext>,
114+
message: String,
115+
calldata: &sdk::Calldata,
116116
) -> Result<String, String> {
117-
self.use_session_key(account, key, tx_ctx)
117+
let secp256k1blob = CheckSecp256k1::new(calldata, message.as_bytes()).expect()?;
118+
let public_key = hex::encode(secp256k1blob.public_key);
119+
self.use_session_key(account, public_key, &calldata.tx_ctx)
118120
}
119121

120122
fn handle_authenticated_action(
@@ -199,12 +201,16 @@ impl Wallet {
199201
.get_mut(&account)
200202
.ok_or("Identity not found")?;
201203

202-
if stored_info.session_keys.iter().any(|sk| sk.key == key) {
204+
if stored_info
205+
.session_keys
206+
.iter()
207+
.any(|sk| sk.public_key == key)
208+
{
203209
return Err("Session key already exists".to_string());
204210
}
205211

206212
stored_info.session_keys.push(SessionKey {
207-
key,
213+
public_key: key,
208214
expiration_date: TimestampMs(expiration_date),
209215
nonce: 0, // Initialize nonce to 0
210216
});
@@ -219,7 +225,7 @@ impl Wallet {
219225
.ok_or("Identity not found")?;
220226

221227
let initial_len = stored_info.session_keys.len();
222-
stored_info.session_keys.retain(|sk| sk.key != key);
228+
stored_info.session_keys.retain(|sk| sk.public_key != key);
223229

224230
if stored_info.session_keys.len() == initial_len {
225231
return Err("Session key not found".to_string());
@@ -232,18 +238,20 @@ impl Wallet {
232238
fn use_session_key(
233239
&mut self,
234240
account: String,
235-
key: String,
241+
public_key: String,
236242
tx_ctx: &Option<TxContext>,
237243
) -> Result<String, String> {
238244
let Some(tx_ctx) = tx_ctx else {
239245
return Err("tx_ctx is missing".to_string());
240246
};
241247
match self.identities.get_mut(&account) {
242248
Some(stored_info) => {
243-
if let Some(session_key) =
244-
stored_info.session_keys.iter_mut().find(|sk| sk.key == key)
249+
if let Some(session_key) = stored_info
250+
.session_keys
251+
.iter_mut()
252+
.find(|sk| sk.public_key == public_key)
245253
{
246-
if session_key.expiration_date < tx_ctx.timestamp {
254+
if session_key.expiration_date > tx_ctx.timestamp {
247255
// Increment nonce during use
248256
session_key.nonce += 1;
249257
return Ok("Session key is valid".to_string());
@@ -299,7 +307,7 @@ pub enum WalletAction {
299307
},
300308
UseSessionKey {
301309
account: String,
302-
key: String,
310+
message: String,
303311
},
304312
}
305313

contracts/wallet/wallet.img

12.9 KB
Binary file not shown.

contracts/wallet/wallet.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2ad4a0521c4491d8999e6b75907cc6fb5712fe3d1a1dce3fdfd95f4ad76630e2
1+
91df241ae1ba7e83d9b2c945cb638e7bd1f55ffe2488017ac9f291d564c9021b

front/src/components/auth/CreateWallet.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ export const CreateWallet = ({ onWalletCreated }: CreateWalletProps) => {
7878

7979
webSocketService.connect(identity);
8080
const unsubscribeWalletEvents = webSocketService.subscribeToWalletEvents((event) => {
81-
console.log('Received wallet event:', event);
8281
if (event.event.startsWith('Successfully registered identity for account')) {
8382
clearTimeout(timeout);
8483
unsubscribeWalletEvents();

front/src/components/auth/LoginWallet.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ export const LoginWallet = ({ onWalletLoggedIn }: LoginWalletProps) => {
6161

6262
webSocketService.connect(identity);
6363
const unsubscribeWalletEvents = webSocketService.subscribeToWalletEvents((event) => {
64-
console.log('Received wallet event:', event);
6564
if (event.event === 'Identity verified') {
6665
clearTimeout(timeout);
6766
unsubscribeWalletEvents();

front/src/components/wallet/SessionKeys.tsx

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,9 @@ export const SessionKeys = ({ wallet }: SessionKeysProps) => {
6363
setStatus('Generating new session key...');
6464
setTransactionHash('');
6565

66+
// Génère une nouvelle paire de clés
67+
const publicKey = sessionKeyService.generateSessionKey();
6668
try {
67-
// Génère une nouvelle paire de clés
68-
const publicKey = sessionKeyService.generateSessionKey();
6969

7070
const identity = `${wallet.username}@${walletContractName}`;
7171
const blob0 = await check_secret_blob(identity, password);
@@ -116,7 +116,7 @@ export const SessionKeys = ({ wallet }: SessionKeysProps) => {
116116
await fetchSessionKeys();
117117
} catch (error) {
118118
setError('Failed to add session key: ' + error);
119-
sessionKeyService.clear(); // Nettoie la clé en cas d'erreur
119+
sessionKeyService.clear(publicKey); // Remove key from local storage if it fails
120120
} finally {
121121
setIsLoading(false);
122122
}
@@ -169,6 +169,51 @@ export const SessionKeys = ({ wallet }: SessionKeysProps) => {
169169
}
170170
};
171171

172+
const handleSendTransactionWithSessionKey = async (key: string) => {
173+
setIsLoading(true);
174+
setError('');
175+
setStatus('Sending transaction...');
176+
setTransactionHash('');
177+
178+
try {
179+
const identity = `${wallet.username}@${walletContractName}`;
180+
const [blob0, blob1] = sessionKeyService.useSessionKey(wallet.username, key, "Hello world!");
181+
182+
const blobTx: BlobTransaction = {
183+
identity,
184+
blobs: [blob0, blob1],
185+
};
186+
187+
const tx_hash = await nodeService.client.sendBlobTx(blobTx);
188+
setTransactionHash(tx_hash);
189+
190+
setStatus('Waiting for transaction confirmation...');
191+
192+
await new Promise((resolve, reject) => {
193+
const timeout = setTimeout(() => {
194+
webSocketService.unsubscribeFromWalletEvents();
195+
reject(new Error('Transaction timed out'));
196+
}, 30000);
197+
198+
webSocketService.connect(wallet.address);
199+
const unsubscribe = webSocketService.subscribeToWalletEvents((event) => {
200+
if (event.event === 'Session key is valid') {
201+
clearTimeout(timeout);
202+
unsubscribe();
203+
webSocketService.disconnect();
204+
resolve(event);
205+
}
206+
});
207+
});
208+
209+
setStatus('Transaction completed successfully');
210+
} catch (error) {
211+
setError('Failed to send transaction: ' + error);
212+
} finally {
213+
setIsLoading(false);
214+
}
215+
};
216+
172217
return (
173218
<div className="session-keys-section">
174219
<h2>Session Keys</h2>
@@ -244,6 +289,13 @@ export const SessionKeys = ({ wallet }: SessionKeysProps) => {
244289
Uses: {key.nonce}
245290
</span>
246291
</div>
292+
<button
293+
onClick={() => handleSendTransactionWithSessionKey(key.key)}
294+
disabled={isLoading}
295+
className="send-transaction-button"
296+
>
297+
Send Transaction
298+
</button>
247299
<button
248300
onClick={() => handleRemoveKey(key.key)}
249301
disabled={isLoading}

0 commit comments

Comments
 (0)