diff --git a/api/endpoints.go b/api/endpoints.go index f8dd4676..ad772011 100644 --- a/api/endpoints.go +++ b/api/endpoints.go @@ -191,6 +191,13 @@ const ( // MIMEApplicationVendorIOTASerializerV2 => bytes. CoreEndpointOutputWithMetadata = "/outputs/{outputId}/full" + // CoreEndpointTransaction is the endpoint for getting a transaction by its transaction ID. + // GET returns the transaction. + // "Accept" header: + // MIMEApplicationJSON => json. + // MIMEApplicationVendorIOTASerializerV2 => bytes. + CoreEndpointTransaction = "/transactions/{transactionId}" + // CoreEndpointTransactionsIncludedBlock is the endpoint for getting the block that was first confirmed for a given transaction ID. // GET returns the block. // "Accept" header: @@ -303,6 +310,7 @@ var ( CoreRouteOutput = route(CorePluginName, CoreEndpointOutput) CoreRouteOutputMetadata = route(CorePluginName, CoreEndpointOutputMetadata) CoreRouteOutputWithMetadata = route(CorePluginName, CoreEndpointOutputWithMetadata) + CoreRouteTransaction = route(CorePluginName, CoreEndpointTransaction) CoreRouteTransactionsIncludedBlock = route(CorePluginName, CoreEndpointTransactionsIncludedBlock) CoreRouteTransactionsIncludedBlockMetadata = route(CorePluginName, CoreEndpointTransactionsIncludedBlockMetadata) CoreRouteTransactionsMetadata = route(CorePluginName, CoreEndpointTransactionsMetadata) diff --git a/nodeclient/http_api_client.go b/nodeclient/http_api_client.go index 7635e0f8..262e74d7 100644 --- a/nodeclient/http_api_client.go +++ b/nodeclient/http_api_client.go @@ -450,6 +450,24 @@ func (client *Client) OutputWithMetadataByID(ctx context.Context, outputID iotag return outputResponse.Output, outputResponse.Metadata, nil } +// TransactionByID gets a transaction by its ID from the node. +func (client *Client) TransactionByID(ctx context.Context, txID iotago.TransactionID) (*iotago.Transaction, error) { + query := client.endpointReplaceTransactionIDParameter(api.CoreRouteTransaction, txID) + + res := new(RawDataEnvelope) + //nolint:bodyclose + if _, err := client.DoWithRequestHeaderHook(ctx, http.MethodGet, query, RequestHeaderHookAcceptIOTASerializerV2, nil, res); err != nil { + return nil, err + } + + tx := new(iotago.Transaction) + if _, err := client.CommittedAPI().Decode(res.Data, tx, serix.WithValidation()); err != nil { + return nil, err + } + + return tx, nil +} + // TransactionIncludedBlock get a block that included the given transaction ID in the ledger. func (client *Client) TransactionIncludedBlock(ctx context.Context, txID iotago.TransactionID) (*iotago.Block, error) { query := client.endpointReplaceTransactionIDParameter(api.CoreRouteTransactionsIncludedBlock, txID) diff --git a/nodeclient/http_api_client_test.go b/nodeclient/http_api_client_test.go index 927b249a..ad5cc658 100644 --- a/nodeclient/http_api_client_test.go +++ b/nodeclient/http_api_client_test.go @@ -463,6 +463,28 @@ func TestClient_OutputWithMetadataByID(t *testing.T) { require.EqualValues(t, originMetadata, responseMetadata) } +func TestClient_TestTransactionByID(t *testing.T) { + defer gock.Off() + + txID := tpkg.RandTransactionID() + + originTransaction := tpkg.RandTransaction(mockAPI) + + mockGetBinary(api.EndpointWithNamedParameterValue(api.CoreRouteTransaction, api.ParameterTransactionID, txID.ToHex()), 200, originTransaction) + + nodeAPI := nodeClient(t) + responseTransaction, err := nodeAPI.TransactionByID(context.Background(), txID) + require.NoError(t, err) + + originTransactionBytes, err := mockAPI.Encode(originTransaction, serix.WithValidation()) + require.NoError(t, err) + + responseTransactionBytes, err := mockAPI.Encode(responseTransaction, serix.WithValidation()) + require.NoError(t, err) + + require.Equal(t, originTransactionBytes, responseTransactionBytes) +} + func TestClient_TransactionIncludedBlock(t *testing.T) { defer gock.Off()