Skip to content

Commit

Permalink
Add /api/core/v3/outputs/{outputId}/full route
Browse files Browse the repository at this point in the history
  • Loading branch information
Thoralf-M committed Dec 4, 2023
1 parent 59cfa35 commit 642eb03
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 29 deletions.
15 changes: 0 additions & 15 deletions sdk/src/client/node_api/core/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,12 @@

pub mod routes;

use packable::PackableExt;

use crate::{
client::{node_api::error::Error as NodeApiError, Client, Error, Result},
types::block::output::{Output, OutputId, OutputMetadata, OutputWithMetadata},
};

impl Client {
// Finds output and its metadata by output ID.
/// GET /api/core/v3/outputs/{outputId}
/// + GET /api/core/v3/outputs/{outputId}/metadata
pub async fn get_output_with_metadata(&self, output_id: &OutputId) -> Result<OutputWithMetadata> {
let output = Output::unpack_verified(
self.get_output_raw(output_id).await?,
&self.get_protocol_parameters().await?,
)?;
let metadata = self.get_output_metadata(output_id).await?;

Ok(OutputWithMetadata::new(output, metadata))
}

/// Requests outputs by their output ID in parallel.
pub async fn get_outputs(&self, output_ids: &[OutputId]) -> Result<Vec<Output>> {
futures::future::try_join_all(output_ids.iter().map(|id| self.get_output(id))).await
Expand Down
10 changes: 9 additions & 1 deletion sdk/src/client/node_api/core/routes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use crate::{
},
block::{
address::ToBech32Ext,
output::{AccountId, Output, OutputId, OutputMetadata},
output::{AccountId, Output, OutputId, OutputMetadata, OutputWithMetadata},
payload::signed_transaction::TransactionId,
slot::{EpochIndex, SlotCommitment, SlotCommitmentId, SlotIndex},
Block, BlockDto, BlockId,
Expand Down Expand Up @@ -256,6 +256,14 @@ impl ClientInner {
self.get_request(path, None, false, true).await
}

/// Finds an output with its metadata by output ID.
/// GET /api/core/v3/outputs/{outputId}/full
pub async fn get_output_with_metadata(&self, output_id: &OutputId) -> Result<OutputWithMetadata> {
let path = &format!("api/core/v3/outputs/{output_id}/full");

self.get_request(path, None, false, true).await
}

/// Returns the earliest confirmed block containing the transaction with the given ID.
/// GET /api/core/v3/transactions/{transactionId}/included-block
pub async fn get_included_block(&self, transaction_id: &TransactionId) -> Result<Block> {
Expand Down
55 changes: 55 additions & 0 deletions sdk/src/types/api/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -525,3 +525,58 @@ pub struct UtxoChangesResponse {
pub created_outputs: Vec<OutputId>,
pub consumed_outputs: Vec<OutputId>,
}

/// Contains the generic [`Output`] with associated [`OutputIdProof`].
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct OutputResponse {
pub(crate) output: Output,
pub(crate) output_id_proof: OutputIdProof,
}

/// The proof of the output identifier.
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct OutputIdProof {
pub(crate) output: Output,
pub(crate) output_commitment_proof: OutputCommitmentProof,
}

#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OutputCommitmentProof {
HashableNode(HashableNode),
LeafHash(LeafHash),
ValueHash(ValueHash),
}

/// The proof of the output commitment.
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct HashableNode {
#[serde(rename = "type")]
pub(crate) kind: u8,
pub(crate) node: Node,
}

/// Node.
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct Node {
pub(crate) l: Option<Box<HashableNode>>,
pub(crate) r: Option<Box<HashableNode>>,
}

/// Leaf Hash contains the hash of a leaf in the tree.
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct LeafHash {
#[serde(rename = "type")]
pub(crate) kind: u8,
pub(crate) hash: String,
}

/// Value Hash contains the hash of the value for which the proof is being computed.
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct ValueHash {
#[serde(rename = "type")]
pub(crate) kind: u8,
pub(crate) hash: String,
}
36 changes: 25 additions & 11 deletions sdk/src/types/block/output/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,15 @@ pub(crate) use self::{
output_id::OutputIndex,
unlock_condition::AddressUnlockCondition,
};
use crate::types::block::{
address::Address,
protocol::{ProtocolParameters, WorkScore, WorkScoreParameters},
semantic::SemanticValidationContext,
slot::SlotIndex,
Error,
use crate::types::{
api::core::OutputResponse,
block::{
address::Address,
protocol::{ProtocolParameters, WorkScore, WorkScoreParameters},
semantic::SemanticValidationContext,
slot::SlotIndex,
Error,
},
};

/// The maximum number of outputs of a transaction.
Expand All @@ -75,27 +78,38 @@ pub enum OutputBuilderAmount {
MinimumAmount(StorageScoreParameters),
}

/// Contains the generic [`Output`] with associated [`OutputMetadata`].
/// Contains the generic [`OutputResponse`] with associated [`OutputMetadata`].
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct OutputWithMetadata {
pub(crate) output: Output,
pub(crate) output: OutputResponse,
pub(crate) metadata: OutputMetadata,
}

impl OutputWithMetadata {
/// Creates a new [`OutputWithMetadata`].
pub fn new(output: Output, metadata: OutputMetadata) -> Self {
pub fn new(output: OutputResponse, metadata: OutputMetadata) -> Self {
Self { output, metadata }
}

/// Returns the [`OutputResponse`].
pub fn output_response(&self) -> &OutputResponse {
&self.output
}

/// Consumes self and returns the [`OutputResponse`].
pub fn into_output_response(self) -> OutputResponse {
self.output
}

/// Returns the [`Output`].
pub fn output(&self) -> &Output {
&self.output
&self.output.output
}

/// Consumes self and returns the [`Output`].
pub fn into_output(self) -> Output {
self.output
self.output.output
}

/// Returns the [`OutputMetadata`].
Expand Down
3 changes: 2 additions & 1 deletion sdk/src/wallet/operations/syncing/outputs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ where
output_id: output_with_meta.metadata().output_id().to_owned(),
metadata: *output_with_meta.metadata(),
output: output_with_meta.output().clone(),
output_response: output_with_meta.output_response().clone(),
is_spent: output_with_meta.metadata().is_spent(),
address: associated_address.address.inner.clone(),
network_id,
Expand Down Expand Up @@ -90,7 +91,7 @@ where
output_data.is_spent = false;
unspent_outputs.push((output_id, output_data.clone()));
outputs.push(OutputWithMetadata::new(
output_data.output.clone(),
output_data.output_response.clone(),
output_data.metadata,
));
}
Expand Down
5 changes: 4 additions & 1 deletion sdk/src/wallet/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub use self::{
use crate::{
client::secret::types::InputSigningData,
types::{
api::core::OutputWithMetadataResponse,
api::core::{OutputResponse, OutputWithMetadataResponse},
block::{
address::Address,
output::{Output, OutputId, OutputMetadata},
Expand All @@ -43,6 +43,9 @@ pub struct OutputData {
pub metadata: OutputMetadata,
/// The actual Output
pub output: Output,
/// The OutputResponse
// TODO: merge with output?
pub output_response: OutputResponse,
/// If an output is spent
pub is_spent: bool,
/// Associated wallet address.
Expand Down

0 comments on commit 642eb03

Please sign in to comment.