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

Feat/ada integration v2 #86

Merged
merged 8 commits into from
Jun 28, 2024
2 changes: 2 additions & 0 deletions libs/ur-parse-lib/src/keystone_ur_decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ mod tests {
use crate::keystone_ur_decoder::{probe_decode, MultiURParseResult, URParseResult};
use alloc::string::ToString;
use ur_registry::crypto_psbt::CryptoPSBT;
use ur_registry::cardano::cardano_sign_data_request::CardanoSignDataRequest;

use ur_registry::ethereum::eth_sign_request::EthSignRequest;

#[test]
Expand Down
107 changes: 107 additions & 0 deletions libs/ur-registry/src/cardano/cardano_sign_data_request.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
use crate::cbor::cbor_map;
use crate::crypto_key_path::CryptoKeyPath;
use crate::error::{URError, URResult};
use crate::registry_types::{RegistryType, CRYPTO_KEYPATH, CARDANO_SIGN_DATA_REQUEST, UUID};
use crate::traits::{From as FromCbor, RegistryItem, To, MapSize};
use crate::types::Bytes;
use alloc::format;
use crate::impl_template_struct;
use alloc::string::{String, ToString};
use alloc::vec::Vec;
use minicbor::data::{Int, Tag};
use minicbor::encode::Write;
use minicbor::{Decoder, Encoder};

const REQUEST_ID: u8 = 1;
const SIGN_DATA: u8 = 2;
const DERIVATION_PATH: u8 = 3;
const ORIGIN: u8 = 4;

impl_template_struct!(CardanoSignDataRequest {request_id: Option<Bytes>, sign_data: Bytes, derivation_path: CryptoKeyPath, origin: Option<String>});

impl MapSize for CardanoSignDataRequest {
fn map_size(&self) -> u64 {
let mut size = 2;
if self.request_id.is_some() {
size += 1;
}
if self.origin.is_some() {
size += 1;
}
size
}
}

impl RegistryItem for CardanoSignDataRequest {
fn get_registry_type() -> RegistryType<'static> {
CARDANO_SIGN_DATA_REQUEST
}
}

impl<C> minicbor::Encode<C> for CardanoSignDataRequest {
fn encode<W: Write>(
&self,
e: &mut Encoder<W>,
_ctx: &mut C,
) -> Result<(), minicbor::encode::Error<W::Error>> {
e.map(self.map_size())?;
if let Some(request_id) = &self.request_id {
e.int(Int::from(REQUEST_ID))?
.tag(Tag::Unassigned(UUID.get_tag()))?
.bytes(request_id)?;
}

e.int(Int::from(SIGN_DATA))?.bytes(&self.sign_data)?;

e.int(Int::from(DERIVATION_PATH))?;
e.tag(Tag::Unassigned(CRYPTO_KEYPATH.get_tag()))?;
CryptoKeyPath::encode(&self.derivation_path, e, _ctx)?;

if let Some(origin) = &self.origin {
e.int(Int::from(ORIGIN))?.str(origin)?;
}

Ok(())
}
}

impl<'b, C> minicbor::Decode<'b, C> for CardanoSignDataRequest {
fn decode(d: &mut Decoder<'b>, _ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
let mut result: CardanoSignDataRequest = CardanoSignDataRequest::default();
cbor_map(d, &mut result, |key, obj, d: &mut Decoder| {
let key =
u8::try_from(key).map_err(|e| minicbor::decode::Error::message(e.to_string()))?;
match key {
REQUEST_ID => {
d.tag()?;
obj.set_request_id(Some(d.bytes()?.to_vec()));
}
SIGN_DATA => {
obj.set_sign_data(d.bytes()?.to_vec());
}
DERIVATION_PATH => {
d.tag()?;
obj.derivation_path = CryptoKeyPath::decode(d, _ctx)?;
}
ORIGIN => {
obj.origin = Some(d.str()?.to_string());
}
_ => {}
}
Ok(())
})?;
Ok(result)
}
}

impl To for CardanoSignDataRequest {
fn to_bytes(&self) -> URResult<Vec<u8>> {
minicbor::to_vec(self.clone()).map_err(|e| URError::CborEncodeError(e.to_string()))
}
}

impl FromCbor<CardanoSignDataRequest> for CardanoSignDataRequest {
fn from_cbor(bytes: Vec<u8>) -> URResult<CardanoSignDataRequest> {
minicbor::decode(&bytes).map_err(|e| URError::CborDecodeError(e.to_string()))
}
}
78 changes: 78 additions & 0 deletions libs/ur-registry/src/cardano/cardano_sign_data_signature.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
use crate::cbor::cbor_map;
use crate::impl_template_struct;
use crate::registry_types::{CARDANO_SIGN_DATA_SIGNATURE, RegistryType, UUID};
use crate::traits::{MapSize, RegistryItem};
use crate::types::Bytes;
use alloc::string::ToString;
use minicbor::data::{Int, Tag};
use minicbor::encode::{Error, Write};
use minicbor::{Decoder, Encoder};

