diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c410af801c..6173927ac3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -233,6 +233,39 @@ jobs: # Might be set to warn for debugging purposes. Warning, log file will be huge. RADIXDLT_LOG_LEVEL: error run: ./gradlew clean runTargetedIntegrationTests --info --refresh-dependencies --parallel + mesh-api-test-suite: + name: Run Mesh API tests + runs-on: selfhosted-ubuntu-22.04-16-cores + steps: + - uses: RDXWorks-actions/checkout@main + with: + # Shallow clones should be disabled for a better relevancy of analysis + fetch-depth: 0 + - name: Setup environment + uses: ./.github/actions/setup-env + - name: Cache Gradle packages + uses: RDXWorks-actions/cache@main + with: + path: ~/.gradle/caches + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} + restore-keys: ${{ runner.os }}-gradle + - name: Build Node + run: ./gradlew build + - name: Run Node in the background + env: + # This is to skip keygen step + RADIXDLT_NODE_KEY: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY= + run: ./gradlew :core:run --info & + - name: Wait for 2 minutes + run: sleep 2m + - name: Install mesh-cli + run: curl -sSfL https://raw.githubusercontent.com/coinbase/mesh-cli/master/scripts/install.sh | sh -s + - name: Run Data API tests + run: ./bin/rosetta-cli check:data --configuration-file core-rust/mesh-api-server/mesh-cli-configs/default.json + - name: Run Construction API tests + run: ./bin/rosetta-cli check:construction --configuration-file core-rust/mesh-api-server/mesh-cli-configs/default.json + - name: Run Coinbase-spec tests + run: ./bin/rosetta-cli check:spec --configuration-file core-rust/mesh-api-server/mesh-cli-configs/default.json cross-xwin: name: Cross compile to Windows runs-on: ubuntu-latest diff --git a/Dockerfile b/Dockerfile index eeadd6f88c..fe13793d12 100644 --- a/Dockerfile +++ b/Dockerfile @@ -178,12 +178,14 @@ RUN USER=root "$HOME/.cargo/bin/cargo" init --lib --name dummy --vcs none . \ && mkdir -p ./node-common/src \ && mkdir -p ./state-manager/src \ && mkdir -p ./p2p/src \ + && mkdir -p ./mesh-api-server/src \ && touch ./core-api-server/src/lib.rs \ && touch ./engine-state-api-server/src/lib.rs \ && touch ./jni-export/src/lib.rs \ && touch ./node-common/src/lib.rs \ && touch ./state-manager/src/lib.rs \ - && touch ./p2p/src/lib.rs + && touch ./p2p/src/lib.rs \ + && touch ./mesh-api-server/src/lib.rs COPY core-rust/Cargo.toml ./ COPY core-rust/Cargo.lock ./ COPY core-rust/core-api-server/Cargo.toml ./core-api-server @@ -192,6 +194,7 @@ COPY core-rust/jni-export/Cargo.toml ./jni-export COPY core-rust/node-common/Cargo.toml ./node-common COPY core-rust/state-manager/Cargo.toml ./state-manager COPY core-rust/p2p/Cargo.toml ./p2p +COPY core-rust/mesh-api-server/Cargo.toml ./mesh-api-server COPY docker/build_scripts/cargo_build_by_platform.sh /opt/radixdlt/cargo_build_by_platform.sh @@ -210,7 +213,7 @@ RUN --mount=type=cache,id=radixdlt-babylon-node-rust-cache,target=/root/.cache/s FROM library-build-stage-cache-packages AS library-build-stage # Tidy up from the previous layer -RUN rm -rf core-api-server engine-state-api-server jni-export node-common state-manager +RUN rm -rf core-api-server engine-state-api-server jni-export node-common state-manager mesh-api-server # Copy across all the code (docker ignore excepted) COPY core-rust ./ @@ -309,6 +312,8 @@ ENV RADIXDLT_HOME=/home/radixdlt \ RADIXDLT_PROMETHEUS_API_BIND_ADDRESS=0.0.0.0 \ RADIXDLT_ENGINE_STATE_API_PORT=3336 \ RADIXDLT_ENGINE_STATE_API_BIND_ADDRESS=0.0.0.0 \ + RADIXDLT_MESH_API_PORT=3337 \ + RADIXDLT_MESH_API_BIND_ADDRESS=0.0.0.0 \ RADIXDLT_NETWORK_ID=240 \ RADIXDLT_NODE_KEY_CREATE_IF_MISSING=false diff --git a/core-rust-bridge/src/main/java/com/radixdlt/api/MeshApiServer.java b/core-rust-bridge/src/main/java/com/radixdlt/api/MeshApiServer.java new file mode 100644 index 0000000000..9784b3d87c --- /dev/null +++ b/core-rust-bridge/src/main/java/com/radixdlt/api/MeshApiServer.java @@ -0,0 +1,107 @@ +/* Copyright 2021 Radix Publishing Ltd incorporated in Jersey (Channel Islands). + * + * Licensed under the Radix License, Version 1.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at: + * + * radixfoundation.org/licenses/LICENSE-v1 + * + * The Licensor hereby grants permission for the Canonical version of the Work to be + * published, distributed and used under or by reference to the Licensor’s trademark + * Radix ® and use of any unregistered trade names, logos or get-up. + * + * The Licensor provides the Work (and each Contributor provides its Contributions) on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, + * including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, + * MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. + * + * Whilst the Work is capable of being deployed, used and adopted (instantiated) to create + * a distributed ledger it is your responsibility to test and validate the code, together + * with all logic and performance of that code under all foreseeable scenarios. + * + * The Licensor does not make or purport to make and hereby excludes liability for all + * and any representation, warranty or undertaking in any form whatsoever, whether express + * or implied, to any entity or person, including any representation, warranty or + * undertaking, as to the functionality security use, value or other characteristics of + * any distributed ledger nor in respect the functioning or value of any tokens which may + * be created stored or transferred using the Work. The Licensor does not warrant that the + * Work or any use of the Work complies with any law or regulation in any territory where + * it may be implemented or used or that it will be appropriate for any specific purpose. + * + * Neither the licensor nor any current or former employees, officers, directors, partners, + * trustees, representatives, agents, advisors, contractors, or volunteers of the Licensor + * shall be liable for any direct or indirect, special, incidental, consequential or other + * losses of any kind, in tort, contract or otherwise (including but not limited to loss + * of revenue, income or profits, or loss of use or data, or loss of reputation, or loss + * of any economic or other opportunity of whatsoever nature or howsoever arising), arising + * out of or in connection with (without limitation of any use, misuse, of any ledger system + * or use made or its functionality or any performance or operation of any code or protocol + * caused by bugs or programming or logic errors or otherwise); + * + * A. any offer, purchase, holding, use, sale, exchange or transmission of any + * cryptographic keys, tokens or assets created, exchanged, stored or arising from any + * interaction with the Work; + * + * B. any failure in a transmission or loss of any token or assets keys or other digital + * artefacts due to errors in transmission; + * + * C. bugs, hacks, logic errors or faults in the Work or any communication; + * + * D. system software or apparatus including but not limited to losses caused by errors + * in holding or transmitting tokens by any third-party; + * + * E. breaches or failure of security including hacker attacks, loss or disclosure of + * password, loss of private key, unauthorised use or misuse of such passwords or keys; + * + * F. any losses including loss of anticipated savings or other benefits resulting from + * use of the Work or any changes to the Work (however implemented). + * + * You are solely responsible for; testing, validating and evaluation of all operation + * logic, functionality, security and appropriateness of using the Work for any commercial + * or non-commercial purpose and for any reproduction or redistribution by You of the + * Work. You assume all risks associated with Your use of the Work and the exercise of + * permissions under this License. + */ + +package com.radixdlt.api; + +import com.google.common.reflect.TypeToken; +import com.radixdlt.environment.MeshApiServerConfig; +import com.radixdlt.environment.NodeRustEnvironment; +import com.radixdlt.sbor.NodeSborCodecs; + +public final class MeshApiServer { + + static { + System.loadLibrary("corerust"); + } + + /** A pointer to the owned Rust structure. */ + @SuppressWarnings("unused") + private final long rustMeshApiServerPointer = 0; + + public static MeshApiServer create( + NodeRustEnvironment nodeRustEnvironment, MeshApiServerConfig config) { + return new MeshApiServer(nodeRustEnvironment, config); + } + + MeshApiServer(NodeRustEnvironment nodeRustEnvironment, MeshApiServerConfig config) { + final var encodedConfig = + NodeSborCodecs.encode(config, NodeSborCodecs.resolveCodec(new TypeToken<>() {})); + init(nodeRustEnvironment, this, encodedConfig); + } + + public void start() { + start(this); + } + + public void stop() { + stop(this); + } + + private static native void init( + NodeRustEnvironment nodeRustEnvironment, MeshApiServer meshApiServer, byte[] config); + + private static native void start(MeshApiServer meshApiServer); + + private static native void stop(MeshApiServer meshApiServer); +} diff --git a/core-rust-bridge/src/main/java/com/radixdlt/api/MeshApiServerModule.java b/core-rust-bridge/src/main/java/com/radixdlt/api/MeshApiServerModule.java new file mode 100644 index 0000000000..80c10ebaee --- /dev/null +++ b/core-rust-bridge/src/main/java/com/radixdlt/api/MeshApiServerModule.java @@ -0,0 +1,96 @@ +/* Copyright 2021 Radix Publishing Ltd incorporated in Jersey (Channel Islands). + * + * Licensed under the Radix License, Version 1.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at: + * + * radixfoundation.org/licenses/LICENSE-v1 + * + * The Licensor hereby grants permission for the Canonical version of the Work to be + * published, distributed and used under or by reference to the Licensor’s trademark + * Radix ® and use of any unregistered trade names, logos or get-up. + * + * The Licensor provides the Work (and each Contributor provides its Contributions) on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, + * including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, + * MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. + * + * Whilst the Work is capable of being deployed, used and adopted (instantiated) to create + * a distributed ledger it is your responsibility to test and validate the code, together + * with all logic and performance of that code under all foreseeable scenarios. + * + * The Licensor does not make or purport to make and hereby excludes liability for all + * and any representation, warranty or undertaking in any form whatsoever, whether express + * or implied, to any entity or person, including any representation, warranty or + * undertaking, as to the functionality security use, value or other characteristics of + * any distributed ledger nor in respect the functioning or value of any tokens which may + * be created stored or transferred using the Work. The Licensor does not warrant that the + * Work or any use of the Work complies with any law or regulation in any territory where + * it may be implemented or used or that it will be appropriate for any specific purpose. + * + * Neither the licensor nor any current or former employees, officers, directors, partners, + * trustees, representatives, agents, advisors, contractors, or volunteers of the Licensor + * shall be liable for any direct or indirect, special, incidental, consequential or other + * losses of any kind, in tort, contract or otherwise (including but not limited to loss + * of revenue, income or profits, or loss of use or data, or loss of reputation, or loss + * of any economic or other opportunity of whatsoever nature or howsoever arising), arising + * out of or in connection with (without limitation of any use, misuse, of any ledger system + * or use made or its functionality or any performance or operation of any code or protocol + * caused by bugs or programming or logic errors or otherwise); + * + * A. any offer, purchase, holding, use, sale, exchange or transmission of any + * cryptographic keys, tokens or assets created, exchanged, stored or arising from any + * interaction with the Work; + * + * B. any failure in a transmission or loss of any token or assets keys or other digital + * artefacts due to errors in transmission; + * + * C. bugs, hacks, logic errors or faults in the Work or any communication; + * + * D. system software or apparatus including but not limited to losses caused by errors + * in holding or transmitting tokens by any third-party; + * + * E. breaches or failure of security including hacker attacks, loss or disclosure of + * password, loss of private key, unauthorised use or misuse of such passwords or keys; + * + * F. any losses including loss of anticipated savings or other benefits resulting from + * use of the Work or any changes to the Work (however implemented). + * + * You are solely responsible for; testing, validating and evaluation of all operation + * logic, functionality, security and appropriateness of using the Work for any commercial + * or non-commercial purpose and for any reproduction or redistribution by You of the + * Work. You assume all risks associated with Your use of the Work and the exercise of + * permissions under this License. + */ + +package com.radixdlt.api; + +import com.google.inject.AbstractModule; +import com.google.inject.Provides; +import com.google.inject.Singleton; +import com.google.inject.multibindings.ProvidesIntoSet; +import com.radixdlt.environment.MeshApiServerConfig; +import com.radixdlt.environment.NodeAutoCloseable; +import com.radixdlt.environment.NodeRustEnvironment; +import com.radixdlt.utils.UInt32; + +public final class MeshApiServerModule extends AbstractModule { + + private final MeshApiServerConfig config; + + public MeshApiServerModule(String apiBindAddress, int apiPort, String nodeDisplayVersion) { + this.config = + new MeshApiServerConfig( + apiBindAddress, UInt32.fromNonNegativeInt(apiPort), nodeDisplayVersion); + } + + @Provides + @Singleton + private MeshApiServer meshApiServer(NodeRustEnvironment nodeRustEnvironment) { + return MeshApiServer.create(nodeRustEnvironment, config); + } + + @ProvidesIntoSet + NodeAutoCloseable closeable(MeshApiServer meshApiServer) { + return meshApiServer::stop; + } +} diff --git a/core-rust-bridge/src/main/java/com/radixdlt/environment/MeshApiServerConfig.java b/core-rust-bridge/src/main/java/com/radixdlt/environment/MeshApiServerConfig.java new file mode 100644 index 0000000000..f2c3c8c619 --- /dev/null +++ b/core-rust-bridge/src/main/java/com/radixdlt/environment/MeshApiServerConfig.java @@ -0,0 +1,77 @@ +/* Copyright 2021 Radix Publishing Ltd incorporated in Jersey (Channel Islands). + * + * Licensed under the Radix License, Version 1.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at: + * + * radixfoundation.org/licenses/LICENSE-v1 + * + * The Licensor hereby grants permission for the Canonical version of the Work to be + * published, distributed and used under or by reference to the Licensor’s trademark + * Radix ® and use of any unregistered trade names, logos or get-up. + * + * The Licensor provides the Work (and each Contributor provides its Contributions) on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, + * including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, + * MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. + * + * Whilst the Work is capable of being deployed, used and adopted (instantiated) to create + * a distributed ledger it is your responsibility to test and validate the code, together + * with all logic and performance of that code under all foreseeable scenarios. + * + * The Licensor does not make or purport to make and hereby excludes liability for all + * and any representation, warranty or undertaking in any form whatsoever, whether express + * or implied, to any entity or person, including any representation, warranty or + * undertaking, as to the functionality security use, value or other characteristics of + * any distributed ledger nor in respect the functioning or value of any tokens which may + * be created stored or transferred using the Work. The Licensor does not warrant that the + * Work or any use of the Work complies with any law or regulation in any territory where + * it may be implemented or used or that it will be appropriate for any specific purpose. + * + * Neither the licensor nor any current or former employees, officers, directors, partners, + * trustees, representatives, agents, advisors, contractors, or volunteers of the Licensor + * shall be liable for any direct or indirect, special, incidental, consequential or other + * losses of any kind, in tort, contract or otherwise (including but not limited to loss + * of revenue, income or profits, or loss of use or data, or loss of reputation, or loss + * of any economic or other opportunity of whatsoever nature or howsoever arising), arising + * out of or in connection with (without limitation of any use, misuse, of any ledger system + * or use made or its functionality or any performance or operation of any code or protocol + * caused by bugs or programming or logic errors or otherwise); + * + * A. any offer, purchase, holding, use, sale, exchange or transmission of any + * cryptographic keys, tokens or assets created, exchanged, stored or arising from any + * interaction with the Work; + * + * B. any failure in a transmission or loss of any token or assets keys or other digital + * artefacts due to errors in transmission; + * + * C. bugs, hacks, logic errors or faults in the Work or any communication; + * + * D. system software or apparatus including but not limited to losses caused by errors + * in holding or transmitting tokens by any third-party; + * + * E. breaches or failure of security including hacker attacks, loss or disclosure of + * password, loss of private key, unauthorised use or misuse of such passwords or keys; + * + * F. any losses including loss of anticipated savings or other benefits resulting from + * use of the Work or any changes to the Work (however implemented). + * + * You are solely responsible for; testing, validating and evaluation of all operation + * logic, functionality, security and appropriateness of using the Work for any commercial + * or non-commercial purpose and for any reproduction or redistribution by You of the + * Work. You assume all risks associated with Your use of the Work and the exercise of + * permissions under this License. + */ + +package com.radixdlt.environment; + +import com.radixdlt.sbor.codec.CodecMap; +import com.radixdlt.sbor.codec.StructCodec; +import com.radixdlt.utils.UInt32; + +public record MeshApiServerConfig(String bindInterface, UInt32 port, String nodeDisplayVersion) { + public static void registerCodec(CodecMap codecMap) { + codecMap.register( + MeshApiServerConfig.class, + codecs -> StructCodec.fromRecordComponents(MeshApiServerConfig.class, codecs)); + } +} diff --git a/core-rust-bridge/src/main/java/com/radixdlt/sbor/NodeSborCodecs.java b/core-rust-bridge/src/main/java/com/radixdlt/sbor/NodeSborCodecs.java index ac96a865a4..2eb8ef70dc 100644 --- a/core-rust-bridge/src/main/java/com/radixdlt/sbor/NodeSborCodecs.java +++ b/core-rust-bridge/src/main/java/com/radixdlt/sbor/NodeSborCodecs.java @@ -196,6 +196,7 @@ public static void registerCodecsWithCodecMap(CodecMap codecMap) { CoreApiServerConfig.registerCodec(codecMap); CoreApiServerFlags.registerCodec(codecMap); EngineStateApiServerConfig.registerCodec(codecMap); + MeshApiServerConfig.registerCodec(codecMap); ValidatorInfo.registerCodec(codecMap); GenesisData.registerCodec(codecMap); GenesisConsensusManagerConfig.registerCodec(codecMap); diff --git a/core-rust/Cargo.lock b/core-rust/Cargo.lock index 10a73a67c7..0f991820e4 100644 --- a/core-rust/Cargo.lock +++ b/core-rust/Cargo.lock @@ -1154,6 +1154,7 @@ dependencies = [ "core-api-server", "engine-state-api-server", "jni", + "mesh-api-server", "node-common", "radix-common", "radix-engine", @@ -1327,6 +1328,48 @@ dependencies = [ "autocfg", ] +[[package]] +name = "mesh-api-server" +version = "0.1.0" +dependencies = [ + "axum", + "blake2", + "chrono", + "convert_case", + "futures", + "futures-util", + "hex", + "hyper", + "itertools", + "jni", + "lazy_static", + "node-common", + "paste", + "prometheus", + "radix-blueprint-schema-init", + "radix-common", + "radix-engine", + "radix-engine-interface", + "radix-rust", + "radix-substate-store-impls", + "radix-substate-store-interface", + "radix-substate-store-queries", + "radix-transactions", + "rand", + "regex", + "sbor", + "serde", + "serde_json", + "serde_with 2.3.0", + "state-manager", + "strum", + "strum_macros", + "tokio", + "tower", + "tower-http", + "tracing", +] + [[package]] name = "mime" version = "0.3.17" diff --git a/core-rust/Cargo.toml b/core-rust/Cargo.toml index d4955f2944..398837d9a1 100644 --- a/core-rust/Cargo.toml +++ b/core-rust/Cargo.toml @@ -5,6 +5,7 @@ members = [ "core-api-server", "engine-state-api-server", "state-manager", + "mesh-api-server" ] resolver = "2" @@ -15,7 +16,7 @@ resolver = "2" # ================================================================ # # To make builds reproducible, we must specify a fixed tag below, not a branch. -# +# # Go to your checkout of `radixdlt-scrypto`, then run the following: # $ git checkout # $ git pull @@ -59,6 +60,11 @@ tower = { version = "=0.4.13" } tower-http = { version = "=0.4.3", features = ["catch-panic"]} hyper = { version = "=0.14.27", features = ["server", "http1"] } paste = { version = "=1.0.14", default-features = false } +strum = { version = "=0.24.1", features = ["derive"] } +strum_macros = { version = "=0.24.3" } +convert_case = { version = "=0.6.0" } +regex = { version = "=1.9.3"} +lazy_static = { version = "=1.4.0" } [profile.dev] opt-level = 3 diff --git a/core-rust/core-api-server/src/core_api/conversions/lts.rs b/core-rust/core-api-server/src/core_api/conversions/lts.rs index 84e44cc80e..4375cfd67d 100644 --- a/core-rust/core-api-server/src/core_api/conversions/lts.rs +++ b/core-rust/core-api-server/src/core_api/conversions/lts.rs @@ -112,13 +112,13 @@ pub fn to_api_lts_fungible_balance_changes( balance_changes: &IndexMap>, ) -> Result, MappingError> { let fee_balance_changes = resolve_global_fee_balance_changes(database, fee_source)?; - FeePaymentComputer::compute(FeePaymentComputationInputs { + let fee_payment_computations = FeePaymentComputer::compute(FeePaymentComputationInputs { fee_balance_changes, fee_summary, fee_destination, balance_changes, - }) - .resolve_fungible_balance_changes(context) + }); + resolve_fungible_balance_changes(&fee_payment_computations, context) } /// Uses the [`SubstateNodeAncestryStore`] (from the given DB) to transform the input @@ -143,242 +143,100 @@ fn resolve_global_fee_balance_changes( Ok(fee_balance_changes) } -struct FeePaymentComputer<'a> { - inputs: FeePaymentComputationInputs<'a>, - computation: FeePaymentComputation, -} - -struct FeePaymentComputationInputs<'a> { - /// The balance changes caused by [`FeeSource#paying_vaults`] (resolved to global ancestors). - /// Note: this information is logically of the same type as [`balance_changes`], but the actual - /// signature is simpler, since all fees are necessarily XRD and thus have fungible balances. - fee_balance_changes: IndexMap, - fee_summary: &'a TransactionFeeSummary, - fee_destination: &'a FeeDestination, - /// The total balance changes (i.e. including the [`fee_balance_changes`]). - balance_changes: &'a IndexMap>, -} - -struct FeePaymentComputation { - relevant_entities: IndexSet, - fee_balance_changes: - NonIterMap>, - non_fee_balance_changes: NonIterMap>, -} - -impl<'a> FeePaymentComputer<'a> { - pub fn compute(inputs: FeePaymentComputationInputs<'a>) -> FeePaymentComputation { - Self { - inputs, - computation: FeePaymentComputation { - relevant_entities: Default::default(), - fee_balance_changes: Default::default(), - non_fee_balance_changes: Default::default(), - }, +fn to_api_lts_fee_fungible_resource_balance_change_type( + fee_type: &FeePaymentBalanceChangeType, +) -> models::LtsFeeFungibleResourceBalanceChangeType { + match fee_type { + FeePaymentBalanceChangeType::FeePayment => { + models::LtsFeeFungibleResourceBalanceChangeType::FeePayment } - .compute_internal() - } - - fn compute_internal(mut self) -> FeePaymentComputation { - // Step 1 - Add initial relevant entities - self.add_initial_ordered_relevant_entities(); - - // Step 2 - Track fee balance changes - self.track_fee_payments(); - self.track_fee_distributions(); - self.track_royalty_distributions(); - - // Step 3 - Compute resultant non-fee balance changes - self.finalize_non_fee_balance_changes(); - - // And finally, return the outputs - self.computation - } - - fn add_initial_ordered_relevant_entities(&mut self) { - for entity in self.inputs.balance_changes.keys() { - self.computation.relevant_entities.insert(*entity); + FeePaymentBalanceChangeType::FeeDistributed => { + models::LtsFeeFungibleResourceBalanceChangeType::FeeDistributed } - } - - fn track_fee_payments(&mut self) { - for (fee_payer, fee_balance_change) in self.inputs.fee_balance_changes.clone() { - self.record_fee_balance_change_if_non_zero( - fee_payer, - fee_balance_change, - models::LtsFeeFungibleResourceBalanceChangeType::FeePayment, - ); + FeePaymentBalanceChangeType::TipDistributed => { + models::LtsFeeFungibleResourceBalanceChangeType::TipDistributed } - } - - fn track_fee_distributions(&mut self) { - self.record_fee_balance_change_if_non_zero( - CONSENSUS_MANAGER.into(), - self.inputs - .fee_summary - .network_fees() - .sub_or_panic(self.inputs.fee_destination.to_burn), - models::LtsFeeFungibleResourceBalanceChangeType::FeeDistributed, - ); - self.record_fee_balance_change_if_non_zero( - CONSENSUS_MANAGER.into(), - self.inputs.fee_summary.total_tipping_cost_in_xrd, - models::LtsFeeFungibleResourceBalanceChangeType::TipDistributed, - ); - } - - fn track_royalty_distributions(&mut self) { - for (recipient, amount) in &self.inputs.fee_destination.to_royalty_recipients { - let recipient: GlobalAddress = match recipient { - RoyaltyRecipient::Package(address, _) => (*address).into(), - RoyaltyRecipient::Component(address, _) => (*address).into(), - }; - self.record_fee_balance_change_if_non_zero( - recipient, - *amount, - models::LtsFeeFungibleResourceBalanceChangeType::RoyaltyDistributed, - ); + FeePaymentBalanceChangeType::RoyaltyDistributed => { + models::LtsFeeFungibleResourceBalanceChangeType::RoyaltyDistributed } } +} - fn record_fee_balance_change_if_non_zero( - &mut self, - address: GlobalAddress, - balance_change: Decimal, - fee_type: models::LtsFeeFungibleResourceBalanceChangeType, - ) { - if balance_change == Decimal::ZERO { - return; - } - // This handles the case that a relevant entity had 0 net balance change. - // For example, if a component received a royalty and output XRD equal to that royalty in the same transaction then - // it wouldn't be in the balance changes - but we'd still want to include it in our output. - self.computation.relevant_entities.insert(address); - self.computation +fn resolve_fungible_balance_changes( + fee_payment_computation: &FeePaymentComputation, + context: &MappingContext, +) -> Result, MappingError> { + let mut output = Vec::with_capacity(fee_payment_computation.relevant_entities.len()); + for entity in &fee_payment_computation.relevant_entities { + // First - calculate the deprecated/duplicated total balance change + let deprecated_fee_payment_balance_change = fee_payment_computation .fee_balance_changes - .entry(address) - .or_default() - .push((fee_type, balance_change)); - } - - fn finalize_non_fee_balance_changes(&mut self) { - for (entity, changes) in self.inputs.balance_changes { - let total_fee_balance_changes: Decimal = self - .computation + .get(&entity) + .map(|fee_changes| { + let total_fee_payment_balance_change = fee_changes + .iter() + .filter_map(|fee_balance_change| match &fee_balance_change.0 { + FeePaymentBalanceChangeType::FeePayment => Some(fee_balance_change.1), + _ => None, + }) + .sum_or_panic(); + let output = if total_fee_payment_balance_change.is_zero() { + None + } else { + Some(Box::new(to_api_lts_fungible_resource_balance_change( + context, + &XRD, + &total_fee_payment_balance_change, + )?)) + }; + Ok(output) + }) + .transpose()? + .flatten(); + output.push(models::LtsEntityFungibleBalanceChanges { + entity_address: to_api_global_address(context, &entity)?, + fee_balance_change: deprecated_fee_payment_balance_change, + fee_balance_changes: fee_payment_computation .fee_balance_changes - .get(entity) - .map(|fee_payments| fee_payments.iter().map(|p| p.1).sum_or_panic()) - .unwrap_or_default(); - let mut non_fee_balance_changes: IndexMap = changes - .iter() - .filter_map(|(resource, balance_change)| { - if resource == &XRD { - let total_balance_change = get_fungible_balance(balance_change) - .expect("Expected XRD to be fungible"); - let total_non_fee_balance_change = - total_balance_change.sub_or_panic(total_fee_balance_changes); - if total_non_fee_balance_change == Decimal::ZERO { - None - } else { - Some((*resource, total_non_fee_balance_change)) - } - } else { - match balance_change { - BalanceChange::Fungible(change) => Some((*resource, *change)), - BalanceChange::NonFungible { .. } => None, - } - } + .get(&entity) + .map(|fee_balance_changes| { + fee_balance_changes + .iter() + .map( + |(fee_change_type, balance_change)| -> Result<_, MappingError> { + Ok(models::LtsFeeFungibleResourceBalanceChange { + resource_address: to_api_resource_address(context, &XRD)?, + balance_change: to_api_decimal(balance_change), + _type: to_api_lts_fee_fungible_resource_balance_change_type( + fee_change_type, + ), + }) + }, + ) + .collect::>() }) - .collect(); - if total_fee_balance_changes != Decimal::ZERO && !changes.contains_key(&XRD) { - // If there were fee-related balance changes, but XRD is not in the balance change set, - // then there must have been an equal-and-opposite non-fee balance change to offset it - non_fee_balance_changes.insert(XRD, total_fee_balance_changes.neg_or_panic()); - } - self.computation + .transpose()? + .unwrap_or_default(), + non_fee_balance_changes: fee_payment_computation .non_fee_balance_changes - .insert(*entity, non_fee_balance_changes); - } - } -} - -impl FeePaymentComputation { - fn resolve_fungible_balance_changes( - self, - context: &MappingContext, - ) -> Result, MappingError> { - let mut output = Vec::with_capacity(self.relevant_entities.len()); - for entity in self.relevant_entities { - // First - calculate the deprecated/duplicated total balance change - let deprecated_fee_payment_balance_change = self - .fee_balance_changes .get(&entity) - .map(|fee_changes| { - let total_fee_payment_balance_change = fee_changes + .map(|non_fee_balance_changes| { + non_fee_balance_changes .iter() - .filter_map(|fee_balance_change| match &fee_balance_change.0 { - models::LtsFeeFungibleResourceBalanceChangeType::FeePayment => { - Some(fee_balance_change.1) - } - _ => None, + .map(|(resource_address, amount)| { + to_api_lts_fungible_resource_balance_change( + context, + resource_address, + amount, + ) }) - .sum_or_panic(); - let output = if total_fee_payment_balance_change.is_zero() { - None - } else { - Some(Box::new(to_api_lts_fungible_resource_balance_change( - context, - &XRD, - &total_fee_payment_balance_change, - )?)) - }; - Ok(output) + .collect::>() }) .transpose()? - .flatten(); - output.push(models::LtsEntityFungibleBalanceChanges { - entity_address: to_api_global_address(context, &entity)?, - fee_balance_change: deprecated_fee_payment_balance_change, - fee_balance_changes: self - .fee_balance_changes - .get(&entity) - .map(|fee_balance_changes| { - fee_balance_changes - .iter() - .map( - |(fee_change_type, balance_change)| -> Result<_, MappingError> { - Ok(models::LtsFeeFungibleResourceBalanceChange { - resource_address: to_api_resource_address(context, &XRD)?, - balance_change: to_api_decimal(balance_change), - _type: *fee_change_type, - }) - }, - ) - .collect::>() - }) - .transpose()? - .unwrap_or_default(), - non_fee_balance_changes: self - .non_fee_balance_changes - .get(&entity) - .map(|non_fee_balance_changes| { - non_fee_balance_changes - .iter() - .map(|(resource_address, amount)| { - to_api_lts_fungible_resource_balance_change( - context, - resource_address, - amount, - ) - }) - .collect::>() - }) - .transpose()? - .unwrap_or_default(), - }); - } - Ok(output) + .unwrap_or_default(), + }); } + Ok(output) } pub fn to_api_lts_fungible_resource_balance_change( @@ -415,13 +273,6 @@ pub fn to_api_lts_resultant_account_fungible_balances( .collect() } -pub fn get_fungible_balance(balance_change: &BalanceChange) -> Option { - match balance_change { - BalanceChange::Fungible(balance_change) => Some(*balance_change), - BalanceChange::NonFungible { .. } => None, - } -} - /// Retrofits the given transaction root, pretending it is an accumulator hash (for LTS purposes). /// The transaction root and accumulator hash encode the same information and have the same /// properties - only their computation differs. diff --git a/core-rust/core-api-server/src/core_api/conversions/numerics.rs b/core-rust/core-api-server/src/core_api/conversions/numerics.rs index 731cadefcd..ad2b03497d 100644 --- a/core-rust/core-api-server/src/core_api/conversions/numerics.rs +++ b/core-rust/core-api-server/src/core_api/conversions/numerics.rs @@ -1,6 +1,5 @@ use crate::prelude::*; use chrono::prelude::*; -use std::any::type_name; use std::ops::RangeInclusive; use crate::core_api::models; @@ -261,92 +260,6 @@ pub fn extract_u16_from_api_i32(input: i32) -> Result { Ok(input.try_into().expect("Number invalid somehow")) } -pub trait PanickingOps: Sized { - fn add_or_panic(self, rhs: Self) -> Self; - fn sub_or_panic(self, rhs: Self) -> Self; - fn mul_or_panic(self, rhs: Self) -> Self; - fn div_or_panic(self, rhs: Self) -> Self; - fn neg_or_panic(self) -> Self; -} - -impl PanickingOps for T -where - T: CheckedAdd - + CheckedSub - + CheckedDiv - + CheckedMul - + CheckedNeg - + Copy - + Display, -{ - fn add_or_panic(self, rhs: Self) -> Self { - op_or_panic(self, "+", rhs, self.checked_add(rhs)) - } - - fn sub_or_panic(self, rhs: Self) -> Self { - op_or_panic(self, "-", rhs, self.checked_sub(rhs)) - } - - fn mul_or_panic(self, rhs: Self) -> Self { - op_or_panic(self, "*", rhs, self.checked_mul(rhs)) - } - - fn div_or_panic(self, rhs: Self) -> Self { - op_or_panic(self, "/", rhs, self.checked_div(rhs)) - } - - fn neg_or_panic(self) -> Self { - if let Some(result) = self.checked_neg() { - result - } else { - panic!("result of -{} does not fit in {}", self, type_name::()); - } - } -} - -pub trait PanickingSumIterator { - fn sum_or_panic(self) -> E; -} - -impl PanickingSumIterator for T -where - T: Iterator, - E: Default + CheckedAdd + Copy + Display, -{ - fn sum_or_panic(self) -> E { - let mut result = E::default(); - for (index, element) in self.enumerate() { - let sum = result.checked_add(element); - if let Some(sum) = sum { - result = sum; - } else { - panic!( - "result of accumulating {}. element ({} + {}) does not fit in {}", - index, - result, - element, - type_name::() - ); - } - } - result - } -} - -fn op_or_panic(left: T, op: &str, right: T, result: Option) -> T { - if let Some(result) = result { - result - } else { - panic!( - "result of {} {} {} does not fit in {}", - left, - op, - right, - type_name::() - ); - } -} - #[cfg(test)] mod tests { use super::*; diff --git a/core-rust/core-api-server/src/core_api/conversions/substates/consensus_manager.rs b/core-rust/core-api-server/src/core_api/conversions/substates/consensus_manager.rs index 2097018bc2..8722bea83b 100644 --- a/core-rust/core-api-server/src/core_api/conversions/substates/consensus_manager.rs +++ b/core-rust/core-api-server/src/core_api/conversions/substates/consensus_manager.rs @@ -2,6 +2,7 @@ use super::super::*; use super::*; use crate::core_api::models; use crate::engine_prelude::*; +use crate::prelude::*; pub fn to_api_registered_validators_by_stake_index_entry_substate( context: &MappingContext, diff --git a/core-rust/jni-export/Cargo.toml b/core-rust/jni-export/Cargo.toml index f63fa08e88..041fff93fd 100644 --- a/core-rust/jni-export/Cargo.toml +++ b/core-rust/jni-export/Cargo.toml @@ -8,6 +8,7 @@ node-common = { path = "../node-common" } state-manager = { path = "../state-manager" } core-api-server = { path = "../core-api-server" } engine-state-api-server = { path = "../engine-state-api-server" } +mesh-api-server = { path = "../mesh-api-server" } sbor = { workspace = true } radix-transactions = { workspace = true } diff --git a/core-rust/jni-export/src/lib.rs b/core-rust/jni-export/src/lib.rs index 67dcbe0ac5..5ce009d580 100644 --- a/core-rust/jni-export/src/lib.rs +++ b/core-rust/jni-export/src/lib.rs @@ -93,4 +93,7 @@ fn export_extern_functions() { // engine-state-api-server engine_state_api_server::jni::export_extern_functions(); + + // mesh-api-server + mesh_api_server::jni::export_extern_functions(); } diff --git a/core-rust/mesh-api-server/.gitignore b/core-rust/mesh-api-server/.gitignore new file mode 100644 index 0000000000..ebba2f2933 --- /dev/null +++ b/core-rust/mesh-api-server/.gitignore @@ -0,0 +1,2 @@ +# mesh-cli dir for logs and validation +test-data/ diff --git a/core-rust/mesh-api-server/Cargo.toml b/core-rust/mesh-api-server/Cargo.toml new file mode 100644 index 0000000000..20ce5a60b8 --- /dev/null +++ b/core-rust/mesh-api-server/Cargo.toml @@ -0,0 +1,45 @@ +[package] +name = "mesh-api-server" +version = "0.1.0" +edition = "2021" + +[dependencies] +node-common = { path = "../node-common" } +state-manager = { path = "../state-manager" } + +sbor = { workspace = true } +radix-transactions = { workspace = true } +radix-common = { workspace = true } +radix-engine-interface = { workspace = true } +radix-engine = { workspace = true } +radix-substate-store-impls = { workspace = true } +radix-substate-store-interface = { workspace = true } +radix-substate-store-queries = { workspace = true } +radix-blueprint-schema-init = { workspace = true } +radix-rust = { workspace = true } + +# Non-Radix Engine Dependencies: +jni = { workspace = true } +tracing = { workspace = true } +tokio = { workspace = true } +prometheus = { workspace = true } +blake2 = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } +serde_with = { workspace = true } +itertools = { workspace = true } +rand = { workspace = true } +chrono = { workspace = true } +hex = { workspace = true } +futures = { workspace = true } +futures-util = { workspace = true } +axum = { workspace = true } +tower = { workspace = true } +tower-http = { workspace = true } +hyper = { workspace = true } +paste = { workspace = true } +strum = { workspace = true } +strum_macros = { workspace = true } +convert_case = { workspace = true } +regex = { workspace = true } +lazy_static = { workspace = true } diff --git a/core-rust/mesh-api-server/mesh-api-schema/models/AccountIdentifier.yaml b/core-rust/mesh-api-server/mesh-api-schema/models/AccountIdentifier.yaml new file mode 100644 index 0000000000..5ed1d3cfd8 --- /dev/null +++ b/core-rust/mesh-api-server/mesh-api-schema/models/AccountIdentifier.yaml @@ -0,0 +1,34 @@ +# Copyright 2020 Coinbase, Inc. +# +# Licensed 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. + +description: | + The account_identifier uniquely identifies an account within a network. + All fields in the account_identifier are utilized to determine this uniqueness + (including the metadata field, if populated). +type: object +required: + - address +properties: + address: + description: | + The address may be a cryptographic public key (or some encoding of it) or a provided username. + type: string + example: "0x3a065000ab4183c6bf581dc1e55a605455fc6d61" + sub_account: + $ref: 'SubAccountIdentifier.yaml' + metadata: + description: | + Blockchains that utilize a username model (where the address is not a derivative of a cryptographic + public key) should specify the public key(s) owned by the address in metadata. + type: object diff --git a/core-rust/mesh-api-server/mesh-api-schema/models/Allow.yaml b/core-rust/mesh-api-server/mesh-api-schema/models/Allow.yaml new file mode 100644 index 0000000000..0fb2337c2a --- /dev/null +++ b/core-rust/mesh-api-server/mesh-api-schema/models/Allow.yaml @@ -0,0 +1,115 @@ +# Copyright 2020 Coinbase, Inc. +# +# Licensed 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. + +description: | + Allow specifies supported Operation status, Operation types, + and all possible error statuses. This Allow object is used by + clients to validate the correctness of a Rosetta Server implementation. It is + expected that these clients will error if they receive some response + that contains any of the above information that is not specified here. +type: object +required: + - operation_statuses + - operation_types + - errors + - historical_balance_lookup + - call_methods + - balance_exemptions + - mempool_coins +properties: + operation_statuses: + description: | + All Operation.Status this implementation supports. Any status + that is returned during parsing that is not listed here will cause + client validation to error. + type: array + items: + $ref: 'OperationStatus.yaml' + operation_types: + description: | + All Operation.Type this implementation supports. Any type + that is returned during parsing that is not listed here will + cause client validation to error. + type: array + items: + type: string + example: "TRANSFER" + errors: + description: | + All Errors that this implementation could return. Any error + that is returned during parsing that is not listed here will + cause client validation to error. + type: array + items: + $ref: 'Error.yaml' + historical_balance_lookup: + type: boolean + description: | + Any Rosetta implementation that supports querying the balance + of an account at any height in the past should set this to true. + timestamp_start_index: + type: integer + format: int64 + minimum: 0 + description: | + If populated, `timestamp_start_index` indicates the first block index + where block timestamps are considered valid (i.e. all blocks + less than `timestamp_start_index` could have invalid timestamps). + This is useful when the genesis block (or blocks) of a network + have timestamp 0. + + If not populated, block timestamps are assumed to be valid for + all available blocks. + call_methods: + type: array + description: | + All methods that are supported by the /call endpoint. Communicating + which parameters should be provided to /call is the responsibility + of the implementer (this is en lieu of defining an entire type + system and requiring the implementer to define that in Allow). + items: + type: string + example: "eth_call" + balance_exemptions: + type: array + description: | + BalanceExemptions is an array of BalanceExemption indicating + which account balances could change without a corresponding Operation. + + BalanceExemptions should be used sparingly as they may + introduce significant complexity for integrators that attempt + to reconcile all account balance changes. + + If your implementation relies on any BalanceExemptions, you MUST implement + historical balance lookup (the ability to query an account balance at any + BlockIdentifier). + items: + $ref: 'BalanceExemption.yaml' + mempool_coins: + type: boolean + description: | + Any Rosetta implementation that can update an AccountIdentifier's unspent + coins based on the contents of the mempool should populate this field + as true. If false, requests to `/account/coins` that set `include_mempool` + as true will be automatically rejected. + block_hash_case: + $ref: 'Case.yaml' + description: | + This specifies the normalized case for block hash in the BlockIdentifier. + If not specified, it's assumed to be case sensitive. + transaction_hash_case: + $ref: 'Case.yaml' + description: | + This specifies the normalized case for transaction hash in the TransactionIdentifier. + If not specified, it's assumed to be case sensitive. diff --git a/core-rust/mesh-api-server/mesh-api-schema/models/Amount.yaml b/core-rust/mesh-api-server/mesh-api-schema/models/Amount.yaml new file mode 100644 index 0000000000..cc4de8441d --- /dev/null +++ b/core-rust/mesh-api-server/mesh-api-schema/models/Amount.yaml @@ -0,0 +1,33 @@ +# Copyright 2020 Coinbase, Inc. +# +# Licensed 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. + +description: | + Amount is some Value of a Currency. + It is considered invalid to specify a Value without a Currency. +type: object +required: + - value + - currency +properties: + value: + description: | + Value of the transaction in atomic units represented as an arbitrary-sized signed integer. + + For example, 1 BTC would be represented by a value of 100000000. + type: string + example: "1238089899992" + currency: + $ref: 'Currency.yaml' + metadata: + type: object diff --git a/core-rust/mesh-api-server/mesh-api-schema/models/BalanceExemption.yaml b/core-rust/mesh-api-server/mesh-api-schema/models/BalanceExemption.yaml new file mode 100644 index 0000000000..7ae31b9955 --- /dev/null +++ b/core-rust/mesh-api-server/mesh-api-schema/models/BalanceExemption.yaml @@ -0,0 +1,44 @@ +# Copyright 2020 Coinbase, Inc. +# +# Licensed 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. + +description: | + BalanceExemption indicates that the balance for an exempt account could + change without a corresponding Operation. This typically occurs with staking + rewards, vesting balances, and Currencies with a dynamic supply. + + Currently, it is possible to exempt an account from strict reconciliation + by SubAccountIdentifier.Address or by Currency. This means that any account + with SubAccountIdentifier.Address would be exempt or any balance of a particular + Currency would be exempt, respectively. + + BalanceExemptions should be used sparingly as they may + introduce significant complexity for integrators that attempt + to reconcile all account balance changes. + + If your implementation relies on any BalanceExemptions, you MUST implement + historical balance lookup (the ability to query an account balance at any + BlockIdentifier). +type: object +properties: + sub_account_address: + description: | + SubAccountAddress is the SubAccountIdentifier.Address that the + BalanceExemption applies to (regardless of the value of + SubAccountIdentifier.Metadata). + type: string + example: "staking" + currency: + $ref: 'Currency.yaml' + exemption_type: + $ref: 'ExemptionType.yaml' diff --git a/core-rust/mesh-api-server/mesh-api-schema/models/Block.yaml b/core-rust/mesh-api-server/mesh-api-schema/models/Block.yaml new file mode 100644 index 0000000000..8a0f6c20d3 --- /dev/null +++ b/core-rust/mesh-api-server/mesh-api-schema/models/Block.yaml @@ -0,0 +1,46 @@ +# Copyright 2020 Coinbase, Inc. +# +# Licensed 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. + +description: | + Blocks contain an array of Transactions that + occurred at a particular BlockIdentifier. + + A hard requirement for blocks returned by Rosetta + implementations is that they MUST be _inalterable_: + once a client has requested and received + a block identified by a specific BlockIndentifier, + all future calls for that same BlockIdentifier + must return the same block contents. +type: object +required: + - block_identifier + - parent_block_identifier + - timestamp + - transactions +properties: + block_identifier: + $ref: 'BlockIdentifier.yaml' + parent_block_identifier: + $ref: 'BlockIdentifier.yaml' + timestamp: + $ref: 'Timestamp.yaml' + transactions: + type: array + items: + $ref: 'Transaction.yaml' + metadata: + type: object + example: + transactions_root: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + difficulty: "123891724987128947" diff --git a/core-rust/mesh-api-server/mesh-api-schema/models/BlockEvent.yaml b/core-rust/mesh-api-server/mesh-api-schema/models/BlockEvent.yaml new file mode 100644 index 0000000000..c0ae50e470 --- /dev/null +++ b/core-rust/mesh-api-server/mesh-api-schema/models/BlockEvent.yaml @@ -0,0 +1,36 @@ +# Copyright 2020 Coinbase, Inc. +# +# Licensed 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. + +description: | + BlockEvent represents the addition or removal of a BlockIdentifier + from storage. Streaming BlockEvents allows lightweight clients to + update their own state without needing to implement their own syncing logic. +type: object +required: + - sequence + - block_identifier + - type +properties: + sequence: + description: | + sequence is the unique identifier of a BlockEvent + within the context of a NetworkIdentifier. + type: integer + format: int64 + minimum: 0 + example: 5 + block_identifier: + $ref: 'BlockIdentifier.yaml' + type: + $ref: 'BlockEventType.yaml' diff --git a/core-rust/mesh-api-server/mesh-api-schema/models/BlockEventType.yaml b/core-rust/mesh-api-server/mesh-api-schema/models/BlockEventType.yaml new file mode 100644 index 0000000000..4ddc7d1fc7 --- /dev/null +++ b/core-rust/mesh-api-server/mesh-api-schema/models/BlockEventType.yaml @@ -0,0 +1,21 @@ +# Copyright 2020 Coinbase, Inc. +# +# Licensed 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. + +description: | + BlockEventType determines if a BlockEvent represents the + addition or removal of a block. +type: string +enum: + - block_added + - block_removed diff --git a/core-rust/mesh-api-server/mesh-api-schema/models/BlockIdentifier.yaml b/core-rust/mesh-api-server/mesh-api-schema/models/BlockIdentifier.yaml new file mode 100644 index 0000000000..a41d478cc6 --- /dev/null +++ b/core-rust/mesh-api-server/mesh-api-schema/models/BlockIdentifier.yaml @@ -0,0 +1,33 @@ +# Copyright 2020 Coinbase, Inc. +# +# Licensed 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. + +description: | + The block_identifier uniquely identifies a block in a particular network. +type: object +required: + - index + - hash +properties: + index: + description: | + This is also known as the block height. + type: integer + format: int64 + example: 1123941 + hash: + type: string + example: "0x1f2cc6c5027d2f201a5453ad1119574d2aed23a392654742ac3c78783c071f85" + description: | + This should be normalized according to the case specified in the block_hash_case + network options. diff --git a/core-rust/mesh-api-server/mesh-api-schema/models/BlockTransaction.yaml b/core-rust/mesh-api-server/mesh-api-schema/models/BlockTransaction.yaml new file mode 100644 index 0000000000..bbf1d0433c --- /dev/null +++ b/core-rust/mesh-api-server/mesh-api-schema/models/BlockTransaction.yaml @@ -0,0 +1,26 @@ +# Copyright 2020 Coinbase, Inc. +# +# Licensed 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. + +description: | + BlockTransaction contains a populated Transaction + and the BlockIdentifier that contains it. +type: object +required: + - block_identifier + - transaction +properties: + block_identifier: + $ref: 'BlockIdentifier.yaml' + transaction: + $ref: 'Transaction.yaml' diff --git a/core-rust/mesh-api-server/mesh-api-schema/models/Case.yaml b/core-rust/mesh-api-server/mesh-api-schema/models/Case.yaml new file mode 100644 index 0000000000..190f5b1880 --- /dev/null +++ b/core-rust/mesh-api-server/mesh-api-schema/models/Case.yaml @@ -0,0 +1,25 @@ +# Copyright 2021 Coinbase, Inc. +# +# Licensed 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. + +description: | + Case specifies the expected case for strings and hashes. +type: string +nullable: true +enum: + - upper_case + - lower_case + - case_sensitive + - null +default: case_sensitive + diff --git a/core-rust/mesh-api-server/mesh-api-schema/models/Coin.yaml b/core-rust/mesh-api-server/mesh-api-schema/models/Coin.yaml new file mode 100644 index 0000000000..10b5991ef0 --- /dev/null +++ b/core-rust/mesh-api-server/mesh-api-schema/models/Coin.yaml @@ -0,0 +1,26 @@ +# Copyright 2020 Coinbase, Inc. +# +# Licensed 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. + +description: | + Coin contains its unique identifier and the amount + it represents. +type: object +required: + - coin_identifier + - amount +properties: + coin_identifier: + $ref: 'CoinIdentifier.yaml' + amount: + $ref: 'Amount.yaml' diff --git a/core-rust/mesh-api-server/mesh-api-schema/models/CoinAction.yaml b/core-rust/mesh-api-server/mesh-api-schema/models/CoinAction.yaml new file mode 100644 index 0000000000..bf13a5242e --- /dev/null +++ b/core-rust/mesh-api-server/mesh-api-schema/models/CoinAction.yaml @@ -0,0 +1,23 @@ +# Copyright 2020 Coinbase, Inc. +# +# Licensed 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. + +description: | + CoinActions are different state changes that a Coin can + undergo. When a Coin is created, it is coin_created. When a Coin is + spent, it is coin_spent. It is assumed that a single Coin + cannot be created or spent more than once. +type: string +enum: + - coin_created + - coin_spent diff --git a/core-rust/mesh-api-server/mesh-api-schema/models/CoinChange.yaml b/core-rust/mesh-api-server/mesh-api-schema/models/CoinChange.yaml new file mode 100644 index 0000000000..4c80e8268c --- /dev/null +++ b/core-rust/mesh-api-server/mesh-api-schema/models/CoinChange.yaml @@ -0,0 +1,33 @@ +# Copyright 2020 Coinbase, Inc. +# +# Licensed 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. + +description: | + CoinChange is used to represent a change in state of + a some coin identified by a coin_identifier. This object + is part of the Operation model and must be populated for + UTXO-based blockchains. + + Coincidentally, this abstraction of UTXOs allows for supporting + both account-based transfers and UTXO-based transfers on the + same blockchain (when a transfer is account-based, don't + populate this model). +type: object +required: + - coin_identifier + - coin_action +properties: + coin_identifier: + $ref: 'CoinIdentifier.yaml' + coin_action: + $ref: 'CoinAction.yaml' diff --git a/core-rust/mesh-api-server/mesh-api-schema/models/CoinIdentifier.yaml b/core-rust/mesh-api-server/mesh-api-schema/models/CoinIdentifier.yaml new file mode 100644 index 0000000000..9c66ef3885 --- /dev/null +++ b/core-rust/mesh-api-server/mesh-api-schema/models/CoinIdentifier.yaml @@ -0,0 +1,26 @@ +# Copyright 2020 Coinbase, Inc. +# +# Licensed 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. + +description: | + CoinIdentifier uniquely identifies a Coin. +type: object +required: + - identifier +properties: + identifier: + description: | + Identifier should be populated with a globally unique identifier + of a Coin. In Bitcoin, this identifier would be transaction_hash:index. + type: string + example: "0x2f23fd8cca835af21f3ac375bac601f97ead75f2e79143bdf71fe2c4be043e8f:1" diff --git a/core-rust/mesh-api-server/mesh-api-schema/models/Currency.yaml b/core-rust/mesh-api-server/mesh-api-schema/models/Currency.yaml new file mode 100644 index 0000000000..5ad4808f33 --- /dev/null +++ b/core-rust/mesh-api-server/mesh-api-schema/models/Currency.yaml @@ -0,0 +1,48 @@ +# Copyright 2020 Coinbase, Inc. +# +# Licensed 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. + +description: | + Currency is composed of a canonical Symbol and + Decimals. This Decimals value is used to convert + an Amount.Value from atomic units (Satoshis) to standard units + (Bitcoins). +type: object +required: + - symbol + - decimals +properties: + symbol: + description: | + Canonical symbol associated with a currency. + type: string + example: "BTC" + decimals: + description: | + Number of decimal places in the standard unit representation of the amount. + + For example, BTC has 8 decimals. Note that it is not possible to represent + the value of some currency in atomic units that is not base 10. + type: integer + format: int32 + minimum: 0 + example: 8 + metadata: + description: | + Any additional information related to the currency itself. + + For example, it would be useful to populate this object with the contract address + of an ERC-20 token. + type: object + example: + Issuer: "Satoshi" diff --git a/core-rust/mesh-api-server/mesh-api-schema/models/CurveType.yaml b/core-rust/mesh-api-server/mesh-api-schema/models/CurveType.yaml new file mode 100644 index 0000000000..6e8813021b --- /dev/null +++ b/core-rust/mesh-api-server/mesh-api-schema/models/CurveType.yaml @@ -0,0 +1,32 @@ +# Copyright 2020 Coinbase, Inc. +# +# Licensed 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. + +description: | + CurveType is the type of cryptographic curve associated with a PublicKey. + + * secp256k1: SEC compressed - `33 bytes` (https://secg.org/sec1-v2.pdf#subsubsection.2.3.3) + * secp256k1_bip340: x-only - `32 bytes` (implicitly even `Y` coord. Secp256k1 compressed keys may be repurposed by dropping the first byte. (https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki#Public_Key_Generation)) + * secp256r1: SEC compressed - `33 bytes` (https://secg.org/sec1-v2.pdf#subsubsection.2.3.3) + * edwards25519: `y (255-bits) || x-sign-bit (1-bit)` - `32 bytes` (https://ed25519.cr.yp.to/ed25519-20110926.pdf) + * tweedle: 1st pk : Fq.t (32 bytes) || 2nd pk : Fq.t (32 bytes) (https://github.com/CodaProtocol/coda/blob/develop/rfcs/0038-rosetta-construction-api.md#marshal-keys) + * pallas: `x (255 bits) || y-parity-bit (1-bit) - 32 bytes` (https://github.com/zcash/pasta) + +type: string +enum: + - secp256k1 + - secp256k1_bip340 + - secp256r1 + - edwards25519 + - tweedle + - pallas diff --git a/core-rust/mesh-api-server/mesh-api-schema/models/Direction.yaml b/core-rust/mesh-api-server/mesh-api-schema/models/Direction.yaml new file mode 100644 index 0000000000..086de4445e --- /dev/null +++ b/core-rust/mesh-api-server/mesh-api-schema/models/Direction.yaml @@ -0,0 +1,21 @@ +# Copyright 2020 Coinbase, Inc. +# +# Licensed 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. +description: | + Used by RelatedTransaction to indicate the direction of the relation (i.e. cross-shard/cross-network sends may + reference `backward` to an earlier transaction and async execution may reference `forward`). Can be used to indicate if + a transaction relation is from child to parent or the reverse. +type: string +enum: + - forward + - backward \ No newline at end of file diff --git a/core-rust/mesh-api-server/mesh-api-schema/models/Error.yaml b/core-rust/mesh-api-server/mesh-api-schema/models/Error.yaml new file mode 100644 index 0000000000..6f2e47b65e --- /dev/null +++ b/core-rust/mesh-api-server/mesh-api-schema/models/Error.yaml @@ -0,0 +1,75 @@ +# Copyright 2020 Coinbase, Inc. +# +# Licensed 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. + +description: | + Instead of utilizing HTTP status codes to describe node errors (which often + do not have a good analog), rich errors are returned using this object. + + Both the code and message fields can be individually used to correctly + identify an error. Implementations MUST use unique values for both + fields. +type: object +required: + - code + - message + - retriable +properties: + code: + description: | + Code is a network-specific error code. If desired, this code + can be equivalent to an HTTP status code. + type: integer + format: int32 + minimum: 0 + example: 12 + message: + description: | + Message is a network-specific error message. + + The message MUST NOT change for a given code. In particular, this + means that any contextual information should be included in + the details field. + type: string + example: "Invalid account format" + description: + description: | + Description allows the implementer to optionally provide additional information + about an error. In many cases, the content of this field will be a copy-and-paste + from existing developer documentation. + + Description can ONLY be populated with generic information about a particular + type of error. It MUST NOT be populated with information about a particular + instantiation of an error (use `details` for this). + + Whereas the content of Error.Message should stay stable across releases, the + content of Error.Description will likely change across releases (as implementers + improve error documentation). For this reason, the content in this field + is not part of any type assertion (unlike Error.Message). + type: string + example: "This error is returned when the requested AccountIdentifier is improperly formatted." + retriable: + description: | + An error is retriable if the same request may succeed if submitted + again. + type: boolean + details: + type: object + description: | + Often times it is useful to return context specific + to the request that caused the error (i.e. a sample of the + stack trace or impacted account) in addition to the + standard error message. + example: + address: "0x1dcc4de8dec75d7aab85b567b6" + error: "not base64" diff --git a/core-rust/mesh-api-server/mesh-api-schema/models/ExemptionType.yaml b/core-rust/mesh-api-server/mesh-api-schema/models/ExemptionType.yaml new file mode 100644 index 0000000000..dfd2f36c88 --- /dev/null +++ b/core-rust/mesh-api-server/mesh-api-schema/models/ExemptionType.yaml @@ -0,0 +1,30 @@ +# Copyright 2020 Coinbase, Inc. +# +# Licensed 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. + +description: | + ExemptionType is used to indicate if the live balance for an + account subject to a BalanceExemption could increase above, + decrease below, or equal the computed balance. + + * greater_or_equal: The live balance may increase above or equal the computed balance. This typically + occurs with staking rewards that accrue on each block. + * less_or_equal: The live balance may decrease below or equal the computed balance. This typically + occurs as balance moves from locked to spendable on a vesting account. + * dynamic: The live balance may increase above, decrease below, or equal the computed balance. This + typically occurs with tokens that have a dynamic supply. +type: string +enum: + - greater_or_equal + - less_or_equal + - dynamic diff --git a/core-rust/mesh-api-server/mesh-api-schema/models/NetworkIdentifier.yaml b/core-rust/mesh-api-server/mesh-api-schema/models/NetworkIdentifier.yaml new file mode 100644 index 0000000000..e4edd192c7 --- /dev/null +++ b/core-rust/mesh-api-server/mesh-api-schema/models/NetworkIdentifier.yaml @@ -0,0 +1,33 @@ +# Copyright 2020 Coinbase, Inc. +# +# Licensed 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. + +description: | + The network_identifier specifies which network a particular object is associated with. +type: object +required: + - blockchain + - network +properties: + blockchain: + type: string + example: "bitcoin" + network: + description: | + If a blockchain has a specific chain-id or network identifier, it + should go in this field. It is up to the client to determine which + network-specific identifier is mainnet or testnet. + type: string + example: "mainnet" + sub_network_identifier: + $ref: 'SubNetworkIdentifier.yaml' diff --git a/core-rust/mesh-api-server/mesh-api-schema/models/Operation.yaml b/core-rust/mesh-api-server/mesh-api-schema/models/Operation.yaml new file mode 100644 index 0000000000..7c5a7bfb98 --- /dev/null +++ b/core-rust/mesh-api-server/mesh-api-schema/models/Operation.yaml @@ -0,0 +1,74 @@ +# Copyright 2020 Coinbase, Inc. +# +# Licensed 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. + +description: | + Operations contain all balance-changing information within a + transaction. They are always one-sided (only affect 1 AccountIdentifier) + and can succeed or fail independently from a Transaction. + + Operations are used both to represent on-chain data (Data API) and to construct + new transactions (Construction API), creating a standard interface for reading + and writing to blockchains. +type: object +required: + - operation_identifier + - type +properties: + operation_identifier: + $ref: 'OperationIdentifier.yaml' + related_operations: + description: | + Restrict referenced related_operations to identifier indices + < the current operation_identifier.index. This ensures there + exists a clear DAG-structure of relations. + + Since operations are one-sided, one could imagine relating operations + in a single transfer or linking operations in a call tree. + type: array + items: + $ref: 'OperationIdentifier.yaml' + example: + - index: 1 + - index: 2 + type: + description: | + Type is the network-specific type of the operation. Ensure that any type that can be returned here is also + specified in the NetworkOptionsResponse. This can be very useful to downstream consumers that parse all + block data. + type: string + example: "Transfer" + status: + description: | + Status is the network-specific status of the operation. Status is not defined on the transaction object + because blockchains with smart contracts may have transactions that partially apply (some operations + are successful and some are not). Blockchains with atomic transactions (all operations succeed or + all operations fail) will have the same status for each operation. + + On-chain operations (operations retrieved in the `/block` and `/block/transaction` endpoints) MUST have + a populated status field (anything on-chain must have succeeded or failed). However, operations provided + during transaction construction (often times called "intent" in the documentation) MUST NOT + have a populated status field (operations yet to be included on-chain have not yet succeeded or failed). + type: string + example: "Reverted" + account: + $ref: 'AccountIdentifier.yaml' + amount: + $ref: 'Amount.yaml' + coin_change: + $ref: 'CoinChange.yaml' + metadata: + type: object + example: + asm: "304502201fd8abb11443f8b1b9a04e0495e0543d05611473a790c8939f089d073f90509a022100f4677825136605d732e2126d09a2d38c20c75946cd9fc239c0497e84c634e3dd01 03301a8259a12e35694cc22ebc45fee635f4993064190f6ce96e7fb19a03bb6be2" + hex: "48304502201fd8abb11443f8b1b9a04e0495e0543d05611473a790c8939f089d073f90509a022100f4677825136605d732e2126d09a2d38c20c75946cd9fc239c0497e84c634e3dd012103301a8259a12e35694cc22ebc45fee635f4993064190f6ce96e7fb19a03bb6be2" diff --git a/core-rust/mesh-api-server/mesh-api-schema/models/OperationIdentifier.yaml b/core-rust/mesh-api-server/mesh-api-schema/models/OperationIdentifier.yaml new file mode 100644 index 0000000000..6ed6021e16 --- /dev/null +++ b/core-rust/mesh-api-server/mesh-api-schema/models/OperationIdentifier.yaml @@ -0,0 +1,42 @@ +# Copyright 2020 Coinbase, Inc. +# +# Licensed 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. + +description: | + The operation_identifier uniquely identifies an operation within a transaction. +type: object +required: + - index +properties: + index: + description: | + The operation index is used to ensure each operation has a unique identifier within + a transaction. This index is only relative to the transaction and NOT GLOBAL. The + operations in each transaction should start from index 0. + + To clarify, there may not be any notion of an operation index in the blockchain being described. + type: integer + format: int64 + minimum: 0 + example: 5 + network_index: + description: | + Some blockchains specify an operation index that is essential for client use. For example, + Bitcoin uses a network_index to identify which UTXO was used in a transaction. + + network_index should not be populated if there is no notion of an operation index in a + blockchain (typically most account-based blockchains). + type: integer + format: int64 + minimum: 0 + example: 0 diff --git a/core-rust/mesh-api-server/mesh-api-schema/models/OperationStatus.yaml b/core-rust/mesh-api-server/mesh-api-schema/models/OperationStatus.yaml new file mode 100644 index 0000000000..6329f6ac5d --- /dev/null +++ b/core-rust/mesh-api-server/mesh-api-schema/models/OperationStatus.yaml @@ -0,0 +1,40 @@ +# Copyright 2020 Coinbase, Inc. +# +# Licensed 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. + +description: | + OperationStatus is utilized to indicate which Operation + status are considered successful. +type: object +required: + - status + - successful +properties: + status: + description: | + The status is the network-specific status of the operation. + type: string + successful: + description: | + An Operation is considered successful if the Operation.Amount + should affect the Operation.Account. Some blockchains (like Bitcoin) + only include successful operations in blocks but other blockchains + (like Ethereum) include unsuccessful operations that incur a fee. + + To reconcile the computed balance from the stream of Operations, + it is critical to understand which Operation.Status indicate an + Operation is successful and should affect an Account. + type: boolean +example: + status: "SUCCESS" + successful: true diff --git a/core-rust/mesh-api-server/mesh-api-schema/models/Operator.yaml b/core-rust/mesh-api-server/mesh-api-schema/models/Operator.yaml new file mode 100644 index 0000000000..71b165b646 --- /dev/null +++ b/core-rust/mesh-api-server/mesh-api-schema/models/Operator.yaml @@ -0,0 +1,24 @@ +# Copyright 2020 Coinbase, Inc. +# +# Licensed 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. + +description: | + Operator is used by query-related endpoints + to determine how to apply conditions. + + If this field is not populated, the default + `and` value will be used. +type: string +enum: + - or + - and diff --git a/core-rust/mesh-api-server/mesh-api-schema/models/PartialBlockIdentifier.yaml b/core-rust/mesh-api-server/mesh-api-schema/models/PartialBlockIdentifier.yaml new file mode 100644 index 0000000000..8e2997db25 --- /dev/null +++ b/core-rust/mesh-api-server/mesh-api-schema/models/PartialBlockIdentifier.yaml @@ -0,0 +1,27 @@ +# Copyright 2020 Coinbase, Inc. +# +# Licensed 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. + +type: object +description: | + When fetching data by BlockIdentifier, it may be possible to only specify the + index or hash. If neither property is specified, it is assumed that the + client is making a request at the current block. +properties: + index: + type: integer + format: int64 + example: 1123941 + hash: + type: string + example: "0x1f2cc6c5027d2f201a5453ad1119574d2aed23a392654742ac3c78783c071f85" diff --git a/core-rust/mesh-api-server/mesh-api-schema/models/Peer.yaml b/core-rust/mesh-api-server/mesh-api-schema/models/Peer.yaml new file mode 100644 index 0000000000..e96cf91200 --- /dev/null +++ b/core-rust/mesh-api-server/mesh-api-schema/models/Peer.yaml @@ -0,0 +1,25 @@ +# Copyright 2020 Coinbase, Inc. +# +# Licensed 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. + +description: | + A Peer is a representation of a node's peer. +type: object +required: + - peer_id +properties: + peer_id: + type: string + example: "0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5" + metadata: + type: object diff --git a/core-rust/mesh-api-server/mesh-api-schema/models/PublicKey.yaml b/core-rust/mesh-api-server/mesh-api-schema/models/PublicKey.yaml new file mode 100644 index 0000000000..03a7ca6190 --- /dev/null +++ b/core-rust/mesh-api-server/mesh-api-schema/models/PublicKey.yaml @@ -0,0 +1,32 @@ +# Copyright 2020 Coinbase, Inc. +# +# Licensed 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. + +description: | + PublicKey contains a public key byte array + for a particular CurveType encoded in hex. + + Note that there is no PrivateKey struct as this + is NEVER the concern of an implementation. +type: object +required: + - hex_bytes + - curve_type +properties: + hex_bytes: + type: string + description: | + Hex-encoded public key bytes in the format + specified by the CurveType. + curve_type: + $ref: "CurveType.yaml" diff --git a/core-rust/mesh-api-server/mesh-api-schema/models/RelatedTransaction.yaml b/core-rust/mesh-api-server/mesh-api-schema/models/RelatedTransaction.yaml new file mode 100644 index 0000000000..5d68d1a3f6 --- /dev/null +++ b/core-rust/mesh-api-server/mesh-api-schema/models/RelatedTransaction.yaml @@ -0,0 +1,28 @@ +# Copyright 2020 Coinbase, Inc. +# +# Licensed 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. + +description: | + The related_transaction allows implementations to link together multiple transactions. + An unpopulated network identifier indicates that the related transaction is on the same network. +type: object +required: + - transaction_identifier + - direction +properties: + network_identifier: + $ref: 'NetworkIdentifier.yaml' + transaction_identifier: + $ref: 'TransactionIdentifier.yaml' + direction: + $ref: 'Direction.yaml' diff --git a/core-rust/mesh-api-server/mesh-api-schema/models/Signature.yaml b/core-rust/mesh-api-server/mesh-api-schema/models/Signature.yaml new file mode 100644 index 0000000000..9ccfec8ea3 --- /dev/null +++ b/core-rust/mesh-api-server/mesh-api-schema/models/Signature.yaml @@ -0,0 +1,36 @@ +# Copyright 2020 Coinbase, Inc. +# +# Licensed 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. + +description: | + Signature contains the payload that was signed, the public keys of the + keypairs used to produce the signature, the signature (encoded in hex), + and the SignatureType. + + PublicKey is often times not known during construction of the signing payloads + but may be needed to combine signatures properly. +type: object +required: + - signing_payload + - public_key + - signature_type + - hex_bytes +properties: + signing_payload: + $ref: "SigningPayload.yaml" + public_key: + $ref: "PublicKey.yaml" + signature_type: + $ref: "SignatureType.yaml" + hex_bytes: + type: string diff --git a/core-rust/mesh-api-server/mesh-api-schema/models/SignatureType.yaml b/core-rust/mesh-api-server/mesh-api-schema/models/SignatureType.yaml new file mode 100644 index 0000000000..058bad4b2a --- /dev/null +++ b/core-rust/mesh-api-server/mesh-api-schema/models/SignatureType.yaml @@ -0,0 +1,31 @@ +# Copyright 2020 Coinbase, Inc. +# +# Licensed 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. + +description: | + SignatureType is the type of a cryptographic signature. + + * ecdsa: `r (32-bytes) || s (32-bytes)` - `64 bytes` + * ecdsa_recovery: `r (32-bytes) || s (32-bytes) || v (1-byte)` - `65 bytes` + * ed25519: `R (32-byte) || s (32-bytes)` - `64 bytes` + * schnorr_1: `r (32-bytes) || s (32-bytes)` - `64 bytes` (schnorr signature implemented by Zilliqa where both `r` and `s` are scalars encoded as `32-bytes` values, most significant byte first.) + * schnorr_bip340: `r (32-bytes) || s (32-bytes)` - `64 bytes` (sig = (bytes(R) || bytes((k + ed) mod n) where `r` is the `X` coordinate of a point `R` whose `Y` coordinate is even, most significant bytes first.) + * schnorr_poseidon: `r (32-bytes) || s (32-bytes)` where s = Hash(1st pk || 2nd pk || r) - `64 bytes` (schnorr signature w/ Poseidon hash function implemented by O(1) Labs where both `r` and `s` are scalars encoded as `32-bytes` values, least significant byte first. https://github.com/CodaProtocol/signer-reference/blob/master/schnorr.ml ) +type: string +enum: + - ecdsa + - ecdsa_recovery + - ed25519 + - schnorr_1 + - schnorr_bip340 + - schnorr_poseidon diff --git a/core-rust/mesh-api-server/mesh-api-schema/models/SigningPayload.yaml b/core-rust/mesh-api-server/mesh-api-schema/models/SigningPayload.yaml new file mode 100644 index 0000000000..41697a3461 --- /dev/null +++ b/core-rust/mesh-api-server/mesh-api-schema/models/SigningPayload.yaml @@ -0,0 +1,38 @@ +# Copyright 2020 Coinbase, Inc. +# +# Licensed 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. + +description: | + SigningPayload is signed by the client with the keypair associated + with an AccountIdentifier using the specified SignatureType. + + SignatureType can be optionally populated if there is + a restriction on the signature scheme that can be + used to sign the payload. +type: object +required: + - hex_bytes +properties: + address: + type: string + description: | + [DEPRECATED by `account_identifier` in `v1.4.4`] The network-specific address of the account that should sign + the payload. + account_identifier: + $ref: 'AccountIdentifier.yaml' + hex_bytes: + type: string + description: | + Hex-encoded string of the payload bytes. + signature_type: + $ref: "SignatureType.yaml" diff --git a/core-rust/mesh-api-server/mesh-api-schema/models/SubAccountIdentifier.yaml b/core-rust/mesh-api-server/mesh-api-schema/models/SubAccountIdentifier.yaml new file mode 100644 index 0000000000..f807fe1262 --- /dev/null +++ b/core-rust/mesh-api-server/mesh-api-schema/models/SubAccountIdentifier.yaml @@ -0,0 +1,36 @@ +# Copyright 2020 Coinbase, Inc. +# +# Licensed 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. + +description: | + An account may have state specific to a contract address (ERC-20 token) + and/or a stake (delegated balance). The sub_account_identifier should + specify which state (if applicable) an account instantiation refers to. +type: object +required: + - address +properties: + address: + description: | + The SubAccount address may be a cryptographic value or some + other identifier (ex: bonded) that uniquely specifies a SubAccount. + type: string + example: "0x6b175474e89094c44da98b954eedeac495271d0f" + metadata: + description: | + If the SubAccount address is not sufficient to uniquely specify a SubAccount, + any other identifying information can be stored here. + + It is important to note that two SubAccounts with identical addresses but + differing metadata will not be considered equal by clients. + type: object diff --git a/core-rust/mesh-api-server/mesh-api-schema/models/SubNetworkIdentifier.yaml b/core-rust/mesh-api-server/mesh-api-schema/models/SubNetworkIdentifier.yaml new file mode 100644 index 0000000000..02722b0448 --- /dev/null +++ b/core-rust/mesh-api-server/mesh-api-schema/models/SubNetworkIdentifier.yaml @@ -0,0 +1,29 @@ +# Copyright 2020 Coinbase, Inc. +# +# Licensed 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. + +description: | + In blockchains with sharded state, the SubNetworkIdentifier + is required to query some object on a specific shard. This identifier is + optional for all non-sharded blockchains. +type: object +required: + - network +properties: + network: + type: string + example: "shard 1" + metadata: + type: object + example: + producer: "0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5" diff --git a/core-rust/mesh-api-server/mesh-api-schema/models/SyncStatus.yaml b/core-rust/mesh-api-server/mesh-api-schema/models/SyncStatus.yaml new file mode 100644 index 0000000000..358c16ae19 --- /dev/null +++ b/core-rust/mesh-api-server/mesh-api-schema/models/SyncStatus.yaml @@ -0,0 +1,62 @@ +# Copyright 2020 Coinbase, Inc. +# +# Licensed 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. + +description: | + SyncStatus is used to provide additional context about an + implementation's sync status. + + This object is often used by implementations to indicate healthiness + when block data cannot be queried until some sync phase completes or + cannot be determined by comparing the timestamp of the most recent + block with the current time. +type: object +properties: + current_index: + description: | + CurrentIndex is the index of the last synced block in the + current stage. + + This is a separate field from current_block_identifier in + NetworkStatusResponse because blocks with indices up to and including + the current_index may not yet be queryable by the caller. To reiterate, + all indices up to and including current_block_identifier in + NetworkStatusResponse must be queryable via the /block endpoint (excluding + indices less than oldest_block_identifier). + type: integer + format: int64 + example: 100 + target_index: + description: | + TargetIndex is the index of the block that the implementation + is attempting to sync to in the current stage. + type: integer + format: int64 + example: 150 + stage: + description: | + Stage is the phase of the sync process. + type: string + example: "header sync" + synced: + description: | + synced is a boolean that indicates if an implementation has synced up + to the most recent block. If this field is not populated, the caller + should rely on a traditional tip timestamp comparison to determine if + an implementation is synced. + + This field is particularly useful for quiescent blockchains (blocks + only produced when there are pending transactions). In these blockchains, + the most recent block could have a timestamp far behind the current + time but the node could be healthy and at tip. + type: boolean diff --git a/core-rust/mesh-api-server/mesh-api-schema/models/Timestamp.yaml b/core-rust/mesh-api-server/mesh-api-schema/models/Timestamp.yaml new file mode 100644 index 0000000000..b7de47130f --- /dev/null +++ b/core-rust/mesh-api-server/mesh-api-schema/models/Timestamp.yaml @@ -0,0 +1,21 @@ +# Copyright 2020 Coinbase, Inc. +# +# Licensed 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. + +description: | + The timestamp of the block in milliseconds since the Unix Epoch. The timestamp is stored in + milliseconds because some blockchains produce blocks more often than once a second. +type: integer +format: int64 +minimum: 0 +example: 1582833600000 diff --git a/core-rust/mesh-api-server/mesh-api-schema/models/Transaction.yaml b/core-rust/mesh-api-server/mesh-api-schema/models/Transaction.yaml new file mode 100644 index 0000000000..5e9d81c808 --- /dev/null +++ b/core-rust/mesh-api-server/mesh-api-schema/models/Transaction.yaml @@ -0,0 +1,40 @@ +# Copyright 2020 Coinbase, Inc. +# +# Licensed 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. + +description: | + Transactions contain an array of Operations + that are attributable to the same TransactionIdentifier. +type: object +required: + - transaction_identifier + - operations +properties: + transaction_identifier: + $ref: 'TransactionIdentifier.yaml' + operations: + type: array + items: + $ref: 'Operation.yaml' + related_transactions: + type: array + items: + $ref: 'RelatedTransaction.yaml' + metadata: + description: | + Transactions that are related to other transactions (like a cross-shard transaction) should include + the tranaction_identifier of these transactions in the metadata. + type: object + example: + size: 12378 + lockTime: 1582272577 diff --git a/core-rust/mesh-api-server/mesh-api-schema/models/TransactionIdentifier.yaml b/core-rust/mesh-api-server/mesh-api-schema/models/TransactionIdentifier.yaml new file mode 100644 index 0000000000..ab1a5445dc --- /dev/null +++ b/core-rust/mesh-api-server/mesh-api-schema/models/TransactionIdentifier.yaml @@ -0,0 +1,28 @@ +# Copyright 2020 Coinbase, Inc. +# +# Licensed 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. + +description: | + The transaction_identifier uniquely identifies a transaction in a particular network and block + or in the mempool. +type: object +required: + - hash +properties: + hash: + description: | + Any transactions that are attributable only to a block (ex: a block event) + should use the hash of the block as the identifier. This should be normalized according to + the case specified in the transaction_hash_case in network options. + type: string + example: "0x2f23fd8cca835af21f3ac375bac601f97ead75f2e79143bdf71fe2c4be043e8f" diff --git a/core-rust/mesh-api-server/mesh-api-schema/models/Version.yaml b/core-rust/mesh-api-server/mesh-api-schema/models/Version.yaml new file mode 100644 index 0000000000..2b7fef7ecb --- /dev/null +++ b/core-rust/mesh-api-server/mesh-api-schema/models/Version.yaml @@ -0,0 +1,48 @@ +# Copyright 2020 Coinbase, Inc. +# +# Licensed 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. + +description: | + The Version object is utilized to inform the client + of the versions of different components of the Rosetta + implementation. +type: object +required: + - rosetta_version + - node_version +properties: + rosetta_version: + description: | + The rosetta_version is the version of the Rosetta interface + the implementation adheres to. This can be useful for clients + looking to reliably parse responses. + type: string + example: "1.2.5" + node_version: + description: | + The node_version is the canonical version of the node + runtime. This can help clients manage deployments. + type: string + example: "1.0.2" + middleware_version: + description: | + When a middleware server is used to adhere to the Rosetta + interface, it should return its version here. This can help + clients manage deployments. + type: string + example: "0.2.7" + metadata: + description: | + Any other information that may be useful about versioning + of dependent services should be returned here. + type: object diff --git a/core-rust/mesh-api-server/mesh-api-schema/schema.yaml b/core-rust/mesh-api-server/mesh-api-schema/schema.yaml new file mode 100644 index 0000000000..0331db7001 --- /dev/null +++ b/core-rust/mesh-api-server/mesh-api-schema/schema.yaml @@ -0,0 +1,1638 @@ +# Copyright 2020 Coinbase, Inc. +# +# Licensed 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. + +openapi: 3.0.2 +info: + version: 1.4.13 + title: Rosetta + description: | + Build Once. Integrate Your Blockchain Everywhere. + license: + name: Apache 2.0 + url: "http://www.apache.org/licenses/LICENSE-2.0.html" +paths: + /network/list: + post: + summary: Get List of Available Networks + description: | + This endpoint returns a list of NetworkIdentifiers that the Rosetta + server supports. + operationId: networkList + tags: + - Network + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/MetadataRequest' + responses: + '200': + description: Expected response to a valid request + content: + application/json: + schema: + $ref: '#/components/schemas/NetworkListResponse' + '500': + description: unexpected error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /network/status: + post: + summary: Get Network Status + description: | + This endpoint returns the current status of the network requested. Any + NetworkIdentifier returned by /network/list should be accessible here. + operationId: networkStatus + tags: + - Network + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/NetworkRequest' + responses: + '200': + description: Expected response to a valid request + content: + application/json: + schema: + $ref: '#/components/schemas/NetworkStatusResponse' + '500': + description: unexpected error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /network/options: + post: + summary: Get Network Options + description: | + This endpoint returns the version information and allowed + network-specific types for a NetworkIdentifier. Any + NetworkIdentifier returned by /network/list should be accessible here. + + Because options are retrievable in the context of a NetworkIdentifier, + it is possible to define unique options for each network. + operationId: networkOptions + tags: + - Network + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/NetworkRequest' + responses: + '200': + description: Expected response to a valid request + content: + application/json: + schema: + $ref: '#/components/schemas/NetworkOptionsResponse' + '500': + description: unexpected error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /block: + post: + summary: Get a Block + description: | + Get a block by its Block Identifier. If transactions are returned in + the same call to the node as fetching the block, the response should + include these transactions in the Block object. If not, an array of + Transaction Identifiers should be returned so /block/transaction + fetches can be done to get all transaction information. + + When requesting a block by the hash component of the BlockIdentifier, + this request MUST be idempotent: repeated invocations for the same + hash-identified block must return the exact same block contents. + + No such restriction is imposed when requesting a block by height, + given that a chain reorg event might cause the specific block at + height `n` to be set to a different one. + operationId: block + tags: + - Block + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/BlockRequest' + responses: + '200': + description: Expected response to a valid request + content: + application/json: + schema: + $ref: '#/components/schemas/BlockResponse' + '500': + description: unexpected error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /block/transaction: + post: + summary: Get a Block Transaction + description: | + Get a transaction in a block by its Transaction Identifier. This endpoint + should only be used when querying a node for a block does not return all + transactions contained within it. + + All transactions returned by this endpoint must be appended to any + transactions returned by the /block method by consumers of this data. + Fetching a transaction by hash is considered an Explorer Method + (which is classified under the Future Work section). + + This method can be used to let consumers to paginate results when the + block trasactions count is too big to be returned in a single BlockResponse. + + Calling this endpoint requires reference to a BlockIdentifier because + transaction parsing can change depending on which block contains the + transaction. For example, in Bitcoin it is necessary to know which block + contains a transaction to determine the destination of fee payments. + Without specifying a block identifier, the node + would have to infer which block to use (which could change during a re-org). + + Implementations that require fetching previous transactions to populate + the response (ex: Previous UTXOs in Bitcoin) may find it useful to run a + cache within the Rosetta server in the /data directory + (on a path that does not conflict with the node). + operationId: blockTransaction + tags: + - Block + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/BlockTransactionRequest' + responses: + '200': + description: Expected response to a valid request + content: + application/json: + schema: + $ref: '#/components/schemas/BlockTransactionResponse' + '500': + description: unexpected error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /mempool: + post: + summary: Get All Mempool Transactions + description: Get all Transaction Identifiers in the mempool + operationId: mempool + tags: + - Mempool + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/NetworkRequest' + responses: + '200': + description: Expected response to a valid request + content: + application/json: + schema: + $ref: '#/components/schemas/MempoolResponse' + '500': + description: unexpected error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /mempool/transaction: + post: + summary: Get a Mempool Transaction + description: | + Get a transaction in the mempool by its Transaction Identifier. This is + a separate request than fetching a block transaction (/block/transaction) + because some blockchain nodes need to know that a transaction query is + for something in the mempool instead of a transaction in a block. + + Transactions may not be fully parsable until they are in a block (ex: may + not be possible to determine the fee to pay before a transaction is + executed). On this endpoint, it is ok that returned transactions are + only estimates of what may actually be included in a block. + operationId: mempoolTransaction + tags: + - Mempool + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/MempoolTransactionRequest' + responses: + '200': + description: Expected response to a valid request + content: + application/json: + schema: + $ref: '#/components/schemas/MempoolTransactionResponse' + '500': + description: unexpected error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /account/balance: + post: + summary: Get an Account's Balance + description: | + Get an array of all AccountBalances for an AccountIdentifier and the + BlockIdentifier at which the balance lookup was performed. The BlockIdentifier + must always be returned because some consumers of account balance data need + to know specifically at which block the balance was calculated to + compare balances they compute from operations with the balance returned + by the node. + + It is important to note that making a balance request for an account + without populating the SubAccountIdentifier should not result in the + balance of all possible SubAccountIdentifiers being returned. Rather, + it should result in the balance pertaining to no SubAccountIdentifiers + being returned (sometimes called the liquid balance). To get all + balances associated with an account, it may be necessary to + perform multiple balance requests with unique AccountIdentifiers. + + It is also possible to perform a historical balance lookup (if the server + supports it) by passing in an optional BlockIdentifier. + operationId: accountBalance + tags: + - Account + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AccountBalanceRequest' + responses: + '200': + description: Expected response to a valid request + content: + application/json: + schema: + $ref: '#/components/schemas/AccountBalanceResponse' + '500': + description: unexpected error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /account/coins: + post: + summary: Get an Account's Unspent Coins + description: | + Get an array of all unspent coins for an AccountIdentifier and the + BlockIdentifier at which the lookup was performed. If your implementation + does not support coins (i.e. it is for an account-based blockchain), + you do not need to implement this endpoint. If you implementation does + support coins (i.e. it is fro a UTXO-based blockchain), you MUST + also complete the `/account/balance` endpoint. + + It is important to note that making a coins request for an account + without populating the SubAccountIdentifier should not result in the + coins of all possible SubAccountIdentifiers being returned. Rather, + it should result in the coins pertaining to no SubAccountIdentifiers + being returned. To get all coins associated with an account, it may be + necessary to perform multiple coin requests with unique AccountIdentifiers. + + Optionally, an implementation may choose to support updating an AccountIdentifier's + unspent coins based on the contents of the mempool. Note, using this functionality + breaks any guarantee of idempotency. + operationId: accountCoins + tags: + - Account + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AccountCoinsRequest' + responses: + '200': + description: Expected response to a valid request + content: + application/json: + schema: + $ref: '#/components/schemas/AccountCoinsResponse' + '500': + description: unexpected error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /construction/derive: + post: + summary: Derive an AccountIdentifier from a PublicKey + description: | + Derive returns the AccountIdentifier associated with a public key. + + Blockchains that require an on-chain action to create an + account should not implement this method. + operationId: constructionDerive + tags: + - Construction + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ConstructionDeriveRequest' + responses: + '200': + description: Expected response to a valid request + content: + application/json: + schema: + $ref: '#/components/schemas/ConstructionDeriveResponse' + '500': + description: unexpected error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /construction/preprocess: + post: + summary: Create a Request to Fetch Metadata + description: | + Preprocess is called prior to `/construction/payloads` to construct a + request for any metadata that is needed for transaction construction + given (i.e. account nonce). + + The `options` object returned from this endpoint will be sent to the `/construction/metadata` + endpoint UNMODIFIED by the caller (in an offline execution environment). If + your Construction API implementation has configuration options, they MUST + be specified in the `/construction/preprocess` request (in the `metadata` + field). + operationId: constructionPreprocess + tags: + - Construction + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ConstructionPreprocessRequest' + responses: + '200': + description: Expected response to a valid request + content: + application/json: + schema: + $ref: '#/components/schemas/ConstructionPreprocessResponse' + '500': + description: unexpected error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /construction/metadata: + post: + summary: Get Metadata for Transaction Construction + description: | + Get any information required to construct a transaction for a specific + network. Metadata returned here could be a recent hash to use, an + account sequence number, or even arbitrary chain state. The request + used when calling this endpoint is created by calling `/construction/preprocess` + in an offline environment. + + You should NEVER assume that the request sent to this endpoint will be + created by the caller or populated with any custom parameters. This must + occur in `/construction/preprocess`. + + It is important to clarify that this endpoint should not pre-construct + any transactions for the client (this should happen in `/construction/payloads`). + This endpoint is left purposely unstructured because of the wide scope + of metadata that could be required. + operationId: constructionMetadata + tags: + - Construction + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ConstructionMetadataRequest' + responses: + '200': + description: Expected response to a valid request + content: + application/json: + schema: + $ref: '#/components/schemas/ConstructionMetadataResponse' + '500': + description: unexpected error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /construction/payloads: + post: + summary: Generate an Unsigned Transaction and Signing Payloads + description: | + Payloads is called with an array of operations + and the response from `/construction/metadata`. It returns an + unsigned transaction blob and a collection of payloads that must + be signed by particular AccountIdentifiers using a certain SignatureType. + + The array of operations provided in transaction construction often times + can not specify all "effects" of a transaction (consider invoked transactions + in Ethereum). However, they can deterministically specify the "intent" + of the transaction, which is sufficient for construction. For this reason, + parsing the corresponding transaction in the Data API (when it lands on chain) + will contain a superset of whatever operations were provided during construction. + operationId: constructionPayloads + tags: + - Construction + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ConstructionPayloadsRequest' + responses: + '200': + description: Expected response to a valid request + content: + application/json: + schema: + $ref: '#/components/schemas/ConstructionPayloadsResponse' + '500': + description: unexpected error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /construction/combine: + post: + summary: Create Network Transaction from Signatures + description: | + Combine creates a network-specific transaction from an unsigned + transaction and an array of provided signatures. + + The signed transaction returned from this method will be sent to the + `/construction/submit` endpoint by the caller. + operationId: constructionCombine + tags: + - Construction + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ConstructionCombineRequest' + responses: + '200': + description: Expected response to a valid request + content: + application/json: + schema: + $ref: '#/components/schemas/ConstructionCombineResponse' + '500': + description: unexpected error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /construction/parse: + post: + summary: Parse a Transaction + description: | + Parse is called on both unsigned and signed transactions to + understand the intent of the formulated transaction. + + This is run as a sanity check before signing (after `/construction/payloads`) + and before broadcast (after `/construction/combine`). + operationId: constructionParse + tags: + - Construction + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ConstructionParseRequest' + responses: + '200': + description: Expected response to a valid request + content: + application/json: + schema: + $ref: '#/components/schemas/ConstructionParseResponse' + '500': + description: unexpected error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /construction/hash: + post: + summary: Get the Hash of a Signed Transaction + description: | + TransactionHash returns the network-specific transaction hash for + a signed transaction. + operationId: constructionHash + tags: + - Construction + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ConstructionHashRequest' + responses: + '200': + description: Expected response to a valid request + content: + application/json: + schema: + $ref: '#/components/schemas/TransactionIdentifierResponse' + '500': + description: unexpected error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /construction/submit: + post: + summary: Submit a Signed Transaction + description: | + Submit a pre-signed transaction to the node. This call should not block + on the transaction being included in a block. Rather, it should return + immediately with an indication of whether or not the transaction was + included in the mempool. + + The transaction submission response should only return a 200 status + if the submitted transaction could be included in the mempool. + Otherwise, it should return an error. + operationId: constructionSubmit + tags: + - Construction + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ConstructionSubmitRequest' + responses: + '200': + description: Expected response to a valid request + content: + application/json: + schema: + $ref: '#/components/schemas/TransactionIdentifierResponse' + '500': + description: unexpected error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /call: + post: + summary: Make a Network-Specific Procedure Call + description: | + Call invokes an arbitrary, network-specific procedure call with network-specific + parameters. The guidance for what this endpoint should or could do is + purposely left vague. In Ethereum, this could be used to invoke `eth_call` + to implement an entire Rosetta API interface for some smart contract that + is not parsed by the implementation creator (like a DEX). This endpoint + could also be used to provide access to data that does not map + to any Rosetta models instead of requiring an integrator to use some + network-specific SDK and call some network-specific endpoint (like surfacing + staking parameters). + + Call is NOT a replacement for implementing Rosetta API endpoints or mapping + network-specific data to Rosetta models. Rather, it enables developers to build + additional Rosetta API interfaces for things they care about without introducing + complexity into a base-level Rosetta implementation. Simply put, imagine + that the average integrator will use layered Rosetta API implementations + that each surfaces unique data. + operationId: call + tags: + - Call + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CallRequest' + responses: + '200': + description: Expected response to a valid request + content: + application/json: + schema: + $ref: '#/components/schemas/CallResponse' + '500': + description: unexpected error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /events/blocks: + post: + summary: | + [INDEXER] Get a range of BlockEvents + description: | + `/events/blocks` allows the caller to query a sequence + of BlockEvents indicating which blocks were added and + removed from storage to reach the current state. + Following BlockEvents allows lightweight clients to update + their state without needing to implement their own syncing + logic (like finding the common parent in a reorg). + + `/events/blocks` is considered an "indexer" endpoint + and Rosetta implementations are not required to complete it + to adhere to the Rosetta spec. However, any Rosetta "indexer" + MUST support this endpoint. + operationId: eventsBlocks + tags: + - Events + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/EventsBlocksRequest' + responses: + '200': + description: Expected response to a valid request + content: + application/json: + schema: + $ref: '#/components/schemas/EventsBlocksResponse' + '500': + description: unexpected error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /search/transactions: + post: + summary: | + [INDEXER] Search for Transactions + description: | + `/search/transactions` allows the caller to search for + transactions that meet certain conditions. Some conditions + include matching a transaction hash, containing an + operation with a certain status, or containing an operation + that affects a certain account. + + `/search/transactions` is considered an "indexer" endpoint + and Rosetta implementations are not required to complete it + to adhere to the Rosetta spec. However, any Rosetta "indexer" + MUST support this endpoint. + operationId: searchTransactions + tags: + - Search + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/SearchTransactionsRequest' + responses: + '200': + description: Expected response to a valid request + content: + application/json: + schema: + $ref: '#/components/schemas/SearchTransactionsResponse' + '500': + description: unexpected error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' +components: + schemas: + # Identifiers + NetworkIdentifier: + $ref: 'models/NetworkIdentifier.yaml' + SubNetworkIdentifier: + $ref: 'models/SubNetworkIdentifier.yaml' + BlockIdentifier: + $ref: 'models/BlockIdentifier.yaml' + PartialBlockIdentifier: + $ref: 'models/PartialBlockIdentifier.yaml' + TransactionIdentifier: + $ref: 'models/TransactionIdentifier.yaml' + OperationIdentifier: + $ref: 'models/OperationIdentifier.yaml' + AccountIdentifier: + $ref: 'models/AccountIdentifier.yaml' + SubAccountIdentifier: + $ref: 'models/SubAccountIdentifier.yaml' + + # Models + Block: + $ref: 'models/Block.yaml' + Transaction: + $ref: 'models/Transaction.yaml' + Operation: + $ref: 'models/Operation.yaml' + Amount: + $ref: 'models/Amount.yaml' + Currency: + $ref: 'models/Currency.yaml' + SyncStatus: + $ref: 'models/SyncStatus.yaml' + Peer: + $ref: 'models/Peer.yaml' + Version: + $ref: 'models/Version.yaml' + Allow: + $ref: 'models/Allow.yaml' + OperationStatus: + $ref: 'models/OperationStatus.yaml' + Timestamp: + $ref: 'models/Timestamp.yaml' + PublicKey: + $ref: 'models/PublicKey.yaml' + CurveType: + $ref: 'models/CurveType.yaml' + SigningPayload: + $ref: 'models/SigningPayload.yaml' + Signature: + $ref: 'models/Signature.yaml' + SignatureType: + $ref: 'models/SignatureType.yaml' + CoinAction: + $ref: 'models/CoinAction.yaml' + CoinIdentifier: + $ref: 'models/CoinIdentifier.yaml' + CoinChange: + $ref: 'models/CoinChange.yaml' + Coin: + $ref: 'models/Coin.yaml' + BalanceExemption: + $ref: 'models/BalanceExemption.yaml' + ExemptionType: + $ref: 'models/ExemptionType.yaml' + BlockEvent: + $ref: 'models/BlockEvent.yaml' + BlockEventType: + $ref: 'models/BlockEventType.yaml' + Operator: + $ref: 'models/Operator.yaml' + BlockTransaction: + $ref: 'models/BlockTransaction.yaml' + RelatedTransaction: + $ref: 'models/RelatedTransaction.yaml' + Direction: + $ref: 'models/Direction.yaml' + Case: + $ref: 'models/Case.yaml' + + # Request/Responses + AccountBalanceRequest: + description: | + An AccountBalanceRequest is utilized to make a balance request + on the /account/balance endpoint. If the block_identifier is populated, + a historical balance query should be performed. + type: object + required: + - network_identifier + - account_identifier + properties: + network_identifier: + $ref: '#/components/schemas/NetworkIdentifier' + account_identifier: + $ref: '#/components/schemas/AccountIdentifier' + block_identifier: + $ref: '#/components/schemas/PartialBlockIdentifier' + currencies: + type: array + description: | + In some cases, the caller may not want to retrieve all available + balances for an AccountIdentifier. If the currencies field + is populated, only balances for the specified currencies + will be returned. If not populated, all available balances + will be returned. + items: + $ref: '#/components/schemas/Currency' + AccountBalanceResponse: + description: | + An AccountBalanceResponse is returned on the /account/balance endpoint. + If an account has a balance for each AccountIdentifier describing it + (ex: an ERC-20 token balance on a few smart contracts), an account + balance request must be made with each AccountIdentifier. + + The `coins` field was removed and replaced by by `/account/coins` in `v1.4.7`. + type: object + required: + - block_identifier + - balances + properties: + block_identifier: + $ref: '#/components/schemas/BlockIdentifier' + balances: + type: array + description: | + A single account may have a balance in multiple currencies. + items: + $ref: '#/components/schemas/Amount' + metadata: + description: | + Account-based blockchains that utilize a nonce or sequence number + should include that number in the metadata. This number could be + unique to the identifier or global across the account address. + type: object + example: + sequence_number: 23 + AccountCoinsRequest: + description: | + AccountCoinsRequest is utilized to make a request on the /account/coins + endpoint. + type: object + required: + - network_identifier + - account_identifier + - include_mempool + properties: + network_identifier: + $ref: '#/components/schemas/NetworkIdentifier' + account_identifier: + $ref: '#/components/schemas/AccountIdentifier' + include_mempool: + type: boolean + description: | + Include state from the mempool when looking up an account's + unspent coins. Note, using this functionality + breaks any guarantee of idempotency. + currencies: + type: array + description: | + In some cases, the caller may not want to retrieve coins for all + currencies for an AccountIdentifier. If the currencies field + is populated, only coins for the specified currencies + will be returned. If not populated, all unspent coins + will be returned. + items: + $ref: '#/components/schemas/Currency' + AccountCoinsResponse: + description: | + AccountCoinsResponse is returned on the /account/coins endpoint and includes + all unspent Coins owned by an AccountIdentifier. + type: object + required: + - block_identifier + - coins + properties: + block_identifier: + $ref: '#/components/schemas/BlockIdentifier' + coins: + type: array + description: | + If a blockchain is UTXO-based, all unspent Coins owned by an account_identifier + should be returned alongside the balance. It is highly recommended to + populate this field so that users of the Rosetta API implementation + don't need to maintain their own indexer to track their UTXOs. + items: + $ref: '#/components/schemas/Coin' + metadata: + description: | + Account-based blockchains that utilize a nonce or sequence number + should include that number in the metadata. This number could be + unique to the identifier or global across the account address. + type: object + example: + sequence_number: 23 + BlockRequest: + description: | + A BlockRequest is utilized to make a block request on the + /block endpoint. + type: object + required: + - network_identifier + - block_identifier + properties: + network_identifier: + $ref: '#/components/schemas/NetworkIdentifier' + block_identifier: + $ref: '#/components/schemas/PartialBlockIdentifier' + BlockResponse: + description: | + A BlockResponse includes a fully-populated block or a partially-populated + block with a list of other transactions to fetch (other_transactions). + + As a result of the consensus algorithm of some blockchains, blocks + can be omitted (i.e. certain block indices can be skipped). If a query + for one of these omitted indices is made, the response should not include + a `Block` object. + + It is VERY important to note that blocks MUST still form a canonical, + connected chain of blocks where each block has a unique index. In other words, + the `PartialBlockIdentifier` of a block after an omitted block should + reference the last non-omitted block. + type: object + properties: + block: + $ref: '#/components/schemas/Block' + other_transactions: + description: | + Some blockchains may require additional transactions to be fetched + that weren't returned in the block response + (ex: block only returns transaction hashes). For blockchains with a + lot of transactions in each block, this + can be very useful as consumers can concurrently fetch all + transactions returned. + type: array + items: + $ref: '#/components/schemas/TransactionIdentifier' + BlockTransactionRequest: + description: | + A BlockTransactionRequest is used to fetch a Transaction included in a + block that is not returned in a BlockResponse. + type: object + required: + - network_identifier + - block_identifier + - transaction_identifier + properties: + network_identifier: + $ref: '#/components/schemas/NetworkIdentifier' + block_identifier: + $ref: '#/components/schemas/BlockIdentifier' + transaction_identifier: + $ref: '#/components/schemas/TransactionIdentifier' + BlockTransactionResponse: + description: | + A BlockTransactionResponse contains information about a block transaction. + type: object + required: + - transaction + properties: + transaction: + $ref: '#/components/schemas/Transaction' + MempoolResponse: + description: | + A MempoolResponse contains all transaction identifiers in the mempool + for a particular network_identifier. + type: object + required: + - transaction_identifiers + properties: + transaction_identifiers: + type: array + items: + $ref: '#/components/schemas/TransactionIdentifier' + MempoolTransactionRequest: + description: | + A MempoolTransactionRequest is utilized to retrieve a transaction + from the mempool. + type: object + required: + - network_identifier + - transaction_identifier + properties: + network_identifier: + $ref: '#/components/schemas/NetworkIdentifier' + transaction_identifier: + $ref: '#/components/schemas/TransactionIdentifier' + MempoolTransactionResponse: + description: | + A MempoolTransactionResponse contains an estimate of a mempool + transaction. It may not be possible to know the full impact of + a transaction in the mempool (ex: fee paid). + type: object + required: + - transaction + properties: + transaction: + $ref: '#/components/schemas/Transaction' + metadata: + type: object + example: + descendant_fees: 123923 + ancestor_count: 2 + MetadataRequest: + description: | + A MetadataRequest is utilized in any request where + the only argument is optional metadata. + type: object + properties: + metadata: + type: object + NetworkListResponse: + description: | + A NetworkListResponse contains all NetworkIdentifiers + that the node can serve information for. + type: object + required: + - network_identifiers + properties: + network_identifiers: + type: array + items: + $ref: '#/components/schemas/NetworkIdentifier' + NetworkRequest: + description: | + A NetworkRequest is utilized to retrieve some data specific exclusively + to a NetworkIdentifier. + type: object + required: + - network_identifier + properties: + network_identifier: + $ref: '#/components/schemas/NetworkIdentifier' + metadata: + type: object + NetworkStatusResponse: + description: | + NetworkStatusResponse contains basic information about the node's + view of a blockchain network. It is assumed that any BlockIdentifier.Index + less than or equal to CurrentBlockIdentifier.Index can be queried. + + If a Rosetta implementation prunes historical state, it should + populate the optional `oldest_block_identifier` field with the + oldest block available to query. If this is not populated, + it is assumed that the `genesis_block_identifier` is the oldest + queryable block. + + If a Rosetta implementation performs some pre-sync before it is + possible to query blocks, sync_status should be populated so that + clients can still monitor healthiness. Without this field, it may + appear that the implementation is stuck syncing and needs to be + terminated. + type: object + required: + - current_block_identifier + - current_block_timestamp + - genesis_block_identifier + properties: + current_block_identifier: + $ref: '#/components/schemas/BlockIdentifier' + current_block_timestamp: + $ref: '#/components/schemas/Timestamp' + genesis_block_identifier: + $ref: '#/components/schemas/BlockIdentifier' + oldest_block_identifier: + $ref: '#/components/schemas/BlockIdentifier' + sync_status: + $ref: '#/components/schemas/SyncStatus' + peers: + type: array + items: + $ref: '#/components/schemas/Peer' + NetworkOptionsResponse: + description: | + NetworkOptionsResponse contains information about the versioning of the + node and the allowed operation statuses, operation types, and errors. + type: object + required: + - version + - allow + properties: + version: + $ref: '#/components/schemas/Version' + allow: + $ref: '#/components/schemas/Allow' + ConstructionMetadataRequest: + description: | + A ConstructionMetadataRequest is utilized to get information required + to construct a transaction. + + The Options object used to specify which metadata to return is left + purposely unstructured to allow flexibility for implementers. Options + is not required in the case that there is network-wide metadata of + interest. + + Optionally, the request can also include an array + of PublicKeys associated with the AccountIdentifiers + returned in ConstructionPreprocessResponse. + type: object + required: + - network_identifier + properties: + network_identifier: + $ref: '#/components/schemas/NetworkIdentifier' + options: + description: | + Some blockchains require different metadata for different types of + transaction construction (ex: delegation versus a transfer). Instead + of requiring a blockchain node to return all possible types of + metadata for construction (which may require multiple node fetches), + the client can populate an options object to limit the metadata + returned to only the subset required. + type: object + public_keys: + type: array + items: + $ref: '#/components/schemas/PublicKey' + ConstructionMetadataResponse: + description: | + The ConstructionMetadataResponse returns network-specific metadata + used for transaction construction. + + Optionally, the implementer can return the suggested fee associated + with the transaction being constructed. The caller may use this info + to adjust the intent of the transaction or to create a transaction with + a different account that can pay the suggested fee. Suggested fee is an array + in case fee payment must occur in multiple currencies. + type: object + required: + - metadata + properties: + metadata: + type: object + example: + account_sequence: 23 + recent_block_hash: "0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5" + suggested_fee: + type: array + items: + $ref: '#/components/schemas/Amount' + ConstructionDeriveRequest: + description: | + ConstructionDeriveRequest is passed to the `/construction/derive` + endpoint. Network is provided in the request because some blockchains + have different address formats for different networks. + Metadata is provided in the request because some blockchains + allow for multiple address types (i.e. different address + for validators vs normal accounts). + type: object + required: + - network_identifier + - public_key + properties: + network_identifier: + $ref: '#/components/schemas/NetworkIdentifier' + public_key: + $ref: '#/components/schemas/PublicKey' + metadata: + type: object + ConstructionDeriveResponse: + description: | + ConstructionDeriveResponse is returned by the `/construction/derive` + endpoint. + type: object + properties: + address: + type: string + description: | + [DEPRECATED by `account_identifier` in `v1.4.4`] Address in network-specific format. + account_identifier: + $ref: '#/components/schemas/AccountIdentifier' + metadata: + type: object + ConstructionPreprocessRequest: + description: | + ConstructionPreprocessRequest is passed to the `/construction/preprocess` + endpoint so that a Rosetta implementation can determine which + metadata it needs to request for construction. + + Metadata provided in this object should NEVER be a product + of live data (i.e. the caller must follow some network-specific + data fetching strategy outside of the Construction API to populate + required Metadata). If live data is required for construction, it MUST + be fetched in the call to `/construction/metadata`. + type: object + required: + - network_identifier + - operations + properties: + network_identifier: + $ref: '#/components/schemas/NetworkIdentifier' + operations: + type: array + items: + $ref: '#/components/schemas/Operation' + metadata: + type: object + ConstructionPreprocessResponse: + description: | + ConstructionPreprocessResponse contains `options` that will + be sent unmodified to `/construction/metadata`. If it is + not necessary to make a request to `/construction/metadata`, + `options` should be omitted. + + Some blockchains require the PublicKey of particular AccountIdentifiers + to construct a valid transaction. To fetch these PublicKeys, populate + `required_public_keys` with the AccountIdentifiers associated with the desired + PublicKeys. If it is not necessary to retrieve any PublicKeys + for construction, `required_public_keys` should be omitted. + type: object + properties: + options: + type: object + description: | + The options that will be sent directly to `/construction/metadata` by + the caller. + required_public_keys: + type: array + items: + $ref: '#/components/schemas/AccountIdentifier' + ConstructionPayloadsRequest: + description: | + ConstructionPayloadsRequest is the request to + `/construction/payloads`. It contains the network, + a slice of operations, and arbitrary metadata + that was returned by the call to `/construction/metadata`. + + Optionally, the request can also include an array + of PublicKeys associated with the AccountIdentifiers + returned in ConstructionPreprocessResponse. + type: object + required: + - network_identifier + - operations + properties: + network_identifier: + $ref: '#/components/schemas/NetworkIdentifier' + operations: + type: array + items: + $ref: '#/components/schemas/Operation' + metadata: + type: object + public_keys: + type: array + items: + $ref: '#/components/schemas/PublicKey' + ConstructionPayloadsResponse: + description: | + ConstructionTransactionResponse is returned by `/construction/payloads`. It + contains an unsigned transaction blob (that is usually needed to construct + the a network transaction from a collection of signatures) and an + array of payloads that must be signed by the caller. + type: object + required: + - unsigned_transaction + - payloads + properties: + unsigned_transaction: + type: string + payloads: + type: array + items: + $ref: '#/components/schemas/SigningPayload' + ConstructionCombineRequest: + description: | + ConstructionCombineRequest is the input to the `/construction/combine` + endpoint. It contains the unsigned transaction blob returned by + `/construction/payloads` and all required signatures to create + a network transaction. + type: object + required: + - network_identifier + - unsigned_transaction + - signatures + properties: + network_identifier: + $ref: '#/components/schemas/NetworkIdentifier' + unsigned_transaction: + type: string + signatures: + type: array + items: + $ref: '#/components/schemas/Signature' + ConstructionCombineResponse: + description: | + ConstructionCombineResponse is returned by `/construction/combine`. + The network payload will be sent directly to the + `construction/submit` endpoint. + type: object + required: + - signed_transaction + properties: + signed_transaction: + type: string + ConstructionParseRequest: + description: | + ConstructionParseRequest is the input to the `/construction/parse` + endpoint. It allows the caller to parse either an unsigned or + signed transaction. + type: object + required: + - network_identifier + - signed + - transaction + properties: + network_identifier: + $ref: '#/components/schemas/NetworkIdentifier' + signed: + type: boolean + description: | + Signed is a boolean indicating whether the transaction is signed. + transaction: + type: string + description: | + This must be either the unsigned transaction blob returned by + `/construction/payloads` or the signed transaction blob + returned by `/construction/combine`. + ConstructionParseResponse: + description: | + ConstructionParseResponse contains an array of operations that occur in + a transaction blob. This should match the array of operations provided + to `/construction/preprocess` and `/construction/payloads`. + type: object + required: + - operations + properties: + operations: + type: array + items: + $ref: '#/components/schemas/Operation' + signers: + description: | + [DEPRECATED by `account_identifier_signers` in `v1.4.4`] All signers (addresses) of a particular transaction. If the transaction + is unsigned, it should be empty. + type: array + items: + type: string + account_identifier_signers: + type: array + items: + $ref: '#/components/schemas/AccountIdentifier' + metadata: + type: object + ConstructionHashRequest: + description: | + ConstructionHashRequest is the input to the `/construction/hash` endpoint. + type: object + required: + - network_identifier + - signed_transaction + properties: + network_identifier: + $ref: '#/components/schemas/NetworkIdentifier' + signed_transaction: + type: string + ConstructionSubmitRequest: + description: | + The transaction submission request includes a signed transaction. + type: object + required: + - network_identifier + - signed_transaction + properties: + network_identifier: + $ref: '#/components/schemas/NetworkIdentifier' + signed_transaction: + type: string + TransactionIdentifierResponse: + description: | + TransactionIdentifierResponse contains the transaction_identifier of a + transaction that was submitted to either `/construction/hash` or + `/construction/submit`. + type: object + required: + - transaction_identifier + properties: + transaction_identifier: + $ref: '#/components/schemas/TransactionIdentifier' + metadata: + type: object + CallRequest: + description: | + CallRequest is the input to the `/call` endpoint. + type: object + required: + - network_identifier + - method + - parameters + properties: + network_identifier: + $ref: '#/components/schemas/NetworkIdentifier' + method: + type: string + description: | + Method is some network-specific procedure call. This method could + map to a network-specific RPC endpoint, a method in an SDK generated + from a smart contract, or some hybrid of the two. + + The implementation must define all available methods in the + Allow object. However, it is up to the caller to determine + which parameters to provide when invoking `/call`. + example: "eth_call" + parameters: + type: object + description: | + Parameters is some network-specific argument for a method. It is + up to the caller to determine which parameters to provide when invoking + `/call`. + example: + block_number: 23 + address: "0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5" + CallResponse: + description: | + CallResponse contains the result of a `/call` invocation. + type: object + required: + - result + - idempotent + properties: + result: + type: object + description: | + Result contains the result of the `/call` invocation. This result + will not be inspected or interpreted by Rosetta tooling and is + left to the caller to decode. + example: + count: 1000 + idempotent: + type: boolean + description: | + Idempotent indicates that if `/call` is invoked with the same + CallRequest again, at any point in time, it will return the same + CallResponse. + + Integrators may cache the CallResponse if this is set to true + to avoid making unnecessary calls to the Rosetta implementation. For + this reason, implementers should be very conservative about returning + true here or they could cause issues for the caller. + EventsBlocksRequest: + description: | + EventsBlocksRequest is utilized to fetch a sequence of BlockEvents + indicating which blocks were added and removed from storage to + reach the current state. + type: object + required: + - network_identifier + properties: + network_identifier: + $ref: '#/components/schemas/NetworkIdentifier' + offset: + description: | + offset is the offset into the event stream to sync events from. If this + field is not populated, we return the limit events backwards from tip. + If this is set to 0, we start from the beginning. + type: integer + format: int64 + minimum: 0 + example: 5 + limit: + description: | + limit is the maximum number of events to fetch in one call. The implementation + may return <= limit events. + type: integer + format: int64 + minimum: 0 + example: 5 + EventsBlocksResponse: + description: | + EventsBlocksResponse contains an ordered collection of BlockEvents + and the max retrievable sequence. + type: object + required: + - max_sequence + - events + properties: + max_sequence: + description: | + max_sequence is the maximum available sequence number to fetch. + type: integer + format: int64 + minimum: 0 + example: 5 + events: + type: array + description: | + events is an array of BlockEvents indicating the order to add + and remove blocks to maintain a canonical view of blockchain + state. Lightweight clients can use this event stream to update + state without implementing their own block syncing logic. + items: + $ref: '#/components/schemas/BlockEvent' + SearchTransactionsRequest: + description: | + SearchTransactionsRequest is used to search for transactions + matching a set of provided conditions in canonical blocks. + type: object + required: + - network_identifier + properties: + network_identifier: + $ref: '#/components/schemas/NetworkIdentifier' + operator: + $ref: '#/components/schemas/Operator' + max_block: + description: | + max_block is the largest block index to consider when searching + for transactions. If this field is not populated, the current + block is considered the max_block. + + If you do not specify a max_block, it is possible a newly synced + block will interfere with paginated transaction queries (as the offset + could become invalid with newly added rows). + type: integer + format: int64 + minimum: 0 + example: 5 + offset: + description: | + offset is the offset into the query result to start returning transactions. + + If any search conditions are changed, the query offset will change and you + must restart your search iteration. + type: integer + format: int64 + minimum: 0 + example: 5 + limit: + description: | + limit is the maximum number of transactions to return in one call. The implementation + may return <= limit transactions. + type: integer + format: int64 + minimum: 0 + example: 5 + transaction_identifier: + $ref: '#/components/schemas/TransactionIdentifier' + account_identifier: + $ref: '#/components/schemas/AccountIdentifier' + coin_identifier: + $ref: '#/components/schemas/CoinIdentifier' + currency: + $ref: '#/components/schemas/Currency' + status: + type: string + description: | + status is the network-specific operation type. + example: "reverted" + type: + type: string + description: | + type is the network-specific operation type. + example: "transfer" + address: + type: string + description: | + address is AccountIdentifier.Address. This is used to get all + transactions related to an AccountIdentifier.Address, regardless + of SubAccountIdentifier. + example: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + success: + type: boolean + description: | + success is a synthetic condition populated by parsing network-specific + operation statuses (using the mapping provided in `/network/options`). + SearchTransactionsResponse: + description: | + SearchTransactionsResponse contains an ordered collection of BlockTransactions + that match the query in SearchTransactionsRequest. These BlockTransactions + are sorted from most recent block to oldest block. + type: object + required: + - transactions + - total_count + properties: + transactions: + type: array + description: | + transactions is an array of BlockTransactions sorted by most recent + BlockIdentifier (meaning that transactions in recent blocks appear + first). + + If there are many transactions for a particular search, transactions + may not contain all matching transactions. It is up to the caller to + paginate these transactions using the max_block field. + items: + $ref: '#/components/schemas/BlockTransaction' + total_count: + description: | + total_count is the number of results for a given search. Callers + typically use this value to concurrently fetch results by offset + or to display a virtual page number associated with results. + type: integer + format: int64 + minimum: 0 + example: 5 + next_offset: + description: | + next_offset is the next offset to use when paginating through + transaction results. If this field is not populated, there are + no more transactions to query. + type: integer + format: int64 + minimum: 0 + example: 5 + + # Miscellaneous + Error: + $ref: 'models/Error.yaml' diff --git a/core-rust/mesh-api-server/mesh-cli-configs/default.json b/core-rust/mesh-api-server/mesh-cli-configs/default.json new file mode 100644 index 0000000000..8e460906d7 --- /dev/null +++ b/core-rust/mesh-api-server/mesh-cli-configs/default.json @@ -0,0 +1,72 @@ +{ + "network": { + "blockchain": "radix", + "network": "localnet" + }, + "online_url": "http://127.0.0.1:3337/mesh", + "data_directory": "test-data", + "http_timeout": 10, + "max_retries": 5, + "retry_elapsed_time": 0, + "max_online_connections": 120, + "max_sync_concurrency": 64, + "tip_delay": 300, + "max_reorg_depth": 100, + "log_configuration": false, + "compression_disabled": false, + "l0_in_memory_enabled": false, + "all_in_memory_enabled": false, + "error_stack_trace_disabled": false, + "coin_supported": false, + "data": { + "active_reconciliation_concurrency": 16, + "inactive_reconciliation_concurrency": 4, + "inactive_reconciliation_frequency": 250, + "log_blocks": false, + "log_transactions": false, + "log_balance_changes": false, + "log_reconciliations": false, + "ignore_reconciliation_error": false, + "exempt_accounts": "", + "bootstrap_balances": "", + "interesting_accounts": "", + "reconciliation_disabled": false, + "reconciliation_drain_disabled": false, + "inactive_discrepancy_search_disabled": false, + "balance_tracking_disabled": false, + "coin_tracking_disabled": false, + "status_port": 9090, + "results_output_file": "", + "pruning_block_disabled": false, + "pruning_balance_disabled": false, + "initial_balance_fetch_disabled": false, + "end_conditions": { + "tip": true, + "index": 10000 + } + }, + "construction": { + "offline_url": "http://localhost:3337/mesh", + "constructor_dsl_file": "workflows.ros", + "prefunded_accounts": [ + { + "account_identifier": { + "address": "account_loc16996e320lnez82q6430eunaz9l3n5fnwk6eh9avrmtmj22e7rd55ln" + }, + "curve_type": "secp256k1", + "privkey": "000000000000000000000000000000000000000000000000000000000000821f", + "currency": { + "symbol": "resource_loc1tknxxxxxxxxxradxrdxxxxxxxxx009923554798xxxxxxxxxvq32hv", + "decimals": 18 + } + } + ], + "stale_depth": 1000, + "broadcast_limit": 1000, + "end_conditions": { + "radix_workflow": 1 + } + }, + "perf": null, + "sign": null +} diff --git a/core-rust/mesh-api-server/mesh-cli-configs/workflows.ros b/core-rust/mesh-api-server/mesh-cli-configs/workflows.ros new file mode 100644 index 0000000000..637ceff711 --- /dev/null +++ b/core-rust/mesh-api-server/mesh-cli-configs/workflows.ros @@ -0,0 +1,65 @@ +radix_workflow(1){ + create_account{ + network = {"network":"localnet", "blockchain":"radix"}; + key = generate_key({"curve_type":"secp256k1"}); + recipient = derive({ + "network_identifier": {{network}}, + "public_key": {{key.public_key}} + }); + save_account({ + "account_identifier": {{recipient.account_identifier}}, + "keypair": {{key}} + }); + print_message("recipient:"); + print_message({{recipient}}); + }, + transfer{ + currency = {"symbol":"resource_loc1tknxxxxxxxxxradxrdxxxxxxxxx009923554798xxxxxxxxxvq32hv", "decimals":18}; + min_balance = "1111000000000000000000"; + + // sender account is the one of the prefunded_accounts + sender = find_balance({ + "minimum_balance":{ + "value": {{min_balance}}, + "currency": {{currency}} + } + }); + print_message("sender:"); + print_message({{sender}}); + + fee_amount = "22000000000000000000"; + // Negative values are badly interpreted by mesh-cli DSL parser, + // which might lead to errors such as: + // CONSTRUCTION FILE PARSING FAILED! + // Message: failed to parse action: the number of missing variables [deposit_amount] > 0: variable undefined + // Therefore workaround use below approach to specify negative value. + withdraw_amount = "0" - "33000000000000000000"; + deposit_amount = "33000000000000000000"; + + transfer.confirmation_depth = "1"; + transfer.network = {{network}}; + transfer.operations = [ + { + "operation_identifier":{"index":0}, + "type":"Withdraw", + "account":{{sender.account_identifier}}, + "amount":{ + "value":{{withdraw_amount}}, + "currency":{{currency}} + } + }, + { + "operation_identifier":{"index":1}, + "type":"Deposit", + "account":{{recipient.account_identifier}}, + "amount":{ + "value":{{deposit_amount}}, + "currency":{{currency}} + } + } + ]; + + print_message("transfer:"); + print_message({{transfer}}); + } +} diff --git a/core-rust/mesh-api-server/scripts/.gitignore b/core-rust/mesh-api-server/scripts/.gitignore new file mode 100644 index 0000000000..e9ffe3568f --- /dev/null +++ b/core-rust/mesh-api-server/scripts/.gitignore @@ -0,0 +1,2 @@ +temp +*.jar \ No newline at end of file diff --git a/core-rust/mesh-api-server/scripts/generate-openapi-server.py b/core-rust/mesh-api-server/scripts/generate-openapi-server.py new file mode 100755 index 0000000000..f3a877a4e8 --- /dev/null +++ b/core-rust/mesh-api-server/scripts/generate-openapi-server.py @@ -0,0 +1,172 @@ +#!/usr/bin/env python3 +import urllib.request, logging, subprocess, os, shutil, re + +# Inspired by https://github.com/radixdlt/radixdlt-python-clients +# Requires python 3+ and various packages above + +logger = logging.getLogger() +logging.basicConfig(format='%(asctime)s [%(levelname)s]: %(message)s', level=logging.INFO) + +MESH_API_SPEC_LOCATION = '../mesh-api-schema' +MESH_API_SPEC_API_FILE = 'schema.yaml' +# MESH_API_SPEC_MODELS_LOCATION = '../mesh-api-schema/models' +MESH_API_RUST_GENERATED_DESTINATION = '../src/mesh_api/generated/' +MESH_API_RUST_PACKAGE = 'mesh_api::generated' +MESH_API_JAVA_GENERATED_DESTINATION = '../../../core/src/test-core/java/' +MESH_API_JAVA_PACKAGE = 'com.radixdlt.api.mesh.generated' + +OPENAPI_GENERATION_FOLDER='.' +OPENAPI_TEMP_GENERATION_FOLDER='./temp' +OPENAPI_GENERATOR_FIXED_VERSION_JAR=os.path.join(OPENAPI_GENERATION_FOLDER, 'openapi-generator-cli-6.0.1.jar') +OPENAPI_GENERATOR_FIXED_VERSION_DOWNLOAD_URL='https://search.maven.org/remotecontent?filepath=org/openapitools/openapi-generator-cli/6.0.1/openapi-generator-cli-6.0.1.jar' + +def safe_os_remove(path, silent = False): + try: + shutil.rmtree(path) if os.path.isdir(path) else os.remove(path) + except Exception as e: + if not silent: logger.warning(e) + +def replace_in_file(filename, target, replacement): + with open(filename, 'r') as file: + file_contents = file.read() + file_contents = file_contents.replace(target, replacement) + with open(filename, 'w') as file: + file.write(str(file_contents)) + +def find_in_file_multiline(filename, regex): + with open(filename, 'r') as file: + file_contents = file.read() + return re.findall(regex, file_contents) + +def create_file(filename, file_contents): + with open(filename, 'w') as file: + file.write(str(file_contents)) + +def copy_file(source, dest): + shutil.copyfile(source, dest) + +def copy_tree(src, dst, symlinks=False, ignore=None): + for item in os.listdir(src): + s = os.path.join(src, item) + d = os.path.join(dst, item) + if os.path.isdir(s): + shutil.copytree(s, d, symlinks, ignore) + else: + shutil.copy2(s, d) + +def run(command, cwd = '.', should_log = False): + if (should_log): logging.debug('Running cmd: %s' % command) + response = subprocess.run(' '.join(command), cwd=cwd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + stderr = response.stderr.decode('utf-8') + if response.returncode != 0: raise Exception(stderr) + stdout = response.stdout.decode('utf-8') + if (should_log): logging.debug('Response: %s', stdout) + return stdout + +def generate_rust_models(schema_file, tmp_client_folder, out_location, rust_package): + safe_os_remove(out_location, True) + # See https://openapi-generator.tech/docs/generators/rust/ + run(['java', '-jar', OPENAPI_GENERATOR_FIXED_VERSION_JAR, 'generate', + '-g', 'rust', + '-i', schema_file, + '-o', tmp_client_folder, + ], should_log=False) + + logging.info("Successfully generated rust models.") + + rust_code_root = os.path.join(tmp_client_folder, 'src') + rust_models = os.path.join(rust_code_root, 'models') + out_models = os.path.join(out_location, 'models') + + os.makedirs(os.path.join(out_location)) + shutil.copytree(rust_models, out_models) + + def get_version_from_oas_file(file_path): + version_finds = find_in_file_multiline(schema_file, re.compile(" version: ([0-9\\.]+)")) + if len(version_finds) == 0: + return "UNKNOWN" + return version_finds[0] + + version = get_version_from_oas_file(schema_file) + logging.info("Version is: " + version) + create_file(os.path.join(out_location, 'mod.rs'), "pub mod models;\npub const SCHEMA_VERSION: &str = \"" + version + "\";\n") + + file_names = [file_name for file_name in os.listdir(out_models) if os.path.isfile(os.path.join(out_models, file_name))] + for file_name in file_names: + file_path = os.path.join(out_models, file_name) + # Fix changes due to putting generated files directly into the crate + replace_in_file(file_path, 'crate::', 'crate::' + rust_package + '::') + replace_in_file(file_path, ', Serialize, Deserialize', ', serde::Serialize, serde::Deserialize') + replace_in_file(file_path, '::std::collections::HashMap', '::utils::rust::prelude::IndexMap') + + logging.info("Successfully fixed up rust models.") + +def generate_java_models(schema_file, tmp_client_folder, out_location, java_package): + java_package_path = java_package.replace('.', '/') + safe_os_remove(out_location + java_package_path, True) + + api_package = java_package + '.api' + invoker_package = java_package + '.client' + models_package = java_package + '.models' + # See https://openapi-generator.tech/docs/generators/java + run(['java', '-jar', OPENAPI_GENERATOR_FIXED_VERSION_JAR, 'generate', + '-g', 'java', + '-i', schema_file, + '-o', tmp_client_folder, + '--additional-properties=openApiNullable=false,useOneOfDiscriminatorLookup=true,library=native,hideGenerationTimestamp=true,apiPackage={},invokerPackage={},modelPackage={}'.format(api_package, invoker_package, models_package), + ], should_log=False) + + logging.info("Successfully generated java models.") + + code_root = os.path.join(tmp_client_folder, 'src/main/java/' + java_package_path + '/') + shutil.copytree(code_root, out_location + java_package_path) + + logging.info("Successfully copied java models.") + +def fix_spec_and_generate_models(spec_path, rust_destination, rust_package, java_destination, java_package): + # download & fix the spec files + os.makedirs(OPENAPI_TEMP_GENERATION_FOLDER) + spec_basename = os.path.basename(spec_path) + spec_temp_path = os.path.join(OPENAPI_TEMP_GENERATION_FOLDER, spec_basename) + spec_temp_location = os.path.join(spec_temp_path, MESH_API_SPEC_API_FILE) + copy_tree(spec_path, spec_temp_path) + + + replace_in_file(spec_temp_location, 'openapi: 3.1.0', 'openapi: 3.0.0') + logging.info('Loaded spec from {}'.format(os.path.abspath(spec_temp_location))) + + logging.info('Generating code from spec...') + + generate_rust_models(spec_temp_location, os.path.join(OPENAPI_TEMP_GENERATION_FOLDER, "models-rust"), rust_destination, rust_package) + generate_java_models(spec_temp_location, os.path.join(OPENAPI_TEMP_GENERATION_FOLDER, "models-java"), java_destination, java_package) + + logging.info("Code has been created.") + + # clean up + safe_os_remove(OPENAPI_TEMP_GENERATION_FOLDER, silent=True) + +if __name__ == "__main__": + logger.info('Will generate models from the API specifications') + + # Set working directory to be the same directory as this script + os.chdir(os.path.dirname(os.path.abspath(__file__))) + + # check & download the openapi-generator.jar + if not os.path.exists(OPENAPI_GENERATOR_FIXED_VERSION_JAR): + logger.info('%s does not exist' % OPENAPI_GENERATOR_FIXED_VERSION_JAR) + logger.info('Will download it from %s...' % OPENAPI_GENERATOR_FIXED_VERSION_DOWNLOAD_URL) + urllib.request.urlretrieve(OPENAPI_GENERATOR_FIXED_VERSION_DOWNLOAD_URL, OPENAPI_GENERATOR_FIXED_VERSION_JAR) + logger.info('Testing the openapi-generator...') + logger.info(run(['ls %s' % OPENAPI_GENERATION_FOLDER])) + run(['java', '-jar', OPENAPI_GENERATOR_FIXED_VERSION_JAR, 'author'], should_log=False) + logger.info('All good.') + + safe_os_remove(OPENAPI_TEMP_GENERATION_FOLDER, silent=True) + + fix_spec_and_generate_models( + MESH_API_SPEC_LOCATION, + MESH_API_RUST_GENERATED_DESTINATION, + MESH_API_RUST_PACKAGE, + MESH_API_JAVA_GENERATED_DESTINATION, + MESH_API_JAVA_PACKAGE + ) diff --git a/core-rust/mesh-api-server/src/jni/mod.rs b/core-rust/mesh-api-server/src/jni/mod.rs new file mode 100644 index 0000000000..f1426a6870 --- /dev/null +++ b/core-rust/mesh-api-server/src/jni/mod.rs @@ -0,0 +1,177 @@ +/* Copyright 2021 Radix Publishing Ltd incorporated in Jersey (Channel Islands). + * + * Licensed under the Radix License, Version 1.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at: + * + * radixfoundation.org/licenses/LICENSE-v1 + * + * The Licensor hereby grants permission for the Canonical version of the Work to be + * published, distributed and used under or by reference to the Licensor’s trademark + * Radix ® and use of any unregistered trade names, logos or get-up. + * + * The Licensor provides the Work (and each Contributor provides its Contributions) on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, + * including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, + * MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. + * + * Whilst the Work is capable of being deployed, used and adopted (instantiated) to create + * a distributed ledger it is your responsibility to test and validate the code, together + * with all logic and performance of that code under all foreseeable scenarios. + * + * The Licensor does not make or purport to make and hereby excludes liability for all + * and any representation, warranty or undertaking in any form whatsoever, whether express + * or implied, to any entity or person, including any representation, warranty or + * undertaking, as to the functionality security use, value or other characteristics of + * any distributed ledger nor in respect the functioning or value of any tokens which may + * be created stored or transferred using the Work. The Licensor does not warrant that the + * Work or any use of the Work complies with any law or regulation in any territory where + * it may be implemented or used or that it will be appropriate for any specific purpose. + * + * Neither the licensor nor any current or former employees, officers, directors, partners, + * trustees, representatives, agents, advisors, contractors, or volunteers of the Licensor + * shall be liable for any direct or indirect, special, incidental, consequential or other + * losses of any kind, in tort, contract or otherwise (including but not limited to loss + * of revenue, income or profits, or loss of use or data, or loss of reputation, or loss + * of any economic or other opportunity of whatsoever nature or howsoever arising), arising + * out of or in connection with (without limitation of any use, misuse, of any ledger system + * or use made or its functionality or any performance or operation of any code or protocol + * caused by bugs or programming or logic errors or otherwise); + * + * A. any offer, purchase, holding, use, sale, exchange or transmission of any + * cryptographic keys, tokens or assets created, exchanged, stored or arising from any + * interaction with the Work; + * + * B. any failure in a transmission or loss of any token or assets keys or other digital + * artefacts due to errors in transmission; + * + * C. bugs, hacks, logic errors or faults in the Work or any communication; + * + * D. system software or apparatus including but not limited to losses caused by errors + * in holding or transmitting tokens by any third-party; + * + * E. breaches or failure of security including hacker attacks, loss or disclosure of + * password, loss of private key, unauthorised use or misuse of such passwords or keys; + * + * F. any losses including loss of anticipated savings or other benefits resulting from + * use of the Work or any changes to the Work (however implemented). + * + * You are solely responsible for; testing, validating and evaluation of all operation + * logic, functionality, security and appropriateness of using the Work for any commercial + * or non-commercial purpose and for any reproduction or redistribution by You of the + * Work. You assume all risks associated with Your use of the Work and the exercise of + * permissions under this License. + */ + +use crate::jni_prelude::*; +use crate::mesh_api::{create_server, MeshApiServerConfig, MeshApiState}; +use futures::channel::oneshot; +use futures::channel::oneshot::Sender; +use futures::FutureExt; +use prometheus::*; +use std::sync::{Arc, MutexGuard}; +use tokio::runtime::Runtime; + +use node_common::java::*; + +const POINTER_JNI_FIELD_NAME: &str = "rustMeshApiServerPointer"; + +pub struct RunningServer { + pub shutdown_signal_sender: Sender<()>, +} + +pub struct JNIMeshApiServer { + pub config: MeshApiServerConfig, + pub runtime: Arc, + pub state: MeshApiState, + pub running_server: Option, + pub metric_registry: Arc, +} + +#[no_mangle] +extern "system" fn Java_com_radixdlt_api_MeshApiServer_init( + env: JNIEnv, + _class: JClass, + j_rust_global_context: JObject, + j_mesh_api_server: JObject, + j_config: jbyteArray, +) { + jni_sbor_coded_call(&env, j_config, |config: MeshApiServerConfig| { + let jni_node_rust_env = JNINodeRustEnvironment::get(&env, j_rust_global_context); + + let jni_mesh_api_server = JNIMeshApiServer { + runtime: jni_node_rust_env.runtime.clone(), + state: MeshApiState { + network: jni_node_rust_env.network.clone(), + state_manager: jni_node_rust_env.state_manager.clone(), + node_display_version: config.node_display_version.clone(), + }, + config, + running_server: None, + metric_registry: jni_node_rust_env.metric_registry.clone(), + }; + + env.set_rust_field( + j_mesh_api_server, + POINTER_JNI_FIELD_NAME, + jni_mesh_api_server, + ) + .unwrap() + }); +} + +#[no_mangle] +extern "system" fn Java_com_radixdlt_api_MeshApiServer_start( + env: JNIEnv, + _class: JClass, + j_mesh_api_server: JObject, +) { + jni_call(&env, || { + let (shutdown_signal_sender, shutdown_signal_receiver) = oneshot::channel::<()>(); + + let mut jni_mesh_api_server: MutexGuard = env + .get_rust_field(j_mesh_api_server, POINTER_JNI_FIELD_NAME) + .unwrap(); + + let config = &jni_mesh_api_server.config; + + let state = jni_mesh_api_server.state.clone(); + let runtime = &jni_mesh_api_server.runtime; + let metric_registry = jni_mesh_api_server.metric_registry.clone(); + + let bind_addr = format!("{}:{}", config.bind_interface, config.port); + runtime.spawn(async move { + create_server( + &bind_addr, + shutdown_signal_receiver.map(|_| ()), + state, + &metric_registry, + ) + .await; + }); + + jni_mesh_api_server.running_server = Some(RunningServer { + shutdown_signal_sender, + }); + }); +} + +#[no_mangle] +extern "system" fn Java_com_radixdlt_api_MeshApiServer_stop( + env: JNIEnv, + _class: JClass, + j_mesh_api_server: JObject, +) { + jni_call(&env, || { + if let Ok(jni_mesh_api_server) = env.take_rust_field::( + j_mesh_api_server, + POINTER_JNI_FIELD_NAME, + ) { + if let Some(running_server) = jni_mesh_api_server.running_server { + running_server.shutdown_signal_sender.send(()).unwrap(); + } + // No-op, drop the jni_mesh_api_server + } + }); +} + +pub fn export_extern_functions() {} diff --git a/core-rust/mesh-api-server/src/lib.rs b/core-rust/mesh-api-server/src/lib.rs new file mode 100644 index 0000000000..db3b508c65 --- /dev/null +++ b/core-rust/mesh-api-server/src/lib.rs @@ -0,0 +1,105 @@ +/* Copyright 2021 Radix Publishing Ltd incorporated in Jersey (Channel Islands). + * + * Licensed under the Radix License, Version 1.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at: + * + * radixfoundation.org/licenses/LICENSE-v1 + * + * The Licensor hereby grants permission for the Canonical version of the Work to be + * published, distributed and used under or by reference to the Licensor’s trademark + * Radix ® and use of any unregistered trade names, logos or get-up. + * + * The Licensor provides the Work (and each Contributor provides its Contributions) on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, + * including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, + * MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. + * + * Whilst the Work is capable of being deployed, used and adopted (instantiated) to create + * a distributed ledger it is your responsibility to test and validate the code, together + * with all logic and performance of that code under all foreseeable scenarios. + * + * The Licensor does not make or purport to make and hereby excludes liability for all + * and any representation, warranty or undertaking in any form whatsoever, whether express + * or implied, to any entity or person, including any representation, warranty or + * undertaking, as to the functionality security use, value or other characteristics of + * any distributed ledger nor in respect the functioning or value of any tokens which may + * be created stored or transferred using the Work. The Licensor does not warrant that the + * Work or any use of the Work complies with any law or regulation in any territory where + * it may be implemented or used or that it will be appropriate for any specific purpose. + * + * Neither the licensor nor any current or former employees, officers, directors, partners, + * trustees, representatives, agents, advisors, contractors, or volunteers of the Licensor + * shall be liable for any direct or indirect, special, incidental, consequential or other + * losses of any kind, in tort, contract or otherwise (including but not limited to loss + * of revenue, income or profits, or loss of use or data, or loss of reputation, or loss + * of any economic or other opportunity of whatsoever nature or howsoever arising), arising + * out of or in connection with (without limitation of any use, misuse, of any ledger system + * or use made or its functionality or any performance or operation of any code or protocol + * caused by bugs or programming or logic errors or otherwise); + * + * A. any offer, purchase, holding, use, sale, exchange or transmission of any + * cryptographic keys, tokens or assets created, exchanged, stored or arising from any + * interaction with the Work; + * + * B. any failure in a transmission or loss of any token or assets keys or other digital + * artefacts due to errors in transmission; + * + * C. bugs, hacks, logic errors or faults in the Work or any communication; + * + * D. system software or apparatus including but not limited to losses caused by errors + * in holding or transmitting tokens by any third-party; + * + * E. breaches or failure of security including hacker attacks, loss or disclosure of + * password, loss of private key, unauthorised use or misuse of such passwords or keys; + * + * F. any losses including loss of anticipated savings or other benefits resulting from + * use of the Work or any changes to the Work (however implemented). + * + * You are solely responsible for; testing, validating and evaluation of all operation + * logic, functionality, security and appropriateness of using the Work for any commercial + * or non-commercial purpose and for any reproduction or redistribution by You of the + * Work. You assume all risks associated with Your use of the Work and the exercise of + * permissions under this License. + */ + +extern crate serde; +extern crate serde_json; + +pub mod jni; +mod mesh_api; + +#[allow(unused_imports)] +pub(crate) mod prelude { + pub(crate) use crate::engine_prelude::*; + pub(crate) use node_common::prelude::*; + pub(crate) use state_manager::prelude::*; + + pub(crate) use crate::mesh_api::*; + pub(crate) use borrow::Borrow; + pub(crate) use historical_state::*; + + // Axum imports + pub(crate) use axum::{ + body::BoxBody, + extract::State, + http::Uri, + response::{IntoResponse, Response}, + Json, + }; +} + +pub(crate) mod jni_prelude { + pub(crate) use crate::prelude::*; + pub(crate) use state_manager::jni_prelude::*; +} + +pub(crate) mod engine_prelude { + pub use radix_common::prelude::*; + pub use radix_engine::blueprints::account::*; + pub use radix_engine::blueprints::models::*; + pub use radix_engine::system::system_substates::*; + pub use radix_engine_interface::prelude::*; + pub use radix_substate_store_interface::interface::*; + pub use radix_substate_store_queries::typed_substate_layout::*; + pub use radix_transactions::model::*; +} diff --git a/core-rust/mesh-api-server/src/mesh_api/conversions/addressing.rs b/core-rust/mesh-api-server/src/mesh_api/conversions/addressing.rs new file mode 100644 index 0000000000..be650db91b --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/conversions/addressing.rs @@ -0,0 +1,132 @@ +use crate::prelude::*; + +pub fn extract_resource_address( + extraction_context: &ExtractionContext, + resource_address: &str, +) -> Result { + ResourceAddress::try_from_bech32(&extraction_context.address_decoder, resource_address) + .ok_or(ExtractionError::InvalidAddress) +} + +pub fn extract_component_address( + extraction_context: &ExtractionContext, + component_address: &str, +) -> Result { + ComponentAddress::try_from_bech32(&extraction_context.address_decoder, component_address) + .ok_or(ExtractionError::InvalidAddress) +} + +pub(crate) fn extract_resource_address_from_currency( + extraction_context: &ExtractionContext, + database: &StateManagerDatabase, + currency: &models::Currency, +) -> Result { + // currency.symbol field keeps bech32-encoded resource address + let resource_address = extract_resource_address(extraction_context, ¤cy.symbol)?; + let resource_node_id = resource_address.as_node_id(); + + if resource_node_id.entity_type() != Some(EntityType::GlobalFungibleResourceManager) { + return Err(ExtractionError::InvalidCurrency { + message: format!("currency {} is not fungible type", currency.symbol), + }); + } + + let divisibility: FungibleResourceManagerDivisibilityFieldSubstate = + read_optional_main_field_substate( + database, + resource_node_id, + &FungibleResourceManagerField::Divisibility.into(), + ) + .ok_or_else(|| ExtractionError::InvalidCurrency { + message: format!("currency {} not found", currency.symbol), + })?; + let divisibility = *divisibility.payload().as_unique_version() as i32; + + if divisibility != currency.decimals { + return Err(ExtractionError::InvalidCurrency { + message: format!( + "currency {} decimals mismatch, specified: {}, current: {}", + ¤cy.symbol, ¤cy.decimals, divisibility + ), + }); + } + Ok(resource_address) +} + +pub fn to_api_resource_address( + context: &MappingContext, + resource_address: &ResourceAddress, +) -> Result { + to_api_entity_address(context, resource_address.as_node_id()) +} + +pub fn to_api_entity_address( + context: &MappingContext, + node_id: &NodeId, +) -> Result { + context + .address_encoder + .encode(node_id.as_ref()) + .map_err(|err| MappingError::InvalidEntityAddress { encode_error: err }) +} + +pub fn to_api_account_identifier_from_global_address( + mapping_context: &MappingContext, + address: impl AsRef, +) -> Result { + let node_id: &NodeId = address.as_ref(); + let address = to_api_entity_address(mapping_context, node_id)?; + + // TODO:MESH remove account filtering + if !node_id.is_global_account() { + return Err(MappingError::InvalidAccount { + message: format!("address {} is not an account", address), + }); + } + + // See https://docs.cdp.coinbase.com/mesh/docs/models#accountidentifier for field + // definitions + Ok(models::AccountIdentifier { + address, + sub_account: None, + metadata: None, + }) +} + +pub fn to_api_account_identifier_from_public_key( + mapping_context: &MappingContext, + public_key: PublicKey, +) -> Result { + let address = mapping_context + .address_encoder + .encode(ComponentAddress::preallocated_account_from_public_key(&public_key).as_bytes()) + .map_err(|err| MappingError::InvalidEntityAddress { encode_error: err })?; + + // See https://docs.cdp.coinbase.com/mesh/docs/models#accountidentifier for field + // definitions + Ok(models::AccountIdentifier { + address, + sub_account: None, + metadata: None, + }) +} +pub fn extract_radix_account_address_from_account_identifier( + extraction_context: &ExtractionContext, + account_identifier: &models::AccountIdentifier, +) -> Result { + if account_identifier.sub_account.is_some() { + return Err(ExtractionError::InvalidAccount { + message: format!("Sub accounts not supported"), + }); + } + let component_address = + extract_component_address(extraction_context, &account_identifier.address)?; + + if component_address.as_node_id().is_global_account() { + Ok(component_address) + } else { + Err(ExtractionError::InvalidAccount { + message: format!("Whilst this API returns balance changes with an `AccountIdentifier` representing any global entity to allow full reconciliation, only Radix account addresses starting `account_` are accepted for the construction and account balance endpoints. {} is not a Radix account.", account_identifier.address), + }) + } +} diff --git a/core-rust/mesh-api-server/src/mesh_api/conversions/block.rs b/core-rust/mesh-api-server/src/mesh_api/conversions/block.rs new file mode 100644 index 0000000000..b729aee398 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/conversions/block.rs @@ -0,0 +1,140 @@ +use crate::prelude::*; + +const MAX_API_STATE_VERSION: u64 = 100000000000000; + +/// We assume that Block is a single transaction. +/// Block index => State version +/// Block hash => 32 bytes of: transaction_tree_hash[0..12] | receipt_tree_hash[0..12] | state_version +pub fn extract_state_version_from_block_hash( + database: &StateManagerDatabase, + block_hash: &str, +) -> Result { + if block_hash.len() == 32 { + let hash_bytes = + hex::decode(block_hash).map_err(|_| ExtractionError::InvalidBlockIdentifier { + message: format!("Error decoding block hash {}", block_hash), + })?; + + let mut index_bytes: [u8; 8] = [0; 8]; + index_bytes.copy_from_slice(&hash_bytes[24..]); + let index = u64::from_be_bytes(index_bytes); + + let state_version = StateVersion::of(index); + let transaction_identifiers = database + .get_committed_transaction_identifiers(state_version) + .ok_or_else(|| ExtractionError::NotFound)?; + + let transaction_tree_hash = transaction_identifiers + .resultant_ledger_hashes + .transaction_root; + let receipt_tree_hash = transaction_identifiers.resultant_ledger_hashes.receipt_root; + + if hash_bytes[..12] != transaction_tree_hash.as_slice()[0..12] { + return Err(ExtractionError::InvalidBlockIdentifier { + message: format!( + "Block hash {} does not match transaction tree hash", + block_hash + ), + }); + } + if hash_bytes[12..24] != receipt_tree_hash.as_slice()[0..12] { + return Err(ExtractionError::InvalidBlockIdentifier { + message: format!("Block hash {} does not match receipt tree hash", block_hash), + }); + } + + Ok(state_version) + } else { + Err(ExtractionError::InvalidBlockIdentifier { + message: format!("hash length {} not equal 32", block_hash.len()), + }) + } +} + +pub fn extract_state_version_from_mesh_api_partial_block_identifier( + database: &StateManagerDatabase, + block_identifier: &models::PartialBlockIdentifier, +) -> Result, ExtractionError> { + let state_version = match (&block_identifier.hash, &block_identifier.index) { + (None, None) => None, + (Some(hash), None) => Some(extract_state_version_from_block_hash(database, hash)?), + (None, Some(index)) => Some(StateVersion::of(*index as u64)), + (Some(hash), Some(index)) => { + let state_version = extract_state_version_from_block_hash(database, hash)?; + if *index as u64 == state_version.number() { + Some(state_version) + } else { + return Err(ExtractionError::InvalidBlockIdentifier { + message: format!("Hash {} does not match index {}", hash, index), + }); + } + } + }; + + Ok(state_version) +} + +pub fn extract_state_version_from_mesh_api_block_identifier( + database: &StateManagerDatabase, + block_identifier: &models::BlockIdentifier, +) -> Result { + let state_version_from_hash = + extract_state_version_from_block_hash(database, &block_identifier.hash)?; + if block_identifier.index as u64 != state_version_from_hash.number() { + Err(ExtractionError::InvalidBlockIdentifier { + message: format!( + "index {} and hash {} mismatch", + block_identifier.index, block_identifier.hash + ), + }) + } else { + Ok(StateVersion::of(block_identifier.index as u64)) + } +} + +pub fn to_mesh_api_block_identifier_from_state_version( + database: &StateManagerDatabase, + state_version: StateVersion, +) -> Result { + let index = to_mesh_api_block_index_from_state_version(state_version)?; + let transaction_identifiers = database + .get_committed_transaction_identifiers(state_version) + .ok_or_else(|| MappingError::TransactionNotFound)?; + + let transaction_tree_hash = transaction_identifiers + .resultant_ledger_hashes + .transaction_root; + let receipt_tree_hash = transaction_identifiers.resultant_ledger_hashes.receipt_root; + + let mut hash_bytes = [0u8; 32]; + + hash_bytes[..12].copy_from_slice(&transaction_tree_hash.as_slice()[..12]); + hash_bytes[12..24].copy_from_slice(&receipt_tree_hash.as_slice()[..12]); + hash_bytes[24..].copy_from_slice((index as u64).to_be_bytes().as_slice()); + + Ok(models::BlockIdentifier { + index, + hash: hex::encode(hash_bytes), + }) +} + +pub fn to_mesh_api_block_identifier_from_ledger_header( + database: &StateManagerDatabase, + ledger_header: &LedgerStateSummary, +) -> Result { + to_mesh_api_block_identifier_from_state_version(database, ledger_header.state_version) +} + +pub fn to_mesh_api_block_index_from_state_version( + state_version: StateVersion, +) -> Result { + let state_version_number = state_version.number(); + if state_version_number > MAX_API_STATE_VERSION { + return Err(MappingError::IntegerError { + message: "State version larger than max api state version".to_owned(), + }); + } + Ok(state_version_number + .try_into() + .expect("State version too large somehow")) +} diff --git a/core-rust/mesh-api-server/src/mesh_api/conversions/context.rs b/core-rust/mesh-api-server/src/mesh_api/conversions/context.rs new file mode 100644 index 0000000000..7f6a1d6ce3 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/conversions/context.rs @@ -0,0 +1,29 @@ +use crate::prelude::*; + +pub struct MappingContext { + pub address_encoder: AddressBech32Encoder, + pub transaction_hash_encoder: TransactionHashBech32Encoder, +} + +impl MappingContext { + pub fn new(network_definition: &NetworkDefinition) -> Self { + Self { + address_encoder: AddressBech32Encoder::new(network_definition), + transaction_hash_encoder: TransactionHashBech32Encoder::new(network_definition), + } + } +} + +pub struct ExtractionContext { + pub address_decoder: AddressBech32Decoder, + pub transaction_hash_decoder: TransactionHashBech32Decoder, +} + +impl ExtractionContext { + pub fn new(network_definition: &NetworkDefinition) -> Self { + Self { + address_decoder: AddressBech32Decoder::new(network_definition), + transaction_hash_decoder: TransactionHashBech32Decoder::new(network_definition), + } + } +} diff --git a/core-rust/mesh-api-server/src/mesh_api/conversions/crypto.rs b/core-rust/mesh-api-server/src/mesh_api/conversions/crypto.rs new file mode 100644 index 0000000000..69b65a1b14 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/conversions/crypto.rs @@ -0,0 +1,64 @@ +use crate::prelude::*; +use models::SignatureType; + +pub(crate) fn extract_public_key( + public_key: &crate::mesh_api::generated::models::PublicKey, +) -> Result { + // https://docs.cdp.coinbase.com/mesh/docs/models#curvetype + // - secp256k1 is SEC compressed, in line with canonical Radix encoding + // - ed25519 is y (255-bits) + x-sign-bit (1-bit), in line with canonical Radix encoding + match public_key.curve_type { + models::CurveType::Secp256k1 => Ok(PublicKey::Secp256k1( + hex::decode(&public_key.hex_bytes) + .ok() + .and_then(|bytes| Secp256k1PublicKey::try_from(bytes.as_slice()).ok()) + .ok_or(ExtractionError::InvalidSecp256k1PublicKey( + public_key.hex_bytes.clone(), + ))?, + )), + models::CurveType::Edwards25519 => Ok(PublicKey::Ed25519( + hex::decode(&public_key.hex_bytes) + .ok() + .and_then(|bytes| Ed25519PublicKey::try_from(bytes.as_slice()).ok()) + .ok_or(ExtractionError::InvalidEd25519PublicKey( + public_key.hex_bytes.clone(), + ))?, + )), + t => Err(ExtractionError::InvalidCurveType(t)), + } +} + +pub(crate) fn extract_signature( + signature: &crate::mesh_api::generated::models::Signature, +) -> Result { + // https://docs.cdp.coinbase.com/mesh/docs/models#signaturetype + // - ecdsa_recovery is r (32-bytes) + s (32-bytes) + v (1-byte), so Radix encoding needs reformatting + // - ed25519 is R (32-bytes) + s (32-bytes), in line with canonical Radix encoding + // - We don't support ecdsa (no recovery) + match signature.signature_type { + SignatureType::EcdsaRecovery => Ok(SignatureV1::Secp256k1( + hex::decode(&signature.hex_bytes) + .ok() + .and_then(|mut bytes| { + // Mesh uses r + s + v + // Radix uses v + r + s + if let Some(v) = bytes.pop() { + bytes.insert(0, v); + } + Secp256k1Signature::try_from(bytes.as_slice()).ok() + }) + .ok_or(ExtractionError::InvalidSecp256k1Signature( + signature.hex_bytes.clone(), + ))?, + )), + SignatureType::Ed25519 => Ok(SignatureV1::Ed25519( + hex::decode(&signature.hex_bytes) + .ok() + .and_then(|bytes| Ed25519Signature::try_from(bytes.as_slice()).ok()) + .ok_or(ExtractionError::InvalidEd25519Signature( + signature.hex_bytes.clone(), + ))?, + )), + t => Err(ExtractionError::InvalidSignatureType(t)), + } +} diff --git a/core-rust/mesh-api-server/src/mesh_api/conversions/currency.rs b/core-rust/mesh-api-server/src/mesh_api/conversions/currency.rs new file mode 100644 index 0000000000..5cdccac3aa --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/conversions/currency.rs @@ -0,0 +1,36 @@ +use crate::prelude::*; + +pub fn to_mesh_api_currency_from_resource_address( + mapping_context: &MappingContext, + database: &StateManagerDatabase, + resource_address: &ResourceAddress, +) -> Result { + let resource_node_id = resource_address.as_node_id(); + // currency.symbol field keeps bech32-encoded resource address + let symbol = to_api_resource_address(mapping_context, resource_address)?; + + if resource_node_id.entity_type() != Some(EntityType::GlobalFungibleResourceManager) { + return Err(MappingError::InvalidResource { + message: format!("resource {} is not fungible type", symbol), + }); + } + + let divisibility: FungibleResourceManagerDivisibilityFieldSubstate = + read_optional_main_field_substate( + database, + resource_node_id, + &FungibleResourceManagerField::Divisibility.into(), + ) + .ok_or_else(|| MappingError::InvalidResource { + message: format!("currency {} not found", symbol), + })?; + let decimals = *divisibility.payload().as_unique_version() as i32; + + // See https://docs.cdp.coinbase.com/mesh/docs/models#currency for field + // definitions + Ok(models::Currency { + symbol, + decimals, + metadata: None, + }) +} diff --git a/core-rust/mesh-api-server/src/mesh_api/conversions/errors.rs b/core-rust/mesh-api-server/src/mesh_api/conversions/errors.rs new file mode 100644 index 0000000000..a341a9025b --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/conversions/errors.rs @@ -0,0 +1,84 @@ +use crate::engine_prelude::*; +use crate::mesh_api::*; + +#[derive(Debug, Clone)] +#[allow(unused)] // Debug is ignored for dead code analysis, but is used in the error messages +pub enum MappingError { + InvalidTransactionHash { + encode_error: TransactionHashBech32EncodeError, + }, + InvalidEntityAddress { + encode_error: AddressBech32EncodeError, + }, + MismatchedSubstateId { + message: String, + }, + IntegerError { + message: String, + }, + KeyValueStoreEntryUnexpectedlyAbsent, + ProofNotFound, + InvalidResource { + message: String, + }, + InvalidAccount { + message: String, + }, + InvalidTransactionIdentifier { + message: String, + }, + /// An error occurring when the contents of some Node-maintained index table do not match the + /// Engine-owned data (most likely due to a bug on either side). + InternalIndexDataMismatch { + message: String, + }, + TransactionNotFound, +} + +impl From for ResponseError { + fn from(mapping_error: MappingError) -> Self { + ResponseError::from(ApiError::ResponseRenderingError) + .with_details(format!("{:?}", mapping_error)) + } +} + +/// Should be used when extracting values from a client request +#[derive(Debug, Clone)] +#[allow(clippy::enum_variant_names)] +#[allow(unused)] // Fields are used in Debug implementations, but it's not enough to satisfy the lint +pub enum ExtractionError { + InvalidInteger { message: String }, + InvalidHash, + InvalidAddress, + InvalidAccount { message: String }, + InvalidBlockIdentifier { message: String }, + InvalidCurrency { message: String }, + NotFound, + InvalidCurveType(models::CurveType), + InvalidSecp256k1PublicKey(String), + InvalidEd25519PublicKey(String), + InvalidSignatureType(models::SignatureType), + InvalidSecp256k1Signature(String), + InvalidEd25519Signature(String), + InvalidAmount(models::Amount), +} + +impl ExtractionError { + pub(crate) fn into_response_error(self, field_name: &str) -> ResponseError { + match self { + ExtractionError::InvalidBlockIdentifier { message } => { + ResponseError::from(ApiError::InvalidBlockIdentifier).with_details(message) + } + ExtractionError::InvalidAccount { message } => { + ResponseError::from(ApiError::InvalidAccount).with_details(message) + } + ExtractionError::InvalidCurrency { message } => { + ResponseError::from(ApiError::InvalidCurrency).with_details(message) + } + _ => ResponseError::from(ApiError::InvalidRequest).with_details(format!( + "Could not extract {field_name} from request, {:?}", + self + )), + } + } +} diff --git a/core-rust/mesh-api-server/src/mesh_api/conversions/mod.rs b/core-rust/mesh-api-server/src/mesh_api/conversions/mod.rs new file mode 100644 index 0000000000..93fcc82d65 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/conversions/mod.rs @@ -0,0 +1,19 @@ +mod addressing; +mod block; +mod context; +mod crypto; +mod currency; +mod errors; +mod numerics; +mod operations; +mod transaction; + +pub use addressing::*; +pub use block::*; +pub use context::*; +pub(crate) use crypto::*; +pub use currency::*; +pub use errors::*; +pub use numerics::*; +pub(crate) use operations::*; +pub use transaction::*; diff --git a/core-rust/mesh-api-server/src/mesh_api/conversions/numerics.rs b/core-rust/mesh-api-server/src/mesh_api/conversions/numerics.rs new file mode 100644 index 0000000000..122dfb0dfd --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/conversions/numerics.rs @@ -0,0 +1,54 @@ +use crate::prelude::*; + +// TODO:MESH Might be nice to have a few mini unit tests here to verify +// that extract_amount and to_mesh_api_amount are opposites and can work +// with e.g. a currency at different number of decimals. +pub(crate) fn extract_amount( + extraction_context: &ExtractionContext, + amount: &models::Amount, +) -> Result<(ResourceAddress, Decimal), ExtractionError> { + let address = ResourceAddress::try_from_bech32( + &extraction_context.address_decoder, + &amount.currency.symbol, + ) + .ok_or(ExtractionError::InvalidAmount(amount.clone()))?; + + let scale = if amount.currency.decimals < 0 || amount.currency.decimals > 18 { + return Err(ExtractionError::InvalidAmount(amount.clone())); + } else { + dec!(10) + .checked_powi(amount.currency.decimals as i64) + .unwrap() + }; + + let quantity = Decimal::from_str(&amount.value) + .ok() + .and_then(|x| x.checked_div(scale)) + .ok_or(ExtractionError::InvalidAmount(amount.clone()))?; + + Ok((address, quantity)) +} + +pub(crate) fn extract_amount_from_option( + extraction_context: &ExtractionContext, + amount: Option>, +) -> Result<(ResourceAddress, Decimal), ExtractionError> { + extract_amount( + extraction_context, + amount.ok_or(ExtractionError::NotFound)?.borrow(), + ) +} + +pub fn to_mesh_api_amount( + amount: Decimal, + currency: models::Currency, +) -> Result { + let value = amount + / Decimal::TEN + .checked_powi((Decimal::SCALE as i32 - currency.decimals) as i64) + .ok_or_else(|| MappingError::IntegerError { + message: "Integer overflow".to_string(), + })?; + + Ok(models::Amount::new(value.attos().to_string(), currency)) +} diff --git a/core-rust/mesh-api-server/src/mesh_api/conversions/operations.rs b/core-rust/mesh-api-server/src/mesh_api/conversions/operations.rs new file mode 100644 index 0000000000..5f65788dd8 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/conversions/operations.rs @@ -0,0 +1,142 @@ +use crate::engine_prelude::*; +use crate::prelude::*; + +#[derive(Debug, Clone, Copy, EnumIter, Display, EnumString)] +pub(crate) enum MeshApiOperationType { + Withdraw, + Deposit, +} + +#[derive(Debug, Clone, Copy, EnumIter, Display)] +pub(crate) enum MeshApiOperationStatus { + #[strum(serialize = "Success")] + Success, + #[strum(serialize = "Failure")] + Failure, +} + +// TODO:MESH This one might be confusing. Failed transaction will still have successful FeePayment +// operation +impl From for MeshApiOperationStatus { + fn from(value: DetailedTransactionOutcome) -> Self { + match value { + DetailedTransactionOutcome::Success(..) => Self::Success, + DetailedTransactionOutcome::Failure(..) => Self::Failure, + } + } +} + +impl From for models::OperationStatus { + fn from(value: MeshApiOperationStatus) -> Self { + let successful = match value { + MeshApiOperationStatus::Failure => false, + MeshApiOperationStatus::Success => true, + }; + Self::new(value.to_string(), successful) + } +} + +pub fn to_mesh_api_operation_no_fee( + mapping_context: &MappingContext, + database: &StateManagerDatabase, + index: i64, + status: Option, + account_address: &GlobalAddress, + resource_address: &ResourceAddress, + amount: Decimal, +) -> Result { + // TODO:MESH what about fee locking, burning, minting? + let op_type = if amount.is_positive() { + MeshApiOperationType::Deposit + } else { + MeshApiOperationType::Withdraw + }; + let currency = + to_mesh_api_currency_from_resource_address(mapping_context, database, resource_address)?; + let account = to_api_account_identifier_from_global_address(mapping_context, account_address)?; + + // see https://docs.cdp.coinbase.com/mesh/docs/models#operation + Ok(models::Operation { + operation_identifier: Box::new(models::OperationIdentifier::new(index)), + related_operations: None, + _type: op_type.to_string(), + status: status.map(|s| s.to_string()), + account: Some(Box::new(account)), + amount: Some(Box::new(to_mesh_api_amount(amount, currency)?)), + coin_change: None, + metadata: None, + }) +} + +pub fn to_mesh_api_operations( + mapping_context: &MappingContext, + database: &StateManagerDatabase, + state_version: StateVersion, +) -> Result, MappingError> { + let local_execution = database + .get_committed_local_transaction_execution(state_version) + .ok_or_else(|| MappingError::InvalidTransactionIdentifier { + message: format!( + "No transaction found at state version {}", + state_version.number() + ), + })?; + let status = MeshApiOperationStatus::from(local_execution.outcome); + let fee_balance_changes = + resolve_global_fee_balance_changes(database, &local_execution.fee_source)?; + + let fee_payment_computation = FeePaymentComputer::compute(FeePaymentComputationInputs { + fee_balance_changes, + fee_summary: &local_execution.fee_summary, + fee_destination: &local_execution.fee_destination, + balance_changes: &local_execution + .global_balance_summary + .global_balance_changes, + }); + + let mut output = Vec::with_capacity(fee_payment_computation.relevant_entities.len()); + for entity in &fee_payment_computation.relevant_entities { + if entity.is_account() { + if let Some(non_fee_balance_changes) = + fee_payment_computation.non_fee_balance_changes.get(&entity) + { + for (resource_address, amount) in non_fee_balance_changes { + let operation = to_mesh_api_operation_no_fee( + mapping_context, + database, + output.len() as i64, + Some(status), + entity, + resource_address, + *amount, + )?; + output.push(operation) + } + } + } + } + + Ok(output) +} + +/// Uses the [`SubstateNodeAncestryStore`] (from the given DB) to transform the input +/// `vault ID -> payment` map into a `global address -> balance change` map. +fn resolve_global_fee_balance_changes( + database: &StateManagerDatabase, + fee_source: &FeeSource, +) -> Result, MappingError> { + let paying_vaults = &fee_source.paying_vaults; + let ancestries = database.batch_get_ancestry(paying_vaults.keys()); + let mut fee_balance_changes = index_map_new(); + for ((vault_id, paid_fee_amount_xrd), ancestry) in paying_vaults.iter().zip(ancestries) { + let ancestry = ancestry.ok_or_else(|| MappingError::InternalIndexDataMismatch { + message: format!("no ancestry record for vault {}", vault_id.to_hex()), + })?; + let global_ancestor_address = GlobalAddress::new_or_panic(ancestry.root.0.into()); + let fee_balance_change = fee_balance_changes + .entry(global_ancestor_address) + .or_insert_with(Decimal::zero); + *fee_balance_change = fee_balance_change.sub_or_panic(*paid_fee_amount_xrd); + } + Ok(fee_balance_changes) +} diff --git a/core-rust/mesh-api-server/src/mesh_api/conversions/transaction.rs b/core-rust/mesh-api-server/src/mesh_api/conversions/transaction.rs new file mode 100644 index 0000000000..ac155e6146 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/conversions/transaction.rs @@ -0,0 +1,57 @@ +use crate::prelude::*; + +pub fn extract_transaction_intent_hash( + context: &ExtractionContext, + hash_str: String, +) -> Result { + hex::decode(&hash_str) + .ok() + .and_then(|bytes| Hash::try_from(bytes.as_slice()).ok()) + .map(TransactionIntentHash::from_hash) + .or_else(|| { + context + .transaction_hash_decoder + .validate_and_decode(&hash_str) + .ok() + }) + .ok_or(ExtractionError::InvalidHash) +} + +pub fn to_api_transaction_hash_bech32m( + context: &MappingContext, + hash: &T, +) -> Result { + context + .transaction_hash_encoder + .encode(hash) + .map_err(|err| MappingError::InvalidTransactionHash { encode_error: err }) +} + +pub fn to_mesh_api_transaction_identifier_from_hash(hash: String) -> models::TransactionIdentifier { + models::TransactionIdentifier { hash } +} + +pub fn to_mesh_api_transaction_identifier( + mapping_context: &MappingContext, + transaction_identifiers: &CommittedTransactionIdentifiers, +) -> Result { + let transaction_identifier = match transaction_identifiers.transaction_hashes.as_user() { + // Unfortunately non-user transactions don't have txid, let's use ledger_transaction_hash as + // transaction_identifier. + // In case if needed to map it to state version, it is possible using + // `get_txn_state_version_by_identifier()` + None => to_api_transaction_hash_bech32m( + mapping_context, + &transaction_identifiers + .transaction_hashes + .ledger_transaction_hash, + )?, + Some(user_hashes) => { + to_api_transaction_hash_bech32m(mapping_context, &user_hashes.transaction_intent_hash)? + } + }; + + Ok(to_mesh_api_transaction_identifier_from_hash( + transaction_identifier, + )) +} diff --git a/core-rust/mesh-api-server/src/mesh_api/errors.rs b/core-rust/mesh-api-server/src/mesh_api/errors.rs new file mode 100644 index 0000000000..6f0b54173d --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/errors.rs @@ -0,0 +1,227 @@ +use crate::prelude::*; +use hyper::StatusCode; +use rand::distributions::Alphanumeric; +use rand::Rng; +use std::any::Any; +use strum::{Display, EnumIter, IntoEnumIterator}; +use tower_http::catch_panic::ResponseForPanic; + +#[derive(Debug, Clone, EnumIter, Display)] +#[repr(i32)] +pub(crate) enum ApiError { + #[strum(serialize = "Endpoint not found")] + EndpointNotFound = 1, + #[strum(serialize = "Endpoint not supported")] + EndpointNotSupported, + #[strum(serialize = "Unexpected server error")] + UnexpectedServerError, + #[strum(serialize = "Invalid network")] + InvalidNetwork, + #[strum(serialize = "Invalid request")] + InvalidRequest, + #[strum(serialize = "Could not render response")] + ResponseRenderingError, + #[strum(serialize = "Invalid account")] + InvalidAccount, + #[strum(serialize = "Invalid currency")] + InvalidCurrency, + #[strum(serialize = "Transaction not found")] + TransactionNotFound, + #[strum(serialize = "Invalid number of signatures")] + InvalidNumberOfSignatures, + #[strum(serialize = "Invalid transaction")] + InvalidTransaction, + #[strum(serialize = "Invalid Withdraw instruction")] + InvalidWithdrawInstruction, + #[strum(serialize = "Named address not supported")] + NamedAddressNotSupported, + #[strum(serialize = "Instruction is not recognized")] + UnrecognizedInstruction, + #[strum(serialize = "Invalid number of public keys")] + InvalidNumberOfPublicKeys, + #[strum(serialize = "Invalid metadata")] + InvalidMetadata, + #[strum(serialize = "Invalid operation")] + InvalidOperation, + #[strum(serialize = "Invalid number of senders")] + InvalidNumberOfSenders, + #[strum(serialize = "Parent block not available")] + ParentBlockNotAvailable, + #[strum(serialize = "Invalid block identifier")] + InvalidBlockIdentifier, + #[strum(serialize = "Submit transaction error")] + SubmitTransactionError, +} + +impl From for ResponseError { + fn from(error: ApiError) -> Self { + Self::new(error.clone() as i32, error.to_string(), false) + } +} + +pub fn list_available_api_errors() -> Vec { + ApiError::iter() + .map(|v| ResponseError::from(v).error) + .collect() +} + +#[derive(Debug, Clone)] +pub(crate) struct InternalServerErrorResponseForPanic; + +impl ResponseForPanic for InternalServerErrorResponseForPanic { + type ResponseBody = BoxBody; + + fn response_for_panic( + &mut self, + _panic_payload: Box, + ) -> Response { + // Please note that we deliberately do *not*: + // - log the panic payload (since the default panic handler already does this); + // - include the panic payload in the response (it may contain sensitive details). + ResponseError::from(ApiError::UnexpectedServerError) + .with_details("Panic caught during request-handling; see logged panic payload") + .into_response() + } +} + +#[derive(Debug, Clone)] +pub(crate) struct ResponseError { + status_code: StatusCode, + error: models::Error, +} + +impl ResponseError { + pub fn new(code: i32, error_message: impl Into, retryable: bool) -> Self { + Self { + // "500" should be returned in case of unexpected error + status_code: StatusCode::INTERNAL_SERVER_ERROR, + error: models::Error::new(code, error_message.into(), retryable), + } + } + + #[allow(unused)] + pub fn retryable(self, retryable: bool) -> Self { + Self { + error: models::Error { + retriable: retryable, + ..self.error + }, + ..self + } + } + + pub fn with_details(self, details_message: impl Into) -> Self { + Self { + error: models::Error { + details: Some(serde_json::json!({ + "details_message": details_message.into(), + })), + ..self.error + }, + ..self + } + } +} + +#[derive(Debug, Clone)] +pub struct TraceId(pub String); + +impl TraceId { + pub fn unique() -> Self { + Self( + rand::thread_rng() + .sample_iter(&Alphanumeric) + .take(32) + .map(char::from) + .collect(), + ) + } +} + +#[derive(Debug, Clone)] +pub struct ErrorResponseEvent { + pub level: LogLevel, + pub error: models::Error, +} + +impl IntoResponse for ResponseError { + fn into_response(self) -> Response { + let trace_id = TraceId::unique(); + let mut returned_body = self.error; + + if let Some(ref mut details) = returned_body.details { + if let Some(map) = details.as_object_mut() { + map.insert( + "trace_id".to_string(), + serde_json::Value::String(trace_id.0), + ); + } + } else { + returned_body.details = Some(serde_json::json!({ + "trace_id": trace_id.0, + })); + } + + let error_response_event = ErrorResponseEvent { + level: resolve_level(self.status_code), + error: returned_body.clone(), + }; + let mut framework_response = (self.status_code, Json(returned_body)).into_response(); + framework_response + .extensions_mut() + .insert(error_response_event); + framework_response + } +} + +fn resolve_level(status_code: StatusCode) -> LogLevel { + if status_code.is_server_error() { + LogLevel::WARN + } else { + LogLevel::DEBUG + } +} + +/// A function to be used within a `map_response` layer in order to emit more customized events when +/// top-level `ErrorResponse` is returned. +/// In short, it is supposed to replace an `err(Debug)` within `#[tracing::instrument(...)]` of +/// every handler function which returns `Result<_, ResponseError<_>>`. It emits almost the same +/// information (except for emitting the path instead of the handler function name). +pub async fn emit_error_response_event(uri: Uri, response: Response) -> Response { + let event = response.extensions().get::(); + if let Some(event) = event { + let ErrorResponseEvent { level, error } = event; + let internal_message = error + .details + .as_ref() + .map(|d| d.to_string()) + .unwrap_or_else(|| "no_details".to_string()) + .to_string(); + match *level { + LogLevel::TRACE => trace!(path = uri.path(), error = debug(error), internal_message), + LogLevel::DEBUG => debug!(path = uri.path(), error = debug(error), internal_message), + LogLevel::INFO => info!(path = uri.path(), error = debug(error), internal_message), + LogLevel::WARN => warn!(path = uri.path(), error = debug(error), internal_message), + LogLevel::ERROR => error!(path = uri.path(), error = debug(error), internal_message), + } + } + response +} + +pub(crate) fn assert_matching_network( + network_identifier: &models::NetworkIdentifier, + network_definition: &NetworkDefinition, +) -> Result<(), ResponseError> { + if network_identifier.network != network_definition.logical_name { + return Err( + ResponseError::from(ApiError::InvalidNetwork).with_details(format!( + "Invalid network - the network is actually: {}", + network_definition.logical_name + )), + ); + } else if network_identifier.sub_network_identifier.is_some() { + return Err(ResponseError::from(ApiError::InvalidNetwork) + .with_details(format!("Invalid network - subnetworks not supported",))); + } + Ok(()) +} diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/mod.rs b/core-rust/mesh-api-server/src/mesh_api/generated/mod.rs new file mode 100644 index 0000000000..5012077b34 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/mod.rs @@ -0,0 +1,2 @@ +pub mod models; +pub const SCHEMA_VERSION: &str = "1.4.13"; diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/account_balance_request.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/account_balance_request.rs new file mode 100644 index 0000000000..3a776ba4f1 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/account_balance_request.rs @@ -0,0 +1,40 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// AccountBalanceRequest : An AccountBalanceRequest is utilized to make a balance request on the /account/balance endpoint. If the block_identifier is populated, a historical balance query should be performed. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct AccountBalanceRequest { + #[serde(rename = "network_identifier")] + pub network_identifier: Box, + #[serde(rename = "account_identifier")] + pub account_identifier: Box, + #[serde(rename = "block_identifier", skip_serializing_if = "Option::is_none")] + pub block_identifier: Option>, + /// In some cases, the caller may not want to retrieve all available balances for an AccountIdentifier. If the currencies field is populated, only balances for the specified currencies will be returned. If not populated, all available balances will be returned. + #[serde(rename = "currencies", skip_serializing_if = "Option::is_none")] + pub currencies: Option>, +} + +impl AccountBalanceRequest { + /// An AccountBalanceRequest is utilized to make a balance request on the /account/balance endpoint. If the block_identifier is populated, a historical balance query should be performed. + pub fn new(network_identifier: crate::mesh_api::generated::models::NetworkIdentifier, account_identifier: crate::mesh_api::generated::models::AccountIdentifier) -> AccountBalanceRequest { + AccountBalanceRequest { + network_identifier: Box::new(network_identifier), + account_identifier: Box::new(account_identifier), + block_identifier: None, + currencies: None, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/account_balance_response.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/account_balance_response.rs new file mode 100644 index 0000000000..0ee07e801a --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/account_balance_response.rs @@ -0,0 +1,38 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// AccountBalanceResponse : An AccountBalanceResponse is returned on the /account/balance endpoint. If an account has a balance for each AccountIdentifier describing it (ex: an ERC-20 token balance on a few smart contracts), an account balance request must be made with each AccountIdentifier. The `coins` field was removed and replaced by by `/account/coins` in `v1.4.7`. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct AccountBalanceResponse { + #[serde(rename = "block_identifier")] + pub block_identifier: Box, + /// A single account may have a balance in multiple currencies. + #[serde(rename = "balances")] + pub balances: Vec, + /// Account-based blockchains that utilize a nonce or sequence number should include that number in the metadata. This number could be unique to the identifier or global across the account address. + #[serde(rename = "metadata", skip_serializing_if = "Option::is_none")] + pub metadata: Option, +} + +impl AccountBalanceResponse { + /// An AccountBalanceResponse is returned on the /account/balance endpoint. If an account has a balance for each AccountIdentifier describing it (ex: an ERC-20 token balance on a few smart contracts), an account balance request must be made with each AccountIdentifier. The `coins` field was removed and replaced by by `/account/coins` in `v1.4.7`. + pub fn new(block_identifier: crate::mesh_api::generated::models::BlockIdentifier, balances: Vec) -> AccountBalanceResponse { + AccountBalanceResponse { + block_identifier: Box::new(block_identifier), + balances, + metadata: None, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/account_coins_request.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/account_coins_request.rs new file mode 100644 index 0000000000..3827fadf4e --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/account_coins_request.rs @@ -0,0 +1,41 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// AccountCoinsRequest : AccountCoinsRequest is utilized to make a request on the /account/coins endpoint. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct AccountCoinsRequest { + #[serde(rename = "network_identifier")] + pub network_identifier: Box, + #[serde(rename = "account_identifier")] + pub account_identifier: Box, + /// Include state from the mempool when looking up an account's unspent coins. Note, using this functionality breaks any guarantee of idempotency. + #[serde(rename = "include_mempool")] + pub include_mempool: bool, + /// In some cases, the caller may not want to retrieve coins for all currencies for an AccountIdentifier. If the currencies field is populated, only coins for the specified currencies will be returned. If not populated, all unspent coins will be returned. + #[serde(rename = "currencies", skip_serializing_if = "Option::is_none")] + pub currencies: Option>, +} + +impl AccountCoinsRequest { + /// AccountCoinsRequest is utilized to make a request on the /account/coins endpoint. + pub fn new(network_identifier: crate::mesh_api::generated::models::NetworkIdentifier, account_identifier: crate::mesh_api::generated::models::AccountIdentifier, include_mempool: bool) -> AccountCoinsRequest { + AccountCoinsRequest { + network_identifier: Box::new(network_identifier), + account_identifier: Box::new(account_identifier), + include_mempool, + currencies: None, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/account_coins_response.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/account_coins_response.rs new file mode 100644 index 0000000000..fb5feb6f37 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/account_coins_response.rs @@ -0,0 +1,38 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// AccountCoinsResponse : AccountCoinsResponse is returned on the /account/coins endpoint and includes all unspent Coins owned by an AccountIdentifier. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct AccountCoinsResponse { + #[serde(rename = "block_identifier")] + pub block_identifier: Box, + /// If a blockchain is UTXO-based, all unspent Coins owned by an account_identifier should be returned alongside the balance. It is highly recommended to populate this field so that users of the Rosetta API implementation don't need to maintain their own indexer to track their UTXOs. + #[serde(rename = "coins")] + pub coins: Vec, + /// Account-based blockchains that utilize a nonce or sequence number should include that number in the metadata. This number could be unique to the identifier or global across the account address. + #[serde(rename = "metadata", skip_serializing_if = "Option::is_none")] + pub metadata: Option, +} + +impl AccountCoinsResponse { + /// AccountCoinsResponse is returned on the /account/coins endpoint and includes all unspent Coins owned by an AccountIdentifier. + pub fn new(block_identifier: crate::mesh_api::generated::models::BlockIdentifier, coins: Vec) -> AccountCoinsResponse { + AccountCoinsResponse { + block_identifier: Box::new(block_identifier), + coins, + metadata: None, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/account_identifier.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/account_identifier.rs new file mode 100644 index 0000000000..e14615e715 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/account_identifier.rs @@ -0,0 +1,38 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// AccountIdentifier : The account_identifier uniquely identifies an account within a network. All fields in the account_identifier are utilized to determine this uniqueness (including the metadata field, if populated). + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct AccountIdentifier { + /// The address may be a cryptographic public key (or some encoding of it) or a provided username. + #[serde(rename = "address")] + pub address: String, + #[serde(rename = "sub_account", skip_serializing_if = "Option::is_none")] + pub sub_account: Option>, + /// Blockchains that utilize a username model (where the address is not a derivative of a cryptographic public key) should specify the public key(s) owned by the address in metadata. + #[serde(rename = "metadata", skip_serializing_if = "Option::is_none")] + pub metadata: Option, +} + +impl AccountIdentifier { + /// The account_identifier uniquely identifies an account within a network. All fields in the account_identifier are utilized to determine this uniqueness (including the metadata field, if populated). + pub fn new(address: String) -> AccountIdentifier { + AccountIdentifier { + address, + sub_account: None, + metadata: None, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/allow.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/allow.rs new file mode 100644 index 0000000000..929cbb2446 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/allow.rs @@ -0,0 +1,65 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// Allow : Allow specifies supported Operation status, Operation types, and all possible error statuses. This Allow object is used by clients to validate the correctness of a Rosetta Server implementation. It is expected that these clients will error if they receive some response that contains any of the above information that is not specified here. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct Allow { + /// All Operation.Status this implementation supports. Any status that is returned during parsing that is not listed here will cause client validation to error. + #[serde(rename = "operation_statuses")] + pub operation_statuses: Vec, + /// All Operation.Type this implementation supports. Any type that is returned during parsing that is not listed here will cause client validation to error. + #[serde(rename = "operation_types")] + pub operation_types: Vec, + /// All Errors that this implementation could return. Any error that is returned during parsing that is not listed here will cause client validation to error. + #[serde(rename = "errors")] + pub errors: Vec, + /// Any Rosetta implementation that supports querying the balance of an account at any height in the past should set this to true. + #[serde(rename = "historical_balance_lookup")] + pub historical_balance_lookup: bool, + /// If populated, `timestamp_start_index` indicates the first block index where block timestamps are considered valid (i.e. all blocks less than `timestamp_start_index` could have invalid timestamps). This is useful when the genesis block (or blocks) of a network have timestamp 0. If not populated, block timestamps are assumed to be valid for all available blocks. + #[serde(rename = "timestamp_start_index", skip_serializing_if = "Option::is_none")] + pub timestamp_start_index: Option, + /// All methods that are supported by the /call endpoint. Communicating which parameters should be provided to /call is the responsibility of the implementer (this is en lieu of defining an entire type system and requiring the implementer to define that in Allow). + #[serde(rename = "call_methods")] + pub call_methods: Vec, + /// BalanceExemptions is an array of BalanceExemption indicating which account balances could change without a corresponding Operation. BalanceExemptions should be used sparingly as they may introduce significant complexity for integrators that attempt to reconcile all account balance changes. If your implementation relies on any BalanceExemptions, you MUST implement historical balance lookup (the ability to query an account balance at any BlockIdentifier). + #[serde(rename = "balance_exemptions")] + pub balance_exemptions: Vec, + /// Any Rosetta implementation that can update an AccountIdentifier's unspent coins based on the contents of the mempool should populate this field as true. If false, requests to `/account/coins` that set `include_mempool` as true will be automatically rejected. + #[serde(rename = "mempool_coins")] + pub mempool_coins: bool, + #[serde(rename = "block_hash_case", skip_serializing_if = "Option::is_none")] + pub block_hash_case: Option, + #[serde(rename = "transaction_hash_case", skip_serializing_if = "Option::is_none")] + pub transaction_hash_case: Option, +} + +impl Allow { + /// Allow specifies supported Operation status, Operation types, and all possible error statuses. This Allow object is used by clients to validate the correctness of a Rosetta Server implementation. It is expected that these clients will error if they receive some response that contains any of the above information that is not specified here. + pub fn new(operation_statuses: Vec, operation_types: Vec, errors: Vec, historical_balance_lookup: bool, call_methods: Vec, balance_exemptions: Vec, mempool_coins: bool) -> Allow { + Allow { + operation_statuses, + operation_types, + errors, + historical_balance_lookup, + timestamp_start_index: None, + call_methods, + balance_exemptions, + mempool_coins, + block_hash_case: None, + transaction_hash_case: None, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/amount.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/amount.rs new file mode 100644 index 0000000000..67326a2f93 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/amount.rs @@ -0,0 +1,37 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// Amount : Amount is some Value of a Currency. It is considered invalid to specify a Value without a Currency. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct Amount { + /// Value of the transaction in atomic units represented as an arbitrary-sized signed integer. For example, 1 BTC would be represented by a value of 100000000. + #[serde(rename = "value")] + pub value: String, + #[serde(rename = "currency")] + pub currency: Box, + #[serde(rename = "metadata", skip_serializing_if = "Option::is_none")] + pub metadata: Option, +} + +impl Amount { + /// Amount is some Value of a Currency. It is considered invalid to specify a Value without a Currency. + pub fn new(value: String, currency: crate::mesh_api::generated::models::Currency) -> Amount { + Amount { + value, + currency: Box::new(currency), + metadata: None, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/balance_exemption.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/balance_exemption.rs new file mode 100644 index 0000000000..7b3339c99a --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/balance_exemption.rs @@ -0,0 +1,37 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// BalanceExemption : BalanceExemption indicates that the balance for an exempt account could change without a corresponding Operation. This typically occurs with staking rewards, vesting balances, and Currencies with a dynamic supply. Currently, it is possible to exempt an account from strict reconciliation by SubAccountIdentifier.Address or by Currency. This means that any account with SubAccountIdentifier.Address would be exempt or any balance of a particular Currency would be exempt, respectively. BalanceExemptions should be used sparingly as they may introduce significant complexity for integrators that attempt to reconcile all account balance changes. If your implementation relies on any BalanceExemptions, you MUST implement historical balance lookup (the ability to query an account balance at any BlockIdentifier). + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct BalanceExemption { + /// SubAccountAddress is the SubAccountIdentifier.Address that the BalanceExemption applies to (regardless of the value of SubAccountIdentifier.Metadata). + #[serde(rename = "sub_account_address", skip_serializing_if = "Option::is_none")] + pub sub_account_address: Option, + #[serde(rename = "currency", skip_serializing_if = "Option::is_none")] + pub currency: Option>, + #[serde(rename = "exemption_type", skip_serializing_if = "Option::is_none")] + pub exemption_type: Option, +} + +impl BalanceExemption { + /// BalanceExemption indicates that the balance for an exempt account could change without a corresponding Operation. This typically occurs with staking rewards, vesting balances, and Currencies with a dynamic supply. Currently, it is possible to exempt an account from strict reconciliation by SubAccountIdentifier.Address or by Currency. This means that any account with SubAccountIdentifier.Address would be exempt or any balance of a particular Currency would be exempt, respectively. BalanceExemptions should be used sparingly as they may introduce significant complexity for integrators that attempt to reconcile all account balance changes. If your implementation relies on any BalanceExemptions, you MUST implement historical balance lookup (the ability to query an account balance at any BlockIdentifier). + pub fn new() -> BalanceExemption { + BalanceExemption { + sub_account_address: None, + currency: None, + exemption_type: None, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/block.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/block.rs new file mode 100644 index 0000000000..7043b2cec3 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/block.rs @@ -0,0 +1,43 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// Block : Blocks contain an array of Transactions that occurred at a particular BlockIdentifier. A hard requirement for blocks returned by Rosetta implementations is that they MUST be _inalterable_: once a client has requested and received a block identified by a specific BlockIndentifier, all future calls for that same BlockIdentifier must return the same block contents. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct Block { + #[serde(rename = "block_identifier")] + pub block_identifier: Box, + #[serde(rename = "parent_block_identifier")] + pub parent_block_identifier: Box, + /// The timestamp of the block in milliseconds since the Unix Epoch. The timestamp is stored in milliseconds because some blockchains produce blocks more often than once a second. + #[serde(rename = "timestamp")] + pub timestamp: i64, + #[serde(rename = "transactions")] + pub transactions: Vec, + #[serde(rename = "metadata", skip_serializing_if = "Option::is_none")] + pub metadata: Option, +} + +impl Block { + /// Blocks contain an array of Transactions that occurred at a particular BlockIdentifier. A hard requirement for blocks returned by Rosetta implementations is that they MUST be _inalterable_: once a client has requested and received a block identified by a specific BlockIndentifier, all future calls for that same BlockIdentifier must return the same block contents. + pub fn new(block_identifier: crate::mesh_api::generated::models::BlockIdentifier, parent_block_identifier: crate::mesh_api::generated::models::BlockIdentifier, timestamp: i64, transactions: Vec) -> Block { + Block { + block_identifier: Box::new(block_identifier), + parent_block_identifier: Box::new(parent_block_identifier), + timestamp, + transactions, + metadata: None, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/block_event.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/block_event.rs new file mode 100644 index 0000000000..2b25960ecb --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/block_event.rs @@ -0,0 +1,37 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// BlockEvent : BlockEvent represents the addition or removal of a BlockIdentifier from storage. Streaming BlockEvents allows lightweight clients to update their own state without needing to implement their own syncing logic. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct BlockEvent { + /// sequence is the unique identifier of a BlockEvent within the context of a NetworkIdentifier. + #[serde(rename = "sequence")] + pub sequence: i64, + #[serde(rename = "block_identifier")] + pub block_identifier: Box, + #[serde(rename = "type")] + pub _type: crate::mesh_api::generated::models::BlockEventType, +} + +impl BlockEvent { + /// BlockEvent represents the addition or removal of a BlockIdentifier from storage. Streaming BlockEvents allows lightweight clients to update their own state without needing to implement their own syncing logic. + pub fn new(sequence: i64, block_identifier: crate::mesh_api::generated::models::BlockIdentifier, _type: crate::mesh_api::generated::models::BlockEventType) -> BlockEvent { + BlockEvent { + sequence, + block_identifier: Box::new(block_identifier), + _type, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/block_event_type.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/block_event_type.rs new file mode 100644 index 0000000000..36484dba7b --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/block_event_type.rs @@ -0,0 +1,40 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// BlockEventType : BlockEventType determines if a BlockEvent represents the addition or removal of a block. + +/// BlockEventType determines if a BlockEvent represents the addition or removal of a block. +#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, serde::Serialize, serde::Deserialize)] +pub enum BlockEventType { + #[serde(rename = "block_added")] + Added, + #[serde(rename = "block_removed")] + Removed, + +} + +impl ToString for BlockEventType { + fn to_string(&self) -> String { + match self { + Self::Added => String::from("block_added"), + Self::Removed => String::from("block_removed"), + } + } +} + +impl Default for BlockEventType { + fn default() -> BlockEventType { + Self::Added + } +} + + + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/block_identifier.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/block_identifier.rs new file mode 100644 index 0000000000..c95236ebc1 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/block_identifier.rs @@ -0,0 +1,35 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// BlockIdentifier : The block_identifier uniquely identifies a block in a particular network. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct BlockIdentifier { + /// This is also known as the block height. + #[serde(rename = "index")] + pub index: i64, + /// This should be normalized according to the case specified in the block_hash_case network options. + #[serde(rename = "hash")] + pub hash: String, +} + +impl BlockIdentifier { + /// The block_identifier uniquely identifies a block in a particular network. + pub fn new(index: i64, hash: String) -> BlockIdentifier { + BlockIdentifier { + index, + hash, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/block_request.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/block_request.rs new file mode 100644 index 0000000000..ad133a62df --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/block_request.rs @@ -0,0 +1,33 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// BlockRequest : A BlockRequest is utilized to make a block request on the /block endpoint. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct BlockRequest { + #[serde(rename = "network_identifier")] + pub network_identifier: Box, + #[serde(rename = "block_identifier")] + pub block_identifier: Box, +} + +impl BlockRequest { + /// A BlockRequest is utilized to make a block request on the /block endpoint. + pub fn new(network_identifier: crate::mesh_api::generated::models::NetworkIdentifier, block_identifier: crate::mesh_api::generated::models::PartialBlockIdentifier) -> BlockRequest { + BlockRequest { + network_identifier: Box::new(network_identifier), + block_identifier: Box::new(block_identifier), + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/block_response.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/block_response.rs new file mode 100644 index 0000000000..f8b49dee76 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/block_response.rs @@ -0,0 +1,34 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// BlockResponse : A BlockResponse includes a fully-populated block or a partially-populated block with a list of other transactions to fetch (other_transactions). As a result of the consensus algorithm of some blockchains, blocks can be omitted (i.e. certain block indices can be skipped). If a query for one of these omitted indices is made, the response should not include a `Block` object. It is VERY important to note that blocks MUST still form a canonical, connected chain of blocks where each block has a unique index. In other words, the `PartialBlockIdentifier` of a block after an omitted block should reference the last non-omitted block. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct BlockResponse { + #[serde(rename = "block", skip_serializing_if = "Option::is_none")] + pub block: Option>, + /// Some blockchains may require additional transactions to be fetched that weren't returned in the block response (ex: block only returns transaction hashes). For blockchains with a lot of transactions in each block, this can be very useful as consumers can concurrently fetch all transactions returned. + #[serde(rename = "other_transactions", skip_serializing_if = "Option::is_none")] + pub other_transactions: Option>, +} + +impl BlockResponse { + /// A BlockResponse includes a fully-populated block or a partially-populated block with a list of other transactions to fetch (other_transactions). As a result of the consensus algorithm of some blockchains, blocks can be omitted (i.e. certain block indices can be skipped). If a query for one of these omitted indices is made, the response should not include a `Block` object. It is VERY important to note that blocks MUST still form a canonical, connected chain of blocks where each block has a unique index. In other words, the `PartialBlockIdentifier` of a block after an omitted block should reference the last non-omitted block. + pub fn new() -> BlockResponse { + BlockResponse { + block: None, + other_transactions: None, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/block_transaction.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/block_transaction.rs new file mode 100644 index 0000000000..6924e50371 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/block_transaction.rs @@ -0,0 +1,33 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// BlockTransaction : BlockTransaction contains a populated Transaction and the BlockIdentifier that contains it. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct BlockTransaction { + #[serde(rename = "block_identifier")] + pub block_identifier: Box, + #[serde(rename = "transaction")] + pub transaction: Box, +} + +impl BlockTransaction { + /// BlockTransaction contains a populated Transaction and the BlockIdentifier that contains it. + pub fn new(block_identifier: crate::mesh_api::generated::models::BlockIdentifier, transaction: crate::mesh_api::generated::models::Transaction) -> BlockTransaction { + BlockTransaction { + block_identifier: Box::new(block_identifier), + transaction: Box::new(transaction), + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/block_transaction_request.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/block_transaction_request.rs new file mode 100644 index 0000000000..688cab714d --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/block_transaction_request.rs @@ -0,0 +1,36 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// BlockTransactionRequest : A BlockTransactionRequest is used to fetch a Transaction included in a block that is not returned in a BlockResponse. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct BlockTransactionRequest { + #[serde(rename = "network_identifier")] + pub network_identifier: Box, + #[serde(rename = "block_identifier")] + pub block_identifier: Box, + #[serde(rename = "transaction_identifier")] + pub transaction_identifier: Box, +} + +impl BlockTransactionRequest { + /// A BlockTransactionRequest is used to fetch a Transaction included in a block that is not returned in a BlockResponse. + pub fn new(network_identifier: crate::mesh_api::generated::models::NetworkIdentifier, block_identifier: crate::mesh_api::generated::models::BlockIdentifier, transaction_identifier: crate::mesh_api::generated::models::TransactionIdentifier) -> BlockTransactionRequest { + BlockTransactionRequest { + network_identifier: Box::new(network_identifier), + block_identifier: Box::new(block_identifier), + transaction_identifier: Box::new(transaction_identifier), + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/block_transaction_response.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/block_transaction_response.rs new file mode 100644 index 0000000000..a52f051c74 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/block_transaction_response.rs @@ -0,0 +1,30 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// BlockTransactionResponse : A BlockTransactionResponse contains information about a block transaction. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct BlockTransactionResponse { + #[serde(rename = "transaction")] + pub transaction: Box, +} + +impl BlockTransactionResponse { + /// A BlockTransactionResponse contains information about a block transaction. + pub fn new(transaction: crate::mesh_api::generated::models::Transaction) -> BlockTransactionResponse { + BlockTransactionResponse { + transaction: Box::new(transaction), + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/call_request.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/call_request.rs new file mode 100644 index 0000000000..48eeb77d0c --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/call_request.rs @@ -0,0 +1,38 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// CallRequest : CallRequest is the input to the `/call` endpoint. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct CallRequest { + #[serde(rename = "network_identifier")] + pub network_identifier: Box, + /// Method is some network-specific procedure call. This method could map to a network-specific RPC endpoint, a method in an SDK generated from a smart contract, or some hybrid of the two. The implementation must define all available methods in the Allow object. However, it is up to the caller to determine which parameters to provide when invoking `/call`. + #[serde(rename = "method")] + pub method: String, + /// Parameters is some network-specific argument for a method. It is up to the caller to determine which parameters to provide when invoking `/call`. + #[serde(rename = "parameters")] + pub parameters: serde_json::Value, +} + +impl CallRequest { + /// CallRequest is the input to the `/call` endpoint. + pub fn new(network_identifier: crate::mesh_api::generated::models::NetworkIdentifier, method: String, parameters: serde_json::Value) -> CallRequest { + CallRequest { + network_identifier: Box::new(network_identifier), + method, + parameters, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/call_response.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/call_response.rs new file mode 100644 index 0000000000..c03aa4852b --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/call_response.rs @@ -0,0 +1,35 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// CallResponse : CallResponse contains the result of a `/call` invocation. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct CallResponse { + /// Result contains the result of the `/call` invocation. This result will not be inspected or interpreted by Rosetta tooling and is left to the caller to decode. + #[serde(rename = "result")] + pub result: serde_json::Value, + /// Idempotent indicates that if `/call` is invoked with the same CallRequest again, at any point in time, it will return the same CallResponse. Integrators may cache the CallResponse if this is set to true to avoid making unnecessary calls to the Rosetta implementation. For this reason, implementers should be very conservative about returning true here or they could cause issues for the caller. + #[serde(rename = "idempotent")] + pub idempotent: bool, +} + +impl CallResponse { + /// CallResponse contains the result of a `/call` invocation. + pub fn new(result: serde_json::Value, idempotent: bool) -> CallResponse { + CallResponse { + result, + idempotent, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/case.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/case.rs new file mode 100644 index 0000000000..16790ff338 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/case.rs @@ -0,0 +1,46 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// Case : Case specifies the expected case for strings and hashes. + +/// Case specifies the expected case for strings and hashes. +#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, serde::Serialize, serde::Deserialize)] +pub enum Case { + #[serde(rename = "upper_case")] + UpperCase, + #[serde(rename = "lower_case")] + LowerCase, + #[serde(rename = "case_sensitive")] + CaseSensitive, + #[serde(rename = "null")] + Null, + +} + +impl ToString for Case { + fn to_string(&self) -> String { + match self { + Self::UpperCase => String::from("upper_case"), + Self::LowerCase => String::from("lower_case"), + Self::CaseSensitive => String::from("case_sensitive"), + Self::Null => String::from("null"), + } + } +} + +impl Default for Case { + fn default() -> Case { + Self::UpperCase + } +} + + + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/coin.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/coin.rs new file mode 100644 index 0000000000..9a11b49af4 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/coin.rs @@ -0,0 +1,33 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// Coin : Coin contains its unique identifier and the amount it represents. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct Coin { + #[serde(rename = "coin_identifier")] + pub coin_identifier: Box, + #[serde(rename = "amount")] + pub amount: Box, +} + +impl Coin { + /// Coin contains its unique identifier and the amount it represents. + pub fn new(coin_identifier: crate::mesh_api::generated::models::CoinIdentifier, amount: crate::mesh_api::generated::models::Amount) -> Coin { + Coin { + coin_identifier: Box::new(coin_identifier), + amount: Box::new(amount), + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/coin_action.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/coin_action.rs new file mode 100644 index 0000000000..f7220b9ad7 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/coin_action.rs @@ -0,0 +1,40 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// CoinAction : CoinActions are different state changes that a Coin can undergo. When a Coin is created, it is coin_created. When a Coin is spent, it is coin_spent. It is assumed that a single Coin cannot be created or spent more than once. + +/// CoinActions are different state changes that a Coin can undergo. When a Coin is created, it is coin_created. When a Coin is spent, it is coin_spent. It is assumed that a single Coin cannot be created or spent more than once. +#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, serde::Serialize, serde::Deserialize)] +pub enum CoinAction { + #[serde(rename = "coin_created")] + Created, + #[serde(rename = "coin_spent")] + Spent, + +} + +impl ToString for CoinAction { + fn to_string(&self) -> String { + match self { + Self::Created => String::from("coin_created"), + Self::Spent => String::from("coin_spent"), + } + } +} + +impl Default for CoinAction { + fn default() -> CoinAction { + Self::Created + } +} + + + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/coin_change.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/coin_change.rs new file mode 100644 index 0000000000..cb1d4c1aa5 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/coin_change.rs @@ -0,0 +1,33 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// CoinChange : CoinChange is used to represent a change in state of a some coin identified by a coin_identifier. This object is part of the Operation model and must be populated for UTXO-based blockchains. Coincidentally, this abstraction of UTXOs allows for supporting both account-based transfers and UTXO-based transfers on the same blockchain (when a transfer is account-based, don't populate this model). + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct CoinChange { + #[serde(rename = "coin_identifier")] + pub coin_identifier: Box, + #[serde(rename = "coin_action")] + pub coin_action: crate::mesh_api::generated::models::CoinAction, +} + +impl CoinChange { + /// CoinChange is used to represent a change in state of a some coin identified by a coin_identifier. This object is part of the Operation model and must be populated for UTXO-based blockchains. Coincidentally, this abstraction of UTXOs allows for supporting both account-based transfers and UTXO-based transfers on the same blockchain (when a transfer is account-based, don't populate this model). + pub fn new(coin_identifier: crate::mesh_api::generated::models::CoinIdentifier, coin_action: crate::mesh_api::generated::models::CoinAction) -> CoinChange { + CoinChange { + coin_identifier: Box::new(coin_identifier), + coin_action, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/coin_identifier.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/coin_identifier.rs new file mode 100644 index 0000000000..31b86fc8db --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/coin_identifier.rs @@ -0,0 +1,31 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// CoinIdentifier : CoinIdentifier uniquely identifies a Coin. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct CoinIdentifier { + /// Identifier should be populated with a globally unique identifier of a Coin. In Bitcoin, this identifier would be transaction_hash:index. + #[serde(rename = "identifier")] + pub identifier: String, +} + +impl CoinIdentifier { + /// CoinIdentifier uniquely identifies a Coin. + pub fn new(identifier: String) -> CoinIdentifier { + CoinIdentifier { + identifier, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/construction_combine_request.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/construction_combine_request.rs new file mode 100644 index 0000000000..aee469d385 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/construction_combine_request.rs @@ -0,0 +1,36 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// ConstructionCombineRequest : ConstructionCombineRequest is the input to the `/construction/combine` endpoint. It contains the unsigned transaction blob returned by `/construction/payloads` and all required signatures to create a network transaction. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct ConstructionCombineRequest { + #[serde(rename = "network_identifier")] + pub network_identifier: Box, + #[serde(rename = "unsigned_transaction")] + pub unsigned_transaction: String, + #[serde(rename = "signatures")] + pub signatures: Vec, +} + +impl ConstructionCombineRequest { + /// ConstructionCombineRequest is the input to the `/construction/combine` endpoint. It contains the unsigned transaction blob returned by `/construction/payloads` and all required signatures to create a network transaction. + pub fn new(network_identifier: crate::mesh_api::generated::models::NetworkIdentifier, unsigned_transaction: String, signatures: Vec) -> ConstructionCombineRequest { + ConstructionCombineRequest { + network_identifier: Box::new(network_identifier), + unsigned_transaction, + signatures, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/construction_combine_response.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/construction_combine_response.rs new file mode 100644 index 0000000000..f63ecd2478 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/construction_combine_response.rs @@ -0,0 +1,30 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// ConstructionCombineResponse : ConstructionCombineResponse is returned by `/construction/combine`. The network payload will be sent directly to the `construction/submit` endpoint. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct ConstructionCombineResponse { + #[serde(rename = "signed_transaction")] + pub signed_transaction: String, +} + +impl ConstructionCombineResponse { + /// ConstructionCombineResponse is returned by `/construction/combine`. The network payload will be sent directly to the `construction/submit` endpoint. + pub fn new(signed_transaction: String) -> ConstructionCombineResponse { + ConstructionCombineResponse { + signed_transaction, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/construction_derive_request.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/construction_derive_request.rs new file mode 100644 index 0000000000..bf3b711eea --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/construction_derive_request.rs @@ -0,0 +1,36 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// ConstructionDeriveRequest : ConstructionDeriveRequest is passed to the `/construction/derive` endpoint. Network is provided in the request because some blockchains have different address formats for different networks. Metadata is provided in the request because some blockchains allow for multiple address types (i.e. different address for validators vs normal accounts). + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct ConstructionDeriveRequest { + #[serde(rename = "network_identifier")] + pub network_identifier: Box, + #[serde(rename = "public_key")] + pub public_key: Box, + #[serde(rename = "metadata", skip_serializing_if = "Option::is_none")] + pub metadata: Option, +} + +impl ConstructionDeriveRequest { + /// ConstructionDeriveRequest is passed to the `/construction/derive` endpoint. Network is provided in the request because some blockchains have different address formats for different networks. Metadata is provided in the request because some blockchains allow for multiple address types (i.e. different address for validators vs normal accounts). + pub fn new(network_identifier: crate::mesh_api::generated::models::NetworkIdentifier, public_key: crate::mesh_api::generated::models::PublicKey) -> ConstructionDeriveRequest { + ConstructionDeriveRequest { + network_identifier: Box::new(network_identifier), + public_key: Box::new(public_key), + metadata: None, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/construction_derive_response.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/construction_derive_response.rs new file mode 100644 index 0000000000..4065e985e2 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/construction_derive_response.rs @@ -0,0 +1,37 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// ConstructionDeriveResponse : ConstructionDeriveResponse is returned by the `/construction/derive` endpoint. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct ConstructionDeriveResponse { + /// [DEPRECATED by `account_identifier` in `v1.4.4`] Address in network-specific format. + #[serde(rename = "address", skip_serializing_if = "Option::is_none")] + pub address: Option, + #[serde(rename = "account_identifier", skip_serializing_if = "Option::is_none")] + pub account_identifier: Option>, + #[serde(rename = "metadata", skip_serializing_if = "Option::is_none")] + pub metadata: Option, +} + +impl ConstructionDeriveResponse { + /// ConstructionDeriveResponse is returned by the `/construction/derive` endpoint. + pub fn new() -> ConstructionDeriveResponse { + ConstructionDeriveResponse { + address: None, + account_identifier: None, + metadata: None, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/construction_hash_request.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/construction_hash_request.rs new file mode 100644 index 0000000000..2674bb42db --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/construction_hash_request.rs @@ -0,0 +1,33 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// ConstructionHashRequest : ConstructionHashRequest is the input to the `/construction/hash` endpoint. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct ConstructionHashRequest { + #[serde(rename = "network_identifier")] + pub network_identifier: Box, + #[serde(rename = "signed_transaction")] + pub signed_transaction: String, +} + +impl ConstructionHashRequest { + /// ConstructionHashRequest is the input to the `/construction/hash` endpoint. + pub fn new(network_identifier: crate::mesh_api::generated::models::NetworkIdentifier, signed_transaction: String) -> ConstructionHashRequest { + ConstructionHashRequest { + network_identifier: Box::new(network_identifier), + signed_transaction, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/construction_metadata_request.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/construction_metadata_request.rs new file mode 100644 index 0000000000..6cbac69a6b --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/construction_metadata_request.rs @@ -0,0 +1,37 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// ConstructionMetadataRequest : A ConstructionMetadataRequest is utilized to get information required to construct a transaction. The Options object used to specify which metadata to return is left purposely unstructured to allow flexibility for implementers. Options is not required in the case that there is network-wide metadata of interest. Optionally, the request can also include an array of PublicKeys associated with the AccountIdentifiers returned in ConstructionPreprocessResponse. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct ConstructionMetadataRequest { + #[serde(rename = "network_identifier")] + pub network_identifier: Box, + /// Some blockchains require different metadata for different types of transaction construction (ex: delegation versus a transfer). Instead of requiring a blockchain node to return all possible types of metadata for construction (which may require multiple node fetches), the client can populate an options object to limit the metadata returned to only the subset required. + #[serde(rename = "options", skip_serializing_if = "Option::is_none")] + pub options: Option, + #[serde(rename = "public_keys", skip_serializing_if = "Option::is_none")] + pub public_keys: Option>, +} + +impl ConstructionMetadataRequest { + /// A ConstructionMetadataRequest is utilized to get information required to construct a transaction. The Options object used to specify which metadata to return is left purposely unstructured to allow flexibility for implementers. Options is not required in the case that there is network-wide metadata of interest. Optionally, the request can also include an array of PublicKeys associated with the AccountIdentifiers returned in ConstructionPreprocessResponse. + pub fn new(network_identifier: crate::mesh_api::generated::models::NetworkIdentifier) -> ConstructionMetadataRequest { + ConstructionMetadataRequest { + network_identifier: Box::new(network_identifier), + options: None, + public_keys: None, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/construction_metadata_response.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/construction_metadata_response.rs new file mode 100644 index 0000000000..afc4349fa9 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/construction_metadata_response.rs @@ -0,0 +1,33 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// ConstructionMetadataResponse : The ConstructionMetadataResponse returns network-specific metadata used for transaction construction. Optionally, the implementer can return the suggested fee associated with the transaction being constructed. The caller may use this info to adjust the intent of the transaction or to create a transaction with a different account that can pay the suggested fee. Suggested fee is an array in case fee payment must occur in multiple currencies. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct ConstructionMetadataResponse { + #[serde(rename = "metadata")] + pub metadata: serde_json::Value, + #[serde(rename = "suggested_fee", skip_serializing_if = "Option::is_none")] + pub suggested_fee: Option>, +} + +impl ConstructionMetadataResponse { + /// The ConstructionMetadataResponse returns network-specific metadata used for transaction construction. Optionally, the implementer can return the suggested fee associated with the transaction being constructed. The caller may use this info to adjust the intent of the transaction or to create a transaction with a different account that can pay the suggested fee. Suggested fee is an array in case fee payment must occur in multiple currencies. + pub fn new(metadata: serde_json::Value) -> ConstructionMetadataResponse { + ConstructionMetadataResponse { + metadata, + suggested_fee: None, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/construction_parse_request.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/construction_parse_request.rs new file mode 100644 index 0000000000..b32c481bd9 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/construction_parse_request.rs @@ -0,0 +1,38 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// ConstructionParseRequest : ConstructionParseRequest is the input to the `/construction/parse` endpoint. It allows the caller to parse either an unsigned or signed transaction. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct ConstructionParseRequest { + #[serde(rename = "network_identifier")] + pub network_identifier: Box, + /// Signed is a boolean indicating whether the transaction is signed. + #[serde(rename = "signed")] + pub signed: bool, + /// This must be either the unsigned transaction blob returned by `/construction/payloads` or the signed transaction blob returned by `/construction/combine`. + #[serde(rename = "transaction")] + pub transaction: String, +} + +impl ConstructionParseRequest { + /// ConstructionParseRequest is the input to the `/construction/parse` endpoint. It allows the caller to parse either an unsigned or signed transaction. + pub fn new(network_identifier: crate::mesh_api::generated::models::NetworkIdentifier, signed: bool, transaction: String) -> ConstructionParseRequest { + ConstructionParseRequest { + network_identifier: Box::new(network_identifier), + signed, + transaction, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/construction_parse_response.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/construction_parse_response.rs new file mode 100644 index 0000000000..abb7565b4f --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/construction_parse_response.rs @@ -0,0 +1,40 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// ConstructionParseResponse : ConstructionParseResponse contains an array of operations that occur in a transaction blob. This should match the array of operations provided to `/construction/preprocess` and `/construction/payloads`. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct ConstructionParseResponse { + #[serde(rename = "operations")] + pub operations: Vec, + /// [DEPRECATED by `account_identifier_signers` in `v1.4.4`] All signers (addresses) of a particular transaction. If the transaction is unsigned, it should be empty. + #[serde(rename = "signers", skip_serializing_if = "Option::is_none")] + pub signers: Option>, + #[serde(rename = "account_identifier_signers", skip_serializing_if = "Option::is_none")] + pub account_identifier_signers: Option>, + #[serde(rename = "metadata", skip_serializing_if = "Option::is_none")] + pub metadata: Option, +} + +impl ConstructionParseResponse { + /// ConstructionParseResponse contains an array of operations that occur in a transaction blob. This should match the array of operations provided to `/construction/preprocess` and `/construction/payloads`. + pub fn new(operations: Vec) -> ConstructionParseResponse { + ConstructionParseResponse { + operations, + signers: None, + account_identifier_signers: None, + metadata: None, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/construction_payloads_request.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/construction_payloads_request.rs new file mode 100644 index 0000000000..9ee55bb528 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/construction_payloads_request.rs @@ -0,0 +1,39 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// ConstructionPayloadsRequest : ConstructionPayloadsRequest is the request to `/construction/payloads`. It contains the network, a slice of operations, and arbitrary metadata that was returned by the call to `/construction/metadata`. Optionally, the request can also include an array of PublicKeys associated with the AccountIdentifiers returned in ConstructionPreprocessResponse. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct ConstructionPayloadsRequest { + #[serde(rename = "network_identifier")] + pub network_identifier: Box, + #[serde(rename = "operations")] + pub operations: Vec, + #[serde(rename = "metadata", skip_serializing_if = "Option::is_none")] + pub metadata: Option, + #[serde(rename = "public_keys", skip_serializing_if = "Option::is_none")] + pub public_keys: Option>, +} + +impl ConstructionPayloadsRequest { + /// ConstructionPayloadsRequest is the request to `/construction/payloads`. It contains the network, a slice of operations, and arbitrary metadata that was returned by the call to `/construction/metadata`. Optionally, the request can also include an array of PublicKeys associated with the AccountIdentifiers returned in ConstructionPreprocessResponse. + pub fn new(network_identifier: crate::mesh_api::generated::models::NetworkIdentifier, operations: Vec) -> ConstructionPayloadsRequest { + ConstructionPayloadsRequest { + network_identifier: Box::new(network_identifier), + operations, + metadata: None, + public_keys: None, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/construction_payloads_response.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/construction_payloads_response.rs new file mode 100644 index 0000000000..ac7b979c0d --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/construction_payloads_response.rs @@ -0,0 +1,33 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// ConstructionPayloadsResponse : ConstructionTransactionResponse is returned by `/construction/payloads`. It contains an unsigned transaction blob (that is usually needed to construct the a network transaction from a collection of signatures) and an array of payloads that must be signed by the caller. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct ConstructionPayloadsResponse { + #[serde(rename = "unsigned_transaction")] + pub unsigned_transaction: String, + #[serde(rename = "payloads")] + pub payloads: Vec, +} + +impl ConstructionPayloadsResponse { + /// ConstructionTransactionResponse is returned by `/construction/payloads`. It contains an unsigned transaction blob (that is usually needed to construct the a network transaction from a collection of signatures) and an array of payloads that must be signed by the caller. + pub fn new(unsigned_transaction: String, payloads: Vec) -> ConstructionPayloadsResponse { + ConstructionPayloadsResponse { + unsigned_transaction, + payloads, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/construction_preprocess_request.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/construction_preprocess_request.rs new file mode 100644 index 0000000000..a197d9d891 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/construction_preprocess_request.rs @@ -0,0 +1,36 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// ConstructionPreprocessRequest : ConstructionPreprocessRequest is passed to the `/construction/preprocess` endpoint so that a Rosetta implementation can determine which metadata it needs to request for construction. Metadata provided in this object should NEVER be a product of live data (i.e. the caller must follow some network-specific data fetching strategy outside of the Construction API to populate required Metadata). If live data is required for construction, it MUST be fetched in the call to `/construction/metadata`. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct ConstructionPreprocessRequest { + #[serde(rename = "network_identifier")] + pub network_identifier: Box, + #[serde(rename = "operations")] + pub operations: Vec, + #[serde(rename = "metadata", skip_serializing_if = "Option::is_none")] + pub metadata: Option, +} + +impl ConstructionPreprocessRequest { + /// ConstructionPreprocessRequest is passed to the `/construction/preprocess` endpoint so that a Rosetta implementation can determine which metadata it needs to request for construction. Metadata provided in this object should NEVER be a product of live data (i.e. the caller must follow some network-specific data fetching strategy outside of the Construction API to populate required Metadata). If live data is required for construction, it MUST be fetched in the call to `/construction/metadata`. + pub fn new(network_identifier: crate::mesh_api::generated::models::NetworkIdentifier, operations: Vec) -> ConstructionPreprocessRequest { + ConstructionPreprocessRequest { + network_identifier: Box::new(network_identifier), + operations, + metadata: None, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/construction_preprocess_response.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/construction_preprocess_response.rs new file mode 100644 index 0000000000..e64cc5ff8b --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/construction_preprocess_response.rs @@ -0,0 +1,34 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// ConstructionPreprocessResponse : ConstructionPreprocessResponse contains `options` that will be sent unmodified to `/construction/metadata`. If it is not necessary to make a request to `/construction/metadata`, `options` should be omitted. Some blockchains require the PublicKey of particular AccountIdentifiers to construct a valid transaction. To fetch these PublicKeys, populate `required_public_keys` with the AccountIdentifiers associated with the desired PublicKeys. If it is not necessary to retrieve any PublicKeys for construction, `required_public_keys` should be omitted. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct ConstructionPreprocessResponse { + /// The options that will be sent directly to `/construction/metadata` by the caller. + #[serde(rename = "options", skip_serializing_if = "Option::is_none")] + pub options: Option, + #[serde(rename = "required_public_keys", skip_serializing_if = "Option::is_none")] + pub required_public_keys: Option>, +} + +impl ConstructionPreprocessResponse { + /// ConstructionPreprocessResponse contains `options` that will be sent unmodified to `/construction/metadata`. If it is not necessary to make a request to `/construction/metadata`, `options` should be omitted. Some blockchains require the PublicKey of particular AccountIdentifiers to construct a valid transaction. To fetch these PublicKeys, populate `required_public_keys` with the AccountIdentifiers associated with the desired PublicKeys. If it is not necessary to retrieve any PublicKeys for construction, `required_public_keys` should be omitted. + pub fn new() -> ConstructionPreprocessResponse { + ConstructionPreprocessResponse { + options: None, + required_public_keys: None, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/construction_submit_request.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/construction_submit_request.rs new file mode 100644 index 0000000000..e34e3051b4 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/construction_submit_request.rs @@ -0,0 +1,33 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// ConstructionSubmitRequest : The transaction submission request includes a signed transaction. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct ConstructionSubmitRequest { + #[serde(rename = "network_identifier")] + pub network_identifier: Box, + #[serde(rename = "signed_transaction")] + pub signed_transaction: String, +} + +impl ConstructionSubmitRequest { + /// The transaction submission request includes a signed transaction. + pub fn new(network_identifier: crate::mesh_api::generated::models::NetworkIdentifier, signed_transaction: String) -> ConstructionSubmitRequest { + ConstructionSubmitRequest { + network_identifier: Box::new(network_identifier), + signed_transaction, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/currency.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/currency.rs new file mode 100644 index 0000000000..a93ab17837 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/currency.rs @@ -0,0 +1,39 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// Currency : Currency is composed of a canonical Symbol and Decimals. This Decimals value is used to convert an Amount.Value from atomic units (Satoshis) to standard units (Bitcoins). + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct Currency { + /// Canonical symbol associated with a currency. + #[serde(rename = "symbol")] + pub symbol: String, + /// Number of decimal places in the standard unit representation of the amount. For example, BTC has 8 decimals. Note that it is not possible to represent the value of some currency in atomic units that is not base 10. + #[serde(rename = "decimals")] + pub decimals: i32, + /// Any additional information related to the currency itself. For example, it would be useful to populate this object with the contract address of an ERC-20 token. + #[serde(rename = "metadata", skip_serializing_if = "Option::is_none")] + pub metadata: Option, +} + +impl Currency { + /// Currency is composed of a canonical Symbol and Decimals. This Decimals value is used to convert an Amount.Value from atomic units (Satoshis) to standard units (Bitcoins). + pub fn new(symbol: String, decimals: i32) -> Currency { + Currency { + symbol, + decimals, + metadata: None, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/curve_type.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/curve_type.rs new file mode 100644 index 0000000000..d92c932b8b --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/curve_type.rs @@ -0,0 +1,52 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// CurveType : CurveType is the type of cryptographic curve associated with a PublicKey. * secp256k1: SEC compressed - `33 bytes` (https://secg.org/sec1-v2.pdf#subsubsection.2.3.3) * secp256k1_bip340: x-only - `32 bytes` (implicitly even `Y` coord. Secp256k1 compressed keys may be repurposed by dropping the first byte. (https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki#Public_Key_Generation)) * secp256r1: SEC compressed - `33 bytes` (https://secg.org/sec1-v2.pdf#subsubsection.2.3.3) * edwards25519: `y (255-bits) || x-sign-bit (1-bit)` - `32 bytes` (https://ed25519.cr.yp.to/ed25519-20110926.pdf) * tweedle: 1st pk : Fq.t (32 bytes) || 2nd pk : Fq.t (32 bytes) (https://github.com/CodaProtocol/coda/blob/develop/rfcs/0038-rosetta-construction-api.md#marshal-keys) * pallas: `x (255 bits) || y-parity-bit (1-bit) - 32 bytes` (https://github.com/zcash/pasta) + +/// CurveType is the type of cryptographic curve associated with a PublicKey. * secp256k1: SEC compressed - `33 bytes` (https://secg.org/sec1-v2.pdf#subsubsection.2.3.3) * secp256k1_bip340: x-only - `32 bytes` (implicitly even `Y` coord. Secp256k1 compressed keys may be repurposed by dropping the first byte. (https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki#Public_Key_Generation)) * secp256r1: SEC compressed - `33 bytes` (https://secg.org/sec1-v2.pdf#subsubsection.2.3.3) * edwards25519: `y (255-bits) || x-sign-bit (1-bit)` - `32 bytes` (https://ed25519.cr.yp.to/ed25519-20110926.pdf) * tweedle: 1st pk : Fq.t (32 bytes) || 2nd pk : Fq.t (32 bytes) (https://github.com/CodaProtocol/coda/blob/develop/rfcs/0038-rosetta-construction-api.md#marshal-keys) * pallas: `x (255 bits) || y-parity-bit (1-bit) - 32 bytes` (https://github.com/zcash/pasta) +#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, serde::Serialize, serde::Deserialize)] +pub enum CurveType { + #[serde(rename = "secp256k1")] + Secp256k1, + #[serde(rename = "secp256k1_bip340")] + Secp256k1Bip340, + #[serde(rename = "secp256r1")] + Secp256r1, + #[serde(rename = "edwards25519")] + Edwards25519, + #[serde(rename = "tweedle")] + Tweedle, + #[serde(rename = "pallas")] + Pallas, + +} + +impl ToString for CurveType { + fn to_string(&self) -> String { + match self { + Self::Secp256k1 => String::from("secp256k1"), + Self::Secp256k1Bip340 => String::from("secp256k1_bip340"), + Self::Secp256r1 => String::from("secp256r1"), + Self::Edwards25519 => String::from("edwards25519"), + Self::Tweedle => String::from("tweedle"), + Self::Pallas => String::from("pallas"), + } + } +} + +impl Default for CurveType { + fn default() -> CurveType { + Self::Secp256k1 + } +} + + + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/direction.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/direction.rs new file mode 100644 index 0000000000..cae3d594a6 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/direction.rs @@ -0,0 +1,40 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// Direction : Used by RelatedTransaction to indicate the direction of the relation (i.e. cross-shard/cross-network sends may reference `backward` to an earlier transaction and async execution may reference `forward`). Can be used to indicate if a transaction relation is from child to parent or the reverse. + +/// Used by RelatedTransaction to indicate the direction of the relation (i.e. cross-shard/cross-network sends may reference `backward` to an earlier transaction and async execution may reference `forward`). Can be used to indicate if a transaction relation is from child to parent or the reverse. +#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, serde::Serialize, serde::Deserialize)] +pub enum Direction { + #[serde(rename = "forward")] + Forward, + #[serde(rename = "backward")] + Backward, + +} + +impl ToString for Direction { + fn to_string(&self) -> String { + match self { + Self::Forward => String::from("forward"), + Self::Backward => String::from("backward"), + } + } +} + +impl Default for Direction { + fn default() -> Direction { + Self::Forward + } +} + + + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/error.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/error.rs new file mode 100644 index 0000000000..b20c3f2c40 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/error.rs @@ -0,0 +1,47 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// Error : Instead of utilizing HTTP status codes to describe node errors (which often do not have a good analog), rich errors are returned using this object. Both the code and message fields can be individually used to correctly identify an error. Implementations MUST use unique values for both fields. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct Error { + /// Code is a network-specific error code. If desired, this code can be equivalent to an HTTP status code. + #[serde(rename = "code")] + pub code: i32, + /// Message is a network-specific error message. The message MUST NOT change for a given code. In particular, this means that any contextual information should be included in the details field. + #[serde(rename = "message")] + pub message: String, + /// Description allows the implementer to optionally provide additional information about an error. In many cases, the content of this field will be a copy-and-paste from existing developer documentation. Description can ONLY be populated with generic information about a particular type of error. It MUST NOT be populated with information about a particular instantiation of an error (use `details` for this). Whereas the content of Error.Message should stay stable across releases, the content of Error.Description will likely change across releases (as implementers improve error documentation). For this reason, the content in this field is not part of any type assertion (unlike Error.Message). + #[serde(rename = "description", skip_serializing_if = "Option::is_none")] + pub description: Option, + /// An error is retriable if the same request may succeed if submitted again. + #[serde(rename = "retriable")] + pub retriable: bool, + /// Often times it is useful to return context specific to the request that caused the error (i.e. a sample of the stack trace or impacted account) in addition to the standard error message. + #[serde(rename = "details", skip_serializing_if = "Option::is_none")] + pub details: Option, +} + +impl Error { + /// Instead of utilizing HTTP status codes to describe node errors (which often do not have a good analog), rich errors are returned using this object. Both the code and message fields can be individually used to correctly identify an error. Implementations MUST use unique values for both fields. + pub fn new(code: i32, message: String, retriable: bool) -> Error { + Error { + code, + message, + description: None, + retriable, + details: None, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/events_blocks_request.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/events_blocks_request.rs new file mode 100644 index 0000000000..9ab0df76aa --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/events_blocks_request.rs @@ -0,0 +1,38 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// EventsBlocksRequest : EventsBlocksRequest is utilized to fetch a sequence of BlockEvents indicating which blocks were added and removed from storage to reach the current state. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct EventsBlocksRequest { + #[serde(rename = "network_identifier")] + pub network_identifier: Box, + /// offset is the offset into the event stream to sync events from. If this field is not populated, we return the limit events backwards from tip. If this is set to 0, we start from the beginning. + #[serde(rename = "offset", skip_serializing_if = "Option::is_none")] + pub offset: Option, + /// limit is the maximum number of events to fetch in one call. The implementation may return <= limit events. + #[serde(rename = "limit", skip_serializing_if = "Option::is_none")] + pub limit: Option, +} + +impl EventsBlocksRequest { + /// EventsBlocksRequest is utilized to fetch a sequence of BlockEvents indicating which blocks were added and removed from storage to reach the current state. + pub fn new(network_identifier: crate::mesh_api::generated::models::NetworkIdentifier) -> EventsBlocksRequest { + EventsBlocksRequest { + network_identifier: Box::new(network_identifier), + offset: None, + limit: None, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/events_blocks_response.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/events_blocks_response.rs new file mode 100644 index 0000000000..ecb0dbf66f --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/events_blocks_response.rs @@ -0,0 +1,35 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// EventsBlocksResponse : EventsBlocksResponse contains an ordered collection of BlockEvents and the max retrievable sequence. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct EventsBlocksResponse { + /// max_sequence is the maximum available sequence number to fetch. + #[serde(rename = "max_sequence")] + pub max_sequence: i64, + /// events is an array of BlockEvents indicating the order to add and remove blocks to maintain a canonical view of blockchain state. Lightweight clients can use this event stream to update state without implementing their own block syncing logic. + #[serde(rename = "events")] + pub events: Vec, +} + +impl EventsBlocksResponse { + /// EventsBlocksResponse contains an ordered collection of BlockEvents and the max retrievable sequence. + pub fn new(max_sequence: i64, events: Vec) -> EventsBlocksResponse { + EventsBlocksResponse { + max_sequence, + events, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/exemption_type.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/exemption_type.rs new file mode 100644 index 0000000000..8567f5fa01 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/exemption_type.rs @@ -0,0 +1,43 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// ExemptionType : ExemptionType is used to indicate if the live balance for an account subject to a BalanceExemption could increase above, decrease below, or equal the computed balance. * greater_or_equal: The live balance may increase above or equal the computed balance. This typically occurs with staking rewards that accrue on each block. * less_or_equal: The live balance may decrease below or equal the computed balance. This typically occurs as balance moves from locked to spendable on a vesting account. * dynamic: The live balance may increase above, decrease below, or equal the computed balance. This typically occurs with tokens that have a dynamic supply. + +/// ExemptionType is used to indicate if the live balance for an account subject to a BalanceExemption could increase above, decrease below, or equal the computed balance. * greater_or_equal: The live balance may increase above or equal the computed balance. This typically occurs with staking rewards that accrue on each block. * less_or_equal: The live balance may decrease below or equal the computed balance. This typically occurs as balance moves from locked to spendable on a vesting account. * dynamic: The live balance may increase above, decrease below, or equal the computed balance. This typically occurs with tokens that have a dynamic supply. +#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, serde::Serialize, serde::Deserialize)] +pub enum ExemptionType { + #[serde(rename = "greater_or_equal")] + GreaterOrEqual, + #[serde(rename = "less_or_equal")] + LessOrEqual, + #[serde(rename = "dynamic")] + Dynamic, + +} + +impl ToString for ExemptionType { + fn to_string(&self) -> String { + match self { + Self::GreaterOrEqual => String::from("greater_or_equal"), + Self::LessOrEqual => String::from("less_or_equal"), + Self::Dynamic => String::from("dynamic"), + } + } +} + +impl Default for ExemptionType { + fn default() -> ExemptionType { + Self::GreaterOrEqual + } +} + + + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/mempool_response.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/mempool_response.rs new file mode 100644 index 0000000000..a5034fd7f6 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/mempool_response.rs @@ -0,0 +1,30 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// MempoolResponse : A MempoolResponse contains all transaction identifiers in the mempool for a particular network_identifier. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct MempoolResponse { + #[serde(rename = "transaction_identifiers")] + pub transaction_identifiers: Vec, +} + +impl MempoolResponse { + /// A MempoolResponse contains all transaction identifiers in the mempool for a particular network_identifier. + pub fn new(transaction_identifiers: Vec) -> MempoolResponse { + MempoolResponse { + transaction_identifiers, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/mempool_transaction_request.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/mempool_transaction_request.rs new file mode 100644 index 0000000000..6a33b1d8d2 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/mempool_transaction_request.rs @@ -0,0 +1,33 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// MempoolTransactionRequest : A MempoolTransactionRequest is utilized to retrieve a transaction from the mempool. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct MempoolTransactionRequest { + #[serde(rename = "network_identifier")] + pub network_identifier: Box, + #[serde(rename = "transaction_identifier")] + pub transaction_identifier: Box, +} + +impl MempoolTransactionRequest { + /// A MempoolTransactionRequest is utilized to retrieve a transaction from the mempool. + pub fn new(network_identifier: crate::mesh_api::generated::models::NetworkIdentifier, transaction_identifier: crate::mesh_api::generated::models::TransactionIdentifier) -> MempoolTransactionRequest { + MempoolTransactionRequest { + network_identifier: Box::new(network_identifier), + transaction_identifier: Box::new(transaction_identifier), + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/mempool_transaction_response.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/mempool_transaction_response.rs new file mode 100644 index 0000000000..a22078c12a --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/mempool_transaction_response.rs @@ -0,0 +1,33 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// MempoolTransactionResponse : A MempoolTransactionResponse contains an estimate of a mempool transaction. It may not be possible to know the full impact of a transaction in the mempool (ex: fee paid). + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct MempoolTransactionResponse { + #[serde(rename = "transaction")] + pub transaction: Box, + #[serde(rename = "metadata", skip_serializing_if = "Option::is_none")] + pub metadata: Option, +} + +impl MempoolTransactionResponse { + /// A MempoolTransactionResponse contains an estimate of a mempool transaction. It may not be possible to know the full impact of a transaction in the mempool (ex: fee paid). + pub fn new(transaction: crate::mesh_api::generated::models::Transaction) -> MempoolTransactionResponse { + MempoolTransactionResponse { + transaction: Box::new(transaction), + metadata: None, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/metadata_request.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/metadata_request.rs new file mode 100644 index 0000000000..31d7392568 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/metadata_request.rs @@ -0,0 +1,30 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// MetadataRequest : A MetadataRequest is utilized in any request where the only argument is optional metadata. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct MetadataRequest { + #[serde(rename = "metadata", skip_serializing_if = "Option::is_none")] + pub metadata: Option, +} + +impl MetadataRequest { + /// A MetadataRequest is utilized in any request where the only argument is optional metadata. + pub fn new() -> MetadataRequest { + MetadataRequest { + metadata: None, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/mod.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/mod.rs new file mode 100644 index 0000000000..eddd86e211 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/mod.rs @@ -0,0 +1,148 @@ +pub mod account_balance_request; +pub use self::account_balance_request::AccountBalanceRequest; +pub mod account_balance_response; +pub use self::account_balance_response::AccountBalanceResponse; +pub mod account_coins_request; +pub use self::account_coins_request::AccountCoinsRequest; +pub mod account_coins_response; +pub use self::account_coins_response::AccountCoinsResponse; +pub mod account_identifier; +pub use self::account_identifier::AccountIdentifier; +pub mod allow; +pub use self::allow::Allow; +pub mod amount; +pub use self::amount::Amount; +pub mod balance_exemption; +pub use self::balance_exemption::BalanceExemption; +pub mod block; +pub use self::block::Block; +pub mod block_event; +pub use self::block_event::BlockEvent; +pub mod block_event_type; +pub use self::block_event_type::BlockEventType; +pub mod block_identifier; +pub use self::block_identifier::BlockIdentifier; +pub mod block_request; +pub use self::block_request::BlockRequest; +pub mod block_response; +pub use self::block_response::BlockResponse; +pub mod block_transaction; +pub use self::block_transaction::BlockTransaction; +pub mod block_transaction_request; +pub use self::block_transaction_request::BlockTransactionRequest; +pub mod block_transaction_response; +pub use self::block_transaction_response::BlockTransactionResponse; +pub mod call_request; +pub use self::call_request::CallRequest; +pub mod call_response; +pub use self::call_response::CallResponse; +pub mod case; +pub use self::case::Case; +pub mod coin; +pub use self::coin::Coin; +pub mod coin_action; +pub use self::coin_action::CoinAction; +pub mod coin_change; +pub use self::coin_change::CoinChange; +pub mod coin_identifier; +pub use self::coin_identifier::CoinIdentifier; +pub mod construction_combine_request; +pub use self::construction_combine_request::ConstructionCombineRequest; +pub mod construction_combine_response; +pub use self::construction_combine_response::ConstructionCombineResponse; +pub mod construction_derive_request; +pub use self::construction_derive_request::ConstructionDeriveRequest; +pub mod construction_derive_response; +pub use self::construction_derive_response::ConstructionDeriveResponse; +pub mod construction_hash_request; +pub use self::construction_hash_request::ConstructionHashRequest; +pub mod construction_metadata_request; +pub use self::construction_metadata_request::ConstructionMetadataRequest; +pub mod construction_metadata_response; +pub use self::construction_metadata_response::ConstructionMetadataResponse; +pub mod construction_parse_request; +pub use self::construction_parse_request::ConstructionParseRequest; +pub mod construction_parse_response; +pub use self::construction_parse_response::ConstructionParseResponse; +pub mod construction_payloads_request; +pub use self::construction_payloads_request::ConstructionPayloadsRequest; +pub mod construction_payloads_response; +pub use self::construction_payloads_response::ConstructionPayloadsResponse; +pub mod construction_preprocess_request; +pub use self::construction_preprocess_request::ConstructionPreprocessRequest; +pub mod construction_preprocess_response; +pub use self::construction_preprocess_response::ConstructionPreprocessResponse; +pub mod construction_submit_request; +pub use self::construction_submit_request::ConstructionSubmitRequest; +pub mod currency; +pub use self::currency::Currency; +pub mod curve_type; +pub use self::curve_type::CurveType; +pub mod direction; +pub use self::direction::Direction; +pub mod error; +pub use self::error::Error; +pub mod events_blocks_request; +pub use self::events_blocks_request::EventsBlocksRequest; +pub mod events_blocks_response; +pub use self::events_blocks_response::EventsBlocksResponse; +pub mod exemption_type; +pub use self::exemption_type::ExemptionType; +pub mod mempool_response; +pub use self::mempool_response::MempoolResponse; +pub mod mempool_transaction_request; +pub use self::mempool_transaction_request::MempoolTransactionRequest; +pub mod mempool_transaction_response; +pub use self::mempool_transaction_response::MempoolTransactionResponse; +pub mod metadata_request; +pub use self::metadata_request::MetadataRequest; +pub mod network_identifier; +pub use self::network_identifier::NetworkIdentifier; +pub mod network_list_response; +pub use self::network_list_response::NetworkListResponse; +pub mod network_options_response; +pub use self::network_options_response::NetworkOptionsResponse; +pub mod network_request; +pub use self::network_request::NetworkRequest; +pub mod network_status_response; +pub use self::network_status_response::NetworkStatusResponse; +pub mod operation; +pub use self::operation::Operation; +pub mod operation_identifier; +pub use self::operation_identifier::OperationIdentifier; +pub mod operation_status; +pub use self::operation_status::OperationStatus; +pub mod operator; +pub use self::operator::Operator; +pub mod partial_block_identifier; +pub use self::partial_block_identifier::PartialBlockIdentifier; +pub mod peer; +pub use self::peer::Peer; +pub mod public_key; +pub use self::public_key::PublicKey; +pub mod related_transaction; +pub use self::related_transaction::RelatedTransaction; +pub mod search_transactions_request; +pub use self::search_transactions_request::SearchTransactionsRequest; +pub mod search_transactions_response; +pub use self::search_transactions_response::SearchTransactionsResponse; +pub mod signature; +pub use self::signature::Signature; +pub mod signature_type; +pub use self::signature_type::SignatureType; +pub mod signing_payload; +pub use self::signing_payload::SigningPayload; +pub mod sub_account_identifier; +pub use self::sub_account_identifier::SubAccountIdentifier; +pub mod sub_network_identifier; +pub use self::sub_network_identifier::SubNetworkIdentifier; +pub mod sync_status; +pub use self::sync_status::SyncStatus; +pub mod transaction; +pub use self::transaction::Transaction; +pub mod transaction_identifier; +pub use self::transaction_identifier::TransactionIdentifier; +pub mod transaction_identifier_response; +pub use self::transaction_identifier_response::TransactionIdentifierResponse; +pub mod version; +pub use self::version::Version; diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/network_identifier.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/network_identifier.rs new file mode 100644 index 0000000000..4b4577bed6 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/network_identifier.rs @@ -0,0 +1,37 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// NetworkIdentifier : The network_identifier specifies which network a particular object is associated with. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct NetworkIdentifier { + #[serde(rename = "blockchain")] + pub blockchain: String, + /// If a blockchain has a specific chain-id or network identifier, it should go in this field. It is up to the client to determine which network-specific identifier is mainnet or testnet. + #[serde(rename = "network")] + pub network: String, + #[serde(rename = "sub_network_identifier", skip_serializing_if = "Option::is_none")] + pub sub_network_identifier: Option>, +} + +impl NetworkIdentifier { + /// The network_identifier specifies which network a particular object is associated with. + pub fn new(blockchain: String, network: String) -> NetworkIdentifier { + NetworkIdentifier { + blockchain, + network, + sub_network_identifier: None, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/network_list_response.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/network_list_response.rs new file mode 100644 index 0000000000..254236f114 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/network_list_response.rs @@ -0,0 +1,30 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// NetworkListResponse : A NetworkListResponse contains all NetworkIdentifiers that the node can serve information for. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct NetworkListResponse { + #[serde(rename = "network_identifiers")] + pub network_identifiers: Vec, +} + +impl NetworkListResponse { + /// A NetworkListResponse contains all NetworkIdentifiers that the node can serve information for. + pub fn new(network_identifiers: Vec) -> NetworkListResponse { + NetworkListResponse { + network_identifiers, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/network_options_response.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/network_options_response.rs new file mode 100644 index 0000000000..c95ca208bc --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/network_options_response.rs @@ -0,0 +1,33 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// NetworkOptionsResponse : NetworkOptionsResponse contains information about the versioning of the node and the allowed operation statuses, operation types, and errors. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct NetworkOptionsResponse { + #[serde(rename = "version")] + pub version: Box, + #[serde(rename = "allow")] + pub allow: Box, +} + +impl NetworkOptionsResponse { + /// NetworkOptionsResponse contains information about the versioning of the node and the allowed operation statuses, operation types, and errors. + pub fn new(version: crate::mesh_api::generated::models::Version, allow: crate::mesh_api::generated::models::Allow) -> NetworkOptionsResponse { + NetworkOptionsResponse { + version: Box::new(version), + allow: Box::new(allow), + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/network_request.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/network_request.rs new file mode 100644 index 0000000000..d8b00bf7ca --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/network_request.rs @@ -0,0 +1,33 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// NetworkRequest : A NetworkRequest is utilized to retrieve some data specific exclusively to a NetworkIdentifier. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct NetworkRequest { + #[serde(rename = "network_identifier")] + pub network_identifier: Box, + #[serde(rename = "metadata", skip_serializing_if = "Option::is_none")] + pub metadata: Option, +} + +impl NetworkRequest { + /// A NetworkRequest is utilized to retrieve some data specific exclusively to a NetworkIdentifier. + pub fn new(network_identifier: crate::mesh_api::generated::models::NetworkIdentifier) -> NetworkRequest { + NetworkRequest { + network_identifier: Box::new(network_identifier), + metadata: None, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/network_status_response.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/network_status_response.rs new file mode 100644 index 0000000000..bb1a534cc5 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/network_status_response.rs @@ -0,0 +1,46 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// NetworkStatusResponse : NetworkStatusResponse contains basic information about the node's view of a blockchain network. It is assumed that any BlockIdentifier.Index less than or equal to CurrentBlockIdentifier.Index can be queried. If a Rosetta implementation prunes historical state, it should populate the optional `oldest_block_identifier` field with the oldest block available to query. If this is not populated, it is assumed that the `genesis_block_identifier` is the oldest queryable block. If a Rosetta implementation performs some pre-sync before it is possible to query blocks, sync_status should be populated so that clients can still monitor healthiness. Without this field, it may appear that the implementation is stuck syncing and needs to be terminated. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct NetworkStatusResponse { + #[serde(rename = "current_block_identifier")] + pub current_block_identifier: Box, + /// The timestamp of the block in milliseconds since the Unix Epoch. The timestamp is stored in milliseconds because some blockchains produce blocks more often than once a second. + #[serde(rename = "current_block_timestamp")] + pub current_block_timestamp: i64, + #[serde(rename = "genesis_block_identifier")] + pub genesis_block_identifier: Box, + #[serde(rename = "oldest_block_identifier", skip_serializing_if = "Option::is_none")] + pub oldest_block_identifier: Option>, + #[serde(rename = "sync_status", skip_serializing_if = "Option::is_none")] + pub sync_status: Option>, + #[serde(rename = "peers", skip_serializing_if = "Option::is_none")] + pub peers: Option>, +} + +impl NetworkStatusResponse { + /// NetworkStatusResponse contains basic information about the node's view of a blockchain network. It is assumed that any BlockIdentifier.Index less than or equal to CurrentBlockIdentifier.Index can be queried. If a Rosetta implementation prunes historical state, it should populate the optional `oldest_block_identifier` field with the oldest block available to query. If this is not populated, it is assumed that the `genesis_block_identifier` is the oldest queryable block. If a Rosetta implementation performs some pre-sync before it is possible to query blocks, sync_status should be populated so that clients can still monitor healthiness. Without this field, it may appear that the implementation is stuck syncing and needs to be terminated. + pub fn new(current_block_identifier: crate::mesh_api::generated::models::BlockIdentifier, current_block_timestamp: i64, genesis_block_identifier: crate::mesh_api::generated::models::BlockIdentifier) -> NetworkStatusResponse { + NetworkStatusResponse { + current_block_identifier: Box::new(current_block_identifier), + current_block_timestamp, + genesis_block_identifier: Box::new(genesis_block_identifier), + oldest_block_identifier: None, + sync_status: None, + peers: None, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/operation.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/operation.rs new file mode 100644 index 0000000000..fb0616627a --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/operation.rs @@ -0,0 +1,54 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// Operation : Operations contain all balance-changing information within a transaction. They are always one-sided (only affect 1 AccountIdentifier) and can succeed or fail independently from a Transaction. Operations are used both to represent on-chain data (Data API) and to construct new transactions (Construction API), creating a standard interface for reading and writing to blockchains. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct Operation { + #[serde(rename = "operation_identifier")] + pub operation_identifier: Box, + /// Restrict referenced related_operations to identifier indices < the current operation_identifier.index. This ensures there exists a clear DAG-structure of relations. Since operations are one-sided, one could imagine relating operations in a single transfer or linking operations in a call tree. + #[serde(rename = "related_operations", skip_serializing_if = "Option::is_none")] + pub related_operations: Option>, + /// Type is the network-specific type of the operation. Ensure that any type that can be returned here is also specified in the NetworkOptionsResponse. This can be very useful to downstream consumers that parse all block data. + #[serde(rename = "type")] + pub _type: String, + /// Status is the network-specific status of the operation. Status is not defined on the transaction object because blockchains with smart contracts may have transactions that partially apply (some operations are successful and some are not). Blockchains with atomic transactions (all operations succeed or all operations fail) will have the same status for each operation. On-chain operations (operations retrieved in the `/block` and `/block/transaction` endpoints) MUST have a populated status field (anything on-chain must have succeeded or failed). However, operations provided during transaction construction (often times called \"intent\" in the documentation) MUST NOT have a populated status field (operations yet to be included on-chain have not yet succeeded or failed). + #[serde(rename = "status", skip_serializing_if = "Option::is_none")] + pub status: Option, + #[serde(rename = "account", skip_serializing_if = "Option::is_none")] + pub account: Option>, + #[serde(rename = "amount", skip_serializing_if = "Option::is_none")] + pub amount: Option>, + #[serde(rename = "coin_change", skip_serializing_if = "Option::is_none")] + pub coin_change: Option>, + #[serde(rename = "metadata", skip_serializing_if = "Option::is_none")] + pub metadata: Option, +} + +impl Operation { + /// Operations contain all balance-changing information within a transaction. They are always one-sided (only affect 1 AccountIdentifier) and can succeed or fail independently from a Transaction. Operations are used both to represent on-chain data (Data API) and to construct new transactions (Construction API), creating a standard interface for reading and writing to blockchains. + pub fn new(operation_identifier: crate::mesh_api::generated::models::OperationIdentifier, _type: String) -> Operation { + Operation { + operation_identifier: Box::new(operation_identifier), + related_operations: None, + _type, + status: None, + account: None, + amount: None, + coin_change: None, + metadata: None, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/operation_identifier.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/operation_identifier.rs new file mode 100644 index 0000000000..152420ff69 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/operation_identifier.rs @@ -0,0 +1,35 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// OperationIdentifier : The operation_identifier uniquely identifies an operation within a transaction. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct OperationIdentifier { + /// The operation index is used to ensure each operation has a unique identifier within a transaction. This index is only relative to the transaction and NOT GLOBAL. The operations in each transaction should start from index 0. To clarify, there may not be any notion of an operation index in the blockchain being described. + #[serde(rename = "index")] + pub index: i64, + /// Some blockchains specify an operation index that is essential for client use. For example, Bitcoin uses a network_index to identify which UTXO was used in a transaction. network_index should not be populated if there is no notion of an operation index in a blockchain (typically most account-based blockchains). + #[serde(rename = "network_index", skip_serializing_if = "Option::is_none")] + pub network_index: Option, +} + +impl OperationIdentifier { + /// The operation_identifier uniquely identifies an operation within a transaction. + pub fn new(index: i64) -> OperationIdentifier { + OperationIdentifier { + index, + network_index: None, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/operation_status.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/operation_status.rs new file mode 100644 index 0000000000..39daf2215c --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/operation_status.rs @@ -0,0 +1,35 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// OperationStatus : OperationStatus is utilized to indicate which Operation status are considered successful. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct OperationStatus { + /// The status is the network-specific status of the operation. + #[serde(rename = "status")] + pub status: String, + /// An Operation is considered successful if the Operation.Amount should affect the Operation.Account. Some blockchains (like Bitcoin) only include successful operations in blocks but other blockchains (like Ethereum) include unsuccessful operations that incur a fee. To reconcile the computed balance from the stream of Operations, it is critical to understand which Operation.Status indicate an Operation is successful and should affect an Account. + #[serde(rename = "successful")] + pub successful: bool, +} + +impl OperationStatus { + /// OperationStatus is utilized to indicate which Operation status are considered successful. + pub fn new(status: String, successful: bool) -> OperationStatus { + OperationStatus { + status, + successful, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/operator.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/operator.rs new file mode 100644 index 0000000000..7cb0bba3d3 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/operator.rs @@ -0,0 +1,40 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// Operator : Operator is used by query-related endpoints to determine how to apply conditions. If this field is not populated, the default `and` value will be used. + +/// Operator is used by query-related endpoints to determine how to apply conditions. If this field is not populated, the default `and` value will be used. +#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, serde::Serialize, serde::Deserialize)] +pub enum Operator { + #[serde(rename = "or")] + Or, + #[serde(rename = "and")] + And, + +} + +impl ToString for Operator { + fn to_string(&self) -> String { + match self { + Self::Or => String::from("or"), + Self::And => String::from("and"), + } + } +} + +impl Default for Operator { + fn default() -> Operator { + Self::Or + } +} + + + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/partial_block_identifier.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/partial_block_identifier.rs new file mode 100644 index 0000000000..fdb0b4f08f --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/partial_block_identifier.rs @@ -0,0 +1,33 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// PartialBlockIdentifier : When fetching data by BlockIdentifier, it may be possible to only specify the index or hash. If neither property is specified, it is assumed that the client is making a request at the current block. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct PartialBlockIdentifier { + #[serde(rename = "index", skip_serializing_if = "Option::is_none")] + pub index: Option, + #[serde(rename = "hash", skip_serializing_if = "Option::is_none")] + pub hash: Option, +} + +impl PartialBlockIdentifier { + /// When fetching data by BlockIdentifier, it may be possible to only specify the index or hash. If neither property is specified, it is assumed that the client is making a request at the current block. + pub fn new() -> PartialBlockIdentifier { + PartialBlockIdentifier { + index: None, + hash: None, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/peer.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/peer.rs new file mode 100644 index 0000000000..2281f69b98 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/peer.rs @@ -0,0 +1,33 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// Peer : A Peer is a representation of a node's peer. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct Peer { + #[serde(rename = "peer_id")] + pub peer_id: String, + #[serde(rename = "metadata", skip_serializing_if = "Option::is_none")] + pub metadata: Option, +} + +impl Peer { + /// A Peer is a representation of a node's peer. + pub fn new(peer_id: String) -> Peer { + Peer { + peer_id, + metadata: None, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/public_key.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/public_key.rs new file mode 100644 index 0000000000..a6bae8a754 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/public_key.rs @@ -0,0 +1,34 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// PublicKey : PublicKey contains a public key byte array for a particular CurveType encoded in hex. Note that there is no PrivateKey struct as this is NEVER the concern of an implementation. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct PublicKey { + /// Hex-encoded public key bytes in the format specified by the CurveType. + #[serde(rename = "hex_bytes")] + pub hex_bytes: String, + #[serde(rename = "curve_type")] + pub curve_type: crate::mesh_api::generated::models::CurveType, +} + +impl PublicKey { + /// PublicKey contains a public key byte array for a particular CurveType encoded in hex. Note that there is no PrivateKey struct as this is NEVER the concern of an implementation. + pub fn new(hex_bytes: String, curve_type: crate::mesh_api::generated::models::CurveType) -> PublicKey { + PublicKey { + hex_bytes, + curve_type, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/related_transaction.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/related_transaction.rs new file mode 100644 index 0000000000..193635f467 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/related_transaction.rs @@ -0,0 +1,36 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// RelatedTransaction : The related_transaction allows implementations to link together multiple transactions. An unpopulated network identifier indicates that the related transaction is on the same network. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct RelatedTransaction { + #[serde(rename = "network_identifier", skip_serializing_if = "Option::is_none")] + pub network_identifier: Option>, + #[serde(rename = "transaction_identifier")] + pub transaction_identifier: Box, + #[serde(rename = "direction")] + pub direction: crate::mesh_api::generated::models::Direction, +} + +impl RelatedTransaction { + /// The related_transaction allows implementations to link together multiple transactions. An unpopulated network identifier indicates that the related transaction is on the same network. + pub fn new(transaction_identifier: crate::mesh_api::generated::models::TransactionIdentifier, direction: crate::mesh_api::generated::models::Direction) -> RelatedTransaction { + RelatedTransaction { + network_identifier: None, + transaction_identifier: Box::new(transaction_identifier), + direction, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/search_transactions_request.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/search_transactions_request.rs new file mode 100644 index 0000000000..ae2bd5dd6b --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/search_transactions_request.rs @@ -0,0 +1,73 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// SearchTransactionsRequest : SearchTransactionsRequest is used to search for transactions matching a set of provided conditions in canonical blocks. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct SearchTransactionsRequest { + #[serde(rename = "network_identifier")] + pub network_identifier: Box, + #[serde(rename = "operator", skip_serializing_if = "Option::is_none")] + pub operator: Option, + /// max_block is the largest block index to consider when searching for transactions. If this field is not populated, the current block is considered the max_block. If you do not specify a max_block, it is possible a newly synced block will interfere with paginated transaction queries (as the offset could become invalid with newly added rows). + #[serde(rename = "max_block", skip_serializing_if = "Option::is_none")] + pub max_block: Option, + /// offset is the offset into the query result to start returning transactions. If any search conditions are changed, the query offset will change and you must restart your search iteration. + #[serde(rename = "offset", skip_serializing_if = "Option::is_none")] + pub offset: Option, + /// limit is the maximum number of transactions to return in one call. The implementation may return <= limit transactions. + #[serde(rename = "limit", skip_serializing_if = "Option::is_none")] + pub limit: Option, + #[serde(rename = "transaction_identifier", skip_serializing_if = "Option::is_none")] + pub transaction_identifier: Option>, + #[serde(rename = "account_identifier", skip_serializing_if = "Option::is_none")] + pub account_identifier: Option>, + #[serde(rename = "coin_identifier", skip_serializing_if = "Option::is_none")] + pub coin_identifier: Option>, + #[serde(rename = "currency", skip_serializing_if = "Option::is_none")] + pub currency: Option>, + /// status is the network-specific operation type. + #[serde(rename = "status", skip_serializing_if = "Option::is_none")] + pub status: Option, + /// type is the network-specific operation type. + #[serde(rename = "type", skip_serializing_if = "Option::is_none")] + pub _type: Option, + /// address is AccountIdentifier.Address. This is used to get all transactions related to an AccountIdentifier.Address, regardless of SubAccountIdentifier. + #[serde(rename = "address", skip_serializing_if = "Option::is_none")] + pub address: Option, + /// success is a synthetic condition populated by parsing network-specific operation statuses (using the mapping provided in `/network/options`). + #[serde(rename = "success", skip_serializing_if = "Option::is_none")] + pub success: Option, +} + +impl SearchTransactionsRequest { + /// SearchTransactionsRequest is used to search for transactions matching a set of provided conditions in canonical blocks. + pub fn new(network_identifier: crate::mesh_api::generated::models::NetworkIdentifier) -> SearchTransactionsRequest { + SearchTransactionsRequest { + network_identifier: Box::new(network_identifier), + operator: None, + max_block: None, + offset: None, + limit: None, + transaction_identifier: None, + account_identifier: None, + coin_identifier: None, + currency: None, + status: None, + _type: None, + address: None, + success: None, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/search_transactions_response.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/search_transactions_response.rs new file mode 100644 index 0000000000..911812f722 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/search_transactions_response.rs @@ -0,0 +1,39 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// SearchTransactionsResponse : SearchTransactionsResponse contains an ordered collection of BlockTransactions that match the query in SearchTransactionsRequest. These BlockTransactions are sorted from most recent block to oldest block. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct SearchTransactionsResponse { + /// transactions is an array of BlockTransactions sorted by most recent BlockIdentifier (meaning that transactions in recent blocks appear first). If there are many transactions for a particular search, transactions may not contain all matching transactions. It is up to the caller to paginate these transactions using the max_block field. + #[serde(rename = "transactions")] + pub transactions: Vec, + /// total_count is the number of results for a given search. Callers typically use this value to concurrently fetch results by offset or to display a virtual page number associated with results. + #[serde(rename = "total_count")] + pub total_count: i64, + /// next_offset is the next offset to use when paginating through transaction results. If this field is not populated, there are no more transactions to query. + #[serde(rename = "next_offset", skip_serializing_if = "Option::is_none")] + pub next_offset: Option, +} + +impl SearchTransactionsResponse { + /// SearchTransactionsResponse contains an ordered collection of BlockTransactions that match the query in SearchTransactionsRequest. These BlockTransactions are sorted from most recent block to oldest block. + pub fn new(transactions: Vec, total_count: i64) -> SearchTransactionsResponse { + SearchTransactionsResponse { + transactions, + total_count, + next_offset: None, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/signature.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/signature.rs new file mode 100644 index 0000000000..09e65ef5b7 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/signature.rs @@ -0,0 +1,39 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// Signature : Signature contains the payload that was signed, the public keys of the keypairs used to produce the signature, the signature (encoded in hex), and the SignatureType. PublicKey is often times not known during construction of the signing payloads but may be needed to combine signatures properly. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct Signature { + #[serde(rename = "signing_payload")] + pub signing_payload: Box, + #[serde(rename = "public_key")] + pub public_key: Box, + #[serde(rename = "signature_type")] + pub signature_type: crate::mesh_api::generated::models::SignatureType, + #[serde(rename = "hex_bytes")] + pub hex_bytes: String, +} + +impl Signature { + /// Signature contains the payload that was signed, the public keys of the keypairs used to produce the signature, the signature (encoded in hex), and the SignatureType. PublicKey is often times not known during construction of the signing payloads but may be needed to combine signatures properly. + pub fn new(signing_payload: crate::mesh_api::generated::models::SigningPayload, public_key: crate::mesh_api::generated::models::PublicKey, signature_type: crate::mesh_api::generated::models::SignatureType, hex_bytes: String) -> Signature { + Signature { + signing_payload: Box::new(signing_payload), + public_key: Box::new(public_key), + signature_type, + hex_bytes, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/signature_type.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/signature_type.rs new file mode 100644 index 0000000000..94522b65c0 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/signature_type.rs @@ -0,0 +1,52 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// SignatureType : SignatureType is the type of a cryptographic signature. * ecdsa: `r (32-bytes) || s (32-bytes)` - `64 bytes` * ecdsa_recovery: `r (32-bytes) || s (32-bytes) || v (1-byte)` - `65 bytes` * ed25519: `R (32-byte) || s (32-bytes)` - `64 bytes` * schnorr_1: `r (32-bytes) || s (32-bytes)` - `64 bytes` (schnorr signature implemented by Zilliqa where both `r` and `s` are scalars encoded as `32-bytes` values, most significant byte first.) * schnorr_bip340: `r (32-bytes) || s (32-bytes)` - `64 bytes` (sig = (bytes(R) || bytes((k + ed) mod n) where `r` is the `X` coordinate of a point `R` whose `Y` coordinate is even, most significant bytes first.) * schnorr_poseidon: `r (32-bytes) || s (32-bytes)` where s = Hash(1st pk || 2nd pk || r) - `64 bytes` (schnorr signature w/ Poseidon hash function implemented by O(1) Labs where both `r` and `s` are scalars encoded as `32-bytes` values, least significant byte first. https://github.com/CodaProtocol/signer-reference/blob/master/schnorr.ml ) + +/// SignatureType is the type of a cryptographic signature. * ecdsa: `r (32-bytes) || s (32-bytes)` - `64 bytes` * ecdsa_recovery: `r (32-bytes) || s (32-bytes) || v (1-byte)` - `65 bytes` * ed25519: `R (32-byte) || s (32-bytes)` - `64 bytes` * schnorr_1: `r (32-bytes) || s (32-bytes)` - `64 bytes` (schnorr signature implemented by Zilliqa where both `r` and `s` are scalars encoded as `32-bytes` values, most significant byte first.) * schnorr_bip340: `r (32-bytes) || s (32-bytes)` - `64 bytes` (sig = (bytes(R) || bytes((k + ed) mod n) where `r` is the `X` coordinate of a point `R` whose `Y` coordinate is even, most significant bytes first.) * schnorr_poseidon: `r (32-bytes) || s (32-bytes)` where s = Hash(1st pk || 2nd pk || r) - `64 bytes` (schnorr signature w/ Poseidon hash function implemented by O(1) Labs where both `r` and `s` are scalars encoded as `32-bytes` values, least significant byte first. https://github.com/CodaProtocol/signer-reference/blob/master/schnorr.ml ) +#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, serde::Serialize, serde::Deserialize)] +pub enum SignatureType { + #[serde(rename = "ecdsa")] + Ecdsa, + #[serde(rename = "ecdsa_recovery")] + EcdsaRecovery, + #[serde(rename = "ed25519")] + Ed25519, + #[serde(rename = "schnorr_1")] + Schnorr1, + #[serde(rename = "schnorr_bip340")] + SchnorrBip340, + #[serde(rename = "schnorr_poseidon")] + SchnorrPoseidon, + +} + +impl ToString for SignatureType { + fn to_string(&self) -> String { + match self { + Self::Ecdsa => String::from("ecdsa"), + Self::EcdsaRecovery => String::from("ecdsa_recovery"), + Self::Ed25519 => String::from("ed25519"), + Self::Schnorr1 => String::from("schnorr_1"), + Self::SchnorrBip340 => String::from("schnorr_bip340"), + Self::SchnorrPoseidon => String::from("schnorr_poseidon"), + } + } +} + +impl Default for SignatureType { + fn default() -> SignatureType { + Self::Ecdsa + } +} + + + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/signing_payload.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/signing_payload.rs new file mode 100644 index 0000000000..5ca7f63d7d --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/signing_payload.rs @@ -0,0 +1,41 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// SigningPayload : SigningPayload is signed by the client with the keypair associated with an AccountIdentifier using the specified SignatureType. SignatureType can be optionally populated if there is a restriction on the signature scheme that can be used to sign the payload. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct SigningPayload { + /// [DEPRECATED by `account_identifier` in `v1.4.4`] The network-specific address of the account that should sign the payload. + #[serde(rename = "address", skip_serializing_if = "Option::is_none")] + pub address: Option, + #[serde(rename = "account_identifier", skip_serializing_if = "Option::is_none")] + pub account_identifier: Option>, + /// Hex-encoded string of the payload bytes. + #[serde(rename = "hex_bytes")] + pub hex_bytes: String, + #[serde(rename = "signature_type", skip_serializing_if = "Option::is_none")] + pub signature_type: Option, +} + +impl SigningPayload { + /// SigningPayload is signed by the client with the keypair associated with an AccountIdentifier using the specified SignatureType. SignatureType can be optionally populated if there is a restriction on the signature scheme that can be used to sign the payload. + pub fn new(hex_bytes: String) -> SigningPayload { + SigningPayload { + address: None, + account_identifier: None, + hex_bytes, + signature_type: None, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/sub_account_identifier.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/sub_account_identifier.rs new file mode 100644 index 0000000000..b5c03b03ef --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/sub_account_identifier.rs @@ -0,0 +1,35 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// SubAccountIdentifier : An account may have state specific to a contract address (ERC-20 token) and/or a stake (delegated balance). The sub_account_identifier should specify which state (if applicable) an account instantiation refers to. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct SubAccountIdentifier { + /// The SubAccount address may be a cryptographic value or some other identifier (ex: bonded) that uniquely specifies a SubAccount. + #[serde(rename = "address")] + pub address: String, + /// If the SubAccount address is not sufficient to uniquely specify a SubAccount, any other identifying information can be stored here. It is important to note that two SubAccounts with identical addresses but differing metadata will not be considered equal by clients. + #[serde(rename = "metadata", skip_serializing_if = "Option::is_none")] + pub metadata: Option, +} + +impl SubAccountIdentifier { + /// An account may have state specific to a contract address (ERC-20 token) and/or a stake (delegated balance). The sub_account_identifier should specify which state (if applicable) an account instantiation refers to. + pub fn new(address: String) -> SubAccountIdentifier { + SubAccountIdentifier { + address, + metadata: None, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/sub_network_identifier.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/sub_network_identifier.rs new file mode 100644 index 0000000000..98239e4934 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/sub_network_identifier.rs @@ -0,0 +1,33 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// SubNetworkIdentifier : In blockchains with sharded state, the SubNetworkIdentifier is required to query some object on a specific shard. This identifier is optional for all non-sharded blockchains. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct SubNetworkIdentifier { + #[serde(rename = "network")] + pub network: String, + #[serde(rename = "metadata", skip_serializing_if = "Option::is_none")] + pub metadata: Option, +} + +impl SubNetworkIdentifier { + /// In blockchains with sharded state, the SubNetworkIdentifier is required to query some object on a specific shard. This identifier is optional for all non-sharded blockchains. + pub fn new(network: String) -> SubNetworkIdentifier { + SubNetworkIdentifier { + network, + metadata: None, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/sync_status.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/sync_status.rs new file mode 100644 index 0000000000..6939a2122d --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/sync_status.rs @@ -0,0 +1,43 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// SyncStatus : SyncStatus is used to provide additional context about an implementation's sync status. This object is often used by implementations to indicate healthiness when block data cannot be queried until some sync phase completes or cannot be determined by comparing the timestamp of the most recent block with the current time. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct SyncStatus { + /// CurrentIndex is the index of the last synced block in the current stage. This is a separate field from current_block_identifier in NetworkStatusResponse because blocks with indices up to and including the current_index may not yet be queryable by the caller. To reiterate, all indices up to and including current_block_identifier in NetworkStatusResponse must be queryable via the /block endpoint (excluding indices less than oldest_block_identifier). + #[serde(rename = "current_index", skip_serializing_if = "Option::is_none")] + pub current_index: Option, + /// TargetIndex is the index of the block that the implementation is attempting to sync to in the current stage. + #[serde(rename = "target_index", skip_serializing_if = "Option::is_none")] + pub target_index: Option, + /// Stage is the phase of the sync process. + #[serde(rename = "stage", skip_serializing_if = "Option::is_none")] + pub stage: Option, + /// synced is a boolean that indicates if an implementation has synced up to the most recent block. If this field is not populated, the caller should rely on a traditional tip timestamp comparison to determine if an implementation is synced. This field is particularly useful for quiescent blockchains (blocks only produced when there are pending transactions). In these blockchains, the most recent block could have a timestamp far behind the current time but the node could be healthy and at tip. + #[serde(rename = "synced", skip_serializing_if = "Option::is_none")] + pub synced: Option, +} + +impl SyncStatus { + /// SyncStatus is used to provide additional context about an implementation's sync status. This object is often used by implementations to indicate healthiness when block data cannot be queried until some sync phase completes or cannot be determined by comparing the timestamp of the most recent block with the current time. + pub fn new() -> SyncStatus { + SyncStatus { + current_index: None, + target_index: None, + stage: None, + synced: None, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/transaction.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/transaction.rs new file mode 100644 index 0000000000..d1e2938c63 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/transaction.rs @@ -0,0 +1,40 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// Transaction : Transactions contain an array of Operations that are attributable to the same TransactionIdentifier. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct Transaction { + #[serde(rename = "transaction_identifier")] + pub transaction_identifier: Box, + #[serde(rename = "operations")] + pub operations: Vec, + #[serde(rename = "related_transactions", skip_serializing_if = "Option::is_none")] + pub related_transactions: Option>, + /// Transactions that are related to other transactions (like a cross-shard transaction) should include the tranaction_identifier of these transactions in the metadata. + #[serde(rename = "metadata", skip_serializing_if = "Option::is_none")] + pub metadata: Option, +} + +impl Transaction { + /// Transactions contain an array of Operations that are attributable to the same TransactionIdentifier. + pub fn new(transaction_identifier: crate::mesh_api::generated::models::TransactionIdentifier, operations: Vec) -> Transaction { + Transaction { + transaction_identifier: Box::new(transaction_identifier), + operations, + related_transactions: None, + metadata: None, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/transaction_identifier.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/transaction_identifier.rs new file mode 100644 index 0000000000..0bba942cef --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/transaction_identifier.rs @@ -0,0 +1,31 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// TransactionIdentifier : The transaction_identifier uniquely identifies a transaction in a particular network and block or in the mempool. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct TransactionIdentifier { + /// Any transactions that are attributable only to a block (ex: a block event) should use the hash of the block as the identifier. This should be normalized according to the case specified in the transaction_hash_case in network options. + #[serde(rename = "hash")] + pub hash: String, +} + +impl TransactionIdentifier { + /// The transaction_identifier uniquely identifies a transaction in a particular network and block or in the mempool. + pub fn new(hash: String) -> TransactionIdentifier { + TransactionIdentifier { + hash, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/transaction_identifier_response.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/transaction_identifier_response.rs new file mode 100644 index 0000000000..362b55305d --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/transaction_identifier_response.rs @@ -0,0 +1,33 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// TransactionIdentifierResponse : TransactionIdentifierResponse contains the transaction_identifier of a transaction that was submitted to either `/construction/hash` or `/construction/submit`. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct TransactionIdentifierResponse { + #[serde(rename = "transaction_identifier")] + pub transaction_identifier: Box, + #[serde(rename = "metadata", skip_serializing_if = "Option::is_none")] + pub metadata: Option, +} + +impl TransactionIdentifierResponse { + /// TransactionIdentifierResponse contains the transaction_identifier of a transaction that was submitted to either `/construction/hash` or `/construction/submit`. + pub fn new(transaction_identifier: crate::mesh_api::generated::models::TransactionIdentifier) -> TransactionIdentifierResponse { + TransactionIdentifierResponse { + transaction_identifier: Box::new(transaction_identifier), + metadata: None, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/generated/models/version.rs b/core-rust/mesh-api-server/src/mesh_api/generated/models/version.rs new file mode 100644 index 0000000000..653bcb80dc --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/generated/models/version.rs @@ -0,0 +1,43 @@ +/* + * Rosetta + * + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * Generated by: https://openapi-generator.tech + */ + +/// Version : The Version object is utilized to inform the client of the versions of different components of the Rosetta implementation. + + + +#[derive(Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize)] +pub struct Version { + /// The rosetta_version is the version of the Rosetta interface the implementation adheres to. This can be useful for clients looking to reliably parse responses. + #[serde(rename = "rosetta_version")] + pub rosetta_version: String, + /// The node_version is the canonical version of the node runtime. This can help clients manage deployments. + #[serde(rename = "node_version")] + pub node_version: String, + /// When a middleware server is used to adhere to the Rosetta interface, it should return its version here. This can help clients manage deployments. + #[serde(rename = "middleware_version", skip_serializing_if = "Option::is_none")] + pub middleware_version: Option, + /// Any other information that may be useful about versioning of dependent services should be returned here. + #[serde(rename = "metadata", skip_serializing_if = "Option::is_none")] + pub metadata: Option, +} + +impl Version { + /// The Version object is utilized to inform the client of the versions of different components of the Rosetta implementation. + pub fn new(rosetta_version: String, node_version: String) -> Version { + Version { + rosetta_version, + node_version, + middleware_version: None, + metadata: None, + } + } +} + + diff --git a/core-rust/mesh-api-server/src/mesh_api/handlers/account_balance.rs b/core-rust/mesh-api-server/src/mesh_api/handlers/account_balance.rs new file mode 100644 index 0000000000..36753b0e3e --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/handlers/account_balance.rs @@ -0,0 +1,157 @@ +use crate::prelude::*; + +pub(crate) async fn handle_account_balance( + state: State, + Json(request): Json, +) -> Result, ResponseError> { + assert_matching_network(&request.network_identifier, &state.network)?; + + let mapping_context = MappingContext::new(&state.network); + let extraction_context = ExtractionContext::new(&state.network); + + let component_address = extract_radix_account_address_from_account_identifier( + &extraction_context, + &request.account_identifier, + ) + .map_err(|err| err.into_response_error("account_identifier"))?; + + let database = state.state_manager.database.snapshot(); + + let header = if request.block_identifier.is_some() { + return Err(ResponseError::from(ApiError::InvalidRequest) + .with_details("Historical balance not supported")); + } else { + read_current_ledger_header(database.deref()) + }; + + let balances = match request.currencies { + Some(currencies) => { + let resources = currencies + .into_iter() + .map(|c| { + extract_resource_address_from_currency( + &extraction_context, + database.deref(), + &c, + ) + }) + .collect::, ExtractionError>>() + .map_err(|err| err.into_response_error("currency"))?; + + get_requested_balances( + &mapping_context, + database.deref(), + &component_address, + &resources, + )? + } + None => { + // Check if account is instantiated + let type_info: Option = read_optional_substate::( + database.deref(), + component_address.as_node_id(), + TYPE_INFO_FIELD_PARTITION, + &TypeInfoField::TypeInfo.into(), + ); + + if type_info.is_some() { + get_all_balances(&mapping_context, database.deref(), &component_address)? + } else { + // We expect empty balances vector here, but let the `get_requested_balances()` + // deal with this. + get_requested_balances(&mapping_context, database.deref(), &component_address, &[])? + } + } + }; + + // see https://docs.cdp.coinbase.com/mesh/docs/models#accountbalanceresponse for field + // definitions + Ok(Json(models::AccountBalanceResponse { + block_identifier: Box::new(to_mesh_api_block_identifier_from_ledger_header( + database.deref(), + &header.into(), + )?), + balances, + metadata: None, + })) +} +// Method `dump_component_state()` might be slow on large accounts, +// therefore we use it only when user didn't specify which balances +// to get. +fn get_all_balances( + mapping_context: &MappingContext, + database: &StateManagerDatabase, + component_address: &ComponentAddress, +) -> Result, MappingError> { + let component_dump = dump_component_state(database, *component_address); + component_dump + .vaults + .into_iter() + .filter_map(|(_node_id, vault_data)| match vault_data { + VaultData::NonFungible { .. } => None, + VaultData::Fungible { + resource_address, + amount, + } => Some((resource_address, amount)), + }) + .fold(IndexMap::new(), |mut index, (resource_address, balance)| { + let sum = index.entry(resource_address).or_insert(Decimal::zero()); + *sum = sum.checked_add(balance).expect("Decimal overflow"); + + index + }) + .into_iter() + .map(|(resource_address, balance)| { + let currency = to_mesh_api_currency_from_resource_address( + &mapping_context, + database, + &resource_address, + )?; + Ok(to_mesh_api_amount(balance, currency)?) + }) + .collect::, MappingError>>() +} + +fn get_requested_balances( + mapping_context: &MappingContext, + database: &StateManagerDatabase, + component_address: &ComponentAddress, + resource_addresses: &[ResourceAddress], +) -> Result, ResponseError> { + resource_addresses.into_iter().map(|resource_address| { + let balance = { + let encoded_key = scrypto_encode(resource_address).expect("Impossible Case!"); + let substate = read_optional_collection_substate::( + database, + component_address.as_node_id(), + AccountCollection::ResourceVaultKeyValue.collection_index(), + &SubstateKey::Map(encoded_key), + ); + match substate { + Some(substate) => { + let vault = substate + .into_value() + .ok_or(MappingError::KeyValueStoreEntryUnexpectedlyAbsent)? + .fully_update_and_into_latest_version(); + read_mandatory_main_field_substate::( + database, + vault.0.as_node_id(), + &FungibleVaultField::Balance.into(), + )? + .into_payload() + .fully_update_and_into_latest_version() + .amount() + } + _ => Decimal::ZERO, + } + }; + + let currency = to_mesh_api_currency_from_resource_address( + &mapping_context, + database, + &resource_address, + )?; + Ok(to_mesh_api_amount(balance, currency)?) + }) + .collect::, ResponseError>>() +} diff --git a/core-rust/mesh-api-server/src/mesh_api/handlers/block.rs b/core-rust/mesh-api-server/src/mesh_api/handlers/block.rs new file mode 100644 index 0000000000..527e5175d3 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/handlers/block.rs @@ -0,0 +1,68 @@ +use crate::prelude::*; + +pub(crate) async fn handle_block( + state: State, + Json(request): Json, +) -> Result, ResponseError> { + assert_matching_network(&request.network_identifier, &state.network)?; + + let database = state.state_manager.database.snapshot(); + let mapping_context = MappingContext::new(&state.network); + + let state_version = extract_state_version_from_mesh_api_partial_block_identifier( + database.deref(), + &request.block_identifier, + ) + .map_err(|err| err.into_response_error("block_identifier"))? + .unwrap_or_else(|| database.max_state_version()); + + let previous_state_version = state_version.previous().map_err(|_| { + ResponseError::from(ApiError::ParentBlockNotAvailable).with_details(format!( + "Parent block not found for state version {}", + state_version.number() + )) + })?; + + let transaction_identifiers = database + .get_committed_transaction_identifiers(state_version) + .ok_or_else(|| { + ResponseError::from(ApiError::TransactionNotFound).with_details(format!( + "Failed fetching transaction identifiers for state version {}", + state_version.number() + )) + })?; + + let operations = to_mesh_api_operations(&mapping_context, database.deref(), state_version)?; + + let transaction_identifier = + to_mesh_api_transaction_identifier(&mapping_context, &transaction_identifiers)?; + + // see https://docs.cdp.coinbase.com/mesh/docs/models#transaction + let transaction = models::Transaction { + transaction_identifier: Box::new(transaction_identifier), + operations, + related_transactions: None, + metadata: None, + }; + + // see https://docs.cdp.coinbase.com/mesh/docs/models#block + let block = models::Block { + block_identifier: Box::new(to_mesh_api_block_identifier_from_state_version( + database.deref(), + state_version, + )?), + parent_block_identifier: Box::new(to_mesh_api_block_identifier_from_state_version( + database.deref(), + previous_state_version, + )?), + timestamp: transaction_identifiers.proposer_timestamp_ms, + transactions: vec![transaction], + metadata: None, + }; + + // see https://docs.cdp.coinbase.com/mesh/docs/models#blockresponse + Ok(Json(models::BlockResponse { + block: Some(Box::new(block)), + other_transactions: None, + })) +} diff --git a/core-rust/mesh-api-server/src/mesh_api/handlers/block_transaction.rs b/core-rust/mesh-api-server/src/mesh_api/handlers/block_transaction.rs new file mode 100644 index 0000000000..77aa3cf8c2 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/handlers/block_transaction.rs @@ -0,0 +1,56 @@ +use crate::prelude::*; + +pub(crate) async fn handle_block_transaction( + state: State, + Json(request): Json, +) -> Result, ResponseError> { + assert_matching_network(&request.network_identifier, &state.network)?; + + let database = state.state_manager.database.snapshot(); + let mapping_context = MappingContext::new(&state.network); + + let state_version = extract_state_version_from_mesh_api_block_identifier( + database.deref(), + &request.block_identifier, + ) + .map_err(|err| err.into_response_error("block_identifier"))?; + + let transaction_identifiers = database + .get_committed_transaction_identifiers(state_version) + .ok_or_else(|| { + ResponseError::from(ApiError::TransactionNotFound).with_details(format!( + "Failed fetching transaction identifiers for state version {}", + state_version.number() + )) + })?; + + let transaction_identifier = + to_mesh_api_transaction_identifier(&mapping_context, &transaction_identifiers)?; + if !request + .transaction_identifier + .as_ref() + .eq(&transaction_identifier) + { + return Err( + ResponseError::from(ApiError::TransactionNotFound).with_details(format!( + "transaction_identifier {} not available in given block", + request.transaction_identifier.hash + )), + ); + } + + let operations = to_mesh_api_operations(&mapping_context, database.deref(), state_version)?; + + // see https://docs.cdp.coinbase.com/mesh/docs/models#transaction + let transaction = models::Transaction { + transaction_identifier: Box::new(transaction_identifier), + operations, + related_transactions: None, + metadata: None, + }; + + // see https://docs.cdp.coinbase.com/mesh/docs/models#blocktransactionresponse + Ok(Json(models::BlockTransactionResponse { + transaction: Box::new(transaction), + })) +} diff --git a/core-rust/mesh-api-server/src/mesh_api/handlers/construction_combine.rs b/core-rust/mesh-api-server/src/mesh_api/handlers/construction_combine.rs new file mode 100644 index 0000000000..9968970afe --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/handlers/construction_combine.rs @@ -0,0 +1,45 @@ +use crate::prelude::*; + +pub(crate) async fn handle_construction_combine( + state: State, + Json(request): Json, +) -> Result, ResponseError> { + assert_matching_network(&request.network_identifier, &state.network)?; + + let signature = if request.signatures.len() == 1 { + extract_signature(&request.signatures[0]) + .map_err(|e| e.into_response_error("signatures"))? + } else { + return Err( + ResponseError::from(ApiError::InvalidNumberOfSignatures).with_details(format!( + "Expected 1 signature, but received {}", + request.signatures.len() + )), + ); + }; + + let intent = RawTransactionIntent::from_hex(&request.unsigned_transaction) + .ok() + .and_then(|x| IntentV1::from_raw(&x).ok()) + .ok_or( + ResponseError::from(ApiError::InvalidTransaction).with_details(format!( + "Invalid unsigned transaction: {}", + &request.unsigned_transaction + )), + )?; + let tx = NotarizedTransactionV1 { + signed_intent: SignedIntentV1 { + intent, + intent_signatures: IntentSignaturesV1 { + signatures: Vec::new(), + }, + }, + notary_signature: NotarySignatureV1(signature), + }; + + // See https://docs.cdp.coinbase.com/mesh/docs/models#constructioncombineresponse for field + // definitions + Ok(Json(models::ConstructionCombineResponse { + signed_transaction: hex::encode(tx.to_raw().unwrap()), + })) +} diff --git a/core-rust/mesh-api-server/src/mesh_api/handlers/construction_derive.rs b/core-rust/mesh-api-server/src/mesh_api/handlers/construction_derive.rs new file mode 100644 index 0000000000..8a2870797e --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/handlers/construction_derive.rs @@ -0,0 +1,23 @@ +use crate::prelude::*; + +pub(crate) async fn handle_construction_derive( + state: State, + Json(request): Json, +) -> Result, ResponseError> { + assert_matching_network(&request.network_identifier, &state.network)?; + + let public_key = + extract_public_key(&request.public_key).map_err(|e| e.into_response_error("public_key"))?; + let account_identifier = to_api_account_identifier_from_public_key( + &MappingContext::new(&state.network), + public_key, + )?; + + // See https://docs.cdp.coinbase.com/mesh/docs/models#constructionderiveresponse for field + // definitions + Ok(Json(models::ConstructionDeriveResponse { + address: None, // deprecated + account_identifier: Some(Box::new(account_identifier)), + metadata: None, + })) +} diff --git a/core-rust/mesh-api-server/src/mesh_api/handlers/construction_hash.rs b/core-rust/mesh-api-server/src/mesh_api/handlers/construction_hash.rs new file mode 100644 index 0000000000..894470e1e1 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/handlers/construction_hash.rs @@ -0,0 +1,31 @@ +use crate::prelude::*; + +pub(crate) async fn handle_construction_hash( + state: State, + Json(request): Json, +) -> Result, ResponseError> { + assert_matching_network(&request.network_identifier, &state.network)?; + + let intent_hash = RawNotarizedTransaction::from_hex(&request.signed_transaction) + .ok() + .and_then(|raw| raw.prepare(PreparationSettings::latest_ref()).ok()) + .and_then(|tx| Some(tx.hashes())) + .ok_or( + ResponseError::from(ApiError::InvalidTransaction).with_details(format!( + "Invalid transaction: {}", + request.signed_transaction + )), + )? + .transaction_intent_hash; + + let transaction_identifier = to_mesh_api_transaction_identifier_from_hash( + to_api_transaction_hash_bech32m(&MappingContext::new(&state.network), &intent_hash)?, + ); + + // See https://docs.cdp.coinbase.com/mesh/docs/models#constructionhashresponse for field + // definitions + Ok(Json(models::TransactionIdentifierResponse { + transaction_identifier: Box::new(transaction_identifier), + metadata: None, + })) +} diff --git a/core-rust/mesh-api-server/src/mesh_api/handlers/construction_metadata.rs b/core-rust/mesh-api-server/src/mesh_api/handlers/construction_metadata.rs new file mode 100644 index 0000000000..2aa39c6166 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/handlers/construction_metadata.rs @@ -0,0 +1,40 @@ +use rand::Rng; +use serde::{Deserialize, Serialize}; + +use crate::prelude::*; + +pub(crate) async fn handle_construction_metadata( + state: State, + Json(request): Json, +) -> Result, ResponseError> { + assert_matching_network(&request.network_identifier, &state.network)?; + + let database = state.state_manager.database.snapshot(); + let current_epoch = database + .get_latest_epoch_proof() + .unwrap() + .ledger_header + .epoch; + let nonce = rand::thread_rng().gen(); + + // See https://docs.cdp.coinbase.com/mesh/docs/models#constructionmetadataresponse for field + // definitions + Ok(Json(models::ConstructionMetadataResponse { + metadata: serde_json::to_value(&ConstructionMetadata { + start_epoch_inclusive: current_epoch.number(), + end_epoch_exclusive: current_epoch.number() + 100, + intent_discriminator: nonce, + tip_percentage: 0, + }) + .unwrap(), + suggested_fee: None, + })) +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct ConstructionMetadata { + pub start_epoch_inclusive: u64, + pub end_epoch_exclusive: u64, + pub intent_discriminator: u32, + pub tip_percentage: u16, +} diff --git a/core-rust/mesh-api-server/src/mesh_api/handlers/construction_parse.rs b/core-rust/mesh-api-server/src/mesh_api/handlers/construction_parse.rs new file mode 100644 index 0000000000..2d5ca80774 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/handlers/construction_parse.rs @@ -0,0 +1,167 @@ +use crate::prelude::*; +use radix_engine_interface::blueprints::account::{ + AccountTryDepositOrAbortManifestInput, AccountWithdrawManifestInput, +}; +use radix_transactions::manifest::{CallMethod, TakeFromWorktop}; +use radix_transactions::validation::TransactionValidator; + +// This method only accepts transactions constructed with the Mesh API, +// which are V1 at the moment. +// Also the number of supported V1 instructions is limited to some basic ones. +// (see `construction_payloads.rs` and parse_instructions() below for more details). +pub(crate) async fn handle_construction_parse( + state: State, + Json(request): Json, +) -> Result, ResponseError> { + assert_matching_network(&request.network_identifier, &state.network)?; + + let transaction_bytes = hex::decode(&request.transaction).map_err(|_| { + ResponseError::from(ApiError::InvalidTransaction) + .with_details(format!("Invalid transaction hex: {}", &request.transaction)) + })?; + + let (instructions, signers) = if request.signed { + let transaction = + NotarizedTransactionV1::from_raw(&RawNotarizedTransaction::from_vec(transaction_bytes)) + .map_err(|_| { + ResponseError::from(ApiError::InvalidTransaction) + .with_details(format!("Invalid transaction: {}", &request.transaction)) + })?; + let validated = transaction + .prepare_and_validate(&TransactionValidator::new_with_latest_config( + &state.network, + )) + .map_err(|e| { + ResponseError::from(ApiError::InvalidTransaction) + .with_details(format!("Invalid transaction: error = {:?}", e)) + })?; + + let instructions = transaction.signed_intent.intent.instructions.0; + let signers = validated.signer_keys; + (instructions, signers) + } else { + let prepared_intent = PreparedIntentV1::prepare( + &RawTransactionIntent::from_vec(transaction_bytes), + &PreparationSettings::latest(), + ) + .unwrap(); + #[allow(deprecated)] + let instructions = prepared_intent.instructions.inner.0; + let signers = index_set_new(); + (instructions, signers) + }; + + let mapping_context = MappingContext::new(&state.network); + let database = state.state_manager.database.snapshot(); + let operations = parse_instructions(&instructions, &mapping_context, database.deref())?; + + // See https://docs.cdp.coinbase.com/mesh/docs/models#constructionparseresponse for field + // definitions + Ok(Json(models::ConstructionParseResponse { + operations, + signers: None, + account_identifier_signers: Some( + signers + .into_iter() + .map(|x| -> Result { + to_api_account_identifier_from_public_key(&mapping_context, x) + }) + .collect::, MappingError>>()?, + ), + metadata: None, + })) +} + +pub fn parse_instructions( + instructions: &[InstructionV1], + mapping_context: &MappingContext, + database: &StateManagerDatabase, +) -> Result, ResponseError> { + let mut operations = Vec::new(); + let mut next_index = 0; + while next_index < instructions.len() { + let mut instruction = &instructions[next_index]; + next_index = next_index + 1; + match instruction { + InstructionV1::CallMethod(CallMethod { + address: DynamicGlobalAddress::Static(global_address), + method_name, + args, + }) if global_address.is_account() => { + let args_bytes = manifest_encode(&args).unwrap(); + match method_name.as_str() { + "lock_fee" => (), + "withdraw" => { + let input = manifest_decode::(&args_bytes) + .map_err(|_| { + ResponseError::from(ApiError::InvalidWithdrawInstruction) + .with_details("Invalid withdraw instruction") + })?; + operations.push(to_mesh_api_operation_no_fee( + mapping_context, + database, + operations.len() as i64, + None, + global_address, + &match input.resource_address { + ManifestResourceAddress::Static(resource_address) => { + resource_address + } + ManifestResourceAddress::Named(_) => { + return Err(ResponseError::from( + ApiError::NamedAddressNotSupported, + ) + .with_details("Named address is not supported")) + } + }, + -input.amount.clone(), + )?); + } + _ => { + return Err(ResponseError::from(ApiError::UnrecognizedInstruction) + .with_details(format!("Unrecognized instruction: {:?}", instruction))); + } + } + } + InstructionV1::TakeFromWorktop(TakeFromWorktop { + resource_address, + amount, + }) if next_index < instructions.len() => { + instruction = &instructions[next_index]; + next_index = next_index + 1; + + match instruction { + InstructionV1::CallMethod(CallMethod { + address: DynamicGlobalAddress::Static(global_address), + method_name, + args, + }) if method_name.eq("try_deposit_or_abort") && global_address.is_account() => { + if let Ok(_input) = manifest_decode::( + &manifest_encode(&args).unwrap(), + ) { + operations.push(to_mesh_api_operation_no_fee( + mapping_context, + database, + operations.len() as i64, + None, + global_address, + resource_address, + *amount, + )?); + } + } + _ => { + return Err(ResponseError::from(ApiError::UnrecognizedInstruction) + .with_details(format!("Unrecognized instruction: {:?}", instruction))); + } + } + } + _ => { + return Err(ResponseError::from(ApiError::UnrecognizedInstruction) + .with_details(format!("Unrecognized instruction: {:?}", instruction))); + } + } + } + + Ok(operations) +} diff --git a/core-rust/mesh-api-server/src/mesh_api/handlers/construction_payloads.rs b/core-rust/mesh-api-server/src/mesh_api/handlers/construction_payloads.rs new file mode 100644 index 0000000000..ef9d23253b --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/handlers/construction_payloads.rs @@ -0,0 +1,126 @@ +use super::ConstructionMetadata; +use crate::prelude::*; +use models::{SignatureType, SigningPayload}; +use radix_transactions::prelude::ManifestBuilder; + +pub(crate) async fn handle_construction_payloads( + state: State, + Json(request): Json, +) -> Result, ResponseError> { + assert_matching_network(&request.network_identifier, &state.network)?; + + let public_keys = request.public_keys.unwrap_or_default(); + let signer_public_key = if public_keys.len() == 1 { + extract_public_key(&public_keys[0]).map_err(|e| e.into_response_error("public_key"))? + } else { + return Err( + ResponseError::from(ApiError::InvalidNumberOfPublicKeys).with_details(format!( + "Expected 1 public key, but received {}", + public_keys.len() + )), + ); + }; + let signature_type = match &signer_public_key { + PublicKey::Secp256k1(_) => SignatureType::EcdsaRecovery, + PublicKey::Ed25519(_) => SignatureType::Ed25519, + }; + let signer_account_address = + ComponentAddress::preallocated_account_from_public_key(&signer_public_key); + let signer_account_identifier = to_api_account_identifier_from_public_key( + &MappingContext::new(&state.network), + signer_public_key, + )?; + + let metadata: ConstructionMetadata = request + .metadata + .clone() + .and_then(|m| serde_json::from_value(m).ok()) + .ok_or( + ResponseError::from(ApiError::InvalidMetadata) + .with_details(format!("Invalid metadata: {:?}", request.metadata)), + )?; + + let extraction_context = ExtractionContext::new(&state.network); + let mut builder = ManifestBuilder::new().lock_fee(signer_account_address, dec!(10)); + for operation in request.operations { + let operation_type = + MeshApiOperationType::from_str(operation._type.as_str()).map_err(|_| { + ResponseError::from(ApiError::InvalidOperation) + .with_details(format!("Invalid operation: {}", operation._type)) + })?; + match operation_type { + MeshApiOperationType::Withdraw => { + let account = match operation.account { + None => Err(ExtractionError::NotFound), + Some(account) => extract_radix_account_address_from_account_identifier( + &extraction_context, + &account, + ), + } + .map_err(|e| e.into_response_error("account"))?; + + let (address, quantity) = + extract_amount_from_option(&extraction_context, operation.amount) + .map_err(|e| e.into_response_error("amount"))?; + builder = builder.withdraw_from_account(account, address, -quantity); + } + MeshApiOperationType::Deposit => { + let account = match operation.account { + None => Err(ExtractionError::NotFound), + Some(account) => extract_radix_account_address_from_account_identifier( + &extraction_context, + &account, + ), + } + .map_err(|e| e.into_response_error("account"))?; + let (address, quantity) = + extract_amount_from_option(&extraction_context, operation.amount) + .map_err(|e| e.into_response_error("amount"))?; + let bucket = builder.generate_bucket_name("bucket"); + builder = builder.take_from_worktop(address, quantity, &bucket); + builder = builder.try_deposit_or_abort(account, None, bucket); + } + } + } + let manifest = builder.build(); + let signed_intent = SignedIntentV1 { + intent: IntentV1 { + header: TransactionHeaderV1 { + network_id: state.network.id, + start_epoch_inclusive: Epoch::of(metadata.start_epoch_inclusive), + end_epoch_exclusive: Epoch::of(metadata.end_epoch_exclusive), + nonce: metadata.intent_discriminator, + notary_public_key: signer_public_key, + notary_is_signatory: true, + tip_percentage: metadata.tip_percentage, + }, + instructions: InstructionsV1(manifest.instructions), + blobs: BlobsV1 { + blobs: Default::default(), + }, + message: MessageV1::None, + }, + intent_signatures: IntentSignaturesV1 { + signatures: Default::default(), + }, + }; + let signed_intent_bytes = signed_intent.to_raw().unwrap(); + + let signed_transaction_intent_hash = + PreparedSignedIntentV1::prepare(&signed_intent_bytes, &PreparationSettings::latest()) + .expect("Signed intent could be prepared") + .signed_transaction_intent_hash(); + let intent_bytes = signed_intent.intent.to_raw().unwrap(); + + // See https://docs.cdp.coinbase.com/mesh/docs/models#constructionpayloadsresponse for field + // definitions + Ok(Json(models::ConstructionPayloadsResponse { + unsigned_transaction: intent_bytes.to_hex(), + payloads: vec![SigningPayload { + address: None, // deprecated + account_identifier: Some(Box::new(signer_account_identifier)), + hex_bytes: hex::encode(signed_transaction_intent_hash.as_bytes()), + signature_type: Some(signature_type), + }], + })) +} diff --git a/core-rust/mesh-api-server/src/mesh_api/handlers/construction_preprocess.rs b/core-rust/mesh-api-server/src/mesh_api/handlers/construction_preprocess.rs new file mode 100644 index 0000000000..a9c5ef3d5e --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/handlers/construction_preprocess.rs @@ -0,0 +1,54 @@ +use crate::prelude::*; + +pub(crate) async fn handle_construction_preprocess( + state: State, + Json(request): Json, +) -> Result, ResponseError> { + assert_matching_network(&request.network_identifier, &state.network)?; + + // We assume that the withdrawing account (sender) will + // - cover the transaction fee + // - sign the transaction + // Add it to the required_public_keys vector. + let mut senders = Vec::new(); + for operation in request.operations { + let operation_type = + MeshApiOperationType::from_str(operation._type.as_str()).map_err(|_| { + ResponseError::from(ApiError::InvalidOperation) + .with_details(format!("Invalid operation: {}", operation._type)) + })?; + match operation_type { + MeshApiOperationType::Withdraw => { + let account = match operation.account { + None => Err(ExtractionError::NotFound), + Some(account) => extract_radix_account_address_from_account_identifier( + &ExtractionContext::new(&state.network), + &account, + ), + } + .map_err(|e| e.into_response_error("account"))?; + senders.push(account); + } + MeshApiOperationType::Deposit => {} + } + } + + if senders.len() != 1 { + return Err( + ResponseError::from(ApiError::InvalidNumberOfSenders).with_details(format!( + "Expected exactly 1 sender (Withdraw operation), but found {}", + senders.len() + )), + ); + } + + // See https://docs.cdp.coinbase.com/mesh/docs/models#constructionpreprocessresponse for field + // definitions + Ok(Json(models::ConstructionPreprocessResponse { + options: None, + required_public_keys: Some(vec![to_api_account_identifier_from_global_address( + &MappingContext::new(&state.network), + senders[0], + )?]), + })) +} diff --git a/core-rust/mesh-api-server/src/mesh_api/handlers/construction_submit.rs b/core-rust/mesh-api-server/src/mesh_api/handlers/construction_submit.rs new file mode 100644 index 0000000000..d751b3d9ad --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/handlers/construction_submit.rs @@ -0,0 +1,63 @@ +use crate::prelude::*; + +pub(crate) async fn handle_construction_submit( + state: State, + Json(request): Json, +) -> Result, ResponseError> { + assert_matching_network(&request.network_identifier, &state.network)?; + + let (raw, intent_hash) = RawNotarizedTransaction::from_hex(&request.signed_transaction) + .ok() + .and_then(|raw| { + let tx = raw.prepare(PreparationSettings::latest_ref()); + tx.map(|tx| (raw, tx)).ok() + }) + .and_then(|(raw, tx)| Some((raw, tx.hashes().transaction_intent_hash))) + .ok_or( + ResponseError::from(ApiError::InvalidTransaction).with_details(format!( + "Invalid transaction: {}", + request.signed_transaction + )), + )?; + + let mempool_add_result = match state.state_manager.mempool_manager.add_and_trigger_relay( + MempoolAddSource::MeshApi, + raw, + false, + ) { + Ok(_) => Ok(()), + Err(e) => match e { + e @ MempoolAddError::PriorityThresholdNotMet { .. } => Err(format!("{:?}", e)), + MempoolAddError::Duplicate(_) => Ok(()), + MempoolAddError::Rejected(rejection, _) => match rejection.reason { + MempoolRejectionReason::SubintentAlreadyFinalized(_) + | MempoolRejectionReason::TransactionIntentAlreadyCommitted(_) => Ok(()), + MempoolRejectionReason::FromExecution(rejection_reason) => { + Err(format!("Execution failure: {:?}", rejection_reason)) + } + MempoolRejectionReason::ValidationError(validation_error) => { + Err(format!("Validation failure: {:?}", validation_error)) + } + }, + }, + }; + + if let Err(message) = mempool_add_result { + return Err(ResponseError::from(ApiError::SubmitTransactionError) + .with_details(format!( + "Failed to submit transaction to mempool: {}", + message + )) + .retryable(true)); + }; + let transaction_identifier = to_mesh_api_transaction_identifier_from_hash( + to_api_transaction_hash_bech32m(&MappingContext::new(&state.network), &intent_hash)?, + ); + + // See https://docs.cdp.coinbase.com/mesh/docs/models#constructionsubmitresponse for field + // definitions + Ok(Json(models::TransactionIdentifierResponse { + transaction_identifier: Box::new(transaction_identifier), + metadata: None, + })) +} diff --git a/core-rust/mesh-api-server/src/mesh_api/handlers/mempool.rs b/core-rust/mesh-api-server/src/mesh_api/handlers/mempool.rs new file mode 100644 index 0000000000..1bc8f70a4a --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/handlers/mempool.rs @@ -0,0 +1,25 @@ +use crate::prelude::*; + +pub(crate) async fn handle_mempool( + state: State, + Json(request): Json, +) -> Result, ResponseError> { + assert_matching_network(&request.network_identifier, &state.network)?; + + let mapping_context = MappingContext::new(&state.network); + let mempool = &state.state_manager.mempool_manager; + + let transaction_identifiers = mempool + .get_mempool_all_hashes() + .into_iter() + .map(|(intent_hash, _)| { + Ok(models::TransactionIdentifier { + hash: to_api_transaction_hash_bech32m(&mapping_context, &intent_hash)?, + }) + }) + .collect::, MappingError>>()?; + + Ok(Json(models::MempoolResponse { + transaction_identifiers, + })) +} diff --git a/core-rust/mesh-api-server/src/mesh_api/handlers/mempool_transaction.rs b/core-rust/mesh-api-server/src/mesh_api/handlers/mempool_transaction.rs new file mode 100644 index 0000000000..d75bfa32b5 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/handlers/mempool_transaction.rs @@ -0,0 +1,51 @@ +use crate::prelude::*; + +pub(crate) async fn handle_mempool_transaction( + state: State, + Json(request): Json, +) -> Result, ResponseError> { + assert_matching_network(&request.network_identifier, &state.network)?; + + let extraction_context = ExtractionContext::new(&state.network); + let mapping_context = MappingContext::new(&state.network); + let mempool = &state.state_manager.mempool_manager; + + // Only user transactions might be present in mempool. + // So it is safe to assume that transaction_identifier includes + // `transaction intent_hash` and not `ledger_transaction_hash` + let intent_hash = extract_transaction_intent_hash( + &extraction_context, + request.transaction_identifier.hash.clone(), + ) + .map_err(|err| err.into_response_error("intent_hash"))?; + + if mempool + .get_mempool_payload_hashes_for_intent(&intent_hash) + .is_empty() + { + return Err( + ResponseError::from(ApiError::TransactionNotFound).with_details(format!( + "transaction {} not found in mempool transactions", + &request.transaction_identifier.hash + )), + ); + } + + let transaction_identifier = Box::new(models::TransactionIdentifier { + hash: to_api_transaction_hash_bech32m(&mapping_context, &intent_hash)?, + }); + + // TODO:MESH prepare transaction estimates + let transaction = Box::new(models::Transaction { + transaction_identifier, + // TODO:MESH Use the same approach as in `construction_parse`? + operations: vec![], + related_transactions: None, + metadata: None, + }); + + Ok(Json(models::MempoolTransactionResponse { + transaction, + metadata: None, + })) +} diff --git a/core-rust/mesh-api-server/src/mesh_api/handlers/mod.rs b/core-rust/mesh-api-server/src/mesh_api/handlers/mod.rs new file mode 100644 index 0000000000..08a2a8ff9e --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/handlers/mod.rs @@ -0,0 +1,33 @@ +mod account_balance; +mod block; +mod block_transaction; +mod construction_combine; +mod construction_derive; +mod construction_hash; +mod construction_metadata; +mod construction_parse; +mod construction_payloads; +mod construction_preprocess; +mod construction_submit; +mod mempool; +mod mempool_transaction; +mod network_list; +mod network_options; +mod network_status; + +pub(crate) use account_balance::*; +pub(crate) use block::*; +pub(crate) use block_transaction::*; +pub(crate) use construction_combine::*; +pub(crate) use construction_derive::*; +pub(crate) use construction_hash::*; +pub(crate) use construction_metadata::*; +pub(crate) use construction_parse::*; +pub(crate) use construction_payloads::*; +pub(crate) use construction_preprocess::*; +pub(crate) use construction_submit::*; +pub(crate) use mempool::*; +pub(crate) use mempool_transaction::*; +pub(crate) use network_list::*; +pub(crate) use network_options::*; +pub(crate) use network_status::*; diff --git a/core-rust/mesh-api-server/src/mesh_api/handlers/network_list.rs b/core-rust/mesh-api-server/src/mesh_api/handlers/network_list.rs new file mode 100644 index 0000000000..8db6a1e1e2 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/handlers/network_list.rs @@ -0,0 +1,15 @@ +use crate::prelude::*; + +pub(crate) async fn handle_network_list( + state: State, + Json(_request): Json, +) -> Result, ResponseError> { + // See https://docs.cdp.coinbase.com/mesh/docs/models#networklistresponse for field definitions + Ok(Json(models::NetworkListResponse { + network_identifiers: vec![models::NetworkIdentifier { + blockchain: "radix".to_string(), + network: state.network.logical_name.to_string(), + sub_network_identifier: None, + }], + })) +} diff --git a/core-rust/mesh-api-server/src/mesh_api/handlers/network_options.rs b/core-rust/mesh-api-server/src/mesh_api/handlers/network_options.rs new file mode 100644 index 0000000000..cc295db359 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/handlers/network_options.rs @@ -0,0 +1,48 @@ +use crate::{mesh_api::generated::SCHEMA_VERSION, prelude::*}; + +pub(crate) async fn handle_network_options( + state: State, + Json(request): Json, +) -> Result, ResponseError> { + assert_matching_network(&request.network_identifier, &state.network)?; + + let database = state.state_manager.database.snapshot(); + + let mut proof_iter = database.get_proof_iter(StateVersion::pre_genesis()); + + // See https://docs.cdp.coinbase.com/mesh/docs/models#networkoptionsresponse for field + // definitions + Ok(Json(models::NetworkOptionsResponse { + version: Box::new(models::Version { + rosetta_version: SCHEMA_VERSION.to_string(), + node_version: state.node_display_version.clone(), + middleware_version: None, + metadata: None, + }), + allow: Box::new(models::Allow { + operation_statuses: MeshApiOperationStatus::iter().map(|s| s.into()).collect(), + operation_types: MeshApiOperationType::iter() + .map(|o| o.to_string()) + .collect(), + errors: list_available_api_errors(), + historical_balance_lookup: false, + timestamp_start_index: proof_iter.find_map(|p| { + // Observed that some timestamp are 0 or 1 + if p.ledger_header.proposer_timestamp_ms > 1 { + Some( + to_mesh_api_block_index_from_state_version(p.ledger_header.state_version) + .unwrap(), + ) + } else { + None + } + }), + // This is for native RPC calls. Not needed for now. + call_methods: vec![], + balance_exemptions: vec![], + mempool_coins: false, + block_hash_case: Some(models::Case::LowerCase), + transaction_hash_case: Some(models::Case::LowerCase), + }), + })) +} diff --git a/core-rust/mesh-api-server/src/mesh_api/handlers/network_status.rs b/core-rust/mesh-api-server/src/mesh_api/handlers/network_status.rs new file mode 100644 index 0000000000..0485fa73f4 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/handlers/network_status.rs @@ -0,0 +1,62 @@ +use crate::prelude::*; + +pub(crate) async fn handle_network_status( + state: State, + Json(request): Json, +) -> Result, ResponseError> { + assert_matching_network(&request.network_identifier, &state.network)?; + + let database = state.state_manager.database.snapshot(); + + let timestamp_substate = + read_mandatory_main_field_substate::( + database.deref(), + CONSENSUS_MANAGER.as_node_id(), + &ConsensusManagerField::ProposerMilliTimestamp.into(), + )? + .into_payload() + .fully_update_and_into_latest_version(); + + let genesis_block_identifier = database + .get_post_genesis_epoch_proof() + .map(|proof| -> Result<_, MappingError> { + Ok(Box::new(to_mesh_api_block_identifier_from_ledger_header( + database.deref(), + &proof.ledger_header.into(), + )?)) + }) + .unwrap_or_else(|| Err(MappingError::ProofNotFound))?; + + let oldest_block_identifier = database + .get_first_proof() + .map(|proof| -> Result<_, MappingError> { + Ok(Box::new(to_mesh_api_block_identifier_from_ledger_header( + database.deref(), + &proof.ledger_header.into(), + )?)) + }) + .unwrap_or_else(|| Err(MappingError::ProofNotFound))?; + + // See https://docs.cdp.coinbase.com/mesh/docs/models#networkstatusresponse for field + // definitions + Ok(Json(models::NetworkStatusResponse { + current_block_identifier: database + .get_latest_proof() + .map(|proof| -> Result<_, MappingError> { + Ok(Box::new(to_mesh_api_block_identifier_from_ledger_header( + database.deref(), + &proof.ledger_header.into(), + )?)) + }) + .unwrap_or_else(|| Err(MappingError::ProofNotFound))?, + + current_block_timestamp: timestamp_substate.epoch_milli, + oldest_block_identifier: Some(oldest_block_identifier), + genesis_block_identifier, + // sync_status not required. + // Comparing the timestamp of the most recent blocks with current time is fine. + sync_status: None, + // This info is in the Java System API. Hard to get it. Setting empty vector for now. + peers: Some(vec![]), + })) +} diff --git a/core-rust/mesh-api-server/src/mesh_api/helpers.rs b/core-rust/mesh-api-server/src/mesh_api/helpers.rs new file mode 100644 index 0000000000..ed1023532b --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/helpers.rs @@ -0,0 +1,89 @@ +use crate::engine_prelude::*; +use crate::prelude::*; + +#[tracing::instrument(skip_all)] +pub(crate) fn read_current_ledger_header( + database: &StateManagerDatabase, +) -> LedgerHeader { + database + .get_latest_proof() + .expect("proof for outputted state must exist") + .ledger_header +} + +#[tracing::instrument(skip_all)] +pub(crate) fn read_mandatory_main_field_substate( + database: &StateManagerDatabase, + node_id: &NodeId, + substate_key: &SubstateKey, +) -> Result, ResponseError> { + read_mandatory_substate::>( + database, + node_id, + MAIN_BASE_PARTITION, + substate_key, + ) +} + +#[tracing::instrument(skip_all)] +pub(crate) fn read_mandatory_substate( + database: &StateManagerDatabase, + node_id: &NodeId, + partition_number: PartitionNumber, + substate_key: &SubstateKey, +) -> Result { + read_optional_substate( + database, + node_id, + partition_number, + substate_key + ).ok_or_else( + || { + MappingError::MismatchedSubstateId { + message: format!( + "Substate key {substate_key:?} not found under NodeId {node_id:?} and partition number {partition_number:?}" + ), + } + .into() + }, + ) +} +#[tracing::instrument(skip_all)] +pub(crate) fn read_optional_main_field_substate( + database: &StateManagerDatabase, + node_id: &NodeId, + substate_key: &SubstateKey, +) -> Option> { + read_optional_substate::>(database, node_id, MAIN_BASE_PARTITION, substate_key) +} + +#[tracing::instrument(skip_all)] +pub(crate) fn read_optional_collection_substate( + database: &StateManagerDatabase, + node_id: &NodeId, + collection_index: CollectionIndex, + substate_key: &SubstateKey, +) -> Option> { + // Note - the field partition (if it exists) takes the first partition number, + // the collections go after - so start at offset 1 + // (assuming there is a tuple partition on the node...) + let partition_number = MAIN_BASE_PARTITION + .at_offset(PartitionOffset(1 + collection_index)) + .unwrap(); + read_optional_substate::>( + database, + node_id, + partition_number, + substate_key, + ) +} + +#[tracing::instrument(skip_all)] +pub(crate) fn read_optional_substate( + database: &StateManagerDatabase, + node_id: &NodeId, + partition_number: PartitionNumber, + substate_key: &SubstateKey, +) -> Option { + database.get_substate::(node_id, partition_number, substate_key) +} diff --git a/core-rust/mesh-api-server/src/mesh_api/metrics.rs b/core-rust/mesh-api-server/src/mesh_api/metrics.rs new file mode 100644 index 0000000000..d5c359e268 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/metrics.rs @@ -0,0 +1,105 @@ +/* Copyright 2021 Radix Publishing Ltd incorporated in Jersey (Channel Islands). + * + * Licensed under the Radix License, Version 1.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at: + * + * radixfoundation.org/licenses/LICENSE-v1 + * + * The Licensor hereby grants permission for the Canonical version of the Work to be + * published, distributed and used under or by reference to the Licensor’s trademark + * Radix ® and use of any unregistered trade names, logos or get-up. + * + * The Licensor provides the Work (and each Contributor provides its Contributions) on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, + * including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, + * MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. + * + * Whilst the Work is capable of being deployed, used and adopted (instantiated) to create + * a distributed ledger it is your responsibility to test and validate the code, together + * with all logic and performance of that code under all foreseeable scenarios. + * + * The Licensor does not make or purport to make and hereby excludes liability for all + * and any representation, warranty or undertaking in any form whatsoever, whether express + * or implied, to any entity or person, including any representation, warranty or + * undertaking, as to the functionality security use, value or other characteristics of + * any distributed ledger nor in respect the functioning or value of any tokens which may + * be created stored or transferred using the Work. The Licensor does not warrant that the + * Work or any use of the Work complies with any law or regulation in any territory where + * it may be implemented or used or that it will be appropriate for any specific purpose. + * + * Neither the licensor nor any current or former employees, officers, directors, partners, + * trustees, representatives, agents, advisors, contractors, or volunteers of the Licensor + * shall be liable for any direct or indirect, special, incidental, consequential or other + * losses of any kind, in tort, contract or otherwise (including but not limited to loss + * of revenue, income or profits, or loss of use or data, or loss of reputation, or loss + * of any economic or other opportunity of whatsoever nature or howsoever arising), arising + * out of or in connection with (without limitation of any use, misuse, of any ledger system + * or use made or its functionality or any performance or operation of any code or protocol + * caused by bugs or programming or logic errors or otherwise); + * + * A. any offer, purchase, holding, use, sale, exchange or transmission of any + * cryptographic keys, tokens or assets created, exchanged, stored or arising from any + * interaction with the Work; + * + * B. any failure in a transmission or loss of any token or assets keys or other digital + * artefacts due to errors in transmission; + * + * C. bugs, hacks, logic errors or faults in the Work or any communication; + * + * D. system software or apparatus including but not limited to losses caused by errors + * in holding or transmitting tokens by any third-party; + * + * E. breaches or failure of security including hacker attacks, loss or disclosure of + * password, loss of private key, unauthorised use or misuse of such passwords or keys; + * + * F. any losses including loss of anticipated savings or other benefits resulting from + * use of the Work or any changes to the Work (however implemented). + * + * You are solely responsible for; testing, validating and evaluation of all operation + * logic, functionality, security and appropriateness of using the Work for any commercial + * or non-commercial purpose and for any reproduction or redistribution by You of the + * Work. You assume all risks associated with Your use of the Work and the exercise of + * permissions under this License. + */ + +use node_common::metrics::*; +use prometheus::*; + +#[derive(Debug, Clone)] +pub struct MeshApiMetrics { + pub handle_request: HistogramVec, + pub requests_accepted: IntCounterVec, + pub requests_not_found: IntCounter, +} + +impl MeshApiMetrics { + // TODO:MESH implement it properly for MeshApi + pub fn new(registry: &Registry) -> Self { + MeshApiMetrics { + handle_request: new_timer_vec( + opts( + "mesh_api_handle_request", + "Time spent by endpoint and status.", + ), + &["endpoint", "status"], + vec![ + 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1.0, 2.5, 5.0, 10.0, + ], + ) + .registered_at(registry), + requests_accepted: IntCounterVec::new( + opts( + "mesh_api_requests_accepted", + "Number of accepted requests by endpoint.", + ), + &["endpoint"], + ) + .registered_at(registry), + requests_not_found: IntCounter::new( + "mesh_api_requests_not_found", + "Number of total requests that did not match any configured route.", + ) + .registered_at(registry), + } + } +} diff --git a/core-rust/mesh-api-server/src/mesh_api/metrics_layer.rs b/core-rust/mesh-api-server/src/mesh_api/metrics_layer.rs new file mode 100644 index 0000000000..2ff1ea427d --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/metrics_layer.rs @@ -0,0 +1,143 @@ +/* Copyright 2021 Radix Publishing Ltd incorporated in Jersey (Channel Islands). + * + * Licensed under the Radix License, Version 1.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at: + * + * radixfoundation.org/licenses/LICENSE-v1 + * + * The Licensor hereby grants permission for the Canonical version of the Work to be + * published, distributed and used under or by reference to the Licensor’s trademark + * Radix ® and use of any unregistered trade names, logos or get-up. + * + * The Licensor provides the Work (and each Contributor provides its Contributions) on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, + * including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, + * MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. + * + * Whilst the Work is capable of being deployed, used and adopted (instantiated) to create + * a distributed ledger it is your responsibility to test and validate the code, together + * with all logic and performance of that code under all foreseeable scenarios. + * + * The Licensor does not make or purport to make and hereby excludes liability for all + * and any representation, warranty or undertaking in any form whatsoever, whether express + * or implied, to any entity or person, including any representation, warranty or + * undertaking, as to the functionality security use, value or other characteristics of + * any distributed ledger nor in respect the functioning or value of any tokens which may + * be created stored or transferred using the Work. The Licensor does not warrant that the + * Work or any use of the Work complies with any law or regulation in any territory where + * it may be implemented or used or that it will be appropriate for any specific purpose. + * + * Neither the licensor nor any current or former employees, officers, directors, partners, + * trustees, representatives, agents, advisors, contractors, or volunteers of the Licensor + * shall be liable for any direct or indirect, special, incidental, consequential or other + * losses of any kind, in tort, contract or otherwise (including but not limited to loss + * of revenue, income or profits, or loss of use or data, or loss of reputation, or loss + * of any economic or other opportunity of whatsoever nature or howsoever arising), arising + * out of or in connection with (without limitation of any use, misuse, of any ledger system + * or use made or its functionality or any performance or operation of any code or protocol + * caused by bugs or programming or logic errors or otherwise); + * + * A. any offer, purchase, holding, use, sale, exchange or transmission of any + * cryptographic keys, tokens or assets created, exchanged, stored or arising from any + * interaction with the Work; + * + * B. any failure in a transmission or loss of any token or assets keys or other digital + * artefacts due to errors in transmission; + * + * C. bugs, hacks, logic errors or faults in the Work or any communication; + * + * D. system software or apparatus including but not limited to losses caused by errors + * in holding or transmitting tokens by any third-party; + * + * E. breaches or failure of security including hacker attacks, loss or disclosure of + * password, loss of private key, unauthorised use or misuse of such passwords or keys; + * + * F. any losses including loss of anticipated savings or other benefits resulting from + * use of the Work or any changes to the Work (however implemented). + * + * You are solely responsible for; testing, validating and evaluation of all operation + * logic, functionality, security and appropriateness of using the Work for any commercial + * or non-commercial purpose and for any reproduction or redistribution by You of the + * Work. You assume all risks associated with Your use of the Work and the exercise of + * permissions under this License. + */ + +use std::{ + sync::Arc, + task::{Context, Poll}, + time::Instant, +}; + +use axum::{http::Request, response::Response}; +use futures_util::future::BoxFuture; +use node_common::metrics::TakesMetricLabels; +use tower::{Layer, Service}; + +use super::metrics::MeshApiMetrics; + +#[derive(Debug, Clone)] +pub struct MetricsLayer { + metrics: Arc, +} + +impl MetricsLayer { + pub fn new(metrics: Arc) -> Self { + Self { metrics } + } +} + +impl Layer for MetricsLayer { + type Service = MetricsService; + + fn layer(&self, inner: S) -> Self::Service { + MetricsService { + inner, + metrics: self.metrics.clone(), + } + } +} + +#[derive(Debug, Clone)] +pub struct MetricsService { + inner: S, + metrics: Arc, +} + +impl Service> for MetricsService +where + S: Service, Response = Response> + Send + 'static, + S::Future: Send + 'static, +{ + type Response = S::Response; + type Error = S::Error; + type Future = BoxFuture<'static, Result>; + + #[inline] + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + self.inner.poll_ready(cx) + } + + fn call(&mut self, request: Request) -> Self::Future { + let start = Instant::now(); + let endpoint: String = request.uri().path().into(); + + let metrics = self.metrics.clone(); + metrics.requests_accepted.with_label(endpoint.clone()).inc(); + + let future = self.inner.call(request); + + Box::pin(async move { + let response: Response = future.await?; + + let duration = start.elapsed().as_secs_f64(); + let status = response.status().as_u16().to_string(); + + metrics + .handle_request + .with_two_labels(endpoint.clone(), status) + .observe(duration); + + Ok(response) + }) + } +} diff --git a/core-rust/mesh-api-server/src/mesh_api/mod.rs b/core-rust/mesh-api-server/src/mesh_api/mod.rs new file mode 100644 index 0000000000..c558ae2a14 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/mod.rs @@ -0,0 +1,86 @@ +/* Copyright 2021 Radix Publishing Ltd incorporated in Jersey (Channel Islands). + * + * Licensed under the Radix License, Version 1.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at: + * + * radixfoundation.org/licenses/LICENSE-v1 + * + * The Licensor hereby grants permission for the Canonical version of the Work to be + * published, distributed and used under or by reference to the Licensor’s trademark + * Radix ® and use of any unregistered trade names, logos or get-up. + * + * The Licensor provides the Work (and each Contributor provides its Contributions) on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, + * including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, + * MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. + * + * Whilst the Work is capable of being deployed, used and adopted (instantiated) to create + * a distributed ledger it is your responsibility to test and validate the code, together + * with all logic and performance of that code under all foreseeable scenarios. + * + * The Licensor does not make or purport to make and hereby excludes liability for all + * and any representation, warranty or undertaking in any form whatsoever, whether express + * or implied, to any entity or person, including any representation, warranty or + * undertaking, as to the functionality security use, value or other characteristics of + * any distributed ledger nor in respect the functioning or value of any tokens which may + * be created stored or transferred using the Work. The Licensor does not warrant that the + * Work or any use of the Work complies with any law or regulation in any territory where + * it may be implemented or used or that it will be appropriate for any specific purpose. + * + * Neither the licensor nor any current or former employees, officers, directors, partners, + * trustees, representatives, agents, advisors, contractors, or volunteers of the Licensor + * shall be liable for any direct or indirect, special, incidental, consequential or other + * losses of any kind, in tort, contract or otherwise (including but not limited to loss + * of revenue, income or profits, or loss of use or data, or loss of reputation, or loss + * of any economic or other opportunity of whatsoever nature or howsoever arising), arising + * out of or in connection with (without limitation of any use, misuse, of any ledger system + * or use made or its functionality or any performance or operation of any code or protocol + * caused by bugs or programming or logic errors or otherwise); + * + * A. any offer, purchase, holding, use, sale, exchange or transmission of any + * cryptographic keys, tokens or assets created, exchanged, stored or arising from any + * interaction with the Work; + * + * B. any failure in a transmission or loss of any token or assets keys or other digital + * artefacts due to errors in transmission; + * + * C. bugs, hacks, logic errors or faults in the Work or any communication; + * + * D. system software or apparatus including but not limited to losses caused by errors + * in holding or transmitting tokens by any third-party; + * + * E. breaches or failure of security including hacker attacks, loss or disclosure of + * password, loss of private key, unauthorised use or misuse of such passwords or keys; + * + * F. any losses including loss of anticipated savings or other benefits resulting from + * use of the Work or any changes to the Work (however implemented). + * + * You are solely responsible for; testing, validating and evaluation of all operation + * logic, functionality, security and appropriateness of using the Work for any commercial + * or non-commercial purpose and for any reproduction or redistribution by You of the + * Work. You assume all risks associated with Your use of the Work and the exercise of + * permissions under this License. + */ +mod conversions; +mod errors; +mod handlers; +mod helpers; +mod metrics; +mod metrics_layer; +mod server; + +#[allow(unused)] +#[rustfmt::skip] +#[allow(clippy::all)] +mod generated; + +pub(crate) use conversions::*; +pub(crate) use errors::*; +pub(crate) use helpers::*; +pub(crate) use server::{create_server, MeshApiServerConfig, MeshApiState}; + +pub(crate) mod models { + pub(crate) use super::generated::models::*; +} + +// Re-exports for handlers diff --git a/core-rust/mesh-api-server/src/mesh_api/server.rs b/core-rust/mesh-api-server/src/mesh_api/server.rs new file mode 100644 index 0000000000..d31d3490c5 --- /dev/null +++ b/core-rust/mesh-api-server/src/mesh_api/server.rs @@ -0,0 +1,185 @@ +/* Copyright 2021 Radix Publishing Ltd incorporated in Jersey (Channel Islands). + * + * Licensed under the Radix License, Version 1.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at: + * + * radixfoundation.org/licenses/LICENSE-v1 + * + * The Licensor hereby grants permission for the Canonical version of the Work to be + * published, distributed and used under or by reference to the Licensor’s trademark + * Radix ® and use of any unregistered trade names, logos or get-up. + * + * The Licensor provides the Work (and each Contributor provides its Contributions) on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, + * including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, + * MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. + * + * Whilst the Work is capable of being deployed, used and adopted (instantiated) to create + * a distributed ledger it is your responsibility to test and validate the code, together + * with all logic and performance of that code under all foreseeable scenarios. + * + * The Licensor does not make or purport to make and hereby excludes liability for all + * and any representation, warranty or undertaking in any form whatsoever, whether express + * or implied, to any entity or person, including any representation, warranty or + * undertaking, as to the functionality security use, value or other characteristics of + * any distributed ledger nor in respect the functioning or value of any tokens which may + * be created stored or transferred using the Work. The Licensor does not warrant that the + * Work or any use of the Work complies with any law or regulation in any territory where + * it may be implemented or used or that it will be appropriate for any specific purpose. + * + * Neither the licensor nor any current or former employees, officers, directors, partners, + * trustees, representatives, agents, advisors, contractors, or volunteers of the Licensor + * shall be liable for any direct or indirect, special, incidental, consequential or other + * losses of any kind, in tort, contract or otherwise (including but not limited to loss + * of revenue, income or profits, or loss of use or data, or loss of reputation, or loss + * of any economic or other opportunity of whatsoever nature or howsoever arising), arising + * out of or in connection with (without limitation of any use, misuse, of any ledger system + * or use made or its functionality or any performance or operation of any code or protocol + * caused by bugs or programming or logic errors or otherwise); + * + * A. any offer, purchase, holding, use, sale, exchange or transmission of any + * cryptographic keys, tokens or assets created, exchanged, stored or arising from any + * interaction with the Work; + * + * B. any failure in a transmission or loss of any token or assets keys or other digital + * artefacts due to errors in transmission; + * + * C. bugs, hacks, logic errors or faults in the Work or any communication; + * + * D. system software or apparatus including but not limited to losses caused by errors + * in holding or transmitting tokens by any third-party; + * + * E. breaches or failure of security including hacker attacks, loss or disclosure of + * password, loss of private key, unauthorised use or misuse of such passwords or keys; + * + * F. any losses including loss of anticipated savings or other benefits resulting from + * use of the Work or any changes to the Work (however implemented). + * + * You are solely responsible for; testing, validating and evaluation of all operation + * logic, functionality, security and appropriateness of using the Work for any commercial + * or non-commercial purpose and for any reproduction or redistribution by You of the + * Work. You assume all risks associated with Your use of the Work and the exercise of + * permissions under this License. + */ + +use crate::prelude::*; +use std::future::Future; +use std::sync::Arc; + +use super::metrics::MeshApiMetrics; +use super::metrics_layer::MetricsLayer; +use axum::extract::State; +use axum::middleware::map_response; + +use axum::{ + routing::{get, post}, + Router, +}; + +use prometheus::Registry; +use state_manager::state_manager::StateManager; +use tower_http::catch_panic::CatchPanicLayer; + +use super::{handlers::*, ResponseError}; + +use crate::mesh_api::{emit_error_response_event, InternalServerErrorResponseForPanic}; + +#[derive(Clone)] +pub struct MeshApiState { + pub network: NetworkDefinition, + pub state_manager: StateManager, + pub node_display_version: String, +} + +impl MeshApiState { + pub fn address_encoder(&self) -> AddressBech32Encoder { + AddressBech32Encoder::new(&self.network) + } + + pub fn hash_encoder(&self) -> TransactionHashBech32Encoder { + TransactionHashBech32Encoder::new(&self.network) + } +} + +pub async fn create_server( + bind_addr: &str, + shutdown_signal: F, + mesh_api_state: MeshApiState, + metric_registry: &Registry, +) where + F: Future, +{ + let router = Router::new() + .route("/network/status", post(handle_network_status)) + .route("/network/list", post(handle_network_list)) + .route("/network/options", post(handle_network_options)) + .route("/account/balance", post(handle_account_balance)) + .route("/block", post(handle_block)) + .route("/block/transaction", post(handle_block_transaction)) + .route("/mempool", post(handle_mempool)) + .route("/mempool/transaction", post(handle_mempool_transaction)) + .route("/construction/derive", post(handle_construction_derive)) + .route( + "/construction/preprocess", + post(handle_construction_preprocess), + ) + .route("/construction/metadata", post(handle_construction_metadata)) + .route("/construction/payloads", post(handle_construction_payloads)) + .route("/construction/parse", post(handle_construction_parse)) + .route("/construction/combine", post(handle_construction_combine)) + .route("/construction/hash", post(handle_construction_hash)) + .route("/construction/submit", post(handle_construction_submit)) + // Below endpoints are optional + // account/coins not needed as we're not UTXO + .route("/account/coins", post(handle_endpoint_not_supported)) + .route("/call", post(handle_endpoint_not_supported)) + .route("/search/transaction", post(handle_endpoint_not_supported)) + .route("/events/blocks", post(handle_endpoint_not_supported)) + .with_state(mesh_api_state); + + let metrics = Arc::new(MeshApiMetrics::new(metric_registry)); + + let prefixed_router = Router::new() + .nest("/mesh", router) + .route("/", get(handle_missing_mesh_path)) + .layer(CatchPanicLayer::custom(InternalServerErrorResponseForPanic)) + // Note: it is important to run the metrics middleware only on router matched paths to avoid out of memory crash + // of node or full storage for prometheus server. + .route_layer(MetricsLayer::new(metrics.clone())) + .layer(map_response(emit_error_response_event)) + .fallback(handle_not_found) + .with_state(metrics); + + let bind_addr = bind_addr.parse().expect("Failed to parse bind address"); + + axum::Server::bind(&bind_addr) + .serve(prefixed_router.into_make_service()) + .with_graceful_shutdown(shutdown_signal) + .await + .unwrap(); +} + +async fn handle_endpoint_not_supported( + _state: State, + Json(_request): Json, +) -> Result, ResponseError> { + Err(ResponseError::from(ApiError::EndpointNotSupported)) +} + +#[tracing::instrument] +pub(crate) async fn handle_missing_mesh_path() -> Result<(), ResponseError> { + Err(ResponseError::from(ApiError::EndpointNotFound).with_details("Try /mesh")) +} + +async fn handle_not_found(metrics: State>) -> Result<(), ResponseError> { + metrics.requests_not_found.inc(); + Err(ResponseError::from(ApiError::EndpointNotFound) + .with_details("Please see API docs for available endpoints")) +} + +#[derive(Debug, Clone, ScryptoSbor)] +pub struct MeshApiServerConfig { + pub bind_interface: String, + pub port: u32, + pub node_display_version: String, +} diff --git a/core-rust/node-common/src/fee_computer.rs b/core-rust/node-common/src/fee_computer.rs new file mode 100644 index 0000000000..27da50f6e1 --- /dev/null +++ b/core-rust/node-common/src/fee_computer.rs @@ -0,0 +1,176 @@ +use crate::prelude::*; +pub use radix_engine::system::system_modules::costing::*; +pub use radix_engine::transaction::*; + +#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)] +pub enum FeePaymentBalanceChangeType { + FeePayment, + FeeDistributed, + TipDistributed, + RoyaltyDistributed, +} + +pub struct FeePaymentComputer<'a> { + inputs: FeePaymentComputationInputs<'a>, + computation: FeePaymentComputation, +} + +pub struct FeePaymentComputationInputs<'a> { + /// The balance changes caused by [`FeeSource#paying_vaults`] (resolved to global ancestors). + /// Note: this information is logically of the same type as [`balance_changes`], but the actual + /// signature is simpler, since all fees are necessarily XRD and thus have fungible balances. + pub fee_balance_changes: IndexMap, + pub fee_summary: &'a TransactionFeeSummary, + pub fee_destination: &'a FeeDestination, + /// The total balance changes (i.e. including the [`fee_balance_changes`]). + pub balance_changes: &'a IndexMap>, +} + +pub struct FeePaymentComputation { + pub relevant_entities: IndexSet, + pub fee_balance_changes: NonIterMap>, + pub non_fee_balance_changes: NonIterMap>, +} + +impl<'a> FeePaymentComputer<'a> { + pub fn compute(inputs: FeePaymentComputationInputs<'a>) -> FeePaymentComputation { + Self { + inputs, + computation: FeePaymentComputation { + relevant_entities: Default::default(), + fee_balance_changes: Default::default(), + non_fee_balance_changes: Default::default(), + }, + } + .compute_internal() + } + + fn compute_internal(mut self) -> FeePaymentComputation { + // Step 1 - Add initial relevant entities + self.add_initial_ordered_relevant_entities(); + + // Step 2 - Track fee balance changes + self.track_fee_payments(); + self.track_fee_distributions(); + self.track_royalty_distributions(); + + // Step 3 - Compute resultant non-fee balance changes + self.finalize_non_fee_balance_changes(); + + // And finally, return the outputs + self.computation + } + + fn add_initial_ordered_relevant_entities(&mut self) { + for entity in self.inputs.balance_changes.keys() { + self.computation.relevant_entities.insert(*entity); + } + } + + fn track_fee_payments(&mut self) { + for (fee_payer, fee_balance_change) in self.inputs.fee_balance_changes.clone() { + self.record_fee_balance_change_if_non_zero( + fee_payer, + fee_balance_change, + FeePaymentBalanceChangeType::FeePayment, + ); + } + } + + fn track_fee_distributions(&mut self) { + self.record_fee_balance_change_if_non_zero( + CONSENSUS_MANAGER.into(), + self.inputs + .fee_summary + .network_fees() + .sub_or_panic(self.inputs.fee_destination.to_burn), + FeePaymentBalanceChangeType::FeeDistributed, + ); + self.record_fee_balance_change_if_non_zero( + CONSENSUS_MANAGER.into(), + self.inputs.fee_summary.total_tipping_cost_in_xrd, + FeePaymentBalanceChangeType::TipDistributed, + ); + } + + fn track_royalty_distributions(&mut self) { + for (recipient, amount) in &self.inputs.fee_destination.to_royalty_recipients { + let recipient: GlobalAddress = match recipient { + RoyaltyRecipient::Package(address, _) => (*address).into(), + RoyaltyRecipient::Component(address, _) => (*address).into(), + }; + self.record_fee_balance_change_if_non_zero( + recipient, + *amount, + FeePaymentBalanceChangeType::RoyaltyDistributed, + ); + } + } + + fn record_fee_balance_change_if_non_zero( + &mut self, + address: GlobalAddress, + balance_change: Decimal, + fee_type: FeePaymentBalanceChangeType, + ) { + if balance_change == Decimal::ZERO { + return; + } + // This handles the case that a relevant entity had 0 net balance change. + // For example, if a component received a royalty and output XRD equal to that royalty in the same transaction then + // it wouldn't be in the balance changes - but we'd still want to include it in our output. + self.computation.relevant_entities.insert(address); + self.computation + .fee_balance_changes + .entry(address) + .or_default() + .push((fee_type, balance_change)); + } + + fn finalize_non_fee_balance_changes(&mut self) { + for (entity, changes) in self.inputs.balance_changes { + let total_fee_balance_changes: Decimal = self + .computation + .fee_balance_changes + .get(entity) + .map(|fee_payments| fee_payments.iter().map(|p| p.1).sum_or_panic()) + .unwrap_or_default(); + let mut non_fee_balance_changes: IndexMap = changes + .iter() + .filter_map(|(resource, balance_change)| { + if resource == &XRD { + let total_balance_change = get_fungible_balance(balance_change) + .expect("Expected XRD to be fungible"); + let total_non_fee_balance_change = + total_balance_change.sub_or_panic(total_fee_balance_changes); + if total_non_fee_balance_change == Decimal::ZERO { + None + } else { + Some((*resource, total_non_fee_balance_change)) + } + } else { + match balance_change { + BalanceChange::Fungible(change) => Some((*resource, *change)), + BalanceChange::NonFungible { .. } => None, + } + } + }) + .collect(); + if total_fee_balance_changes != Decimal::ZERO && !changes.contains_key(&XRD) { + // If there were fee-related balance changes, but XRD is not in the balance change set, + // then there must have been an equal-and-opposite non-fee balance change to offset it + non_fee_balance_changes.insert(XRD, total_fee_balance_changes.neg_or_panic()); + } + self.computation + .non_fee_balance_changes + .insert(*entity, non_fee_balance_changes); + } + } +} + +pub fn get_fungible_balance(balance_change: &BalanceChange) -> Option { + match balance_change { + BalanceChange::Fungible(balance_change) => Some(*balance_change), + BalanceChange::NonFungible { .. } => None, + } +} diff --git a/core-rust/node-common/src/lib.rs b/core-rust/node-common/src/lib.rs index 03ef428dab..a415b73605 100644 --- a/core-rust/node-common/src/lib.rs +++ b/core-rust/node-common/src/lib.rs @@ -64,11 +64,13 @@ pub mod config; pub mod environment; +pub mod fee_computer; pub mod indexing; pub mod java; pub mod jni; pub mod locks; pub mod metrics; +pub mod numerics; pub mod scheduler; pub mod store; pub mod utils; @@ -76,8 +78,10 @@ pub mod utils; pub mod prelude { // Modules to export downstream pub use crate::config::*; + pub use crate::fee_computer::*; pub use crate::locks::*; pub use crate::metrics::*; + pub use crate::numerics::*; pub use crate::store::*; pub use crate::utils::*; diff --git a/core-rust/node-common/src/numerics.rs b/core-rust/node-common/src/numerics.rs new file mode 100644 index 0000000000..73e277c6e4 --- /dev/null +++ b/core-rust/node-common/src/numerics.rs @@ -0,0 +1,88 @@ +use crate::prelude::*; +use std::any::type_name; + +pub trait PanickingOps: Sized { + fn add_or_panic(self, rhs: Self) -> Self; + fn sub_or_panic(self, rhs: Self) -> Self; + fn mul_or_panic(self, rhs: Self) -> Self; + fn div_or_panic(self, rhs: Self) -> Self; + fn neg_or_panic(self) -> Self; +} + +impl PanickingOps for T +where + T: CheckedAdd + + CheckedSub + + CheckedDiv + + CheckedMul + + CheckedNeg + + Copy + + Display, +{ + fn add_or_panic(self, rhs: Self) -> Self { + op_or_panic(self, "+", rhs, self.checked_add(rhs)) + } + + fn sub_or_panic(self, rhs: Self) -> Self { + op_or_panic(self, "-", rhs, self.checked_sub(rhs)) + } + + fn mul_or_panic(self, rhs: Self) -> Self { + op_or_panic(self, "*", rhs, self.checked_mul(rhs)) + } + + fn div_or_panic(self, rhs: Self) -> Self { + op_or_panic(self, "/", rhs, self.checked_div(rhs)) + } + + fn neg_or_panic(self) -> Self { + if let Some(result) = self.checked_neg() { + result + } else { + panic!("result of -{} does not fit in {}", self, type_name::()); + } + } +} + +pub trait PanickingSumIterator { + fn sum_or_panic(self) -> E; +} + +impl PanickingSumIterator for T +where + T: Iterator, + E: Default + CheckedAdd + Copy + Display, +{ + fn sum_or_panic(self) -> E { + let mut result = E::default(); + for (index, element) in self.enumerate() { + let sum = result.checked_add(element); + if let Some(sum) = sum { + result = sum; + } else { + panic!( + "result of accumulating {}. element ({} + {}) does not fit in {}", + index, + result, + element, + type_name::() + ); + } + } + result + } +} + +fn op_or_panic(left: T, op: &str, right: T, result: Option) -> T { + if let Some(result) = result { + result + } else { + panic!( + "result of {} {} {} does not fit in {}", + left, + op, + right, + type_name::() + ); + } +} diff --git a/core-rust/state-manager/src/mempool/metrics.rs b/core-rust/state-manager/src/mempool/metrics.rs index 1d1a050a22..f93faebc28 100644 --- a/core-rust/state-manager/src/mempool/metrics.rs +++ b/core-rust/state-manager/src/mempool/metrics.rs @@ -132,6 +132,7 @@ impl MetricLabel for MempoolAddSource { match *self { MempoolAddSource::CoreApi => "CoreApi", MempoolAddSource::MempoolSync => "MempoolSync", + MempoolAddSource::MeshApi => "MeshApi", } } } diff --git a/core-rust/state-manager/src/mempool/mod.rs b/core-rust/state-manager/src/mempool/mod.rs index d0be55506c..92d003ad79 100644 --- a/core-rust/state-manager/src/mempool/mod.rs +++ b/core-rust/state-manager/src/mempool/mod.rs @@ -80,6 +80,7 @@ pub use priority_mempool::*; pub enum MempoolAddSource { CoreApi, MempoolSync, + MeshApi, } #[derive(Debug, Clone)] diff --git a/core/default.config b/core/default.config index 18f8b33d2b..d872a35e41 100644 --- a/core/default.config +++ b/core/default.config @@ -7,3 +7,6 @@ network.id=240 # The below comes from running ./gradlew -P "validators=1" -P "network=localnet" ":cli-tools:generateDevGenesis" # Or running "Generate Single Validator Genesis" IntelliJ task network.genesis_data=/wYAAHNOYVBwWQAHAgCfdxlxngUUXCEGCgEACQEABQkHKAAAIQoJZAAAAAr0DRoICrgLCRsMCuCTBAUKFTQYoABAehDzWgUVMgEAIKAAAGSns7bgDTIWAAFWDVUuRAAYABBjLV7HaxWBDQHAICICAAEgIQEGIAchA//5e9V1Xu6kIEU6FDVSNdOC9kcvhWihiy8FehRgKXVWAQEBAWJ1APCVICECAgwEbmFtZSIAAQwTRGVmYXVsdCB2YWxpZGF0b3IgMQIMCGluZm9fdXJsIg0BDBhodHRwczovL3d3dy5yYWRpeGRsdC5jb22A0V2lblLuqlWNSPddLPYcqXQbJq7Y9QscHefNoU86AQIggAHR0ouStuhEmbg7B5fvUjVVPut+2qDOokPBEowv5zcgIQECIAchA//5dtEAASgACSEKAKBeSwE0oAAAAEDq7XRG0JwsnwwBKw0B4CAMCgx0cmFuc2Zlcl94cmQIcmFkaXN3YXAIbWV0YWRhdGERZnVuZ2libGVfcmVzb3VyY2UVbm9uX0IWAPBpHWFjY291bnRfYXV0aG9yaXplZF9kZXBvc2l0b3JzDmdsb2JhbF9uX293bmVkJm5vbl9mdW5naWJsZV9yZXNvdXJjZV93aXRoX3JlbW90ZV90eXBlGWt2X3N0b3JlX3dpdGhfcmVtb3RlXwEaPA9tYXhfdHJhbnNhY3Rpb24= + +# Enable MeshAPI server +api.mesh.enabled=true diff --git a/core/src/main/java/com/radixdlt/RadixNode.java b/core/src/main/java/com/radixdlt/RadixNode.java index 644ef391f2..b86a6f3ce0 100644 --- a/core/src/main/java/com/radixdlt/RadixNode.java +++ b/core/src/main/java/com/radixdlt/RadixNode.java @@ -69,6 +69,7 @@ import com.radixdlt.addressing.Addressing; import com.radixdlt.api.CoreApiServer; import com.radixdlt.api.EngineStateApiServer; +import com.radixdlt.api.MeshApiServer; import com.radixdlt.api.prometheus.PrometheusApi; import com.radixdlt.api.system.SystemApi; import com.radixdlt.consensus.bft.SelfValidatorInfo; @@ -154,6 +155,12 @@ public static RadixNode run( final var engineStateApiServer = injector.getInstance(EngineStateApiServer.class); engineStateApiServer.start(); + // Start the Mesh API server if it's module has been installed + if (injector.getExistingBinding(Key.get(MeshApiServer.class)) != null) { + final var meshApiServer = injector.getInstance(MeshApiServer.class); + meshApiServer.start(); + } + return radixNode; } diff --git a/core/src/main/java/com/radixdlt/RadixNodeModule.java b/core/src/main/java/com/radixdlt/RadixNodeModule.java index 15c7b974ce..9a2494556f 100644 --- a/core/src/main/java/com/radixdlt/RadixNodeModule.java +++ b/core/src/main/java/com/radixdlt/RadixNodeModule.java @@ -69,6 +69,7 @@ import com.radixdlt.addressing.Addressing; import com.radixdlt.api.CoreApiServerModule; import com.radixdlt.api.EngineStateApiServerModule; +import com.radixdlt.api.MeshApiServerModule; import com.radixdlt.api.prometheus.PrometheusApiModule; import com.radixdlt.api.system.SystemApiModule; import com.radixdlt.config.SelfValidatorAddressConfig; @@ -118,12 +119,14 @@ public final class RadixNodeModule extends AbstractModule { private static final int DEFAULT_ENGINE_STATE_API_PORT = 3336; private static final int DEFAULT_SYSTEM_API_PORT = 3334; private static final int DEFAULT_PROMETHEUS_API_PORT = 3335; + private static final int DEFAULT_MESH_API_PORT = 3337; // APIs are only exposed on localhost by default private static final String DEFAULT_CORE_API_BIND_ADDRESS = "127.0.0.1"; private static final String DEFAULT_ENGINE_STATE_API_BIND_ADDRESS = "127.0.0.1"; private static final String DEFAULT_SYSTEM_API_BIND_ADDRESS = "127.0.0.1"; private static final String DEFAULT_PROMETHEUS_API_BIND_ADDRESS = "127.0.0.1"; + private static final String DEFAULT_MESH_API_BIND_ADDRESS = "127.0.0.1"; private final RuntimeProperties properties; private final Network network; @@ -429,6 +432,16 @@ protected void configure() { properties.get("api.engine_state.port", DEFAULT_ENGINE_STATE_API_PORT); install(new EngineStateApiServerModule(engineStateApiBindAddress, engineStateApiPort)); + final var meshApiBindAddress = + properties.get("api.mesh.bind_address", DEFAULT_MESH_API_BIND_ADDRESS); + final var meshApiPort = properties.get("api.mesh.port", DEFAULT_MESH_API_PORT); + // Install MeshAPI server module only if it is enabled + if (properties.get("api.mesh.enabled", false)) { + install( + new MeshApiServerModule( + meshApiBindAddress, meshApiPort, ApplicationVersion.INSTANCE.display())); + } + final var systemApiBindAddress = properties.get("api.system.bind_address", DEFAULT_SYSTEM_API_BIND_ADDRESS); final var systemApiPort = properties.get("api.system.port", DEFAULT_SYSTEM_API_PORT); diff --git a/core/src/main/java/com/radixdlt/monitoring/ApplicationVersion.java b/core/src/main/java/com/radixdlt/monitoring/ApplicationVersion.java index 1972ff2977..a7ecd6444e 100644 --- a/core/src/main/java/com/radixdlt/monitoring/ApplicationVersion.java +++ b/core/src/main/java/com/radixdlt/monitoring/ApplicationVersion.java @@ -64,6 +64,7 @@ package com.radixdlt.monitoring; +import io.netty.util.internal.StringUtil; import java.io.IOException; import java.util.*; @@ -100,9 +101,9 @@ private static ApplicationVersion loadFromResource(String resourceName) { if (is != null) { var p = new Properties(); p.load(is); - branch = p.getProperty("VERSION_BRANCH", branch); - commit = p.getProperty("VERSION_COMMIT", commit); - display = p.getProperty("VERSION_DISPLAY", display); + branch = propertyWithFallback(p, "VERSION_BRANCH", branch); + commit = propertyWithFallback(p, "VERSION_COMMIT", commit); + display = propertyWithFallback(p, "VERSION_DISPLAY", display); Map map = new HashMap<>(); for (var key : p.stringPropertyNames()) { var mapKey = key.split("_", 2)[1].toLowerCase(Locale.US); @@ -116,4 +117,13 @@ private static ApplicationVersion loadFromResource(String resourceName) { } return new ApplicationVersion(branch, commit, display, string); } + + private static String propertyWithFallback( + Properties properties, String propertyName, String fallback) { + var value = properties.getProperty(propertyName); + if (StringUtil.isNullOrEmpty(value)) { + return fallback; + } + return value; + } } diff --git a/core/src/test-core/java/com/radixdlt/api/MeshApiHelper.java b/core/src/test-core/java/com/radixdlt/api/MeshApiHelper.java new file mode 100644 index 0000000000..e30bc13e40 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/MeshApiHelper.java @@ -0,0 +1,171 @@ +/* Copyright 2021 Radix Publishing Ltd incorporated in Jersey (Channel Islands). + * + * Licensed under the Radix License, Version 1.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at: + * + * radixfoundation.org/licenses/LICENSE-v1 + * + * The Licensor hereby grants permission for the Canonical version of the Work to be + * published, distributed and used under or by reference to the Licensor’s trademark + * Radix ® and use of any unregistered trade names, logos or get-up. + * + * The Licensor provides the Work (and each Contributor provides its Contributions) on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, + * including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, + * MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. + * + * Whilst the Work is capable of being deployed, used and adopted (instantiated) to create + * a distributed ledger it is your responsibility to test and validate the code, together + * with all logic and performance of that code under all foreseeable scenarios. + * + * The Licensor does not make or purport to make and hereby excludes liability for all + * and any representation, warranty or undertaking in any form whatsoever, whether express + * or implied, to any entity or person, including any representation, warranty or + * undertaking, as to the functionality security use, value or other characteristics of + * any distributed ledger nor in respect the functioning or value of any tokens which may + * be created stored or transferred using the Work. The Licensor does not warrant that the + * Work or any use of the Work complies with any law or regulation in any territory where + * it may be implemented or used or that it will be appropriate for any specific purpose. + * + * Neither the licensor nor any current or former employees, officers, directors, partners, + * trustees, representatives, agents, advisors, contractors, or volunteers of the Licensor + * shall be liable for any direct or indirect, special, incidental, consequential or other + * losses of any kind, in tort, contract or otherwise (including but not limited to loss + * of revenue, income or profits, or loss of use or data, or loss of reputation, or loss + * of any economic or other opportunity of whatsoever nature or howsoever arising), arising + * out of or in connection with (without limitation of any use, misuse, of any ledger system + * or use made or its functionality or any performance or operation of any code or protocol + * caused by bugs or programming or logic errors or otherwise); + * + * A. any offer, purchase, holding, use, sale, exchange or transmission of any + * cryptographic keys, tokens or assets created, exchanged, stored or arising from any + * interaction with the Work; + * + * B. any failure in a transmission or loss of any token or assets keys or other digital + * artefacts due to errors in transmission; + * + * C. bugs, hacks, logic errors or faults in the Work or any communication; + * + * D. system software or apparatus including but not limited to losses caused by errors + * in holding or transmitting tokens by any third-party; + * + * E. breaches or failure of security including hacker attacks, loss or disclosure of + * password, loss of private key, unauthorised use or misuse of such passwords or keys; + * + * F. any losses including loss of anticipated savings or other benefits resulting from + * use of the Work or any changes to the Work (however implemented). + * + * You are solely responsible for; testing, validating and evaluation of all operation + * logic, functionality, security and appropriateness of using the Work for any commercial + * or non-commercial purpose and for any reproduction or redistribution by You of the + * Work. You assume all risks associated with Your use of the Work and the exercise of + * permissions under this License. + */ + +package com.radixdlt.api; + +import static org.assertj.core.api.Assertions.catchThrowableOfType; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.google.common.reflect.ClassPath; +import com.google.inject.AbstractModule; +import com.google.inject.Module; +import com.google.inject.multibindings.ProvidesIntoSet; +import com.radixdlt.api.mesh.generated.api.*; +import com.radixdlt.api.mesh.generated.client.ApiClient; +import com.radixdlt.api.mesh.generated.client.ApiException; +import com.radixdlt.api.mesh.generated.models.*; +import com.radixdlt.environment.StartProcessorOnRunner; +import com.radixdlt.monitoring.ApplicationVersion; +import com.radixdlt.networks.Network; +import com.radixdlt.utils.FreePortFinder; +import java.net.http.HttpClient; +import org.assertj.core.api.ThrowableAssert; + +public class MeshApiHelper { + + private final int meshApiPort; + private final Network network; + private final ApiClient apiClient; + + static { + ensureOpenApiModelsAreReady(); + } + + public static MeshApiHelper forTests() { + return new MeshApiHelper(Network.INTEGRATIONTESTNET); + } + + public MeshApiHelper(Network network) { + this.meshApiPort = FreePortFinder.findFreeLocalPort(); + this.network = network; + final var apiClient = new ApiClient(); + apiClient.updateBaseUri("http://127.0.0.1:" + meshApiPort + "/mesh"); + apiClient.setHttpClientBuilder( + HttpClient.newBuilder().sslContext(DummySslContextFactory.create())); + this.apiClient = apiClient; + } + + private static void ensureOpenApiModelsAreReady() { + /* The generated Open API models are rubbish and requires that static initializers run on models before + * deserialization to work correctly... But that doesn't happen in e.g. models under the response model in + * assertErrorResponseOfType. + * As a workaround for now, let's go through all the types and explicitly ensure their static initializers run + * by using the Class.forName method. + */ + try { + ClassPath.from(ClassLoader.getSystemClassLoader()).getAllClasses().stream() + .filter(clazz -> clazz.getPackageName().equals("com.radixdlt.api.mesh.generated.models")) + .forEach( + clazz -> { + try { + Class.forName(clazz.getName()); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + }); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } + + public Module module() { + return new AbstractModule() { + @Override + protected void configure() { + install( + new MeshApiServerModule( + "127.0.0.1", meshApiPort, ApplicationVersion.INSTANCE.display())); + } + + @ProvidesIntoSet + private StartProcessorOnRunner startCoreApi(MeshApiServer meshApiServer) { + // This is a slightly hacky way to run something on node start-up in a Deterministic test. + // Stop is called by the AutoClosable binding in CoreApiServerModule + return new StartProcessorOnRunner("meshApi", meshApiServer::start); + } + }; + } + + public ApiClient client() { + return this.apiClient; + } + + public MempoolApi mempoolApi() { + return new MempoolApi(client()); + } + + public NetworkIdentifier networkIdentifier() { + return new NetworkIdentifier().blockchain("radix").network(this.network.getLogicalName()); + } + + public Response assertErrorResponseOfType( + ThrowableAssert.ThrowingCallable apiCall, Class responseClass) { + var apiException = catchThrowableOfType(apiCall, ApiException.class); + try { + return apiClient.getObjectMapper().readValue(apiException.getResponseBody(), responseClass); + } catch (JsonProcessingException ex) { + throw new RuntimeException(ex); + } + } +} diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/api/AccountApi.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/api/AccountApi.java new file mode 100644 index 0000000000..a4fb3a63f9 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/api/AccountApi.java @@ -0,0 +1,237 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +package com.radixdlt.api.mesh.generated.api; + +import com.radixdlt.api.mesh.generated.client.ApiClient; +import com.radixdlt.api.mesh.generated.client.ApiException; +import com.radixdlt.api.mesh.generated.client.ApiResponse; +import com.radixdlt.api.mesh.generated.client.Pair; + +import com.radixdlt.api.mesh.generated.models.AccountBalanceRequest; +import com.radixdlt.api.mesh.generated.models.AccountBalanceResponse; +import com.radixdlt.api.mesh.generated.models.AccountCoinsRequest; +import com.radixdlt.api.mesh.generated.models.AccountCoinsResponse; +import com.radixdlt.api.mesh.generated.models.Error; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.time.Duration; + +import java.util.ArrayList; +import java.util.StringJoiner; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Consumer; + +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class AccountApi { + private final HttpClient memberVarHttpClient; + private final ObjectMapper memberVarObjectMapper; + private final String memberVarBaseUri; + private final Consumer memberVarInterceptor; + private final Duration memberVarReadTimeout; + private final Consumer> memberVarResponseInterceptor; + private final Consumer> memberVarAsyncResponseInterceptor; + + public AccountApi() { + this(new ApiClient()); + } + + public AccountApi(ApiClient apiClient) { + memberVarHttpClient = apiClient.getHttpClient(); + memberVarObjectMapper = apiClient.getObjectMapper(); + memberVarBaseUri = apiClient.getBaseUri(); + memberVarInterceptor = apiClient.getRequestInterceptor(); + memberVarReadTimeout = apiClient.getReadTimeout(); + memberVarResponseInterceptor = apiClient.getResponseInterceptor(); + memberVarAsyncResponseInterceptor = apiClient.getAsyncResponseInterceptor(); + } + + protected ApiException getApiException(String operationId, HttpResponse response) throws IOException { + String body = response.body() == null ? null : new String(response.body().readAllBytes()); + String message = formatExceptionMessage(operationId, response.statusCode(), body); + return new ApiException(response.statusCode(), message, response.headers(), body); + } + + private String formatExceptionMessage(String operationId, int statusCode, String body) { + if (body == null || body.isEmpty()) { + body = "[no body]"; + } + return operationId + " call failed with: " + statusCode + " - " + body; + } + + /** + * Get an Account's Balance + * Get an array of all AccountBalances for an AccountIdentifier and the BlockIdentifier at which the balance lookup was performed. The BlockIdentifier must always be returned because some consumers of account balance data need to know specifically at which block the balance was calculated to compare balances they compute from operations with the balance returned by the node. It is important to note that making a balance request for an account without populating the SubAccountIdentifier should not result in the balance of all possible SubAccountIdentifiers being returned. Rather, it should result in the balance pertaining to no SubAccountIdentifiers being returned (sometimes called the liquid balance). To get all balances associated with an account, it may be necessary to perform multiple balance requests with unique AccountIdentifiers. It is also possible to perform a historical balance lookup (if the server supports it) by passing in an optional BlockIdentifier. + * @param accountBalanceRequest (required) + * @return AccountBalanceResponse + * @throws ApiException if fails to make API call + */ + public AccountBalanceResponse accountBalance(AccountBalanceRequest accountBalanceRequest) throws ApiException { + ApiResponse localVarResponse = accountBalanceWithHttpInfo(accountBalanceRequest); + return localVarResponse.getData(); + } + + /** + * Get an Account's Balance + * Get an array of all AccountBalances for an AccountIdentifier and the BlockIdentifier at which the balance lookup was performed. The BlockIdentifier must always be returned because some consumers of account balance data need to know specifically at which block the balance was calculated to compare balances they compute from operations with the balance returned by the node. It is important to note that making a balance request for an account without populating the SubAccountIdentifier should not result in the balance of all possible SubAccountIdentifiers being returned. Rather, it should result in the balance pertaining to no SubAccountIdentifiers being returned (sometimes called the liquid balance). To get all balances associated with an account, it may be necessary to perform multiple balance requests with unique AccountIdentifiers. It is also possible to perform a historical balance lookup (if the server supports it) by passing in an optional BlockIdentifier. + * @param accountBalanceRequest (required) + * @return ApiResponse<AccountBalanceResponse> + * @throws ApiException if fails to make API call + */ + public ApiResponse accountBalanceWithHttpInfo(AccountBalanceRequest accountBalanceRequest) throws ApiException { + HttpRequest.Builder localVarRequestBuilder = accountBalanceRequestBuilder(accountBalanceRequest); + try { + HttpResponse localVarResponse = memberVarHttpClient.send( + localVarRequestBuilder.build(), + HttpResponse.BodyHandlers.ofInputStream()); + if (memberVarResponseInterceptor != null) { + memberVarResponseInterceptor.accept(localVarResponse); + } + try { + if (localVarResponse.statusCode()/ 100 != 2) { + throw getApiException("accountBalance", localVarResponse); + } + return new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + memberVarObjectMapper.readValue(localVarResponse.body(), new TypeReference() {}) // closes the InputStream + + ); + } finally { + } + } catch (IOException e) { + throw new ApiException(e); + } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new ApiException(e); + } + } + + private HttpRequest.Builder accountBalanceRequestBuilder(AccountBalanceRequest accountBalanceRequest) throws ApiException { + // verify the required parameter 'accountBalanceRequest' is set + if (accountBalanceRequest == null) { + throw new ApiException(400, "Missing the required parameter 'accountBalanceRequest' when calling accountBalance"); + } + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = "/account/balance"; + + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + + localVarRequestBuilder.header("Content-Type", "application/json"); + localVarRequestBuilder.header("Accept", "application/json"); + + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(accountBalanceRequest); + localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } + /** + * Get an Account's Unspent Coins + * Get an array of all unspent coins for an AccountIdentifier and the BlockIdentifier at which the lookup was performed. If your implementation does not support coins (i.e. it is for an account-based blockchain), you do not need to implement this endpoint. If you implementation does support coins (i.e. it is fro a UTXO-based blockchain), you MUST also complete the `/account/balance` endpoint. It is important to note that making a coins request for an account without populating the SubAccountIdentifier should not result in the coins of all possible SubAccountIdentifiers being returned. Rather, it should result in the coins pertaining to no SubAccountIdentifiers being returned. To get all coins associated with an account, it may be necessary to perform multiple coin requests with unique AccountIdentifiers. Optionally, an implementation may choose to support updating an AccountIdentifier's unspent coins based on the contents of the mempool. Note, using this functionality breaks any guarantee of idempotency. + * @param accountCoinsRequest (required) + * @return AccountCoinsResponse + * @throws ApiException if fails to make API call + */ + public AccountCoinsResponse accountCoins(AccountCoinsRequest accountCoinsRequest) throws ApiException { + ApiResponse localVarResponse = accountCoinsWithHttpInfo(accountCoinsRequest); + return localVarResponse.getData(); + } + + /** + * Get an Account's Unspent Coins + * Get an array of all unspent coins for an AccountIdentifier and the BlockIdentifier at which the lookup was performed. If your implementation does not support coins (i.e. it is for an account-based blockchain), you do not need to implement this endpoint. If you implementation does support coins (i.e. it is fro a UTXO-based blockchain), you MUST also complete the `/account/balance` endpoint. It is important to note that making a coins request for an account without populating the SubAccountIdentifier should not result in the coins of all possible SubAccountIdentifiers being returned. Rather, it should result in the coins pertaining to no SubAccountIdentifiers being returned. To get all coins associated with an account, it may be necessary to perform multiple coin requests with unique AccountIdentifiers. Optionally, an implementation may choose to support updating an AccountIdentifier's unspent coins based on the contents of the mempool. Note, using this functionality breaks any guarantee of idempotency. + * @param accountCoinsRequest (required) + * @return ApiResponse<AccountCoinsResponse> + * @throws ApiException if fails to make API call + */ + public ApiResponse accountCoinsWithHttpInfo(AccountCoinsRequest accountCoinsRequest) throws ApiException { + HttpRequest.Builder localVarRequestBuilder = accountCoinsRequestBuilder(accountCoinsRequest); + try { + HttpResponse localVarResponse = memberVarHttpClient.send( + localVarRequestBuilder.build(), + HttpResponse.BodyHandlers.ofInputStream()); + if (memberVarResponseInterceptor != null) { + memberVarResponseInterceptor.accept(localVarResponse); + } + try { + if (localVarResponse.statusCode()/ 100 != 2) { + throw getApiException("accountCoins", localVarResponse); + } + return new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + memberVarObjectMapper.readValue(localVarResponse.body(), new TypeReference() {}) // closes the InputStream + + ); + } finally { + } + } catch (IOException e) { + throw new ApiException(e); + } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new ApiException(e); + } + } + + private HttpRequest.Builder accountCoinsRequestBuilder(AccountCoinsRequest accountCoinsRequest) throws ApiException { + // verify the required parameter 'accountCoinsRequest' is set + if (accountCoinsRequest == null) { + throw new ApiException(400, "Missing the required parameter 'accountCoinsRequest' when calling accountCoins"); + } + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = "/account/coins"; + + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + + localVarRequestBuilder.header("Content-Type", "application/json"); + localVarRequestBuilder.header("Accept", "application/json"); + + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(accountCoinsRequest); + localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } +} diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/api/BlockApi.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/api/BlockApi.java new file mode 100644 index 0000000000..2d3877c54d --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/api/BlockApi.java @@ -0,0 +1,237 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +package com.radixdlt.api.mesh.generated.api; + +import com.radixdlt.api.mesh.generated.client.ApiClient; +import com.radixdlt.api.mesh.generated.client.ApiException; +import com.radixdlt.api.mesh.generated.client.ApiResponse; +import com.radixdlt.api.mesh.generated.client.Pair; + +import com.radixdlt.api.mesh.generated.models.BlockRequest; +import com.radixdlt.api.mesh.generated.models.BlockResponse; +import com.radixdlt.api.mesh.generated.models.BlockTransactionRequest; +import com.radixdlt.api.mesh.generated.models.BlockTransactionResponse; +import com.radixdlt.api.mesh.generated.models.Error; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.time.Duration; + +import java.util.ArrayList; +import java.util.StringJoiner; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Consumer; + +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class BlockApi { + private final HttpClient memberVarHttpClient; + private final ObjectMapper memberVarObjectMapper; + private final String memberVarBaseUri; + private final Consumer memberVarInterceptor; + private final Duration memberVarReadTimeout; + private final Consumer> memberVarResponseInterceptor; + private final Consumer> memberVarAsyncResponseInterceptor; + + public BlockApi() { + this(new ApiClient()); + } + + public BlockApi(ApiClient apiClient) { + memberVarHttpClient = apiClient.getHttpClient(); + memberVarObjectMapper = apiClient.getObjectMapper(); + memberVarBaseUri = apiClient.getBaseUri(); + memberVarInterceptor = apiClient.getRequestInterceptor(); + memberVarReadTimeout = apiClient.getReadTimeout(); + memberVarResponseInterceptor = apiClient.getResponseInterceptor(); + memberVarAsyncResponseInterceptor = apiClient.getAsyncResponseInterceptor(); + } + + protected ApiException getApiException(String operationId, HttpResponse response) throws IOException { + String body = response.body() == null ? null : new String(response.body().readAllBytes()); + String message = formatExceptionMessage(operationId, response.statusCode(), body); + return new ApiException(response.statusCode(), message, response.headers(), body); + } + + private String formatExceptionMessage(String operationId, int statusCode, String body) { + if (body == null || body.isEmpty()) { + body = "[no body]"; + } + return operationId + " call failed with: " + statusCode + " - " + body; + } + + /** + * Get a Block + * Get a block by its Block Identifier. If transactions are returned in the same call to the node as fetching the block, the response should include these transactions in the Block object. If not, an array of Transaction Identifiers should be returned so /block/transaction fetches can be done to get all transaction information. When requesting a block by the hash component of the BlockIdentifier, this request MUST be idempotent: repeated invocations for the same hash-identified block must return the exact same block contents. No such restriction is imposed when requesting a block by height, given that a chain reorg event might cause the specific block at height `n` to be set to a different one. + * @param blockRequest (required) + * @return BlockResponse + * @throws ApiException if fails to make API call + */ + public BlockResponse block(BlockRequest blockRequest) throws ApiException { + ApiResponse localVarResponse = blockWithHttpInfo(blockRequest); + return localVarResponse.getData(); + } + + /** + * Get a Block + * Get a block by its Block Identifier. If transactions are returned in the same call to the node as fetching the block, the response should include these transactions in the Block object. If not, an array of Transaction Identifiers should be returned so /block/transaction fetches can be done to get all transaction information. When requesting a block by the hash component of the BlockIdentifier, this request MUST be idempotent: repeated invocations for the same hash-identified block must return the exact same block contents. No such restriction is imposed when requesting a block by height, given that a chain reorg event might cause the specific block at height `n` to be set to a different one. + * @param blockRequest (required) + * @return ApiResponse<BlockResponse> + * @throws ApiException if fails to make API call + */ + public ApiResponse blockWithHttpInfo(BlockRequest blockRequest) throws ApiException { + HttpRequest.Builder localVarRequestBuilder = blockRequestBuilder(blockRequest); + try { + HttpResponse localVarResponse = memberVarHttpClient.send( + localVarRequestBuilder.build(), + HttpResponse.BodyHandlers.ofInputStream()); + if (memberVarResponseInterceptor != null) { + memberVarResponseInterceptor.accept(localVarResponse); + } + try { + if (localVarResponse.statusCode()/ 100 != 2) { + throw getApiException("block", localVarResponse); + } + return new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + memberVarObjectMapper.readValue(localVarResponse.body(), new TypeReference() {}) // closes the InputStream + + ); + } finally { + } + } catch (IOException e) { + throw new ApiException(e); + } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new ApiException(e); + } + } + + private HttpRequest.Builder blockRequestBuilder(BlockRequest blockRequest) throws ApiException { + // verify the required parameter 'blockRequest' is set + if (blockRequest == null) { + throw new ApiException(400, "Missing the required parameter 'blockRequest' when calling block"); + } + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = "/block"; + + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + + localVarRequestBuilder.header("Content-Type", "application/json"); + localVarRequestBuilder.header("Accept", "application/json"); + + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(blockRequest); + localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } + /** + * Get a Block Transaction + * Get a transaction in a block by its Transaction Identifier. This endpoint should only be used when querying a node for a block does not return all transactions contained within it. All transactions returned by this endpoint must be appended to any transactions returned by the /block method by consumers of this data. Fetching a transaction by hash is considered an Explorer Method (which is classified under the Future Work section). This method can be used to let consumers to paginate results when the block trasactions count is too big to be returned in a single BlockResponse. Calling this endpoint requires reference to a BlockIdentifier because transaction parsing can change depending on which block contains the transaction. For example, in Bitcoin it is necessary to know which block contains a transaction to determine the destination of fee payments. Without specifying a block identifier, the node would have to infer which block to use (which could change during a re-org). Implementations that require fetching previous transactions to populate the response (ex: Previous UTXOs in Bitcoin) may find it useful to run a cache within the Rosetta server in the /data directory (on a path that does not conflict with the node). + * @param blockTransactionRequest (required) + * @return BlockTransactionResponse + * @throws ApiException if fails to make API call + */ + public BlockTransactionResponse blockTransaction(BlockTransactionRequest blockTransactionRequest) throws ApiException { + ApiResponse localVarResponse = blockTransactionWithHttpInfo(blockTransactionRequest); + return localVarResponse.getData(); + } + + /** + * Get a Block Transaction + * Get a transaction in a block by its Transaction Identifier. This endpoint should only be used when querying a node for a block does not return all transactions contained within it. All transactions returned by this endpoint must be appended to any transactions returned by the /block method by consumers of this data. Fetching a transaction by hash is considered an Explorer Method (which is classified under the Future Work section). This method can be used to let consumers to paginate results when the block trasactions count is too big to be returned in a single BlockResponse. Calling this endpoint requires reference to a BlockIdentifier because transaction parsing can change depending on which block contains the transaction. For example, in Bitcoin it is necessary to know which block contains a transaction to determine the destination of fee payments. Without specifying a block identifier, the node would have to infer which block to use (which could change during a re-org). Implementations that require fetching previous transactions to populate the response (ex: Previous UTXOs in Bitcoin) may find it useful to run a cache within the Rosetta server in the /data directory (on a path that does not conflict with the node). + * @param blockTransactionRequest (required) + * @return ApiResponse<BlockTransactionResponse> + * @throws ApiException if fails to make API call + */ + public ApiResponse blockTransactionWithHttpInfo(BlockTransactionRequest blockTransactionRequest) throws ApiException { + HttpRequest.Builder localVarRequestBuilder = blockTransactionRequestBuilder(blockTransactionRequest); + try { + HttpResponse localVarResponse = memberVarHttpClient.send( + localVarRequestBuilder.build(), + HttpResponse.BodyHandlers.ofInputStream()); + if (memberVarResponseInterceptor != null) { + memberVarResponseInterceptor.accept(localVarResponse); + } + try { + if (localVarResponse.statusCode()/ 100 != 2) { + throw getApiException("blockTransaction", localVarResponse); + } + return new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + memberVarObjectMapper.readValue(localVarResponse.body(), new TypeReference() {}) // closes the InputStream + + ); + } finally { + } + } catch (IOException e) { + throw new ApiException(e); + } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new ApiException(e); + } + } + + private HttpRequest.Builder blockTransactionRequestBuilder(BlockTransactionRequest blockTransactionRequest) throws ApiException { + // verify the required parameter 'blockTransactionRequest' is set + if (blockTransactionRequest == null) { + throw new ApiException(400, "Missing the required parameter 'blockTransactionRequest' when calling blockTransaction"); + } + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = "/block/transaction"; + + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + + localVarRequestBuilder.header("Content-Type", "application/json"); + localVarRequestBuilder.header("Accept", "application/json"); + + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(blockTransactionRequest); + localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } +} diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/api/CallApi.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/api/CallApi.java new file mode 100644 index 0000000000..a1babeb062 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/api/CallApi.java @@ -0,0 +1,157 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +package com.radixdlt.api.mesh.generated.api; + +import com.radixdlt.api.mesh.generated.client.ApiClient; +import com.radixdlt.api.mesh.generated.client.ApiException; +import com.radixdlt.api.mesh.generated.client.ApiResponse; +import com.radixdlt.api.mesh.generated.client.Pair; + +import com.radixdlt.api.mesh.generated.models.CallRequest; +import com.radixdlt.api.mesh.generated.models.CallResponse; +import com.radixdlt.api.mesh.generated.models.Error; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.time.Duration; + +import java.util.ArrayList; +import java.util.StringJoiner; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Consumer; + +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class CallApi { + private final HttpClient memberVarHttpClient; + private final ObjectMapper memberVarObjectMapper; + private final String memberVarBaseUri; + private final Consumer memberVarInterceptor; + private final Duration memberVarReadTimeout; + private final Consumer> memberVarResponseInterceptor; + private final Consumer> memberVarAsyncResponseInterceptor; + + public CallApi() { + this(new ApiClient()); + } + + public CallApi(ApiClient apiClient) { + memberVarHttpClient = apiClient.getHttpClient(); + memberVarObjectMapper = apiClient.getObjectMapper(); + memberVarBaseUri = apiClient.getBaseUri(); + memberVarInterceptor = apiClient.getRequestInterceptor(); + memberVarReadTimeout = apiClient.getReadTimeout(); + memberVarResponseInterceptor = apiClient.getResponseInterceptor(); + memberVarAsyncResponseInterceptor = apiClient.getAsyncResponseInterceptor(); + } + + protected ApiException getApiException(String operationId, HttpResponse response) throws IOException { + String body = response.body() == null ? null : new String(response.body().readAllBytes()); + String message = formatExceptionMessage(operationId, response.statusCode(), body); + return new ApiException(response.statusCode(), message, response.headers(), body); + } + + private String formatExceptionMessage(String operationId, int statusCode, String body) { + if (body == null || body.isEmpty()) { + body = "[no body]"; + } + return operationId + " call failed with: " + statusCode + " - " + body; + } + + /** + * Make a Network-Specific Procedure Call + * Call invokes an arbitrary, network-specific procedure call with network-specific parameters. The guidance for what this endpoint should or could do is purposely left vague. In Ethereum, this could be used to invoke `eth_call` to implement an entire Rosetta API interface for some smart contract that is not parsed by the implementation creator (like a DEX). This endpoint could also be used to provide access to data that does not map to any Rosetta models instead of requiring an integrator to use some network-specific SDK and call some network-specific endpoint (like surfacing staking parameters). Call is NOT a replacement for implementing Rosetta API endpoints or mapping network-specific data to Rosetta models. Rather, it enables developers to build additional Rosetta API interfaces for things they care about without introducing complexity into a base-level Rosetta implementation. Simply put, imagine that the average integrator will use layered Rosetta API implementations that each surfaces unique data. + * @param callRequest (required) + * @return CallResponse + * @throws ApiException if fails to make API call + */ + public CallResponse call(CallRequest callRequest) throws ApiException { + ApiResponse localVarResponse = callWithHttpInfo(callRequest); + return localVarResponse.getData(); + } + + /** + * Make a Network-Specific Procedure Call + * Call invokes an arbitrary, network-specific procedure call with network-specific parameters. The guidance for what this endpoint should or could do is purposely left vague. In Ethereum, this could be used to invoke `eth_call` to implement an entire Rosetta API interface for some smart contract that is not parsed by the implementation creator (like a DEX). This endpoint could also be used to provide access to data that does not map to any Rosetta models instead of requiring an integrator to use some network-specific SDK and call some network-specific endpoint (like surfacing staking parameters). Call is NOT a replacement for implementing Rosetta API endpoints or mapping network-specific data to Rosetta models. Rather, it enables developers to build additional Rosetta API interfaces for things they care about without introducing complexity into a base-level Rosetta implementation. Simply put, imagine that the average integrator will use layered Rosetta API implementations that each surfaces unique data. + * @param callRequest (required) + * @return ApiResponse<CallResponse> + * @throws ApiException if fails to make API call + */ + public ApiResponse callWithHttpInfo(CallRequest callRequest) throws ApiException { + HttpRequest.Builder localVarRequestBuilder = callRequestBuilder(callRequest); + try { + HttpResponse localVarResponse = memberVarHttpClient.send( + localVarRequestBuilder.build(), + HttpResponse.BodyHandlers.ofInputStream()); + if (memberVarResponseInterceptor != null) { + memberVarResponseInterceptor.accept(localVarResponse); + } + try { + if (localVarResponse.statusCode()/ 100 != 2) { + throw getApiException("call", localVarResponse); + } + return new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + memberVarObjectMapper.readValue(localVarResponse.body(), new TypeReference() {}) // closes the InputStream + + ); + } finally { + } + } catch (IOException e) { + throw new ApiException(e); + } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new ApiException(e); + } + } + + private HttpRequest.Builder callRequestBuilder(CallRequest callRequest) throws ApiException { + // verify the required parameter 'callRequest' is set + if (callRequest == null) { + throw new ApiException(400, "Missing the required parameter 'callRequest' when calling call"); + } + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = "/call"; + + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + + localVarRequestBuilder.header("Content-Type", "application/json"); + localVarRequestBuilder.header("Accept", "application/json"); + + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(callRequest); + localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } +} diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/api/ConstructionApi.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/api/ConstructionApi.java new file mode 100644 index 0000000000..7fb054d23f --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/api/ConstructionApi.java @@ -0,0 +1,716 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +package com.radixdlt.api.mesh.generated.api; + +import com.radixdlt.api.mesh.generated.client.ApiClient; +import com.radixdlt.api.mesh.generated.client.ApiException; +import com.radixdlt.api.mesh.generated.client.ApiResponse; +import com.radixdlt.api.mesh.generated.client.Pair; + +import com.radixdlt.api.mesh.generated.models.ConstructionCombineRequest; +import com.radixdlt.api.mesh.generated.models.ConstructionCombineResponse; +import com.radixdlt.api.mesh.generated.models.ConstructionDeriveRequest; +import com.radixdlt.api.mesh.generated.models.ConstructionDeriveResponse; +import com.radixdlt.api.mesh.generated.models.ConstructionHashRequest; +import com.radixdlt.api.mesh.generated.models.ConstructionMetadataRequest; +import com.radixdlt.api.mesh.generated.models.ConstructionMetadataResponse; +import com.radixdlt.api.mesh.generated.models.ConstructionParseRequest; +import com.radixdlt.api.mesh.generated.models.ConstructionParseResponse; +import com.radixdlt.api.mesh.generated.models.ConstructionPayloadsRequest; +import com.radixdlt.api.mesh.generated.models.ConstructionPayloadsResponse; +import com.radixdlt.api.mesh.generated.models.ConstructionPreprocessRequest; +import com.radixdlt.api.mesh.generated.models.ConstructionPreprocessResponse; +import com.radixdlt.api.mesh.generated.models.ConstructionSubmitRequest; +import com.radixdlt.api.mesh.generated.models.Error; +import com.radixdlt.api.mesh.generated.models.TransactionIdentifierResponse; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.time.Duration; + +import java.util.ArrayList; +import java.util.StringJoiner; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Consumer; + +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class ConstructionApi { + private final HttpClient memberVarHttpClient; + private final ObjectMapper memberVarObjectMapper; + private final String memberVarBaseUri; + private final Consumer memberVarInterceptor; + private final Duration memberVarReadTimeout; + private final Consumer> memberVarResponseInterceptor; + private final Consumer> memberVarAsyncResponseInterceptor; + + public ConstructionApi() { + this(new ApiClient()); + } + + public ConstructionApi(ApiClient apiClient) { + memberVarHttpClient = apiClient.getHttpClient(); + memberVarObjectMapper = apiClient.getObjectMapper(); + memberVarBaseUri = apiClient.getBaseUri(); + memberVarInterceptor = apiClient.getRequestInterceptor(); + memberVarReadTimeout = apiClient.getReadTimeout(); + memberVarResponseInterceptor = apiClient.getResponseInterceptor(); + memberVarAsyncResponseInterceptor = apiClient.getAsyncResponseInterceptor(); + } + + protected ApiException getApiException(String operationId, HttpResponse response) throws IOException { + String body = response.body() == null ? null : new String(response.body().readAllBytes()); + String message = formatExceptionMessage(operationId, response.statusCode(), body); + return new ApiException(response.statusCode(), message, response.headers(), body); + } + + private String formatExceptionMessage(String operationId, int statusCode, String body) { + if (body == null || body.isEmpty()) { + body = "[no body]"; + } + return operationId + " call failed with: " + statusCode + " - " + body; + } + + /** + * Create Network Transaction from Signatures + * Combine creates a network-specific transaction from an unsigned transaction and an array of provided signatures. The signed transaction returned from this method will be sent to the `/construction/submit` endpoint by the caller. + * @param constructionCombineRequest (required) + * @return ConstructionCombineResponse + * @throws ApiException if fails to make API call + */ + public ConstructionCombineResponse constructionCombine(ConstructionCombineRequest constructionCombineRequest) throws ApiException { + ApiResponse localVarResponse = constructionCombineWithHttpInfo(constructionCombineRequest); + return localVarResponse.getData(); + } + + /** + * Create Network Transaction from Signatures + * Combine creates a network-specific transaction from an unsigned transaction and an array of provided signatures. The signed transaction returned from this method will be sent to the `/construction/submit` endpoint by the caller. + * @param constructionCombineRequest (required) + * @return ApiResponse<ConstructionCombineResponse> + * @throws ApiException if fails to make API call + */ + public ApiResponse constructionCombineWithHttpInfo(ConstructionCombineRequest constructionCombineRequest) throws ApiException { + HttpRequest.Builder localVarRequestBuilder = constructionCombineRequestBuilder(constructionCombineRequest); + try { + HttpResponse localVarResponse = memberVarHttpClient.send( + localVarRequestBuilder.build(), + HttpResponse.BodyHandlers.ofInputStream()); + if (memberVarResponseInterceptor != null) { + memberVarResponseInterceptor.accept(localVarResponse); + } + try { + if (localVarResponse.statusCode()/ 100 != 2) { + throw getApiException("constructionCombine", localVarResponse); + } + return new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + memberVarObjectMapper.readValue(localVarResponse.body(), new TypeReference() {}) // closes the InputStream + + ); + } finally { + } + } catch (IOException e) { + throw new ApiException(e); + } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new ApiException(e); + } + } + + private HttpRequest.Builder constructionCombineRequestBuilder(ConstructionCombineRequest constructionCombineRequest) throws ApiException { + // verify the required parameter 'constructionCombineRequest' is set + if (constructionCombineRequest == null) { + throw new ApiException(400, "Missing the required parameter 'constructionCombineRequest' when calling constructionCombine"); + } + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = "/construction/combine"; + + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + + localVarRequestBuilder.header("Content-Type", "application/json"); + localVarRequestBuilder.header("Accept", "application/json"); + + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(constructionCombineRequest); + localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } + /** + * Derive an AccountIdentifier from a PublicKey + * Derive returns the AccountIdentifier associated with a public key. Blockchains that require an on-chain action to create an account should not implement this method. + * @param constructionDeriveRequest (required) + * @return ConstructionDeriveResponse + * @throws ApiException if fails to make API call + */ + public ConstructionDeriveResponse constructionDerive(ConstructionDeriveRequest constructionDeriveRequest) throws ApiException { + ApiResponse localVarResponse = constructionDeriveWithHttpInfo(constructionDeriveRequest); + return localVarResponse.getData(); + } + + /** + * Derive an AccountIdentifier from a PublicKey + * Derive returns the AccountIdentifier associated with a public key. Blockchains that require an on-chain action to create an account should not implement this method. + * @param constructionDeriveRequest (required) + * @return ApiResponse<ConstructionDeriveResponse> + * @throws ApiException if fails to make API call + */ + public ApiResponse constructionDeriveWithHttpInfo(ConstructionDeriveRequest constructionDeriveRequest) throws ApiException { + HttpRequest.Builder localVarRequestBuilder = constructionDeriveRequestBuilder(constructionDeriveRequest); + try { + HttpResponse localVarResponse = memberVarHttpClient.send( + localVarRequestBuilder.build(), + HttpResponse.BodyHandlers.ofInputStream()); + if (memberVarResponseInterceptor != null) { + memberVarResponseInterceptor.accept(localVarResponse); + } + try { + if (localVarResponse.statusCode()/ 100 != 2) { + throw getApiException("constructionDerive", localVarResponse); + } + return new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + memberVarObjectMapper.readValue(localVarResponse.body(), new TypeReference() {}) // closes the InputStream + + ); + } finally { + } + } catch (IOException e) { + throw new ApiException(e); + } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new ApiException(e); + } + } + + private HttpRequest.Builder constructionDeriveRequestBuilder(ConstructionDeriveRequest constructionDeriveRequest) throws ApiException { + // verify the required parameter 'constructionDeriveRequest' is set + if (constructionDeriveRequest == null) { + throw new ApiException(400, "Missing the required parameter 'constructionDeriveRequest' when calling constructionDerive"); + } + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = "/construction/derive"; + + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + + localVarRequestBuilder.header("Content-Type", "application/json"); + localVarRequestBuilder.header("Accept", "application/json"); + + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(constructionDeriveRequest); + localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } + /** + * Get the Hash of a Signed Transaction + * TransactionHash returns the network-specific transaction hash for a signed transaction. + * @param constructionHashRequest (required) + * @return TransactionIdentifierResponse + * @throws ApiException if fails to make API call + */ + public TransactionIdentifierResponse constructionHash(ConstructionHashRequest constructionHashRequest) throws ApiException { + ApiResponse localVarResponse = constructionHashWithHttpInfo(constructionHashRequest); + return localVarResponse.getData(); + } + + /** + * Get the Hash of a Signed Transaction + * TransactionHash returns the network-specific transaction hash for a signed transaction. + * @param constructionHashRequest (required) + * @return ApiResponse<TransactionIdentifierResponse> + * @throws ApiException if fails to make API call + */ + public ApiResponse constructionHashWithHttpInfo(ConstructionHashRequest constructionHashRequest) throws ApiException { + HttpRequest.Builder localVarRequestBuilder = constructionHashRequestBuilder(constructionHashRequest); + try { + HttpResponse localVarResponse = memberVarHttpClient.send( + localVarRequestBuilder.build(), + HttpResponse.BodyHandlers.ofInputStream()); + if (memberVarResponseInterceptor != null) { + memberVarResponseInterceptor.accept(localVarResponse); + } + try { + if (localVarResponse.statusCode()/ 100 != 2) { + throw getApiException("constructionHash", localVarResponse); + } + return new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + memberVarObjectMapper.readValue(localVarResponse.body(), new TypeReference() {}) // closes the InputStream + + ); + } finally { + } + } catch (IOException e) { + throw new ApiException(e); + } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new ApiException(e); + } + } + + private HttpRequest.Builder constructionHashRequestBuilder(ConstructionHashRequest constructionHashRequest) throws ApiException { + // verify the required parameter 'constructionHashRequest' is set + if (constructionHashRequest == null) { + throw new ApiException(400, "Missing the required parameter 'constructionHashRequest' when calling constructionHash"); + } + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = "/construction/hash"; + + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + + localVarRequestBuilder.header("Content-Type", "application/json"); + localVarRequestBuilder.header("Accept", "application/json"); + + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(constructionHashRequest); + localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } + /** + * Get Metadata for Transaction Construction + * Get any information required to construct a transaction for a specific network. Metadata returned here could be a recent hash to use, an account sequence number, or even arbitrary chain state. The request used when calling this endpoint is created by calling `/construction/preprocess` in an offline environment. You should NEVER assume that the request sent to this endpoint will be created by the caller or populated with any custom parameters. This must occur in `/construction/preprocess`. It is important to clarify that this endpoint should not pre-construct any transactions for the client (this should happen in `/construction/payloads`). This endpoint is left purposely unstructured because of the wide scope of metadata that could be required. + * @param constructionMetadataRequest (required) + * @return ConstructionMetadataResponse + * @throws ApiException if fails to make API call + */ + public ConstructionMetadataResponse constructionMetadata(ConstructionMetadataRequest constructionMetadataRequest) throws ApiException { + ApiResponse localVarResponse = constructionMetadataWithHttpInfo(constructionMetadataRequest); + return localVarResponse.getData(); + } + + /** + * Get Metadata for Transaction Construction + * Get any information required to construct a transaction for a specific network. Metadata returned here could be a recent hash to use, an account sequence number, or even arbitrary chain state. The request used when calling this endpoint is created by calling `/construction/preprocess` in an offline environment. You should NEVER assume that the request sent to this endpoint will be created by the caller or populated with any custom parameters. This must occur in `/construction/preprocess`. It is important to clarify that this endpoint should not pre-construct any transactions for the client (this should happen in `/construction/payloads`). This endpoint is left purposely unstructured because of the wide scope of metadata that could be required. + * @param constructionMetadataRequest (required) + * @return ApiResponse<ConstructionMetadataResponse> + * @throws ApiException if fails to make API call + */ + public ApiResponse constructionMetadataWithHttpInfo(ConstructionMetadataRequest constructionMetadataRequest) throws ApiException { + HttpRequest.Builder localVarRequestBuilder = constructionMetadataRequestBuilder(constructionMetadataRequest); + try { + HttpResponse localVarResponse = memberVarHttpClient.send( + localVarRequestBuilder.build(), + HttpResponse.BodyHandlers.ofInputStream()); + if (memberVarResponseInterceptor != null) { + memberVarResponseInterceptor.accept(localVarResponse); + } + try { + if (localVarResponse.statusCode()/ 100 != 2) { + throw getApiException("constructionMetadata", localVarResponse); + } + return new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + memberVarObjectMapper.readValue(localVarResponse.body(), new TypeReference() {}) // closes the InputStream + + ); + } finally { + } + } catch (IOException e) { + throw new ApiException(e); + } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new ApiException(e); + } + } + + private HttpRequest.Builder constructionMetadataRequestBuilder(ConstructionMetadataRequest constructionMetadataRequest) throws ApiException { + // verify the required parameter 'constructionMetadataRequest' is set + if (constructionMetadataRequest == null) { + throw new ApiException(400, "Missing the required parameter 'constructionMetadataRequest' when calling constructionMetadata"); + } + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = "/construction/metadata"; + + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + + localVarRequestBuilder.header("Content-Type", "application/json"); + localVarRequestBuilder.header("Accept", "application/json"); + + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(constructionMetadataRequest); + localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } + /** + * Parse a Transaction + * Parse is called on both unsigned and signed transactions to understand the intent of the formulated transaction. This is run as a sanity check before signing (after `/construction/payloads`) and before broadcast (after `/construction/combine`). + * @param constructionParseRequest (required) + * @return ConstructionParseResponse + * @throws ApiException if fails to make API call + */ + public ConstructionParseResponse constructionParse(ConstructionParseRequest constructionParseRequest) throws ApiException { + ApiResponse localVarResponse = constructionParseWithHttpInfo(constructionParseRequest); + return localVarResponse.getData(); + } + + /** + * Parse a Transaction + * Parse is called on both unsigned and signed transactions to understand the intent of the formulated transaction. This is run as a sanity check before signing (after `/construction/payloads`) and before broadcast (after `/construction/combine`). + * @param constructionParseRequest (required) + * @return ApiResponse<ConstructionParseResponse> + * @throws ApiException if fails to make API call + */ + public ApiResponse constructionParseWithHttpInfo(ConstructionParseRequest constructionParseRequest) throws ApiException { + HttpRequest.Builder localVarRequestBuilder = constructionParseRequestBuilder(constructionParseRequest); + try { + HttpResponse localVarResponse = memberVarHttpClient.send( + localVarRequestBuilder.build(), + HttpResponse.BodyHandlers.ofInputStream()); + if (memberVarResponseInterceptor != null) { + memberVarResponseInterceptor.accept(localVarResponse); + } + try { + if (localVarResponse.statusCode()/ 100 != 2) { + throw getApiException("constructionParse", localVarResponse); + } + return new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + memberVarObjectMapper.readValue(localVarResponse.body(), new TypeReference() {}) // closes the InputStream + + ); + } finally { + } + } catch (IOException e) { + throw new ApiException(e); + } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new ApiException(e); + } + } + + private HttpRequest.Builder constructionParseRequestBuilder(ConstructionParseRequest constructionParseRequest) throws ApiException { + // verify the required parameter 'constructionParseRequest' is set + if (constructionParseRequest == null) { + throw new ApiException(400, "Missing the required parameter 'constructionParseRequest' when calling constructionParse"); + } + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = "/construction/parse"; + + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + + localVarRequestBuilder.header("Content-Type", "application/json"); + localVarRequestBuilder.header("Accept", "application/json"); + + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(constructionParseRequest); + localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } + /** + * Generate an Unsigned Transaction and Signing Payloads + * Payloads is called with an array of operations and the response from `/construction/metadata`. It returns an unsigned transaction blob and a collection of payloads that must be signed by particular AccountIdentifiers using a certain SignatureType. The array of operations provided in transaction construction often times can not specify all \"effects\" of a transaction (consider invoked transactions in Ethereum). However, they can deterministically specify the \"intent\" of the transaction, which is sufficient for construction. For this reason, parsing the corresponding transaction in the Data API (when it lands on chain) will contain a superset of whatever operations were provided during construction. + * @param constructionPayloadsRequest (required) + * @return ConstructionPayloadsResponse + * @throws ApiException if fails to make API call + */ + public ConstructionPayloadsResponse constructionPayloads(ConstructionPayloadsRequest constructionPayloadsRequest) throws ApiException { + ApiResponse localVarResponse = constructionPayloadsWithHttpInfo(constructionPayloadsRequest); + return localVarResponse.getData(); + } + + /** + * Generate an Unsigned Transaction and Signing Payloads + * Payloads is called with an array of operations and the response from `/construction/metadata`. It returns an unsigned transaction blob and a collection of payloads that must be signed by particular AccountIdentifiers using a certain SignatureType. The array of operations provided in transaction construction often times can not specify all \"effects\" of a transaction (consider invoked transactions in Ethereum). However, they can deterministically specify the \"intent\" of the transaction, which is sufficient for construction. For this reason, parsing the corresponding transaction in the Data API (when it lands on chain) will contain a superset of whatever operations were provided during construction. + * @param constructionPayloadsRequest (required) + * @return ApiResponse<ConstructionPayloadsResponse> + * @throws ApiException if fails to make API call + */ + public ApiResponse constructionPayloadsWithHttpInfo(ConstructionPayloadsRequest constructionPayloadsRequest) throws ApiException { + HttpRequest.Builder localVarRequestBuilder = constructionPayloadsRequestBuilder(constructionPayloadsRequest); + try { + HttpResponse localVarResponse = memberVarHttpClient.send( + localVarRequestBuilder.build(), + HttpResponse.BodyHandlers.ofInputStream()); + if (memberVarResponseInterceptor != null) { + memberVarResponseInterceptor.accept(localVarResponse); + } + try { + if (localVarResponse.statusCode()/ 100 != 2) { + throw getApiException("constructionPayloads", localVarResponse); + } + return new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + memberVarObjectMapper.readValue(localVarResponse.body(), new TypeReference() {}) // closes the InputStream + + ); + } finally { + } + } catch (IOException e) { + throw new ApiException(e); + } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new ApiException(e); + } + } + + private HttpRequest.Builder constructionPayloadsRequestBuilder(ConstructionPayloadsRequest constructionPayloadsRequest) throws ApiException { + // verify the required parameter 'constructionPayloadsRequest' is set + if (constructionPayloadsRequest == null) { + throw new ApiException(400, "Missing the required parameter 'constructionPayloadsRequest' when calling constructionPayloads"); + } + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = "/construction/payloads"; + + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + + localVarRequestBuilder.header("Content-Type", "application/json"); + localVarRequestBuilder.header("Accept", "application/json"); + + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(constructionPayloadsRequest); + localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } + /** + * Create a Request to Fetch Metadata + * Preprocess is called prior to `/construction/payloads` to construct a request for any metadata that is needed for transaction construction given (i.e. account nonce). The `options` object returned from this endpoint will be sent to the `/construction/metadata` endpoint UNMODIFIED by the caller (in an offline execution environment). If your Construction API implementation has configuration options, they MUST be specified in the `/construction/preprocess` request (in the `metadata` field). + * @param constructionPreprocessRequest (required) + * @return ConstructionPreprocessResponse + * @throws ApiException if fails to make API call + */ + public ConstructionPreprocessResponse constructionPreprocess(ConstructionPreprocessRequest constructionPreprocessRequest) throws ApiException { + ApiResponse localVarResponse = constructionPreprocessWithHttpInfo(constructionPreprocessRequest); + return localVarResponse.getData(); + } + + /** + * Create a Request to Fetch Metadata + * Preprocess is called prior to `/construction/payloads` to construct a request for any metadata that is needed for transaction construction given (i.e. account nonce). The `options` object returned from this endpoint will be sent to the `/construction/metadata` endpoint UNMODIFIED by the caller (in an offline execution environment). If your Construction API implementation has configuration options, they MUST be specified in the `/construction/preprocess` request (in the `metadata` field). + * @param constructionPreprocessRequest (required) + * @return ApiResponse<ConstructionPreprocessResponse> + * @throws ApiException if fails to make API call + */ + public ApiResponse constructionPreprocessWithHttpInfo(ConstructionPreprocessRequest constructionPreprocessRequest) throws ApiException { + HttpRequest.Builder localVarRequestBuilder = constructionPreprocessRequestBuilder(constructionPreprocessRequest); + try { + HttpResponse localVarResponse = memberVarHttpClient.send( + localVarRequestBuilder.build(), + HttpResponse.BodyHandlers.ofInputStream()); + if (memberVarResponseInterceptor != null) { + memberVarResponseInterceptor.accept(localVarResponse); + } + try { + if (localVarResponse.statusCode()/ 100 != 2) { + throw getApiException("constructionPreprocess", localVarResponse); + } + return new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + memberVarObjectMapper.readValue(localVarResponse.body(), new TypeReference() {}) // closes the InputStream + + ); + } finally { + } + } catch (IOException e) { + throw new ApiException(e); + } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new ApiException(e); + } + } + + private HttpRequest.Builder constructionPreprocessRequestBuilder(ConstructionPreprocessRequest constructionPreprocessRequest) throws ApiException { + // verify the required parameter 'constructionPreprocessRequest' is set + if (constructionPreprocessRequest == null) { + throw new ApiException(400, "Missing the required parameter 'constructionPreprocessRequest' when calling constructionPreprocess"); + } + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = "/construction/preprocess"; + + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + + localVarRequestBuilder.header("Content-Type", "application/json"); + localVarRequestBuilder.header("Accept", "application/json"); + + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(constructionPreprocessRequest); + localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } + /** + * Submit a Signed Transaction + * Submit a pre-signed transaction to the node. This call should not block on the transaction being included in a block. Rather, it should return immediately with an indication of whether or not the transaction was included in the mempool. The transaction submission response should only return a 200 status if the submitted transaction could be included in the mempool. Otherwise, it should return an error. + * @param constructionSubmitRequest (required) + * @return TransactionIdentifierResponse + * @throws ApiException if fails to make API call + */ + public TransactionIdentifierResponse constructionSubmit(ConstructionSubmitRequest constructionSubmitRequest) throws ApiException { + ApiResponse localVarResponse = constructionSubmitWithHttpInfo(constructionSubmitRequest); + return localVarResponse.getData(); + } + + /** + * Submit a Signed Transaction + * Submit a pre-signed transaction to the node. This call should not block on the transaction being included in a block. Rather, it should return immediately with an indication of whether or not the transaction was included in the mempool. The transaction submission response should only return a 200 status if the submitted transaction could be included in the mempool. Otherwise, it should return an error. + * @param constructionSubmitRequest (required) + * @return ApiResponse<TransactionIdentifierResponse> + * @throws ApiException if fails to make API call + */ + public ApiResponse constructionSubmitWithHttpInfo(ConstructionSubmitRequest constructionSubmitRequest) throws ApiException { + HttpRequest.Builder localVarRequestBuilder = constructionSubmitRequestBuilder(constructionSubmitRequest); + try { + HttpResponse localVarResponse = memberVarHttpClient.send( + localVarRequestBuilder.build(), + HttpResponse.BodyHandlers.ofInputStream()); + if (memberVarResponseInterceptor != null) { + memberVarResponseInterceptor.accept(localVarResponse); + } + try { + if (localVarResponse.statusCode()/ 100 != 2) { + throw getApiException("constructionSubmit", localVarResponse); + } + return new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + memberVarObjectMapper.readValue(localVarResponse.body(), new TypeReference() {}) // closes the InputStream + + ); + } finally { + } + } catch (IOException e) { + throw new ApiException(e); + } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new ApiException(e); + } + } + + private HttpRequest.Builder constructionSubmitRequestBuilder(ConstructionSubmitRequest constructionSubmitRequest) throws ApiException { + // verify the required parameter 'constructionSubmitRequest' is set + if (constructionSubmitRequest == null) { + throw new ApiException(400, "Missing the required parameter 'constructionSubmitRequest' when calling constructionSubmit"); + } + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = "/construction/submit"; + + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + + localVarRequestBuilder.header("Content-Type", "application/json"); + localVarRequestBuilder.header("Accept", "application/json"); + + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(constructionSubmitRequest); + localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } +} diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/api/EventsApi.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/api/EventsApi.java new file mode 100644 index 0000000000..5fce110655 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/api/EventsApi.java @@ -0,0 +1,157 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +package com.radixdlt.api.mesh.generated.api; + +import com.radixdlt.api.mesh.generated.client.ApiClient; +import com.radixdlt.api.mesh.generated.client.ApiException; +import com.radixdlt.api.mesh.generated.client.ApiResponse; +import com.radixdlt.api.mesh.generated.client.Pair; + +import com.radixdlt.api.mesh.generated.models.Error; +import com.radixdlt.api.mesh.generated.models.EventsBlocksRequest; +import com.radixdlt.api.mesh.generated.models.EventsBlocksResponse; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.time.Duration; + +import java.util.ArrayList; +import java.util.StringJoiner; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Consumer; + +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class EventsApi { + private final HttpClient memberVarHttpClient; + private final ObjectMapper memberVarObjectMapper; + private final String memberVarBaseUri; + private final Consumer memberVarInterceptor; + private final Duration memberVarReadTimeout; + private final Consumer> memberVarResponseInterceptor; + private final Consumer> memberVarAsyncResponseInterceptor; + + public EventsApi() { + this(new ApiClient()); + } + + public EventsApi(ApiClient apiClient) { + memberVarHttpClient = apiClient.getHttpClient(); + memberVarObjectMapper = apiClient.getObjectMapper(); + memberVarBaseUri = apiClient.getBaseUri(); + memberVarInterceptor = apiClient.getRequestInterceptor(); + memberVarReadTimeout = apiClient.getReadTimeout(); + memberVarResponseInterceptor = apiClient.getResponseInterceptor(); + memberVarAsyncResponseInterceptor = apiClient.getAsyncResponseInterceptor(); + } + + protected ApiException getApiException(String operationId, HttpResponse response) throws IOException { + String body = response.body() == null ? null : new String(response.body().readAllBytes()); + String message = formatExceptionMessage(operationId, response.statusCode(), body); + return new ApiException(response.statusCode(), message, response.headers(), body); + } + + private String formatExceptionMessage(String operationId, int statusCode, String body) { + if (body == null || body.isEmpty()) { + body = "[no body]"; + } + return operationId + " call failed with: " + statusCode + " - " + body; + } + + /** + * [INDEXER] Get a range of BlockEvents + * `/events/blocks` allows the caller to query a sequence of BlockEvents indicating which blocks were added and removed from storage to reach the current state. Following BlockEvents allows lightweight clients to update their state without needing to implement their own syncing logic (like finding the common parent in a reorg). `/events/blocks` is considered an \"indexer\" endpoint and Rosetta implementations are not required to complete it to adhere to the Rosetta spec. However, any Rosetta \"indexer\" MUST support this endpoint. + * @param eventsBlocksRequest (required) + * @return EventsBlocksResponse + * @throws ApiException if fails to make API call + */ + public EventsBlocksResponse eventsBlocks(EventsBlocksRequest eventsBlocksRequest) throws ApiException { + ApiResponse localVarResponse = eventsBlocksWithHttpInfo(eventsBlocksRequest); + return localVarResponse.getData(); + } + + /** + * [INDEXER] Get a range of BlockEvents + * `/events/blocks` allows the caller to query a sequence of BlockEvents indicating which blocks were added and removed from storage to reach the current state. Following BlockEvents allows lightweight clients to update their state without needing to implement their own syncing logic (like finding the common parent in a reorg). `/events/blocks` is considered an \"indexer\" endpoint and Rosetta implementations are not required to complete it to adhere to the Rosetta spec. However, any Rosetta \"indexer\" MUST support this endpoint. + * @param eventsBlocksRequest (required) + * @return ApiResponse<EventsBlocksResponse> + * @throws ApiException if fails to make API call + */ + public ApiResponse eventsBlocksWithHttpInfo(EventsBlocksRequest eventsBlocksRequest) throws ApiException { + HttpRequest.Builder localVarRequestBuilder = eventsBlocksRequestBuilder(eventsBlocksRequest); + try { + HttpResponse localVarResponse = memberVarHttpClient.send( + localVarRequestBuilder.build(), + HttpResponse.BodyHandlers.ofInputStream()); + if (memberVarResponseInterceptor != null) { + memberVarResponseInterceptor.accept(localVarResponse); + } + try { + if (localVarResponse.statusCode()/ 100 != 2) { + throw getApiException("eventsBlocks", localVarResponse); + } + return new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + memberVarObjectMapper.readValue(localVarResponse.body(), new TypeReference() {}) // closes the InputStream + + ); + } finally { + } + } catch (IOException e) { + throw new ApiException(e); + } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new ApiException(e); + } + } + + private HttpRequest.Builder eventsBlocksRequestBuilder(EventsBlocksRequest eventsBlocksRequest) throws ApiException { + // verify the required parameter 'eventsBlocksRequest' is set + if (eventsBlocksRequest == null) { + throw new ApiException(400, "Missing the required parameter 'eventsBlocksRequest' when calling eventsBlocks"); + } + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = "/events/blocks"; + + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + + localVarRequestBuilder.header("Content-Type", "application/json"); + localVarRequestBuilder.header("Accept", "application/json"); + + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(eventsBlocksRequest); + localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } +} diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/api/MempoolApi.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/api/MempoolApi.java new file mode 100644 index 0000000000..bb6302dc3f --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/api/MempoolApi.java @@ -0,0 +1,237 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +package com.radixdlt.api.mesh.generated.api; + +import com.radixdlt.api.mesh.generated.client.ApiClient; +import com.radixdlt.api.mesh.generated.client.ApiException; +import com.radixdlt.api.mesh.generated.client.ApiResponse; +import com.radixdlt.api.mesh.generated.client.Pair; + +import com.radixdlt.api.mesh.generated.models.Error; +import com.radixdlt.api.mesh.generated.models.MempoolResponse; +import com.radixdlt.api.mesh.generated.models.MempoolTransactionRequest; +import com.radixdlt.api.mesh.generated.models.MempoolTransactionResponse; +import com.radixdlt.api.mesh.generated.models.NetworkRequest; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.time.Duration; + +import java.util.ArrayList; +import java.util.StringJoiner; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Consumer; + +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class MempoolApi { + private final HttpClient memberVarHttpClient; + private final ObjectMapper memberVarObjectMapper; + private final String memberVarBaseUri; + private final Consumer memberVarInterceptor; + private final Duration memberVarReadTimeout; + private final Consumer> memberVarResponseInterceptor; + private final Consumer> memberVarAsyncResponseInterceptor; + + public MempoolApi() { + this(new ApiClient()); + } + + public MempoolApi(ApiClient apiClient) { + memberVarHttpClient = apiClient.getHttpClient(); + memberVarObjectMapper = apiClient.getObjectMapper(); + memberVarBaseUri = apiClient.getBaseUri(); + memberVarInterceptor = apiClient.getRequestInterceptor(); + memberVarReadTimeout = apiClient.getReadTimeout(); + memberVarResponseInterceptor = apiClient.getResponseInterceptor(); + memberVarAsyncResponseInterceptor = apiClient.getAsyncResponseInterceptor(); + } + + protected ApiException getApiException(String operationId, HttpResponse response) throws IOException { + String body = response.body() == null ? null : new String(response.body().readAllBytes()); + String message = formatExceptionMessage(operationId, response.statusCode(), body); + return new ApiException(response.statusCode(), message, response.headers(), body); + } + + private String formatExceptionMessage(String operationId, int statusCode, String body) { + if (body == null || body.isEmpty()) { + body = "[no body]"; + } + return operationId + " call failed with: " + statusCode + " - " + body; + } + + /** + * Get All Mempool Transactions + * Get all Transaction Identifiers in the mempool + * @param networkRequest (required) + * @return MempoolResponse + * @throws ApiException if fails to make API call + */ + public MempoolResponse mempool(NetworkRequest networkRequest) throws ApiException { + ApiResponse localVarResponse = mempoolWithHttpInfo(networkRequest); + return localVarResponse.getData(); + } + + /** + * Get All Mempool Transactions + * Get all Transaction Identifiers in the mempool + * @param networkRequest (required) + * @return ApiResponse<MempoolResponse> + * @throws ApiException if fails to make API call + */ + public ApiResponse mempoolWithHttpInfo(NetworkRequest networkRequest) throws ApiException { + HttpRequest.Builder localVarRequestBuilder = mempoolRequestBuilder(networkRequest); + try { + HttpResponse localVarResponse = memberVarHttpClient.send( + localVarRequestBuilder.build(), + HttpResponse.BodyHandlers.ofInputStream()); + if (memberVarResponseInterceptor != null) { + memberVarResponseInterceptor.accept(localVarResponse); + } + try { + if (localVarResponse.statusCode()/ 100 != 2) { + throw getApiException("mempool", localVarResponse); + } + return new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + memberVarObjectMapper.readValue(localVarResponse.body(), new TypeReference() {}) // closes the InputStream + + ); + } finally { + } + } catch (IOException e) { + throw new ApiException(e); + } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new ApiException(e); + } + } + + private HttpRequest.Builder mempoolRequestBuilder(NetworkRequest networkRequest) throws ApiException { + // verify the required parameter 'networkRequest' is set + if (networkRequest == null) { + throw new ApiException(400, "Missing the required parameter 'networkRequest' when calling mempool"); + } + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = "/mempool"; + + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + + localVarRequestBuilder.header("Content-Type", "application/json"); + localVarRequestBuilder.header("Accept", "application/json"); + + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(networkRequest); + localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } + /** + * Get a Mempool Transaction + * Get a transaction in the mempool by its Transaction Identifier. This is a separate request than fetching a block transaction (/block/transaction) because some blockchain nodes need to know that a transaction query is for something in the mempool instead of a transaction in a block. Transactions may not be fully parsable until they are in a block (ex: may not be possible to determine the fee to pay before a transaction is executed). On this endpoint, it is ok that returned transactions are only estimates of what may actually be included in a block. + * @param mempoolTransactionRequest (required) + * @return MempoolTransactionResponse + * @throws ApiException if fails to make API call + */ + public MempoolTransactionResponse mempoolTransaction(MempoolTransactionRequest mempoolTransactionRequest) throws ApiException { + ApiResponse localVarResponse = mempoolTransactionWithHttpInfo(mempoolTransactionRequest); + return localVarResponse.getData(); + } + + /** + * Get a Mempool Transaction + * Get a transaction in the mempool by its Transaction Identifier. This is a separate request than fetching a block transaction (/block/transaction) because some blockchain nodes need to know that a transaction query is for something in the mempool instead of a transaction in a block. Transactions may not be fully parsable until they are in a block (ex: may not be possible to determine the fee to pay before a transaction is executed). On this endpoint, it is ok that returned transactions are only estimates of what may actually be included in a block. + * @param mempoolTransactionRequest (required) + * @return ApiResponse<MempoolTransactionResponse> + * @throws ApiException if fails to make API call + */ + public ApiResponse mempoolTransactionWithHttpInfo(MempoolTransactionRequest mempoolTransactionRequest) throws ApiException { + HttpRequest.Builder localVarRequestBuilder = mempoolTransactionRequestBuilder(mempoolTransactionRequest); + try { + HttpResponse localVarResponse = memberVarHttpClient.send( + localVarRequestBuilder.build(), + HttpResponse.BodyHandlers.ofInputStream()); + if (memberVarResponseInterceptor != null) { + memberVarResponseInterceptor.accept(localVarResponse); + } + try { + if (localVarResponse.statusCode()/ 100 != 2) { + throw getApiException("mempoolTransaction", localVarResponse); + } + return new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + memberVarObjectMapper.readValue(localVarResponse.body(), new TypeReference() {}) // closes the InputStream + + ); + } finally { + } + } catch (IOException e) { + throw new ApiException(e); + } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new ApiException(e); + } + } + + private HttpRequest.Builder mempoolTransactionRequestBuilder(MempoolTransactionRequest mempoolTransactionRequest) throws ApiException { + // verify the required parameter 'mempoolTransactionRequest' is set + if (mempoolTransactionRequest == null) { + throw new ApiException(400, "Missing the required parameter 'mempoolTransactionRequest' when calling mempoolTransaction"); + } + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = "/mempool/transaction"; + + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + + localVarRequestBuilder.header("Content-Type", "application/json"); + localVarRequestBuilder.header("Accept", "application/json"); + + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(mempoolTransactionRequest); + localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } +} diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/api/NetworkApi.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/api/NetworkApi.java new file mode 100644 index 0000000000..c95c14bf8f --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/api/NetworkApi.java @@ -0,0 +1,316 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +package com.radixdlt.api.mesh.generated.api; + +import com.radixdlt.api.mesh.generated.client.ApiClient; +import com.radixdlt.api.mesh.generated.client.ApiException; +import com.radixdlt.api.mesh.generated.client.ApiResponse; +import com.radixdlt.api.mesh.generated.client.Pair; + +import com.radixdlt.api.mesh.generated.models.Error; +import com.radixdlt.api.mesh.generated.models.MetadataRequest; +import com.radixdlt.api.mesh.generated.models.NetworkListResponse; +import com.radixdlt.api.mesh.generated.models.NetworkOptionsResponse; +import com.radixdlt.api.mesh.generated.models.NetworkRequest; +import com.radixdlt.api.mesh.generated.models.NetworkStatusResponse; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.time.Duration; + +import java.util.ArrayList; +import java.util.StringJoiner; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Consumer; + +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class NetworkApi { + private final HttpClient memberVarHttpClient; + private final ObjectMapper memberVarObjectMapper; + private final String memberVarBaseUri; + private final Consumer memberVarInterceptor; + private final Duration memberVarReadTimeout; + private final Consumer> memberVarResponseInterceptor; + private final Consumer> memberVarAsyncResponseInterceptor; + + public NetworkApi() { + this(new ApiClient()); + } + + public NetworkApi(ApiClient apiClient) { + memberVarHttpClient = apiClient.getHttpClient(); + memberVarObjectMapper = apiClient.getObjectMapper(); + memberVarBaseUri = apiClient.getBaseUri(); + memberVarInterceptor = apiClient.getRequestInterceptor(); + memberVarReadTimeout = apiClient.getReadTimeout(); + memberVarResponseInterceptor = apiClient.getResponseInterceptor(); + memberVarAsyncResponseInterceptor = apiClient.getAsyncResponseInterceptor(); + } + + protected ApiException getApiException(String operationId, HttpResponse response) throws IOException { + String body = response.body() == null ? null : new String(response.body().readAllBytes()); + String message = formatExceptionMessage(operationId, response.statusCode(), body); + return new ApiException(response.statusCode(), message, response.headers(), body); + } + + private String formatExceptionMessage(String operationId, int statusCode, String body) { + if (body == null || body.isEmpty()) { + body = "[no body]"; + } + return operationId + " call failed with: " + statusCode + " - " + body; + } + + /** + * Get List of Available Networks + * This endpoint returns a list of NetworkIdentifiers that the Rosetta server supports. + * @param metadataRequest (required) + * @return NetworkListResponse + * @throws ApiException if fails to make API call + */ + public NetworkListResponse networkList(MetadataRequest metadataRequest) throws ApiException { + ApiResponse localVarResponse = networkListWithHttpInfo(metadataRequest); + return localVarResponse.getData(); + } + + /** + * Get List of Available Networks + * This endpoint returns a list of NetworkIdentifiers that the Rosetta server supports. + * @param metadataRequest (required) + * @return ApiResponse<NetworkListResponse> + * @throws ApiException if fails to make API call + */ + public ApiResponse networkListWithHttpInfo(MetadataRequest metadataRequest) throws ApiException { + HttpRequest.Builder localVarRequestBuilder = networkListRequestBuilder(metadataRequest); + try { + HttpResponse localVarResponse = memberVarHttpClient.send( + localVarRequestBuilder.build(), + HttpResponse.BodyHandlers.ofInputStream()); + if (memberVarResponseInterceptor != null) { + memberVarResponseInterceptor.accept(localVarResponse); + } + try { + if (localVarResponse.statusCode()/ 100 != 2) { + throw getApiException("networkList", localVarResponse); + } + return new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + memberVarObjectMapper.readValue(localVarResponse.body(), new TypeReference() {}) // closes the InputStream + + ); + } finally { + } + } catch (IOException e) { + throw new ApiException(e); + } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new ApiException(e); + } + } + + private HttpRequest.Builder networkListRequestBuilder(MetadataRequest metadataRequest) throws ApiException { + // verify the required parameter 'metadataRequest' is set + if (metadataRequest == null) { + throw new ApiException(400, "Missing the required parameter 'metadataRequest' when calling networkList"); + } + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = "/network/list"; + + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + + localVarRequestBuilder.header("Content-Type", "application/json"); + localVarRequestBuilder.header("Accept", "application/json"); + + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(metadataRequest); + localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } + /** + * Get Network Options + * This endpoint returns the version information and allowed network-specific types for a NetworkIdentifier. Any NetworkIdentifier returned by /network/list should be accessible here. Because options are retrievable in the context of a NetworkIdentifier, it is possible to define unique options for each network. + * @param networkRequest (required) + * @return NetworkOptionsResponse + * @throws ApiException if fails to make API call + */ + public NetworkOptionsResponse networkOptions(NetworkRequest networkRequest) throws ApiException { + ApiResponse localVarResponse = networkOptionsWithHttpInfo(networkRequest); + return localVarResponse.getData(); + } + + /** + * Get Network Options + * This endpoint returns the version information and allowed network-specific types for a NetworkIdentifier. Any NetworkIdentifier returned by /network/list should be accessible here. Because options are retrievable in the context of a NetworkIdentifier, it is possible to define unique options for each network. + * @param networkRequest (required) + * @return ApiResponse<NetworkOptionsResponse> + * @throws ApiException if fails to make API call + */ + public ApiResponse networkOptionsWithHttpInfo(NetworkRequest networkRequest) throws ApiException { + HttpRequest.Builder localVarRequestBuilder = networkOptionsRequestBuilder(networkRequest); + try { + HttpResponse localVarResponse = memberVarHttpClient.send( + localVarRequestBuilder.build(), + HttpResponse.BodyHandlers.ofInputStream()); + if (memberVarResponseInterceptor != null) { + memberVarResponseInterceptor.accept(localVarResponse); + } + try { + if (localVarResponse.statusCode()/ 100 != 2) { + throw getApiException("networkOptions", localVarResponse); + } + return new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + memberVarObjectMapper.readValue(localVarResponse.body(), new TypeReference() {}) // closes the InputStream + + ); + } finally { + } + } catch (IOException e) { + throw new ApiException(e); + } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new ApiException(e); + } + } + + private HttpRequest.Builder networkOptionsRequestBuilder(NetworkRequest networkRequest) throws ApiException { + // verify the required parameter 'networkRequest' is set + if (networkRequest == null) { + throw new ApiException(400, "Missing the required parameter 'networkRequest' when calling networkOptions"); + } + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = "/network/options"; + + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + + localVarRequestBuilder.header("Content-Type", "application/json"); + localVarRequestBuilder.header("Accept", "application/json"); + + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(networkRequest); + localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } + /** + * Get Network Status + * This endpoint returns the current status of the network requested. Any NetworkIdentifier returned by /network/list should be accessible here. + * @param networkRequest (required) + * @return NetworkStatusResponse + * @throws ApiException if fails to make API call + */ + public NetworkStatusResponse networkStatus(NetworkRequest networkRequest) throws ApiException { + ApiResponse localVarResponse = networkStatusWithHttpInfo(networkRequest); + return localVarResponse.getData(); + } + + /** + * Get Network Status + * This endpoint returns the current status of the network requested. Any NetworkIdentifier returned by /network/list should be accessible here. + * @param networkRequest (required) + * @return ApiResponse<NetworkStatusResponse> + * @throws ApiException if fails to make API call + */ + public ApiResponse networkStatusWithHttpInfo(NetworkRequest networkRequest) throws ApiException { + HttpRequest.Builder localVarRequestBuilder = networkStatusRequestBuilder(networkRequest); + try { + HttpResponse localVarResponse = memberVarHttpClient.send( + localVarRequestBuilder.build(), + HttpResponse.BodyHandlers.ofInputStream()); + if (memberVarResponseInterceptor != null) { + memberVarResponseInterceptor.accept(localVarResponse); + } + try { + if (localVarResponse.statusCode()/ 100 != 2) { + throw getApiException("networkStatus", localVarResponse); + } + return new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + memberVarObjectMapper.readValue(localVarResponse.body(), new TypeReference() {}) // closes the InputStream + + ); + } finally { + } + } catch (IOException e) { + throw new ApiException(e); + } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new ApiException(e); + } + } + + private HttpRequest.Builder networkStatusRequestBuilder(NetworkRequest networkRequest) throws ApiException { + // verify the required parameter 'networkRequest' is set + if (networkRequest == null) { + throw new ApiException(400, "Missing the required parameter 'networkRequest' when calling networkStatus"); + } + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = "/network/status"; + + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + + localVarRequestBuilder.header("Content-Type", "application/json"); + localVarRequestBuilder.header("Accept", "application/json"); + + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(networkRequest); + localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } +} diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/api/SearchApi.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/api/SearchApi.java new file mode 100644 index 0000000000..7a4960d19c --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/api/SearchApi.java @@ -0,0 +1,157 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +package com.radixdlt.api.mesh.generated.api; + +import com.radixdlt.api.mesh.generated.client.ApiClient; +import com.radixdlt.api.mesh.generated.client.ApiException; +import com.radixdlt.api.mesh.generated.client.ApiResponse; +import com.radixdlt.api.mesh.generated.client.Pair; + +import com.radixdlt.api.mesh.generated.models.Error; +import com.radixdlt.api.mesh.generated.models.SearchTransactionsRequest; +import com.radixdlt.api.mesh.generated.models.SearchTransactionsResponse; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.time.Duration; + +import java.util.ArrayList; +import java.util.StringJoiner; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Consumer; + +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class SearchApi { + private final HttpClient memberVarHttpClient; + private final ObjectMapper memberVarObjectMapper; + private final String memberVarBaseUri; + private final Consumer memberVarInterceptor; + private final Duration memberVarReadTimeout; + private final Consumer> memberVarResponseInterceptor; + private final Consumer> memberVarAsyncResponseInterceptor; + + public SearchApi() { + this(new ApiClient()); + } + + public SearchApi(ApiClient apiClient) { + memberVarHttpClient = apiClient.getHttpClient(); + memberVarObjectMapper = apiClient.getObjectMapper(); + memberVarBaseUri = apiClient.getBaseUri(); + memberVarInterceptor = apiClient.getRequestInterceptor(); + memberVarReadTimeout = apiClient.getReadTimeout(); + memberVarResponseInterceptor = apiClient.getResponseInterceptor(); + memberVarAsyncResponseInterceptor = apiClient.getAsyncResponseInterceptor(); + } + + protected ApiException getApiException(String operationId, HttpResponse response) throws IOException { + String body = response.body() == null ? null : new String(response.body().readAllBytes()); + String message = formatExceptionMessage(operationId, response.statusCode(), body); + return new ApiException(response.statusCode(), message, response.headers(), body); + } + + private String formatExceptionMessage(String operationId, int statusCode, String body) { + if (body == null || body.isEmpty()) { + body = "[no body]"; + } + return operationId + " call failed with: " + statusCode + " - " + body; + } + + /** + * [INDEXER] Search for Transactions + * `/search/transactions` allows the caller to search for transactions that meet certain conditions. Some conditions include matching a transaction hash, containing an operation with a certain status, or containing an operation that affects a certain account. `/search/transactions` is considered an \"indexer\" endpoint and Rosetta implementations are not required to complete it to adhere to the Rosetta spec. However, any Rosetta \"indexer\" MUST support this endpoint. + * @param searchTransactionsRequest (required) + * @return SearchTransactionsResponse + * @throws ApiException if fails to make API call + */ + public SearchTransactionsResponse searchTransactions(SearchTransactionsRequest searchTransactionsRequest) throws ApiException { + ApiResponse localVarResponse = searchTransactionsWithHttpInfo(searchTransactionsRequest); + return localVarResponse.getData(); + } + + /** + * [INDEXER] Search for Transactions + * `/search/transactions` allows the caller to search for transactions that meet certain conditions. Some conditions include matching a transaction hash, containing an operation with a certain status, or containing an operation that affects a certain account. `/search/transactions` is considered an \"indexer\" endpoint and Rosetta implementations are not required to complete it to adhere to the Rosetta spec. However, any Rosetta \"indexer\" MUST support this endpoint. + * @param searchTransactionsRequest (required) + * @return ApiResponse<SearchTransactionsResponse> + * @throws ApiException if fails to make API call + */ + public ApiResponse searchTransactionsWithHttpInfo(SearchTransactionsRequest searchTransactionsRequest) throws ApiException { + HttpRequest.Builder localVarRequestBuilder = searchTransactionsRequestBuilder(searchTransactionsRequest); + try { + HttpResponse localVarResponse = memberVarHttpClient.send( + localVarRequestBuilder.build(), + HttpResponse.BodyHandlers.ofInputStream()); + if (memberVarResponseInterceptor != null) { + memberVarResponseInterceptor.accept(localVarResponse); + } + try { + if (localVarResponse.statusCode()/ 100 != 2) { + throw getApiException("searchTransactions", localVarResponse); + } + return new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + memberVarObjectMapper.readValue(localVarResponse.body(), new TypeReference() {}) // closes the InputStream + + ); + } finally { + } + } catch (IOException e) { + throw new ApiException(e); + } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new ApiException(e); + } + } + + private HttpRequest.Builder searchTransactionsRequestBuilder(SearchTransactionsRequest searchTransactionsRequest) throws ApiException { + // verify the required parameter 'searchTransactionsRequest' is set + if (searchTransactionsRequest == null) { + throw new ApiException(400, "Missing the required parameter 'searchTransactionsRequest' when calling searchTransactions"); + } + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = "/search/transactions"; + + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + + localVarRequestBuilder.header("Content-Type", "application/json"); + localVarRequestBuilder.header("Accept", "application/json"); + + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(searchTransactionsRequest); + localVarRequestBuilder.method("POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } +} diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/client/ApiClient.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/client/ApiClient.java new file mode 100644 index 0000000000..2538853531 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/client/ApiClient.java @@ -0,0 +1,454 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +package com.radixdlt.api.mesh.generated.client; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; + +import java.io.InputStream; +import java.net.URI; +import java.net.URLEncoder; +import java.net.http.HttpClient; +import java.net.http.HttpConnectTimeoutException; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.time.Duration; +import java.time.OffsetDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.StringJoiner; +import java.util.function.Consumer; +import java.util.stream.Collectors; + +import static java.nio.charset.StandardCharsets.UTF_8; + +/** + * Configuration and utility class for API clients. + * + *

This class can be constructed and modified, then used to instantiate the + * various API classes. The API classes use the settings in this class to + * configure themselves, but otherwise do not store a link to this class.

+ * + *

This class is mutable and not synchronized, so it is not thread-safe. + * The API classes generated from this are immutable and thread-safe.

+ * + *

The setter methods of this class return the current object to facilitate + * a fluent style of configuration.

+ */ +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class ApiClient { + + private HttpClient.Builder builder; + private ObjectMapper mapper; + private String scheme; + private String host; + private int port; + private String basePath; + private Consumer interceptor; + private Consumer> responseInterceptor; + private Consumer> asyncResponseInterceptor; + private Duration readTimeout; + private Duration connectTimeout; + + private static String valueToString(Object value) { + if (value == null) { + return ""; + } + if (value instanceof OffsetDateTime) { + return ((OffsetDateTime) value).format(DateTimeFormatter.ISO_OFFSET_DATE_TIME); + } + return value.toString(); + } + + /** + * URL encode a string in the UTF-8 encoding. + * + * @param s String to encode. + * @return URL-encoded representation of the input string. + */ + public static String urlEncode(String s) { + return URLEncoder.encode(s, UTF_8).replaceAll("\\+", "%20"); + } + + /** + * Convert a URL query name/value parameter to a list of encoded {@link Pair} + * objects. + * + *

The value can be null, in which case an empty list is returned.

+ * + * @param name The query name parameter. + * @param value The query value, which may not be a collection but may be + * null. + * @return A singleton list of the {@link Pair} objects representing the input + * parameters, which is encoded for use in a URL. If the value is null, an + * empty list is returned. + */ + public static List parameterToPairs(String name, Object value) { + if (name == null || name.isEmpty() || value == null) { + return Collections.emptyList(); + } + return Collections.singletonList(new Pair(urlEncode(name), urlEncode(valueToString(value)))); + } + + /** + * Convert a URL query name/collection parameter to a list of encoded + * {@link Pair} objects. + * + * @param collectionFormat The swagger collectionFormat string (csv, tsv, etc). + * @param name The query name parameter. + * @param values A collection of values for the given query name, which may be + * null. + * @return A list of {@link Pair} objects representing the input parameters, + * which is encoded for use in a URL. If the values collection is null, an + * empty list is returned. + */ + public static List parameterToPairs( + String collectionFormat, String name, Collection values) { + if (name == null || name.isEmpty() || values == null || values.isEmpty()) { + return Collections.emptyList(); + } + + // get the collection format (default: csv) + String format = collectionFormat == null || collectionFormat.isEmpty() ? "csv" : collectionFormat; + + // create the params based on the collection format + if ("multi".equals(format)) { + return values.stream() + .map(value -> new Pair(urlEncode(name), urlEncode(valueToString(value)))) + .collect(Collectors.toList()); + } + + String delimiter; + switch(format) { + case "csv": + delimiter = urlEncode(","); + break; + case "ssv": + delimiter = urlEncode(" "); + break; + case "tsv": + delimiter = urlEncode("\t"); + break; + case "pipes": + delimiter = urlEncode("|"); + break; + default: + throw new IllegalArgumentException("Illegal collection format: " + collectionFormat); + } + + StringJoiner joiner = new StringJoiner(delimiter); + for (Object value : values) { + joiner.add(urlEncode(valueToString(value))); + } + + return Collections.singletonList(new Pair(urlEncode(name), joiner.toString())); + } + + /** + * Create an instance of ApiClient. + */ + public ApiClient() { + this.builder = createDefaultHttpClientBuilder(); + this.mapper = createDefaultObjectMapper(); + updateBaseUri(getDefaultBaseUri()); + interceptor = null; + readTimeout = null; + connectTimeout = null; + responseInterceptor = null; + asyncResponseInterceptor = null; + } + + /** + * Create an instance of ApiClient. + * + * @param builder Http client builder. + * @param mapper Object mapper. + * @param baseUri Base URI + */ + public ApiClient(HttpClient.Builder builder, ObjectMapper mapper, String baseUri) { + this.builder = builder; + this.mapper = mapper; + updateBaseUri(baseUri != null ? baseUri : getDefaultBaseUri()); + interceptor = null; + readTimeout = null; + connectTimeout = null; + responseInterceptor = null; + asyncResponseInterceptor = null; + } + + protected ObjectMapper createDefaultObjectMapper() { + ObjectMapper mapper = new ObjectMapper(); + mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + mapper.configure(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE, false); + mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + mapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING); + mapper.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING); + mapper.disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE); + mapper.registerModule(new JavaTimeModule()); + return mapper; + } + + protected String getDefaultBaseUri() { + return "http://localhost"; + } + + protected HttpClient.Builder createDefaultHttpClientBuilder() { + return HttpClient.newBuilder(); + } + + public void updateBaseUri(String baseUri) { + URI uri = URI.create(baseUri); + scheme = uri.getScheme(); + host = uri.getHost(); + port = uri.getPort(); + basePath = uri.getRawPath(); + } + + /** + * Set a custom {@link HttpClient.Builder} object to use when creating the + * {@link HttpClient} that is used by the API client. + * + * @param builder Custom client builder. + * @return This object. + */ + public ApiClient setHttpClientBuilder(HttpClient.Builder builder) { + this.builder = builder; + return this; + } + + /** + * Get an {@link HttpClient} based on the current {@link HttpClient.Builder}. + * + *

The returned object is immutable and thread-safe.

+ * + * @return The HTTP client. + */ + public HttpClient getHttpClient() { + return builder.build(); + } + + /** + * Set a custom {@link ObjectMapper} to serialize and deserialize the request + * and response bodies. + * + * @param mapper Custom object mapper. + * @return This object. + */ + public ApiClient setObjectMapper(ObjectMapper mapper) { + this.mapper = mapper; + return this; + } + + /** + * Get a copy of the current {@link ObjectMapper}. + * + * @return A copy of the current object mapper. + */ + public ObjectMapper getObjectMapper() { + return mapper.copy(); + } + + /** + * Set a custom host name for the target service. + * + * @param host The host name of the target service. + * @return This object. + */ + public ApiClient setHost(String host) { + this.host = host; + return this; + } + + /** + * Set a custom port number for the target service. + * + * @param port The port of the target service. Set this to -1 to reset the + * value to the default for the scheme. + * @return This object. + */ + public ApiClient setPort(int port) { + this.port = port; + return this; + } + + /** + * Set a custom base path for the target service, for example '/v2'. + * + * @param basePath The base path against which the rest of the path is + * resolved. + * @return This object. + */ + public ApiClient setBasePath(String basePath) { + this.basePath = basePath; + return this; + } + + /** + * Get the base URI to resolve the endpoint paths against. + * + * @return The complete base URI that the rest of the API parameters are + * resolved against. + */ + public String getBaseUri() { + return scheme + "://" + host + (port == -1 ? "" : ":" + port) + basePath; + } + + /** + * Set a custom scheme for the target service, for example 'https'. + * + * @param scheme The scheme of the target service + * @return This object. + */ + public ApiClient setScheme(String scheme){ + this.scheme = scheme; + return this; + } + + /** + * Set a custom request interceptor. + * + *

A request interceptor is a mechanism for altering each request before it + * is sent. After the request has been fully configured but not yet built, the + * request builder is passed into this function for further modification, + * after which it is sent out.

+ * + *

This is useful for altering the requests in a custom manner, such as + * adding headers. It could also be used for logging and monitoring.

+ * + * @param interceptor A function invoked before creating each request. A value + * of null resets the interceptor to a no-op. + * @return This object. + */ + public ApiClient setRequestInterceptor(Consumer interceptor) { + this.interceptor = interceptor; + return this; + } + + /** + * Get the custom interceptor. + * + * @return The custom interceptor that was set, or null if there isn't any. + */ + public Consumer getRequestInterceptor() { + return interceptor; + } + + /** + * Set a custom response interceptor. + * + *

This is useful for logging, monitoring or extraction of header variables

+ * + * @param interceptor A function invoked before creating each request. A value + * of null resets the interceptor to a no-op. + * @return This object. + */ + public ApiClient setResponseInterceptor(Consumer> interceptor) { + this.responseInterceptor = interceptor; + return this; + } + + /** + * Get the custom response interceptor. + * + * @return The custom interceptor that was set, or null if there isn't any. + */ + public Consumer> getResponseInterceptor() { + return responseInterceptor; + } + + /** + * Set a custom async response interceptor. Use this interceptor when asyncNative is set to 'true'. + * + *

This is useful for logging, monitoring or extraction of header variables

+ * + * @param interceptor A function invoked before creating each request. A value + * of null resets the interceptor to a no-op. + * @return This object. + */ + public ApiClient setAsyncResponseInterceptor(Consumer> interceptor) { + this.asyncResponseInterceptor = interceptor; + return this; + } + + /** + * Get the custom async response interceptor. Use this interceptor when asyncNative is set to 'true'. + * + * @return The custom interceptor that was set, or null if there isn't any. + */ + public Consumer> getAsyncResponseInterceptor() { + return asyncResponseInterceptor; + } + + /** + * Set the read timeout for the http client. + * + *

This is the value used by default for each request, though it can be + * overridden on a per-request basis with a request interceptor.

+ * + * @param readTimeout The read timeout used by default by the http client. + * Setting this value to null resets the timeout to an + * effectively infinite value. + * @return This object. + */ + public ApiClient setReadTimeout(Duration readTimeout) { + this.readTimeout = readTimeout; + return this; + } + + /** + * Get the read timeout that was set. + * + * @return The read timeout, or null if no timeout was set. Null represents + * an infinite wait time. + */ + public Duration getReadTimeout() { + return readTimeout; + } + /** + * Sets the connect timeout (in milliseconds) for the http client. + * + *

In the case where a new connection needs to be established, if + * the connection cannot be established within the given {@code + * duration}, then {@link HttpClient#send(HttpRequest,BodyHandler) + * HttpClient::send} throws an {@link HttpConnectTimeoutException}, or + * {@link HttpClient#sendAsync(HttpRequest,BodyHandler) + * HttpClient::sendAsync} completes exceptionally with an + * {@code HttpConnectTimeoutException}. If a new connection does not + * need to be established, for example if a connection can be reused + * from a previous request, then this timeout duration has no effect. + * + * @param connectTimeout connection timeout in milliseconds + * + * @return This object. + */ + public ApiClient setConnectTimeout(Duration connectTimeout) { + this.connectTimeout = connectTimeout; + this.builder.connectTimeout(connectTimeout); + return this; + } + + /** + * Get connection timeout (in milliseconds). + * + * @return Timeout in milliseconds + */ + public Duration getConnectTimeout() { + return connectTimeout; + } +} diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/client/ApiException.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/client/ApiException.java new file mode 100644 index 0000000000..978bf820de --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/client/ApiException.java @@ -0,0 +1,90 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.client; + +import java.net.http.HttpHeaders; + +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class ApiException extends Exception { + private int code = 0; + private HttpHeaders responseHeaders = null; + private String responseBody = null; + + public ApiException() {} + + public ApiException(Throwable throwable) { + super(throwable); + } + + public ApiException(String message) { + super(message); + } + + public ApiException(String message, Throwable throwable, int code, HttpHeaders responseHeaders, String responseBody) { + super(message, throwable); + this.code = code; + this.responseHeaders = responseHeaders; + this.responseBody = responseBody; + } + + public ApiException(String message, int code, HttpHeaders responseHeaders, String responseBody) { + this(message, (Throwable) null, code, responseHeaders, responseBody); + } + + public ApiException(String message, Throwable throwable, int code, HttpHeaders responseHeaders) { + this(message, throwable, code, responseHeaders, null); + } + + public ApiException(int code, HttpHeaders responseHeaders, String responseBody) { + this((String) null, (Throwable) null, code, responseHeaders, responseBody); + } + + public ApiException(int code, String message) { + super(message); + this.code = code; + } + + public ApiException(int code, String message, HttpHeaders responseHeaders, String responseBody) { + this(code, message); + this.responseHeaders = responseHeaders; + this.responseBody = responseBody; + } + + /** + * Get the HTTP status code. + * + * @return HTTP status code + */ + public int getCode() { + return code; + } + + /** + * Get the HTTP response headers. + * + * @return Headers as an HttpHeaders object + */ + public HttpHeaders getResponseHeaders() { + return responseHeaders; + } + + /** + * Get the HTTP response body. + * + * @return Response body in the form of string + */ + public String getResponseBody() { + return responseBody; + } +} diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/client/ApiResponse.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/client/ApiResponse.java new file mode 100644 index 0000000000..d60c6b2f5b --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/client/ApiResponse.java @@ -0,0 +1,59 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.client; + +import java.util.List; +import java.util.Map; + +/** + * API response returned by API call. + * + * @param The type of data that is deserialized from response body + */ +public class ApiResponse { + final private int statusCode; + final private Map> headers; + final private T data; + + /** + * @param statusCode The status code of HTTP response + * @param headers The headers of HTTP response + */ + public ApiResponse(int statusCode, Map> headers) { + this(statusCode, headers, null); + } + + /** + * @param statusCode The status code of HTTP response + * @param headers The headers of HTTP response + * @param data The object deserialized from response bod + */ + public ApiResponse(int statusCode, Map> headers, T data) { + this.statusCode = statusCode; + this.headers = headers; + this.data = data; + } + + public int getStatusCode() { + return statusCode; + } + + public Map> getHeaders() { + return headers; + } + + public T getData() { + return data; + } +} diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/client/Configuration.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/client/Configuration.java new file mode 100644 index 0000000000..d9c6659abb --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/client/Configuration.java @@ -0,0 +1,39 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.client; + +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class Configuration { + private static ApiClient defaultApiClient = new ApiClient(); + + /** + * Get the default API client, which would be used when creating API + * instances without providing an API client. + * + * @return Default API client + */ + public static ApiClient getDefaultApiClient() { + return defaultApiClient; + } + + /** + * Set the default API client, which would be used when creating API + * instances without providing an API client. + * + * @param apiClient API client + */ + public static void setDefaultApiClient(ApiClient apiClient) { + defaultApiClient = apiClient; + } +} diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/client/JSON.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/client/JSON.java new file mode 100644 index 0000000000..4b1240728a --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/client/JSON.java @@ -0,0 +1,245 @@ +package com.radixdlt.api.mesh.generated.client; + +import com.fasterxml.jackson.annotation.*; +import com.fasterxml.jackson.databind.*; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.radixdlt.api.mesh.generated.models.*; + +import java.text.DateFormat; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class JSON { + private ObjectMapper mapper; + + public JSON() { + mapper = new ObjectMapper(); + mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + mapper.configure(MapperFeature.ALLOW_COERCION_OF_SCALARS, false); + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true); + mapper.configure(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE, true); + mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + mapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING); + mapper.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING); + mapper.setDateFormat(new RFC3339DateFormat()); + mapper.registerModule(new JavaTimeModule()); + } + + /** + * Set the date format for JSON (de)serialization with Date properties. + * + * @param dateFormat Date format + */ + public void setDateFormat(DateFormat dateFormat) { + mapper.setDateFormat(dateFormat); + } + + /** + * Get the object mapper + * + * @return object mapper + */ + public ObjectMapper getMapper() { return mapper; } + + /** + * Returns the target model class that should be used to deserialize the input data. + * The discriminator mappings are used to determine the target model class. + * + * @param node The input data. + * @param modelClass The class that contains the discriminator mappings. + * + * @return the target model class. + */ + public static Class getClassForElement(JsonNode node, Class modelClass) { + ClassDiscriminatorMapping cdm = modelDiscriminators.get(modelClass); + if (cdm != null) { + return cdm.getClassForElement(node, new HashSet>()); + } + return null; + } + + /** + * Helper class to register the discriminator mappings. + */ + private static class ClassDiscriminatorMapping { + // The model class name. + Class modelClass; + // The name of the discriminator property. + String discriminatorName; + // The discriminator mappings for a model class. + Map> discriminatorMappings; + + // Constructs a new class discriminator. + ClassDiscriminatorMapping(Class cls, String propertyName, Map> mappings) { + modelClass = cls; + discriminatorName = propertyName; + discriminatorMappings = new HashMap>(); + if (mappings != null) { + discriminatorMappings.putAll(mappings); + } + } + + // Return the name of the discriminator property for this model class. + String getDiscriminatorPropertyName() { + return discriminatorName; + } + + // Return the discriminator value or null if the discriminator is not + // present in the payload. + String getDiscriminatorValue(JsonNode node) { + // Determine the value of the discriminator property in the input data. + if (discriminatorName != null) { + // Get the value of the discriminator property, if present in the input payload. + node = node.get(discriminatorName); + if (node != null && node.isValueNode()) { + String discrValue = node.asText(); + if (discrValue != null) { + return discrValue; + } + } + } + return null; + } + + /** + * Returns the target model class that should be used to deserialize the input data. + * This function can be invoked for anyOf/oneOf composed models with discriminator mappings. + * The discriminator mappings are used to determine the target model class. + * + * @param node The input data. + * @param visitedClasses The set of classes that have already been visited. + * + * @return the target model class. + */ + Class getClassForElement(JsonNode node, Set> visitedClasses) { + if (visitedClasses.contains(modelClass)) { + // Class has already been visited. + return null; + } + // Determine the value of the discriminator property in the input data. + String discrValue = getDiscriminatorValue(node); + if (discrValue == null) { + return null; + } + Class cls = discriminatorMappings.get(discrValue); + // It may not be sufficient to return this cls directly because that target class + // may itself be a composed schema, possibly with its own discriminator. + visitedClasses.add(modelClass); + for (Class childClass : discriminatorMappings.values()) { + ClassDiscriminatorMapping childCdm = modelDiscriminators.get(childClass); + if (childCdm == null) { + continue; + } + if (!discriminatorName.equals(childCdm.discriminatorName)) { + discrValue = getDiscriminatorValue(node); + if (discrValue == null) { + continue; + } + } + if (childCdm != null) { + // Recursively traverse the discriminator mappings. + Class childDiscr = childCdm.getClassForElement(node, visitedClasses); + if (childDiscr != null) { + return childDiscr; + } + } + } + return cls; + } + } + + /** + * Returns true if inst is an instance of modelClass in the OpenAPI model hierarchy. + * + * The Java class hierarchy is not implemented the same way as the OpenAPI model hierarchy, + * so it's not possible to use the instanceof keyword. + * + * @param modelClass A OpenAPI model class. + * @param inst The instance object. + * @param visitedClasses The set of classes that have already been visited. + * + * @return true if inst is an instance of modelClass in the OpenAPI model hierarchy. + */ + public static boolean isInstanceOf(Class modelClass, Object inst, Set> visitedClasses) { + if (modelClass.isInstance(inst)) { + // This handles the 'allOf' use case with single parent inheritance. + return true; + } + if (visitedClasses.contains(modelClass)) { + // This is to prevent infinite recursion when the composed schemas have + // a circular dependency. + return false; + } + visitedClasses.add(modelClass); + + // Traverse the oneOf/anyOf composed schemas. + Map> descendants = modelDescendants.get(modelClass); + if (descendants != null) { + for (Class childType : descendants.values()) { + if (isInstanceOf(childType, inst, visitedClasses)) { + return true; + } + } + } + return false; + } + + /** + * A map of discriminators for all model classes. + */ + private static Map, ClassDiscriminatorMapping> modelDiscriminators = new HashMap<>(); + + /** + * A map of oneOf/anyOf descendants for each model class. + */ + private static Map, Map>> modelDescendants = new HashMap<>(); + + /** + * Register a model class discriminator. + * + * @param modelClass the model class + * @param discriminatorPropertyName the name of the discriminator property + * @param mappings a map with the discriminator mappings. + */ + public static void registerDiscriminator(Class modelClass, String discriminatorPropertyName, Map> mappings) { + ClassDiscriminatorMapping m = new ClassDiscriminatorMapping(modelClass, discriminatorPropertyName, mappings); + modelDiscriminators.put(modelClass, m); + } + + /** + * Register the oneOf/anyOf descendants of the modelClass. + * + * @param modelClass the model class + * @param descendants a map of oneOf/anyOf descendants. + */ + public static void registerDescendants(Class modelClass, Map> descendants) { + modelDescendants.put(modelClass, descendants); + } + + private static JSON json; + + static { + json = new JSON(); + } + + /** + * Get the default JSON instance. + * + * @return the default JSON instance + */ + public static JSON getDefault() { + return json; + } + + /** + * Set the default JSON instance. + * + * @param json JSON instance to be used + */ + public static void setDefault(JSON json) { + JSON.json = json; + } +} diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/client/Pair.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/client/Pair.java new file mode 100644 index 0000000000..1542e899fc --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/client/Pair.java @@ -0,0 +1,57 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.client; + +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class Pair { + private String name = ""; + private String value = ""; + + public Pair (String name, String value) { + setName(name); + setValue(value); + } + + private void setName(String name) { + if (!isValidString(name)) { + return; + } + + this.name = name; + } + + private void setValue(String value) { + if (!isValidString(value)) { + return; + } + + this.value = value; + } + + public String getName() { + return this.name; + } + + public String getValue() { + return this.value; + } + + private boolean isValidString(String arg) { + if (arg == null) { + return false; + } + + return true; + } +} diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/client/RFC3339DateFormat.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/client/RFC3339DateFormat.java new file mode 100644 index 0000000000..094313f25c --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/client/RFC3339DateFormat.java @@ -0,0 +1,57 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +package com.radixdlt.api.mesh.generated.client; + +import com.fasterxml.jackson.databind.util.StdDateFormat; + +import java.text.DateFormat; +import java.text.FieldPosition; +import java.text.ParsePosition; +import java.util.Date; +import java.text.DecimalFormat; +import java.util.GregorianCalendar; +import java.util.TimeZone; + +public class RFC3339DateFormat extends DateFormat { + private static final long serialVersionUID = 1L; + private static final TimeZone TIMEZONE_Z = TimeZone.getTimeZone("UTC"); + + private final StdDateFormat fmt = new StdDateFormat() + .withTimeZone(TIMEZONE_Z) + .withColonInTimeZone(true); + + public RFC3339DateFormat() { + this.calendar = new GregorianCalendar(); + this.numberFormat = new DecimalFormat(); + } + + @Override + public Date parse(String source) { + return parse(source, new ParsePosition(0)); + } + + @Override + public Date parse(String source, ParsePosition pos) { + return fmt.parse(source, pos); + } + + @Override + public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) { + return fmt.format(date, toAppendTo, fieldPosition); + } + + @Override + public Object clone() { + return super.clone(); + } +} \ No newline at end of file diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/client/ServerConfiguration.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/client/ServerConfiguration.java new file mode 100644 index 0000000000..008799af0c --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/client/ServerConfiguration.java @@ -0,0 +1,58 @@ +package com.radixdlt.api.mesh.generated.client; + +import java.util.Map; + +/** + * Representing a Server configuration. + */ +public class ServerConfiguration { + public String URL; + public String description; + public Map variables; + + /** + * @param URL A URL to the target host. + * @param description A description of the host designated by the URL. + * @param variables A map between a variable name and its value. The value is used for substitution in the server's URL template. + */ + public ServerConfiguration(String URL, String description, Map variables) { + this.URL = URL; + this.description = description; + this.variables = variables; + } + + /** + * Format URL template using given variables. + * + * @param variables A map between a variable name and its value. + * @return Formatted URL. + */ + public String URL(Map variables) { + String url = this.URL; + + // go through variables and replace placeholders + for (Map.Entry variable: this.variables.entrySet()) { + String name = variable.getKey(); + ServerVariable serverVariable = variable.getValue(); + String value = serverVariable.defaultValue; + + if (variables != null && variables.containsKey(name)) { + value = variables.get(name); + if (serverVariable.enumValues.size() > 0 && !serverVariable.enumValues.contains(value)) { + throw new IllegalArgumentException("The variable " + name + " in the server URL has invalid value " + value + "."); + } + } + url = url.replaceAll("\\{" + name + "\\}", value); + } + return url; + } + + /** + * Format URL template using default server variables. + * + * @return Formatted URL. + */ + public String URL() { + return URL(null); + } +} diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/client/ServerVariable.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/client/ServerVariable.java new file mode 100644 index 0000000000..c2db316ca7 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/client/ServerVariable.java @@ -0,0 +1,23 @@ +package com.radixdlt.api.mesh.generated.client; + +import java.util.HashSet; + +/** + * Representing a Server Variable for server URL template substitution. + */ +public class ServerVariable { + public String description; + public String defaultValue; + public HashSet enumValues = null; + + /** + * @param description A description for the server variable. + * @param defaultValue The default value to use for substitution. + * @param enumValues An enumeration of string values to be used if the substitution options are from a limited set. + */ + public ServerVariable(String description, String defaultValue, HashSet enumValues) { + this.description = description; + this.defaultValue = defaultValue; + this.enumValues = enumValues; + } +} diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/AbstractOpenApiSchema.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/AbstractOpenApiSchema.java new file mode 100644 index 0000000000..70aea9cb34 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/AbstractOpenApiSchema.java @@ -0,0 +1,148 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import com.radixdlt.api.mesh.generated.client.ApiException; +import java.util.Objects; +import java.lang.reflect.Type; +import java.util.Map; + +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * Abstract class for oneOf,anyOf schemas defined in OpenAPI spec + */ +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public abstract class AbstractOpenApiSchema { + + // store the actual instance of the schema/object + private Object instance; + + // is nullable + private Boolean isNullable; + + // schema type (e.g. oneOf, anyOf) + private final String schemaType; + + public AbstractOpenApiSchema(String schemaType, Boolean isNullable) { + this.schemaType = schemaType; + this.isNullable = isNullable; + } + + /** + * Get the list of oneOf/anyOf composed schemas allowed to be stored in this object + * + * @return an instance of the actual schema/object + */ + public abstract Map> getSchemas(); + + /** + * Get the actual instance + * + * @return an instance of the actual schema/object + */ + @JsonValue + public Object getActualInstance() {return instance;} + + /** + * Set the actual instance + * + * @param instance the actual instance of the schema/object + */ + public void setActualInstance(Object instance) {this.instance = instance;} + + /** + * Get the instant recursively when the schemas defined in oneOf/anyof happen to be oneOf/anyOf schema as well + * + * @return an instance of the actual schema/object + */ + public Object getActualInstanceRecursively() { + return getActualInstanceRecursively(this); + } + + private Object getActualInstanceRecursively(AbstractOpenApiSchema object) { + if (object.getActualInstance() == null) { + return null; + } else if (object.getActualInstance() instanceof AbstractOpenApiSchema) { + return getActualInstanceRecursively((AbstractOpenApiSchema)object.getActualInstance()); + } else { + return object.getActualInstance(); + } + } + + /** + * Get the schema type (e.g. anyOf, oneOf) + * + * @return the schema type + */ + public String getSchemaType() { + return schemaType; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ").append(getClass()).append(" {\n"); + sb.append(" instance: ").append(toIndentedString(instance)).append("\n"); + sb.append(" isNullable: ").append(toIndentedString(isNullable)).append("\n"); + sb.append(" schemaType: ").append(toIndentedString(schemaType)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + AbstractOpenApiSchema a = (AbstractOpenApiSchema) o; + return Objects.equals(this.instance, a.instance) && + Objects.equals(this.isNullable, a.isNullable) && + Objects.equals(this.schemaType, a.schemaType); + } + + @Override + public int hashCode() { + return Objects.hash(instance, isNullable, schemaType); + } + + /** + * Is nullable + * + * @return true if it's nullable + */ + public Boolean isNullable() { + if (Boolean.TRUE.equals(isNullable)) { + return Boolean.TRUE; + } else { + return Boolean.FALSE; + } + } + + + +} diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/AccountBalanceRequest.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/AccountBalanceRequest.java new file mode 100644 index 0000000000..e24b506945 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/AccountBalanceRequest.java @@ -0,0 +1,222 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.AccountIdentifier; +import com.radixdlt.api.mesh.generated.models.Currency; +import com.radixdlt.api.mesh.generated.models.NetworkIdentifier; +import com.radixdlt.api.mesh.generated.models.PartialBlockIdentifier; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import java.util.ArrayList; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * An AccountBalanceRequest is utilized to make a balance request on the /account/balance endpoint. If the block_identifier is populated, a historical balance query should be performed. + */ +@ApiModel(description = "An AccountBalanceRequest is utilized to make a balance request on the /account/balance endpoint. If the block_identifier is populated, a historical balance query should be performed. ") +@JsonPropertyOrder({ + AccountBalanceRequest.JSON_PROPERTY_NETWORK_IDENTIFIER, + AccountBalanceRequest.JSON_PROPERTY_ACCOUNT_IDENTIFIER, + AccountBalanceRequest.JSON_PROPERTY_BLOCK_IDENTIFIER, + AccountBalanceRequest.JSON_PROPERTY_CURRENCIES +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class AccountBalanceRequest { + public static final String JSON_PROPERTY_NETWORK_IDENTIFIER = "network_identifier"; + private NetworkIdentifier networkIdentifier; + + public static final String JSON_PROPERTY_ACCOUNT_IDENTIFIER = "account_identifier"; + private AccountIdentifier accountIdentifier; + + public static final String JSON_PROPERTY_BLOCK_IDENTIFIER = "block_identifier"; + private PartialBlockIdentifier blockIdentifier; + + public static final String JSON_PROPERTY_CURRENCIES = "currencies"; + private List currencies = null; + + public AccountBalanceRequest() { + } + + public AccountBalanceRequest networkIdentifier(NetworkIdentifier networkIdentifier) { + this.networkIdentifier = networkIdentifier; + return this; + } + + /** + * Get networkIdentifier + * @return networkIdentifier + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_NETWORK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public NetworkIdentifier getNetworkIdentifier() { + return networkIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_NETWORK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setNetworkIdentifier(NetworkIdentifier networkIdentifier) { + this.networkIdentifier = networkIdentifier; + } + + + public AccountBalanceRequest accountIdentifier(AccountIdentifier accountIdentifier) { + this.accountIdentifier = accountIdentifier; + return this; + } + + /** + * Get accountIdentifier + * @return accountIdentifier + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_ACCOUNT_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public AccountIdentifier getAccountIdentifier() { + return accountIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_ACCOUNT_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setAccountIdentifier(AccountIdentifier accountIdentifier) { + this.accountIdentifier = accountIdentifier; + } + + + public AccountBalanceRequest blockIdentifier(PartialBlockIdentifier blockIdentifier) { + this.blockIdentifier = blockIdentifier; + return this; + } + + /** + * Get blockIdentifier + * @return blockIdentifier + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_BLOCK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public PartialBlockIdentifier getBlockIdentifier() { + return blockIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_BLOCK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setBlockIdentifier(PartialBlockIdentifier blockIdentifier) { + this.blockIdentifier = blockIdentifier; + } + + + public AccountBalanceRequest currencies(List currencies) { + this.currencies = currencies; + return this; + } + + public AccountBalanceRequest addCurrenciesItem(Currency currenciesItem) { + if (this.currencies == null) { + this.currencies = new ArrayList<>(); + } + this.currencies.add(currenciesItem); + return this; + } + + /** + * In some cases, the caller may not want to retrieve all available balances for an AccountIdentifier. If the currencies field is populated, only balances for the specified currencies will be returned. If not populated, all available balances will be returned. + * @return currencies + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "In some cases, the caller may not want to retrieve all available balances for an AccountIdentifier. If the currencies field is populated, only balances for the specified currencies will be returned. If not populated, all available balances will be returned. ") + @JsonProperty(JSON_PROPERTY_CURRENCIES) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public List getCurrencies() { + return currencies; + } + + + @JsonProperty(JSON_PROPERTY_CURRENCIES) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setCurrencies(List currencies) { + this.currencies = currencies; + } + + + /** + * Return true if this AccountBalanceRequest object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + AccountBalanceRequest accountBalanceRequest = (AccountBalanceRequest) o; + return Objects.equals(this.networkIdentifier, accountBalanceRequest.networkIdentifier) && + Objects.equals(this.accountIdentifier, accountBalanceRequest.accountIdentifier) && + Objects.equals(this.blockIdentifier, accountBalanceRequest.blockIdentifier) && + Objects.equals(this.currencies, accountBalanceRequest.currencies); + } + + @Override + public int hashCode() { + return Objects.hash(networkIdentifier, accountIdentifier, blockIdentifier, currencies); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class AccountBalanceRequest {\n"); + sb.append(" networkIdentifier: ").append(toIndentedString(networkIdentifier)).append("\n"); + sb.append(" accountIdentifier: ").append(toIndentedString(accountIdentifier)).append("\n"); + sb.append(" blockIdentifier: ").append(toIndentedString(blockIdentifier)).append("\n"); + sb.append(" currencies: ").append(toIndentedString(currencies)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/AccountBalanceResponse.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/AccountBalanceResponse.java new file mode 100644 index 0000000000..01c3457176 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/AccountBalanceResponse.java @@ -0,0 +1,185 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.Amount; +import com.radixdlt.api.mesh.generated.models.BlockIdentifier; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import java.util.ArrayList; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * An AccountBalanceResponse is returned on the /account/balance endpoint. If an account has a balance for each AccountIdentifier describing it (ex: an ERC-20 token balance on a few smart contracts), an account balance request must be made with each AccountIdentifier. The `coins` field was removed and replaced by by `/account/coins` in `v1.4.7`. + */ +@ApiModel(description = "An AccountBalanceResponse is returned on the /account/balance endpoint. If an account has a balance for each AccountIdentifier describing it (ex: an ERC-20 token balance on a few smart contracts), an account balance request must be made with each AccountIdentifier. The `coins` field was removed and replaced by by `/account/coins` in `v1.4.7`. ") +@JsonPropertyOrder({ + AccountBalanceResponse.JSON_PROPERTY_BLOCK_IDENTIFIER, + AccountBalanceResponse.JSON_PROPERTY_BALANCES, + AccountBalanceResponse.JSON_PROPERTY_METADATA +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class AccountBalanceResponse { + public static final String JSON_PROPERTY_BLOCK_IDENTIFIER = "block_identifier"; + private BlockIdentifier blockIdentifier; + + public static final String JSON_PROPERTY_BALANCES = "balances"; + private List balances = new ArrayList<>(); + + public static final String JSON_PROPERTY_METADATA = "metadata"; + private Object metadata; + + public AccountBalanceResponse() { + } + + public AccountBalanceResponse blockIdentifier(BlockIdentifier blockIdentifier) { + this.blockIdentifier = blockIdentifier; + return this; + } + + /** + * Get blockIdentifier + * @return blockIdentifier + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_BLOCK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public BlockIdentifier getBlockIdentifier() { + return blockIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_BLOCK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setBlockIdentifier(BlockIdentifier blockIdentifier) { + this.blockIdentifier = blockIdentifier; + } + + + public AccountBalanceResponse balances(List balances) { + this.balances = balances; + return this; + } + + public AccountBalanceResponse addBalancesItem(Amount balancesItem) { + this.balances.add(balancesItem); + return this; + } + + /** + * A single account may have a balance in multiple currencies. + * @return balances + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "A single account may have a balance in multiple currencies. ") + @JsonProperty(JSON_PROPERTY_BALANCES) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public List getBalances() { + return balances; + } + + + @JsonProperty(JSON_PROPERTY_BALANCES) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setBalances(List balances) { + this.balances = balances; + } + + + public AccountBalanceResponse metadata(Object metadata) { + this.metadata = metadata; + return this; + } + + /** + * Account-based blockchains that utilize a nonce or sequence number should include that number in the metadata. This number could be unique to the identifier or global across the account address. + * @return metadata + **/ + @javax.annotation.Nullable + @ApiModelProperty(example = "{\"sequence_number\":23}", value = "Account-based blockchains that utilize a nonce or sequence number should include that number in the metadata. This number could be unique to the identifier or global across the account address. ") + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Object getMetadata() { + return metadata; + } + + + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setMetadata(Object metadata) { + this.metadata = metadata; + } + + + /** + * Return true if this AccountBalanceResponse object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + AccountBalanceResponse accountBalanceResponse = (AccountBalanceResponse) o; + return Objects.equals(this.blockIdentifier, accountBalanceResponse.blockIdentifier) && + Objects.equals(this.balances, accountBalanceResponse.balances) && + Objects.equals(this.metadata, accountBalanceResponse.metadata); + } + + @Override + public int hashCode() { + return Objects.hash(blockIdentifier, balances, metadata); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class AccountBalanceResponse {\n"); + sb.append(" blockIdentifier: ").append(toIndentedString(blockIdentifier)).append("\n"); + sb.append(" balances: ").append(toIndentedString(balances)).append("\n"); + sb.append(" metadata: ").append(toIndentedString(metadata)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/AccountCoinsRequest.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/AccountCoinsRequest.java new file mode 100644 index 0000000000..24a6caec8c --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/AccountCoinsRequest.java @@ -0,0 +1,221 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.AccountIdentifier; +import com.radixdlt.api.mesh.generated.models.Currency; +import com.radixdlt.api.mesh.generated.models.NetworkIdentifier; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import java.util.ArrayList; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * AccountCoinsRequest is utilized to make a request on the /account/coins endpoint. + */ +@ApiModel(description = "AccountCoinsRequest is utilized to make a request on the /account/coins endpoint. ") +@JsonPropertyOrder({ + AccountCoinsRequest.JSON_PROPERTY_NETWORK_IDENTIFIER, + AccountCoinsRequest.JSON_PROPERTY_ACCOUNT_IDENTIFIER, + AccountCoinsRequest.JSON_PROPERTY_INCLUDE_MEMPOOL, + AccountCoinsRequest.JSON_PROPERTY_CURRENCIES +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class AccountCoinsRequest { + public static final String JSON_PROPERTY_NETWORK_IDENTIFIER = "network_identifier"; + private NetworkIdentifier networkIdentifier; + + public static final String JSON_PROPERTY_ACCOUNT_IDENTIFIER = "account_identifier"; + private AccountIdentifier accountIdentifier; + + public static final String JSON_PROPERTY_INCLUDE_MEMPOOL = "include_mempool"; + private Boolean includeMempool; + + public static final String JSON_PROPERTY_CURRENCIES = "currencies"; + private List currencies = null; + + public AccountCoinsRequest() { + } + + public AccountCoinsRequest networkIdentifier(NetworkIdentifier networkIdentifier) { + this.networkIdentifier = networkIdentifier; + return this; + } + + /** + * Get networkIdentifier + * @return networkIdentifier + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_NETWORK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public NetworkIdentifier getNetworkIdentifier() { + return networkIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_NETWORK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setNetworkIdentifier(NetworkIdentifier networkIdentifier) { + this.networkIdentifier = networkIdentifier; + } + + + public AccountCoinsRequest accountIdentifier(AccountIdentifier accountIdentifier) { + this.accountIdentifier = accountIdentifier; + return this; + } + + /** + * Get accountIdentifier + * @return accountIdentifier + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_ACCOUNT_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public AccountIdentifier getAccountIdentifier() { + return accountIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_ACCOUNT_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setAccountIdentifier(AccountIdentifier accountIdentifier) { + this.accountIdentifier = accountIdentifier; + } + + + public AccountCoinsRequest includeMempool(Boolean includeMempool) { + this.includeMempool = includeMempool; + return this; + } + + /** + * Include state from the mempool when looking up an account's unspent coins. Note, using this functionality breaks any guarantee of idempotency. + * @return includeMempool + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "Include state from the mempool when looking up an account's unspent coins. Note, using this functionality breaks any guarantee of idempotency. ") + @JsonProperty(JSON_PROPERTY_INCLUDE_MEMPOOL) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public Boolean getIncludeMempool() { + return includeMempool; + } + + + @JsonProperty(JSON_PROPERTY_INCLUDE_MEMPOOL) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setIncludeMempool(Boolean includeMempool) { + this.includeMempool = includeMempool; + } + + + public AccountCoinsRequest currencies(List currencies) { + this.currencies = currencies; + return this; + } + + public AccountCoinsRequest addCurrenciesItem(Currency currenciesItem) { + if (this.currencies == null) { + this.currencies = new ArrayList<>(); + } + this.currencies.add(currenciesItem); + return this; + } + + /** + * In some cases, the caller may not want to retrieve coins for all currencies for an AccountIdentifier. If the currencies field is populated, only coins for the specified currencies will be returned. If not populated, all unspent coins will be returned. + * @return currencies + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "In some cases, the caller may not want to retrieve coins for all currencies for an AccountIdentifier. If the currencies field is populated, only coins for the specified currencies will be returned. If not populated, all unspent coins will be returned. ") + @JsonProperty(JSON_PROPERTY_CURRENCIES) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public List getCurrencies() { + return currencies; + } + + + @JsonProperty(JSON_PROPERTY_CURRENCIES) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setCurrencies(List currencies) { + this.currencies = currencies; + } + + + /** + * Return true if this AccountCoinsRequest object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + AccountCoinsRequest accountCoinsRequest = (AccountCoinsRequest) o; + return Objects.equals(this.networkIdentifier, accountCoinsRequest.networkIdentifier) && + Objects.equals(this.accountIdentifier, accountCoinsRequest.accountIdentifier) && + Objects.equals(this.includeMempool, accountCoinsRequest.includeMempool) && + Objects.equals(this.currencies, accountCoinsRequest.currencies); + } + + @Override + public int hashCode() { + return Objects.hash(networkIdentifier, accountIdentifier, includeMempool, currencies); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class AccountCoinsRequest {\n"); + sb.append(" networkIdentifier: ").append(toIndentedString(networkIdentifier)).append("\n"); + sb.append(" accountIdentifier: ").append(toIndentedString(accountIdentifier)).append("\n"); + sb.append(" includeMempool: ").append(toIndentedString(includeMempool)).append("\n"); + sb.append(" currencies: ").append(toIndentedString(currencies)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/AccountCoinsResponse.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/AccountCoinsResponse.java new file mode 100644 index 0000000000..b5f60fd04f --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/AccountCoinsResponse.java @@ -0,0 +1,185 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.BlockIdentifier; +import com.radixdlt.api.mesh.generated.models.Coin; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import java.util.ArrayList; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * AccountCoinsResponse is returned on the /account/coins endpoint and includes all unspent Coins owned by an AccountIdentifier. + */ +@ApiModel(description = "AccountCoinsResponse is returned on the /account/coins endpoint and includes all unspent Coins owned by an AccountIdentifier. ") +@JsonPropertyOrder({ + AccountCoinsResponse.JSON_PROPERTY_BLOCK_IDENTIFIER, + AccountCoinsResponse.JSON_PROPERTY_COINS, + AccountCoinsResponse.JSON_PROPERTY_METADATA +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class AccountCoinsResponse { + public static final String JSON_PROPERTY_BLOCK_IDENTIFIER = "block_identifier"; + private BlockIdentifier blockIdentifier; + + public static final String JSON_PROPERTY_COINS = "coins"; + private List coins = new ArrayList<>(); + + public static final String JSON_PROPERTY_METADATA = "metadata"; + private Object metadata; + + public AccountCoinsResponse() { + } + + public AccountCoinsResponse blockIdentifier(BlockIdentifier blockIdentifier) { + this.blockIdentifier = blockIdentifier; + return this; + } + + /** + * Get blockIdentifier + * @return blockIdentifier + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_BLOCK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public BlockIdentifier getBlockIdentifier() { + return blockIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_BLOCK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setBlockIdentifier(BlockIdentifier blockIdentifier) { + this.blockIdentifier = blockIdentifier; + } + + + public AccountCoinsResponse coins(List coins) { + this.coins = coins; + return this; + } + + public AccountCoinsResponse addCoinsItem(Coin coinsItem) { + this.coins.add(coinsItem); + return this; + } + + /** + * If a blockchain is UTXO-based, all unspent Coins owned by an account_identifier should be returned alongside the balance. It is highly recommended to populate this field so that users of the Rosetta API implementation don't need to maintain their own indexer to track their UTXOs. + * @return coins + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "If a blockchain is UTXO-based, all unspent Coins owned by an account_identifier should be returned alongside the balance. It is highly recommended to populate this field so that users of the Rosetta API implementation don't need to maintain their own indexer to track their UTXOs. ") + @JsonProperty(JSON_PROPERTY_COINS) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public List getCoins() { + return coins; + } + + + @JsonProperty(JSON_PROPERTY_COINS) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setCoins(List coins) { + this.coins = coins; + } + + + public AccountCoinsResponse metadata(Object metadata) { + this.metadata = metadata; + return this; + } + + /** + * Account-based blockchains that utilize a nonce or sequence number should include that number in the metadata. This number could be unique to the identifier or global across the account address. + * @return metadata + **/ + @javax.annotation.Nullable + @ApiModelProperty(example = "{\"sequence_number\":23}", value = "Account-based blockchains that utilize a nonce or sequence number should include that number in the metadata. This number could be unique to the identifier or global across the account address. ") + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Object getMetadata() { + return metadata; + } + + + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setMetadata(Object metadata) { + this.metadata = metadata; + } + + + /** + * Return true if this AccountCoinsResponse object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + AccountCoinsResponse accountCoinsResponse = (AccountCoinsResponse) o; + return Objects.equals(this.blockIdentifier, accountCoinsResponse.blockIdentifier) && + Objects.equals(this.coins, accountCoinsResponse.coins) && + Objects.equals(this.metadata, accountCoinsResponse.metadata); + } + + @Override + public int hashCode() { + return Objects.hash(blockIdentifier, coins, metadata); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class AccountCoinsResponse {\n"); + sb.append(" blockIdentifier: ").append(toIndentedString(blockIdentifier)).append("\n"); + sb.append(" coins: ").append(toIndentedString(coins)).append("\n"); + sb.append(" metadata: ").append(toIndentedString(metadata)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/AccountIdentifier.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/AccountIdentifier.java new file mode 100644 index 0000000000..8897415704 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/AccountIdentifier.java @@ -0,0 +1,177 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.SubAccountIdentifier; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * The account_identifier uniquely identifies an account within a network. All fields in the account_identifier are utilized to determine this uniqueness (including the metadata field, if populated). + */ +@ApiModel(description = "The account_identifier uniquely identifies an account within a network. All fields in the account_identifier are utilized to determine this uniqueness (including the metadata field, if populated). ") +@JsonPropertyOrder({ + AccountIdentifier.JSON_PROPERTY_ADDRESS, + AccountIdentifier.JSON_PROPERTY_SUB_ACCOUNT, + AccountIdentifier.JSON_PROPERTY_METADATA +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class AccountIdentifier { + public static final String JSON_PROPERTY_ADDRESS = "address"; + private String address; + + public static final String JSON_PROPERTY_SUB_ACCOUNT = "sub_account"; + private SubAccountIdentifier subAccount; + + public static final String JSON_PROPERTY_METADATA = "metadata"; + private Object metadata; + + public AccountIdentifier() { + } + + public AccountIdentifier address(String address) { + this.address = address; + return this; + } + + /** + * The address may be a cryptographic public key (or some encoding of it) or a provided username. + * @return address + **/ + @javax.annotation.Nonnull + @ApiModelProperty(example = "0x3a065000ab4183c6bf581dc1e55a605455fc6d61", required = true, value = "The address may be a cryptographic public key (or some encoding of it) or a provided username. ") + @JsonProperty(JSON_PROPERTY_ADDRESS) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getAddress() { + return address; + } + + + @JsonProperty(JSON_PROPERTY_ADDRESS) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setAddress(String address) { + this.address = address; + } + + + public AccountIdentifier subAccount(SubAccountIdentifier subAccount) { + this.subAccount = subAccount; + return this; + } + + /** + * Get subAccount + * @return subAccount + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_SUB_ACCOUNT) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public SubAccountIdentifier getSubAccount() { + return subAccount; + } + + + @JsonProperty(JSON_PROPERTY_SUB_ACCOUNT) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setSubAccount(SubAccountIdentifier subAccount) { + this.subAccount = subAccount; + } + + + public AccountIdentifier metadata(Object metadata) { + this.metadata = metadata; + return this; + } + + /** + * Blockchains that utilize a username model (where the address is not a derivative of a cryptographic public key) should specify the public key(s) owned by the address in metadata. + * @return metadata + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "Blockchains that utilize a username model (where the address is not a derivative of a cryptographic public key) should specify the public key(s) owned by the address in metadata. ") + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Object getMetadata() { + return metadata; + } + + + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setMetadata(Object metadata) { + this.metadata = metadata; + } + + + /** + * Return true if this AccountIdentifier object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + AccountIdentifier accountIdentifier = (AccountIdentifier) o; + return Objects.equals(this.address, accountIdentifier.address) && + Objects.equals(this.subAccount, accountIdentifier.subAccount) && + Objects.equals(this.metadata, accountIdentifier.metadata); + } + + @Override + public int hashCode() { + return Objects.hash(address, subAccount, metadata); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class AccountIdentifier {\n"); + sb.append(" address: ").append(toIndentedString(address)).append("\n"); + sb.append(" subAccount: ").append(toIndentedString(subAccount)).append("\n"); + sb.append(" metadata: ").append(toIndentedString(metadata)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/Allow.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/Allow.java new file mode 100644 index 0000000000..0ae84a50b1 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/Allow.java @@ -0,0 +1,432 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.BalanceExemption; +import com.radixdlt.api.mesh.generated.models.Error; +import com.radixdlt.api.mesh.generated.models.ModelCase; +import com.radixdlt.api.mesh.generated.models.OperationStatus; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import java.util.ArrayList; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * Allow specifies supported Operation status, Operation types, and all possible error statuses. This Allow object is used by clients to validate the correctness of a Rosetta Server implementation. It is expected that these clients will error if they receive some response that contains any of the above information that is not specified here. + */ +@ApiModel(description = "Allow specifies supported Operation status, Operation types, and all possible error statuses. This Allow object is used by clients to validate the correctness of a Rosetta Server implementation. It is expected that these clients will error if they receive some response that contains any of the above information that is not specified here. ") +@JsonPropertyOrder({ + Allow.JSON_PROPERTY_OPERATION_STATUSES, + Allow.JSON_PROPERTY_OPERATION_TYPES, + Allow.JSON_PROPERTY_ERRORS, + Allow.JSON_PROPERTY_HISTORICAL_BALANCE_LOOKUP, + Allow.JSON_PROPERTY_TIMESTAMP_START_INDEX, + Allow.JSON_PROPERTY_CALL_METHODS, + Allow.JSON_PROPERTY_BALANCE_EXEMPTIONS, + Allow.JSON_PROPERTY_MEMPOOL_COINS, + Allow.JSON_PROPERTY_BLOCK_HASH_CASE, + Allow.JSON_PROPERTY_TRANSACTION_HASH_CASE +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class Allow { + public static final String JSON_PROPERTY_OPERATION_STATUSES = "operation_statuses"; + private List operationStatuses = new ArrayList<>(); + + public static final String JSON_PROPERTY_OPERATION_TYPES = "operation_types"; + private List operationTypes = new ArrayList<>(); + + public static final String JSON_PROPERTY_ERRORS = "errors"; + private List errors = new ArrayList<>(); + + public static final String JSON_PROPERTY_HISTORICAL_BALANCE_LOOKUP = "historical_balance_lookup"; + private Boolean historicalBalanceLookup; + + public static final String JSON_PROPERTY_TIMESTAMP_START_INDEX = "timestamp_start_index"; + private Long timestampStartIndex; + + public static final String JSON_PROPERTY_CALL_METHODS = "call_methods"; + private List callMethods = new ArrayList<>(); + + public static final String JSON_PROPERTY_BALANCE_EXEMPTIONS = "balance_exemptions"; + private List balanceExemptions = new ArrayList<>(); + + public static final String JSON_PROPERTY_MEMPOOL_COINS = "mempool_coins"; + private Boolean mempoolCoins; + + public static final String JSON_PROPERTY_BLOCK_HASH_CASE = "block_hash_case"; + private ModelCase blockHashCase = ModelCase.CASE_SENSITIVE; + + public static final String JSON_PROPERTY_TRANSACTION_HASH_CASE = "transaction_hash_case"; + private ModelCase transactionHashCase = ModelCase.CASE_SENSITIVE; + + public Allow() { + } + + public Allow operationStatuses(List operationStatuses) { + this.operationStatuses = operationStatuses; + return this; + } + + public Allow addOperationStatusesItem(OperationStatus operationStatusesItem) { + this.operationStatuses.add(operationStatusesItem); + return this; + } + + /** + * All Operation.Status this implementation supports. Any status that is returned during parsing that is not listed here will cause client validation to error. + * @return operationStatuses + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "All Operation.Status this implementation supports. Any status that is returned during parsing that is not listed here will cause client validation to error. ") + @JsonProperty(JSON_PROPERTY_OPERATION_STATUSES) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public List getOperationStatuses() { + return operationStatuses; + } + + + @JsonProperty(JSON_PROPERTY_OPERATION_STATUSES) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setOperationStatuses(List operationStatuses) { + this.operationStatuses = operationStatuses; + } + + + public Allow operationTypes(List operationTypes) { + this.operationTypes = operationTypes; + return this; + } + + public Allow addOperationTypesItem(String operationTypesItem) { + this.operationTypes.add(operationTypesItem); + return this; + } + + /** + * All Operation.Type this implementation supports. Any type that is returned during parsing that is not listed here will cause client validation to error. + * @return operationTypes + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "All Operation.Type this implementation supports. Any type that is returned during parsing that is not listed here will cause client validation to error. ") + @JsonProperty(JSON_PROPERTY_OPERATION_TYPES) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public List getOperationTypes() { + return operationTypes; + } + + + @JsonProperty(JSON_PROPERTY_OPERATION_TYPES) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setOperationTypes(List operationTypes) { + this.operationTypes = operationTypes; + } + + + public Allow errors(List errors) { + this.errors = errors; + return this; + } + + public Allow addErrorsItem(Error errorsItem) { + this.errors.add(errorsItem); + return this; + } + + /** + * All Errors that this implementation could return. Any error that is returned during parsing that is not listed here will cause client validation to error. + * @return errors + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "All Errors that this implementation could return. Any error that is returned during parsing that is not listed here will cause client validation to error. ") + @JsonProperty(JSON_PROPERTY_ERRORS) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public List getErrors() { + return errors; + } + + + @JsonProperty(JSON_PROPERTY_ERRORS) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setErrors(List errors) { + this.errors = errors; + } + + + public Allow historicalBalanceLookup(Boolean historicalBalanceLookup) { + this.historicalBalanceLookup = historicalBalanceLookup; + return this; + } + + /** + * Any Rosetta implementation that supports querying the balance of an account at any height in the past should set this to true. + * @return historicalBalanceLookup + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "Any Rosetta implementation that supports querying the balance of an account at any height in the past should set this to true. ") + @JsonProperty(JSON_PROPERTY_HISTORICAL_BALANCE_LOOKUP) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public Boolean getHistoricalBalanceLookup() { + return historicalBalanceLookup; + } + + + @JsonProperty(JSON_PROPERTY_HISTORICAL_BALANCE_LOOKUP) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setHistoricalBalanceLookup(Boolean historicalBalanceLookup) { + this.historicalBalanceLookup = historicalBalanceLookup; + } + + + public Allow timestampStartIndex(Long timestampStartIndex) { + this.timestampStartIndex = timestampStartIndex; + return this; + } + + /** + * If populated, `timestamp_start_index` indicates the first block index where block timestamps are considered valid (i.e. all blocks less than `timestamp_start_index` could have invalid timestamps). This is useful when the genesis block (or blocks) of a network have timestamp 0. If not populated, block timestamps are assumed to be valid for all available blocks. + * minimum: 0 + * @return timestampStartIndex + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "If populated, `timestamp_start_index` indicates the first block index where block timestamps are considered valid (i.e. all blocks less than `timestamp_start_index` could have invalid timestamps). This is useful when the genesis block (or blocks) of a network have timestamp 0. If not populated, block timestamps are assumed to be valid for all available blocks. ") + @JsonProperty(JSON_PROPERTY_TIMESTAMP_START_INDEX) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Long getTimestampStartIndex() { + return timestampStartIndex; + } + + + @JsonProperty(JSON_PROPERTY_TIMESTAMP_START_INDEX) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setTimestampStartIndex(Long timestampStartIndex) { + this.timestampStartIndex = timestampStartIndex; + } + + + public Allow callMethods(List callMethods) { + this.callMethods = callMethods; + return this; + } + + public Allow addCallMethodsItem(String callMethodsItem) { + this.callMethods.add(callMethodsItem); + return this; + } + + /** + * All methods that are supported by the /call endpoint. Communicating which parameters should be provided to /call is the responsibility of the implementer (this is en lieu of defining an entire type system and requiring the implementer to define that in Allow). + * @return callMethods + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "All methods that are supported by the /call endpoint. Communicating which parameters should be provided to /call is the responsibility of the implementer (this is en lieu of defining an entire type system and requiring the implementer to define that in Allow). ") + @JsonProperty(JSON_PROPERTY_CALL_METHODS) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public List getCallMethods() { + return callMethods; + } + + + @JsonProperty(JSON_PROPERTY_CALL_METHODS) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setCallMethods(List callMethods) { + this.callMethods = callMethods; + } + + + public Allow balanceExemptions(List balanceExemptions) { + this.balanceExemptions = balanceExemptions; + return this; + } + + public Allow addBalanceExemptionsItem(BalanceExemption balanceExemptionsItem) { + this.balanceExemptions.add(balanceExemptionsItem); + return this; + } + + /** + * BalanceExemptions is an array of BalanceExemption indicating which account balances could change without a corresponding Operation. BalanceExemptions should be used sparingly as they may introduce significant complexity for integrators that attempt to reconcile all account balance changes. If your implementation relies on any BalanceExemptions, you MUST implement historical balance lookup (the ability to query an account balance at any BlockIdentifier). + * @return balanceExemptions + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "BalanceExemptions is an array of BalanceExemption indicating which account balances could change without a corresponding Operation. BalanceExemptions should be used sparingly as they may introduce significant complexity for integrators that attempt to reconcile all account balance changes. If your implementation relies on any BalanceExemptions, you MUST implement historical balance lookup (the ability to query an account balance at any BlockIdentifier). ") + @JsonProperty(JSON_PROPERTY_BALANCE_EXEMPTIONS) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public List getBalanceExemptions() { + return balanceExemptions; + } + + + @JsonProperty(JSON_PROPERTY_BALANCE_EXEMPTIONS) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setBalanceExemptions(List balanceExemptions) { + this.balanceExemptions = balanceExemptions; + } + + + public Allow mempoolCoins(Boolean mempoolCoins) { + this.mempoolCoins = mempoolCoins; + return this; + } + + /** + * Any Rosetta implementation that can update an AccountIdentifier's unspent coins based on the contents of the mempool should populate this field as true. If false, requests to `/account/coins` that set `include_mempool` as true will be automatically rejected. + * @return mempoolCoins + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "Any Rosetta implementation that can update an AccountIdentifier's unspent coins based on the contents of the mempool should populate this field as true. If false, requests to `/account/coins` that set `include_mempool` as true will be automatically rejected. ") + @JsonProperty(JSON_PROPERTY_MEMPOOL_COINS) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public Boolean getMempoolCoins() { + return mempoolCoins; + } + + + @JsonProperty(JSON_PROPERTY_MEMPOOL_COINS) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setMempoolCoins(Boolean mempoolCoins) { + this.mempoolCoins = mempoolCoins; + } + + + public Allow blockHashCase(ModelCase blockHashCase) { + this.blockHashCase = blockHashCase; + return this; + } + + /** + * Get blockHashCase + * @return blockHashCase + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_BLOCK_HASH_CASE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public ModelCase getBlockHashCase() { + return blockHashCase; + } + + + @JsonProperty(JSON_PROPERTY_BLOCK_HASH_CASE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setBlockHashCase(ModelCase blockHashCase) { + this.blockHashCase = blockHashCase; + } + + + public Allow transactionHashCase(ModelCase transactionHashCase) { + this.transactionHashCase = transactionHashCase; + return this; + } + + /** + * Get transactionHashCase + * @return transactionHashCase + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_TRANSACTION_HASH_CASE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public ModelCase getTransactionHashCase() { + return transactionHashCase; + } + + + @JsonProperty(JSON_PROPERTY_TRANSACTION_HASH_CASE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setTransactionHashCase(ModelCase transactionHashCase) { + this.transactionHashCase = transactionHashCase; + } + + + /** + * Return true if this Allow object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Allow allow = (Allow) o; + return Objects.equals(this.operationStatuses, allow.operationStatuses) && + Objects.equals(this.operationTypes, allow.operationTypes) && + Objects.equals(this.errors, allow.errors) && + Objects.equals(this.historicalBalanceLookup, allow.historicalBalanceLookup) && + Objects.equals(this.timestampStartIndex, allow.timestampStartIndex) && + Objects.equals(this.callMethods, allow.callMethods) && + Objects.equals(this.balanceExemptions, allow.balanceExemptions) && + Objects.equals(this.mempoolCoins, allow.mempoolCoins) && + Objects.equals(this.blockHashCase, allow.blockHashCase) && + Objects.equals(this.transactionHashCase, allow.transactionHashCase); + } + + @Override + public int hashCode() { + return Objects.hash(operationStatuses, operationTypes, errors, historicalBalanceLookup, timestampStartIndex, callMethods, balanceExemptions, mempoolCoins, blockHashCase, transactionHashCase); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Allow {\n"); + sb.append(" operationStatuses: ").append(toIndentedString(operationStatuses)).append("\n"); + sb.append(" operationTypes: ").append(toIndentedString(operationTypes)).append("\n"); + sb.append(" errors: ").append(toIndentedString(errors)).append("\n"); + sb.append(" historicalBalanceLookup: ").append(toIndentedString(historicalBalanceLookup)).append("\n"); + sb.append(" timestampStartIndex: ").append(toIndentedString(timestampStartIndex)).append("\n"); + sb.append(" callMethods: ").append(toIndentedString(callMethods)).append("\n"); + sb.append(" balanceExemptions: ").append(toIndentedString(balanceExemptions)).append("\n"); + sb.append(" mempoolCoins: ").append(toIndentedString(mempoolCoins)).append("\n"); + sb.append(" blockHashCase: ").append(toIndentedString(blockHashCase)).append("\n"); + sb.append(" transactionHashCase: ").append(toIndentedString(transactionHashCase)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/Amount.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/Amount.java new file mode 100644 index 0000000000..a2141bef09 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/Amount.java @@ -0,0 +1,177 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.Currency; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * Amount is some Value of a Currency. It is considered invalid to specify a Value without a Currency. + */ +@ApiModel(description = "Amount is some Value of a Currency. It is considered invalid to specify a Value without a Currency. ") +@JsonPropertyOrder({ + Amount.JSON_PROPERTY_VALUE, + Amount.JSON_PROPERTY_CURRENCY, + Amount.JSON_PROPERTY_METADATA +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class Amount { + public static final String JSON_PROPERTY_VALUE = "value"; + private String value; + + public static final String JSON_PROPERTY_CURRENCY = "currency"; + private Currency currency; + + public static final String JSON_PROPERTY_METADATA = "metadata"; + private Object metadata; + + public Amount() { + } + + public Amount value(String value) { + this.value = value; + return this; + } + + /** + * Value of the transaction in atomic units represented as an arbitrary-sized signed integer. For example, 1 BTC would be represented by a value of 100000000. + * @return value + **/ + @javax.annotation.Nonnull + @ApiModelProperty(example = "1238089899992", required = true, value = "Value of the transaction in atomic units represented as an arbitrary-sized signed integer. For example, 1 BTC would be represented by a value of 100000000. ") + @JsonProperty(JSON_PROPERTY_VALUE) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getValue() { + return value; + } + + + @JsonProperty(JSON_PROPERTY_VALUE) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setValue(String value) { + this.value = value; + } + + + public Amount currency(Currency currency) { + this.currency = currency; + return this; + } + + /** + * Get currency + * @return currency + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_CURRENCY) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public Currency getCurrency() { + return currency; + } + + + @JsonProperty(JSON_PROPERTY_CURRENCY) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setCurrency(Currency currency) { + this.currency = currency; + } + + + public Amount metadata(Object metadata) { + this.metadata = metadata; + return this; + } + + /** + * Get metadata + * @return metadata + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Object getMetadata() { + return metadata; + } + + + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setMetadata(Object metadata) { + this.metadata = metadata; + } + + + /** + * Return true if this Amount object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Amount amount = (Amount) o; + return Objects.equals(this.value, amount.value) && + Objects.equals(this.currency, amount.currency) && + Objects.equals(this.metadata, amount.metadata); + } + + @Override + public int hashCode() { + return Objects.hash(value, currency, metadata); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Amount {\n"); + sb.append(" value: ").append(toIndentedString(value)).append("\n"); + sb.append(" currency: ").append(toIndentedString(currency)).append("\n"); + sb.append(" metadata: ").append(toIndentedString(metadata)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/BalanceExemption.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/BalanceExemption.java new file mode 100644 index 0000000000..71f73498b7 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/BalanceExemption.java @@ -0,0 +1,178 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.Currency; +import com.radixdlt.api.mesh.generated.models.ExemptionType; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * BalanceExemption indicates that the balance for an exempt account could change without a corresponding Operation. This typically occurs with staking rewards, vesting balances, and Currencies with a dynamic supply. Currently, it is possible to exempt an account from strict reconciliation by SubAccountIdentifier.Address or by Currency. This means that any account with SubAccountIdentifier.Address would be exempt or any balance of a particular Currency would be exempt, respectively. BalanceExemptions should be used sparingly as they may introduce significant complexity for integrators that attempt to reconcile all account balance changes. If your implementation relies on any BalanceExemptions, you MUST implement historical balance lookup (the ability to query an account balance at any BlockIdentifier). + */ +@ApiModel(description = "BalanceExemption indicates that the balance for an exempt account could change without a corresponding Operation. This typically occurs with staking rewards, vesting balances, and Currencies with a dynamic supply. Currently, it is possible to exempt an account from strict reconciliation by SubAccountIdentifier.Address or by Currency. This means that any account with SubAccountIdentifier.Address would be exempt or any balance of a particular Currency would be exempt, respectively. BalanceExemptions should be used sparingly as they may introduce significant complexity for integrators that attempt to reconcile all account balance changes. If your implementation relies on any BalanceExemptions, you MUST implement historical balance lookup (the ability to query an account balance at any BlockIdentifier). ") +@JsonPropertyOrder({ + BalanceExemption.JSON_PROPERTY_SUB_ACCOUNT_ADDRESS, + BalanceExemption.JSON_PROPERTY_CURRENCY, + BalanceExemption.JSON_PROPERTY_EXEMPTION_TYPE +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class BalanceExemption { + public static final String JSON_PROPERTY_SUB_ACCOUNT_ADDRESS = "sub_account_address"; + private String subAccountAddress; + + public static final String JSON_PROPERTY_CURRENCY = "currency"; + private Currency currency; + + public static final String JSON_PROPERTY_EXEMPTION_TYPE = "exemption_type"; + private ExemptionType exemptionType; + + public BalanceExemption() { + } + + public BalanceExemption subAccountAddress(String subAccountAddress) { + this.subAccountAddress = subAccountAddress; + return this; + } + + /** + * SubAccountAddress is the SubAccountIdentifier.Address that the BalanceExemption applies to (regardless of the value of SubAccountIdentifier.Metadata). + * @return subAccountAddress + **/ + @javax.annotation.Nullable + @ApiModelProperty(example = "staking", value = "SubAccountAddress is the SubAccountIdentifier.Address that the BalanceExemption applies to (regardless of the value of SubAccountIdentifier.Metadata). ") + @JsonProperty(JSON_PROPERTY_SUB_ACCOUNT_ADDRESS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getSubAccountAddress() { + return subAccountAddress; + } + + + @JsonProperty(JSON_PROPERTY_SUB_ACCOUNT_ADDRESS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setSubAccountAddress(String subAccountAddress) { + this.subAccountAddress = subAccountAddress; + } + + + public BalanceExemption currency(Currency currency) { + this.currency = currency; + return this; + } + + /** + * Get currency + * @return currency + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_CURRENCY) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Currency getCurrency() { + return currency; + } + + + @JsonProperty(JSON_PROPERTY_CURRENCY) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setCurrency(Currency currency) { + this.currency = currency; + } + + + public BalanceExemption exemptionType(ExemptionType exemptionType) { + this.exemptionType = exemptionType; + return this; + } + + /** + * Get exemptionType + * @return exemptionType + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_EXEMPTION_TYPE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public ExemptionType getExemptionType() { + return exemptionType; + } + + + @JsonProperty(JSON_PROPERTY_EXEMPTION_TYPE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setExemptionType(ExemptionType exemptionType) { + this.exemptionType = exemptionType; + } + + + /** + * Return true if this BalanceExemption object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + BalanceExemption balanceExemption = (BalanceExemption) o; + return Objects.equals(this.subAccountAddress, balanceExemption.subAccountAddress) && + Objects.equals(this.currency, balanceExemption.currency) && + Objects.equals(this.exemptionType, balanceExemption.exemptionType); + } + + @Override + public int hashCode() { + return Objects.hash(subAccountAddress, currency, exemptionType); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class BalanceExemption {\n"); + sb.append(" subAccountAddress: ").append(toIndentedString(subAccountAddress)).append("\n"); + sb.append(" currency: ").append(toIndentedString(currency)).append("\n"); + sb.append(" exemptionType: ").append(toIndentedString(exemptionType)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/Block.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/Block.java new file mode 100644 index 0000000000..801b24313b --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/Block.java @@ -0,0 +1,250 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.BlockIdentifier; +import com.radixdlt.api.mesh.generated.models.Transaction; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import java.util.ArrayList; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * Blocks contain an array of Transactions that occurred at a particular BlockIdentifier. A hard requirement for blocks returned by Rosetta implementations is that they MUST be _inalterable_: once a client has requested and received a block identified by a specific BlockIndentifier, all future calls for that same BlockIdentifier must return the same block contents. + */ +@ApiModel(description = "Blocks contain an array of Transactions that occurred at a particular BlockIdentifier. A hard requirement for blocks returned by Rosetta implementations is that they MUST be _inalterable_: once a client has requested and received a block identified by a specific BlockIndentifier, all future calls for that same BlockIdentifier must return the same block contents. ") +@JsonPropertyOrder({ + Block.JSON_PROPERTY_BLOCK_IDENTIFIER, + Block.JSON_PROPERTY_PARENT_BLOCK_IDENTIFIER, + Block.JSON_PROPERTY_TIMESTAMP, + Block.JSON_PROPERTY_TRANSACTIONS, + Block.JSON_PROPERTY_METADATA +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class Block { + public static final String JSON_PROPERTY_BLOCK_IDENTIFIER = "block_identifier"; + private BlockIdentifier blockIdentifier; + + public static final String JSON_PROPERTY_PARENT_BLOCK_IDENTIFIER = "parent_block_identifier"; + private BlockIdentifier parentBlockIdentifier; + + public static final String JSON_PROPERTY_TIMESTAMP = "timestamp"; + private Long timestamp; + + public static final String JSON_PROPERTY_TRANSACTIONS = "transactions"; + private List transactions = new ArrayList<>(); + + public static final String JSON_PROPERTY_METADATA = "metadata"; + private Object metadata; + + public Block() { + } + + public Block blockIdentifier(BlockIdentifier blockIdentifier) { + this.blockIdentifier = blockIdentifier; + return this; + } + + /** + * Get blockIdentifier + * @return blockIdentifier + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_BLOCK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public BlockIdentifier getBlockIdentifier() { + return blockIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_BLOCK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setBlockIdentifier(BlockIdentifier blockIdentifier) { + this.blockIdentifier = blockIdentifier; + } + + + public Block parentBlockIdentifier(BlockIdentifier parentBlockIdentifier) { + this.parentBlockIdentifier = parentBlockIdentifier; + return this; + } + + /** + * Get parentBlockIdentifier + * @return parentBlockIdentifier + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_PARENT_BLOCK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public BlockIdentifier getParentBlockIdentifier() { + return parentBlockIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_PARENT_BLOCK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setParentBlockIdentifier(BlockIdentifier parentBlockIdentifier) { + this.parentBlockIdentifier = parentBlockIdentifier; + } + + + public Block timestamp(Long timestamp) { + this.timestamp = timestamp; + return this; + } + + /** + * The timestamp of the block in milliseconds since the Unix Epoch. The timestamp is stored in milliseconds because some blockchains produce blocks more often than once a second. + * minimum: 0 + * @return timestamp + **/ + @javax.annotation.Nonnull + @ApiModelProperty(example = "1582833600000", required = true, value = "The timestamp of the block in milliseconds since the Unix Epoch. The timestamp is stored in milliseconds because some blockchains produce blocks more often than once a second. ") + @JsonProperty(JSON_PROPERTY_TIMESTAMP) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public Long getTimestamp() { + return timestamp; + } + + + @JsonProperty(JSON_PROPERTY_TIMESTAMP) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setTimestamp(Long timestamp) { + this.timestamp = timestamp; + } + + + public Block transactions(List transactions) { + this.transactions = transactions; + return this; + } + + public Block addTransactionsItem(Transaction transactionsItem) { + this.transactions.add(transactionsItem); + return this; + } + + /** + * Get transactions + * @return transactions + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_TRANSACTIONS) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public List getTransactions() { + return transactions; + } + + + @JsonProperty(JSON_PROPERTY_TRANSACTIONS) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setTransactions(List transactions) { + this.transactions = transactions; + } + + + public Block metadata(Object metadata) { + this.metadata = metadata; + return this; + } + + /** + * Get metadata + * @return metadata + **/ + @javax.annotation.Nullable + @ApiModelProperty(example = "{transactions_root=0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347, difficulty=123891724987128947}", value = "") + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Object getMetadata() { + return metadata; + } + + + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setMetadata(Object metadata) { + this.metadata = metadata; + } + + + /** + * Return true if this Block object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Block block = (Block) o; + return Objects.equals(this.blockIdentifier, block.blockIdentifier) && + Objects.equals(this.parentBlockIdentifier, block.parentBlockIdentifier) && + Objects.equals(this.timestamp, block.timestamp) && + Objects.equals(this.transactions, block.transactions) && + Objects.equals(this.metadata, block.metadata); + } + + @Override + public int hashCode() { + return Objects.hash(blockIdentifier, parentBlockIdentifier, timestamp, transactions, metadata); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Block {\n"); + sb.append(" blockIdentifier: ").append(toIndentedString(blockIdentifier)).append("\n"); + sb.append(" parentBlockIdentifier: ").append(toIndentedString(parentBlockIdentifier)).append("\n"); + sb.append(" timestamp: ").append(toIndentedString(timestamp)).append("\n"); + sb.append(" transactions: ").append(toIndentedString(transactions)).append("\n"); + sb.append(" metadata: ").append(toIndentedString(metadata)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/BlockEvent.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/BlockEvent.java new file mode 100644 index 0000000000..6fcfccc851 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/BlockEvent.java @@ -0,0 +1,179 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.BlockEventType; +import com.radixdlt.api.mesh.generated.models.BlockIdentifier; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * BlockEvent represents the addition or removal of a BlockIdentifier from storage. Streaming BlockEvents allows lightweight clients to update their own state without needing to implement their own syncing logic. + */ +@ApiModel(description = "BlockEvent represents the addition or removal of a BlockIdentifier from storage. Streaming BlockEvents allows lightweight clients to update their own state without needing to implement their own syncing logic. ") +@JsonPropertyOrder({ + BlockEvent.JSON_PROPERTY_SEQUENCE, + BlockEvent.JSON_PROPERTY_BLOCK_IDENTIFIER, + BlockEvent.JSON_PROPERTY_TYPE +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class BlockEvent { + public static final String JSON_PROPERTY_SEQUENCE = "sequence"; + private Long sequence; + + public static final String JSON_PROPERTY_BLOCK_IDENTIFIER = "block_identifier"; + private BlockIdentifier blockIdentifier; + + public static final String JSON_PROPERTY_TYPE = "type"; + private BlockEventType type; + + public BlockEvent() { + } + + public BlockEvent sequence(Long sequence) { + this.sequence = sequence; + return this; + } + + /** + * sequence is the unique identifier of a BlockEvent within the context of a NetworkIdentifier. + * minimum: 0 + * @return sequence + **/ + @javax.annotation.Nonnull + @ApiModelProperty(example = "5", required = true, value = "sequence is the unique identifier of a BlockEvent within the context of a NetworkIdentifier. ") + @JsonProperty(JSON_PROPERTY_SEQUENCE) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public Long getSequence() { + return sequence; + } + + + @JsonProperty(JSON_PROPERTY_SEQUENCE) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setSequence(Long sequence) { + this.sequence = sequence; + } + + + public BlockEvent blockIdentifier(BlockIdentifier blockIdentifier) { + this.blockIdentifier = blockIdentifier; + return this; + } + + /** + * Get blockIdentifier + * @return blockIdentifier + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_BLOCK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public BlockIdentifier getBlockIdentifier() { + return blockIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_BLOCK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setBlockIdentifier(BlockIdentifier blockIdentifier) { + this.blockIdentifier = blockIdentifier; + } + + + public BlockEvent type(BlockEventType type) { + this.type = type; + return this; + } + + /** + * Get type + * @return type + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_TYPE) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public BlockEventType getType() { + return type; + } + + + @JsonProperty(JSON_PROPERTY_TYPE) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setType(BlockEventType type) { + this.type = type; + } + + + /** + * Return true if this BlockEvent object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + BlockEvent blockEvent = (BlockEvent) o; + return Objects.equals(this.sequence, blockEvent.sequence) && + Objects.equals(this.blockIdentifier, blockEvent.blockIdentifier) && + Objects.equals(this.type, blockEvent.type); + } + + @Override + public int hashCode() { + return Objects.hash(sequence, blockIdentifier, type); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class BlockEvent {\n"); + sb.append(" sequence: ").append(toIndentedString(sequence)).append("\n"); + sb.append(" blockIdentifier: ").append(toIndentedString(blockIdentifier)).append("\n"); + sb.append(" type: ").append(toIndentedString(type)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/BlockEventType.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/BlockEventType.java new file mode 100644 index 0000000000..edff01a32d --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/BlockEventType.java @@ -0,0 +1,62 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import io.swagger.annotations.ApiModel; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * BlockEventType determines if a BlockEvent represents the addition or removal of a block. + */ +public enum BlockEventType { + + ADDED("block_added"), + + REMOVED("block_removed"); + + private String value; + + BlockEventType(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static BlockEventType fromValue(String value) { + for (BlockEventType b : BlockEventType.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/BlockIdentifier.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/BlockIdentifier.java new file mode 100644 index 0000000000..5acd346dd7 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/BlockIdentifier.java @@ -0,0 +1,144 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * The block_identifier uniquely identifies a block in a particular network. + */ +@ApiModel(description = "The block_identifier uniquely identifies a block in a particular network. ") +@JsonPropertyOrder({ + BlockIdentifier.JSON_PROPERTY_INDEX, + BlockIdentifier.JSON_PROPERTY_HASH +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class BlockIdentifier { + public static final String JSON_PROPERTY_INDEX = "index"; + private Long index; + + public static final String JSON_PROPERTY_HASH = "hash"; + private String hash; + + public BlockIdentifier() { + } + + public BlockIdentifier index(Long index) { + this.index = index; + return this; + } + + /** + * This is also known as the block height. + * @return index + **/ + @javax.annotation.Nonnull + @ApiModelProperty(example = "1123941", required = true, value = "This is also known as the block height. ") + @JsonProperty(JSON_PROPERTY_INDEX) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public Long getIndex() { + return index; + } + + + @JsonProperty(JSON_PROPERTY_INDEX) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setIndex(Long index) { + this.index = index; + } + + + public BlockIdentifier hash(String hash) { + this.hash = hash; + return this; + } + + /** + * This should be normalized according to the case specified in the block_hash_case network options. + * @return hash + **/ + @javax.annotation.Nonnull + @ApiModelProperty(example = "0x1f2cc6c5027d2f201a5453ad1119574d2aed23a392654742ac3c78783c071f85", required = true, value = "This should be normalized according to the case specified in the block_hash_case network options. ") + @JsonProperty(JSON_PROPERTY_HASH) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getHash() { + return hash; + } + + + @JsonProperty(JSON_PROPERTY_HASH) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setHash(String hash) { + this.hash = hash; + } + + + /** + * Return true if this BlockIdentifier object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + BlockIdentifier blockIdentifier = (BlockIdentifier) o; + return Objects.equals(this.index, blockIdentifier.index) && + Objects.equals(this.hash, blockIdentifier.hash); + } + + @Override + public int hashCode() { + return Objects.hash(index, hash); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class BlockIdentifier {\n"); + sb.append(" index: ").append(toIndentedString(index)).append("\n"); + sb.append(" hash: ").append(toIndentedString(hash)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/BlockRequest.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/BlockRequest.java new file mode 100644 index 0000000000..b119cbe185 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/BlockRequest.java @@ -0,0 +1,146 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.NetworkIdentifier; +import com.radixdlt.api.mesh.generated.models.PartialBlockIdentifier; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * A BlockRequest is utilized to make a block request on the /block endpoint. + */ +@ApiModel(description = "A BlockRequest is utilized to make a block request on the /block endpoint. ") +@JsonPropertyOrder({ + BlockRequest.JSON_PROPERTY_NETWORK_IDENTIFIER, + BlockRequest.JSON_PROPERTY_BLOCK_IDENTIFIER +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class BlockRequest { + public static final String JSON_PROPERTY_NETWORK_IDENTIFIER = "network_identifier"; + private NetworkIdentifier networkIdentifier; + + public static final String JSON_PROPERTY_BLOCK_IDENTIFIER = "block_identifier"; + private PartialBlockIdentifier blockIdentifier; + + public BlockRequest() { + } + + public BlockRequest networkIdentifier(NetworkIdentifier networkIdentifier) { + this.networkIdentifier = networkIdentifier; + return this; + } + + /** + * Get networkIdentifier + * @return networkIdentifier + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_NETWORK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public NetworkIdentifier getNetworkIdentifier() { + return networkIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_NETWORK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setNetworkIdentifier(NetworkIdentifier networkIdentifier) { + this.networkIdentifier = networkIdentifier; + } + + + public BlockRequest blockIdentifier(PartialBlockIdentifier blockIdentifier) { + this.blockIdentifier = blockIdentifier; + return this; + } + + /** + * Get blockIdentifier + * @return blockIdentifier + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_BLOCK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public PartialBlockIdentifier getBlockIdentifier() { + return blockIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_BLOCK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setBlockIdentifier(PartialBlockIdentifier blockIdentifier) { + this.blockIdentifier = blockIdentifier; + } + + + /** + * Return true if this BlockRequest object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + BlockRequest blockRequest = (BlockRequest) o; + return Objects.equals(this.networkIdentifier, blockRequest.networkIdentifier) && + Objects.equals(this.blockIdentifier, blockRequest.blockIdentifier); + } + + @Override + public int hashCode() { + return Objects.hash(networkIdentifier, blockIdentifier); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class BlockRequest {\n"); + sb.append(" networkIdentifier: ").append(toIndentedString(networkIdentifier)).append("\n"); + sb.append(" blockIdentifier: ").append(toIndentedString(blockIdentifier)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/BlockResponse.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/BlockResponse.java new file mode 100644 index 0000000000..cdfea0ca71 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/BlockResponse.java @@ -0,0 +1,156 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.Block; +import com.radixdlt.api.mesh.generated.models.TransactionIdentifier; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import java.util.ArrayList; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * A BlockResponse includes a fully-populated block or a partially-populated block with a list of other transactions to fetch (other_transactions). As a result of the consensus algorithm of some blockchains, blocks can be omitted (i.e. certain block indices can be skipped). If a query for one of these omitted indices is made, the response should not include a `Block` object. It is VERY important to note that blocks MUST still form a canonical, connected chain of blocks where each block has a unique index. In other words, the `PartialBlockIdentifier` of a block after an omitted block should reference the last non-omitted block. + */ +@ApiModel(description = "A BlockResponse includes a fully-populated block or a partially-populated block with a list of other transactions to fetch (other_transactions). As a result of the consensus algorithm of some blockchains, blocks can be omitted (i.e. certain block indices can be skipped). If a query for one of these omitted indices is made, the response should not include a `Block` object. It is VERY important to note that blocks MUST still form a canonical, connected chain of blocks where each block has a unique index. In other words, the `PartialBlockIdentifier` of a block after an omitted block should reference the last non-omitted block. ") +@JsonPropertyOrder({ + BlockResponse.JSON_PROPERTY_BLOCK, + BlockResponse.JSON_PROPERTY_OTHER_TRANSACTIONS +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class BlockResponse { + public static final String JSON_PROPERTY_BLOCK = "block"; + private Block block; + + public static final String JSON_PROPERTY_OTHER_TRANSACTIONS = "other_transactions"; + private List otherTransactions = null; + + public BlockResponse() { + } + + public BlockResponse block(Block block) { + this.block = block; + return this; + } + + /** + * Get block + * @return block + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_BLOCK) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Block getBlock() { + return block; + } + + + @JsonProperty(JSON_PROPERTY_BLOCK) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setBlock(Block block) { + this.block = block; + } + + + public BlockResponse otherTransactions(List otherTransactions) { + this.otherTransactions = otherTransactions; + return this; + } + + public BlockResponse addOtherTransactionsItem(TransactionIdentifier otherTransactionsItem) { + if (this.otherTransactions == null) { + this.otherTransactions = new ArrayList<>(); + } + this.otherTransactions.add(otherTransactionsItem); + return this; + } + + /** + * Some blockchains may require additional transactions to be fetched that weren't returned in the block response (ex: block only returns transaction hashes). For blockchains with a lot of transactions in each block, this can be very useful as consumers can concurrently fetch all transactions returned. + * @return otherTransactions + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "Some blockchains may require additional transactions to be fetched that weren't returned in the block response (ex: block only returns transaction hashes). For blockchains with a lot of transactions in each block, this can be very useful as consumers can concurrently fetch all transactions returned. ") + @JsonProperty(JSON_PROPERTY_OTHER_TRANSACTIONS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public List getOtherTransactions() { + return otherTransactions; + } + + + @JsonProperty(JSON_PROPERTY_OTHER_TRANSACTIONS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setOtherTransactions(List otherTransactions) { + this.otherTransactions = otherTransactions; + } + + + /** + * Return true if this BlockResponse object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + BlockResponse blockResponse = (BlockResponse) o; + return Objects.equals(this.block, blockResponse.block) && + Objects.equals(this.otherTransactions, blockResponse.otherTransactions); + } + + @Override + public int hashCode() { + return Objects.hash(block, otherTransactions); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class BlockResponse {\n"); + sb.append(" block: ").append(toIndentedString(block)).append("\n"); + sb.append(" otherTransactions: ").append(toIndentedString(otherTransactions)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/BlockTransaction.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/BlockTransaction.java new file mode 100644 index 0000000000..73b54cee2c --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/BlockTransaction.java @@ -0,0 +1,146 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.BlockIdentifier; +import com.radixdlt.api.mesh.generated.models.Transaction; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * BlockTransaction contains a populated Transaction and the BlockIdentifier that contains it. + */ +@ApiModel(description = "BlockTransaction contains a populated Transaction and the BlockIdentifier that contains it. ") +@JsonPropertyOrder({ + BlockTransaction.JSON_PROPERTY_BLOCK_IDENTIFIER, + BlockTransaction.JSON_PROPERTY_TRANSACTION +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class BlockTransaction { + public static final String JSON_PROPERTY_BLOCK_IDENTIFIER = "block_identifier"; + private BlockIdentifier blockIdentifier; + + public static final String JSON_PROPERTY_TRANSACTION = "transaction"; + private Transaction transaction; + + public BlockTransaction() { + } + + public BlockTransaction blockIdentifier(BlockIdentifier blockIdentifier) { + this.blockIdentifier = blockIdentifier; + return this; + } + + /** + * Get blockIdentifier + * @return blockIdentifier + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_BLOCK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public BlockIdentifier getBlockIdentifier() { + return blockIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_BLOCK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setBlockIdentifier(BlockIdentifier blockIdentifier) { + this.blockIdentifier = blockIdentifier; + } + + + public BlockTransaction transaction(Transaction transaction) { + this.transaction = transaction; + return this; + } + + /** + * Get transaction + * @return transaction + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_TRANSACTION) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public Transaction getTransaction() { + return transaction; + } + + + @JsonProperty(JSON_PROPERTY_TRANSACTION) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setTransaction(Transaction transaction) { + this.transaction = transaction; + } + + + /** + * Return true if this BlockTransaction object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + BlockTransaction blockTransaction = (BlockTransaction) o; + return Objects.equals(this.blockIdentifier, blockTransaction.blockIdentifier) && + Objects.equals(this.transaction, blockTransaction.transaction); + } + + @Override + public int hashCode() { + return Objects.hash(blockIdentifier, transaction); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class BlockTransaction {\n"); + sb.append(" blockIdentifier: ").append(toIndentedString(blockIdentifier)).append("\n"); + sb.append(" transaction: ").append(toIndentedString(transaction)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/BlockTransactionRequest.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/BlockTransactionRequest.java new file mode 100644 index 0000000000..86211c0331 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/BlockTransactionRequest.java @@ -0,0 +1,179 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.BlockIdentifier; +import com.radixdlt.api.mesh.generated.models.NetworkIdentifier; +import com.radixdlt.api.mesh.generated.models.TransactionIdentifier; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * A BlockTransactionRequest is used to fetch a Transaction included in a block that is not returned in a BlockResponse. + */ +@ApiModel(description = "A BlockTransactionRequest is used to fetch a Transaction included in a block that is not returned in a BlockResponse. ") +@JsonPropertyOrder({ + BlockTransactionRequest.JSON_PROPERTY_NETWORK_IDENTIFIER, + BlockTransactionRequest.JSON_PROPERTY_BLOCK_IDENTIFIER, + BlockTransactionRequest.JSON_PROPERTY_TRANSACTION_IDENTIFIER +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class BlockTransactionRequest { + public static final String JSON_PROPERTY_NETWORK_IDENTIFIER = "network_identifier"; + private NetworkIdentifier networkIdentifier; + + public static final String JSON_PROPERTY_BLOCK_IDENTIFIER = "block_identifier"; + private BlockIdentifier blockIdentifier; + + public static final String JSON_PROPERTY_TRANSACTION_IDENTIFIER = "transaction_identifier"; + private TransactionIdentifier transactionIdentifier; + + public BlockTransactionRequest() { + } + + public BlockTransactionRequest networkIdentifier(NetworkIdentifier networkIdentifier) { + this.networkIdentifier = networkIdentifier; + return this; + } + + /** + * Get networkIdentifier + * @return networkIdentifier + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_NETWORK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public NetworkIdentifier getNetworkIdentifier() { + return networkIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_NETWORK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setNetworkIdentifier(NetworkIdentifier networkIdentifier) { + this.networkIdentifier = networkIdentifier; + } + + + public BlockTransactionRequest blockIdentifier(BlockIdentifier blockIdentifier) { + this.blockIdentifier = blockIdentifier; + return this; + } + + /** + * Get blockIdentifier + * @return blockIdentifier + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_BLOCK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public BlockIdentifier getBlockIdentifier() { + return blockIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_BLOCK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setBlockIdentifier(BlockIdentifier blockIdentifier) { + this.blockIdentifier = blockIdentifier; + } + + + public BlockTransactionRequest transactionIdentifier(TransactionIdentifier transactionIdentifier) { + this.transactionIdentifier = transactionIdentifier; + return this; + } + + /** + * Get transactionIdentifier + * @return transactionIdentifier + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_TRANSACTION_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public TransactionIdentifier getTransactionIdentifier() { + return transactionIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_TRANSACTION_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setTransactionIdentifier(TransactionIdentifier transactionIdentifier) { + this.transactionIdentifier = transactionIdentifier; + } + + + /** + * Return true if this BlockTransactionRequest object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + BlockTransactionRequest blockTransactionRequest = (BlockTransactionRequest) o; + return Objects.equals(this.networkIdentifier, blockTransactionRequest.networkIdentifier) && + Objects.equals(this.blockIdentifier, blockTransactionRequest.blockIdentifier) && + Objects.equals(this.transactionIdentifier, blockTransactionRequest.transactionIdentifier); + } + + @Override + public int hashCode() { + return Objects.hash(networkIdentifier, blockIdentifier, transactionIdentifier); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class BlockTransactionRequest {\n"); + sb.append(" networkIdentifier: ").append(toIndentedString(networkIdentifier)).append("\n"); + sb.append(" blockIdentifier: ").append(toIndentedString(blockIdentifier)).append("\n"); + sb.append(" transactionIdentifier: ").append(toIndentedString(transactionIdentifier)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/BlockTransactionResponse.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/BlockTransactionResponse.java new file mode 100644 index 0000000000..5e53b8a768 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/BlockTransactionResponse.java @@ -0,0 +1,113 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.Transaction; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * A BlockTransactionResponse contains information about a block transaction. + */ +@ApiModel(description = "A BlockTransactionResponse contains information about a block transaction. ") +@JsonPropertyOrder({ + BlockTransactionResponse.JSON_PROPERTY_TRANSACTION +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class BlockTransactionResponse { + public static final String JSON_PROPERTY_TRANSACTION = "transaction"; + private Transaction transaction; + + public BlockTransactionResponse() { + } + + public BlockTransactionResponse transaction(Transaction transaction) { + this.transaction = transaction; + return this; + } + + /** + * Get transaction + * @return transaction + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_TRANSACTION) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public Transaction getTransaction() { + return transaction; + } + + + @JsonProperty(JSON_PROPERTY_TRANSACTION) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setTransaction(Transaction transaction) { + this.transaction = transaction; + } + + + /** + * Return true if this BlockTransactionResponse object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + BlockTransactionResponse blockTransactionResponse = (BlockTransactionResponse) o; + return Objects.equals(this.transaction, blockTransactionResponse.transaction); + } + + @Override + public int hashCode() { + return Objects.hash(transaction); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class BlockTransactionResponse {\n"); + sb.append(" transaction: ").append(toIndentedString(transaction)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/CallRequest.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/CallRequest.java new file mode 100644 index 0000000000..550974bc81 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/CallRequest.java @@ -0,0 +1,177 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.NetworkIdentifier; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * CallRequest is the input to the `/call` endpoint. + */ +@ApiModel(description = "CallRequest is the input to the `/call` endpoint. ") +@JsonPropertyOrder({ + CallRequest.JSON_PROPERTY_NETWORK_IDENTIFIER, + CallRequest.JSON_PROPERTY_METHOD, + CallRequest.JSON_PROPERTY_PARAMETERS +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class CallRequest { + public static final String JSON_PROPERTY_NETWORK_IDENTIFIER = "network_identifier"; + private NetworkIdentifier networkIdentifier; + + public static final String JSON_PROPERTY_METHOD = "method"; + private String method; + + public static final String JSON_PROPERTY_PARAMETERS = "parameters"; + private Object parameters; + + public CallRequest() { + } + + public CallRequest networkIdentifier(NetworkIdentifier networkIdentifier) { + this.networkIdentifier = networkIdentifier; + return this; + } + + /** + * Get networkIdentifier + * @return networkIdentifier + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_NETWORK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public NetworkIdentifier getNetworkIdentifier() { + return networkIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_NETWORK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setNetworkIdentifier(NetworkIdentifier networkIdentifier) { + this.networkIdentifier = networkIdentifier; + } + + + public CallRequest method(String method) { + this.method = method; + return this; + } + + /** + * Method is some network-specific procedure call. This method could map to a network-specific RPC endpoint, a method in an SDK generated from a smart contract, or some hybrid of the two. The implementation must define all available methods in the Allow object. However, it is up to the caller to determine which parameters to provide when invoking `/call`. + * @return method + **/ + @javax.annotation.Nonnull + @ApiModelProperty(example = "eth_call", required = true, value = "Method is some network-specific procedure call. This method could map to a network-specific RPC endpoint, a method in an SDK generated from a smart contract, or some hybrid of the two. The implementation must define all available methods in the Allow object. However, it is up to the caller to determine which parameters to provide when invoking `/call`. ") + @JsonProperty(JSON_PROPERTY_METHOD) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getMethod() { + return method; + } + + + @JsonProperty(JSON_PROPERTY_METHOD) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setMethod(String method) { + this.method = method; + } + + + public CallRequest parameters(Object parameters) { + this.parameters = parameters; + return this; + } + + /** + * Parameters is some network-specific argument for a method. It is up to the caller to determine which parameters to provide when invoking `/call`. + * @return parameters + **/ + @javax.annotation.Nonnull + @ApiModelProperty(example = "{\"block_number\":23,\"address\":\"0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5\"}", required = true, value = "Parameters is some network-specific argument for a method. It is up to the caller to determine which parameters to provide when invoking `/call`. ") + @JsonProperty(JSON_PROPERTY_PARAMETERS) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public Object getParameters() { + return parameters; + } + + + @JsonProperty(JSON_PROPERTY_PARAMETERS) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setParameters(Object parameters) { + this.parameters = parameters; + } + + + /** + * Return true if this CallRequest object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + CallRequest callRequest = (CallRequest) o; + return Objects.equals(this.networkIdentifier, callRequest.networkIdentifier) && + Objects.equals(this.method, callRequest.method) && + Objects.equals(this.parameters, callRequest.parameters); + } + + @Override + public int hashCode() { + return Objects.hash(networkIdentifier, method, parameters); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class CallRequest {\n"); + sb.append(" networkIdentifier: ").append(toIndentedString(networkIdentifier)).append("\n"); + sb.append(" method: ").append(toIndentedString(method)).append("\n"); + sb.append(" parameters: ").append(toIndentedString(parameters)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/CallResponse.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/CallResponse.java new file mode 100644 index 0000000000..0a6546c23c --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/CallResponse.java @@ -0,0 +1,144 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * CallResponse contains the result of a `/call` invocation. + */ +@ApiModel(description = "CallResponse contains the result of a `/call` invocation. ") +@JsonPropertyOrder({ + CallResponse.JSON_PROPERTY_RESULT, + CallResponse.JSON_PROPERTY_IDEMPOTENT +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class CallResponse { + public static final String JSON_PROPERTY_RESULT = "result"; + private Object result; + + public static final String JSON_PROPERTY_IDEMPOTENT = "idempotent"; + private Boolean idempotent; + + public CallResponse() { + } + + public CallResponse result(Object result) { + this.result = result; + return this; + } + + /** + * Result contains the result of the `/call` invocation. This result will not be inspected or interpreted by Rosetta tooling and is left to the caller to decode. + * @return result + **/ + @javax.annotation.Nonnull + @ApiModelProperty(example = "{\"count\":1000}", required = true, value = "Result contains the result of the `/call` invocation. This result will not be inspected or interpreted by Rosetta tooling and is left to the caller to decode. ") + @JsonProperty(JSON_PROPERTY_RESULT) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public Object getResult() { + return result; + } + + + @JsonProperty(JSON_PROPERTY_RESULT) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setResult(Object result) { + this.result = result; + } + + + public CallResponse idempotent(Boolean idempotent) { + this.idempotent = idempotent; + return this; + } + + /** + * Idempotent indicates that if `/call` is invoked with the same CallRequest again, at any point in time, it will return the same CallResponse. Integrators may cache the CallResponse if this is set to true to avoid making unnecessary calls to the Rosetta implementation. For this reason, implementers should be very conservative about returning true here or they could cause issues for the caller. + * @return idempotent + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "Idempotent indicates that if `/call` is invoked with the same CallRequest again, at any point in time, it will return the same CallResponse. Integrators may cache the CallResponse if this is set to true to avoid making unnecessary calls to the Rosetta implementation. For this reason, implementers should be very conservative about returning true here or they could cause issues for the caller. ") + @JsonProperty(JSON_PROPERTY_IDEMPOTENT) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public Boolean getIdempotent() { + return idempotent; + } + + + @JsonProperty(JSON_PROPERTY_IDEMPOTENT) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setIdempotent(Boolean idempotent) { + this.idempotent = idempotent; + } + + + /** + * Return true if this CallResponse object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + CallResponse callResponse = (CallResponse) o; + return Objects.equals(this.result, callResponse.result) && + Objects.equals(this.idempotent, callResponse.idempotent); + } + + @Override + public int hashCode() { + return Objects.hash(result, idempotent); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class CallResponse {\n"); + sb.append(" result: ").append(toIndentedString(result)).append("\n"); + sb.append(" idempotent: ").append(toIndentedString(idempotent)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/Coin.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/Coin.java new file mode 100644 index 0000000000..8c9070b76a --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/Coin.java @@ -0,0 +1,146 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.Amount; +import com.radixdlt.api.mesh.generated.models.CoinIdentifier; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * Coin contains its unique identifier and the amount it represents. + */ +@ApiModel(description = "Coin contains its unique identifier and the amount it represents. ") +@JsonPropertyOrder({ + Coin.JSON_PROPERTY_COIN_IDENTIFIER, + Coin.JSON_PROPERTY_AMOUNT +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class Coin { + public static final String JSON_PROPERTY_COIN_IDENTIFIER = "coin_identifier"; + private CoinIdentifier coinIdentifier; + + public static final String JSON_PROPERTY_AMOUNT = "amount"; + private Amount amount; + + public Coin() { + } + + public Coin coinIdentifier(CoinIdentifier coinIdentifier) { + this.coinIdentifier = coinIdentifier; + return this; + } + + /** + * Get coinIdentifier + * @return coinIdentifier + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_COIN_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public CoinIdentifier getCoinIdentifier() { + return coinIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_COIN_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setCoinIdentifier(CoinIdentifier coinIdentifier) { + this.coinIdentifier = coinIdentifier; + } + + + public Coin amount(Amount amount) { + this.amount = amount; + return this; + } + + /** + * Get amount + * @return amount + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_AMOUNT) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public Amount getAmount() { + return amount; + } + + + @JsonProperty(JSON_PROPERTY_AMOUNT) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setAmount(Amount amount) { + this.amount = amount; + } + + + /** + * Return true if this Coin object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Coin coin = (Coin) o; + return Objects.equals(this.coinIdentifier, coin.coinIdentifier) && + Objects.equals(this.amount, coin.amount); + } + + @Override + public int hashCode() { + return Objects.hash(coinIdentifier, amount); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Coin {\n"); + sb.append(" coinIdentifier: ").append(toIndentedString(coinIdentifier)).append("\n"); + sb.append(" amount: ").append(toIndentedString(amount)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/CoinAction.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/CoinAction.java new file mode 100644 index 0000000000..6d989313e6 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/CoinAction.java @@ -0,0 +1,62 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import io.swagger.annotations.ApiModel; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * CoinActions are different state changes that a Coin can undergo. When a Coin is created, it is coin_created. When a Coin is spent, it is coin_spent. It is assumed that a single Coin cannot be created or spent more than once. + */ +public enum CoinAction { + + CREATED("coin_created"), + + SPENT("coin_spent"); + + private String value; + + CoinAction(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static CoinAction fromValue(String value) { + for (CoinAction b : CoinAction.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/CoinChange.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/CoinChange.java new file mode 100644 index 0000000000..2d69bb8d32 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/CoinChange.java @@ -0,0 +1,146 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.CoinAction; +import com.radixdlt.api.mesh.generated.models.CoinIdentifier; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * CoinChange is used to represent a change in state of a some coin identified by a coin_identifier. This object is part of the Operation model and must be populated for UTXO-based blockchains. Coincidentally, this abstraction of UTXOs allows for supporting both account-based transfers and UTXO-based transfers on the same blockchain (when a transfer is account-based, don't populate this model). + */ +@ApiModel(description = "CoinChange is used to represent a change in state of a some coin identified by a coin_identifier. This object is part of the Operation model and must be populated for UTXO-based blockchains. Coincidentally, this abstraction of UTXOs allows for supporting both account-based transfers and UTXO-based transfers on the same blockchain (when a transfer is account-based, don't populate this model). ") +@JsonPropertyOrder({ + CoinChange.JSON_PROPERTY_COIN_IDENTIFIER, + CoinChange.JSON_PROPERTY_COIN_ACTION +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class CoinChange { + public static final String JSON_PROPERTY_COIN_IDENTIFIER = "coin_identifier"; + private CoinIdentifier coinIdentifier; + + public static final String JSON_PROPERTY_COIN_ACTION = "coin_action"; + private CoinAction coinAction; + + public CoinChange() { + } + + public CoinChange coinIdentifier(CoinIdentifier coinIdentifier) { + this.coinIdentifier = coinIdentifier; + return this; + } + + /** + * Get coinIdentifier + * @return coinIdentifier + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_COIN_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public CoinIdentifier getCoinIdentifier() { + return coinIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_COIN_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setCoinIdentifier(CoinIdentifier coinIdentifier) { + this.coinIdentifier = coinIdentifier; + } + + + public CoinChange coinAction(CoinAction coinAction) { + this.coinAction = coinAction; + return this; + } + + /** + * Get coinAction + * @return coinAction + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_COIN_ACTION) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public CoinAction getCoinAction() { + return coinAction; + } + + + @JsonProperty(JSON_PROPERTY_COIN_ACTION) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setCoinAction(CoinAction coinAction) { + this.coinAction = coinAction; + } + + + /** + * Return true if this CoinChange object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + CoinChange coinChange = (CoinChange) o; + return Objects.equals(this.coinIdentifier, coinChange.coinIdentifier) && + Objects.equals(this.coinAction, coinChange.coinAction); + } + + @Override + public int hashCode() { + return Objects.hash(coinIdentifier, coinAction); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class CoinChange {\n"); + sb.append(" coinIdentifier: ").append(toIndentedString(coinIdentifier)).append("\n"); + sb.append(" coinAction: ").append(toIndentedString(coinAction)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/CoinIdentifier.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/CoinIdentifier.java new file mode 100644 index 0000000000..315783c0e1 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/CoinIdentifier.java @@ -0,0 +1,112 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * CoinIdentifier uniquely identifies a Coin. + */ +@ApiModel(description = "CoinIdentifier uniquely identifies a Coin. ") +@JsonPropertyOrder({ + CoinIdentifier.JSON_PROPERTY_IDENTIFIER +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class CoinIdentifier { + public static final String JSON_PROPERTY_IDENTIFIER = "identifier"; + private String identifier; + + public CoinIdentifier() { + } + + public CoinIdentifier identifier(String identifier) { + this.identifier = identifier; + return this; + } + + /** + * Identifier should be populated with a globally unique identifier of a Coin. In Bitcoin, this identifier would be transaction_hash:index. + * @return identifier + **/ + @javax.annotation.Nonnull + @ApiModelProperty(example = "0x2f23fd8cca835af21f3ac375bac601f97ead75f2e79143bdf71fe2c4be043e8f:1", required = true, value = "Identifier should be populated with a globally unique identifier of a Coin. In Bitcoin, this identifier would be transaction_hash:index. ") + @JsonProperty(JSON_PROPERTY_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getIdentifier() { + return identifier; + } + + + @JsonProperty(JSON_PROPERTY_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setIdentifier(String identifier) { + this.identifier = identifier; + } + + + /** + * Return true if this CoinIdentifier object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + CoinIdentifier coinIdentifier = (CoinIdentifier) o; + return Objects.equals(this.identifier, coinIdentifier.identifier); + } + + @Override + public int hashCode() { + return Objects.hash(identifier); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class CoinIdentifier {\n"); + sb.append(" identifier: ").append(toIndentedString(identifier)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ConstructionCombineRequest.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ConstructionCombineRequest.java new file mode 100644 index 0000000000..d053fbb727 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ConstructionCombineRequest.java @@ -0,0 +1,185 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.NetworkIdentifier; +import com.radixdlt.api.mesh.generated.models.Signature; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import java.util.ArrayList; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * ConstructionCombineRequest is the input to the `/construction/combine` endpoint. It contains the unsigned transaction blob returned by `/construction/payloads` and all required signatures to create a network transaction. + */ +@ApiModel(description = "ConstructionCombineRequest is the input to the `/construction/combine` endpoint. It contains the unsigned transaction blob returned by `/construction/payloads` and all required signatures to create a network transaction. ") +@JsonPropertyOrder({ + ConstructionCombineRequest.JSON_PROPERTY_NETWORK_IDENTIFIER, + ConstructionCombineRequest.JSON_PROPERTY_UNSIGNED_TRANSACTION, + ConstructionCombineRequest.JSON_PROPERTY_SIGNATURES +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class ConstructionCombineRequest { + public static final String JSON_PROPERTY_NETWORK_IDENTIFIER = "network_identifier"; + private NetworkIdentifier networkIdentifier; + + public static final String JSON_PROPERTY_UNSIGNED_TRANSACTION = "unsigned_transaction"; + private String unsignedTransaction; + + public static final String JSON_PROPERTY_SIGNATURES = "signatures"; + private List signatures = new ArrayList<>(); + + public ConstructionCombineRequest() { + } + + public ConstructionCombineRequest networkIdentifier(NetworkIdentifier networkIdentifier) { + this.networkIdentifier = networkIdentifier; + return this; + } + + /** + * Get networkIdentifier + * @return networkIdentifier + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_NETWORK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public NetworkIdentifier getNetworkIdentifier() { + return networkIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_NETWORK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setNetworkIdentifier(NetworkIdentifier networkIdentifier) { + this.networkIdentifier = networkIdentifier; + } + + + public ConstructionCombineRequest unsignedTransaction(String unsignedTransaction) { + this.unsignedTransaction = unsignedTransaction; + return this; + } + + /** + * Get unsignedTransaction + * @return unsignedTransaction + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_UNSIGNED_TRANSACTION) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getUnsignedTransaction() { + return unsignedTransaction; + } + + + @JsonProperty(JSON_PROPERTY_UNSIGNED_TRANSACTION) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setUnsignedTransaction(String unsignedTransaction) { + this.unsignedTransaction = unsignedTransaction; + } + + + public ConstructionCombineRequest signatures(List signatures) { + this.signatures = signatures; + return this; + } + + public ConstructionCombineRequest addSignaturesItem(Signature signaturesItem) { + this.signatures.add(signaturesItem); + return this; + } + + /** + * Get signatures + * @return signatures + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_SIGNATURES) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public List getSignatures() { + return signatures; + } + + + @JsonProperty(JSON_PROPERTY_SIGNATURES) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setSignatures(List signatures) { + this.signatures = signatures; + } + + + /** + * Return true if this ConstructionCombineRequest object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ConstructionCombineRequest constructionCombineRequest = (ConstructionCombineRequest) o; + return Objects.equals(this.networkIdentifier, constructionCombineRequest.networkIdentifier) && + Objects.equals(this.unsignedTransaction, constructionCombineRequest.unsignedTransaction) && + Objects.equals(this.signatures, constructionCombineRequest.signatures); + } + + @Override + public int hashCode() { + return Objects.hash(networkIdentifier, unsignedTransaction, signatures); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ConstructionCombineRequest {\n"); + sb.append(" networkIdentifier: ").append(toIndentedString(networkIdentifier)).append("\n"); + sb.append(" unsignedTransaction: ").append(toIndentedString(unsignedTransaction)).append("\n"); + sb.append(" signatures: ").append(toIndentedString(signatures)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ConstructionCombineResponse.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ConstructionCombineResponse.java new file mode 100644 index 0000000000..330c2daca0 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ConstructionCombineResponse.java @@ -0,0 +1,112 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * ConstructionCombineResponse is returned by `/construction/combine`. The network payload will be sent directly to the `construction/submit` endpoint. + */ +@ApiModel(description = "ConstructionCombineResponse is returned by `/construction/combine`. The network payload will be sent directly to the `construction/submit` endpoint. ") +@JsonPropertyOrder({ + ConstructionCombineResponse.JSON_PROPERTY_SIGNED_TRANSACTION +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class ConstructionCombineResponse { + public static final String JSON_PROPERTY_SIGNED_TRANSACTION = "signed_transaction"; + private String signedTransaction; + + public ConstructionCombineResponse() { + } + + public ConstructionCombineResponse signedTransaction(String signedTransaction) { + this.signedTransaction = signedTransaction; + return this; + } + + /** + * Get signedTransaction + * @return signedTransaction + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_SIGNED_TRANSACTION) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getSignedTransaction() { + return signedTransaction; + } + + + @JsonProperty(JSON_PROPERTY_SIGNED_TRANSACTION) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setSignedTransaction(String signedTransaction) { + this.signedTransaction = signedTransaction; + } + + + /** + * Return true if this ConstructionCombineResponse object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ConstructionCombineResponse constructionCombineResponse = (ConstructionCombineResponse) o; + return Objects.equals(this.signedTransaction, constructionCombineResponse.signedTransaction); + } + + @Override + public int hashCode() { + return Objects.hash(signedTransaction); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ConstructionCombineResponse {\n"); + sb.append(" signedTransaction: ").append(toIndentedString(signedTransaction)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ConstructionDeriveRequest.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ConstructionDeriveRequest.java new file mode 100644 index 0000000000..b9ee3101c6 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ConstructionDeriveRequest.java @@ -0,0 +1,178 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.NetworkIdentifier; +import com.radixdlt.api.mesh.generated.models.PublicKey; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * ConstructionDeriveRequest is passed to the `/construction/derive` endpoint. Network is provided in the request because some blockchains have different address formats for different networks. Metadata is provided in the request because some blockchains allow for multiple address types (i.e. different address for validators vs normal accounts). + */ +@ApiModel(description = "ConstructionDeriveRequest is passed to the `/construction/derive` endpoint. Network is provided in the request because some blockchains have different address formats for different networks. Metadata is provided in the request because some blockchains allow for multiple address types (i.e. different address for validators vs normal accounts). ") +@JsonPropertyOrder({ + ConstructionDeriveRequest.JSON_PROPERTY_NETWORK_IDENTIFIER, + ConstructionDeriveRequest.JSON_PROPERTY_PUBLIC_KEY, + ConstructionDeriveRequest.JSON_PROPERTY_METADATA +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class ConstructionDeriveRequest { + public static final String JSON_PROPERTY_NETWORK_IDENTIFIER = "network_identifier"; + private NetworkIdentifier networkIdentifier; + + public static final String JSON_PROPERTY_PUBLIC_KEY = "public_key"; + private PublicKey publicKey; + + public static final String JSON_PROPERTY_METADATA = "metadata"; + private Object metadata; + + public ConstructionDeriveRequest() { + } + + public ConstructionDeriveRequest networkIdentifier(NetworkIdentifier networkIdentifier) { + this.networkIdentifier = networkIdentifier; + return this; + } + + /** + * Get networkIdentifier + * @return networkIdentifier + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_NETWORK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public NetworkIdentifier getNetworkIdentifier() { + return networkIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_NETWORK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setNetworkIdentifier(NetworkIdentifier networkIdentifier) { + this.networkIdentifier = networkIdentifier; + } + + + public ConstructionDeriveRequest publicKey(PublicKey publicKey) { + this.publicKey = publicKey; + return this; + } + + /** + * Get publicKey + * @return publicKey + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_PUBLIC_KEY) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public PublicKey getPublicKey() { + return publicKey; + } + + + @JsonProperty(JSON_PROPERTY_PUBLIC_KEY) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setPublicKey(PublicKey publicKey) { + this.publicKey = publicKey; + } + + + public ConstructionDeriveRequest metadata(Object metadata) { + this.metadata = metadata; + return this; + } + + /** + * Get metadata + * @return metadata + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Object getMetadata() { + return metadata; + } + + + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setMetadata(Object metadata) { + this.metadata = metadata; + } + + + /** + * Return true if this ConstructionDeriveRequest object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ConstructionDeriveRequest constructionDeriveRequest = (ConstructionDeriveRequest) o; + return Objects.equals(this.networkIdentifier, constructionDeriveRequest.networkIdentifier) && + Objects.equals(this.publicKey, constructionDeriveRequest.publicKey) && + Objects.equals(this.metadata, constructionDeriveRequest.metadata); + } + + @Override + public int hashCode() { + return Objects.hash(networkIdentifier, publicKey, metadata); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ConstructionDeriveRequest {\n"); + sb.append(" networkIdentifier: ").append(toIndentedString(networkIdentifier)).append("\n"); + sb.append(" publicKey: ").append(toIndentedString(publicKey)).append("\n"); + sb.append(" metadata: ").append(toIndentedString(metadata)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ConstructionDeriveResponse.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ConstructionDeriveResponse.java new file mode 100644 index 0000000000..3a4d2dde52 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ConstructionDeriveResponse.java @@ -0,0 +1,177 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.AccountIdentifier; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * ConstructionDeriveResponse is returned by the `/construction/derive` endpoint. + */ +@ApiModel(description = "ConstructionDeriveResponse is returned by the `/construction/derive` endpoint. ") +@JsonPropertyOrder({ + ConstructionDeriveResponse.JSON_PROPERTY_ADDRESS, + ConstructionDeriveResponse.JSON_PROPERTY_ACCOUNT_IDENTIFIER, + ConstructionDeriveResponse.JSON_PROPERTY_METADATA +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class ConstructionDeriveResponse { + public static final String JSON_PROPERTY_ADDRESS = "address"; + private String address; + + public static final String JSON_PROPERTY_ACCOUNT_IDENTIFIER = "account_identifier"; + private AccountIdentifier accountIdentifier; + + public static final String JSON_PROPERTY_METADATA = "metadata"; + private Object metadata; + + public ConstructionDeriveResponse() { + } + + public ConstructionDeriveResponse address(String address) { + this.address = address; + return this; + } + + /** + * [DEPRECATED by `account_identifier` in `v1.4.4`] Address in network-specific format. + * @return address + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "[DEPRECATED by `account_identifier` in `v1.4.4`] Address in network-specific format. ") + @JsonProperty(JSON_PROPERTY_ADDRESS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getAddress() { + return address; + } + + + @JsonProperty(JSON_PROPERTY_ADDRESS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setAddress(String address) { + this.address = address; + } + + + public ConstructionDeriveResponse accountIdentifier(AccountIdentifier accountIdentifier) { + this.accountIdentifier = accountIdentifier; + return this; + } + + /** + * Get accountIdentifier + * @return accountIdentifier + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_ACCOUNT_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public AccountIdentifier getAccountIdentifier() { + return accountIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_ACCOUNT_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setAccountIdentifier(AccountIdentifier accountIdentifier) { + this.accountIdentifier = accountIdentifier; + } + + + public ConstructionDeriveResponse metadata(Object metadata) { + this.metadata = metadata; + return this; + } + + /** + * Get metadata + * @return metadata + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Object getMetadata() { + return metadata; + } + + + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setMetadata(Object metadata) { + this.metadata = metadata; + } + + + /** + * Return true if this ConstructionDeriveResponse object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ConstructionDeriveResponse constructionDeriveResponse = (ConstructionDeriveResponse) o; + return Objects.equals(this.address, constructionDeriveResponse.address) && + Objects.equals(this.accountIdentifier, constructionDeriveResponse.accountIdentifier) && + Objects.equals(this.metadata, constructionDeriveResponse.metadata); + } + + @Override + public int hashCode() { + return Objects.hash(address, accountIdentifier, metadata); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ConstructionDeriveResponse {\n"); + sb.append(" address: ").append(toIndentedString(address)).append("\n"); + sb.append(" accountIdentifier: ").append(toIndentedString(accountIdentifier)).append("\n"); + sb.append(" metadata: ").append(toIndentedString(metadata)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ConstructionHashRequest.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ConstructionHashRequest.java new file mode 100644 index 0000000000..25ee6e07b0 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ConstructionHashRequest.java @@ -0,0 +1,145 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.NetworkIdentifier; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * ConstructionHashRequest is the input to the `/construction/hash` endpoint. + */ +@ApiModel(description = "ConstructionHashRequest is the input to the `/construction/hash` endpoint. ") +@JsonPropertyOrder({ + ConstructionHashRequest.JSON_PROPERTY_NETWORK_IDENTIFIER, + ConstructionHashRequest.JSON_PROPERTY_SIGNED_TRANSACTION +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class ConstructionHashRequest { + public static final String JSON_PROPERTY_NETWORK_IDENTIFIER = "network_identifier"; + private NetworkIdentifier networkIdentifier; + + public static final String JSON_PROPERTY_SIGNED_TRANSACTION = "signed_transaction"; + private String signedTransaction; + + public ConstructionHashRequest() { + } + + public ConstructionHashRequest networkIdentifier(NetworkIdentifier networkIdentifier) { + this.networkIdentifier = networkIdentifier; + return this; + } + + /** + * Get networkIdentifier + * @return networkIdentifier + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_NETWORK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public NetworkIdentifier getNetworkIdentifier() { + return networkIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_NETWORK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setNetworkIdentifier(NetworkIdentifier networkIdentifier) { + this.networkIdentifier = networkIdentifier; + } + + + public ConstructionHashRequest signedTransaction(String signedTransaction) { + this.signedTransaction = signedTransaction; + return this; + } + + /** + * Get signedTransaction + * @return signedTransaction + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_SIGNED_TRANSACTION) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getSignedTransaction() { + return signedTransaction; + } + + + @JsonProperty(JSON_PROPERTY_SIGNED_TRANSACTION) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setSignedTransaction(String signedTransaction) { + this.signedTransaction = signedTransaction; + } + + + /** + * Return true if this ConstructionHashRequest object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ConstructionHashRequest constructionHashRequest = (ConstructionHashRequest) o; + return Objects.equals(this.networkIdentifier, constructionHashRequest.networkIdentifier) && + Objects.equals(this.signedTransaction, constructionHashRequest.signedTransaction); + } + + @Override + public int hashCode() { + return Objects.hash(networkIdentifier, signedTransaction); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ConstructionHashRequest {\n"); + sb.append(" networkIdentifier: ").append(toIndentedString(networkIdentifier)).append("\n"); + sb.append(" signedTransaction: ").append(toIndentedString(signedTransaction)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ConstructionMetadataRequest.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ConstructionMetadataRequest.java new file mode 100644 index 0000000000..37cf8e6ce9 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ConstructionMetadataRequest.java @@ -0,0 +1,188 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.NetworkIdentifier; +import com.radixdlt.api.mesh.generated.models.PublicKey; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import java.util.ArrayList; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * A ConstructionMetadataRequest is utilized to get information required to construct a transaction. The Options object used to specify which metadata to return is left purposely unstructured to allow flexibility for implementers. Options is not required in the case that there is network-wide metadata of interest. Optionally, the request can also include an array of PublicKeys associated with the AccountIdentifiers returned in ConstructionPreprocessResponse. + */ +@ApiModel(description = "A ConstructionMetadataRequest is utilized to get information required to construct a transaction. The Options object used to specify which metadata to return is left purposely unstructured to allow flexibility for implementers. Options is not required in the case that there is network-wide metadata of interest. Optionally, the request can also include an array of PublicKeys associated with the AccountIdentifiers returned in ConstructionPreprocessResponse. ") +@JsonPropertyOrder({ + ConstructionMetadataRequest.JSON_PROPERTY_NETWORK_IDENTIFIER, + ConstructionMetadataRequest.JSON_PROPERTY_OPTIONS, + ConstructionMetadataRequest.JSON_PROPERTY_PUBLIC_KEYS +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class ConstructionMetadataRequest { + public static final String JSON_PROPERTY_NETWORK_IDENTIFIER = "network_identifier"; + private NetworkIdentifier networkIdentifier; + + public static final String JSON_PROPERTY_OPTIONS = "options"; + private Object options; + + public static final String JSON_PROPERTY_PUBLIC_KEYS = "public_keys"; + private List publicKeys = null; + + public ConstructionMetadataRequest() { + } + + public ConstructionMetadataRequest networkIdentifier(NetworkIdentifier networkIdentifier) { + this.networkIdentifier = networkIdentifier; + return this; + } + + /** + * Get networkIdentifier + * @return networkIdentifier + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_NETWORK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public NetworkIdentifier getNetworkIdentifier() { + return networkIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_NETWORK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setNetworkIdentifier(NetworkIdentifier networkIdentifier) { + this.networkIdentifier = networkIdentifier; + } + + + public ConstructionMetadataRequest options(Object options) { + this.options = options; + return this; + } + + /** + * Some blockchains require different metadata for different types of transaction construction (ex: delegation versus a transfer). Instead of requiring a blockchain node to return all possible types of metadata for construction (which may require multiple node fetches), the client can populate an options object to limit the metadata returned to only the subset required. + * @return options + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "Some blockchains require different metadata for different types of transaction construction (ex: delegation versus a transfer). Instead of requiring a blockchain node to return all possible types of metadata for construction (which may require multiple node fetches), the client can populate an options object to limit the metadata returned to only the subset required. ") + @JsonProperty(JSON_PROPERTY_OPTIONS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Object getOptions() { + return options; + } + + + @JsonProperty(JSON_PROPERTY_OPTIONS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setOptions(Object options) { + this.options = options; + } + + + public ConstructionMetadataRequest publicKeys(List publicKeys) { + this.publicKeys = publicKeys; + return this; + } + + public ConstructionMetadataRequest addPublicKeysItem(PublicKey publicKeysItem) { + if (this.publicKeys == null) { + this.publicKeys = new ArrayList<>(); + } + this.publicKeys.add(publicKeysItem); + return this; + } + + /** + * Get publicKeys + * @return publicKeys + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_PUBLIC_KEYS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public List getPublicKeys() { + return publicKeys; + } + + + @JsonProperty(JSON_PROPERTY_PUBLIC_KEYS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setPublicKeys(List publicKeys) { + this.publicKeys = publicKeys; + } + + + /** + * Return true if this ConstructionMetadataRequest object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ConstructionMetadataRequest constructionMetadataRequest = (ConstructionMetadataRequest) o; + return Objects.equals(this.networkIdentifier, constructionMetadataRequest.networkIdentifier) && + Objects.equals(this.options, constructionMetadataRequest.options) && + Objects.equals(this.publicKeys, constructionMetadataRequest.publicKeys); + } + + @Override + public int hashCode() { + return Objects.hash(networkIdentifier, options, publicKeys); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ConstructionMetadataRequest {\n"); + sb.append(" networkIdentifier: ").append(toIndentedString(networkIdentifier)).append("\n"); + sb.append(" options: ").append(toIndentedString(options)).append("\n"); + sb.append(" publicKeys: ").append(toIndentedString(publicKeys)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ConstructionMetadataResponse.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ConstructionMetadataResponse.java new file mode 100644 index 0000000000..70080c188a --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ConstructionMetadataResponse.java @@ -0,0 +1,155 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.Amount; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import java.util.ArrayList; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * The ConstructionMetadataResponse returns network-specific metadata used for transaction construction. Optionally, the implementer can return the suggested fee associated with the transaction being constructed. The caller may use this info to adjust the intent of the transaction or to create a transaction with a different account that can pay the suggested fee. Suggested fee is an array in case fee payment must occur in multiple currencies. + */ +@ApiModel(description = "The ConstructionMetadataResponse returns network-specific metadata used for transaction construction. Optionally, the implementer can return the suggested fee associated with the transaction being constructed. The caller may use this info to adjust the intent of the transaction or to create a transaction with a different account that can pay the suggested fee. Suggested fee is an array in case fee payment must occur in multiple currencies. ") +@JsonPropertyOrder({ + ConstructionMetadataResponse.JSON_PROPERTY_METADATA, + ConstructionMetadataResponse.JSON_PROPERTY_SUGGESTED_FEE +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class ConstructionMetadataResponse { + public static final String JSON_PROPERTY_METADATA = "metadata"; + private Object metadata; + + public static final String JSON_PROPERTY_SUGGESTED_FEE = "suggested_fee"; + private List suggestedFee = null; + + public ConstructionMetadataResponse() { + } + + public ConstructionMetadataResponse metadata(Object metadata) { + this.metadata = metadata; + return this; + } + + /** + * Get metadata + * @return metadata + **/ + @javax.annotation.Nonnull + @ApiModelProperty(example = "{\"account_sequence\":23,\"recent_block_hash\":\"0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5\"}", required = true, value = "") + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public Object getMetadata() { + return metadata; + } + + + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setMetadata(Object metadata) { + this.metadata = metadata; + } + + + public ConstructionMetadataResponse suggestedFee(List suggestedFee) { + this.suggestedFee = suggestedFee; + return this; + } + + public ConstructionMetadataResponse addSuggestedFeeItem(Amount suggestedFeeItem) { + if (this.suggestedFee == null) { + this.suggestedFee = new ArrayList<>(); + } + this.suggestedFee.add(suggestedFeeItem); + return this; + } + + /** + * Get suggestedFee + * @return suggestedFee + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_SUGGESTED_FEE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public List getSuggestedFee() { + return suggestedFee; + } + + + @JsonProperty(JSON_PROPERTY_SUGGESTED_FEE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setSuggestedFee(List suggestedFee) { + this.suggestedFee = suggestedFee; + } + + + /** + * Return true if this ConstructionMetadataResponse object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ConstructionMetadataResponse constructionMetadataResponse = (ConstructionMetadataResponse) o; + return Objects.equals(this.metadata, constructionMetadataResponse.metadata) && + Objects.equals(this.suggestedFee, constructionMetadataResponse.suggestedFee); + } + + @Override + public int hashCode() { + return Objects.hash(metadata, suggestedFee); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ConstructionMetadataResponse {\n"); + sb.append(" metadata: ").append(toIndentedString(metadata)).append("\n"); + sb.append(" suggestedFee: ").append(toIndentedString(suggestedFee)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ConstructionParseRequest.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ConstructionParseRequest.java new file mode 100644 index 0000000000..7b4883cf32 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ConstructionParseRequest.java @@ -0,0 +1,177 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.NetworkIdentifier; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * ConstructionParseRequest is the input to the `/construction/parse` endpoint. It allows the caller to parse either an unsigned or signed transaction. + */ +@ApiModel(description = "ConstructionParseRequest is the input to the `/construction/parse` endpoint. It allows the caller to parse either an unsigned or signed transaction. ") +@JsonPropertyOrder({ + ConstructionParseRequest.JSON_PROPERTY_NETWORK_IDENTIFIER, + ConstructionParseRequest.JSON_PROPERTY_SIGNED, + ConstructionParseRequest.JSON_PROPERTY_TRANSACTION +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class ConstructionParseRequest { + public static final String JSON_PROPERTY_NETWORK_IDENTIFIER = "network_identifier"; + private NetworkIdentifier networkIdentifier; + + public static final String JSON_PROPERTY_SIGNED = "signed"; + private Boolean signed; + + public static final String JSON_PROPERTY_TRANSACTION = "transaction"; + private String transaction; + + public ConstructionParseRequest() { + } + + public ConstructionParseRequest networkIdentifier(NetworkIdentifier networkIdentifier) { + this.networkIdentifier = networkIdentifier; + return this; + } + + /** + * Get networkIdentifier + * @return networkIdentifier + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_NETWORK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public NetworkIdentifier getNetworkIdentifier() { + return networkIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_NETWORK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setNetworkIdentifier(NetworkIdentifier networkIdentifier) { + this.networkIdentifier = networkIdentifier; + } + + + public ConstructionParseRequest signed(Boolean signed) { + this.signed = signed; + return this; + } + + /** + * Signed is a boolean indicating whether the transaction is signed. + * @return signed + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "Signed is a boolean indicating whether the transaction is signed. ") + @JsonProperty(JSON_PROPERTY_SIGNED) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public Boolean getSigned() { + return signed; + } + + + @JsonProperty(JSON_PROPERTY_SIGNED) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setSigned(Boolean signed) { + this.signed = signed; + } + + + public ConstructionParseRequest transaction(String transaction) { + this.transaction = transaction; + return this; + } + + /** + * This must be either the unsigned transaction blob returned by `/construction/payloads` or the signed transaction blob returned by `/construction/combine`. + * @return transaction + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "This must be either the unsigned transaction blob returned by `/construction/payloads` or the signed transaction blob returned by `/construction/combine`. ") + @JsonProperty(JSON_PROPERTY_TRANSACTION) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getTransaction() { + return transaction; + } + + + @JsonProperty(JSON_PROPERTY_TRANSACTION) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setTransaction(String transaction) { + this.transaction = transaction; + } + + + /** + * Return true if this ConstructionParseRequest object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ConstructionParseRequest constructionParseRequest = (ConstructionParseRequest) o; + return Objects.equals(this.networkIdentifier, constructionParseRequest.networkIdentifier) && + Objects.equals(this.signed, constructionParseRequest.signed) && + Objects.equals(this.transaction, constructionParseRequest.transaction); + } + + @Override + public int hashCode() { + return Objects.hash(networkIdentifier, signed, transaction); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ConstructionParseRequest {\n"); + sb.append(" networkIdentifier: ").append(toIndentedString(networkIdentifier)).append("\n"); + sb.append(" signed: ").append(toIndentedString(signed)).append("\n"); + sb.append(" transaction: ").append(toIndentedString(transaction)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ConstructionParseResponse.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ConstructionParseResponse.java new file mode 100644 index 0000000000..ddd54c5787 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ConstructionParseResponse.java @@ -0,0 +1,233 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.AccountIdentifier; +import com.radixdlt.api.mesh.generated.models.Operation; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import java.util.ArrayList; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * ConstructionParseResponse contains an array of operations that occur in a transaction blob. This should match the array of operations provided to `/construction/preprocess` and `/construction/payloads`. + */ +@ApiModel(description = "ConstructionParseResponse contains an array of operations that occur in a transaction blob. This should match the array of operations provided to `/construction/preprocess` and `/construction/payloads`. ") +@JsonPropertyOrder({ + ConstructionParseResponse.JSON_PROPERTY_OPERATIONS, + ConstructionParseResponse.JSON_PROPERTY_SIGNERS, + ConstructionParseResponse.JSON_PROPERTY_ACCOUNT_IDENTIFIER_SIGNERS, + ConstructionParseResponse.JSON_PROPERTY_METADATA +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class ConstructionParseResponse { + public static final String JSON_PROPERTY_OPERATIONS = "operations"; + private List operations = new ArrayList<>(); + + public static final String JSON_PROPERTY_SIGNERS = "signers"; + private List signers = null; + + public static final String JSON_PROPERTY_ACCOUNT_IDENTIFIER_SIGNERS = "account_identifier_signers"; + private List accountIdentifierSigners = null; + + public static final String JSON_PROPERTY_METADATA = "metadata"; + private Object metadata; + + public ConstructionParseResponse() { + } + + public ConstructionParseResponse operations(List operations) { + this.operations = operations; + return this; + } + + public ConstructionParseResponse addOperationsItem(Operation operationsItem) { + this.operations.add(operationsItem); + return this; + } + + /** + * Get operations + * @return operations + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_OPERATIONS) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public List getOperations() { + return operations; + } + + + @JsonProperty(JSON_PROPERTY_OPERATIONS) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setOperations(List operations) { + this.operations = operations; + } + + + public ConstructionParseResponse signers(List signers) { + this.signers = signers; + return this; + } + + public ConstructionParseResponse addSignersItem(String signersItem) { + if (this.signers == null) { + this.signers = new ArrayList<>(); + } + this.signers.add(signersItem); + return this; + } + + /** + * [DEPRECATED by `account_identifier_signers` in `v1.4.4`] All signers (addresses) of a particular transaction. If the transaction is unsigned, it should be empty. + * @return signers + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "[DEPRECATED by `account_identifier_signers` in `v1.4.4`] All signers (addresses) of a particular transaction. If the transaction is unsigned, it should be empty. ") + @JsonProperty(JSON_PROPERTY_SIGNERS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public List getSigners() { + return signers; + } + + + @JsonProperty(JSON_PROPERTY_SIGNERS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setSigners(List signers) { + this.signers = signers; + } + + + public ConstructionParseResponse accountIdentifierSigners(List accountIdentifierSigners) { + this.accountIdentifierSigners = accountIdentifierSigners; + return this; + } + + public ConstructionParseResponse addAccountIdentifierSignersItem(AccountIdentifier accountIdentifierSignersItem) { + if (this.accountIdentifierSigners == null) { + this.accountIdentifierSigners = new ArrayList<>(); + } + this.accountIdentifierSigners.add(accountIdentifierSignersItem); + return this; + } + + /** + * Get accountIdentifierSigners + * @return accountIdentifierSigners + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_ACCOUNT_IDENTIFIER_SIGNERS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public List getAccountIdentifierSigners() { + return accountIdentifierSigners; + } + + + @JsonProperty(JSON_PROPERTY_ACCOUNT_IDENTIFIER_SIGNERS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setAccountIdentifierSigners(List accountIdentifierSigners) { + this.accountIdentifierSigners = accountIdentifierSigners; + } + + + public ConstructionParseResponse metadata(Object metadata) { + this.metadata = metadata; + return this; + } + + /** + * Get metadata + * @return metadata + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Object getMetadata() { + return metadata; + } + + + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setMetadata(Object metadata) { + this.metadata = metadata; + } + + + /** + * Return true if this ConstructionParseResponse object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ConstructionParseResponse constructionParseResponse = (ConstructionParseResponse) o; + return Objects.equals(this.operations, constructionParseResponse.operations) && + Objects.equals(this.signers, constructionParseResponse.signers) && + Objects.equals(this.accountIdentifierSigners, constructionParseResponse.accountIdentifierSigners) && + Objects.equals(this.metadata, constructionParseResponse.metadata); + } + + @Override + public int hashCode() { + return Objects.hash(operations, signers, accountIdentifierSigners, metadata); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ConstructionParseResponse {\n"); + sb.append(" operations: ").append(toIndentedString(operations)).append("\n"); + sb.append(" signers: ").append(toIndentedString(signers)).append("\n"); + sb.append(" accountIdentifierSigners: ").append(toIndentedString(accountIdentifierSigners)).append("\n"); + sb.append(" metadata: ").append(toIndentedString(metadata)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ConstructionPayloadsRequest.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ConstructionPayloadsRequest.java new file mode 100644 index 0000000000..47c144e127 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ConstructionPayloadsRequest.java @@ -0,0 +1,226 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.NetworkIdentifier; +import com.radixdlt.api.mesh.generated.models.Operation; +import com.radixdlt.api.mesh.generated.models.PublicKey; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import java.util.ArrayList; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * ConstructionPayloadsRequest is the request to `/construction/payloads`. It contains the network, a slice of operations, and arbitrary metadata that was returned by the call to `/construction/metadata`. Optionally, the request can also include an array of PublicKeys associated with the AccountIdentifiers returned in ConstructionPreprocessResponse. + */ +@ApiModel(description = "ConstructionPayloadsRequest is the request to `/construction/payloads`. It contains the network, a slice of operations, and arbitrary metadata that was returned by the call to `/construction/metadata`. Optionally, the request can also include an array of PublicKeys associated with the AccountIdentifiers returned in ConstructionPreprocessResponse. ") +@JsonPropertyOrder({ + ConstructionPayloadsRequest.JSON_PROPERTY_NETWORK_IDENTIFIER, + ConstructionPayloadsRequest.JSON_PROPERTY_OPERATIONS, + ConstructionPayloadsRequest.JSON_PROPERTY_METADATA, + ConstructionPayloadsRequest.JSON_PROPERTY_PUBLIC_KEYS +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class ConstructionPayloadsRequest { + public static final String JSON_PROPERTY_NETWORK_IDENTIFIER = "network_identifier"; + private NetworkIdentifier networkIdentifier; + + public static final String JSON_PROPERTY_OPERATIONS = "operations"; + private List operations = new ArrayList<>(); + + public static final String JSON_PROPERTY_METADATA = "metadata"; + private Object metadata; + + public static final String JSON_PROPERTY_PUBLIC_KEYS = "public_keys"; + private List publicKeys = null; + + public ConstructionPayloadsRequest() { + } + + public ConstructionPayloadsRequest networkIdentifier(NetworkIdentifier networkIdentifier) { + this.networkIdentifier = networkIdentifier; + return this; + } + + /** + * Get networkIdentifier + * @return networkIdentifier + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_NETWORK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public NetworkIdentifier getNetworkIdentifier() { + return networkIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_NETWORK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setNetworkIdentifier(NetworkIdentifier networkIdentifier) { + this.networkIdentifier = networkIdentifier; + } + + + public ConstructionPayloadsRequest operations(List operations) { + this.operations = operations; + return this; + } + + public ConstructionPayloadsRequest addOperationsItem(Operation operationsItem) { + this.operations.add(operationsItem); + return this; + } + + /** + * Get operations + * @return operations + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_OPERATIONS) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public List getOperations() { + return operations; + } + + + @JsonProperty(JSON_PROPERTY_OPERATIONS) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setOperations(List operations) { + this.operations = operations; + } + + + public ConstructionPayloadsRequest metadata(Object metadata) { + this.metadata = metadata; + return this; + } + + /** + * Get metadata + * @return metadata + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Object getMetadata() { + return metadata; + } + + + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setMetadata(Object metadata) { + this.metadata = metadata; + } + + + public ConstructionPayloadsRequest publicKeys(List publicKeys) { + this.publicKeys = publicKeys; + return this; + } + + public ConstructionPayloadsRequest addPublicKeysItem(PublicKey publicKeysItem) { + if (this.publicKeys == null) { + this.publicKeys = new ArrayList<>(); + } + this.publicKeys.add(publicKeysItem); + return this; + } + + /** + * Get publicKeys + * @return publicKeys + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_PUBLIC_KEYS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public List getPublicKeys() { + return publicKeys; + } + + + @JsonProperty(JSON_PROPERTY_PUBLIC_KEYS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setPublicKeys(List publicKeys) { + this.publicKeys = publicKeys; + } + + + /** + * Return true if this ConstructionPayloadsRequest object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ConstructionPayloadsRequest constructionPayloadsRequest = (ConstructionPayloadsRequest) o; + return Objects.equals(this.networkIdentifier, constructionPayloadsRequest.networkIdentifier) && + Objects.equals(this.operations, constructionPayloadsRequest.operations) && + Objects.equals(this.metadata, constructionPayloadsRequest.metadata) && + Objects.equals(this.publicKeys, constructionPayloadsRequest.publicKeys); + } + + @Override + public int hashCode() { + return Objects.hash(networkIdentifier, operations, metadata, publicKeys); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ConstructionPayloadsRequest {\n"); + sb.append(" networkIdentifier: ").append(toIndentedString(networkIdentifier)).append("\n"); + sb.append(" operations: ").append(toIndentedString(operations)).append("\n"); + sb.append(" metadata: ").append(toIndentedString(metadata)).append("\n"); + sb.append(" publicKeys: ").append(toIndentedString(publicKeys)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ConstructionPayloadsResponse.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ConstructionPayloadsResponse.java new file mode 100644 index 0000000000..5c871122a6 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ConstructionPayloadsResponse.java @@ -0,0 +1,152 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.SigningPayload; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import java.util.ArrayList; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * ConstructionTransactionResponse is returned by `/construction/payloads`. It contains an unsigned transaction blob (that is usually needed to construct the a network transaction from a collection of signatures) and an array of payloads that must be signed by the caller. + */ +@ApiModel(description = "ConstructionTransactionResponse is returned by `/construction/payloads`. It contains an unsigned transaction blob (that is usually needed to construct the a network transaction from a collection of signatures) and an array of payloads that must be signed by the caller. ") +@JsonPropertyOrder({ + ConstructionPayloadsResponse.JSON_PROPERTY_UNSIGNED_TRANSACTION, + ConstructionPayloadsResponse.JSON_PROPERTY_PAYLOADS +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class ConstructionPayloadsResponse { + public static final String JSON_PROPERTY_UNSIGNED_TRANSACTION = "unsigned_transaction"; + private String unsignedTransaction; + + public static final String JSON_PROPERTY_PAYLOADS = "payloads"; + private List payloads = new ArrayList<>(); + + public ConstructionPayloadsResponse() { + } + + public ConstructionPayloadsResponse unsignedTransaction(String unsignedTransaction) { + this.unsignedTransaction = unsignedTransaction; + return this; + } + + /** + * Get unsignedTransaction + * @return unsignedTransaction + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_UNSIGNED_TRANSACTION) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getUnsignedTransaction() { + return unsignedTransaction; + } + + + @JsonProperty(JSON_PROPERTY_UNSIGNED_TRANSACTION) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setUnsignedTransaction(String unsignedTransaction) { + this.unsignedTransaction = unsignedTransaction; + } + + + public ConstructionPayloadsResponse payloads(List payloads) { + this.payloads = payloads; + return this; + } + + public ConstructionPayloadsResponse addPayloadsItem(SigningPayload payloadsItem) { + this.payloads.add(payloadsItem); + return this; + } + + /** + * Get payloads + * @return payloads + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_PAYLOADS) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public List getPayloads() { + return payloads; + } + + + @JsonProperty(JSON_PROPERTY_PAYLOADS) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setPayloads(List payloads) { + this.payloads = payloads; + } + + + /** + * Return true if this ConstructionPayloadsResponse object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ConstructionPayloadsResponse constructionPayloadsResponse = (ConstructionPayloadsResponse) o; + return Objects.equals(this.unsignedTransaction, constructionPayloadsResponse.unsignedTransaction) && + Objects.equals(this.payloads, constructionPayloadsResponse.payloads); + } + + @Override + public int hashCode() { + return Objects.hash(unsignedTransaction, payloads); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ConstructionPayloadsResponse {\n"); + sb.append(" unsignedTransaction: ").append(toIndentedString(unsignedTransaction)).append("\n"); + sb.append(" payloads: ").append(toIndentedString(payloads)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ConstructionPreprocessRequest.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ConstructionPreprocessRequest.java new file mode 100644 index 0000000000..bb3a4d37dd --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ConstructionPreprocessRequest.java @@ -0,0 +1,185 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.NetworkIdentifier; +import com.radixdlt.api.mesh.generated.models.Operation; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import java.util.ArrayList; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * ConstructionPreprocessRequest is passed to the `/construction/preprocess` endpoint so that a Rosetta implementation can determine which metadata it needs to request for construction. Metadata provided in this object should NEVER be a product of live data (i.e. the caller must follow some network-specific data fetching strategy outside of the Construction API to populate required Metadata). If live data is required for construction, it MUST be fetched in the call to `/construction/metadata`. + */ +@ApiModel(description = "ConstructionPreprocessRequest is passed to the `/construction/preprocess` endpoint so that a Rosetta implementation can determine which metadata it needs to request for construction. Metadata provided in this object should NEVER be a product of live data (i.e. the caller must follow some network-specific data fetching strategy outside of the Construction API to populate required Metadata). If live data is required for construction, it MUST be fetched in the call to `/construction/metadata`. ") +@JsonPropertyOrder({ + ConstructionPreprocessRequest.JSON_PROPERTY_NETWORK_IDENTIFIER, + ConstructionPreprocessRequest.JSON_PROPERTY_OPERATIONS, + ConstructionPreprocessRequest.JSON_PROPERTY_METADATA +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class ConstructionPreprocessRequest { + public static final String JSON_PROPERTY_NETWORK_IDENTIFIER = "network_identifier"; + private NetworkIdentifier networkIdentifier; + + public static final String JSON_PROPERTY_OPERATIONS = "operations"; + private List operations = new ArrayList<>(); + + public static final String JSON_PROPERTY_METADATA = "metadata"; + private Object metadata; + + public ConstructionPreprocessRequest() { + } + + public ConstructionPreprocessRequest networkIdentifier(NetworkIdentifier networkIdentifier) { + this.networkIdentifier = networkIdentifier; + return this; + } + + /** + * Get networkIdentifier + * @return networkIdentifier + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_NETWORK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public NetworkIdentifier getNetworkIdentifier() { + return networkIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_NETWORK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setNetworkIdentifier(NetworkIdentifier networkIdentifier) { + this.networkIdentifier = networkIdentifier; + } + + + public ConstructionPreprocessRequest operations(List operations) { + this.operations = operations; + return this; + } + + public ConstructionPreprocessRequest addOperationsItem(Operation operationsItem) { + this.operations.add(operationsItem); + return this; + } + + /** + * Get operations + * @return operations + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_OPERATIONS) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public List getOperations() { + return operations; + } + + + @JsonProperty(JSON_PROPERTY_OPERATIONS) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setOperations(List operations) { + this.operations = operations; + } + + + public ConstructionPreprocessRequest metadata(Object metadata) { + this.metadata = metadata; + return this; + } + + /** + * Get metadata + * @return metadata + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Object getMetadata() { + return metadata; + } + + + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setMetadata(Object metadata) { + this.metadata = metadata; + } + + + /** + * Return true if this ConstructionPreprocessRequest object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ConstructionPreprocessRequest constructionPreprocessRequest = (ConstructionPreprocessRequest) o; + return Objects.equals(this.networkIdentifier, constructionPreprocessRequest.networkIdentifier) && + Objects.equals(this.operations, constructionPreprocessRequest.operations) && + Objects.equals(this.metadata, constructionPreprocessRequest.metadata); + } + + @Override + public int hashCode() { + return Objects.hash(networkIdentifier, operations, metadata); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ConstructionPreprocessRequest {\n"); + sb.append(" networkIdentifier: ").append(toIndentedString(networkIdentifier)).append("\n"); + sb.append(" operations: ").append(toIndentedString(operations)).append("\n"); + sb.append(" metadata: ").append(toIndentedString(metadata)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ConstructionPreprocessResponse.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ConstructionPreprocessResponse.java new file mode 100644 index 0000000000..7b2aeec346 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ConstructionPreprocessResponse.java @@ -0,0 +1,155 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.AccountIdentifier; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import java.util.ArrayList; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * ConstructionPreprocessResponse contains `options` that will be sent unmodified to `/construction/metadata`. If it is not necessary to make a request to `/construction/metadata`, `options` should be omitted. Some blockchains require the PublicKey of particular AccountIdentifiers to construct a valid transaction. To fetch these PublicKeys, populate `required_public_keys` with the AccountIdentifiers associated with the desired PublicKeys. If it is not necessary to retrieve any PublicKeys for construction, `required_public_keys` should be omitted. + */ +@ApiModel(description = "ConstructionPreprocessResponse contains `options` that will be sent unmodified to `/construction/metadata`. If it is not necessary to make a request to `/construction/metadata`, `options` should be omitted. Some blockchains require the PublicKey of particular AccountIdentifiers to construct a valid transaction. To fetch these PublicKeys, populate `required_public_keys` with the AccountIdentifiers associated with the desired PublicKeys. If it is not necessary to retrieve any PublicKeys for construction, `required_public_keys` should be omitted. ") +@JsonPropertyOrder({ + ConstructionPreprocessResponse.JSON_PROPERTY_OPTIONS, + ConstructionPreprocessResponse.JSON_PROPERTY_REQUIRED_PUBLIC_KEYS +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class ConstructionPreprocessResponse { + public static final String JSON_PROPERTY_OPTIONS = "options"; + private Object options; + + public static final String JSON_PROPERTY_REQUIRED_PUBLIC_KEYS = "required_public_keys"; + private List requiredPublicKeys = null; + + public ConstructionPreprocessResponse() { + } + + public ConstructionPreprocessResponse options(Object options) { + this.options = options; + return this; + } + + /** + * The options that will be sent directly to `/construction/metadata` by the caller. + * @return options + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "The options that will be sent directly to `/construction/metadata` by the caller. ") + @JsonProperty(JSON_PROPERTY_OPTIONS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Object getOptions() { + return options; + } + + + @JsonProperty(JSON_PROPERTY_OPTIONS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setOptions(Object options) { + this.options = options; + } + + + public ConstructionPreprocessResponse requiredPublicKeys(List requiredPublicKeys) { + this.requiredPublicKeys = requiredPublicKeys; + return this; + } + + public ConstructionPreprocessResponse addRequiredPublicKeysItem(AccountIdentifier requiredPublicKeysItem) { + if (this.requiredPublicKeys == null) { + this.requiredPublicKeys = new ArrayList<>(); + } + this.requiredPublicKeys.add(requiredPublicKeysItem); + return this; + } + + /** + * Get requiredPublicKeys + * @return requiredPublicKeys + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_REQUIRED_PUBLIC_KEYS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public List getRequiredPublicKeys() { + return requiredPublicKeys; + } + + + @JsonProperty(JSON_PROPERTY_REQUIRED_PUBLIC_KEYS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setRequiredPublicKeys(List requiredPublicKeys) { + this.requiredPublicKeys = requiredPublicKeys; + } + + + /** + * Return true if this ConstructionPreprocessResponse object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ConstructionPreprocessResponse constructionPreprocessResponse = (ConstructionPreprocessResponse) o; + return Objects.equals(this.options, constructionPreprocessResponse.options) && + Objects.equals(this.requiredPublicKeys, constructionPreprocessResponse.requiredPublicKeys); + } + + @Override + public int hashCode() { + return Objects.hash(options, requiredPublicKeys); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ConstructionPreprocessResponse {\n"); + sb.append(" options: ").append(toIndentedString(options)).append("\n"); + sb.append(" requiredPublicKeys: ").append(toIndentedString(requiredPublicKeys)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ConstructionSubmitRequest.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ConstructionSubmitRequest.java new file mode 100644 index 0000000000..55abb05d29 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ConstructionSubmitRequest.java @@ -0,0 +1,145 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.NetworkIdentifier; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * The transaction submission request includes a signed transaction. + */ +@ApiModel(description = "The transaction submission request includes a signed transaction. ") +@JsonPropertyOrder({ + ConstructionSubmitRequest.JSON_PROPERTY_NETWORK_IDENTIFIER, + ConstructionSubmitRequest.JSON_PROPERTY_SIGNED_TRANSACTION +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class ConstructionSubmitRequest { + public static final String JSON_PROPERTY_NETWORK_IDENTIFIER = "network_identifier"; + private NetworkIdentifier networkIdentifier; + + public static final String JSON_PROPERTY_SIGNED_TRANSACTION = "signed_transaction"; + private String signedTransaction; + + public ConstructionSubmitRequest() { + } + + public ConstructionSubmitRequest networkIdentifier(NetworkIdentifier networkIdentifier) { + this.networkIdentifier = networkIdentifier; + return this; + } + + /** + * Get networkIdentifier + * @return networkIdentifier + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_NETWORK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public NetworkIdentifier getNetworkIdentifier() { + return networkIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_NETWORK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setNetworkIdentifier(NetworkIdentifier networkIdentifier) { + this.networkIdentifier = networkIdentifier; + } + + + public ConstructionSubmitRequest signedTransaction(String signedTransaction) { + this.signedTransaction = signedTransaction; + return this; + } + + /** + * Get signedTransaction + * @return signedTransaction + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_SIGNED_TRANSACTION) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getSignedTransaction() { + return signedTransaction; + } + + + @JsonProperty(JSON_PROPERTY_SIGNED_TRANSACTION) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setSignedTransaction(String signedTransaction) { + this.signedTransaction = signedTransaction; + } + + + /** + * Return true if this ConstructionSubmitRequest object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ConstructionSubmitRequest constructionSubmitRequest = (ConstructionSubmitRequest) o; + return Objects.equals(this.networkIdentifier, constructionSubmitRequest.networkIdentifier) && + Objects.equals(this.signedTransaction, constructionSubmitRequest.signedTransaction); + } + + @Override + public int hashCode() { + return Objects.hash(networkIdentifier, signedTransaction); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ConstructionSubmitRequest {\n"); + sb.append(" networkIdentifier: ").append(toIndentedString(networkIdentifier)).append("\n"); + sb.append(" signedTransaction: ").append(toIndentedString(signedTransaction)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/Currency.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/Currency.java new file mode 100644 index 0000000000..0a2cf6d199 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/Currency.java @@ -0,0 +1,177 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * Currency is composed of a canonical Symbol and Decimals. This Decimals value is used to convert an Amount.Value from atomic units (Satoshis) to standard units (Bitcoins). + */ +@ApiModel(description = "Currency is composed of a canonical Symbol and Decimals. This Decimals value is used to convert an Amount.Value from atomic units (Satoshis) to standard units (Bitcoins). ") +@JsonPropertyOrder({ + Currency.JSON_PROPERTY_SYMBOL, + Currency.JSON_PROPERTY_DECIMALS, + Currency.JSON_PROPERTY_METADATA +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class Currency { + public static final String JSON_PROPERTY_SYMBOL = "symbol"; + private String symbol; + + public static final String JSON_PROPERTY_DECIMALS = "decimals"; + private Integer decimals; + + public static final String JSON_PROPERTY_METADATA = "metadata"; + private Object metadata; + + public Currency() { + } + + public Currency symbol(String symbol) { + this.symbol = symbol; + return this; + } + + /** + * Canonical symbol associated with a currency. + * @return symbol + **/ + @javax.annotation.Nonnull + @ApiModelProperty(example = "BTC", required = true, value = "Canonical symbol associated with a currency. ") + @JsonProperty(JSON_PROPERTY_SYMBOL) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getSymbol() { + return symbol; + } + + + @JsonProperty(JSON_PROPERTY_SYMBOL) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setSymbol(String symbol) { + this.symbol = symbol; + } + + + public Currency decimals(Integer decimals) { + this.decimals = decimals; + return this; + } + + /** + * Number of decimal places in the standard unit representation of the amount. For example, BTC has 8 decimals. Note that it is not possible to represent the value of some currency in atomic units that is not base 10. + * minimum: 0 + * @return decimals + **/ + @javax.annotation.Nonnull + @ApiModelProperty(example = "8", required = true, value = "Number of decimal places in the standard unit representation of the amount. For example, BTC has 8 decimals. Note that it is not possible to represent the value of some currency in atomic units that is not base 10. ") + @JsonProperty(JSON_PROPERTY_DECIMALS) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public Integer getDecimals() { + return decimals; + } + + + @JsonProperty(JSON_PROPERTY_DECIMALS) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setDecimals(Integer decimals) { + this.decimals = decimals; + } + + + public Currency metadata(Object metadata) { + this.metadata = metadata; + return this; + } + + /** + * Any additional information related to the currency itself. For example, it would be useful to populate this object with the contract address of an ERC-20 token. + * @return metadata + **/ + @javax.annotation.Nullable + @ApiModelProperty(example = "{Issuer=Satoshi}", value = "Any additional information related to the currency itself. For example, it would be useful to populate this object with the contract address of an ERC-20 token. ") + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Object getMetadata() { + return metadata; + } + + + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setMetadata(Object metadata) { + this.metadata = metadata; + } + + + /** + * Return true if this Currency object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Currency currency = (Currency) o; + return Objects.equals(this.symbol, currency.symbol) && + Objects.equals(this.decimals, currency.decimals) && + Objects.equals(this.metadata, currency.metadata); + } + + @Override + public int hashCode() { + return Objects.hash(symbol, decimals, metadata); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Currency {\n"); + sb.append(" symbol: ").append(toIndentedString(symbol)).append("\n"); + sb.append(" decimals: ").append(toIndentedString(decimals)).append("\n"); + sb.append(" metadata: ").append(toIndentedString(metadata)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/CurveType.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/CurveType.java new file mode 100644 index 0000000000..2d0abaa4f5 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/CurveType.java @@ -0,0 +1,70 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import io.swagger.annotations.ApiModel; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * CurveType is the type of cryptographic curve associated with a PublicKey. * secp256k1: SEC compressed - `33 bytes` (https://secg.org/sec1-v2.pdf#subsubsection.2.3.3) * secp256k1_bip340: x-only - `32 bytes` (implicitly even `Y` coord. Secp256k1 compressed keys may be repurposed by dropping the first byte. (https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki#Public_Key_Generation)) * secp256r1: SEC compressed - `33 bytes` (https://secg.org/sec1-v2.pdf#subsubsection.2.3.3) * edwards25519: `y (255-bits) || x-sign-bit (1-bit)` - `32 bytes` (https://ed25519.cr.yp.to/ed25519-20110926.pdf) * tweedle: 1st pk : Fq.t (32 bytes) || 2nd pk : Fq.t (32 bytes) (https://github.com/CodaProtocol/coda/blob/develop/rfcs/0038-rosetta-construction-api.md#marshal-keys) * pallas: `x (255 bits) || y-parity-bit (1-bit) - 32 bytes` (https://github.com/zcash/pasta) + */ +public enum CurveType { + + SECP256K1("secp256k1"), + + SECP256K1_BIP340("secp256k1_bip340"), + + SECP256R1("secp256r1"), + + EDWARDS25519("edwards25519"), + + TWEEDLE("tweedle"), + + PALLAS("pallas"); + + private String value; + + CurveType(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static CurveType fromValue(String value) { + for (CurveType b : CurveType.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/Direction.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/Direction.java new file mode 100644 index 0000000000..3d425aeff7 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/Direction.java @@ -0,0 +1,62 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import io.swagger.annotations.ApiModel; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * Used by RelatedTransaction to indicate the direction of the relation (i.e. cross-shard/cross-network sends may reference `backward` to an earlier transaction and async execution may reference `forward`). Can be used to indicate if a transaction relation is from child to parent or the reverse. + */ +public enum Direction { + + FORWARD("forward"), + + BACKWARD("backward"); + + private String value; + + Direction(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static Direction fromValue(String value) { + for (Direction b : Direction.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/Error.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/Error.java new file mode 100644 index 0000000000..8e4410e569 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/Error.java @@ -0,0 +1,241 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * Instead of utilizing HTTP status codes to describe node errors (which often do not have a good analog), rich errors are returned using this object. Both the code and message fields can be individually used to correctly identify an error. Implementations MUST use unique values for both fields. + */ +@ApiModel(description = "Instead of utilizing HTTP status codes to describe node errors (which often do not have a good analog), rich errors are returned using this object. Both the code and message fields can be individually used to correctly identify an error. Implementations MUST use unique values for both fields. ") +@JsonPropertyOrder({ + Error.JSON_PROPERTY_CODE, + Error.JSON_PROPERTY_MESSAGE, + Error.JSON_PROPERTY_DESCRIPTION, + Error.JSON_PROPERTY_RETRIABLE, + Error.JSON_PROPERTY_DETAILS +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class Error { + public static final String JSON_PROPERTY_CODE = "code"; + private Integer code; + + public static final String JSON_PROPERTY_MESSAGE = "message"; + private String message; + + public static final String JSON_PROPERTY_DESCRIPTION = "description"; + private String description; + + public static final String JSON_PROPERTY_RETRIABLE = "retriable"; + private Boolean retriable; + + public static final String JSON_PROPERTY_DETAILS = "details"; + private Object details; + + public Error() { + } + + public Error code(Integer code) { + this.code = code; + return this; + } + + /** + * Code is a network-specific error code. If desired, this code can be equivalent to an HTTP status code. + * minimum: 0 + * @return code + **/ + @javax.annotation.Nonnull + @ApiModelProperty(example = "12", required = true, value = "Code is a network-specific error code. If desired, this code can be equivalent to an HTTP status code. ") + @JsonProperty(JSON_PROPERTY_CODE) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public Integer getCode() { + return code; + } + + + @JsonProperty(JSON_PROPERTY_CODE) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setCode(Integer code) { + this.code = code; + } + + + public Error message(String message) { + this.message = message; + return this; + } + + /** + * Message is a network-specific error message. The message MUST NOT change for a given code. In particular, this means that any contextual information should be included in the details field. + * @return message + **/ + @javax.annotation.Nonnull + @ApiModelProperty(example = "Invalid account format", required = true, value = "Message is a network-specific error message. The message MUST NOT change for a given code. In particular, this means that any contextual information should be included in the details field. ") + @JsonProperty(JSON_PROPERTY_MESSAGE) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getMessage() { + return message; + } + + + @JsonProperty(JSON_PROPERTY_MESSAGE) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setMessage(String message) { + this.message = message; + } + + + public Error description(String description) { + this.description = description; + return this; + } + + /** + * Description allows the implementer to optionally provide additional information about an error. In many cases, the content of this field will be a copy-and-paste from existing developer documentation. Description can ONLY be populated with generic information about a particular type of error. It MUST NOT be populated with information about a particular instantiation of an error (use `details` for this). Whereas the content of Error.Message should stay stable across releases, the content of Error.Description will likely change across releases (as implementers improve error documentation). For this reason, the content in this field is not part of any type assertion (unlike Error.Message). + * @return description + **/ + @javax.annotation.Nullable + @ApiModelProperty(example = "This error is returned when the requested AccountIdentifier is improperly formatted.", value = "Description allows the implementer to optionally provide additional information about an error. In many cases, the content of this field will be a copy-and-paste from existing developer documentation. Description can ONLY be populated with generic information about a particular type of error. It MUST NOT be populated with information about a particular instantiation of an error (use `details` for this). Whereas the content of Error.Message should stay stable across releases, the content of Error.Description will likely change across releases (as implementers improve error documentation). For this reason, the content in this field is not part of any type assertion (unlike Error.Message). ") + @JsonProperty(JSON_PROPERTY_DESCRIPTION) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getDescription() { + return description; + } + + + @JsonProperty(JSON_PROPERTY_DESCRIPTION) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setDescription(String description) { + this.description = description; + } + + + public Error retriable(Boolean retriable) { + this.retriable = retriable; + return this; + } + + /** + * An error is retriable if the same request may succeed if submitted again. + * @return retriable + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "An error is retriable if the same request may succeed if submitted again. ") + @JsonProperty(JSON_PROPERTY_RETRIABLE) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public Boolean getRetriable() { + return retriable; + } + + + @JsonProperty(JSON_PROPERTY_RETRIABLE) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setRetriable(Boolean retriable) { + this.retriable = retriable; + } + + + public Error details(Object details) { + this.details = details; + return this; + } + + /** + * Often times it is useful to return context specific to the request that caused the error (i.e. a sample of the stack trace or impacted account) in addition to the standard error message. + * @return details + **/ + @javax.annotation.Nullable + @ApiModelProperty(example = "{address=0x1dcc4de8dec75d7aab85b567b6, error=not base64}", value = "Often times it is useful to return context specific to the request that caused the error (i.e. a sample of the stack trace or impacted account) in addition to the standard error message. ") + @JsonProperty(JSON_PROPERTY_DETAILS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Object getDetails() { + return details; + } + + + @JsonProperty(JSON_PROPERTY_DETAILS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setDetails(Object details) { + this.details = details; + } + + + /** + * Return true if this Error object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Error error = (Error) o; + return Objects.equals(this.code, error.code) && + Objects.equals(this.message, error.message) && + Objects.equals(this.description, error.description) && + Objects.equals(this.retriable, error.retriable) && + Objects.equals(this.details, error.details); + } + + @Override + public int hashCode() { + return Objects.hash(code, message, description, retriable, details); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Error {\n"); + sb.append(" code: ").append(toIndentedString(code)).append("\n"); + sb.append(" message: ").append(toIndentedString(message)).append("\n"); + sb.append(" description: ").append(toIndentedString(description)).append("\n"); + sb.append(" retriable: ").append(toIndentedString(retriable)).append("\n"); + sb.append(" details: ").append(toIndentedString(details)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/EventsBlocksRequest.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/EventsBlocksRequest.java new file mode 100644 index 0000000000..a1192f116f --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/EventsBlocksRequest.java @@ -0,0 +1,179 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.NetworkIdentifier; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * EventsBlocksRequest is utilized to fetch a sequence of BlockEvents indicating which blocks were added and removed from storage to reach the current state. + */ +@ApiModel(description = "EventsBlocksRequest is utilized to fetch a sequence of BlockEvents indicating which blocks were added and removed from storage to reach the current state. ") +@JsonPropertyOrder({ + EventsBlocksRequest.JSON_PROPERTY_NETWORK_IDENTIFIER, + EventsBlocksRequest.JSON_PROPERTY_OFFSET, + EventsBlocksRequest.JSON_PROPERTY_LIMIT +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class EventsBlocksRequest { + public static final String JSON_PROPERTY_NETWORK_IDENTIFIER = "network_identifier"; + private NetworkIdentifier networkIdentifier; + + public static final String JSON_PROPERTY_OFFSET = "offset"; + private Long offset; + + public static final String JSON_PROPERTY_LIMIT = "limit"; + private Long limit; + + public EventsBlocksRequest() { + } + + public EventsBlocksRequest networkIdentifier(NetworkIdentifier networkIdentifier) { + this.networkIdentifier = networkIdentifier; + return this; + } + + /** + * Get networkIdentifier + * @return networkIdentifier + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_NETWORK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public NetworkIdentifier getNetworkIdentifier() { + return networkIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_NETWORK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setNetworkIdentifier(NetworkIdentifier networkIdentifier) { + this.networkIdentifier = networkIdentifier; + } + + + public EventsBlocksRequest offset(Long offset) { + this.offset = offset; + return this; + } + + /** + * offset is the offset into the event stream to sync events from. If this field is not populated, we return the limit events backwards from tip. If this is set to 0, we start from the beginning. + * minimum: 0 + * @return offset + **/ + @javax.annotation.Nullable + @ApiModelProperty(example = "5", value = "offset is the offset into the event stream to sync events from. If this field is not populated, we return the limit events backwards from tip. If this is set to 0, we start from the beginning. ") + @JsonProperty(JSON_PROPERTY_OFFSET) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Long getOffset() { + return offset; + } + + + @JsonProperty(JSON_PROPERTY_OFFSET) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setOffset(Long offset) { + this.offset = offset; + } + + + public EventsBlocksRequest limit(Long limit) { + this.limit = limit; + return this; + } + + /** + * limit is the maximum number of events to fetch in one call. The implementation may return <= limit events. + * minimum: 0 + * @return limit + **/ + @javax.annotation.Nullable + @ApiModelProperty(example = "5", value = "limit is the maximum number of events to fetch in one call. The implementation may return <= limit events. ") + @JsonProperty(JSON_PROPERTY_LIMIT) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Long getLimit() { + return limit; + } + + + @JsonProperty(JSON_PROPERTY_LIMIT) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setLimit(Long limit) { + this.limit = limit; + } + + + /** + * Return true if this EventsBlocksRequest object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + EventsBlocksRequest eventsBlocksRequest = (EventsBlocksRequest) o; + return Objects.equals(this.networkIdentifier, eventsBlocksRequest.networkIdentifier) && + Objects.equals(this.offset, eventsBlocksRequest.offset) && + Objects.equals(this.limit, eventsBlocksRequest.limit); + } + + @Override + public int hashCode() { + return Objects.hash(networkIdentifier, offset, limit); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class EventsBlocksRequest {\n"); + sb.append(" networkIdentifier: ").append(toIndentedString(networkIdentifier)).append("\n"); + sb.append(" offset: ").append(toIndentedString(offset)).append("\n"); + sb.append(" limit: ").append(toIndentedString(limit)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/EventsBlocksResponse.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/EventsBlocksResponse.java new file mode 100644 index 0000000000..3d4bff2c48 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/EventsBlocksResponse.java @@ -0,0 +1,153 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.BlockEvent; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import java.util.ArrayList; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * EventsBlocksResponse contains an ordered collection of BlockEvents and the max retrievable sequence. + */ +@ApiModel(description = "EventsBlocksResponse contains an ordered collection of BlockEvents and the max retrievable sequence. ") +@JsonPropertyOrder({ + EventsBlocksResponse.JSON_PROPERTY_MAX_SEQUENCE, + EventsBlocksResponse.JSON_PROPERTY_EVENTS +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class EventsBlocksResponse { + public static final String JSON_PROPERTY_MAX_SEQUENCE = "max_sequence"; + private Long maxSequence; + + public static final String JSON_PROPERTY_EVENTS = "events"; + private List events = new ArrayList<>(); + + public EventsBlocksResponse() { + } + + public EventsBlocksResponse maxSequence(Long maxSequence) { + this.maxSequence = maxSequence; + return this; + } + + /** + * max_sequence is the maximum available sequence number to fetch. + * minimum: 0 + * @return maxSequence + **/ + @javax.annotation.Nonnull + @ApiModelProperty(example = "5", required = true, value = "max_sequence is the maximum available sequence number to fetch. ") + @JsonProperty(JSON_PROPERTY_MAX_SEQUENCE) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public Long getMaxSequence() { + return maxSequence; + } + + + @JsonProperty(JSON_PROPERTY_MAX_SEQUENCE) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setMaxSequence(Long maxSequence) { + this.maxSequence = maxSequence; + } + + + public EventsBlocksResponse events(List events) { + this.events = events; + return this; + } + + public EventsBlocksResponse addEventsItem(BlockEvent eventsItem) { + this.events.add(eventsItem); + return this; + } + + /** + * events is an array of BlockEvents indicating the order to add and remove blocks to maintain a canonical view of blockchain state. Lightweight clients can use this event stream to update state without implementing their own block syncing logic. + * @return events + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "events is an array of BlockEvents indicating the order to add and remove blocks to maintain a canonical view of blockchain state. Lightweight clients can use this event stream to update state without implementing their own block syncing logic. ") + @JsonProperty(JSON_PROPERTY_EVENTS) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public List getEvents() { + return events; + } + + + @JsonProperty(JSON_PROPERTY_EVENTS) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setEvents(List events) { + this.events = events; + } + + + /** + * Return true if this EventsBlocksResponse object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + EventsBlocksResponse eventsBlocksResponse = (EventsBlocksResponse) o; + return Objects.equals(this.maxSequence, eventsBlocksResponse.maxSequence) && + Objects.equals(this.events, eventsBlocksResponse.events); + } + + @Override + public int hashCode() { + return Objects.hash(maxSequence, events); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class EventsBlocksResponse {\n"); + sb.append(" maxSequence: ").append(toIndentedString(maxSequence)).append("\n"); + sb.append(" events: ").append(toIndentedString(events)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ExemptionType.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ExemptionType.java new file mode 100644 index 0000000000..c5de8c695b --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ExemptionType.java @@ -0,0 +1,64 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import io.swagger.annotations.ApiModel; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * ExemptionType is used to indicate if the live balance for an account subject to a BalanceExemption could increase above, decrease below, or equal the computed balance. * greater_or_equal: The live balance may increase above or equal the computed balance. This typically occurs with staking rewards that accrue on each block. * less_or_equal: The live balance may decrease below or equal the computed balance. This typically occurs as balance moves from locked to spendable on a vesting account. * dynamic: The live balance may increase above, decrease below, or equal the computed balance. This typically occurs with tokens that have a dynamic supply. + */ +public enum ExemptionType { + + GREATER_OR_EQUAL("greater_or_equal"), + + LESS_OR_EQUAL("less_or_equal"), + + DYNAMIC("dynamic"); + + private String value; + + ExemptionType(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static ExemptionType fromValue(String value) { + for (ExemptionType b : ExemptionType.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/MempoolResponse.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/MempoolResponse.java new file mode 100644 index 0000000000..ec8ea1931c --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/MempoolResponse.java @@ -0,0 +1,120 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.TransactionIdentifier; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import java.util.ArrayList; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * A MempoolResponse contains all transaction identifiers in the mempool for a particular network_identifier. + */ +@ApiModel(description = "A MempoolResponse contains all transaction identifiers in the mempool for a particular network_identifier. ") +@JsonPropertyOrder({ + MempoolResponse.JSON_PROPERTY_TRANSACTION_IDENTIFIERS +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class MempoolResponse { + public static final String JSON_PROPERTY_TRANSACTION_IDENTIFIERS = "transaction_identifiers"; + private List transactionIdentifiers = new ArrayList<>(); + + public MempoolResponse() { + } + + public MempoolResponse transactionIdentifiers(List transactionIdentifiers) { + this.transactionIdentifiers = transactionIdentifiers; + return this; + } + + public MempoolResponse addTransactionIdentifiersItem(TransactionIdentifier transactionIdentifiersItem) { + this.transactionIdentifiers.add(transactionIdentifiersItem); + return this; + } + + /** + * Get transactionIdentifiers + * @return transactionIdentifiers + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_TRANSACTION_IDENTIFIERS) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public List getTransactionIdentifiers() { + return transactionIdentifiers; + } + + + @JsonProperty(JSON_PROPERTY_TRANSACTION_IDENTIFIERS) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setTransactionIdentifiers(List transactionIdentifiers) { + this.transactionIdentifiers = transactionIdentifiers; + } + + + /** + * Return true if this MempoolResponse object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + MempoolResponse mempoolResponse = (MempoolResponse) o; + return Objects.equals(this.transactionIdentifiers, mempoolResponse.transactionIdentifiers); + } + + @Override + public int hashCode() { + return Objects.hash(transactionIdentifiers); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class MempoolResponse {\n"); + sb.append(" transactionIdentifiers: ").append(toIndentedString(transactionIdentifiers)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/MempoolTransactionRequest.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/MempoolTransactionRequest.java new file mode 100644 index 0000000000..6315899d68 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/MempoolTransactionRequest.java @@ -0,0 +1,146 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.NetworkIdentifier; +import com.radixdlt.api.mesh.generated.models.TransactionIdentifier; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * A MempoolTransactionRequest is utilized to retrieve a transaction from the mempool. + */ +@ApiModel(description = "A MempoolTransactionRequest is utilized to retrieve a transaction from the mempool. ") +@JsonPropertyOrder({ + MempoolTransactionRequest.JSON_PROPERTY_NETWORK_IDENTIFIER, + MempoolTransactionRequest.JSON_PROPERTY_TRANSACTION_IDENTIFIER +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class MempoolTransactionRequest { + public static final String JSON_PROPERTY_NETWORK_IDENTIFIER = "network_identifier"; + private NetworkIdentifier networkIdentifier; + + public static final String JSON_PROPERTY_TRANSACTION_IDENTIFIER = "transaction_identifier"; + private TransactionIdentifier transactionIdentifier; + + public MempoolTransactionRequest() { + } + + public MempoolTransactionRequest networkIdentifier(NetworkIdentifier networkIdentifier) { + this.networkIdentifier = networkIdentifier; + return this; + } + + /** + * Get networkIdentifier + * @return networkIdentifier + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_NETWORK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public NetworkIdentifier getNetworkIdentifier() { + return networkIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_NETWORK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setNetworkIdentifier(NetworkIdentifier networkIdentifier) { + this.networkIdentifier = networkIdentifier; + } + + + public MempoolTransactionRequest transactionIdentifier(TransactionIdentifier transactionIdentifier) { + this.transactionIdentifier = transactionIdentifier; + return this; + } + + /** + * Get transactionIdentifier + * @return transactionIdentifier + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_TRANSACTION_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public TransactionIdentifier getTransactionIdentifier() { + return transactionIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_TRANSACTION_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setTransactionIdentifier(TransactionIdentifier transactionIdentifier) { + this.transactionIdentifier = transactionIdentifier; + } + + + /** + * Return true if this MempoolTransactionRequest object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + MempoolTransactionRequest mempoolTransactionRequest = (MempoolTransactionRequest) o; + return Objects.equals(this.networkIdentifier, mempoolTransactionRequest.networkIdentifier) && + Objects.equals(this.transactionIdentifier, mempoolTransactionRequest.transactionIdentifier); + } + + @Override + public int hashCode() { + return Objects.hash(networkIdentifier, transactionIdentifier); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class MempoolTransactionRequest {\n"); + sb.append(" networkIdentifier: ").append(toIndentedString(networkIdentifier)).append("\n"); + sb.append(" transactionIdentifier: ").append(toIndentedString(transactionIdentifier)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/MempoolTransactionResponse.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/MempoolTransactionResponse.java new file mode 100644 index 0000000000..4b871aec84 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/MempoolTransactionResponse.java @@ -0,0 +1,145 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.Transaction; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * A MempoolTransactionResponse contains an estimate of a mempool transaction. It may not be possible to know the full impact of a transaction in the mempool (ex: fee paid). + */ +@ApiModel(description = "A MempoolTransactionResponse contains an estimate of a mempool transaction. It may not be possible to know the full impact of a transaction in the mempool (ex: fee paid). ") +@JsonPropertyOrder({ + MempoolTransactionResponse.JSON_PROPERTY_TRANSACTION, + MempoolTransactionResponse.JSON_PROPERTY_METADATA +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class MempoolTransactionResponse { + public static final String JSON_PROPERTY_TRANSACTION = "transaction"; + private Transaction transaction; + + public static final String JSON_PROPERTY_METADATA = "metadata"; + private Object metadata; + + public MempoolTransactionResponse() { + } + + public MempoolTransactionResponse transaction(Transaction transaction) { + this.transaction = transaction; + return this; + } + + /** + * Get transaction + * @return transaction + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_TRANSACTION) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public Transaction getTransaction() { + return transaction; + } + + + @JsonProperty(JSON_PROPERTY_TRANSACTION) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setTransaction(Transaction transaction) { + this.transaction = transaction; + } + + + public MempoolTransactionResponse metadata(Object metadata) { + this.metadata = metadata; + return this; + } + + /** + * Get metadata + * @return metadata + **/ + @javax.annotation.Nullable + @ApiModelProperty(example = "{\"descendant_fees\":123923,\"ancestor_count\":2}", value = "") + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Object getMetadata() { + return metadata; + } + + + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setMetadata(Object metadata) { + this.metadata = metadata; + } + + + /** + * Return true if this MempoolTransactionResponse object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + MempoolTransactionResponse mempoolTransactionResponse = (MempoolTransactionResponse) o; + return Objects.equals(this.transaction, mempoolTransactionResponse.transaction) && + Objects.equals(this.metadata, mempoolTransactionResponse.metadata); + } + + @Override + public int hashCode() { + return Objects.hash(transaction, metadata); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class MempoolTransactionResponse {\n"); + sb.append(" transaction: ").append(toIndentedString(transaction)).append("\n"); + sb.append(" metadata: ").append(toIndentedString(metadata)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/MetadataRequest.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/MetadataRequest.java new file mode 100644 index 0000000000..260c5d117e --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/MetadataRequest.java @@ -0,0 +1,112 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * A MetadataRequest is utilized in any request where the only argument is optional metadata. + */ +@ApiModel(description = "A MetadataRequest is utilized in any request where the only argument is optional metadata. ") +@JsonPropertyOrder({ + MetadataRequest.JSON_PROPERTY_METADATA +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class MetadataRequest { + public static final String JSON_PROPERTY_METADATA = "metadata"; + private Object metadata; + + public MetadataRequest() { + } + + public MetadataRequest metadata(Object metadata) { + this.metadata = metadata; + return this; + } + + /** + * Get metadata + * @return metadata + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Object getMetadata() { + return metadata; + } + + + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setMetadata(Object metadata) { + this.metadata = metadata; + } + + + /** + * Return true if this MetadataRequest object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + MetadataRequest metadataRequest = (MetadataRequest) o; + return Objects.equals(this.metadata, metadataRequest.metadata); + } + + @Override + public int hashCode() { + return Objects.hash(metadata); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class MetadataRequest {\n"); + sb.append(" metadata: ").append(toIndentedString(metadata)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ModelCase.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ModelCase.java new file mode 100644 index 0000000000..ec9265ec5a --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/ModelCase.java @@ -0,0 +1,66 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import io.swagger.annotations.ApiModel; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * Case specifies the expected case for strings and hashes. + */ +public enum ModelCase { + + UPPER_CASE("upper_case"), + + LOWER_CASE("lower_case"), + + CASE_SENSITIVE("case_sensitive"), + + NULL("null"); + + private String value; + + ModelCase(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static ModelCase fromValue(String value) { + for (ModelCase b : ModelCase.values()) { + if (b.value.equals(value)) { + return b; + } + } + return null; + } +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/NetworkIdentifier.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/NetworkIdentifier.java new file mode 100644 index 0000000000..0884bbd7bf --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/NetworkIdentifier.java @@ -0,0 +1,177 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.SubNetworkIdentifier; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * The network_identifier specifies which network a particular object is associated with. + */ +@ApiModel(description = "The network_identifier specifies which network a particular object is associated with. ") +@JsonPropertyOrder({ + NetworkIdentifier.JSON_PROPERTY_BLOCKCHAIN, + NetworkIdentifier.JSON_PROPERTY_NETWORK, + NetworkIdentifier.JSON_PROPERTY_SUB_NETWORK_IDENTIFIER +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class NetworkIdentifier { + public static final String JSON_PROPERTY_BLOCKCHAIN = "blockchain"; + private String blockchain; + + public static final String JSON_PROPERTY_NETWORK = "network"; + private String network; + + public static final String JSON_PROPERTY_SUB_NETWORK_IDENTIFIER = "sub_network_identifier"; + private SubNetworkIdentifier subNetworkIdentifier; + + public NetworkIdentifier() { + } + + public NetworkIdentifier blockchain(String blockchain) { + this.blockchain = blockchain; + return this; + } + + /** + * Get blockchain + * @return blockchain + **/ + @javax.annotation.Nonnull + @ApiModelProperty(example = "bitcoin", required = true, value = "") + @JsonProperty(JSON_PROPERTY_BLOCKCHAIN) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getBlockchain() { + return blockchain; + } + + + @JsonProperty(JSON_PROPERTY_BLOCKCHAIN) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setBlockchain(String blockchain) { + this.blockchain = blockchain; + } + + + public NetworkIdentifier network(String network) { + this.network = network; + return this; + } + + /** + * If a blockchain has a specific chain-id or network identifier, it should go in this field. It is up to the client to determine which network-specific identifier is mainnet or testnet. + * @return network + **/ + @javax.annotation.Nonnull + @ApiModelProperty(example = "mainnet", required = true, value = "If a blockchain has a specific chain-id or network identifier, it should go in this field. It is up to the client to determine which network-specific identifier is mainnet or testnet. ") + @JsonProperty(JSON_PROPERTY_NETWORK) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getNetwork() { + return network; + } + + + @JsonProperty(JSON_PROPERTY_NETWORK) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setNetwork(String network) { + this.network = network; + } + + + public NetworkIdentifier subNetworkIdentifier(SubNetworkIdentifier subNetworkIdentifier) { + this.subNetworkIdentifier = subNetworkIdentifier; + return this; + } + + /** + * Get subNetworkIdentifier + * @return subNetworkIdentifier + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_SUB_NETWORK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public SubNetworkIdentifier getSubNetworkIdentifier() { + return subNetworkIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_SUB_NETWORK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setSubNetworkIdentifier(SubNetworkIdentifier subNetworkIdentifier) { + this.subNetworkIdentifier = subNetworkIdentifier; + } + + + /** + * Return true if this NetworkIdentifier object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + NetworkIdentifier networkIdentifier = (NetworkIdentifier) o; + return Objects.equals(this.blockchain, networkIdentifier.blockchain) && + Objects.equals(this.network, networkIdentifier.network) && + Objects.equals(this.subNetworkIdentifier, networkIdentifier.subNetworkIdentifier); + } + + @Override + public int hashCode() { + return Objects.hash(blockchain, network, subNetworkIdentifier); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class NetworkIdentifier {\n"); + sb.append(" blockchain: ").append(toIndentedString(blockchain)).append("\n"); + sb.append(" network: ").append(toIndentedString(network)).append("\n"); + sb.append(" subNetworkIdentifier: ").append(toIndentedString(subNetworkIdentifier)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/NetworkListResponse.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/NetworkListResponse.java new file mode 100644 index 0000000000..08dd7a577b --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/NetworkListResponse.java @@ -0,0 +1,120 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.NetworkIdentifier; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import java.util.ArrayList; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * A NetworkListResponse contains all NetworkIdentifiers that the node can serve information for. + */ +@ApiModel(description = "A NetworkListResponse contains all NetworkIdentifiers that the node can serve information for. ") +@JsonPropertyOrder({ + NetworkListResponse.JSON_PROPERTY_NETWORK_IDENTIFIERS +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class NetworkListResponse { + public static final String JSON_PROPERTY_NETWORK_IDENTIFIERS = "network_identifiers"; + private List networkIdentifiers = new ArrayList<>(); + + public NetworkListResponse() { + } + + public NetworkListResponse networkIdentifiers(List networkIdentifiers) { + this.networkIdentifiers = networkIdentifiers; + return this; + } + + public NetworkListResponse addNetworkIdentifiersItem(NetworkIdentifier networkIdentifiersItem) { + this.networkIdentifiers.add(networkIdentifiersItem); + return this; + } + + /** + * Get networkIdentifiers + * @return networkIdentifiers + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_NETWORK_IDENTIFIERS) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public List getNetworkIdentifiers() { + return networkIdentifiers; + } + + + @JsonProperty(JSON_PROPERTY_NETWORK_IDENTIFIERS) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setNetworkIdentifiers(List networkIdentifiers) { + this.networkIdentifiers = networkIdentifiers; + } + + + /** + * Return true if this NetworkListResponse object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + NetworkListResponse networkListResponse = (NetworkListResponse) o; + return Objects.equals(this.networkIdentifiers, networkListResponse.networkIdentifiers); + } + + @Override + public int hashCode() { + return Objects.hash(networkIdentifiers); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class NetworkListResponse {\n"); + sb.append(" networkIdentifiers: ").append(toIndentedString(networkIdentifiers)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/NetworkOptionsResponse.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/NetworkOptionsResponse.java new file mode 100644 index 0000000000..4c514ee403 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/NetworkOptionsResponse.java @@ -0,0 +1,146 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.Allow; +import com.radixdlt.api.mesh.generated.models.Version; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * NetworkOptionsResponse contains information about the versioning of the node and the allowed operation statuses, operation types, and errors. + */ +@ApiModel(description = "NetworkOptionsResponse contains information about the versioning of the node and the allowed operation statuses, operation types, and errors. ") +@JsonPropertyOrder({ + NetworkOptionsResponse.JSON_PROPERTY_VERSION, + NetworkOptionsResponse.JSON_PROPERTY_ALLOW +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class NetworkOptionsResponse { + public static final String JSON_PROPERTY_VERSION = "version"; + private Version version; + + public static final String JSON_PROPERTY_ALLOW = "allow"; + private Allow allow; + + public NetworkOptionsResponse() { + } + + public NetworkOptionsResponse version(Version version) { + this.version = version; + return this; + } + + /** + * Get version + * @return version + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_VERSION) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public Version getVersion() { + return version; + } + + + @JsonProperty(JSON_PROPERTY_VERSION) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setVersion(Version version) { + this.version = version; + } + + + public NetworkOptionsResponse allow(Allow allow) { + this.allow = allow; + return this; + } + + /** + * Get allow + * @return allow + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_ALLOW) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public Allow getAllow() { + return allow; + } + + + @JsonProperty(JSON_PROPERTY_ALLOW) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setAllow(Allow allow) { + this.allow = allow; + } + + + /** + * Return true if this NetworkOptionsResponse object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + NetworkOptionsResponse networkOptionsResponse = (NetworkOptionsResponse) o; + return Objects.equals(this.version, networkOptionsResponse.version) && + Objects.equals(this.allow, networkOptionsResponse.allow); + } + + @Override + public int hashCode() { + return Objects.hash(version, allow); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class NetworkOptionsResponse {\n"); + sb.append(" version: ").append(toIndentedString(version)).append("\n"); + sb.append(" allow: ").append(toIndentedString(allow)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/NetworkRequest.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/NetworkRequest.java new file mode 100644 index 0000000000..8f27a1e0b7 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/NetworkRequest.java @@ -0,0 +1,145 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.NetworkIdentifier; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * A NetworkRequest is utilized to retrieve some data specific exclusively to a NetworkIdentifier. + */ +@ApiModel(description = "A NetworkRequest is utilized to retrieve some data specific exclusively to a NetworkIdentifier. ") +@JsonPropertyOrder({ + NetworkRequest.JSON_PROPERTY_NETWORK_IDENTIFIER, + NetworkRequest.JSON_PROPERTY_METADATA +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class NetworkRequest { + public static final String JSON_PROPERTY_NETWORK_IDENTIFIER = "network_identifier"; + private NetworkIdentifier networkIdentifier; + + public static final String JSON_PROPERTY_METADATA = "metadata"; + private Object metadata; + + public NetworkRequest() { + } + + public NetworkRequest networkIdentifier(NetworkIdentifier networkIdentifier) { + this.networkIdentifier = networkIdentifier; + return this; + } + + /** + * Get networkIdentifier + * @return networkIdentifier + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_NETWORK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public NetworkIdentifier getNetworkIdentifier() { + return networkIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_NETWORK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setNetworkIdentifier(NetworkIdentifier networkIdentifier) { + this.networkIdentifier = networkIdentifier; + } + + + public NetworkRequest metadata(Object metadata) { + this.metadata = metadata; + return this; + } + + /** + * Get metadata + * @return metadata + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Object getMetadata() { + return metadata; + } + + + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setMetadata(Object metadata) { + this.metadata = metadata; + } + + + /** + * Return true if this NetworkRequest object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + NetworkRequest networkRequest = (NetworkRequest) o; + return Objects.equals(this.networkIdentifier, networkRequest.networkIdentifier) && + Objects.equals(this.metadata, networkRequest.metadata); + } + + @Override + public int hashCode() { + return Objects.hash(networkIdentifier, metadata); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class NetworkRequest {\n"); + sb.append(" networkIdentifier: ").append(toIndentedString(networkIdentifier)).append("\n"); + sb.append(" metadata: ").append(toIndentedString(metadata)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/NetworkStatusResponse.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/NetworkStatusResponse.java new file mode 100644 index 0000000000..82f4514c7d --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/NetworkStatusResponse.java @@ -0,0 +1,286 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.BlockIdentifier; +import com.radixdlt.api.mesh.generated.models.Peer; +import com.radixdlt.api.mesh.generated.models.SyncStatus; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import java.util.ArrayList; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * NetworkStatusResponse contains basic information about the node's view of a blockchain network. It is assumed that any BlockIdentifier.Index less than or equal to CurrentBlockIdentifier.Index can be queried. If a Rosetta implementation prunes historical state, it should populate the optional `oldest_block_identifier` field with the oldest block available to query. If this is not populated, it is assumed that the `genesis_block_identifier` is the oldest queryable block. If a Rosetta implementation performs some pre-sync before it is possible to query blocks, sync_status should be populated so that clients can still monitor healthiness. Without this field, it may appear that the implementation is stuck syncing and needs to be terminated. + */ +@ApiModel(description = "NetworkStatusResponse contains basic information about the node's view of a blockchain network. It is assumed that any BlockIdentifier.Index less than or equal to CurrentBlockIdentifier.Index can be queried. If a Rosetta implementation prunes historical state, it should populate the optional `oldest_block_identifier` field with the oldest block available to query. If this is not populated, it is assumed that the `genesis_block_identifier` is the oldest queryable block. If a Rosetta implementation performs some pre-sync before it is possible to query blocks, sync_status should be populated so that clients can still monitor healthiness. Without this field, it may appear that the implementation is stuck syncing and needs to be terminated. ") +@JsonPropertyOrder({ + NetworkStatusResponse.JSON_PROPERTY_CURRENT_BLOCK_IDENTIFIER, + NetworkStatusResponse.JSON_PROPERTY_CURRENT_BLOCK_TIMESTAMP, + NetworkStatusResponse.JSON_PROPERTY_GENESIS_BLOCK_IDENTIFIER, + NetworkStatusResponse.JSON_PROPERTY_OLDEST_BLOCK_IDENTIFIER, + NetworkStatusResponse.JSON_PROPERTY_SYNC_STATUS, + NetworkStatusResponse.JSON_PROPERTY_PEERS +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class NetworkStatusResponse { + public static final String JSON_PROPERTY_CURRENT_BLOCK_IDENTIFIER = "current_block_identifier"; + private BlockIdentifier currentBlockIdentifier; + + public static final String JSON_PROPERTY_CURRENT_BLOCK_TIMESTAMP = "current_block_timestamp"; + private Long currentBlockTimestamp; + + public static final String JSON_PROPERTY_GENESIS_BLOCK_IDENTIFIER = "genesis_block_identifier"; + private BlockIdentifier genesisBlockIdentifier; + + public static final String JSON_PROPERTY_OLDEST_BLOCK_IDENTIFIER = "oldest_block_identifier"; + private BlockIdentifier oldestBlockIdentifier; + + public static final String JSON_PROPERTY_SYNC_STATUS = "sync_status"; + private SyncStatus syncStatus; + + public static final String JSON_PROPERTY_PEERS = "peers"; + private List peers = null; + + public NetworkStatusResponse() { + } + + public NetworkStatusResponse currentBlockIdentifier(BlockIdentifier currentBlockIdentifier) { + this.currentBlockIdentifier = currentBlockIdentifier; + return this; + } + + /** + * Get currentBlockIdentifier + * @return currentBlockIdentifier + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_CURRENT_BLOCK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public BlockIdentifier getCurrentBlockIdentifier() { + return currentBlockIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_CURRENT_BLOCK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setCurrentBlockIdentifier(BlockIdentifier currentBlockIdentifier) { + this.currentBlockIdentifier = currentBlockIdentifier; + } + + + public NetworkStatusResponse currentBlockTimestamp(Long currentBlockTimestamp) { + this.currentBlockTimestamp = currentBlockTimestamp; + return this; + } + + /** + * The timestamp of the block in milliseconds since the Unix Epoch. The timestamp is stored in milliseconds because some blockchains produce blocks more often than once a second. + * minimum: 0 + * @return currentBlockTimestamp + **/ + @javax.annotation.Nonnull + @ApiModelProperty(example = "1582833600000", required = true, value = "The timestamp of the block in milliseconds since the Unix Epoch. The timestamp is stored in milliseconds because some blockchains produce blocks more often than once a second. ") + @JsonProperty(JSON_PROPERTY_CURRENT_BLOCK_TIMESTAMP) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public Long getCurrentBlockTimestamp() { + return currentBlockTimestamp; + } + + + @JsonProperty(JSON_PROPERTY_CURRENT_BLOCK_TIMESTAMP) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setCurrentBlockTimestamp(Long currentBlockTimestamp) { + this.currentBlockTimestamp = currentBlockTimestamp; + } + + + public NetworkStatusResponse genesisBlockIdentifier(BlockIdentifier genesisBlockIdentifier) { + this.genesisBlockIdentifier = genesisBlockIdentifier; + return this; + } + + /** + * Get genesisBlockIdentifier + * @return genesisBlockIdentifier + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_GENESIS_BLOCK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public BlockIdentifier getGenesisBlockIdentifier() { + return genesisBlockIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_GENESIS_BLOCK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setGenesisBlockIdentifier(BlockIdentifier genesisBlockIdentifier) { + this.genesisBlockIdentifier = genesisBlockIdentifier; + } + + + public NetworkStatusResponse oldestBlockIdentifier(BlockIdentifier oldestBlockIdentifier) { + this.oldestBlockIdentifier = oldestBlockIdentifier; + return this; + } + + /** + * Get oldestBlockIdentifier + * @return oldestBlockIdentifier + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_OLDEST_BLOCK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public BlockIdentifier getOldestBlockIdentifier() { + return oldestBlockIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_OLDEST_BLOCK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setOldestBlockIdentifier(BlockIdentifier oldestBlockIdentifier) { + this.oldestBlockIdentifier = oldestBlockIdentifier; + } + + + public NetworkStatusResponse syncStatus(SyncStatus syncStatus) { + this.syncStatus = syncStatus; + return this; + } + + /** + * Get syncStatus + * @return syncStatus + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_SYNC_STATUS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public SyncStatus getSyncStatus() { + return syncStatus; + } + + + @JsonProperty(JSON_PROPERTY_SYNC_STATUS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setSyncStatus(SyncStatus syncStatus) { + this.syncStatus = syncStatus; + } + + + public NetworkStatusResponse peers(List peers) { + this.peers = peers; + return this; + } + + public NetworkStatusResponse addPeersItem(Peer peersItem) { + if (this.peers == null) { + this.peers = new ArrayList<>(); + } + this.peers.add(peersItem); + return this; + } + + /** + * Get peers + * @return peers + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_PEERS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public List getPeers() { + return peers; + } + + + @JsonProperty(JSON_PROPERTY_PEERS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setPeers(List peers) { + this.peers = peers; + } + + + /** + * Return true if this NetworkStatusResponse object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + NetworkStatusResponse networkStatusResponse = (NetworkStatusResponse) o; + return Objects.equals(this.currentBlockIdentifier, networkStatusResponse.currentBlockIdentifier) && + Objects.equals(this.currentBlockTimestamp, networkStatusResponse.currentBlockTimestamp) && + Objects.equals(this.genesisBlockIdentifier, networkStatusResponse.genesisBlockIdentifier) && + Objects.equals(this.oldestBlockIdentifier, networkStatusResponse.oldestBlockIdentifier) && + Objects.equals(this.syncStatus, networkStatusResponse.syncStatus) && + Objects.equals(this.peers, networkStatusResponse.peers); + } + + @Override + public int hashCode() { + return Objects.hash(currentBlockIdentifier, currentBlockTimestamp, genesisBlockIdentifier, oldestBlockIdentifier, syncStatus, peers); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class NetworkStatusResponse {\n"); + sb.append(" currentBlockIdentifier: ").append(toIndentedString(currentBlockIdentifier)).append("\n"); + sb.append(" currentBlockTimestamp: ").append(toIndentedString(currentBlockTimestamp)).append("\n"); + sb.append(" genesisBlockIdentifier: ").append(toIndentedString(genesisBlockIdentifier)).append("\n"); + sb.append(" oldestBlockIdentifier: ").append(toIndentedString(oldestBlockIdentifier)).append("\n"); + sb.append(" syncStatus: ").append(toIndentedString(syncStatus)).append("\n"); + sb.append(" peers: ").append(toIndentedString(peers)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/Operation.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/Operation.java new file mode 100644 index 0000000000..dc45395ed2 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/Operation.java @@ -0,0 +1,350 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.AccountIdentifier; +import com.radixdlt.api.mesh.generated.models.Amount; +import com.radixdlt.api.mesh.generated.models.CoinChange; +import com.radixdlt.api.mesh.generated.models.OperationIdentifier; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import java.util.ArrayList; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * Operations contain all balance-changing information within a transaction. They are always one-sided (only affect 1 AccountIdentifier) and can succeed or fail independently from a Transaction. Operations are used both to represent on-chain data (Data API) and to construct new transactions (Construction API), creating a standard interface for reading and writing to blockchains. + */ +@ApiModel(description = "Operations contain all balance-changing information within a transaction. They are always one-sided (only affect 1 AccountIdentifier) and can succeed or fail independently from a Transaction. Operations are used both to represent on-chain data (Data API) and to construct new transactions (Construction API), creating a standard interface for reading and writing to blockchains. ") +@JsonPropertyOrder({ + Operation.JSON_PROPERTY_OPERATION_IDENTIFIER, + Operation.JSON_PROPERTY_RELATED_OPERATIONS, + Operation.JSON_PROPERTY_TYPE, + Operation.JSON_PROPERTY_STATUS, + Operation.JSON_PROPERTY_ACCOUNT, + Operation.JSON_PROPERTY_AMOUNT, + Operation.JSON_PROPERTY_COIN_CHANGE, + Operation.JSON_PROPERTY_METADATA +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class Operation { + public static final String JSON_PROPERTY_OPERATION_IDENTIFIER = "operation_identifier"; + private OperationIdentifier operationIdentifier; + + public static final String JSON_PROPERTY_RELATED_OPERATIONS = "related_operations"; + private List relatedOperations = null; + + public static final String JSON_PROPERTY_TYPE = "type"; + private String type; + + public static final String JSON_PROPERTY_STATUS = "status"; + private String status; + + public static final String JSON_PROPERTY_ACCOUNT = "account"; + private AccountIdentifier account; + + public static final String JSON_PROPERTY_AMOUNT = "amount"; + private Amount amount; + + public static final String JSON_PROPERTY_COIN_CHANGE = "coin_change"; + private CoinChange coinChange; + + public static final String JSON_PROPERTY_METADATA = "metadata"; + private Object metadata; + + public Operation() { + } + + public Operation operationIdentifier(OperationIdentifier operationIdentifier) { + this.operationIdentifier = operationIdentifier; + return this; + } + + /** + * Get operationIdentifier + * @return operationIdentifier + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_OPERATION_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public OperationIdentifier getOperationIdentifier() { + return operationIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_OPERATION_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setOperationIdentifier(OperationIdentifier operationIdentifier) { + this.operationIdentifier = operationIdentifier; + } + + + public Operation relatedOperations(List relatedOperations) { + this.relatedOperations = relatedOperations; + return this; + } + + public Operation addRelatedOperationsItem(OperationIdentifier relatedOperationsItem) { + if (this.relatedOperations == null) { + this.relatedOperations = new ArrayList<>(); + } + this.relatedOperations.add(relatedOperationsItem); + return this; + } + + /** + * Restrict referenced related_operations to identifier indices < the current operation_identifier.index. This ensures there exists a clear DAG-structure of relations. Since operations are one-sided, one could imagine relating operations in a single transfer or linking operations in a call tree. + * @return relatedOperations + **/ + @javax.annotation.Nullable + @ApiModelProperty(example = "[{index=1}, {index=2}]", value = "Restrict referenced related_operations to identifier indices < the current operation_identifier.index. This ensures there exists a clear DAG-structure of relations. Since operations are one-sided, one could imagine relating operations in a single transfer or linking operations in a call tree. ") + @JsonProperty(JSON_PROPERTY_RELATED_OPERATIONS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public List getRelatedOperations() { + return relatedOperations; + } + + + @JsonProperty(JSON_PROPERTY_RELATED_OPERATIONS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setRelatedOperations(List relatedOperations) { + this.relatedOperations = relatedOperations; + } + + + public Operation type(String type) { + this.type = type; + return this; + } + + /** + * Type is the network-specific type of the operation. Ensure that any type that can be returned here is also specified in the NetworkOptionsResponse. This can be very useful to downstream consumers that parse all block data. + * @return type + **/ + @javax.annotation.Nonnull + @ApiModelProperty(example = "Transfer", required = true, value = "Type is the network-specific type of the operation. Ensure that any type that can be returned here is also specified in the NetworkOptionsResponse. This can be very useful to downstream consumers that parse all block data. ") + @JsonProperty(JSON_PROPERTY_TYPE) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getType() { + return type; + } + + + @JsonProperty(JSON_PROPERTY_TYPE) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setType(String type) { + this.type = type; + } + + + public Operation status(String status) { + this.status = status; + return this; + } + + /** + * Status is the network-specific status of the operation. Status is not defined on the transaction object because blockchains with smart contracts may have transactions that partially apply (some operations are successful and some are not). Blockchains with atomic transactions (all operations succeed or all operations fail) will have the same status for each operation. On-chain operations (operations retrieved in the `/block` and `/block/transaction` endpoints) MUST have a populated status field (anything on-chain must have succeeded or failed). However, operations provided during transaction construction (often times called \"intent\" in the documentation) MUST NOT have a populated status field (operations yet to be included on-chain have not yet succeeded or failed). + * @return status + **/ + @javax.annotation.Nullable + @ApiModelProperty(example = "Reverted", value = "Status is the network-specific status of the operation. Status is not defined on the transaction object because blockchains with smart contracts may have transactions that partially apply (some operations are successful and some are not). Blockchains with atomic transactions (all operations succeed or all operations fail) will have the same status for each operation. On-chain operations (operations retrieved in the `/block` and `/block/transaction` endpoints) MUST have a populated status field (anything on-chain must have succeeded or failed). However, operations provided during transaction construction (often times called \"intent\" in the documentation) MUST NOT have a populated status field (operations yet to be included on-chain have not yet succeeded or failed). ") + @JsonProperty(JSON_PROPERTY_STATUS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getStatus() { + return status; + } + + + @JsonProperty(JSON_PROPERTY_STATUS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setStatus(String status) { + this.status = status; + } + + + public Operation account(AccountIdentifier account) { + this.account = account; + return this; + } + + /** + * Get account + * @return account + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_ACCOUNT) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public AccountIdentifier getAccount() { + return account; + } + + + @JsonProperty(JSON_PROPERTY_ACCOUNT) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setAccount(AccountIdentifier account) { + this.account = account; + } + + + public Operation amount(Amount amount) { + this.amount = amount; + return this; + } + + /** + * Get amount + * @return amount + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_AMOUNT) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Amount getAmount() { + return amount; + } + + + @JsonProperty(JSON_PROPERTY_AMOUNT) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setAmount(Amount amount) { + this.amount = amount; + } + + + public Operation coinChange(CoinChange coinChange) { + this.coinChange = coinChange; + return this; + } + + /** + * Get coinChange + * @return coinChange + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_COIN_CHANGE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public CoinChange getCoinChange() { + return coinChange; + } + + + @JsonProperty(JSON_PROPERTY_COIN_CHANGE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setCoinChange(CoinChange coinChange) { + this.coinChange = coinChange; + } + + + public Operation metadata(Object metadata) { + this.metadata = metadata; + return this; + } + + /** + * Get metadata + * @return metadata + **/ + @javax.annotation.Nullable + @ApiModelProperty(example = "{asm=304502201fd8abb11443f8b1b9a04e0495e0543d05611473a790c8939f089d073f90509a022100f4677825136605d732e2126d09a2d38c20c75946cd9fc239c0497e84c634e3dd01 03301a8259a12e35694cc22ebc45fee635f4993064190f6ce96e7fb19a03bb6be2, hex=48304502201fd8abb11443f8b1b9a04e0495e0543d05611473a790c8939f089d073f90509a022100f4677825136605d732e2126d09a2d38c20c75946cd9fc239c0497e84c634e3dd012103301a8259a12e35694cc22ebc45fee635f4993064190f6ce96e7fb19a03bb6be2}", value = "") + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Object getMetadata() { + return metadata; + } + + + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setMetadata(Object metadata) { + this.metadata = metadata; + } + + + /** + * Return true if this Operation object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Operation operation = (Operation) o; + return Objects.equals(this.operationIdentifier, operation.operationIdentifier) && + Objects.equals(this.relatedOperations, operation.relatedOperations) && + Objects.equals(this.type, operation.type) && + Objects.equals(this.status, operation.status) && + Objects.equals(this.account, operation.account) && + Objects.equals(this.amount, operation.amount) && + Objects.equals(this.coinChange, operation.coinChange) && + Objects.equals(this.metadata, operation.metadata); + } + + @Override + public int hashCode() { + return Objects.hash(operationIdentifier, relatedOperations, type, status, account, amount, coinChange, metadata); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Operation {\n"); + sb.append(" operationIdentifier: ").append(toIndentedString(operationIdentifier)).append("\n"); + sb.append(" relatedOperations: ").append(toIndentedString(relatedOperations)).append("\n"); + sb.append(" type: ").append(toIndentedString(type)).append("\n"); + sb.append(" status: ").append(toIndentedString(status)).append("\n"); + sb.append(" account: ").append(toIndentedString(account)).append("\n"); + sb.append(" amount: ").append(toIndentedString(amount)).append("\n"); + sb.append(" coinChange: ").append(toIndentedString(coinChange)).append("\n"); + sb.append(" metadata: ").append(toIndentedString(metadata)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/OperationIdentifier.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/OperationIdentifier.java new file mode 100644 index 0000000000..509dc36131 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/OperationIdentifier.java @@ -0,0 +1,146 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * The operation_identifier uniquely identifies an operation within a transaction. + */ +@ApiModel(description = "The operation_identifier uniquely identifies an operation within a transaction. ") +@JsonPropertyOrder({ + OperationIdentifier.JSON_PROPERTY_INDEX, + OperationIdentifier.JSON_PROPERTY_NETWORK_INDEX +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class OperationIdentifier { + public static final String JSON_PROPERTY_INDEX = "index"; + private Long index; + + public static final String JSON_PROPERTY_NETWORK_INDEX = "network_index"; + private Long networkIndex; + + public OperationIdentifier() { + } + + public OperationIdentifier index(Long index) { + this.index = index; + return this; + } + + /** + * The operation index is used to ensure each operation has a unique identifier within a transaction. This index is only relative to the transaction and NOT GLOBAL. The operations in each transaction should start from index 0. To clarify, there may not be any notion of an operation index in the blockchain being described. + * minimum: 0 + * @return index + **/ + @javax.annotation.Nonnull + @ApiModelProperty(example = "5", required = true, value = "The operation index is used to ensure each operation has a unique identifier within a transaction. This index is only relative to the transaction and NOT GLOBAL. The operations in each transaction should start from index 0. To clarify, there may not be any notion of an operation index in the blockchain being described. ") + @JsonProperty(JSON_PROPERTY_INDEX) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public Long getIndex() { + return index; + } + + + @JsonProperty(JSON_PROPERTY_INDEX) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setIndex(Long index) { + this.index = index; + } + + + public OperationIdentifier networkIndex(Long networkIndex) { + this.networkIndex = networkIndex; + return this; + } + + /** + * Some blockchains specify an operation index that is essential for client use. For example, Bitcoin uses a network_index to identify which UTXO was used in a transaction. network_index should not be populated if there is no notion of an operation index in a blockchain (typically most account-based blockchains). + * minimum: 0 + * @return networkIndex + **/ + @javax.annotation.Nullable + @ApiModelProperty(example = "0", value = "Some blockchains specify an operation index that is essential for client use. For example, Bitcoin uses a network_index to identify which UTXO was used in a transaction. network_index should not be populated if there is no notion of an operation index in a blockchain (typically most account-based blockchains). ") + @JsonProperty(JSON_PROPERTY_NETWORK_INDEX) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Long getNetworkIndex() { + return networkIndex; + } + + + @JsonProperty(JSON_PROPERTY_NETWORK_INDEX) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setNetworkIndex(Long networkIndex) { + this.networkIndex = networkIndex; + } + + + /** + * Return true if this OperationIdentifier object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + OperationIdentifier operationIdentifier = (OperationIdentifier) o; + return Objects.equals(this.index, operationIdentifier.index) && + Objects.equals(this.networkIndex, operationIdentifier.networkIndex); + } + + @Override + public int hashCode() { + return Objects.hash(index, networkIndex); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class OperationIdentifier {\n"); + sb.append(" index: ").append(toIndentedString(index)).append("\n"); + sb.append(" networkIndex: ").append(toIndentedString(networkIndex)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/OperationStatus.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/OperationStatus.java new file mode 100644 index 0000000000..3a33b10594 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/OperationStatus.java @@ -0,0 +1,144 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * OperationStatus is utilized to indicate which Operation status are considered successful. + */ +@ApiModel(description = "OperationStatus is utilized to indicate which Operation status are considered successful. ") +@JsonPropertyOrder({ + OperationStatus.JSON_PROPERTY_STATUS, + OperationStatus.JSON_PROPERTY_SUCCESSFUL +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class OperationStatus { + public static final String JSON_PROPERTY_STATUS = "status"; + private String status; + + public static final String JSON_PROPERTY_SUCCESSFUL = "successful"; + private Boolean successful; + + public OperationStatus() { + } + + public OperationStatus status(String status) { + this.status = status; + return this; + } + + /** + * The status is the network-specific status of the operation. + * @return status + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "The status is the network-specific status of the operation. ") + @JsonProperty(JSON_PROPERTY_STATUS) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getStatus() { + return status; + } + + + @JsonProperty(JSON_PROPERTY_STATUS) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setStatus(String status) { + this.status = status; + } + + + public OperationStatus successful(Boolean successful) { + this.successful = successful; + return this; + } + + /** + * An Operation is considered successful if the Operation.Amount should affect the Operation.Account. Some blockchains (like Bitcoin) only include successful operations in blocks but other blockchains (like Ethereum) include unsuccessful operations that incur a fee. To reconcile the computed balance from the stream of Operations, it is critical to understand which Operation.Status indicate an Operation is successful and should affect an Account. + * @return successful + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "An Operation is considered successful if the Operation.Amount should affect the Operation.Account. Some blockchains (like Bitcoin) only include successful operations in blocks but other blockchains (like Ethereum) include unsuccessful operations that incur a fee. To reconcile the computed balance from the stream of Operations, it is critical to understand which Operation.Status indicate an Operation is successful and should affect an Account. ") + @JsonProperty(JSON_PROPERTY_SUCCESSFUL) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public Boolean getSuccessful() { + return successful; + } + + + @JsonProperty(JSON_PROPERTY_SUCCESSFUL) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setSuccessful(Boolean successful) { + this.successful = successful; + } + + + /** + * Return true if this OperationStatus object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + OperationStatus operationStatus = (OperationStatus) o; + return Objects.equals(this.status, operationStatus.status) && + Objects.equals(this.successful, operationStatus.successful); + } + + @Override + public int hashCode() { + return Objects.hash(status, successful); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class OperationStatus {\n"); + sb.append(" status: ").append(toIndentedString(status)).append("\n"); + sb.append(" successful: ").append(toIndentedString(successful)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/Operator.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/Operator.java new file mode 100644 index 0000000000..a8e457404b --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/Operator.java @@ -0,0 +1,62 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import io.swagger.annotations.ApiModel; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * Operator is used by query-related endpoints to determine how to apply conditions. If this field is not populated, the default `and` value will be used. + */ +public enum Operator { + + OR("or"), + + AND("and"); + + private String value; + + Operator(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static Operator fromValue(String value) { + for (Operator b : Operator.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/PartialBlockIdentifier.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/PartialBlockIdentifier.java new file mode 100644 index 0000000000..b95c2c3952 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/PartialBlockIdentifier.java @@ -0,0 +1,144 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * When fetching data by BlockIdentifier, it may be possible to only specify the index or hash. If neither property is specified, it is assumed that the client is making a request at the current block. + */ +@ApiModel(description = "When fetching data by BlockIdentifier, it may be possible to only specify the index or hash. If neither property is specified, it is assumed that the client is making a request at the current block. ") +@JsonPropertyOrder({ + PartialBlockIdentifier.JSON_PROPERTY_INDEX, + PartialBlockIdentifier.JSON_PROPERTY_HASH +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class PartialBlockIdentifier { + public static final String JSON_PROPERTY_INDEX = "index"; + private Long index; + + public static final String JSON_PROPERTY_HASH = "hash"; + private String hash; + + public PartialBlockIdentifier() { + } + + public PartialBlockIdentifier index(Long index) { + this.index = index; + return this; + } + + /** + * Get index + * @return index + **/ + @javax.annotation.Nullable + @ApiModelProperty(example = "1123941", value = "") + @JsonProperty(JSON_PROPERTY_INDEX) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Long getIndex() { + return index; + } + + + @JsonProperty(JSON_PROPERTY_INDEX) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setIndex(Long index) { + this.index = index; + } + + + public PartialBlockIdentifier hash(String hash) { + this.hash = hash; + return this; + } + + /** + * Get hash + * @return hash + **/ + @javax.annotation.Nullable + @ApiModelProperty(example = "0x1f2cc6c5027d2f201a5453ad1119574d2aed23a392654742ac3c78783c071f85", value = "") + @JsonProperty(JSON_PROPERTY_HASH) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getHash() { + return hash; + } + + + @JsonProperty(JSON_PROPERTY_HASH) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setHash(String hash) { + this.hash = hash; + } + + + /** + * Return true if this PartialBlockIdentifier object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PartialBlockIdentifier partialBlockIdentifier = (PartialBlockIdentifier) o; + return Objects.equals(this.index, partialBlockIdentifier.index) && + Objects.equals(this.hash, partialBlockIdentifier.hash); + } + + @Override + public int hashCode() { + return Objects.hash(index, hash); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class PartialBlockIdentifier {\n"); + sb.append(" index: ").append(toIndentedString(index)).append("\n"); + sb.append(" hash: ").append(toIndentedString(hash)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/Peer.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/Peer.java new file mode 100644 index 0000000000..b17c5ebbad --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/Peer.java @@ -0,0 +1,144 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * A Peer is a representation of a node's peer. + */ +@ApiModel(description = "A Peer is a representation of a node's peer. ") +@JsonPropertyOrder({ + Peer.JSON_PROPERTY_PEER_ID, + Peer.JSON_PROPERTY_METADATA +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class Peer { + public static final String JSON_PROPERTY_PEER_ID = "peer_id"; + private String peerId; + + public static final String JSON_PROPERTY_METADATA = "metadata"; + private Object metadata; + + public Peer() { + } + + public Peer peerId(String peerId) { + this.peerId = peerId; + return this; + } + + /** + * Get peerId + * @return peerId + **/ + @javax.annotation.Nonnull + @ApiModelProperty(example = "0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5", required = true, value = "") + @JsonProperty(JSON_PROPERTY_PEER_ID) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getPeerId() { + return peerId; + } + + + @JsonProperty(JSON_PROPERTY_PEER_ID) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setPeerId(String peerId) { + this.peerId = peerId; + } + + + public Peer metadata(Object metadata) { + this.metadata = metadata; + return this; + } + + /** + * Get metadata + * @return metadata + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Object getMetadata() { + return metadata; + } + + + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setMetadata(Object metadata) { + this.metadata = metadata; + } + + + /** + * Return true if this Peer object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Peer peer = (Peer) o; + return Objects.equals(this.peerId, peer.peerId) && + Objects.equals(this.metadata, peer.metadata); + } + + @Override + public int hashCode() { + return Objects.hash(peerId, metadata); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Peer {\n"); + sb.append(" peerId: ").append(toIndentedString(peerId)).append("\n"); + sb.append(" metadata: ").append(toIndentedString(metadata)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/PublicKey.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/PublicKey.java new file mode 100644 index 0000000000..d9e25e355b --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/PublicKey.java @@ -0,0 +1,145 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.CurveType; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * PublicKey contains a public key byte array for a particular CurveType encoded in hex. Note that there is no PrivateKey struct as this is NEVER the concern of an implementation. + */ +@ApiModel(description = "PublicKey contains a public key byte array for a particular CurveType encoded in hex. Note that there is no PrivateKey struct as this is NEVER the concern of an implementation. ") +@JsonPropertyOrder({ + PublicKey.JSON_PROPERTY_HEX_BYTES, + PublicKey.JSON_PROPERTY_CURVE_TYPE +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class PublicKey { + public static final String JSON_PROPERTY_HEX_BYTES = "hex_bytes"; + private String hexBytes; + + public static final String JSON_PROPERTY_CURVE_TYPE = "curve_type"; + private CurveType curveType; + + public PublicKey() { + } + + public PublicKey hexBytes(String hexBytes) { + this.hexBytes = hexBytes; + return this; + } + + /** + * Hex-encoded public key bytes in the format specified by the CurveType. + * @return hexBytes + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "Hex-encoded public key bytes in the format specified by the CurveType. ") + @JsonProperty(JSON_PROPERTY_HEX_BYTES) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getHexBytes() { + return hexBytes; + } + + + @JsonProperty(JSON_PROPERTY_HEX_BYTES) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setHexBytes(String hexBytes) { + this.hexBytes = hexBytes; + } + + + public PublicKey curveType(CurveType curveType) { + this.curveType = curveType; + return this; + } + + /** + * Get curveType + * @return curveType + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_CURVE_TYPE) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public CurveType getCurveType() { + return curveType; + } + + + @JsonProperty(JSON_PROPERTY_CURVE_TYPE) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setCurveType(CurveType curveType) { + this.curveType = curveType; + } + + + /** + * Return true if this PublicKey object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PublicKey publicKey = (PublicKey) o; + return Objects.equals(this.hexBytes, publicKey.hexBytes) && + Objects.equals(this.curveType, publicKey.curveType); + } + + @Override + public int hashCode() { + return Objects.hash(hexBytes, curveType); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class PublicKey {\n"); + sb.append(" hexBytes: ").append(toIndentedString(hexBytes)).append("\n"); + sb.append(" curveType: ").append(toIndentedString(curveType)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/RelatedTransaction.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/RelatedTransaction.java new file mode 100644 index 0000000000..c915e9242a --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/RelatedTransaction.java @@ -0,0 +1,179 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.Direction; +import com.radixdlt.api.mesh.generated.models.NetworkIdentifier; +import com.radixdlt.api.mesh.generated.models.TransactionIdentifier; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * The related_transaction allows implementations to link together multiple transactions. An unpopulated network identifier indicates that the related transaction is on the same network. + */ +@ApiModel(description = "The related_transaction allows implementations to link together multiple transactions. An unpopulated network identifier indicates that the related transaction is on the same network. ") +@JsonPropertyOrder({ + RelatedTransaction.JSON_PROPERTY_NETWORK_IDENTIFIER, + RelatedTransaction.JSON_PROPERTY_TRANSACTION_IDENTIFIER, + RelatedTransaction.JSON_PROPERTY_DIRECTION +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class RelatedTransaction { + public static final String JSON_PROPERTY_NETWORK_IDENTIFIER = "network_identifier"; + private NetworkIdentifier networkIdentifier; + + public static final String JSON_PROPERTY_TRANSACTION_IDENTIFIER = "transaction_identifier"; + private TransactionIdentifier transactionIdentifier; + + public static final String JSON_PROPERTY_DIRECTION = "direction"; + private Direction direction; + + public RelatedTransaction() { + } + + public RelatedTransaction networkIdentifier(NetworkIdentifier networkIdentifier) { + this.networkIdentifier = networkIdentifier; + return this; + } + + /** + * Get networkIdentifier + * @return networkIdentifier + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_NETWORK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public NetworkIdentifier getNetworkIdentifier() { + return networkIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_NETWORK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setNetworkIdentifier(NetworkIdentifier networkIdentifier) { + this.networkIdentifier = networkIdentifier; + } + + + public RelatedTransaction transactionIdentifier(TransactionIdentifier transactionIdentifier) { + this.transactionIdentifier = transactionIdentifier; + return this; + } + + /** + * Get transactionIdentifier + * @return transactionIdentifier + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_TRANSACTION_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public TransactionIdentifier getTransactionIdentifier() { + return transactionIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_TRANSACTION_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setTransactionIdentifier(TransactionIdentifier transactionIdentifier) { + this.transactionIdentifier = transactionIdentifier; + } + + + public RelatedTransaction direction(Direction direction) { + this.direction = direction; + return this; + } + + /** + * Get direction + * @return direction + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_DIRECTION) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public Direction getDirection() { + return direction; + } + + + @JsonProperty(JSON_PROPERTY_DIRECTION) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setDirection(Direction direction) { + this.direction = direction; + } + + + /** + * Return true if this RelatedTransaction object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + RelatedTransaction relatedTransaction = (RelatedTransaction) o; + return Objects.equals(this.networkIdentifier, relatedTransaction.networkIdentifier) && + Objects.equals(this.transactionIdentifier, relatedTransaction.transactionIdentifier) && + Objects.equals(this.direction, relatedTransaction.direction); + } + + @Override + public int hashCode() { + return Objects.hash(networkIdentifier, transactionIdentifier, direction); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class RelatedTransaction {\n"); + sb.append(" networkIdentifier: ").append(toIndentedString(networkIdentifier)).append("\n"); + sb.append(" transactionIdentifier: ").append(toIndentedString(transactionIdentifier)).append("\n"); + sb.append(" direction: ").append(toIndentedString(direction)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/SearchTransactionsRequest.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/SearchTransactionsRequest.java new file mode 100644 index 0000000000..a0dfcd43b5 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/SearchTransactionsRequest.java @@ -0,0 +1,505 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.AccountIdentifier; +import com.radixdlt.api.mesh.generated.models.CoinIdentifier; +import com.radixdlt.api.mesh.generated.models.Currency; +import com.radixdlt.api.mesh.generated.models.NetworkIdentifier; +import com.radixdlt.api.mesh.generated.models.Operator; +import com.radixdlt.api.mesh.generated.models.TransactionIdentifier; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * SearchTransactionsRequest is used to search for transactions matching a set of provided conditions in canonical blocks. + */ +@ApiModel(description = "SearchTransactionsRequest is used to search for transactions matching a set of provided conditions in canonical blocks. ") +@JsonPropertyOrder({ + SearchTransactionsRequest.JSON_PROPERTY_NETWORK_IDENTIFIER, + SearchTransactionsRequest.JSON_PROPERTY_OPERATOR, + SearchTransactionsRequest.JSON_PROPERTY_MAX_BLOCK, + SearchTransactionsRequest.JSON_PROPERTY_OFFSET, + SearchTransactionsRequest.JSON_PROPERTY_LIMIT, + SearchTransactionsRequest.JSON_PROPERTY_TRANSACTION_IDENTIFIER, + SearchTransactionsRequest.JSON_PROPERTY_ACCOUNT_IDENTIFIER, + SearchTransactionsRequest.JSON_PROPERTY_COIN_IDENTIFIER, + SearchTransactionsRequest.JSON_PROPERTY_CURRENCY, + SearchTransactionsRequest.JSON_PROPERTY_STATUS, + SearchTransactionsRequest.JSON_PROPERTY_TYPE, + SearchTransactionsRequest.JSON_PROPERTY_ADDRESS, + SearchTransactionsRequest.JSON_PROPERTY_SUCCESS +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class SearchTransactionsRequest { + public static final String JSON_PROPERTY_NETWORK_IDENTIFIER = "network_identifier"; + private NetworkIdentifier networkIdentifier; + + public static final String JSON_PROPERTY_OPERATOR = "operator"; + private Operator operator; + + public static final String JSON_PROPERTY_MAX_BLOCK = "max_block"; + private Long maxBlock; + + public static final String JSON_PROPERTY_OFFSET = "offset"; + private Long offset; + + public static final String JSON_PROPERTY_LIMIT = "limit"; + private Long limit; + + public static final String JSON_PROPERTY_TRANSACTION_IDENTIFIER = "transaction_identifier"; + private TransactionIdentifier transactionIdentifier; + + public static final String JSON_PROPERTY_ACCOUNT_IDENTIFIER = "account_identifier"; + private AccountIdentifier accountIdentifier; + + public static final String JSON_PROPERTY_COIN_IDENTIFIER = "coin_identifier"; + private CoinIdentifier coinIdentifier; + + public static final String JSON_PROPERTY_CURRENCY = "currency"; + private Currency currency; + + public static final String JSON_PROPERTY_STATUS = "status"; + private String status; + + public static final String JSON_PROPERTY_TYPE = "type"; + private String type; + + public static final String JSON_PROPERTY_ADDRESS = "address"; + private String address; + + public static final String JSON_PROPERTY_SUCCESS = "success"; + private Boolean success; + + public SearchTransactionsRequest() { + } + + public SearchTransactionsRequest networkIdentifier(NetworkIdentifier networkIdentifier) { + this.networkIdentifier = networkIdentifier; + return this; + } + + /** + * Get networkIdentifier + * @return networkIdentifier + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_NETWORK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public NetworkIdentifier getNetworkIdentifier() { + return networkIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_NETWORK_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setNetworkIdentifier(NetworkIdentifier networkIdentifier) { + this.networkIdentifier = networkIdentifier; + } + + + public SearchTransactionsRequest operator(Operator operator) { + this.operator = operator; + return this; + } + + /** + * Get operator + * @return operator + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_OPERATOR) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Operator getOperator() { + return operator; + } + + + @JsonProperty(JSON_PROPERTY_OPERATOR) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setOperator(Operator operator) { + this.operator = operator; + } + + + public SearchTransactionsRequest maxBlock(Long maxBlock) { + this.maxBlock = maxBlock; + return this; + } + + /** + * max_block is the largest block index to consider when searching for transactions. If this field is not populated, the current block is considered the max_block. If you do not specify a max_block, it is possible a newly synced block will interfere with paginated transaction queries (as the offset could become invalid with newly added rows). + * minimum: 0 + * @return maxBlock + **/ + @javax.annotation.Nullable + @ApiModelProperty(example = "5", value = "max_block is the largest block index to consider when searching for transactions. If this field is not populated, the current block is considered the max_block. If you do not specify a max_block, it is possible a newly synced block will interfere with paginated transaction queries (as the offset could become invalid with newly added rows). ") + @JsonProperty(JSON_PROPERTY_MAX_BLOCK) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Long getMaxBlock() { + return maxBlock; + } + + + @JsonProperty(JSON_PROPERTY_MAX_BLOCK) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setMaxBlock(Long maxBlock) { + this.maxBlock = maxBlock; + } + + + public SearchTransactionsRequest offset(Long offset) { + this.offset = offset; + return this; + } + + /** + * offset is the offset into the query result to start returning transactions. If any search conditions are changed, the query offset will change and you must restart your search iteration. + * minimum: 0 + * @return offset + **/ + @javax.annotation.Nullable + @ApiModelProperty(example = "5", value = "offset is the offset into the query result to start returning transactions. If any search conditions are changed, the query offset will change and you must restart your search iteration. ") + @JsonProperty(JSON_PROPERTY_OFFSET) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Long getOffset() { + return offset; + } + + + @JsonProperty(JSON_PROPERTY_OFFSET) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setOffset(Long offset) { + this.offset = offset; + } + + + public SearchTransactionsRequest limit(Long limit) { + this.limit = limit; + return this; + } + + /** + * limit is the maximum number of transactions to return in one call. The implementation may return <= limit transactions. + * minimum: 0 + * @return limit + **/ + @javax.annotation.Nullable + @ApiModelProperty(example = "5", value = "limit is the maximum number of transactions to return in one call. The implementation may return <= limit transactions. ") + @JsonProperty(JSON_PROPERTY_LIMIT) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Long getLimit() { + return limit; + } + + + @JsonProperty(JSON_PROPERTY_LIMIT) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setLimit(Long limit) { + this.limit = limit; + } + + + public SearchTransactionsRequest transactionIdentifier(TransactionIdentifier transactionIdentifier) { + this.transactionIdentifier = transactionIdentifier; + return this; + } + + /** + * Get transactionIdentifier + * @return transactionIdentifier + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_TRANSACTION_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public TransactionIdentifier getTransactionIdentifier() { + return transactionIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_TRANSACTION_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setTransactionIdentifier(TransactionIdentifier transactionIdentifier) { + this.transactionIdentifier = transactionIdentifier; + } + + + public SearchTransactionsRequest accountIdentifier(AccountIdentifier accountIdentifier) { + this.accountIdentifier = accountIdentifier; + return this; + } + + /** + * Get accountIdentifier + * @return accountIdentifier + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_ACCOUNT_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public AccountIdentifier getAccountIdentifier() { + return accountIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_ACCOUNT_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setAccountIdentifier(AccountIdentifier accountIdentifier) { + this.accountIdentifier = accountIdentifier; + } + + + public SearchTransactionsRequest coinIdentifier(CoinIdentifier coinIdentifier) { + this.coinIdentifier = coinIdentifier; + return this; + } + + /** + * Get coinIdentifier + * @return coinIdentifier + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_COIN_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public CoinIdentifier getCoinIdentifier() { + return coinIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_COIN_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setCoinIdentifier(CoinIdentifier coinIdentifier) { + this.coinIdentifier = coinIdentifier; + } + + + public SearchTransactionsRequest currency(Currency currency) { + this.currency = currency; + return this; + } + + /** + * Get currency + * @return currency + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_CURRENCY) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Currency getCurrency() { + return currency; + } + + + @JsonProperty(JSON_PROPERTY_CURRENCY) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setCurrency(Currency currency) { + this.currency = currency; + } + + + public SearchTransactionsRequest status(String status) { + this.status = status; + return this; + } + + /** + * status is the network-specific operation type. + * @return status + **/ + @javax.annotation.Nullable + @ApiModelProperty(example = "reverted", value = "status is the network-specific operation type. ") + @JsonProperty(JSON_PROPERTY_STATUS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getStatus() { + return status; + } + + + @JsonProperty(JSON_PROPERTY_STATUS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setStatus(String status) { + this.status = status; + } + + + public SearchTransactionsRequest type(String type) { + this.type = type; + return this; + } + + /** + * type is the network-specific operation type. + * @return type + **/ + @javax.annotation.Nullable + @ApiModelProperty(example = "transfer", value = "type is the network-specific operation type. ") + @JsonProperty(JSON_PROPERTY_TYPE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getType() { + return type; + } + + + @JsonProperty(JSON_PROPERTY_TYPE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setType(String type) { + this.type = type; + } + + + public SearchTransactionsRequest address(String address) { + this.address = address; + return this; + } + + /** + * address is AccountIdentifier.Address. This is used to get all transactions related to an AccountIdentifier.Address, regardless of SubAccountIdentifier. + * @return address + **/ + @javax.annotation.Nullable + @ApiModelProperty(example = "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", value = "address is AccountIdentifier.Address. This is used to get all transactions related to an AccountIdentifier.Address, regardless of SubAccountIdentifier. ") + @JsonProperty(JSON_PROPERTY_ADDRESS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getAddress() { + return address; + } + + + @JsonProperty(JSON_PROPERTY_ADDRESS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setAddress(String address) { + this.address = address; + } + + + public SearchTransactionsRequest success(Boolean success) { + this.success = success; + return this; + } + + /** + * success is a synthetic condition populated by parsing network-specific operation statuses (using the mapping provided in `/network/options`). + * @return success + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "success is a synthetic condition populated by parsing network-specific operation statuses (using the mapping provided in `/network/options`). ") + @JsonProperty(JSON_PROPERTY_SUCCESS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Boolean getSuccess() { + return success; + } + + + @JsonProperty(JSON_PROPERTY_SUCCESS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setSuccess(Boolean success) { + this.success = success; + } + + + /** + * Return true if this SearchTransactionsRequest object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + SearchTransactionsRequest searchTransactionsRequest = (SearchTransactionsRequest) o; + return Objects.equals(this.networkIdentifier, searchTransactionsRequest.networkIdentifier) && + Objects.equals(this.operator, searchTransactionsRequest.operator) && + Objects.equals(this.maxBlock, searchTransactionsRequest.maxBlock) && + Objects.equals(this.offset, searchTransactionsRequest.offset) && + Objects.equals(this.limit, searchTransactionsRequest.limit) && + Objects.equals(this.transactionIdentifier, searchTransactionsRequest.transactionIdentifier) && + Objects.equals(this.accountIdentifier, searchTransactionsRequest.accountIdentifier) && + Objects.equals(this.coinIdentifier, searchTransactionsRequest.coinIdentifier) && + Objects.equals(this.currency, searchTransactionsRequest.currency) && + Objects.equals(this.status, searchTransactionsRequest.status) && + Objects.equals(this.type, searchTransactionsRequest.type) && + Objects.equals(this.address, searchTransactionsRequest.address) && + Objects.equals(this.success, searchTransactionsRequest.success); + } + + @Override + public int hashCode() { + return Objects.hash(networkIdentifier, operator, maxBlock, offset, limit, transactionIdentifier, accountIdentifier, coinIdentifier, currency, status, type, address, success); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class SearchTransactionsRequest {\n"); + sb.append(" networkIdentifier: ").append(toIndentedString(networkIdentifier)).append("\n"); + sb.append(" operator: ").append(toIndentedString(operator)).append("\n"); + sb.append(" maxBlock: ").append(toIndentedString(maxBlock)).append("\n"); + sb.append(" offset: ").append(toIndentedString(offset)).append("\n"); + sb.append(" limit: ").append(toIndentedString(limit)).append("\n"); + sb.append(" transactionIdentifier: ").append(toIndentedString(transactionIdentifier)).append("\n"); + sb.append(" accountIdentifier: ").append(toIndentedString(accountIdentifier)).append("\n"); + sb.append(" coinIdentifier: ").append(toIndentedString(coinIdentifier)).append("\n"); + sb.append(" currency: ").append(toIndentedString(currency)).append("\n"); + sb.append(" status: ").append(toIndentedString(status)).append("\n"); + sb.append(" type: ").append(toIndentedString(type)).append("\n"); + sb.append(" address: ").append(toIndentedString(address)).append("\n"); + sb.append(" success: ").append(toIndentedString(success)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/SearchTransactionsResponse.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/SearchTransactionsResponse.java new file mode 100644 index 0000000000..1049520a86 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/SearchTransactionsResponse.java @@ -0,0 +1,186 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.BlockTransaction; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import java.util.ArrayList; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * SearchTransactionsResponse contains an ordered collection of BlockTransactions that match the query in SearchTransactionsRequest. These BlockTransactions are sorted from most recent block to oldest block. + */ +@ApiModel(description = "SearchTransactionsResponse contains an ordered collection of BlockTransactions that match the query in SearchTransactionsRequest. These BlockTransactions are sorted from most recent block to oldest block. ") +@JsonPropertyOrder({ + SearchTransactionsResponse.JSON_PROPERTY_TRANSACTIONS, + SearchTransactionsResponse.JSON_PROPERTY_TOTAL_COUNT, + SearchTransactionsResponse.JSON_PROPERTY_NEXT_OFFSET +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class SearchTransactionsResponse { + public static final String JSON_PROPERTY_TRANSACTIONS = "transactions"; + private List transactions = new ArrayList<>(); + + public static final String JSON_PROPERTY_TOTAL_COUNT = "total_count"; + private Long totalCount; + + public static final String JSON_PROPERTY_NEXT_OFFSET = "next_offset"; + private Long nextOffset; + + public SearchTransactionsResponse() { + } + + public SearchTransactionsResponse transactions(List transactions) { + this.transactions = transactions; + return this; + } + + public SearchTransactionsResponse addTransactionsItem(BlockTransaction transactionsItem) { + this.transactions.add(transactionsItem); + return this; + } + + /** + * transactions is an array of BlockTransactions sorted by most recent BlockIdentifier (meaning that transactions in recent blocks appear first). If there are many transactions for a particular search, transactions may not contain all matching transactions. It is up to the caller to paginate these transactions using the max_block field. + * @return transactions + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "transactions is an array of BlockTransactions sorted by most recent BlockIdentifier (meaning that transactions in recent blocks appear first). If there are many transactions for a particular search, transactions may not contain all matching transactions. It is up to the caller to paginate these transactions using the max_block field. ") + @JsonProperty(JSON_PROPERTY_TRANSACTIONS) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public List getTransactions() { + return transactions; + } + + + @JsonProperty(JSON_PROPERTY_TRANSACTIONS) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setTransactions(List transactions) { + this.transactions = transactions; + } + + + public SearchTransactionsResponse totalCount(Long totalCount) { + this.totalCount = totalCount; + return this; + } + + /** + * total_count is the number of results for a given search. Callers typically use this value to concurrently fetch results by offset or to display a virtual page number associated with results. + * minimum: 0 + * @return totalCount + **/ + @javax.annotation.Nonnull + @ApiModelProperty(example = "5", required = true, value = "total_count is the number of results for a given search. Callers typically use this value to concurrently fetch results by offset or to display a virtual page number associated with results. ") + @JsonProperty(JSON_PROPERTY_TOTAL_COUNT) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public Long getTotalCount() { + return totalCount; + } + + + @JsonProperty(JSON_PROPERTY_TOTAL_COUNT) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setTotalCount(Long totalCount) { + this.totalCount = totalCount; + } + + + public SearchTransactionsResponse nextOffset(Long nextOffset) { + this.nextOffset = nextOffset; + return this; + } + + /** + * next_offset is the next offset to use when paginating through transaction results. If this field is not populated, there are no more transactions to query. + * minimum: 0 + * @return nextOffset + **/ + @javax.annotation.Nullable + @ApiModelProperty(example = "5", value = "next_offset is the next offset to use when paginating through transaction results. If this field is not populated, there are no more transactions to query. ") + @JsonProperty(JSON_PROPERTY_NEXT_OFFSET) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Long getNextOffset() { + return nextOffset; + } + + + @JsonProperty(JSON_PROPERTY_NEXT_OFFSET) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setNextOffset(Long nextOffset) { + this.nextOffset = nextOffset; + } + + + /** + * Return true if this SearchTransactionsResponse object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + SearchTransactionsResponse searchTransactionsResponse = (SearchTransactionsResponse) o; + return Objects.equals(this.transactions, searchTransactionsResponse.transactions) && + Objects.equals(this.totalCount, searchTransactionsResponse.totalCount) && + Objects.equals(this.nextOffset, searchTransactionsResponse.nextOffset); + } + + @Override + public int hashCode() { + return Objects.hash(transactions, totalCount, nextOffset); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class SearchTransactionsResponse {\n"); + sb.append(" transactions: ").append(toIndentedString(transactions)).append("\n"); + sb.append(" totalCount: ").append(toIndentedString(totalCount)).append("\n"); + sb.append(" nextOffset: ").append(toIndentedString(nextOffset)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/Signature.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/Signature.java new file mode 100644 index 0000000000..27b125495d --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/Signature.java @@ -0,0 +1,211 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.PublicKey; +import com.radixdlt.api.mesh.generated.models.SignatureType; +import com.radixdlt.api.mesh.generated.models.SigningPayload; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * Signature contains the payload that was signed, the public keys of the keypairs used to produce the signature, the signature (encoded in hex), and the SignatureType. PublicKey is often times not known during construction of the signing payloads but may be needed to combine signatures properly. + */ +@ApiModel(description = "Signature contains the payload that was signed, the public keys of the keypairs used to produce the signature, the signature (encoded in hex), and the SignatureType. PublicKey is often times not known during construction of the signing payloads but may be needed to combine signatures properly. ") +@JsonPropertyOrder({ + Signature.JSON_PROPERTY_SIGNING_PAYLOAD, + Signature.JSON_PROPERTY_PUBLIC_KEY, + Signature.JSON_PROPERTY_SIGNATURE_TYPE, + Signature.JSON_PROPERTY_HEX_BYTES +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class Signature { + public static final String JSON_PROPERTY_SIGNING_PAYLOAD = "signing_payload"; + private SigningPayload signingPayload; + + public static final String JSON_PROPERTY_PUBLIC_KEY = "public_key"; + private PublicKey publicKey; + + public static final String JSON_PROPERTY_SIGNATURE_TYPE = "signature_type"; + private SignatureType signatureType; + + public static final String JSON_PROPERTY_HEX_BYTES = "hex_bytes"; + private String hexBytes; + + public Signature() { + } + + public Signature signingPayload(SigningPayload signingPayload) { + this.signingPayload = signingPayload; + return this; + } + + /** + * Get signingPayload + * @return signingPayload + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_SIGNING_PAYLOAD) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public SigningPayload getSigningPayload() { + return signingPayload; + } + + + @JsonProperty(JSON_PROPERTY_SIGNING_PAYLOAD) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setSigningPayload(SigningPayload signingPayload) { + this.signingPayload = signingPayload; + } + + + public Signature publicKey(PublicKey publicKey) { + this.publicKey = publicKey; + return this; + } + + /** + * Get publicKey + * @return publicKey + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_PUBLIC_KEY) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public PublicKey getPublicKey() { + return publicKey; + } + + + @JsonProperty(JSON_PROPERTY_PUBLIC_KEY) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setPublicKey(PublicKey publicKey) { + this.publicKey = publicKey; + } + + + public Signature signatureType(SignatureType signatureType) { + this.signatureType = signatureType; + return this; + } + + /** + * Get signatureType + * @return signatureType + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_SIGNATURE_TYPE) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public SignatureType getSignatureType() { + return signatureType; + } + + + @JsonProperty(JSON_PROPERTY_SIGNATURE_TYPE) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setSignatureType(SignatureType signatureType) { + this.signatureType = signatureType; + } + + + public Signature hexBytes(String hexBytes) { + this.hexBytes = hexBytes; + return this; + } + + /** + * Get hexBytes + * @return hexBytes + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_HEX_BYTES) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getHexBytes() { + return hexBytes; + } + + + @JsonProperty(JSON_PROPERTY_HEX_BYTES) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setHexBytes(String hexBytes) { + this.hexBytes = hexBytes; + } + + + /** + * Return true if this Signature object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Signature signature = (Signature) o; + return Objects.equals(this.signingPayload, signature.signingPayload) && + Objects.equals(this.publicKey, signature.publicKey) && + Objects.equals(this.signatureType, signature.signatureType) && + Objects.equals(this.hexBytes, signature.hexBytes); + } + + @Override + public int hashCode() { + return Objects.hash(signingPayload, publicKey, signatureType, hexBytes); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Signature {\n"); + sb.append(" signingPayload: ").append(toIndentedString(signingPayload)).append("\n"); + sb.append(" publicKey: ").append(toIndentedString(publicKey)).append("\n"); + sb.append(" signatureType: ").append(toIndentedString(signatureType)).append("\n"); + sb.append(" hexBytes: ").append(toIndentedString(hexBytes)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/SignatureType.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/SignatureType.java new file mode 100644 index 0000000000..8369a7df3f --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/SignatureType.java @@ -0,0 +1,70 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import io.swagger.annotations.ApiModel; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * SignatureType is the type of a cryptographic signature. * ecdsa: `r (32-bytes) || s (32-bytes)` - `64 bytes` * ecdsa_recovery: `r (32-bytes) || s (32-bytes) || v (1-byte)` - `65 bytes` * ed25519: `R (32-byte) || s (32-bytes)` - `64 bytes` * schnorr_1: `r (32-bytes) || s (32-bytes)` - `64 bytes` (schnorr signature implemented by Zilliqa where both `r` and `s` are scalars encoded as `32-bytes` values, most significant byte first.) * schnorr_bip340: `r (32-bytes) || s (32-bytes)` - `64 bytes` (sig = (bytes(R) || bytes((k + ed) mod n) where `r` is the `X` coordinate of a point `R` whose `Y` coordinate is even, most significant bytes first.) * schnorr_poseidon: `r (32-bytes) || s (32-bytes)` where s = Hash(1st pk || 2nd pk || r) - `64 bytes` (schnorr signature w/ Poseidon hash function implemented by O(1) Labs where both `r` and `s` are scalars encoded as `32-bytes` values, least significant byte first. https://github.com/CodaProtocol/signer-reference/blob/master/schnorr.ml ) + */ +public enum SignatureType { + + ECDSA("ecdsa"), + + ECDSA_RECOVERY("ecdsa_recovery"), + + ED25519("ed25519"), + + SCHNORR_1("schnorr_1"), + + SCHNORR_BIP340("schnorr_bip340"), + + SCHNORR_POSEIDON("schnorr_poseidon"); + + private String value; + + SignatureType(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static SignatureType fromValue(String value) { + for (SignatureType b : SignatureType.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/SigningPayload.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/SigningPayload.java new file mode 100644 index 0000000000..988b3f0154 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/SigningPayload.java @@ -0,0 +1,210 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.AccountIdentifier; +import com.radixdlt.api.mesh.generated.models.SignatureType; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * SigningPayload is signed by the client with the keypair associated with an AccountIdentifier using the specified SignatureType. SignatureType can be optionally populated if there is a restriction on the signature scheme that can be used to sign the payload. + */ +@ApiModel(description = "SigningPayload is signed by the client with the keypair associated with an AccountIdentifier using the specified SignatureType. SignatureType can be optionally populated if there is a restriction on the signature scheme that can be used to sign the payload. ") +@JsonPropertyOrder({ + SigningPayload.JSON_PROPERTY_ADDRESS, + SigningPayload.JSON_PROPERTY_ACCOUNT_IDENTIFIER, + SigningPayload.JSON_PROPERTY_HEX_BYTES, + SigningPayload.JSON_PROPERTY_SIGNATURE_TYPE +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class SigningPayload { + public static final String JSON_PROPERTY_ADDRESS = "address"; + private String address; + + public static final String JSON_PROPERTY_ACCOUNT_IDENTIFIER = "account_identifier"; + private AccountIdentifier accountIdentifier; + + public static final String JSON_PROPERTY_HEX_BYTES = "hex_bytes"; + private String hexBytes; + + public static final String JSON_PROPERTY_SIGNATURE_TYPE = "signature_type"; + private SignatureType signatureType; + + public SigningPayload() { + } + + public SigningPayload address(String address) { + this.address = address; + return this; + } + + /** + * [DEPRECATED by `account_identifier` in `v1.4.4`] The network-specific address of the account that should sign the payload. + * @return address + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "[DEPRECATED by `account_identifier` in `v1.4.4`] The network-specific address of the account that should sign the payload. ") + @JsonProperty(JSON_PROPERTY_ADDRESS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getAddress() { + return address; + } + + + @JsonProperty(JSON_PROPERTY_ADDRESS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setAddress(String address) { + this.address = address; + } + + + public SigningPayload accountIdentifier(AccountIdentifier accountIdentifier) { + this.accountIdentifier = accountIdentifier; + return this; + } + + /** + * Get accountIdentifier + * @return accountIdentifier + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_ACCOUNT_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public AccountIdentifier getAccountIdentifier() { + return accountIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_ACCOUNT_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setAccountIdentifier(AccountIdentifier accountIdentifier) { + this.accountIdentifier = accountIdentifier; + } + + + public SigningPayload hexBytes(String hexBytes) { + this.hexBytes = hexBytes; + return this; + } + + /** + * Hex-encoded string of the payload bytes. + * @return hexBytes + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "Hex-encoded string of the payload bytes. ") + @JsonProperty(JSON_PROPERTY_HEX_BYTES) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getHexBytes() { + return hexBytes; + } + + + @JsonProperty(JSON_PROPERTY_HEX_BYTES) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setHexBytes(String hexBytes) { + this.hexBytes = hexBytes; + } + + + public SigningPayload signatureType(SignatureType signatureType) { + this.signatureType = signatureType; + return this; + } + + /** + * Get signatureType + * @return signatureType + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_SIGNATURE_TYPE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public SignatureType getSignatureType() { + return signatureType; + } + + + @JsonProperty(JSON_PROPERTY_SIGNATURE_TYPE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setSignatureType(SignatureType signatureType) { + this.signatureType = signatureType; + } + + + /** + * Return true if this SigningPayload object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + SigningPayload signingPayload = (SigningPayload) o; + return Objects.equals(this.address, signingPayload.address) && + Objects.equals(this.accountIdentifier, signingPayload.accountIdentifier) && + Objects.equals(this.hexBytes, signingPayload.hexBytes) && + Objects.equals(this.signatureType, signingPayload.signatureType); + } + + @Override + public int hashCode() { + return Objects.hash(address, accountIdentifier, hexBytes, signatureType); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class SigningPayload {\n"); + sb.append(" address: ").append(toIndentedString(address)).append("\n"); + sb.append(" accountIdentifier: ").append(toIndentedString(accountIdentifier)).append("\n"); + sb.append(" hexBytes: ").append(toIndentedString(hexBytes)).append("\n"); + sb.append(" signatureType: ").append(toIndentedString(signatureType)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/SubAccountIdentifier.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/SubAccountIdentifier.java new file mode 100644 index 0000000000..007eb9944e --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/SubAccountIdentifier.java @@ -0,0 +1,144 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * An account may have state specific to a contract address (ERC-20 token) and/or a stake (delegated balance). The sub_account_identifier should specify which state (if applicable) an account instantiation refers to. + */ +@ApiModel(description = "An account may have state specific to a contract address (ERC-20 token) and/or a stake (delegated balance). The sub_account_identifier should specify which state (if applicable) an account instantiation refers to. ") +@JsonPropertyOrder({ + SubAccountIdentifier.JSON_PROPERTY_ADDRESS, + SubAccountIdentifier.JSON_PROPERTY_METADATA +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class SubAccountIdentifier { + public static final String JSON_PROPERTY_ADDRESS = "address"; + private String address; + + public static final String JSON_PROPERTY_METADATA = "metadata"; + private Object metadata; + + public SubAccountIdentifier() { + } + + public SubAccountIdentifier address(String address) { + this.address = address; + return this; + } + + /** + * The SubAccount address may be a cryptographic value or some other identifier (ex: bonded) that uniquely specifies a SubAccount. + * @return address + **/ + @javax.annotation.Nonnull + @ApiModelProperty(example = "0x6b175474e89094c44da98b954eedeac495271d0f", required = true, value = "The SubAccount address may be a cryptographic value or some other identifier (ex: bonded) that uniquely specifies a SubAccount. ") + @JsonProperty(JSON_PROPERTY_ADDRESS) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getAddress() { + return address; + } + + + @JsonProperty(JSON_PROPERTY_ADDRESS) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setAddress(String address) { + this.address = address; + } + + + public SubAccountIdentifier metadata(Object metadata) { + this.metadata = metadata; + return this; + } + + /** + * If the SubAccount address is not sufficient to uniquely specify a SubAccount, any other identifying information can be stored here. It is important to note that two SubAccounts with identical addresses but differing metadata will not be considered equal by clients. + * @return metadata + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "If the SubAccount address is not sufficient to uniquely specify a SubAccount, any other identifying information can be stored here. It is important to note that two SubAccounts with identical addresses but differing metadata will not be considered equal by clients. ") + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Object getMetadata() { + return metadata; + } + + + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setMetadata(Object metadata) { + this.metadata = metadata; + } + + + /** + * Return true if this SubAccountIdentifier object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + SubAccountIdentifier subAccountIdentifier = (SubAccountIdentifier) o; + return Objects.equals(this.address, subAccountIdentifier.address) && + Objects.equals(this.metadata, subAccountIdentifier.metadata); + } + + @Override + public int hashCode() { + return Objects.hash(address, metadata); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class SubAccountIdentifier {\n"); + sb.append(" address: ").append(toIndentedString(address)).append("\n"); + sb.append(" metadata: ").append(toIndentedString(metadata)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/SubNetworkIdentifier.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/SubNetworkIdentifier.java new file mode 100644 index 0000000000..5bd32e223e --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/SubNetworkIdentifier.java @@ -0,0 +1,144 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * In blockchains with sharded state, the SubNetworkIdentifier is required to query some object on a specific shard. This identifier is optional for all non-sharded blockchains. + */ +@ApiModel(description = "In blockchains with sharded state, the SubNetworkIdentifier is required to query some object on a specific shard. This identifier is optional for all non-sharded blockchains. ") +@JsonPropertyOrder({ + SubNetworkIdentifier.JSON_PROPERTY_NETWORK, + SubNetworkIdentifier.JSON_PROPERTY_METADATA +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class SubNetworkIdentifier { + public static final String JSON_PROPERTY_NETWORK = "network"; + private String network; + + public static final String JSON_PROPERTY_METADATA = "metadata"; + private Object metadata; + + public SubNetworkIdentifier() { + } + + public SubNetworkIdentifier network(String network) { + this.network = network; + return this; + } + + /** + * Get network + * @return network + **/ + @javax.annotation.Nonnull + @ApiModelProperty(example = "shard 1", required = true, value = "") + @JsonProperty(JSON_PROPERTY_NETWORK) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getNetwork() { + return network; + } + + + @JsonProperty(JSON_PROPERTY_NETWORK) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setNetwork(String network) { + this.network = network; + } + + + public SubNetworkIdentifier metadata(Object metadata) { + this.metadata = metadata; + return this; + } + + /** + * Get metadata + * @return metadata + **/ + @javax.annotation.Nullable + @ApiModelProperty(example = "{producer=0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5}", value = "") + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Object getMetadata() { + return metadata; + } + + + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setMetadata(Object metadata) { + this.metadata = metadata; + } + + + /** + * Return true if this SubNetworkIdentifier object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + SubNetworkIdentifier subNetworkIdentifier = (SubNetworkIdentifier) o; + return Objects.equals(this.network, subNetworkIdentifier.network) && + Objects.equals(this.metadata, subNetworkIdentifier.metadata); + } + + @Override + public int hashCode() { + return Objects.hash(network, metadata); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class SubNetworkIdentifier {\n"); + sb.append(" network: ").append(toIndentedString(network)).append("\n"); + sb.append(" metadata: ").append(toIndentedString(metadata)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/SyncStatus.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/SyncStatus.java new file mode 100644 index 0000000000..1745568ecc --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/SyncStatus.java @@ -0,0 +1,208 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * SyncStatus is used to provide additional context about an implementation's sync status. This object is often used by implementations to indicate healthiness when block data cannot be queried until some sync phase completes or cannot be determined by comparing the timestamp of the most recent block with the current time. + */ +@ApiModel(description = "SyncStatus is used to provide additional context about an implementation's sync status. This object is often used by implementations to indicate healthiness when block data cannot be queried until some sync phase completes or cannot be determined by comparing the timestamp of the most recent block with the current time. ") +@JsonPropertyOrder({ + SyncStatus.JSON_PROPERTY_CURRENT_INDEX, + SyncStatus.JSON_PROPERTY_TARGET_INDEX, + SyncStatus.JSON_PROPERTY_STAGE, + SyncStatus.JSON_PROPERTY_SYNCED +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class SyncStatus { + public static final String JSON_PROPERTY_CURRENT_INDEX = "current_index"; + private Long currentIndex; + + public static final String JSON_PROPERTY_TARGET_INDEX = "target_index"; + private Long targetIndex; + + public static final String JSON_PROPERTY_STAGE = "stage"; + private String stage; + + public static final String JSON_PROPERTY_SYNCED = "synced"; + private Boolean synced; + + public SyncStatus() { + } + + public SyncStatus currentIndex(Long currentIndex) { + this.currentIndex = currentIndex; + return this; + } + + /** + * CurrentIndex is the index of the last synced block in the current stage. This is a separate field from current_block_identifier in NetworkStatusResponse because blocks with indices up to and including the current_index may not yet be queryable by the caller. To reiterate, all indices up to and including current_block_identifier in NetworkStatusResponse must be queryable via the /block endpoint (excluding indices less than oldest_block_identifier). + * @return currentIndex + **/ + @javax.annotation.Nullable + @ApiModelProperty(example = "100", value = "CurrentIndex is the index of the last synced block in the current stage. This is a separate field from current_block_identifier in NetworkStatusResponse because blocks with indices up to and including the current_index may not yet be queryable by the caller. To reiterate, all indices up to and including current_block_identifier in NetworkStatusResponse must be queryable via the /block endpoint (excluding indices less than oldest_block_identifier). ") + @JsonProperty(JSON_PROPERTY_CURRENT_INDEX) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Long getCurrentIndex() { + return currentIndex; + } + + + @JsonProperty(JSON_PROPERTY_CURRENT_INDEX) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setCurrentIndex(Long currentIndex) { + this.currentIndex = currentIndex; + } + + + public SyncStatus targetIndex(Long targetIndex) { + this.targetIndex = targetIndex; + return this; + } + + /** + * TargetIndex is the index of the block that the implementation is attempting to sync to in the current stage. + * @return targetIndex + **/ + @javax.annotation.Nullable + @ApiModelProperty(example = "150", value = "TargetIndex is the index of the block that the implementation is attempting to sync to in the current stage. ") + @JsonProperty(JSON_PROPERTY_TARGET_INDEX) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Long getTargetIndex() { + return targetIndex; + } + + + @JsonProperty(JSON_PROPERTY_TARGET_INDEX) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setTargetIndex(Long targetIndex) { + this.targetIndex = targetIndex; + } + + + public SyncStatus stage(String stage) { + this.stage = stage; + return this; + } + + /** + * Stage is the phase of the sync process. + * @return stage + **/ + @javax.annotation.Nullable + @ApiModelProperty(example = "header sync", value = "Stage is the phase of the sync process. ") + @JsonProperty(JSON_PROPERTY_STAGE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getStage() { + return stage; + } + + + @JsonProperty(JSON_PROPERTY_STAGE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setStage(String stage) { + this.stage = stage; + } + + + public SyncStatus synced(Boolean synced) { + this.synced = synced; + return this; + } + + /** + * synced is a boolean that indicates if an implementation has synced up to the most recent block. If this field is not populated, the caller should rely on a traditional tip timestamp comparison to determine if an implementation is synced. This field is particularly useful for quiescent blockchains (blocks only produced when there are pending transactions). In these blockchains, the most recent block could have a timestamp far behind the current time but the node could be healthy and at tip. + * @return synced + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "synced is a boolean that indicates if an implementation has synced up to the most recent block. If this field is not populated, the caller should rely on a traditional tip timestamp comparison to determine if an implementation is synced. This field is particularly useful for quiescent blockchains (blocks only produced when there are pending transactions). In these blockchains, the most recent block could have a timestamp far behind the current time but the node could be healthy and at tip. ") + @JsonProperty(JSON_PROPERTY_SYNCED) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Boolean getSynced() { + return synced; + } + + + @JsonProperty(JSON_PROPERTY_SYNCED) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setSynced(Boolean synced) { + this.synced = synced; + } + + + /** + * Return true if this SyncStatus object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + SyncStatus syncStatus = (SyncStatus) o; + return Objects.equals(this.currentIndex, syncStatus.currentIndex) && + Objects.equals(this.targetIndex, syncStatus.targetIndex) && + Objects.equals(this.stage, syncStatus.stage) && + Objects.equals(this.synced, syncStatus.synced); + } + + @Override + public int hashCode() { + return Objects.hash(currentIndex, targetIndex, stage, synced); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class SyncStatus {\n"); + sb.append(" currentIndex: ").append(toIndentedString(currentIndex)).append("\n"); + sb.append(" targetIndex: ").append(toIndentedString(targetIndex)).append("\n"); + sb.append(" stage: ").append(toIndentedString(stage)).append("\n"); + sb.append(" synced: ").append(toIndentedString(synced)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/Transaction.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/Transaction.java new file mode 100644 index 0000000000..e8e2e6b5dd --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/Transaction.java @@ -0,0 +1,226 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.Operation; +import com.radixdlt.api.mesh.generated.models.RelatedTransaction; +import com.radixdlt.api.mesh.generated.models.TransactionIdentifier; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import java.util.ArrayList; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * Transactions contain an array of Operations that are attributable to the same TransactionIdentifier. + */ +@ApiModel(description = "Transactions contain an array of Operations that are attributable to the same TransactionIdentifier. ") +@JsonPropertyOrder({ + Transaction.JSON_PROPERTY_TRANSACTION_IDENTIFIER, + Transaction.JSON_PROPERTY_OPERATIONS, + Transaction.JSON_PROPERTY_RELATED_TRANSACTIONS, + Transaction.JSON_PROPERTY_METADATA +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class Transaction { + public static final String JSON_PROPERTY_TRANSACTION_IDENTIFIER = "transaction_identifier"; + private TransactionIdentifier transactionIdentifier; + + public static final String JSON_PROPERTY_OPERATIONS = "operations"; + private List operations = new ArrayList<>(); + + public static final String JSON_PROPERTY_RELATED_TRANSACTIONS = "related_transactions"; + private List relatedTransactions = null; + + public static final String JSON_PROPERTY_METADATA = "metadata"; + private Object metadata; + + public Transaction() { + } + + public Transaction transactionIdentifier(TransactionIdentifier transactionIdentifier) { + this.transactionIdentifier = transactionIdentifier; + return this; + } + + /** + * Get transactionIdentifier + * @return transactionIdentifier + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_TRANSACTION_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public TransactionIdentifier getTransactionIdentifier() { + return transactionIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_TRANSACTION_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setTransactionIdentifier(TransactionIdentifier transactionIdentifier) { + this.transactionIdentifier = transactionIdentifier; + } + + + public Transaction operations(List operations) { + this.operations = operations; + return this; + } + + public Transaction addOperationsItem(Operation operationsItem) { + this.operations.add(operationsItem); + return this; + } + + /** + * Get operations + * @return operations + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_OPERATIONS) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public List getOperations() { + return operations; + } + + + @JsonProperty(JSON_PROPERTY_OPERATIONS) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setOperations(List operations) { + this.operations = operations; + } + + + public Transaction relatedTransactions(List relatedTransactions) { + this.relatedTransactions = relatedTransactions; + return this; + } + + public Transaction addRelatedTransactionsItem(RelatedTransaction relatedTransactionsItem) { + if (this.relatedTransactions == null) { + this.relatedTransactions = new ArrayList<>(); + } + this.relatedTransactions.add(relatedTransactionsItem); + return this; + } + + /** + * Get relatedTransactions + * @return relatedTransactions + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_RELATED_TRANSACTIONS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public List getRelatedTransactions() { + return relatedTransactions; + } + + + @JsonProperty(JSON_PROPERTY_RELATED_TRANSACTIONS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setRelatedTransactions(List relatedTransactions) { + this.relatedTransactions = relatedTransactions; + } + + + public Transaction metadata(Object metadata) { + this.metadata = metadata; + return this; + } + + /** + * Transactions that are related to other transactions (like a cross-shard transaction) should include the tranaction_identifier of these transactions in the metadata. + * @return metadata + **/ + @javax.annotation.Nullable + @ApiModelProperty(example = "{size=12378, lockTime=1582272577}", value = "Transactions that are related to other transactions (like a cross-shard transaction) should include the tranaction_identifier of these transactions in the metadata. ") + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Object getMetadata() { + return metadata; + } + + + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setMetadata(Object metadata) { + this.metadata = metadata; + } + + + /** + * Return true if this Transaction object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Transaction transaction = (Transaction) o; + return Objects.equals(this.transactionIdentifier, transaction.transactionIdentifier) && + Objects.equals(this.operations, transaction.operations) && + Objects.equals(this.relatedTransactions, transaction.relatedTransactions) && + Objects.equals(this.metadata, transaction.metadata); + } + + @Override + public int hashCode() { + return Objects.hash(transactionIdentifier, operations, relatedTransactions, metadata); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Transaction {\n"); + sb.append(" transactionIdentifier: ").append(toIndentedString(transactionIdentifier)).append("\n"); + sb.append(" operations: ").append(toIndentedString(operations)).append("\n"); + sb.append(" relatedTransactions: ").append(toIndentedString(relatedTransactions)).append("\n"); + sb.append(" metadata: ").append(toIndentedString(metadata)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/TransactionIdentifier.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/TransactionIdentifier.java new file mode 100644 index 0000000000..691bc152fa --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/TransactionIdentifier.java @@ -0,0 +1,112 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * The transaction_identifier uniquely identifies a transaction in a particular network and block or in the mempool. + */ +@ApiModel(description = "The transaction_identifier uniquely identifies a transaction in a particular network and block or in the mempool. ") +@JsonPropertyOrder({ + TransactionIdentifier.JSON_PROPERTY_HASH +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class TransactionIdentifier { + public static final String JSON_PROPERTY_HASH = "hash"; + private String hash; + + public TransactionIdentifier() { + } + + public TransactionIdentifier hash(String hash) { + this.hash = hash; + return this; + } + + /** + * Any transactions that are attributable only to a block (ex: a block event) should use the hash of the block as the identifier. This should be normalized according to the case specified in the transaction_hash_case in network options. + * @return hash + **/ + @javax.annotation.Nonnull + @ApiModelProperty(example = "0x2f23fd8cca835af21f3ac375bac601f97ead75f2e79143bdf71fe2c4be043e8f", required = true, value = "Any transactions that are attributable only to a block (ex: a block event) should use the hash of the block as the identifier. This should be normalized according to the case specified in the transaction_hash_case in network options. ") + @JsonProperty(JSON_PROPERTY_HASH) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getHash() { + return hash; + } + + + @JsonProperty(JSON_PROPERTY_HASH) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setHash(String hash) { + this.hash = hash; + } + + + /** + * Return true if this TransactionIdentifier object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + TransactionIdentifier transactionIdentifier = (TransactionIdentifier) o; + return Objects.equals(this.hash, transactionIdentifier.hash); + } + + @Override + public int hashCode() { + return Objects.hash(hash); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class TransactionIdentifier {\n"); + sb.append(" hash: ").append(toIndentedString(hash)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/TransactionIdentifierResponse.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/TransactionIdentifierResponse.java new file mode 100644 index 0000000000..29fb635d2e --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/TransactionIdentifierResponse.java @@ -0,0 +1,145 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.radixdlt.api.mesh.generated.models.TransactionIdentifier; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * TransactionIdentifierResponse contains the transaction_identifier of a transaction that was submitted to either `/construction/hash` or `/construction/submit`. + */ +@ApiModel(description = "TransactionIdentifierResponse contains the transaction_identifier of a transaction that was submitted to either `/construction/hash` or `/construction/submit`. ") +@JsonPropertyOrder({ + TransactionIdentifierResponse.JSON_PROPERTY_TRANSACTION_IDENTIFIER, + TransactionIdentifierResponse.JSON_PROPERTY_METADATA +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class TransactionIdentifierResponse { + public static final String JSON_PROPERTY_TRANSACTION_IDENTIFIER = "transaction_identifier"; + private TransactionIdentifier transactionIdentifier; + + public static final String JSON_PROPERTY_METADATA = "metadata"; + private Object metadata; + + public TransactionIdentifierResponse() { + } + + public TransactionIdentifierResponse transactionIdentifier(TransactionIdentifier transactionIdentifier) { + this.transactionIdentifier = transactionIdentifier; + return this; + } + + /** + * Get transactionIdentifier + * @return transactionIdentifier + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + @JsonProperty(JSON_PROPERTY_TRANSACTION_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public TransactionIdentifier getTransactionIdentifier() { + return transactionIdentifier; + } + + + @JsonProperty(JSON_PROPERTY_TRANSACTION_IDENTIFIER) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setTransactionIdentifier(TransactionIdentifier transactionIdentifier) { + this.transactionIdentifier = transactionIdentifier; + } + + + public TransactionIdentifierResponse metadata(Object metadata) { + this.metadata = metadata; + return this; + } + + /** + * Get metadata + * @return metadata + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "") + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Object getMetadata() { + return metadata; + } + + + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setMetadata(Object metadata) { + this.metadata = metadata; + } + + + /** + * Return true if this TransactionIdentifierResponse object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + TransactionIdentifierResponse transactionIdentifierResponse = (TransactionIdentifierResponse) o; + return Objects.equals(this.transactionIdentifier, transactionIdentifierResponse.transactionIdentifier) && + Objects.equals(this.metadata, transactionIdentifierResponse.metadata); + } + + @Override + public int hashCode() { + return Objects.hash(transactionIdentifier, metadata); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class TransactionIdentifierResponse {\n"); + sb.append(" transactionIdentifier: ").append(toIndentedString(transactionIdentifier)).append("\n"); + sb.append(" metadata: ").append(toIndentedString(metadata)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/Version.java b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/Version.java new file mode 100644 index 0000000000..50bdfe7a47 --- /dev/null +++ b/core/src/test-core/java/com/radixdlt/api/mesh/generated/models/Version.java @@ -0,0 +1,208 @@ +/* + * Rosetta + * Build Once. Integrate Your Blockchain Everywhere. + * + * The version of the OpenAPI document: 1.4.13 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.radixdlt.api.mesh.generated.models; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * The Version object is utilized to inform the client of the versions of different components of the Rosetta implementation. + */ +@ApiModel(description = "The Version object is utilized to inform the client of the versions of different components of the Rosetta implementation. ") +@JsonPropertyOrder({ + Version.JSON_PROPERTY_ROSETTA_VERSION, + Version.JSON_PROPERTY_NODE_VERSION, + Version.JSON_PROPERTY_MIDDLEWARE_VERSION, + Version.JSON_PROPERTY_METADATA +}) +@javax.annotation.processing.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class Version { + public static final String JSON_PROPERTY_ROSETTA_VERSION = "rosetta_version"; + private String rosettaVersion; + + public static final String JSON_PROPERTY_NODE_VERSION = "node_version"; + private String nodeVersion; + + public static final String JSON_PROPERTY_MIDDLEWARE_VERSION = "middleware_version"; + private String middlewareVersion; + + public static final String JSON_PROPERTY_METADATA = "metadata"; + private Object metadata; + + public Version() { + } + + public Version rosettaVersion(String rosettaVersion) { + this.rosettaVersion = rosettaVersion; + return this; + } + + /** + * The rosetta_version is the version of the Rosetta interface the implementation adheres to. This can be useful for clients looking to reliably parse responses. + * @return rosettaVersion + **/ + @javax.annotation.Nonnull + @ApiModelProperty(example = "1.2.5", required = true, value = "The rosetta_version is the version of the Rosetta interface the implementation adheres to. This can be useful for clients looking to reliably parse responses. ") + @JsonProperty(JSON_PROPERTY_ROSETTA_VERSION) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getRosettaVersion() { + return rosettaVersion; + } + + + @JsonProperty(JSON_PROPERTY_ROSETTA_VERSION) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setRosettaVersion(String rosettaVersion) { + this.rosettaVersion = rosettaVersion; + } + + + public Version nodeVersion(String nodeVersion) { + this.nodeVersion = nodeVersion; + return this; + } + + /** + * The node_version is the canonical version of the node runtime. This can help clients manage deployments. + * @return nodeVersion + **/ + @javax.annotation.Nonnull + @ApiModelProperty(example = "1.0.2", required = true, value = "The node_version is the canonical version of the node runtime. This can help clients manage deployments. ") + @JsonProperty(JSON_PROPERTY_NODE_VERSION) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getNodeVersion() { + return nodeVersion; + } + + + @JsonProperty(JSON_PROPERTY_NODE_VERSION) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setNodeVersion(String nodeVersion) { + this.nodeVersion = nodeVersion; + } + + + public Version middlewareVersion(String middlewareVersion) { + this.middlewareVersion = middlewareVersion; + return this; + } + + /** + * When a middleware server is used to adhere to the Rosetta interface, it should return its version here. This can help clients manage deployments. + * @return middlewareVersion + **/ + @javax.annotation.Nullable + @ApiModelProperty(example = "0.2.7", value = "When a middleware server is used to adhere to the Rosetta interface, it should return its version here. This can help clients manage deployments. ") + @JsonProperty(JSON_PROPERTY_MIDDLEWARE_VERSION) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getMiddlewareVersion() { + return middlewareVersion; + } + + + @JsonProperty(JSON_PROPERTY_MIDDLEWARE_VERSION) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setMiddlewareVersion(String middlewareVersion) { + this.middlewareVersion = middlewareVersion; + } + + + public Version metadata(Object metadata) { + this.metadata = metadata; + return this; + } + + /** + * Any other information that may be useful about versioning of dependent services should be returned here. + * @return metadata + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "Any other information that may be useful about versioning of dependent services should be returned here. ") + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Object getMetadata() { + return metadata; + } + + + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setMetadata(Object metadata) { + this.metadata = metadata; + } + + + /** + * Return true if this Version object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Version version = (Version) o; + return Objects.equals(this.rosettaVersion, version.rosettaVersion) && + Objects.equals(this.nodeVersion, version.nodeVersion) && + Objects.equals(this.middlewareVersion, version.middlewareVersion) && + Objects.equals(this.metadata, version.metadata); + } + + @Override + public int hashCode() { + return Objects.hash(rosettaVersion, nodeVersion, middlewareVersion, metadata); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Version {\n"); + sb.append(" rosettaVersion: ").append(toIndentedString(rosettaVersion)).append("\n"); + sb.append(" nodeVersion: ").append(toIndentedString(nodeVersion)).append("\n"); + sb.append(" middlewareVersion: ").append(toIndentedString(middlewareVersion)).append("\n"); + sb.append(" metadata: ").append(toIndentedString(metadata)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/core/src/test/java/com/radixdlt/api/DeterministicMeshApiTestBase.java b/core/src/test/java/com/radixdlt/api/DeterministicMeshApiTestBase.java new file mode 100644 index 0000000000..d4ede19ffb --- /dev/null +++ b/core/src/test/java/com/radixdlt/api/DeterministicMeshApiTestBase.java @@ -0,0 +1,159 @@ +/* Copyright 2021 Radix Publishing Ltd incorporated in Jersey (Channel Islands). + * + * Licensed under the Radix License, Version 1.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at: + * + * radixfoundation.org/licenses/LICENSE-v1 + * + * The Licensor hereby grants permission for the Canonical version of the Work to be + * published, distributed and used under or by reference to the Licensor’s trademark + * Radix ® and use of any unregistered trade names, logos or get-up. + * + * The Licensor provides the Work (and each Contributor provides its Contributions) on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, + * including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, + * MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. + * + * Whilst the Work is capable of being deployed, used and adopted (instantiated) to create + * a distributed ledger it is your responsibility to test and validate the code, together + * with all logic and performance of that code under all foreseeable scenarios. + * + * The Licensor does not make or purport to make and hereby excludes liability for all + * and any representation, warranty or undertaking in any form whatsoever, whether express + * or implied, to any entity or person, including any representation, warranty or + * undertaking, as to the functionality security use, value or other characteristics of + * any distributed ledger nor in respect the functioning or value of any tokens which may + * be created stored or transferred using the Work. The Licensor does not warrant that the + * Work or any use of the Work complies with any law or regulation in any territory where + * it may be implemented or used or that it will be appropriate for any specific purpose. + * + * Neither the licensor nor any current or former employees, officers, directors, partners, + * trustees, representatives, agents, advisors, contractors, or volunteers of the Licensor + * shall be liable for any direct or indirect, special, incidental, consequential or other + * losses of any kind, in tort, contract or otherwise (including but not limited to loss + * of revenue, income or profits, or loss of use or data, or loss of reputation, or loss + * of any economic or other opportunity of whatsoever nature or howsoever arising), arising + * out of or in connection with (without limitation of any use, misuse, of any ledger system + * or use made or its functionality or any performance or operation of any code or protocol + * caused by bugs or programming or logic errors or otherwise); + * + * A. any offer, purchase, holding, use, sale, exchange or transmission of any + * cryptographic keys, tokens or assets created, exchanged, stored or arising from any + * interaction with the Work; + * + * B. any failure in a transmission or loss of any token or assets keys or other digital + * artefacts due to errors in transmission; + * + * C. bugs, hacks, logic errors or faults in the Work or any communication; + * + * D. system software or apparatus including but not limited to losses caused by errors + * in holding or transmitting tokens by any third-party; + * + * E. breaches or failure of security including hacker attacks, loss or disclosure of + * password, loss of private key, unauthorised use or misuse of such passwords or keys; + * + * F. any losses including loss of anticipated savings or other benefits resulting from + * use of the Work or any changes to the Work (however implemented). + * + * You are solely responsible for; testing, validating and evaluation of all operation + * logic, functionality, security and appropriateness of using the Work for any commercial + * or non-commercial purpose and for any reproduction or redistribution by You of the + * Work. You assume all risks associated with Your use of the Work and the exercise of + * permissions under this License. + */ + +package com.radixdlt.api; + +import static com.radixdlt.environment.deterministic.network.MessageSelector.firstSelector; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.radixdlt.addressing.Addressing; +import com.radixdlt.api.core.generated.api.TransactionApi; +import com.radixdlt.api.mesh.generated.api.MempoolApi; +import com.radixdlt.api.mesh.generated.models.NetworkIdentifier; +import com.radixdlt.genesis.GenesisBuilder; +import com.radixdlt.genesis.GenesisConsensusManagerConfig; +import com.radixdlt.harness.deterministic.DeterministicTest; +import com.radixdlt.harness.deterministic.PhysicalNodeConfig; +import com.radixdlt.modules.FunctionalRadixNodeModule; +import com.radixdlt.modules.FunctionalRadixNodeModule.NodeStorageConfig; +import com.radixdlt.modules.StateComputerConfig; +import com.radixdlt.networks.Network; +import com.radixdlt.rev2.Decimal; +import com.radixdlt.rev2.NetworkDefinition; +import com.radixdlt.sync.SyncRelayConfig; +import org.assertj.core.api.ThrowableAssert; +import org.junit.Rule; +import org.junit.rules.TemporaryFolder; + +public abstract class DeterministicMeshApiTestBase { + + @Rule public TemporaryFolder folder = new TemporaryFolder(); + public static Network network = Network.INTEGRATIONTESTNET; + public static NetworkDefinition networkDefinition = NetworkDefinition.from(network); + public static String networkLogicalName = networkDefinition.logical_name(); + public static Addressing addressing = Addressing.ofNetwork(NetworkDefinition.from(network)); + + /** For now, we use CoreAPI for e.g. submitting transactions */ + private final CoreApiHelper coreApiHelper; + + private final MeshApiHelper meshApiHelper; + + protected DeterministicMeshApiTestBase() { + this.coreApiHelper = new CoreApiHelper(network); + this.meshApiHelper = new MeshApiHelper(network); + } + + protected StateComputerConfig.REv2StateComputerConfig defaultConfig() { + return StateComputerConfig.rev2() + .withGenesis( + GenesisBuilder.createTestGenesisWithNumValidators( + 1, + Decimal.ONE, + GenesisConsensusManagerConfig.Builder.testDefaults() + .epochExactRoundCount(1000000))); + } + + protected DeterministicTest buildRunningServerTest(StateComputerConfig stateComputerConfig) { + var test = + DeterministicTest.builder() + .addPhysicalNodes(PhysicalNodeConfig.createBatch(1, true)) + .messageSelector(firstSelector()) + .addMonitors() + .addModule(coreApiHelper.module()) + .addModule(meshApiHelper.module()) + .functionalNodeModule( + new FunctionalRadixNodeModule( + NodeStorageConfig.tempFolder(folder), + true, + FunctionalRadixNodeModule.SafetyRecoveryConfig.MOCKED, + FunctionalRadixNodeModule.ConsensusConfig.of(1000), + FunctionalRadixNodeModule.LedgerConfig.stateComputerWithSyncRelay( + stateComputerConfig, SyncRelayConfig.of(200, 10, 2000)))); + try { + test.startAllNodes(); + } catch (Exception ex) { + test.close(); + throw ex; + } + return test; + } + + public Response assertErrorResponseOfType( + ThrowableAssert.ThrowingCallable apiCall, Class responseClass) + throws JsonProcessingException { + return coreApiHelper.assertErrorResponseOfType(apiCall, responseClass); + } + + protected TransactionApi getCoreTransactionApi() { + return coreApiHelper.transactionApi(); + } + + public MempoolApi getMempoolApi() { + return meshApiHelper.mempoolApi(); + } + + public NetworkIdentifier getNetworkIdentifier() { + return meshApiHelper.networkIdentifier(); + } +} diff --git a/core/src/test/java/com/radixdlt/api/mesh_api/MeshApiMempoolEndpointsTest.java b/core/src/test/java/com/radixdlt/api/mesh_api/MeshApiMempoolEndpointsTest.java new file mode 100644 index 0000000000..f2cbebe438 --- /dev/null +++ b/core/src/test/java/com/radixdlt/api/mesh_api/MeshApiMempoolEndpointsTest.java @@ -0,0 +1,152 @@ +/* Copyright 2021 Radix Publishing Ltd incorporated in Jersey (Channel Islands). + * + * Licensed under the Radix License, Version 1.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at: + * + * radixfoundation.org/licenses/LICENSE-v1 + * + * The Licensor hereby grants permission for the Canonical version of the Work to be + * published, distributed and used under or by reference to the Licensor’s trademark + * Radix ® and use of any unregistered trade names, logos or get-up. + * + * The Licensor provides the Work (and each Contributor provides its Contributions) on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, + * including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, + * MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. + * + * Whilst the Work is capable of being deployed, used and adopted (instantiated) to create + * a distributed ledger it is your responsibility to test and validate the code, together + * with all logic and performance of that code under all foreseeable scenarios. + * + * The Licensor does not make or purport to make and hereby excludes liability for all + * and any representation, warranty or undertaking in any form whatsoever, whether express + * or implied, to any entity or person, including any representation, warranty or + * undertaking, as to the functionality security use, value or other characteristics of + * any distributed ledger nor in respect the functioning or value of any tokens which may + * be created stored or transferred using the Work. The Licensor does not warrant that the + * Work or any use of the Work complies with any law or regulation in any territory where + * it may be implemented or used or that it will be appropriate for any specific purpose. + * + * Neither the licensor nor any current or former employees, officers, directors, partners, + * trustees, representatives, agents, advisors, contractors, or volunteers of the Licensor + * shall be liable for any direct or indirect, special, incidental, consequential or other + * losses of any kind, in tort, contract or otherwise (including but not limited to loss + * of revenue, income or profits, or loss of use or data, or loss of reputation, or loss + * of any economic or other opportunity of whatsoever nature or howsoever arising), arising + * out of or in connection with (without limitation of any use, misuse, of any ledger system + * or use made or its functionality or any performance or operation of any code or protocol + * caused by bugs or programming or logic errors or otherwise); + * + * A. any offer, purchase, holding, use, sale, exchange or transmission of any + * cryptographic keys, tokens or assets created, exchanged, stored or arising from any + * interaction with the Work; + * + * B. any failure in a transmission or loss of any token or assets keys or other digital + * artefacts due to errors in transmission; + * + * C. bugs, hacks, logic errors or faults in the Work or any communication; + * + * D. system software or apparatus including but not limited to losses caused by errors + * in holding or transmitting tokens by any third-party; + * + * E. breaches or failure of security including hacker attacks, loss or disclosure of + * password, loss of private key, unauthorised use or misuse of such passwords or keys; + * + * F. any losses including loss of anticipated savings or other benefits resulting from + * use of the Work or any changes to the Work (however implemented). + * + * You are solely responsible for; testing, validating and evaluation of all operation + * logic, functionality, security and appropriateness of using the Work for any commercial + * or non-commercial purpose and for any reproduction or redistribution by You of the + * Work. You assume all risks associated with Your use of the Work and the exercise of + * permissions under this License. + */ + +package com.radixdlt.api.mesh_api; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.radixdlt.api.DeterministicMeshApiTestBase; +import com.radixdlt.api.core.generated.models.TransactionSubmitRequest; +import com.radixdlt.api.mesh.generated.models.*; +import com.radixdlt.rev2.TransactionBuilder; +import java.util.HashSet; +import org.junit.Test; + +public class MeshApiMempoolEndpointsTest extends DeterministicMeshApiTestBase { + + @Test + public void test_mempool_endpoint() throws Exception { + try (var test = buildRunningServerTest(defaultConfig())) { + test.suppressUnusedWarning(); + + // Arrange + var expected_transaction_identifiers = new HashSet(); + + for (int i = 0; i < 2; i++) { + var transaction = TransactionBuilder.forTests().prepare(); + + expected_transaction_identifiers.add( + new TransactionIdentifier() + .hash(addressing.encode(transaction.transactionIntentHash()))); + + // Submit transaction to the CoreAPI + var response = + getCoreTransactionApi() + .transactionSubmitPost( + new TransactionSubmitRequest() + .network(networkLogicalName) + .notarizedTransactionHex(transaction.hexPayloadBytes())); + + assertThat(response.getDuplicate()).isFalse(); + } + + // Act + // Get mempool from the MeshAPI + var mempool_response = + new HashSet<>( + getMempoolApi() + .mempool(new NetworkRequest().networkIdentifier(getNetworkIdentifier())) + .getTransactionIdentifiers()); + + // Assert that both transactions are in the mempool list + assertThat(mempool_response.equals(expected_transaction_identifiers)); + } + } + + @Test + public void test_mempool_transaction_endpoint() throws Exception { + try (var test = buildRunningServerTest(defaultConfig())) { + test.suppressUnusedWarning(); + + // Arrange + var transaction = TransactionBuilder.forTests().prepare(); + var transaction_identifier = + new TransactionIdentifier().hash(addressing.encode(transaction.transactionIntentHash())); + + // Submit transaction to the CoreAPI + var response = + getCoreTransactionApi() + .transactionSubmitPost( + new TransactionSubmitRequest() + .network(networkLogicalName) + .notarizedTransactionHex(transaction.hexPayloadBytes())); + + assertThat(response.getDuplicate()).isFalse(); + + // Act + // Get mempool transaction from the MeshAPI + var mempool_transaction_response = + getMempoolApi() + .mempoolTransaction( + new MempoolTransactionRequest() + .networkIdentifier(getNetworkIdentifier()) + .transactionIdentifier(transaction_identifier)) + .getTransaction(); + + // Assert that transaction1 is in the mempool transaction list + assertThat(mempool_transaction_response) + .isEqualTo(new Transaction().transactionIdentifier(transaction_identifier)); + } + } +} diff --git a/docker/config/default.config.envsubst b/docker/config/default.config.envsubst index 6764636567..62c6c84ede 100644 --- a/docker/config/default.config.envsubst +++ b/docker/config/default.config.envsubst @@ -42,6 +42,10 @@ api.core.flags.enable_unbounded_endpoints=${RADIXDLT_CORE_API_FLAGS_ENABLE_UNBOU api.engine_state.port=$RADIXDLT_ENGINE_STATE_API_PORT api.engine_state.bind_address=$RADIXDLT_ENGINE_STATE_API_BIND_ADDRESS +api.mesh.enabled=$RADIXDLT_MESH_API_ENABLED +api.mesh.port=$RADIXDLT_MESH_API_PORT +api.mesh.bind_address=$RADIXDLT_MESH_API_BIND_ADDRESS + api.system.port=$RADIXDLT_SYSTEM_API_PORT api.system.bind_address=$RADIXDLT_SYSTEM_API_BIND_ADDRESS api.system.enable_db_checkpoint=${RADIXDLT_SYSTEM_API_ENABLE_DB_CHECKPOINT} diff --git a/docker/core.yml b/docker/core.yml index bf70571beb..672bfd189b 100644 --- a/docker/core.yml +++ b/docker/core.yml @@ -12,6 +12,7 @@ services: RADIXDLT_SYSTEM_API_PORT: 3334 RADIXDLT_PROMETHEUS_API_PORT: 3335 RADIXDLT_ENGINE_STATE_API_PORT: 3336 + RADIXDLT_MESH_API_PORT: 3337 RADIXDLT_GENESIS_DATA: ${RADIXDLT_GENESIS_DATA} JAVA_OPTS: -server -Xmx512m -Xmx512m -XX:+HeapDumpOnOutOfMemoryError -XX:+AlwaysPreTouch -Dguice_bytecode_gen_option=DISABLED -Djavax.net.ssl.trustStore=/etc/ssl/certs/java/cacerts -Djavax.net.ssl.trustStoreType=jks -Djava.security.egd=file:/dev/urandom -Dcom.sun.management.jmxremote.port=9011 -Dcom.sun.management.jmxremote.rmi.port=9011 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=core -agentlib:jdwp=transport=dt_socket,address=*:50505,suspend=n,server=y --enable-preview # Adjust the following envvar for trace collection