summon_client_sdk/
signatures.rsuse cardano_multiplatform_lib::address::Address as Address;
use cardano_message_signing as cms;
use cardano_multiplatform_lib::crypto::PrivateKey as PrivateKey;
use cardano_message_signing::error::JsError;
use cms::utils::ToBytes;
use serde::{Serialize, Deserialize};
use wasm_bindgen::prelude::wasm_bindgen;
#[wasm_bindgen]
#[derive(Serialize, Deserialize)]
pub struct DataSignatureRes {
dt: Option<DataSignature>,
error: String,
}
#[wasm_bindgen]
impl DataSignatureRes {
#[wasm_bindgen(constructor)]
pub fn new(dt: Option<DataSignature>, error_in: Option<String>) -> Self {
Self {
dt,
error: error_in.unwrap_or("".to_string())
}
}
pub fn error(&self) -> String {
self.error.clone()
}
pub fn dt(&self) -> Option<DataSignature> {
self.dt.clone()
}
}
#[wasm_bindgen]
#[derive(Serialize, Deserialize, Clone)]
pub struct DataSignature {
signature: Vec<u8>, key: Vec<u8>, }
#[wasm_bindgen]
impl DataSignature {
#[wasm_bindgen(constructor)]
pub fn new(cose_sig: &[u8], cose_key: &[u8]) -> Self {
Self {
key: cose_key.to_vec(),
signature: cose_sig.to_vec()
}
}
pub fn key(&self) -> Vec<u8> {
self.key.clone()
}
pub fn signature(&self) -> Vec<u8> {
self.signature.clone()
}
}
pub fn sign_data_like_cip30(key: PrivateKey, address_bech32: &str, message: &str) -> Result<DataSignature, JsError> {
let public_key = key.to_public();
let mut protected_headers = cms::HeaderMap::new();
protected_headers.set_algorithm_id(&cms::Label::from_algorithm_id(
cms::builders::AlgorithmId::EdDSA,
));
let maybe_address = Address::from_bech32(address_bech32);
match maybe_address {
Ok(address) => {
let cbor_value_address = cms::cbor::CBORValue::new_bytes(
address
.to_bytes(),
);
protected_headers.set_header(
&cms::Label::new_text("address".to_string()),
&cbor_value_address,
).expect("Failed to set address protected COSESign1 header value");
let protected_serialized = cms::ProtectedHeaderMap::new(&protected_headers);
let unprotected_headers = cms::HeaderMap::new();
let headers = cms::Headers::new(&protected_serialized, &unprotected_headers);
let builder = cms::builders::COSESign1Builder::new(&headers, message.as_bytes().to_vec(), false);
let to_sign = builder.make_data_to_sign().to_bytes();
let signed_sig_struc = key.sign(&to_sign);
let mut key = cms::COSEKey::new(&cms::Label::from_key_type(cms::builders::KeyType::OKP));
key.set_algorithm_id(&cms::Label::from_algorithm_id(
cms::builders::AlgorithmId::EdDSA,
));
key.set_header(
&cms::Label::new_int(&cms::utils::Int::new_negative(
cms::utils::BigNum::from_str("1").unwrap(),
)),
&cms::cbor::CBORValue::new_int(
&cms::utils::Int::new_i32(6), ),
).expect("Failed to set encryption COSESign1 header value"); key.set_header(
&cms::Label::new_int(&cms::utils::Int::new_negative(
cms::utils::BigNum::from_str("2").unwrap(),
)),
&cms::cbor::CBORValue::new_bytes(public_key.as_bytes()),
).expect("Failed to set content type COSESign1 header value"); let cose_sign1 = builder.build(signed_sig_struc.to_bytes());
return Ok(DataSignature::new(
&cose_sign1.to_bytes(),
&key.to_bytes(),
));
},
_ => Err(JsError::from_str("Failed to serialize provided address.")),
}
}