Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
a4dff84
Separate Wallet from Signer.
deuszx May 26, 2025
33f835d
Move InMemorySigner to signer::in_memory module
deuszx May 26, 2025
5e23d7e
Init version of EmbeddedSigner
deuszx May 27, 2025
1cb9f0c
contains_key uses js_sys::Promise
deuszx May 27, 2025
036c84d
Use EmbeddedSigner in Client
deuszx May 27, 2025
48f8224
Remove InMemorySigner
deuszx May 28, 2025
02ac58f
Move JsSigner type API into extern block
deuszx May 28, 2025
9c4d680
Export InMemoryWallet to JS as Wallet
deuszx May 28, 2025
aa5544f
Export IJsSigner interface from Rust
deuszx May 29, 2025
230f8f3
More JS Types
deuszx May 29, 2025
e1d8ddf
Do not use custom type when integrating with JS - makes things more d…
deuszx May 29, 2025
35c0ce1
Move the EmbeddedSigner into linera-protocol repo
deuszx May 30, 2025
84724fa
Chainlistner::run needs to be spawned
deuszx May 30, 2025
07f1c3b
EvmSignature::new works with CryptoHash
deuszx Jun 2, 2025
dd65c7f
Log serialiation error details for Wasm bytecode
deuszx Jun 2, 2025
a6b1f81
Make signing with EmbeddedSigner work.
deuszx Jun 2, 2025
e9b6455
pnpm workspace
deuszx Jun 2, 2025
83d28c6
Fix typo
deuszx Jun 3, 2025
24e8368
Add MetaMask signer - broken
deuszx Jun 3, 2025
543246f
Fix CI
deuszx Jun 3, 2025
dceacae
Cleanup
deuszx Jun 3, 2025
b249416
Add comments to types accessible from JS/TS
deuszx Jun 3, 2025
16ab4fa
Install and run prettier formatter
deuszx Jun 3, 2025
b15b611
Address most review comments.
deuszx Jun 4, 2025
afbb71e
Remove MetaMask implementation
deuszx Jun 4, 2025
8cca7b0
Extract Signer typescript interface to a file.
deuszx Jun 4, 2025
f716fa8
Rename back to PersistentWallet
deuszx Jun 4, 2025
e007e41
Add JS name remap to Rust's Wasm interface
deuszx Jun 6, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@
# Helm
kubernetes/linera-validator/working/*
node_modules
**/dist/
2 changes: 1 addition & 1 deletion linera-base/src/crypto/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ impl AccountSecretKey {
AccountSignature::Secp256k1(signature)
}
AccountSecretKey::EvmSecp256k1(secret) => {
let signature = secp256k1::evm::EvmSignature::new(value, secret);
let signature = secp256k1::evm::EvmSignature::new(CryptoHash::new(value), secret);
AccountSignature::EvmSecp256k1(signature)
}
}
Expand Down
53 changes: 37 additions & 16 deletions linera-base/src/crypto/secp256k1/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,12 @@ pub struct EvmKeyPair {
#[derive(Eq, PartialEq, Copy, Clone)]
pub struct EvmSignature(pub(crate) Signature);

#[cfg(with_testing)]
impl FromStr for EvmSignature {
type Err = CryptoError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
let bytes = hex::decode(s)?;
// If the string starts with "0x", we remove it before decoding.
let bytes = hex::decode(s.strip_prefix("0x").unwrap_or(s))?;
let sig = Signature::from_erc2098(&bytes);
Ok(EvmSignature(sig))
}
Expand Down Expand Up @@ -195,7 +195,9 @@ impl FromStr for EvmPublicKey {
type Err = CryptoError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
hex::decode(s)?.as_slice().try_into()
hex::decode(s.strip_prefix("0x").unwrap_or(s))?
.as_slice()
.try_into()
}
}

Expand Down Expand Up @@ -371,13 +373,9 @@ impl EvmSecretKey {
}

