Skip to content

Commit

Permalink
Add a preview builder
Browse files Browse the repository at this point in the history
  • Loading branch information
0xOmarA committed Nov 11, 2024
1 parent 2b797ad commit 221c1ea
Show file tree
Hide file tree
Showing 6 changed files with 361 additions and 1 deletion.
2 changes: 2 additions & 0 deletions crates/radix-engine-toolkit-uniffi/src/builder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@

pub mod manifest_builder;

pub mod preview_transaction_v2_builder;
pub mod transaction_v1_builder;
pub mod transaction_v2_builder;

pub mod partial_transaction_v2_builder;
pub mod signed_partial_transaction_v2_builder;
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

use crate::prelude::*;
use std::ops::Deref;

#[derive(Clone, Debug, Object)]
pub struct PartialTransactionV2Builder {
child_partial_transactions: Vec<PartialTransactionV2>,
root_subintent_header: Option<IntentHeaderV2>,
root_subintent_message: MessageV2,
root_subintent_manifest: Option<TransactionManifestV2>,
}

#[uniffi::export]
impl PartialTransactionV2Builder {
#[uniffi::constructor]
pub fn new() -> Arc<Self> {
Arc::new(Self {
child_partial_transactions: Default::default(),
root_subintent_header: Default::default(),
root_subintent_message: Default::default(),
root_subintent_manifest: Default::default(),
})
}

pub fn add_child(
self: Arc<Self>,
child: Arc<PartialTransactionV2>,
) -> Arc<Self> {
self.with_builder(|builder| {
builder
.child_partial_transactions
.push(child.as_ref().clone())
})
}

pub fn message(self: Arc<Self>, message: MessageV2) -> Arc<Self> {
self.with_builder(|builder| builder.root_subintent_message = message)
}

pub fn intent_header(
self: Arc<Self>,
intent_header: IntentHeaderV2,
) -> Arc<Self> {
self.with_builder(|builder| {
builder.root_subintent_header = Some(intent_header)
})
}

pub fn manifest(
self: Arc<Self>,
manifest: Arc<TransactionManifestV2>,
) -> Arc<Self> {
self.with_builder(|builder| {
builder.root_subintent_manifest = Some(manifest.as_ref().clone())
})
}

pub fn build(self: Arc<Self>) -> Result<Arc<PartialTransactionV2>> {
// Deconstructing the builder.
let PartialTransactionV2Builder {
child_partial_transactions,
root_subintent_header: Some(header),
root_subintent_message: message,
root_subintent_manifest:
Some(TransactionManifestV2 {
instructions,
blobs,
children,
}),
} = Arc::try_unwrap(self).unwrap_or_else(|x| (*x).clone())
else {
return Err(
RadixEngineToolkitError::NotAllBuilderItemsWereSpecified,
);
};

// Constructing the partial transaction
let partial_transaction = PartialTransactionV2 {
root_subintent: SubintentV2::new(IntentCoreV2::new(
header,
blobs,
message,
children,
instructions,
)),
non_root_subintents: child_partial_transactions
.iter()
.flat_map(|child| {
let mut subintents = Vec::new();
subintents.push(child.root_subintent.clone());
subintents
.extend(child.non_root_subintents.iter().cloned());
subintents
})
.collect(),
};

Ok(Arc::new(partial_transaction))
}
}

