diff --git a/.github/workflows/bindings-wallet-nodejs.yml b/.github/workflows/bindings-wallet-nodejs.yml deleted file mode 100644 index e86578a441..0000000000 --- a/.github/workflows/bindings-wallet-nodejs.yml +++ /dev/null @@ -1,106 +0,0 @@ -name: Nodejs bindings checks (wallet) - -on: - push: - branches: [develop, production, 2.0] - paths: - - ".github/actions/**" - - "**.rs" # Include all rust files - - "**Cargo.toml" # Include all Cargo.toml files - - "**Cargo.lock" # Include all Cargo.lock files - - "!**/examples/**" # Exclude all examples - - "!**/tests/**" # Exclude all tests - - "!cli/**" # Exclude CLI - - "!**/bindings/**" # Exclude all bindings - - "bindings/nodejs-old/**" - - ".github/workflows/bindings-wallet-nodejs.yml" - - ".patches/*" - pull_request: - branches: [develop, production, 2.0] - paths: - - ".github/actions/**" - - "**.rs" # Include all rust files - - "**Cargo.toml" # Include all Cargo.toml files - - "**Cargo.lock" # Include all Cargo.lock files - - "!**/examples/**" # Exclude all examples - - "!**/tests/**" # Exclude all tests - - "!cli/**" # Exclude CLI - - "!**/bindings/**" # Exclude all bindings - - "bindings/nodejs-old/**" - - ".github/workflows/bindings-wallet-nodejs.yml" - - ".patches/*" - schedule: - - cron: "0 1 * * *" - workflow_dispatch: - -env: - CARGO_INCREMENTAL: 0 - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - test: - name: Test - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - os: [windows-latest, macos-13, ubuntu-latest] - node: ["18"] - - steps: - - name: Checkout the Source Code - uses: actions/checkout@v3 - - - name: Select Xcode (macOS) - uses: maxim-lobanov/setup-xcode@v1 - if: matrix.os == 'macos-13' - with: - xcode-version: '14.3' - - - name: Set deployment target (macOS) - run: echo "MACOSX_DEPLOYMENT_TARGET=10.13" >> $GITHUB_ENV - if: matrix.os == 'macos-13' - - - name: Set up Rust - uses: ./.github/actions/setup-rust - with: - cache-root: bindings/nodejs-old - - - name: Set Up Node.js ${{ matrix.node }} and Yarn Cache - uses: actions/setup-node@v2 - with: - node-version: ${{ matrix.node }} - cache: npm - cache-dependency-path: bindings/nodejs-old/package-lock.json - - # This step is required for bindgen to work on Windows. - - name: Set Up Clang/LLVM (Windows) - if: ${{ startsWith(matrix.os, 'windows') }} - uses: ./.github/actions/setup-clang - - - name: Install Required Dependencies (Ubuntu) - if: ${{ startsWith(matrix.os, 'ubuntu') }} - run: | - sudo apt-get update - sudo apt-get install libudev-dev libusb-1.0-0-dev - - # This step is required to support macOS 10.13 - - name: Patch librocksdb-sys (macOS) - if: ${{ startsWith(matrix.os, 'macos') }} - run: | - cargo install cargo-patch - cp ${{ github.workspace }}/.patches/rocksdb_faligned_allocation.patch . - git apply --ignore-space-change --ignore-whitespace ${{ github.workspace }}/.patches/macos_cargo_toml.patch - cat Cargo.toml - cargo patch - - - name: Build nodejs binding - run: npm ci --build-from-source - working-directory: bindings/nodejs-old - - - name: Run npm test - run: npm test - working-directory: bindings/nodejs-old diff --git a/bindings/core/src/method_handler/client.rs b/bindings/core/src/method_handler/client.rs index a5e4a28db3..097fa95159 100644 --- a/bindings/core/src/method_handler/client.rs +++ b/bindings/core/src/method_handler/client.rs @@ -283,7 +283,7 @@ pub(crate) async fn call_client_method_internal(client: &Client, method: ClientM ClientMethod::GetBlockRaw { block_id } => Response::Raw(client.get_block_raw(&block_id).await?), ClientMethod::GetOutput { output_id } => Response::OutputWithMetadataResponse( client - .get_output(&output_id) + .get_output_with_metadata(&output_id) .await .map(OutputWithMetadataResponse::from)?, ), @@ -313,7 +313,7 @@ pub(crate) async fn call_client_method_internal(client: &Client, method: ClientM ClientMethod::FoundryOutputId { foundry_id } => Response::OutputId(client.foundry_output_id(foundry_id).await?), ClientMethod::GetOutputs { output_ids } => { let outputs_response = client - .get_outputs(&output_ids) + .get_outputs_with_metadata(&output_ids) .await? .iter() .map(OutputWithMetadataResponse::from) @@ -322,7 +322,7 @@ pub(crate) async fn call_client_method_internal(client: &Client, method: ClientM } ClientMethod::GetOutputsIgnoreErrors { output_ids } => { let outputs_response = client - .get_outputs_ignore_errors(&output_ids) + .get_outputs_with_metadata_ignore_errors(&output_ids) .await? .iter() .map(OutputWithMetadataResponse::from) diff --git a/sdk/examples/client/02_address_balance.rs b/sdk/examples/client/02_address_balance.rs index e3622665a0..80d6eb4f47 100644 --- a/sdk/examples/client/02_address_balance.rs +++ b/sdk/examples/client/02_address_balance.rs @@ -56,8 +56,7 @@ async fn main() -> Result<()> { // Calculate the total amount and native tokens let mut total_amount = 0; let mut total_native_tokens = NativeTokensBuilder::new(); - for output_response in outputs_responses { - let output = output_response.output(); + for output in outputs_responses { if let Some(native_tokens) = output.native_tokens() { total_native_tokens.add_native_tokens(native_tokens.clone())?; } diff --git a/sdk/examples/client/output/nft.rs b/sdk/examples/client/output/nft.rs index 96112d2832..6ec6eb09e9 100644 --- a/sdk/examples/client/output/nft.rs +++ b/sdk/examples/client/output/nft.rs @@ -94,18 +94,16 @@ async fn main() -> Result<()> { let output_ids_response = client .basic_output_ids([QueryParameter::Address(bech32_nft_address)]) .await?; - let output_with_meta = client.get_output(&output_ids_response.items[0]).await?; + let output = client.get_output(&output_ids_response.items[0]).await?; let block = client .build_block() .with_secret_manager(&secret_manager) .with_input(nft_output_id.into())? .with_input(output_ids_response.items[0].into())? - .with_outputs([ - NftOutputBuilder::new_with_amount(1_000_000 + output_with_meta.output().amount(), nft_id) - .add_unlock_condition(AddressUnlockCondition::new(bech32_nft_address)) - .finish_output(token_supply)?, - ])? + .with_outputs([NftOutputBuilder::new_with_amount(1_000_000 + output.amount(), nft_id) + .add_unlock_condition(AddressUnlockCondition::new(bech32_nft_address)) + .finish_output(token_supply)?])? .finish() .await?; @@ -122,8 +120,8 @@ async fn main() -> Result<()> { ////////////////////////////////// let nft_output_id = get_nft_output_id(block.payload().unwrap())?; - let output_with_meta = client.get_output(&nft_output_id).await?; - let outputs = [BasicOutputBuilder::new_with_amount(output_with_meta.output().amount()) + let output = client.get_output(&nft_output_id).await?; + let outputs = [BasicOutputBuilder::new_with_amount(output.amount()) .add_unlock_condition(AddressUnlockCondition::new(bech32_nft_address)) .finish_output(token_supply)?]; diff --git a/sdk/examples/client/send_all.rs b/sdk/examples/client/send_all.rs index 6a7caf0a39..5a8591bc11 100644 --- a/sdk/examples/client/send_all.rs +++ b/sdk/examples/client/send_all.rs @@ -56,9 +56,7 @@ async fn main() -> Result<()> { let mut total_amount = 0; let mut total_native_tokens = NativeTokensBuilder::new(); - for output_response in outputs_responses { - let output = output_response.output(); - + for output in outputs_responses { if let Some(native_tokens) = output.native_tokens() { total_native_tokens.add_native_tokens(native_tokens.clone())?; } diff --git a/sdk/src/client/api/block_builder/input_selection/automatic.rs b/sdk/src/client/api/block_builder/input_selection/automatic.rs index 53f0606b45..bd0c2616cd 100644 --- a/sdk/src/client/api/block_builder/input_selection/automatic.rs +++ b/sdk/src/client/api/block_builder/input_selection/automatic.rs @@ -57,7 +57,7 @@ impl<'a> ClientBlockBuilder<'a> { .items, ); - self.client.get_outputs(&output_ids).await + self.client.get_outputs_with_metadata(&output_ids).await } /// Searches inputs for provided outputs, by requesting the outputs from the account addresses or for diff --git a/sdk/src/client/api/block_builder/input_selection/manual.rs b/sdk/src/client/api/block_builder/input_selection/manual.rs index d2ad690d2a..8901e34030 100644 --- a/sdk/src/client/api/block_builder/input_selection/manual.rs +++ b/sdk/src/client/api/block_builder/input_selection/manual.rs @@ -38,7 +38,7 @@ impl<'a> ClientBlockBuilder<'a> { if let Some(inputs) = &self.inputs { for input in inputs { - let output_with_meta = self.client.get_output(input.output_id()).await?; + let output_with_meta = self.client.get_output_with_metadata(input.output_id()).await?; if !output_with_meta.metadata().is_spent() { let alias_transition = is_alias_transition( diff --git a/sdk/src/client/api/block_builder/input_selection/sender_issuer.rs b/sdk/src/client/api/block_builder/input_selection/sender_issuer.rs index d869d65f11..29a2714c50 100644 --- a/sdk/src/client/api/block_builder/input_selection/sender_issuer.rs +++ b/sdk/src/client/api/block_builder/input_selection/sender_issuer.rs @@ -99,7 +99,7 @@ impl<'a> ClientBlockBuilder<'a> { } }) { let output_id = self.client.alias_output_id(*alias_id).await?; - let output_with_meta = self.client.get_output(&output_id).await?; + let output_with_meta = self.client.get_output_with_metadata(&output_id).await?; if let Output::Alias(alias_output) = output_with_meta.output() { // State transition if we add them to inputs let unlock_address = alias_output.state_controller_address(); @@ -151,7 +151,7 @@ impl<'a> ClientBlockBuilder<'a> { } }) { let output_id = self.client.nft_output_id(*nft_id).await?; - let output_with_meta = self.client.get_output(&output_id).await?; + let output_with_meta = self.client.get_output_with_metadata(&output_id).await?; if let Output::Nft(nft_output) = output_with_meta.output() { let unlock_address = nft_output .unlock_conditions() diff --git a/sdk/src/client/api/block_builder/input_selection/utxo_chains.rs b/sdk/src/client/api/block_builder/input_selection/utxo_chains.rs index 43572124ab..ae2b230055 100644 --- a/sdk/src/client/api/block_builder/input_selection/utxo_chains.rs +++ b/sdk/src/client/api/block_builder/input_selection/utxo_chains.rs @@ -57,7 +57,7 @@ pub(crate) async fn get_alias_and_nft_outputs_recursively( match unlock_address { Address::Alias(address) => { let input_id = client.alias_output_id(*address.alias_id()).await?; - let input = client.get_output(&input_id).await?; + let input = client.get_output_with_metadata(&input_id).await?; if let Output::Alias(alias_input) = input.output() { // State transition if we add them to inputs let alias_unlock_address = alias_input.state_controller_address(); @@ -71,7 +71,7 @@ pub(crate) async fn get_alias_and_nft_outputs_recursively( } Address::Nft(address) => { let input_id = client.nft_output_id(*address.nft_id()).await?; - let input = client.get_output(&input_id).await?; + let input = client.get_output_with_metadata(&input_id).await?; if let Output::Nft(nft_input) = input.output() { let unlock_address = nft_input .unlock_conditions() @@ -119,7 +119,7 @@ impl<'a> ClientBlockBuilder<'a> { // Check if the transaction is a governance_transition, by checking if the new index is the same // as the previous index let output_id = client.alias_output_id(*alias_output.alias_id()).await?; - let input = client.get_output(&output_id).await?; + let input = client.get_output_with_metadata(&output_id).await?; if let Output::Alias(alias_input) = input.output() { // A governance transition is identified by an unchanged State Index in next // state. @@ -135,7 +135,7 @@ impl<'a> ClientBlockBuilder<'a> { // If the id is null then this output creates it and we can't have a previous output if !nft_output.nft_id().is_null() { let output_id = client.nft_output_id(*nft_output.nft_id()).await?; - let input = client.get_output(&output_id).await?; + let input = client.get_output_with_metadata(&output_id).await?; if let Output::Nft(nft_input) = input.output() { let unlock_address = nft_input .unlock_conditions() @@ -148,7 +148,7 @@ impl<'a> ClientBlockBuilder<'a> { Output::Foundry(foundry_output) => { // if it's the first foundry output, then we can't have it as input if let Ok(output_id) = client.foundry_output_id(foundry_output.id()).await { - let input = client.get_output(&output_id).await?; + let input = client.get_output_with_metadata(&output_id).await?; if let Output::Foundry(foundry_input_output) = input.output() { utxo_chains.push((Address::Alias(*foundry_input_output.alias_address()), input)); } diff --git a/sdk/src/client/api/consolidation.rs b/sdk/src/client/api/consolidation.rs index 684f2a031a..5f9790a862 100644 --- a/sdk/src/client/api/consolidation.rs +++ b/sdk/src/client/api/consolidation.rs @@ -46,7 +46,7 @@ impl Client { ]) .await?; - let basic_outputs_responses = self.get_outputs(&output_ids_response.items).await?; + let basic_outputs_responses = self.get_outputs_with_metadata(&output_ids_response.items).await?; if !basic_outputs_responses.is_empty() { // If we reach the same index again diff --git a/sdk/src/client/api/high_level.rs b/sdk/src/client/api/high_level.rs index 98f1d8527b..0a5d7a8715 100644 --- a/sdk/src/client/api/high_level.rs +++ b/sdk/src/client/api/high_level.rs @@ -53,7 +53,7 @@ impl Client { }) .collect::>(); - self.get_outputs(&input_ids).await + self.get_outputs_with_metadata(&input_ids).await } /// Get a builder that can be used to construct a block in parts. @@ -179,7 +179,7 @@ impl Client { }) .and_then(|res| async { let items = res.items; - self.get_outputs(&items).await + self.get_outputs_with_metadata(&items).await }) .try_collect::>() .await?; diff --git a/sdk/src/client/node_api/core/mod.rs b/sdk/src/client/node_api/core/mod.rs index 9ae39e13b5..0dfce551c6 100644 --- a/sdk/src/client/node_api/core/mod.rs +++ b/sdk/src/client/node_api/core/mod.rs @@ -5,16 +5,31 @@ pub mod routes; +use packable::PackableExt; + #[cfg(not(target_family = "wasm"))] use crate::client::constants::MAX_PARALLEL_API_REQUESTS; use crate::{ client::{Client, Result}, - types::block::output::{OutputId, OutputMetadata, OutputWithMetadata}, + 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 { + 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)) + } + /// Request outputs by their output ID in parallel - pub async fn get_outputs(&self, output_ids: &[OutputId]) -> Result> { + pub async fn get_outputs(&self, output_ids: &[OutputId]) -> Result> { #[cfg(target_family = "wasm")] let outputs = futures::future::try_join_all(output_ids.iter().map(|id| self.get_output(id))).await?; @@ -38,9 +53,38 @@ impl Client { Ok(outputs) } + /// Request outputs and their metadata by their output ID in parallel + pub async fn get_outputs_with_metadata(&self, output_ids: &[OutputId]) -> Result> { + #[cfg(target_family = "wasm")] + let outputs = + futures::future::try_join_all(output_ids.iter().map(|id| self.get_output_with_metadata(id))).await?; + + #[cfg(not(target_family = "wasm"))] + let outputs = + futures::future::try_join_all(output_ids.chunks(MAX_PARALLEL_API_REQUESTS).map(|output_ids_chunk| { + let client = self.clone(); + let output_ids_chunk = output_ids_chunk.to_vec(); + async move { + tokio::spawn(async move { + futures::future::try_join_all( + output_ids_chunk.iter().map(|id| client.get_output_with_metadata(id)), + ) + .await + }) + .await? + } + })) + .await? + .into_iter() + .flatten() + .collect(); + + Ok(outputs) + } + /// Request outputs by their output ID in parallel, ignoring failed requests /// Useful to get data about spent outputs, that might not be pruned yet - pub async fn get_outputs_ignore_errors(&self, output_ids: &[OutputId]) -> Result> { + pub async fn get_outputs_ignore_errors(&self, output_ids: &[OutputId]) -> Result> { #[cfg(target_family = "wasm")] let outputs = futures::future::join_all(output_ids.iter().map(|id| self.get_output(id))) .await @@ -69,6 +113,40 @@ impl Client { Ok(outputs) } + /// Request outputs and their metadata by their output ID in parallel, ignoring failed requests + /// Useful to get data about spent outputs, that might not be pruned yet + pub async fn get_outputs_with_metadata_ignore_errors( + &self, + output_ids: &[OutputId], + ) -> Result> { + #[cfg(target_family = "wasm")] + let outputs = futures::future::join_all(output_ids.iter().map(|id| self.get_output_with_metadata(id))) + .await + .into_iter() + .filter_map(Result::ok) + .collect(); + + #[cfg(not(target_family = "wasm"))] + let outputs = + futures::future::try_join_all(output_ids.chunks(MAX_PARALLEL_API_REQUESTS).map(|output_ids_chunk| { + let client = self.clone(); + let output_ids_chunk = output_ids_chunk.to_vec(); + tokio::spawn(async move { + futures::future::join_all(output_ids_chunk.iter().map(|id| client.get_output_with_metadata(id))) + .await + .into_iter() + .filter_map(Result::ok) + .collect::>() + }) + })) + .await? + .into_iter() + .flatten() + .collect(); + + Ok(outputs) + } + /// Requests metadata for outputs by their output ID in parallel, ignoring failed requests pub async fn get_outputs_metadata_ignore_errors(&self, output_ids: &[OutputId]) -> Result> { #[cfg(target_family = "wasm")] diff --git a/sdk/src/client/node_api/core/routes.rs b/sdk/src/client/node_api/core/routes.rs index e87a2419fe..d7db2fbc1a 100644 --- a/sdk/src/client/node_api/core/routes.rs +++ b/sdk/src/client/node_api/core/routes.rs @@ -15,11 +15,10 @@ use crate::{ }, types::{ api::core::response::{ - BlockMetadataResponse, InfoResponse, OutputWithMetadataResponse, PeerResponse, RoutesResponse, - SubmitBlockResponse, TipsResponse, + BlockMetadataResponse, InfoResponse, PeerResponse, RoutesResponse, SubmitBlockResponse, TipsResponse, }, block::{ - output::{Output, OutputId, OutputMetadata, OutputWithMetadata}, + output::{dto::OutputDto, Output, OutputId, OutputMetadata}, payload::transaction::TransactionId, slot::{SlotCommitment, SlotCommitmentId, SlotIndex}, Block, BlockDto, BlockId, @@ -261,20 +260,18 @@ impl ClientInner { /// Finds an output by its ID and returns it as object. /// GET /api/core/v3/outputs/{outputId} - pub async fn get_output(&self, output_id: &OutputId) -> Result { + pub async fn get_output(&self, output_id: &OutputId) -> Result { let path = &format!("api/core/v3/outputs/{output_id}"); - let response: OutputWithMetadataResponse = self + let output = self .node_manager .read() .await - .get_request(path, None, self.get_timeout().await, false, true) + .get_request::(path, None, self.get_timeout().await, false, true) .await?; - let token_supply = self.get_token_supply().await?; - let output = Output::try_from_dto_with_params(response.output, token_supply)?; - Ok(OutputWithMetadata::new(output, response.metadata)) + Ok(Output::try_from_dto_with_params(output, token_supply)?) } /// Finds an output by its ID and returns it as raw bytes. @@ -442,8 +439,7 @@ impl Client { .map_err(|_| crate::client::Error::UrlAuth("password"))?; } } - let path = "api/core/v3/info"; - url.set_path(path); + url.set_path(INFO_PATH); let resp: InfoResponse = crate::client::node_manager::http_client::HttpClient::new(DEFAULT_USER_AGENT.to_string()) diff --git a/sdk/src/wallet/account/mod.rs b/sdk/src/wallet/account/mod.rs index 270de73e4d..498c03075f 100644 --- a/sdk/src/wallet/account/mod.rs +++ b/sdk/src/wallet/account/mod.rs @@ -225,9 +225,9 @@ where // Foundry was not found in the account, try to get it from the node let foundry_output_id = self.client().foundry_output_id(foundry_id).await?; - let output_response = self.client().get_output(&foundry_output_id).await?; + let output = self.client().get_output(&foundry_output_id).await?; - Ok(output_response.output().to_owned()) + Ok(output) } /// Save the account to the database, accepts the updated_account as option so we don't need to drop it before diff --git a/sdk/src/wallet/account/operations/syncing/foundries.rs b/sdk/src/wallet/account/operations/syncing/foundries.rs index 1d4b97bb3b..96c5998d37 100644 --- a/sdk/src/wallet/account/operations/syncing/foundries.rs +++ b/sdk/src/wallet/account/operations/syncing/foundries.rs @@ -39,9 +39,9 @@ where .await?; // Update account with new foundries. - for foundry_output_with_metadata in results.into_iter().flatten() { - if let Output::Foundry(foundry) = foundry_output_with_metadata.output() { - foundries.insert(foundry.id(), foundry.to_owned()); + for foundry in results.into_iter().flatten() { + if let Output::Foundry(foundry) = foundry { + foundries.insert(foundry.id(), foundry); } } diff --git a/sdk/src/wallet/account/operations/syncing/outputs.rs b/sdk/src/wallet/account/operations/syncing/outputs.rs index 2f10d4032f..5344e34f16 100644 --- a/sdk/src/wallet/account/operations/syncing/outputs.rs +++ b/sdk/src/wallet/account/operations/syncing/outputs.rs @@ -104,7 +104,7 @@ where drop(account_details); if !unknown_outputs.is_empty() { - outputs.extend(self.client().get_outputs(&unknown_outputs).await?); + outputs.extend(self.client().get_outputs_with_metadata(&unknown_outputs).await?); } log::debug!( @@ -214,7 +214,7 @@ pub(crate) async fn get_inputs_for_transaction_payload( .collect::>(); client - .get_outputs_ignore_errors(&output_ids) + .get_outputs_with_metadata_ignore_errors(&output_ids) .await .map_err(|e| e.into()) } diff --git a/sdk/tests/client/consolidation.rs b/sdk/tests/client/consolidation.rs index 84224d0f04..644fd44271 100644 --- a/sdk/tests/client/consolidation.rs +++ b/sdk/tests/client/consolidation.rs @@ -34,7 +34,7 @@ async fn consolidate_outputs() -> Result<()> { assert_eq!(output_ids_response.items.len(), 1); let initial_output = client.get_output(&output_ids_response.items[0]).await?; - let initial_base_coin_amount = initial_output.output().amount(); + let initial_base_coin_amount = initial_output.amount(); // First split funds to multiple addresses let token_supply = client.get_token_supply().await?; @@ -77,7 +77,7 @@ async fn consolidate_outputs() -> Result<()> { assert_eq!(output_ids_response.items.len(), 1); let final_output = client.get_output(&output_ids_response.items[0]).await?; - let final_base_coin_amount = final_output.output().amount(); + let final_base_coin_amount = final_output.amount(); // The output has the full amount again assert_eq!(final_base_coin_amount, initial_base_coin_amount); diff --git a/sdk/tests/client/node_api/core.rs b/sdk/tests/client/node_api/core.rs index a6501e6963..e0338f113d 100644 --- a/sdk/tests/client/node_api/core.rs +++ b/sdk/tests/client/node_api/core.rs @@ -144,7 +144,7 @@ async fn test_get_output_raw() { let (_block_id, transaction_id) = setup_transaction_block(&client).await; let output_id = OutputId::new(transaction_id, 0).unwrap(); - let output = client.get_output(&output_id).await.unwrap().into_output(); + let output = client.get_output(&output_id).await.unwrap(); let output_raw = Output::unpack_verified( client.get_output_raw(&output_id).await.unwrap(), &client.get_protocol_parameters().await.unwrap(), diff --git a/sdk/tests/client/transactions.rs b/sdk/tests/client/transactions.rs index fd847133a4..af30ff0ae3 100644 --- a/sdk/tests/client/transactions.rs +++ b/sdk/tests/client/transactions.rs @@ -107,7 +107,7 @@ async fn custom_input() -> Result<()> { // The first output would be picked when using automatic input selection, so use the second one instead let input_id = output_ids_response.items[1]; - let input_amount = client.get_output(&input_id).await?.output().amount(); + let input_amount = client.get_output(&input_id).await?.amount(); let output = BasicOutputBuilder::new_with_amount(input_amount) .add_unlock_condition(AddressUnlockCondition::new(address))