Skip to content

Commit

Permalink
support starknet wallets for sdk
Browse files Browse the repository at this point in the history
  • Loading branch information
nick-zkp committed Dec 14, 2023
1 parent 82898da commit 1886441
Show file tree
Hide file tree
Showing 11 changed files with 101 additions and 76 deletions.
7 changes: 3 additions & 4 deletions bindings/wasm/src/json_rpc_signer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,19 @@ pub struct JsonRpcSigner {
//#[wasm_bindgen(constructor)]
#[wasm_bindgen(js_name=newRpcSignerWtihProvider)]
pub fn new_with_provider(provider: Provider) -> Result<JsonRpcSigner, JsValue> {
let inner = InterfaceJsonRpcSigner::new(JsonRpcProvider::Provider(provider))?;
let inner = InterfaceJsonRpcSigner::new(JsonRpcProvider::Provider(provider),None)?;
Ok(JsonRpcSigner { inner })
}

//#[wasm_bindgen(constructor)]
#[wasm_bindgen(js_name=newRpcSignerWithSigner)]
pub fn new_with_signer(signer: Signer) -> Result<JsonRpcSigner, JsValue> {
let inner = InterfaceJsonRpcSigner::new(JsonRpcProvider::Signer(signer))?;
pub fn new_with_signer(signer: Signer, pub_key: String) -> Result<JsonRpcSigner, JsValue> {
let inner = InterfaceJsonRpcSigner::new(JsonRpcProvider::Signer(signer),Some(pub_key))?;
Ok(JsonRpcSigner { inner })
}

#[wasm_bindgen]
impl JsonRpcSigner {

#[wasm_bindgen(js_name = initZklinkSigner)]
pub async fn init_zklink_signer(&mut self, signature: Option<String>) -> Result<(), JsValue> {
Ok(self.inner.init_zklink_signer(signature).await?)
Expand Down
4 changes: 2 additions & 2 deletions bindings/wasm/src/rpc_type_converter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use wasm_bindgen::prelude::wasm_bindgen;
use wasm_bindgen::JsValue;
use zklink_sdk_provider::response::AccountQuery as RpcAccountQuery;
use zklink_sdk_signers::eth_signer::{EIP1271Signature, PackedEthSignature};
use zklink_sdk_signers::starknet_signer::{StarkECDSASignature, StarkSignature};
use zklink_sdk_signers::starknet_signer::StarkECDSASignature;
use zklink_sdk_signers::zklink_signer::PackedSignature;
use zklink_sdk_types::basic_types::AccountId;
use zklink_sdk_types::prelude::ZkLinkSignature;
Expand Down Expand Up @@ -125,7 +125,7 @@ impl TryFrom<TxLayer1Signature> for TypesTxLayer1Signature {
)))
}
L1SignatureType::Stark => {
let signature = StarkSignature::from_hex(&signature.signature)
let signature = StarkECDSASignature::from_hex(&signature.signature)
.map_err(|e| JsValue::from_str(&format!("error: {e}")))?;

Ok(TypesTxLayer1Signature::StarkSignature(signature))
Expand Down
14 changes: 6 additions & 8 deletions interface/src/json_rpc_signer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use zklink_sdk_signers::starknet_signer::starknet_json_rpc_signer::{
StarknetJsonRpcSigner,Signer as StarknetAccountSigner
};

use zklink_sdk_signers::zklink_signer::{ZkLinkSignature, ZkLinkSigner, ZkSignerError};
use zklink_sdk_signers::zklink_signer::{ZkLinkSignature, ZkLinkSigner};
use zklink_sdk_types::prelude::PackedEthSignature;
use zklink_sdk_types::signatures::TxSignature;
use zklink_sdk_types::tx_type::change_pubkey::{ChangePubKey, ChangePubKeyAuthData, Create2Data};
Expand All @@ -22,9 +22,7 @@ use zklink_sdk_types::tx_type::transfer::Transfer;
use zklink_sdk_types::tx_type::withdraw::Withdraw;
use zklink_sdk_types::tx_type::zklink_tx::ZkLinkTx;
use zklink_sdk_types::tx_type::ZkSignatureTrait;
use zklink_sdk_signers::eth_signer::EthSignerError;
use zklink_sdk_signers::starknet_signer::StarkSignature;
use zklink_sdk_signers::starknet_signer::typed_data::message::{TypedDataMessage, Message};
use zklink_sdk_signers::starknet_signer::StarkECDSASignature;
use zklink_sdk_signers::starknet_signer::error::StarkSignerError;

pub enum JsonRpcProvider {
Expand All @@ -42,12 +40,12 @@ pub struct JsonRpcSigner {
}

impl JsonRpcSigner {
pub fn new(provider: JsonRpcProvider) -> Result<Self, SignError> {
pub fn new(provider: JsonRpcProvider,pub_key: Option<String>) -> Result<Self, SignError> {
let eth_json_rpc_signer = match provider {
JsonRpcProvider::Provider(provider) =>
Layer1JsonRpcSigner::EthSigner(EthJsonRpcSigner::new(provider)),
JsonRpcProvider::Signer(signer) =>
Layer1JsonRpcSigner::StarknetSigner(StarknetJsonRpcSigner::new(signer))
Layer1JsonRpcSigner::StarknetSigner(StarknetJsonRpcSigner::new(signer,pub_key.unwrap()))
};
let default_zklink_signer = ZkLinkSigner::new()?;
Ok(Self {
Expand All @@ -65,8 +63,8 @@ impl JsonRpcSigner {
ZkLinkSigner::new_from_seed(&seed)?
},
Layer1JsonRpcSigner::StarknetSigner(_) => {
let signature = StarkSignature::from_hex(&s)?;
let seed = signature.to_bytes_be();
let signature = StarkECDSASignature::from_hex(&s)?;
let seed = signature.signature.to_bytes_be();
ZkLinkSigner::new_from_seed(&seed)?
}
}
Expand Down
1 change: 1 addition & 0 deletions interface/src/sign_transfer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use zklink_sdk_signers::zklink_signer::pk_signer::ZkLinkSigner;
use zklink_sdk_types::basic_types::GetBytes;
use zklink_sdk_types::prelude::TxSignature;
use zklink_sdk_types::tx_type::transfer::Transfer;
#[cfg(feature = "web")]
use zklink_sdk_signers::starknet_signer::typed_data::message::TypedDataMessage;

#[cfg(not(feature = "web"))]
Expand Down
3 changes: 1 addition & 2 deletions interface/src/sign_withdraw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@ use zklink_sdk_types::prelude::TxSignature;
use zklink_sdk_types::tx_type::withdraw::Withdraw;
use zklink_sdk_types::tx_type::ZkSignatureTrait;
#[cfg(feature = "web")]
use crate::json_rpc_signer::Layer1JsonRpcSigner;
#[cfg(feature = "web")]
use zklink_sdk_signers::starknet_signer::starknet_json_rpc_signer::StarknetJsonRpcSigner;
#[cfg(feature = "web")]
use zklink_sdk_signers::starknet_signer::typed_data::message::TypedDataMessage;

#[cfg(not(feature = "web"))]
Expand Down
11 changes: 3 additions & 8 deletions signers/src/starknet_signer/ecdsa_signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ use starknet_signers::VerifyingKey;
use std::fmt;
use std::fmt::Formatter;
use zklink_sdk_utils::serde::ZeroPrefixHexSerde;
use num::BigUint;
use std::str::FromStr;

#[derive(Clone, PartialEq,Serialize, Deserialize,Eq,Debug)]
Expand Down Expand Up @@ -40,17 +39,13 @@ impl StarkSignature {
}

pub fn from_str(r:&str,s: &str) -> Result<Self, StarkSignerError> {
let r = BigUint::from_str(r)
let r = FieldElement::from_str(r)
.map_err(|e| StarkSignerError::InvalidSignature(e.to_string()))?;
let s = BigUint::from_str(s)
let s = FieldElement::from_str(s)
.map_err(|e| StarkSignerError::InvalidSignature(e.to_string()))?;
let mut bytes = [0;64];
bytes[0..32].clone_from_slice(&s.to_bytes_be());
bytes[32..].clone_from_slice(&r.to_bytes_be());
Self::from_bytes_be(&bytes)
Ok(Self { s,r })
}


pub fn from_bytes_be(bytes: &[u8]) -> Result<Self, StarkSignerError> {
let mut s = [0_u8; 32];
let mut r = [0_u8; 32];
Expand Down
104 changes: 63 additions & 41 deletions signers/src/starknet_signer/pk_signer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use starknet::core::crypto::compute_hash_on_elements;
use starknet::core::types::FieldElement;
use starknet_signers::SigningKey;

pub struct StarkSigner(SigningKey);
pub struct StarkSigner(pub SigningKey);

impl Default for StarkSigner {
fn default() -> Self {
Expand All @@ -32,23 +32,20 @@ impl StarkSigner {

/// 1. get the hash of the message
/// 2. sign hash
pub fn sign_message(&self, msg: &[u8]) -> Result<StarkSignature, Error> {
pub fn sign_message(&self, msg: &[u8]) -> Result<StarkECDSASignature, Error> {
let hash = Self::get_msg_hash(msg);
let signature = self
.0
.sign(&hash)
.map_err(|e| Error::sign_error(e.to_string()))?;
// let s = StarkECDSASignature {
// pub_key: self.public_key(),
// signature: StarkSignature {
// s: signature.s,
// r: signature.r,
// },
// };
Ok(StarkSignature {
s: signature.s,
r: signature.r,
})
let s = StarkECDSASignature {
pub_key: self.public_key(),
signature: StarkSignature {
s: signature.s,
r: signature.r,
},
};
Ok(s)
}

/// 1. change msg to FieldElement list
Expand All @@ -68,6 +65,9 @@ mod tests {
use serde::{Deserialize, Serialize};
use crate::starknet_signer::typed_data::TypedData;
use crate::starknet_signer::typed_data::message::{TypedDataMessage, Message};
use starknet_signers::VerifyingKey;
use num::BigUint;
use std::str::FromStr;

#[derive(Serialize, Deserialize, Debug)]
struct TestSignature {
Expand All @@ -78,34 +78,56 @@ mod tests {
fn test_starknet_sign() {
let private_key = "0x02c5dbad71c92a45cc4b40573ae661f8147869a91d57b8d9b8f48c8af7f83159";
let stark_signer = StarkSigner::new_from_hex_str(private_key).unwrap();
let msg = b"hello world";
let signature = stark_signer.sign_message(msg).unwrap();
let is_ok = signature.verify(msg).unwrap();
assert!(is_ok);
let data = TestSignature { signature };
let s = serde_json::to_string(&data).unwrap();
println!("{s}");
let data2: TestSignature = serde_json::from_str(&s).unwrap();
println!("{data2:?}");
let msg_hash = "0x51d5faacb1bdeb6293d52fd4be0a7c62417cb73962cdd6aff385b67239cf081";
let signature = stark_signer.0.sign(&FieldElement::from_hex_be(msg_hash).unwrap()).unwrap();
//let pub_key = stark_signer.public_key();
let pub_key = "0x3b478eae5afdd35358abcc7955bba7acda3d16f4485b62f2497f78ed6bc7126";
let verifying_key = VerifyingKey::from_scalar(FieldElement::from_hex_be(pub_key).unwrap());
let is_ok = verifying_key
.verify(
&FieldElement::from_hex_be(msg_hash).unwrap(),
&signature
)
.unwrap();
println!("{:?}",is_ok);

}

// #[test]
// fn test_signature_verify() {
// let r = "1242659239673499744454485192657408749892787349417938392478090301874476933289";
// let s = "3203688086163592132535350422117785905751559823323905824858605377390311728388";
// let pubkey = "0x4893e2057aabcfc20bfa81a09efdcf39807698f9748123c51145fc81aeadab1";
// let msg = TypedDataMessage::CreateL2Key(Message {
// data: "Create zkLink L2".to_string()
// });
// let typed_data = TypedData::new(msg);
//
// let signature = StarkECDSASignature {
// pub_key: FieldElement::from_hex_be(&pubkey).unwrap(),
// signature: StarkSignature {
// s: FieldElement::from_hex_be(&s).unwrap(),
// r: FieldElement::from_hex_be(&r).unwrap()
// } };
// let is_ok = signature.verify(msg).unwrap();
// assert!(is_ok);
// }
#[test]
fn test_signature_verify() {
let r_str = "1242659239673499744454485192657408749892787349417938392478090301874476933289";
let s_str = "3203688086163592132535350422117785905751559823323905824858605377390311728388";
let pubkey = "1082125475812817975721104073212648033952831721853656627074253194227094744819";
let msg_hash = "0x51d5faacb1bdeb6293d52fd4be0a7c62417cb73962cdd6aff385b67239cf081";
// let msg = TypedDataMessage::CreateL2Key(Message {
// data: "Create zkLink L2".to_string()
// });
// let typed_data = TypedData::new(msg);
//
let mut s = [0;32];
let mut r = [0;32];
let r_num = BigUint::from_str(r_str).unwrap();
let s_num = BigUint::from_str(s_str).unwrap();
s.clone_from_slice(&s_num.to_bytes_be());
r.clone_from_slice(&r_num.to_bytes_be());
let pub_key = FieldElement::from_str(&pubkey).unwrap();
// let signature = StarkECDSASignature {
// pub_key: FieldElement::from_hex_be(&pubkey).unwrap(),
// signature: StarkSignature {
// s: FieldElement::from_bytes_be(BigUint::from_str(s).unwrap().to_bytes_be()).unwrap(),
// r: FieldElement::from_bytes_be(BigUint::from_str(r).unwrap().to_bytes_be()).unwrap()
// } };

let verifying_key = VerifyingKey::from_scalar(pub_key);
let is_ok = verifying_key
.verify(
&FieldElement::from_hex_be(msg_hash).unwrap(),
&Signature {
s: FieldElement::from_str(&s_str).unwrap(),
r: FieldElement::from_str(&r_str).unwrap()
},
)
.unwrap();
assert!(is_ok);
}
}
21 changes: 16 additions & 5 deletions signers/src/starknet_signer/starknet_json_rpc_signer.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use wasm_bindgen::prelude::*;
use crate::starknet_signer::StarkSignature;
use crate::starknet_signer::{StarkSignature, StarkECDSASignature};
use crate::starknet_signer::error::StarkSignerError;
use crate::starknet_signer::typed_data::{message::TypedDataMessage, TypedData};
use starknet::core::types::FieldElement;
use std::str::FromStr;

#[wasm_bindgen]
// Rustfmt removes the 'async' keyword from async functions in extern blocks. It's fixed
Expand All @@ -17,17 +19,18 @@ extern "C" {

pub struct StarknetJsonRpcSigner {
signer: Signer,
pub_key: String,
}

impl StarknetJsonRpcSigner {
pub fn new(signer: Signer) -> StarknetJsonRpcSigner{
StarknetJsonRpcSigner { signer }
pub fn new(signer: Signer,pub_key: String) -> StarknetJsonRpcSigner{
StarknetJsonRpcSigner { signer,pub_key }
}

pub async fn sign_message(
&self,
message: TypedDataMessage,
) -> Result<StarkSignature, StarkSignerError> {
) -> Result<StarkECDSASignature, StarkSignerError> {
let typed_data = TypedData::new(message);
let typed_data = serde_wasm_bindgen::to_value(&typed_data)
.map_err(|e| StarkSignerError::SignError(e.to_string()))?;
Expand All @@ -38,7 +41,15 @@ impl StarknetJsonRpcSigner {
})?;
let signature: Vec<String> = serde_wasm_bindgen::from_value::<Vec<String>>(signature)
.map_err(|e| StarkSignerError::InvalidSignature(e.to_string()))?;
StarkSignature::from_str(&signature[0],&signature[1])

let signature = StarkSignature::from_str(&signature[0],&signature[1])
.map_err(|e| StarkSignerError::InvalidSignature(e.to_string()))?;
let pub_key = FieldElement::from_str(&self.pub_key)
.map_err(|e| StarkSignerError::SignError(e.to_string()))?;
Ok(StarkECDSASignature {
pub_key,
signature,
})
}
}

Expand Down
2 changes: 1 addition & 1 deletion signers/src/starknet_signer/typed_data/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ impl TypedData {
let domain = StarknetDomain {
name: "zklink".to_string(),
version: "1".to_string(),
chain_id: "SN_MAIN".to_string()
chain_id: "SN_GOERLI".to_string()
};
Self {
types,
Expand Down
3 changes: 2 additions & 1 deletion signers/src/zklink_signer/pk_signer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ pub fn sha256_bytes(input: &[u8]) -> Vec<u8> {
impl ZkLinkSigner {
const SIGN_MESSAGE: &'static str =
"Sign this message to create a key to interact with zkLink's layer2 services.\nNOTE: This application is powered by zkLink protocol.\n\nOnly sign this message for a trusted client!";
#[cfg(feature = "web")]
const STARKNET_SIGN_MESSAGE: &'static str =
"Create zkLink's layer2 key.\n";
pub fn new() -> Result<Self, Error> {
Expand Down Expand Up @@ -134,7 +135,7 @@ impl ZkLinkSigner {
let signature = starknet_signer
.sign_message(message)
.await?;
let seed = signature.to_bytes_be();
let seed = signature.signature.to_bytes_be();
Self::new_from_seed(&seed)
}

Expand Down
7 changes: 3 additions & 4 deletions types/src/signatures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use serde::{Deserialize, Serialize};
use zklink_sdk_signers::eth_signer::eip1271_signature::EIP1271Signature;
use zklink_sdk_signers::eth_signer::packed_eth_signature::PackedEthSignature;
use zklink_sdk_signers::starknet_signer::ecdsa_signature::StarkECDSASignature;
use zklink_sdk_signers::starknet_signer::StarkSignature;

/// Representation of the signature secured by L1.
/// May be either a signature generated via Ethereum private key
Expand All @@ -14,7 +13,7 @@ use zklink_sdk_signers::starknet_signer::StarkSignature;
pub enum TxLayer1Signature {
EthereumSignature(PackedEthSignature),
EIP1271Signature(EIP1271Signature),
StarkSignature(StarkSignature),
StarkSignature(StarkECDSASignature),
}

#[derive(Debug, Clone, Serialize, Deserialize)]
Expand All @@ -35,8 +34,8 @@ impl From<EIP1271Signature> for TxLayer1Signature {
}
}

impl From<StarkSignature> for TxLayer1Signature {
fn from(value: StarkSignature) -> Self {
impl From<StarkECDSASignature> for TxLayer1Signature {
fn from(value: StarkECDSASignature) -> Self {
Self::StarkSignature(value)
}
}
Expand Down

0 comments on commit 1886441

Please sign in to comment.