impl EvmSignature {
/// Computes a secp256k1 signature for `value` using the given `secret`.
/// It first serializes the `T` type and then creates the `CryptoHash` from the serialized bytes.
pub fn new<'de, T>(value: &T, secret: &EvmSecretKey) -> Self
where
T: BcsSignable<'de>,
{
Self::sign_prehash(secret, CryptoHash::new(value))
/// Computes a secp256k1 signature for `prehash` using the given `secret`.
pub fn new(prehash: CryptoHash, secret: &EvmSecretKey) -> Self {
Self::sign_prehash(secret, prehash)
}

/// Computes a signature from a prehash.
Expand Down Expand Up @@ -533,13 +531,33 @@ mod serde_utils {

#[cfg(with_testing)]
mod tests {
#[test]
fn eip191_compatibility() {
use std::str::FromStr;

use crate::crypto::{CryptoHash, EvmSecretKey, EvmSignature};

// Generated in MetaMask.
let secret_key = "f77a21701522a03b01c111ad2d2cdaf2b8403b47507ee0aec3c2e52b765d7a66";
let signer = EvmSecretKey::from_str(secret_key).unwrap();

let crypto_hash = CryptoHash::from_str(
"c520e2b24b05e70c39c36d4aa98e9129ac0079ea002d4c382e6996ea11946d1e",
)
.unwrap();

let signature = EvmSignature::new(crypto_hash, &signer);
let js_signature = EvmSignature::from_str("0xe257048813b851f812ba6e508e972d8bb09504824692b027ca95d31301dbe8c7103a2f35ce9950d031d260f412dcba09c24027288872a67abe261c0a3e55c9121b").unwrap();
assert_eq!(signature, js_signature);
}

#[test]
fn test_signatures() {
use serde::{Deserialize, Serialize};

use crate::crypto::{
secp256k1::evm::{EvmKeyPair, EvmSignature},
BcsSignable, TestString,
BcsSignable, CryptoHash, TestString,
};

#[derive(Debug, Serialize, Deserialize)]
Expand All @@ -551,10 +569,11 @@ mod tests {
let keypair2 = EvmKeyPair::generate();

let ts = TestString("hello".into());
let ts_cryptohash = CryptoHash::new(&ts);
let tsx = TestString("hellox".into());
let foo = Foo("hello".into());

let s = EvmSignature::new(&ts, &keypair1.secret_key);
let s = EvmSignature::new(ts_cryptohash, &keypair1.secret_key);
assert!(s.check(&ts, &keypair1.public_key).is_ok());
assert!(s.check(&ts, &keypair2.public_key).is_err());
assert!(s.check(&tsx, &keypair1.public_key).is_err());
Expand Down Expand Up @@ -587,10 +606,11 @@ mod tests {
fn test_signature_serialization() {
use crate::crypto::{
secp256k1::evm::{EvmKeyPair, EvmSignature},
TestString,
CryptoHash, TestString,
};
let keypair = EvmKeyPair::generate();
let sig = EvmSignature::new(&TestString("hello".into()), &keypair.secret_key);
let prehash = CryptoHash::new(&TestString("hello".into()));
let sig = EvmSignature::new(prehash, &keypair.secret_key);
let s = serde_json::to_string(&sig).unwrap();
let sig2: EvmSignature = serde_json::from_str(&s).unwrap();
assert_eq!(sig, sig2);
Expand Down Expand Up @@ -628,10 +648,11 @@ mod tests {
fn human_readable_ser() {
use crate::crypto::{
secp256k1::evm::{EvmKeyPair, EvmSignature},
TestString,
CryptoHash, TestString,
};
let key_pair = EvmKeyPair::generate();
let sig = EvmSignature::new(&TestString("hello".into()), &key_pair.secret_key);
let prehash = CryptoHash::new(&TestString("hello".into()));
let sig = EvmSignature::new(prehash, &key_pair.secret_key);
let s = serde_json::to_string(&sig).unwrap();
let sig2: EvmSignature = serde_json::from_str(&s).unwrap();
assert_eq!(sig, sig2);
Expand Down
4 changes: 2 additions & 2 deletions linera-chain/src/data_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -754,10 +754,10 @@ mod signing {
use std::str::FromStr;

// Generated in MetaMask.
let pk = "f77a21701522a03b01c111ad2d2cdaf2b8403b47507ee0aec3c2e52b765d7a66";
let secret_key = "f77a21701522a03b01c111ad2d2cdaf2b8403b47507ee0aec3c2e52b765d7a66";

let signer: AccountSecretKey = AccountSecretKey::EvmSecp256k1(
linera_base::crypto::EvmSecretKey::from_str(pk).unwrap(),
linera_base::crypto::EvmSecretKey::from_str(secret_key).unwrap(),
);

let proposed_block = ProposedBlock {
Expand Down
2 changes: 1 addition & 1 deletion linera-execution/src/wasm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ pub enum WasmExecutionError {
LoadServiceModule(#[source] anyhow::Error),
#[error("Failed to instrument Wasm module to add fuel metering")]
InstrumentModule,
#[error("Invalid Wasm module")]
#[error("Invalid Wasm module: {0}")]
InvalidBytecode(#[from] wasm_instrument::parity_wasm::SerializationError),
#[cfg(with_wasmer)]
#[error("Failed to instantiate Wasm module: {_0}")]
Expand Down
4 changes: 2 additions & 2 deletions linera-rpc/tests/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// SPDX-License-Identifier: Apache-2.0

use linera_base::{
crypto::{AccountPublicKey, AccountSignature, TestString},
crypto::{AccountPublicKey, AccountSignature, CryptoHash, TestString},
data_types::{BlobContent, ChainDescription, ChainOrigin, OracleResponse, Round},
identifiers::{AccountOwner, BlobType, GenericApplicationId},
ownership::ChainOwnership,
Expand Down Expand Up @@ -47,7 +47,7 @@ fn get_registry() -> Result<Registry> {
let evm_public_key = evm_secret_key.public();
tracer.trace_value(&mut samples, &evm_public_key)?;
let evm_signature = linera_base::crypto::EvmSignature::new(
&TestString::new("signature".to_string()),
CryptoHash::new(&TestString::new("signature".to_string())),
&evm_secret_key,
);
tracer.trace_value(&mut samples, &evm_signature)?;
Expand Down
56 changes: 31 additions & 25 deletions linera-web/package.json
Original file line number Diff line number Diff line change
@@ -1,27 +1,33 @@
{
"name": "@linera/client",
"version": "0.14.0",
"description": "Web client for the Linera blockchain",
"main": "dist/linera_web.js",
"types": "dist/linera_web.d.ts",
"files": [ "dist" ],
"type": "module",
"scripts": {
"install": "true",
"build": "bash build.bash --release",
"prepare": "pnpm build",
"lint": "cargo fmt --check && cargo clippy -- -W clippy::pedantic",
"ci": "pnpm lint"
},
"keywords": [],
"author": "Linera <[email protected]>",
"license": "Apache-2.0",
"repository": {
"type": "git",
"url": "git+https://github.com/linera-io/linera-web.git"
},
"bugs": {
"url": "https://github.com/linera-io/linera-web/issues"
},
"homepage": "https://github.com/linera-io/linera-web#readme"
"name": "@linera/client",
"version": "0.14.0",
"description": "Web client for the Linera blockchain",
"main": "dist/linera_web.js",
"types": "dist/linera_web.d.ts",
"files": [
"dist"
],
"type": "module",
"scripts": {
"install": "true",
"build": "bash build.bash --release",
"prepare": "pnpm build",
"lint": "cargo fmt --check && cargo clippy -- -W clippy::pedantic",
"ci": "pnpm lint",
"format": "pnpm exec prettier . --write"
},
"keywords": [],
"author": "Linera <[email protected]>",
"license": "Apache-2.0",
"repository": {
"type": "git",
"url": "git+https://github.com/linera-io/linera-web.git"
},
"bugs": {
"url": "https://github.com/linera-io/linera-web/issues"
},
"homepage": "https://github.com/linera-io/linera-web#readme",
"devDependencies": {
"prettier": "3.5.3"
}
}
Loading
Loading