diff --git a/bindings/core/src/method/client.rs b/bindings/core/src/method/client.rs index 29e806f6bd..20f12efe31 100644 --- a/bindings/core/src/method/client.rs +++ b/bindings/core/src/method/client.rs @@ -175,6 +175,12 @@ pub enum ClientMethod { /// Block ID block_id: BlockId, }, + /// Get a block with its metadata + #[serde(rename_all = "camelCase")] + GetBlockWithMetadata { + /// Block ID + block_id: BlockId, + }, /// Get block raw #[serde(rename_all = "camelCase")] GetBlockRaw { diff --git a/bindings/core/src/method_handler/client.rs b/bindings/core/src/method_handler/client.rs index 753c897297..cb9a955938 100644 --- a/bindings/core/src/method_handler/client.rs +++ b/bindings/core/src/method_handler/client.rs @@ -196,6 +196,9 @@ pub(crate) async fn call_client_method_internal(client: &Client, method: ClientM ClientMethod::GetBlockMetadata { block_id } => { Response::BlockMetadata(client.get_block_metadata(&block_id).await?) } + ClientMethod::GetBlockWithMetadata { block_id } => { + Response::BlockWithMetadata(client.get_block_with_metadata(&block_id).await?) + } ClientMethod::GetBlockRaw { block_id } => Response::Raw(client.get_block_raw(&block_id).await?), ClientMethod::GetOutput { output_id } => Response::OutputWithMetadataResponse( client diff --git a/bindings/core/src/response.rs b/bindings/core/src/response.rs index 978a80b602..03df850853 100644 --- a/bindings/core/src/response.rs +++ b/bindings/core/src/response.rs @@ -16,8 +16,8 @@ use iota_sdk::{ types::{ api::{ core::{ - BlockMetadataResponse, InfoResponse as NodeInfo, IssuanceBlockHeaderResponse, - OutputWithMetadataResponse, PeerResponse, + BlockMetadataResponse, BlockWithMetadataResponse, InfoResponse as NodeInfo, + IssuanceBlockHeaderResponse, OutputWithMetadataResponse, PeerResponse, }, plugins::indexer::OutputIdsResponse, }, @@ -118,6 +118,9 @@ pub enum Response { /// - [`GetBlockMetadata`](crate::method::ClientMethod::GetBlockMetadata) BlockMetadata(BlockMetadataResponse), /// Response for: + /// - [`GetBlockWithMetadata`](crate::method::ClientMethod::GetBlockWithMetadata) + BlockWithMetadata(BlockWithMetadataResponse), + /// Response for: /// - [`GetBlockRaw`](crate::method::ClientMethod::GetBlockRaw) Raw(Vec), /// Response for: diff --git a/bindings/nodejs/lib/client/client.ts b/bindings/nodejs/lib/client/client.ts index dcbc06e1a5..fdd64f7f1d 100644 --- a/bindings/nodejs/lib/client/client.ts +++ b/bindings/nodejs/lib/client/client.ts @@ -57,6 +57,7 @@ import { u64, TransactionId, Bech32Address, + IBlockWithMetadata, } from '../types'; import { OutputResponse, IOutputsResponse } from '../types/models/api'; @@ -194,6 +195,23 @@ export class Client { return JSON.parse(response).payload; } + /** + * Get a block with its metadata. + * + * @param blockId The corresponding block ID of the requested block. + * @returns The requested block with its metadata. + */ + async getBlockWithMetadata(blockId: BlockId): Promise { + const response = await this.methodHandler.callMethod({ + name: 'getBlockWithMetadata', + data: { + blockId, + }, + }); + + return JSON.parse(response).payload; + } + /** * Find inputs from addresses for a given amount (useful for offline signing). * diff --git a/bindings/nodejs/lib/types/client/bridge/client.ts b/bindings/nodejs/lib/types/client/bridge/client.ts index 6db9d5ac29..3c36f250b9 100644 --- a/bindings/nodejs/lib/types/client/bridge/client.ts +++ b/bindings/nodejs/lib/types/client/bridge/client.ts @@ -82,6 +82,13 @@ export interface __GetBlockMetadataMethod__ { }; } +export interface __GetBlockWithMetadataMethod__ { + name: 'getBlockWithMetadata'; + data: { + blockId: BlockId; + }; +} + export interface __FindInputsMethod__ { name: 'findInputs'; data: { diff --git a/bindings/nodejs/lib/types/client/bridge/index.ts b/bindings/nodejs/lib/types/client/bridge/index.ts index 8535e6086d..563f71b7d3 100644 --- a/bindings/nodejs/lib/types/client/bridge/index.ts +++ b/bindings/nodejs/lib/types/client/bridge/index.ts @@ -12,6 +12,7 @@ import type { __GetNetworkInfoMethod__, __GetBlockMethod__, __GetBlockMetadataMethod__, + __GetBlockWithMetadataMethod__, __FindInputsMethod__, __SignTransactionMethod__, __BuildBasicBlockMethod__, @@ -65,6 +66,7 @@ export type __ClientMethods__ = | __GetNetworkInfoMethod__ | __GetBlockMethod__ | __GetBlockMetadataMethod__ + | __GetBlockWithMetadataMethod__ | __FindInputsMethod__ | __SignTransactionMethod__ | __SignatureUnlockMethod__ diff --git a/bindings/nodejs/lib/types/models/block-metadata.ts b/bindings/nodejs/lib/types/models/block-metadata.ts index 2cd740e522..70043f2a60 100644 --- a/bindings/nodejs/lib/types/models/block-metadata.ts +++ b/bindings/nodejs/lib/types/models/block-metadata.ts @@ -5,6 +5,7 @@ import type { TransactionFailureReason } from './transaction-failure-reason'; import type { HexEncodedString } from '../utils/hex-encoding'; import { BlockState, TransactionState } from './state'; import { BlockFailureReason } from './block-failure-reason'; +import { Block } from '../block'; /** * Response from the metadata endpoint. @@ -31,3 +32,17 @@ export interface IBlockMetadata { */ transactionFailureReason?: TransactionFailureReason; } + +/** + * Response from the full endpoint. + */ +export interface IBlockWithMetadata { + /** + * The block. + */ + block: Block; + /** + * The block metadata. + */ + metadata: IBlockMetadata; +} diff --git a/bindings/python/iota_sdk/client/_node_core_api.py b/bindings/python/iota_sdk/client/_node_core_api.py index bf6cf14bca..b48a59798f 100644 --- a/bindings/python/iota_sdk/client/_node_core_api.py +++ b/bindings/python/iota_sdk/client/_node_core_api.py @@ -6,7 +6,7 @@ from dacite import from_dict from iota_sdk.types.block.signed_block import SignedBlock -from iota_sdk.types.block.metadata import BlockMetadata +from iota_sdk.types.block.metadata import BlockMetadata, BlockWithMetadata from iota_sdk.types.common import HexStr from iota_sdk.types.node_info import NodeInfo, NodeInfoWrapper from iota_sdk.types.output_metadata import OutputWithMetadata, OutputMetadata @@ -102,6 +102,13 @@ def get_block_metadata(self, block_id: HexStr) -> BlockMetadata: 'blockId': block_id })) + def get_block_with_metadata(self, block_id: HexStr) -> BlockWithMetadata: + """Get a block with its metadata corresponding to the given block id. + """ + return BlockWithMetadata.from_dict(self._call_method('getBlockWithMetadata', { + 'blockId': block_id + })) + def get_block_raw(self, block_id: HexStr) -> List[int]: """Get the raw bytes of the block corresponding to the given block id. """ diff --git a/bindings/python/iota_sdk/types/block/metadata.py b/bindings/python/iota_sdk/types/block/metadata.py index de34a46e6d..ae313ecd73 100644 --- a/bindings/python/iota_sdk/types/block/metadata.py +++ b/bindings/python/iota_sdk/types/block/metadata.py @@ -6,6 +6,8 @@ from dataclasses import dataclass from typing import Optional from iota_sdk.types.common import HexStr, json +# TODO rename change to Block +from iota_sdk.types.block.signed_block import SignedBlock @json @@ -182,3 +184,17 @@ def __str__(self): 26: "Destruction of nfts is not allowed in the transaction capabilities.", 255: "The semantic validation failed for a reason not covered by the previous variants." }[self.value] + + +@json +@dataclass +class BlockWithMetadata: + """Represents a block with its metadata. + Response of GET /api/core/v3/blocks/{blockId}/full. + + Attributes: + block: The block. + metadata: The block metadata. + """ + block: SignedBlock + metadata: BlockMetadata diff --git a/sdk/src/client/node_api/core/routes.rs b/sdk/src/client/node_api/core/routes.rs index 5420251a37..06916d35a9 100644 --- a/sdk/src/client/node_api/core/routes.rs +++ b/sdk/src/client/node_api/core/routes.rs @@ -16,9 +16,9 @@ use crate::{ }, types::{ api::core::{ - BlockMetadataResponse, CommitteeResponse, CongestionResponse, InfoResponse, IssuanceBlockHeaderResponse, - ManaRewardsResponse, PeerResponse, RoutesResponse, SubmitBlockResponse, UtxoChangesResponse, - ValidatorResponse, ValidatorsResponse, + BlockMetadataResponse, BlockWithMetadataResponse, CommitteeResponse, CongestionResponse, InfoResponse, + IssuanceBlockHeaderResponse, ManaRewardsResponse, PeerResponse, RoutesResponse, SubmitBlockResponse, + UtxoChangesResponse, ValidatorResponse, ValidatorsResponse, }, block::{ address::ToBech32Ext, @@ -222,6 +222,14 @@ impl ClientInner { self.get_request(path, None, true, true).await } + /// Returns a block with its metadata. + /// GET /api/core/v3/blocks/{blockId}/full + pub async fn get_block_with_metadata(&self, block_id: &BlockId) -> Result { + let path = &format!("api/core/v3/blocks/{block_id}/full"); + + self.get_request(path, None, true, true).await + } + // UTXO routes. /// Finds an output by its ID and returns it as object. diff --git a/sdk/src/types/api/core.rs b/sdk/src/types/api/core.rs index d8449f01bc..e2c6c0af24 100644 --- a/sdk/src/types/api/core.rs +++ b/sdk/src/types/api/core.rs @@ -14,11 +14,11 @@ use crate::{ types::block::{ address::Bech32Address, core::Parents, - output::{dto::OutputDto, AccountId, OutputId, OutputMetadata, OutputWithMetadata}, + output::{dto::OutputDto, OutputId, OutputMetadata, OutputWithMetadata}, protocol::{ProtocolParameters, ProtocolParametersHash}, semantic::TransactionFailureReason, slot::{EpochIndex, SlotCommitment, SlotCommitmentId, SlotIndex}, - BlockId, + BlockDto, BlockId, }, utils::serde::{option_string, string}, }; @@ -404,6 +404,14 @@ pub struct BlockMetadataResponse { pub transaction_failure_reason: Option, } +/// Response of GET /api/core/v3/blocks/{blockId}/full. +/// Returns a block and its metadata. +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +pub struct BlockWithMetadataResponse { + pub block: BlockDto, + pub metadata: BlockMetadataResponse, +} + /// Response of GET /api/core/v3/outputs/{output_id}. /// Returns an output and its metadata. #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] diff --git a/sdk/src/wallet/update.rs b/sdk/src/wallet/update.rs index 77ce6f8622..820dd663eb 100644 --- a/sdk/src/wallet/update.rs +++ b/sdk/src/wallet/update.rs @@ -5,10 +5,7 @@ use std::collections::HashMap; use crate::{ client::secret::SecretManage, - types::{ - api::core::OutputWithMetadataResponse, - block::output::{OutputId, OutputMetadata}, - }, + types::block::output::{OutputId, OutputMetadata}, wallet::{ types::{InclusionState, OutputData, TransactionWithMetadata}, Wallet, @@ -16,6 +13,7 @@ use crate::{ }; #[cfg(feature = "events")] use crate::{ + types::api::core::OutputWithMetadataResponse, types::block::payload::signed_transaction::dto::SignedTransactionPayloadDto, wallet::{ events::types::{NewOutputEvent, SpentOutputEvent, TransactionInclusionEvent, WalletEvent},