Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add stellar integration #84

Merged
merged 3 commits into from
May 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions libs/ur-registry-ffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,7 @@ mod util_internal;
pub mod utils;
pub mod sui;
pub mod ton;
pub mod stellar;


ffi_support::define_string_destructor!(keystone_sdk_destroy_string);
2 changes: 2 additions & 0 deletions libs/ur-registry-ffi/src/stellar/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod stellar_sign_request;
pub mod stellar_signature;
129 changes: 129 additions & 0 deletions libs/ur-registry-ffi/src/stellar/stellar_sign_request.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
use hex;
use serde_json::json;
use ur_registry::crypto_key_path::CryptoKeyPath;
use ur_registry::stellar::stellar_sign_request::{SignType, StellarSignRequest};
use ur_registry::traits::To;
use uuid::Uuid;

use crate::export;
use crate::util_internal::string_helper::remove_prefix_0x;

export! {
@Java_com_keystone_sdk_KeystoneNativeSDK_generateStellarSignRequest
fn generate_stellar_sign_request(
request_id: &str,
sign_data: &str,
path: &str,
xfp: &str,
address: &str,
origin: &str,
sign_type: u32
) -> String {
let xfp_bytes = match hex::decode(xfp) {
Ok(v) => v,
Err(_) => return json!({"error": "xfp is invalid"}).to_string(),
};
let xfp_slice: [u8; 4] = match xfp_bytes.as_slice().try_into() {
Ok(v) => v,
Err(_) => return json!({"error": "length of xfp must be exactly 8"}).to_string(),
};
let derivation_path = match CryptoKeyPath::from_path(path.to_string(), Some(xfp_slice)) {
Ok(v) => v,
Err(_) => return json!({"error": "path is invalid"}).to_string(),
};
let sign_type = match SignType::from_u32(sign_type) {
Ok(v) => v,
Err(_) => return json!({"error": "sign_type is invalid"}).to_string(),
};
let request_id = match Uuid::parse_str(request_id) {
Ok(v) => v,
Err(_) => return json!({"error": "uuid is invalid"}).to_string(),
}.as_bytes().to_vec();
let sign_date_bytes = match hex::decode(remove_prefix_0x(sign_data)) {
Ok(v) => v,
Err(_) => return json!({"error": "sign data is invalid"}).to_string(),
};
let address = if address.len() == 0 { None } else { Some(address.as_bytes().to_vec()) };
let origin = if origin.len() == 0 { None } else { Some(origin.to_string()) };

let result = StellarSignRequest::new(
Some(request_id),
sign_date_bytes,
derivation_path,
address,
origin,
sign_type
);

let cbor = match result.to_bytes() {
Ok(v) => v,
Err(_) => return json!({"error": "cbor serialization failed"}).to_string(),
};
let cbor = hex::encode(cbor);
let ur_type = "stellar-sign-request";
let ur = json!({
"type": ur_type,
"cbor": cbor,
});
ur.to_string()
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_generate_stellar_sign_request() {
let request_id = "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d";
let sign_data = "01000103c8d842a2f17fd7aab608ce2ea535a6e958dffa20caf669b347b911c4171965530f957620b228bae2b94c82ddd4c093983a67365555b737ec7ddc1117e61c72e0000000000000000000000000000000000000000000000000000000000000000010295cc2f1f39f3604718496ea00676d6a72ec66ad09d926e3ece34f565f18d201020200010c0200000000e1f50500000000";
let path = "m/44'/501'/0'/0'";
let xfp = "12121212";
let address = "";
let sign_type = 1;
let origin = "";

let expect_result = "{\"cbor\":\"a401d825509b1deb4d3b7d4bad9bdd2b0d7b3dcb6d02589601000103c8d842a2f17fd7aab608ce2ea535a6e958dffa20caf669b347b911c4171965530f957620b228bae2b94c82ddd4c093983a67365555b737ec7ddc1117e61c72e0000000000000000000000000000000000000000000000000000000000000000010295cc2f1f39f3604718496ea00676d6a72ec66ad09d926e3ece34f565f18d201020200010c0200000000e1f5050000000003d90130a20188182cf51901f5f500f500f5021a121212120601\",\"type\":\"stellar-sign-request\"}";

assert_eq!(
expect_result,
generate_stellar_sign_request(request_id, sign_data, path, xfp, address, origin, sign_type)
);
}

#[test]
fn test_generate_stellar_sign_request_path_error() {
let request_id = "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d";
let sign_data = "01000103c8d842a2f17fd7aab608ce2ea535a6e958dffa20caf669b347b911c4171965530f957620b228bae2b94c82ddd4c093983a67365555b737ec7ddc1117e61c72e0000000000000000000000000000000000000000000000000000000000000000010295cc2f1f39f3604718496ea00676d6a72ec66ad09d926e3ece34f565f18d201020200010c0200000000e1f50500000000";
let path = "";
let xfp = "1212120";
let address = "";
let sign_type = 1;
let origin = "keystone";

let err_result_derivation_path = "{\"error\":\"xfp is invalid\"}";

assert_eq!(
err_result_derivation_path,
generate_stellar_sign_request(request_id, sign_data, path, xfp, address, origin, sign_type)
);
}

#[test]
fn test_generate_stellar_sign_request_err_sign_data() {
let request_id = "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d";
let sign_data = "0123h";
let path = "m/44'/501'/0'/0'";
let xfp = "12121212";
let address = "";
let sign_type = 1;
let origin = "keystone";

let err_result = "{\"error\":\"sign data is invalid\"}";

assert_eq!(
err_result,
generate_stellar_sign_request(request_id, sign_data, path, xfp, address, origin, sign_type)
);
}
}
74 changes: 74 additions & 0 deletions libs/ur-registry-ffi/src/stellar/stellar_signature.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
use anyhow::format_err;
use anyhow::Error;
use hex;
use serde_json::json;
use ur_registry::registry_types::STELLAR_SIGNATURE;
use ur_registry::stellar::stellar_signature::StellarSignature;
use ur_registry::traits::From;
use uuid::Uuid;

use crate::export;

export! {
@Java_com_keystone_sdk_KeystoneNativeSDK_parseStellarSignature
fn parse_stellar_signature(ur_type: &str, cbor_hex: &str) -> String {
if STELLAR_SIGNATURE.get_type() != ur_type {
return json!({"error": "type not match"}).to_string();
}

let parse_signature = || -> Result<(String, String), Error> {
let cbor = hex::decode(cbor_hex.to_string())?;
let stellar_signature = StellarSignature::from_cbor(cbor).map_err(|_| format_err!(""))?;
let uuid = stellar_signature.get_request_id().ok_or(format_err!(""))?;
let uuid_hex = hex::encode(uuid);
let request_id = Uuid::parse_str(&uuid_hex)?.to_string();
let signature = hex::encode(stellar_signature.get_signature());
Ok((request_id, signature))
};
match parse_signature() {
Ok((request_id, signature)) => json!({
"request_id": request_id,
"signature": signature,
}).to_string(),
Err(_) => json!({"error": "signature is invalid"}).to_string(),
}
}
}

#[cfg(test)]
mod tests {

use super::*;
#[test]
fn test_parse_stellar_signature() {
let stellar_signature_cbor = "a201d825509b1deb4d3b7d4bad9bdd2b0d7b3dcb6d025840d4f0a7bcd95bba1fbb1051885054730e3f47064288575aacc102fbbf6a9a14daa066991e360d3e3406c20c00a40973eff37c7d641e5b351ec4a99bfe86f335f7";
let expect_result = "{\"request_id\":\"9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d\",\"signature\":\"d4f0a7bcd95bba1fbb1051885054730e3f47064288575aacc102fbbf6a9a14daa066991e360d3e3406c20c00a40973eff37c7d641e5b351ec4a99bfe86f335f7\"}";

assert_eq!(
expect_result,
parse_stellar_signature("stellar-signature", stellar_signature_cbor)
);
}

#[test]
fn test_parse_stellar_signature_type_error() {
let stellar_signature_cbor = "a301d825509b1deb4d3b7d4bad9bdd2b0d7b3dcb6d025841d4f0a7bcd95bba1fbb1051885054730e3f47064288575aacc102fbbf6a9a14daa066991e360d3e3406c20c00a40973eff37c7d641e5b351ec4a99bfe86f335f71303686b657973746f6e65";
let expect_result = "{\"error\":\"type not match\"}";

assert_eq!(
expect_result,
parse_stellar_signature("eth-signature", stellar_signature_cbor)
);
}

#[test]
fn test_parse_stellar_signature_error() {
let stellar_signature_cbor = "a201";
let expect_result = "{\"error\":\"signature is invalid\"}";

assert_eq!(
expect_result,
parse_stellar_signature("stellar-signature", stellar_signature_cbor)
);
}
}
1 change: 1 addition & 0 deletions libs/ur-registry/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ pub mod pb;
pub mod registry_types;
pub mod script_expression;
pub mod solana;
pub mod stellar;
pub mod sui;
pub mod ton;
pub mod traits;
Expand Down
3 changes: 3 additions & 0 deletions libs/ur-registry/src/macros_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ use crate::keystone::{
};
use crate::near::{near_sign_request::NearSignRequest, near_signature::NearSignature};
use crate::solana::{sol_sign_request::SolSignRequest, sol_signature::SolSignature};
use crate::stellar::{stellar_sign_request::StellarSignRequest, stellar_signature::StellarSignature};
use crate::sui::sui_sign_request::SuiSignRequest;
use crate::sui::sui_signature::SuiSignature;
use crate::ton::{ton_signature::TonSignature, ton_sign_request::TonSignRequest};
Expand Down Expand Up @@ -68,6 +69,8 @@ impl_cbor_bytes!(
NearSignature,
SolSignRequest,
SolSignature,
StellarSignRequest,
StellarSignature,
SuiSignRequest,
SuiSignature,
TonSignature,
Expand Down
6 changes: 6 additions & 0 deletions libs/ur-registry/src/registry_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub enum URType {
CryptoAccount(String),
EthSignRequest(String),
SolSignRequest(String),
StellarSignRequest(String),
NearSignRequest(String),
ArweaveSignRequest(String),
AptosSignRequest(String),
Expand All @@ -33,6 +34,7 @@ impl URType {
"keystone-sign-request" => Ok(URType::KeystoneSignRequest(type_str.to_string())),
"eth-sign-request" => Ok(URType::EthSignRequest(type_str.to_string())),
"sol-sign-request" => Ok(URType::SolSignRequest(type_str.to_string())),
"stellar-sign-request" => Ok(URType::StellarSignRequest(type_str.to_string())),
"arweave-sign-request" => Ok(URType::ArweaveSignRequest(type_str.to_string())),
"cosmos-sign-request" => Ok(URType::CosmosSignRequest(type_str.to_string())),
"evm-sign-request" => Ok(URType::EvmSignRequest(type_str.to_string())),
Expand All @@ -56,6 +58,7 @@ impl URType {
URType::KeystoneSignRequest(type_str) => type_str.to_string(),
URType::EthSignRequest(type_str) => type_str.to_string(),
URType::SolSignRequest(type_str) => type_str.to_string(),
URType::StellarSignRequest(type_str) => type_str.to_string(),
URType::NearSignRequest(type_str) => type_str.to_string(),
URType::ArweaveSignRequest(type_str) => type_str.to_string(),
URType::AptosSignRequest(type_str) => type_str.to_string(),
Expand Down Expand Up @@ -141,3 +144,6 @@ pub const TON_SIGNATURE: RegistryType = RegistryType("ton-signature", Some(7202)
// BTC
pub const BTC_SIGN_REQUEST: RegistryType = RegistryType("btc-sign-request", Some(8101));
pub const BTC_SIGNATURE: RegistryType = RegistryType("btc-signature", Some(8102));
// Stellar
pub const STELLAR_SIGN_REQUEST: RegistryType = RegistryType("stellar-sign-request", Some(8201));
pub const STELLAR_SIGNATURE: RegistryType = RegistryType("stellar-signature", Some(8202));
2 changes: 2 additions & 0 deletions libs/ur-registry/src/stellar/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod stellar_sign_request;
pub mod stellar_signature;
Loading
Loading