const REQUEST_ID: u8 = 1;
const SIGNATURE: u8 = 2;
const PUBLIC_KEY: u8 = 3;

impl_template_struct!(CardanoSignDataSignature {
request_id: Option<Bytes>,
signature: Bytes,
public_key: Bytes
});

impl RegistryItem for CardanoSignDataSignature {
fn get_registry_type() -> RegistryType<'static> {
CARDANO_SIGN_DATA_SIGNATURE
}
}

impl MapSize for CardanoSignDataSignature {
fn map_size(&self) -> u64 {
let mut size = 2;
if self.request_id.is_some() {
size += 1;
}
size
}
}

impl<C> minicbor::Encode<C> for CardanoSignDataSignature {
fn encode<W: Write>(&self, e: &mut Encoder<W>, _ctx: &mut C) -> Result<(), Error<W::Error>> {
e.map(self.map_size())?;

if let Some(id) = &self.request_id {
e.int(Int::from(REQUEST_ID))?
.tag(Tag::Unassigned(UUID.get_tag()))?
.bytes(id)?;
}

e.int(Int::from(SIGNATURE))?.bytes(&self.signature)?;

e.int(Int::from(PUBLIC_KEY))?.bytes(&self.public_key)?;

Ok(())
}
}

impl<'b, C> minicbor::Decode<'b, C> for CardanoSignDataSignature {
fn decode(d: &mut Decoder<'b>, _ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
let mut cardano_sign_data_signature = CardanoSignDataSignature::default();
cbor_map(d, &mut cardano_sign_data_signature, |key, obj, d| {
let key =
u8::try_from(key).map_err(|e| minicbor::decode::Error::message(e.to_string()))?;
match key {
REQUEST_ID => {
d.tag()?;
obj.set_request_id(Some(d.bytes()?.to_vec()));
}
SIGNATURE => {
obj.set_signature(d.bytes()?.to_vec());
}
PUBLIC_KEY => {
obj.set_public_key(d.bytes()?.to_vec());
}
_ => {}
}
Ok(())
})?;
Ok(cardano_sign_data_signature)
}
}
86 changes: 86 additions & 0 deletions libs/ur-registry/src/cardano/cardano_sign_structure.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
use crate::cbor::cbor_array;
use crate::crypto_key_path::CryptoKeyPath;
use crate::error::{URError, URResult};
use crate::registry_types::{CARDANO_CERT_KEY, CRYPTO_KEYPATH, RegistryType};
use crate::traits::{From as FromCbor, MapSize, RegistryItem, To};
use crate::types::Bytes;

use alloc::string::{String, ToString};
use alloc::vec::Vec;
use prost::Message;
use core::convert::From;
use minicbor::data::{Int, Tag};
use minicbor::encode::{Error, Write};
use minicbor::{Decoder, Encoder};

const KEY_CONTEXT: u8 = 0;
const KEY_PROTECTED_HEADER: u8 = 1;
const KEY_EXTERNAL_AAD: u8 = 2;
const KEY_PAYLOAD: u8 = 3;

use crate::impl_template_struct;

impl_template_struct!(CardanoSignStructure {
context: Bytes,
protected_header: Bytes,
external_aad: Bytes,
payload: String
});

impl MapSize for CardanoSignStructure {
fn map_size(&self) -> u64 {
4
}
}

impl<'b, C> minicbor::Decode<'b, C> for CardanoSignStructure {
fn decode(d: &mut Decoder<'b>, _ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
let mut cardano_sign_structure = CardanoSignStructure::default();
cbor_array(d, &mut cardano_sign_structure, |_index, obj, d| {
let _index =
u8::try_from(_index).map_err(|e| minicbor::decode::Error::message(e.to_string()))?;

match _index {
KEY_CONTEXT => {
obj.context = d.str()?.to_string().encode_to_vec()
}
KEY_PROTECTED_HEADER => {
obj.protected_header = d.bytes()?.to_vec()
}
KEY_EXTERNAL_AAD => {
obj.external_aad = d.bytes()?.to_vec()
}
KEY_PAYLOAD => {
obj.payload = hex::encode(d.bytes()?);
}
_ => {
d.skip()?;
}
}
Ok(())
})?;
Ok(cardano_sign_structure)
}
}

impl FromCbor<CardanoSignStructure> for CardanoSignStructure {
fn from_cbor(bytes: Vec<u8>) -> URResult<CardanoSignStructure> {
minicbor::decode(&bytes).map_err(|e| URError::CborDecodeError(e.to_string()))
}
}

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