impl PartialTransactionV2Builder {
fn with_builder(
self: Arc<Self>,
callback: impl FnOnce(&mut Self),
) -> Arc<Self> {
let mut this = Arc::try_unwrap(self).unwrap_or_else(|x| (*x).clone());
callback(&mut this);
Arc::new(this)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

use crate::prelude::*;
use std::ops::Deref;

#[derive(Clone, Debug, Object)]
pub struct PreviewTransactionV2Builder {
transaction_header: Option<TransactionHeaderV2>,
transaction_intent_header: Option<IntentHeaderV2>,
transaction_intent_message: MessageV2,
transaction_intent_manifest: Option<TransactionManifestV2>,
child_partial_transactions: Vec<PartialTransactionV2>,
root_signer_public_keys: IndexSet<PublicKey>,
non_root_subintent_signer_public_keys: Vec<Vec<PublicKey>>,
}

#[uniffi::export]
impl PreviewTransactionV2Builder {
#[uniffi::constructor]
pub fn new() -> Arc<Self> {
Arc::new(Self {
transaction_header: Default::default(),
transaction_intent_header: Default::default(),
transaction_intent_message: Default::default(),
transaction_intent_manifest: Default::default(),
child_partial_transactions: Default::default(),
root_signer_public_keys: Default::default(),
non_root_subintent_signer_public_keys: Default::default(),
})
}

pub fn add_child(
self: Arc<Self>,
partial_transaction: Arc<PartialTransactionV2>,
signers: Vec<PublicKey>,
) -> Arc<Self> {
self.with_builder(|builder| {
builder
.child_partial_transactions
.push(partial_transaction.deref().clone());
builder.non_root_subintent_signer_public_keys.push(signers);
})
}

pub fn message(self: Arc<Self>, message: MessageV2) -> Arc<Self> {
self.with_builder(|builder| {
builder.transaction_intent_message = message
})
}

pub fn intent_header(
self: Arc<Self>,
intent_header: IntentHeaderV2,
) -> Arc<Self> {
self.with_builder(|builder| {
builder.transaction_intent_header = Some(intent_header)
})
}

pub fn transaction_header(
self: Arc<Self>,
transaction_header: TransactionHeaderV2,
) -> Arc<Self> {
self.with_builder(|builder| {
builder.transaction_header = Some(transaction_header)
})
}

pub fn manifest(
self: Arc<Self>,
manifest: Arc<TransactionManifestV2>,
) -> Arc<Self> {
self.with_builder(|builder| {
builder.transaction_intent_manifest =
Some(manifest.as_ref().clone())
})
}

pub fn add_root_intent_signer(
self: Arc<Self>,
signer: PublicKey,
) -> Arc<Self> {
self.with_builder(|builder| {
builder.root_signer_public_keys.insert(signer);
})
}

pub fn build(self: Arc<Self>) -> Result<Vec<u8>> {
// Deconstructing the builder.
let Self {
transaction_header: Some(transaction_header),
transaction_intent_header: Some(header),
transaction_intent_message: message,
child_partial_transactions,
root_signer_public_keys,
non_root_subintent_signer_public_keys,
transaction_intent_manifest:
Some(TransactionManifestV2 {
instructions,
blobs,
children,
}),
} = Arc::try_unwrap(self).unwrap_or_else(|x| (*x).clone())
else {
return Err(
RadixEngineToolkitError::NotAllBuilderItemsWereSpecified,
);
};

// Constructing the transaction intent
let transaction_intent = TransactionIntentV2 {
transaction_header,
root_intent_core: IntentCoreV2::new(
header,
blobs,
message,
children,
instructions,
),
non_root_subintents: child_partial_transactions
.iter()
.flat_map(|child| {
let mut subintents = Vec::new();
subintents.push(child.root_subintent.clone());
subintents
.extend(child.non_root_subintents.iter().cloned());
subintents
})
.collect(),
};
let transaction_intent =
NativeTransactionIntentV2::try_from(transaction_intent)?;

let preview_transaction = NativePreviewTransactionV2 {
transaction_intent,
root_signer_public_keys: root_signer_public_keys
.into_iter()
.map(TryInto::try_into)
.collect::<Result<_>>()?,
non_root_subintent_signer_public_keys:
non_root_subintent_signer_public_keys
.into_iter()
.map(|public_keys| {
public_keys
.into_iter()
.map(TryInto::try_into)
.collect::<Result<_>>()
})
.collect::<Result<_>>()?,
};

let raw_preview_transaction = preview_transaction.to_raw()?;
Ok(raw_preview_transaction.to_vec())
}
}

impl PreviewTransactionV2Builder {
fn with_builder(
self: Arc<Self>,
callback: impl FnOnce(&mut Self),
) -> Arc<Self> {
let mut this =
Arc::try_unwrap(self).unwrap_or_else(|arc| (*arc).clone());
callback(&mut this);
Arc::new(this)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

use crate::prelude::*;

#[derive(Clone, Enum, Debug)]
#[derive(Clone, Enum, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum PublicKey {
Secp256k1 { value: Vec<u8> },
Ed25519 { value: Vec<u8> },
Expand Down
1 change: 1 addition & 0 deletions crates/radix-engine-toolkit-uniffi/src/internal_prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,7 @@ mod native {
TransactionHeaderV2 as NativeTransactionHeaderV2,
DecryptorsByCurveV2 as NativeDecryptorsByCurveV2,
EncryptedMessageV2 as NativeEncryptedMessageV2,
PreviewTransactionV2 as NativePreviewTransactionV2,

MessageV1 as NativeMessageV1,
AesGcmPayload as NativeAesGcmPayload,
Expand Down
Loading

0 comments on commit 221c1ea

Please sign in to comment.