#[test]
fn test_decode_sign_structure() {
let sign_structure_str = "846a5369676e617475726531582aa201276761646472657373581de133a4f1f468454744b2ff3644b2ab79d48e76a3187f902fe8a1bcfaad4058857b22707572706f7365223a224b6f696f73204163636f756e7420566572696669636174696f6e222c226163636f756e74223a2265313333613466316634363834353437343462326666333634346232616237396434386537366133313837663930326665386131626366616164222c226e6f6e6365223a313731393533383936383333347d";
let sign_structure_bytes = hex::decode(sign_structure_str).unwrap();

let sign_structure = CardanoSignStructure::from_cbor(sign_structure_bytes).unwrap();
let payload = hex::decode(sign_structure.payload).unwrap();
let payload = String::from_utf8(payload).unwrap();
assert_eq!(payload, "{\"purpose\":\"Koios Account Verification\",\"account\":\"e133a4f1f468454744b2ff3644b2ab79d48e76a3187f902fe8a1bcfaad\",\"nonce\":1719538968334}");
}
}
3 changes: 3 additions & 0 deletions libs/ur-registry/src/cardano/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
pub mod cardano_cert_key;
pub mod cardano_sign_request;
pub mod cardano_sign_data_request;
pub mod cardano_signature;
pub mod cardano_sign_data_signature;
pub mod cardano_utxo;
pub mod cardano_sign_structure;
4 changes: 4 additions & 0 deletions libs/ur-registry/src/macros_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ use crate::bytes::Bytes;
use crate::cardano::{
cardano_cert_key::CardanoCertKey, cardano_sign_request::CardanoSignRequest,
cardano_signature::CardanoSignature, cardano_utxo::CardanoUTXO,
cardano_sign_data_request::CardanoSignDataRequest,
cardano_sign_data_signature::CardanoSignDataSignature,
};
use crate::cosmos::{cosmos_sign_request::CosmosSignRequest, cosmos_signature::CosmosSignature};
use crate::cosmos::{evm_sign_request::EvmSignRequest, evm_signature::EvmSignature};
Expand Down Expand Up @@ -50,6 +52,8 @@ impl_cbor_bytes!(
CardanoSignature,
CardanoUTXO,
CardanoSignRequest,
CardanoSignDataRequest,
CardanoSignDataSignature,
CardanoCertKey,
AptosSignRequest,
AptosSignature,
Expand Down
5 changes: 5 additions & 0 deletions libs/ur-registry/src/registry_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub enum URType {
ArweaveSignRequest(String),
AptosSignRequest(String),
CardanoSignRequest(String),
CardanoSignDataRequest(String),
CosmosSignRequest(String),
EvmSignRequest(String),
SuiSignRequest(String),
Expand Down Expand Up @@ -42,6 +43,7 @@ impl URType {
"aptos-sign-request" => Ok(URType::AptosSignRequest(type_str.to_string())),
"sui-sign-request" => Ok(URType::SuiSignRequest(type_str.to_string())),
"cardano-sign-request" => Ok(URType::CardanoSignRequest(type_str.to_string())),
"cardano-sign-data-request" => Ok(URType::CardanoSignDataRequest(type_str.to_string())),
"qr-hardware-call" => Ok(URType::QRHardwareCall(type_str.to_string())),
"ton-sign-request" => Ok(URType::TonSignRequest(type_str.to_string())),
_ => Err(URError::NotSupportURTypeError(type_str.to_string())),
Expand All @@ -63,6 +65,7 @@ impl URType {
URType::ArweaveSignRequest(type_str) => type_str.to_string(),
URType::AptosSignRequest(type_str) => type_str.to_string(),
URType::CardanoSignRequest(type_str) => type_str.to_string(),
URType::CardanoSignDataRequest(type_str) => type_str.to_string(),
URType::SuiSignRequest(type_str) => type_str.to_string(),
URType::CosmosSignRequest(type_str) => type_str.to_string(),
URType::EvmSignRequest(type_str) => type_str.to_string(),
Expand Down Expand Up @@ -135,6 +138,8 @@ pub const CARDANO_UTXO: RegistryType = RegistryType("cardano-utxo", Some(2201));
pub const CARDANO_SIGN_REQUEST: RegistryType = RegistryType("cardano-sign-request", Some(2202));
pub const CARDANO_SIGNATURE: RegistryType = RegistryType("cardano-signature", Some(2203));
pub const CARDANO_CERT_KEY: RegistryType = RegistryType("cardano-cert-key", Some(2204));
pub const CARDANO_SIGN_DATA_REQUEST: RegistryType = RegistryType("cardano-sign-data-request", Some(2205));
pub const CARDANO_SIGN_DATA_SIGNATURE: RegistryType = RegistryType("cardano-sign-data-signature", Some(2206));
// Sui
pub const SUI_SIGN_REQUEST: RegistryType = RegistryType("sui-sign-request", Some(7101));
pub const SUI_SIGNATURE: RegistryType = RegistryType("sui-signature", Some(7102));
Expand Down
Loading