├── .changes ├── alias-nft-unlock.md ├── aliasIdToBech32.md ├── aliasoutputbuilder.md ├── basic-auth.md ├── bech32-address.md ├── build-fix.md ├── burn-interface.md ├── computeAlias-NftId.md ├── computeFoundryId.md ├── config.json ├── enum-serialization-attributes.md ├── fix-build-script.md ├── fix-burn-mismatch.md ├── fix-rebuild-script.md ├── get-included-block-metadata.md ├── hashTransactionEssence.md ├── input-signing-data.md ├── install.md ├── ledger-nano-prompt.md ├── mqtt.md ├── networkinfo.md ├── nftIdToBech32.md ├── node-sync-health.md ├── outputIds.md ├── pow.md ├── pre.json ├── prebuilds.md ├── protocol-parameters.md ├── readme.md ├── signatureUnlock.md ├── switch-to-napi-6.md └── unhealthy-nodes.md ├── .github ├── CODE_OF_CONDUCT.md ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ ├── config.yml │ ├── create-task.yml │ └── feature_request.md ├── actions │ ├── private-tangle │ │ ├── setup │ │ │ └── action.yml │ │ └── tear-down │ │ │ └── action.yml │ ├── setup-clang │ │ └── action.yml │ └── setup-rust │ │ └── action.yml ├── pull_request_template.md └── workflows │ ├── bindings-java-release.yml │ ├── bindings-java.yml │ ├── bindings-nodejs.yml │ ├── bindings-python-release.yml │ ├── bindings-python.yml │ ├── bindings-wasm-release.yml │ ├── bindings-wasm.yml │ ├── core.yml │ ├── covector.yml │ ├── coverage.yml │ ├── private-tangle-tests.yml │ └── wasm-compatibility.yml ├── .gitignore ├── .license_template ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── client ├── .env.example ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE ├── bindings │ ├── java │ │ ├── .gitignore │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── build.gradle │ │ ├── examples │ │ │ ├── build.gradle │ │ │ └── src │ │ │ │ ├── BuildAliasOutput.java │ │ │ │ ├── BuildBasicOutput.java │ │ │ │ ├── BuildFoundryOutput.java │ │ │ │ ├── BuildNftOutput.java │ │ │ │ ├── CreateBlock.java │ │ │ │ ├── ExampleUtils.java │ │ │ │ ├── GenerateAddresses.java │ │ │ │ ├── GenerateMnemonic.java │ │ │ │ ├── GetAddressBalance.java │ │ │ │ ├── GetBlock.java │ │ │ │ ├── GetBlockMetadata.java │ │ │ │ ├── GetBlockRaw.java │ │ │ │ ├── GetHealth.java │ │ │ │ ├── GetInfo.java │ │ │ │ ├── GetMilestoneById.java │ │ │ │ ├── GetMilestoneByIdRaw.java │ │ │ │ ├── GetMilestoneByIndex.java │ │ │ │ ├── GetMilestoneByIndexRaw.java │ │ │ │ ├── GetOutputs.java │ │ │ │ ├── GetReceipts.java │ │ │ │ ├── GetReceiptsMigratedAt.java │ │ │ │ ├── GetTips.java │ │ │ │ ├── GetTreasury.java │ │ │ │ ├── GetUtxoChangesById.java │ │ │ │ ├── GetUtxoChangesByIndex.java │ │ │ │ ├── PostBlock.java │ │ │ │ ├── PostBlockRaw.java │ │ │ │ ├── PrepareAndSignTransaction.java │ │ │ │ └── WrongSeedConversionSecretManager.java │ │ ├── gradle │ │ │ └── wrapper │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ └── gradle-wrapper.properties │ │ ├── gradlew │ │ ├── gradlew.bat │ │ ├── lib │ │ │ ├── build.gradle │ │ │ ├── native │ │ │ │ ├── Cargo.toml │ │ │ │ └── src │ │ │ │ │ ├── lib.rs │ │ │ │ │ └── main.rs │ │ │ └── src │ │ │ │ ├── main │ │ │ │ └── java │ │ │ │ │ └── org │ │ │ │ │ └── iota │ │ │ │ │ ├── Client.java │ │ │ │ │ ├── apis │ │ │ │ │ ├── ClientCommand.java │ │ │ │ │ ├── HighLevelApi.java │ │ │ │ │ ├── MiscellaneousApi.java │ │ │ │ │ ├── NativeApi.java │ │ │ │ │ ├── NativeUtils.java │ │ │ │ │ ├── NodeCoreApi.java │ │ │ │ │ ├── NodeIndexerApi.java │ │ │ │ │ └── UtilsApi.java │ │ │ │ │ └── types │ │ │ │ │ ├── AbstractObject.java │ │ │ │ │ ├── Block.java │ │ │ │ │ ├── BlockMetadata.java │ │ │ │ │ ├── BlockPayload.java │ │ │ │ │ ├── Burn.java │ │ │ │ │ ├── ClientConfig.java │ │ │ │ │ ├── Feature.java │ │ │ │ │ ├── JsonUtils.java │ │ │ │ │ ├── LedgerNanoStatus.java │ │ │ │ │ ├── MilestonePayload.java │ │ │ │ │ ├── NativeToken.java │ │ │ │ │ ├── Node.java │ │ │ │ │ ├── Output.java │ │ │ │ │ ├── OutputMetadata.java │ │ │ │ │ ├── Peer.java │ │ │ │ │ ├── PreparedTransactionData.java │ │ │ │ │ ├── Receipt.java │ │ │ │ │ ├── TaggedDataPayload.java │ │ │ │ │ ├── TokenScheme.java │ │ │ │ │ ├── TransactionPayload.java │ │ │ │ │ ├── UnlockCondition.java │ │ │ │ │ ├── UtxoInput.java │ │ │ │ │ ├── expections │ │ │ │ │ ├── ClientException.java │ │ │ │ │ ├── InitializeClientException.java │ │ │ │ │ └── NoFundsReceivedFromFaucetException.java │ │ │ │ │ ├── ids │ │ │ │ │ ├── AbstractId.java │ │ │ │ │ ├── AliasId.java │ │ │ │ │ ├── BlockId.java │ │ │ │ │ ├── FoundryId.java │ │ │ │ │ ├── MilestoneId.java │ │ │ │ │ ├── NftId.java │ │ │ │ │ ├── OutputId.java │ │ │ │ │ └── TransactionId.java │ │ │ │ │ ├── output_builder │ │ │ │ │ ├── AliasOutputBuilderParams.java │ │ │ │ │ ├── BasicOutputBuilderParams.java │ │ │ │ │ ├── FoundryOutputBuilderParams.java │ │ │ │ │ └── NftOutputBuilderParams.java │ │ │ │ │ ├── responses │ │ │ │ │ ├── NodeInfoResponse.java │ │ │ │ │ ├── OutputIdsResponse.java │ │ │ │ │ ├── ProtocolParametersResponse.java │ │ │ │ │ ├── TreasuryResponse.java │ │ │ │ │ └── UtxoChangesResponse.java │ │ │ │ │ └── secret │ │ │ │ │ ├── BuildBlockOptions.java │ │ │ │ │ ├── GenerateAddressesOptions.java │ │ │ │ │ ├── LedgerNanoSecretManager.java │ │ │ │ │ ├── MnemonicSecretManager.java │ │ │ │ │ ├── PlaceholderSecretManager.java │ │ │ │ │ ├── Range.java │ │ │ │ │ ├── SecretManager.java │ │ │ │ │ ├── SeedSecretManager.java │ │ │ │ │ ├── StrongholdSecretManager.java │ │ │ │ │ └── WrongSeedConversionSecretManager.java │ │ │ │ └── test │ │ │ │ └── java │ │ │ │ └── org │ │ │ │ └── iota │ │ │ │ ├── AddressDerivation.java │ │ │ │ ├── ApiTest.java │ │ │ │ ├── HighLevelApiTest.java │ │ │ │ ├── IndexerApiTest.java │ │ │ │ └── NodeCoreApiTest.java │ │ └── settings.gradle │ ├── nodejs │ │ ├── .env.example │ │ ├── .eslintignore │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── .npmignore │ │ ├── .prettierrc.js │ │ ├── CHANGELOG.md │ │ ├── Cargo.toml │ │ ├── LICENSE │ │ ├── README.md │ │ ├── binding.gyp │ │ ├── examples │ │ │ ├── 00_get_info.ts │ │ │ ├── 01_mnemonic.ts │ │ │ ├── 02_generate_addresses.ts │ │ │ ├── 03_get_address_outputs.ts │ │ │ ├── 04_get_output.ts │ │ │ ├── 05_get_address_balance.ts │ │ │ ├── 06_simple_block.ts │ │ │ ├── 07_get_block_data.ts │ │ │ ├── 08_data_block.ts │ │ │ ├── 09_transaction.ts │ │ │ ├── 10_mqtt.ts │ │ │ ├── 11_build_output.ts │ │ │ ├── 12_get_raw_block.ts │ │ │ ├── 13_build_alias_output.ts │ │ │ ├── 14_build_foundry_output.ts │ │ │ ├── 15_build_nft_output.ts │ │ │ ├── consolidation.ts │ │ │ ├── ledger_nano.ts │ │ │ ├── offline_signing │ │ │ │ ├── 0_address_generation.ts │ │ │ │ ├── 1_transaction_preparation.ts │ │ │ │ ├── 2_transaction_signing.ts │ │ │ │ ├── 3_send_block.ts │ │ │ │ ├── example_address.json │ │ │ │ ├── example_prepared_transaction.json │ │ │ │ └── example_signed_transaction.json │ │ │ ├── package.json │ │ │ ├── stronghold.ts │ │ │ ├── tsconfig.json │ │ │ └── yarn.lock │ │ ├── jest.config.js │ │ ├── lib │ │ │ ├── Client.ts │ │ │ ├── MessageHandler.ts │ │ │ ├── bindings.ts │ │ │ ├── constants.ts │ │ │ ├── index.ts │ │ │ ├── logger.ts │ │ │ └── utils.ts │ │ ├── package.json │ │ ├── scripts │ │ │ ├── move-artifact.js │ │ │ ├── neon-build.js │ │ │ └── strip.js │ │ ├── src │ │ │ ├── lib.rs │ │ │ └── message_handler.rs │ │ ├── test │ │ │ ├── client │ │ │ │ ├── examples.spec.ts │ │ │ │ ├── infoMethods.spec.ts │ │ │ │ ├── messageMethods.spec.ts │ │ │ │ ├── milestoneMethods.spec.ts │ │ │ │ ├── offlineSigningExamples.spec.ts │ │ │ │ ├── outputBuilders.spec.ts │ │ │ │ ├── utilityMethods.spec.ts │ │ │ │ └── utxoMethods.spec.ts │ │ │ ├── customMatchers.ts │ │ │ └── fixtures │ │ │ │ ├── addressOutputs.json │ │ │ │ ├── addresses.ts │ │ │ │ ├── sigUnlockPreparedTx.json │ │ │ │ └── signedTransaction.json │ │ ├── tsconfig.json │ │ ├── types │ │ │ ├── blockId.ts │ │ │ ├── bridge │ │ │ │ ├── client.ts │ │ │ │ └── index.ts │ │ │ ├── buildBlockOptions.ts │ │ │ ├── burn.ts │ │ │ ├── clientOptions.ts │ │ │ ├── generateAddressesOptions.ts │ │ │ ├── index.ts │ │ │ ├── ledgerNanoStatus.ts │ │ │ ├── loggerConfig.ts │ │ │ ├── network.ts │ │ │ ├── nodeInfo.ts │ │ │ ├── outputBuilderOptions │ │ │ │ ├── aliasOutputOptions.ts │ │ │ │ ├── basicOutputOptions.ts │ │ │ │ ├── foundryOutputOptions.ts │ │ │ │ ├── index.ts │ │ │ │ └── nftOutputOptions.ts │ │ │ ├── outputIdsResponse.ts │ │ │ ├── preparedTransactionData.ts │ │ │ ├── queryParameters.ts │ │ │ ├── range.ts │ │ │ └── secretManager.ts │ │ └── yarn.lock │ ├── python │ │ ├── .gitignore │ │ ├── CHANGELOG.md │ │ ├── Cargo.toml │ │ ├── MANIFEST.in │ │ ├── README.md │ │ ├── examples │ │ │ ├── 00_get_info.py │ │ │ ├── 01_mnemonic.py │ │ │ ├── 02_generate_addresses.py │ │ │ ├── 03_get_address_outputs.py │ │ │ ├── 04_get_output.py │ │ │ ├── 05_get_address_balance.py │ │ │ ├── 06_simple_block.py │ │ │ ├── 07_get_block_data.py │ │ │ ├── 08_data_block.py │ │ │ ├── 09_transaction.py │ │ │ ├── 10_mint_nft.py │ │ │ ├── 11_build_output.py │ │ │ ├── README.md │ │ │ ├── build_alias.py │ │ │ ├── build_foundry.py │ │ │ ├── get_raw_block.py │ │ │ ├── ledger_nano.py │ │ │ ├── logger.py │ │ │ ├── post_raw_block.py │ │ │ └── stronghold.py │ │ ├── iota_client │ │ │ ├── __init__.py │ │ │ ├── _base_api.py │ │ │ ├── _high_level_api.py │ │ │ ├── _node_core_api.py │ │ │ ├── _node_indexer_api.py │ │ │ ├── _utils.py │ │ │ ├── client.py │ │ │ ├── common.py │ │ │ └── secret_manager.py │ │ ├── pydoc-markdown.yml │ │ ├── pyproject.toml │ │ ├── requirements-dev.txt │ │ ├── setup.py │ │ ├── src │ │ │ ├── lib.rs │ │ │ └── types │ │ │ │ ├── error.rs │ │ │ │ ├── handler.rs │ │ │ │ └── mod.rs │ │ ├── tests │ │ │ ├── __pycache__ │ │ │ │ └── test_addresses.cpython-310-pytest-7.1.2.pyc │ │ │ └── test_addresses.py │ │ └── tox.ini │ └── wasm │ │ ├── .cargo │ │ └── config.toml │ │ ├── .eslintignore │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── .prettierrc.js │ │ ├── CHANGELOG.md │ │ ├── Cargo.toml │ │ ├── LICENSE │ │ ├── README.md │ │ ├── build_scripts │ │ ├── copyNodejsDefs.js │ │ ├── lints.js │ │ ├── node.js │ │ ├── utils │ │ │ └── generatePackage.js │ │ └── web.js │ │ ├── jest.config.js │ │ ├── lib │ │ └── bindings.ts │ │ ├── package.json │ │ ├── src │ │ ├── lib.rs │ │ └── message_handler.rs │ │ ├── test │ │ └── utilityMethods.spec.ts │ │ ├── tsconfig.base.json │ │ ├── tsconfig.node.json │ │ ├── tsconfig.web.json │ │ └── yarn.lock ├── examples │ ├── 00_generate_mnemonic.rs │ ├── 01_generate_addresses.rs │ ├── 02_get_address_balance.rs │ ├── 03_simple_block.rs │ ├── 07_mqtt.rs │ ├── block │ │ ├── 00_block_no_payload.rs │ │ ├── 01_block_confirmation_time.rs │ │ ├── 02_block_custom_parents.rs │ │ ├── 03_block_custom_payload.rs │ │ ├── 04_block_tagged_data.rs │ │ ├── custom_inputs.rs │ │ ├── output.rs │ │ └── transaction.rs │ ├── client_config.rs │ ├── custom_remainder_address.rs │ ├── get_funds.rs │ ├── high_level │ │ ├── consolidation.rs │ │ ├── inputs_from_transaction_id.rs │ │ └── search_address.rs │ ├── ledger_nano.rs │ ├── ledger_nano_transaction.rs │ ├── logger.rs │ ├── node_api_core │ │ ├── 00_get_health.rs │ │ ├── 01_get_routes.rs │ │ ├── 02_get_info.rs │ │ ├── 03_get_tips.rs │ │ ├── 04_post_block.rs │ │ ├── 05_post_block_raw.rs │ │ ├── 06_get_block.rs │ │ ├── 07_get_block_raw.rs │ │ ├── 08_get_block_metadata.rs │ │ ├── 09_get_output.rs │ │ ├── 10_get_output_raw.rs │ │ ├── 11_get_output_metadata.rs │ │ ├── 12_get_receipts.rs │ │ ├── 13_get_receipts_migrated_at.rs │ │ ├── 14_get_treasury.rs │ │ ├── 15_get_included_block.rs │ │ ├── 16_get_included_block_raw.rs │ │ ├── 17_get_milestone_by_id.rs │ │ ├── 18_get_milestone_by_id_raw.rs │ │ ├── 19_get_utxo_changes_by_id.rs │ │ ├── 20_get_milestone_by_index.rs │ │ ├── 21_get_milestone_by_index_raw.rs │ │ └── 22_get_utxo_changes_by_index.rs │ ├── node_api_indexer │ │ ├── 00_get_basic_outputs.rs │ │ ├── 01_get_alias_output.rs │ │ ├── 02_get_alias_outputs.rs │ │ ├── 03_get_foundry_output.rs │ │ ├── 04_get_foundry_outputs.rs │ │ ├── 05_get_nft_output.rs │ │ ├── 06_get_nft_outputs.rs │ │ └── 07_get_random_basic_outputs.rs │ ├── offline_signing │ │ ├── 0_address_generation.rs │ │ ├── 1_transaction_preparation.rs │ │ ├── 2_transaction_signing.rs │ │ └── 3_send_block.rs │ ├── output │ │ ├── alias.rs │ │ ├── all.rs │ │ ├── all_automatic_input_selection.rs │ │ ├── basic.rs │ │ ├── build_alias_output.rs │ │ ├── build_basic_output.rs │ │ ├── expiration.rs │ │ ├── foundry.rs │ │ ├── micro_transaction.rs │ │ ├── native_tokens.rs │ │ ├── nft.rs │ │ └── recursive_alias.rs │ ├── participation.rs │ ├── quorum.rs │ ├── send_all.rs │ ├── split_funds.rs │ ├── stronghold.rs │ └── tagged_data_to_utf8.rs ├── src │ ├── api │ │ ├── address.rs │ │ ├── block_builder │ │ │ ├── input_selection │ │ │ │ ├── automatic.rs │ │ │ │ ├── core │ │ │ │ │ ├── burn.rs │ │ │ │ │ ├── error.rs │ │ │ │ │ ├── mod.rs │ │ │ │ │ ├── remainder.rs │ │ │ │ │ ├── requirement │ │ │ │ │ │ ├── alias.rs │ │ │ │ │ │ ├── amount.rs │ │ │ │ │ │ ├── ed25519.rs │ │ │ │ │ │ ├── foundry.rs │ │ │ │ │ │ ├── issuer.rs │ │ │ │ │ │ ├── mod.rs │ │ │ │ │ │ ├── native_tokens.rs │ │ │ │ │ │ ├── nft.rs │ │ │ │ │ │ └── sender.rs │ │ │ │ │ └── transition.rs │ │ │ │ ├── helpers.rs │ │ │ │ ├── manual.rs │ │ │ │ ├── mod.rs │ │ │ │ ├── sender_issuer.rs │ │ │ │ └── utxo_chains.rs │ │ │ ├── mod.rs │ │ │ ├── pow.rs │ │ │ └── transaction.rs │ │ ├── consolidation.rs │ │ ├── high_level.rs │ │ ├── mod.rs │ │ └── types.rs │ ├── builder.rs │ ├── client.rs │ ├── constants.rs │ ├── error.rs │ ├── lib.rs │ ├── message_interface │ │ ├── message.rs │ │ ├── message_handler.rs │ │ ├── mod.rs │ │ └── response.rs │ ├── node_api │ │ ├── core │ │ │ ├── mod.rs │ │ │ └── routes.rs │ │ ├── indexer │ │ │ ├── mod.rs │ │ │ ├── query_parameters.rs │ │ │ └── routes.rs │ │ ├── mod.rs │ │ ├── mqtt │ │ │ ├── error.rs │ │ │ ├── mod.rs │ │ │ └── types.rs │ │ └── participation.rs │ ├── node_manager │ │ ├── builder.rs │ │ ├── http_client.rs │ │ ├── mod.rs │ │ ├── node.rs │ │ └── syncing.rs │ ├── secret │ │ ├── ledger_nano.rs │ │ ├── mnemonic.rs │ │ ├── mod.rs │ │ ├── placeholder.rs │ │ ├── stronghold.rs │ │ └── types.rs │ ├── storage │ │ ├── mod.rs │ │ └── stronghold.rs │ ├── stronghold │ │ ├── common.rs │ │ ├── mod.rs │ │ ├── secret.rs │ │ └── storage.rs │ └── utils.rs └── tests │ ├── addresses.rs │ ├── client_builder.rs │ ├── common │ ├── constants.rs │ └── mod.rs │ ├── error.rs │ ├── fixtures │ └── test_vectors.json │ ├── input_selection │ ├── alias_outputs.rs │ ├── basic_outputs.rs │ ├── burn.rs │ ├── expiration.rs │ ├── foundry_outputs.rs │ ├── mod.rs │ ├── native_tokens.rs │ ├── nft_outputs.rs │ ├── outputs.rs │ ├── storage_deposit_return.rs │ └── timelock.rs │ ├── message_interface.rs │ ├── mnemonic.rs │ ├── mod.rs │ ├── mqtt │ ├── mod.rs │ └── topic.rs │ ├── node_api.rs │ ├── secret_manager.rs │ ├── signing │ ├── alias.rs │ ├── basic.rs │ ├── mod.rs │ └── nft.rs │ └── transactions.rs ├── coverage.sh ├── pow ├── CHANGELOG.md ├── Cargo.toml ├── README.md ├── src │ ├── lib.rs │ ├── miner.rs │ ├── score.rs │ └── wasm_miner.rs └── tests │ ├── miner.rs │ └── score.rs ├── rustfmt.toml └── types ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE ├── README.md ├── fuzz ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── fuzz_targets │ ├── fuzz_address.rs │ ├── fuzz_block.rs │ ├── fuzz_feature.rs │ ├── fuzz_input.rs │ ├── fuzz_output.rs │ ├── fuzz_payload.rs │ ├── fuzz_signature.rs │ ├── fuzz_unlock.rs │ └── fuzz_unlock_condition.rs └── src │ └── fuzz_sorter.rs ├── src ├── api │ ├── core │ │ ├── dto.rs │ │ ├── error.rs │ │ ├── mod.rs │ │ └── response.rs │ ├── mod.rs │ └── plugins │ │ ├── indexer.rs │ │ ├── mod.rs │ │ └── participation │ │ ├── error.rs │ │ ├── mod.rs │ │ ├── responses.rs │ │ └── types.rs ├── block │ ├── address │ │ ├── alias.rs │ │ ├── ed25519.rs │ │ ├── mod.rs │ │ └── nft.rs │ ├── block.rs │ ├── block_id.rs │ ├── dto.rs │ ├── error.rs │ ├── helper.rs │ ├── input │ │ ├── mod.rs │ │ ├── treasury.rs │ │ └── utxo.rs │ ├── macro.rs │ ├── mod.rs │ ├── output │ │ ├── alias.rs │ │ ├── alias_id.rs │ │ ├── basic.rs │ │ ├── chain_id.rs │ │ ├── feature │ │ │ ├── issuer.rs │ │ │ ├── metadata.rs │ │ │ ├── mod.rs │ │ │ ├── sender.rs │ │ │ └── tag.rs │ │ ├── foundry.rs │ │ ├── foundry_id.rs │ │ ├── inputs_commitment.rs │ │ ├── metadata.rs │ │ ├── mod.rs │ │ ├── native_token.rs │ │ ├── nft.rs │ │ ├── nft_id.rs │ │ ├── output_id.rs │ │ ├── rent.rs │ │ ├── state_transition.rs │ │ ├── token_id.rs │ │ ├── token_scheme │ │ │ ├── mod.rs │ │ │ └── simple.rs │ │ ├── treasury.rs │ │ └── unlock_condition │ │ │ ├── address.rs │ │ │ ├── expiration.rs │ │ │ ├── governor_address.rs │ │ │ ├── immutable_alias_address.rs │ │ │ ├── mod.rs │ │ │ ├── state_controller_address.rs │ │ │ ├── storage_deposit_return.rs │ │ │ └── timelock.rs │ ├── parent.rs │ ├── payload │ │ ├── milestone │ │ │ ├── essence.rs │ │ │ ├── index.rs │ │ │ ├── merkle.rs │ │ │ ├── milestone_id.rs │ │ │ ├── mod.rs │ │ │ └── option │ │ │ │ ├── mod.rs │ │ │ │ ├── parameters.rs │ │ │ │ └── receipt │ │ │ │ ├── migrated_funds_entry.rs │ │ │ │ ├── mod.rs │ │ │ │ └── tail_transaction_hash.rs │ │ ├── mod.rs │ │ ├── tagged_data │ │ │ └── mod.rs │ │ ├── transaction │ │ │ ├── essence │ │ │ │ ├── mod.rs │ │ │ │ └── regular.rs │ │ │ ├── mod.rs │ │ │ └── transaction_id.rs │ │ └── treasury_transaction │ │ │ └── mod.rs │ ├── protocol.rs │ ├── rand │ │ ├── address.rs │ │ ├── block.rs │ │ ├── bool.rs │ │ ├── bytes.rs │ │ ├── input.rs │ │ ├── milestone.rs │ │ ├── milestone_option.rs │ │ ├── mod.rs │ │ ├── number.rs │ │ ├── option.rs │ │ ├── output │ │ │ ├── feature.rs │ │ │ ├── mod.rs │ │ │ └── unlock_condition.rs │ │ ├── parents.rs │ │ ├── payload.rs │ │ ├── receipt.rs │ │ ├── string.rs │ │ └── transaction.rs │ ├── semantic.rs │ ├── signature │ │ ├── ed25519.rs │ │ └── mod.rs │ └── unlock │ │ ├── alias.rs │ │ ├── mod.rs │ │ ├── nft.rs │ │ ├── reference.rs │ │ └── signature.rs └── lib.rs └── tests ├── address ├── alias.rs ├── ed25519.rs ├── mod.rs └── nft.rs ├── api ├── mod.rs └── participation.rs ├── block.rs ├── block_id.rs ├── ed25519_signature.rs ├── foundry_id.rs ├── input ├── mod.rs ├── treasury.rs └── utxo.rs ├── migrated_funds_entry.rs ├── milestone_id.rs ├── milestone_index.rs ├── milestone_payload.rs ├── milestone_payload_essence.rs ├── mod.rs ├── output_id.rs ├── parents.rs ├── payload.rs ├── receipt_milestone_option.rs ├── reference_unlock.rs ├── rent.rs ├── signature_unlock.rs ├── tagged_data_payload.rs ├── tail_transaction_hash.rs ├── transaction_essence.rs ├── transaction_id.rs ├── transaction_payload.rs ├── transaction_regular_essence.rs ├── treasury_output.rs ├── treasury_transaction_payload.rs └── unlocks.rs /.changes/alias-nft-unlock.md: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | "nodejs-binding": patch 4 | --- 5 | 6 | Add alias and nfts output in `try_select_input` to the inputs, when required for an unlock condition of an input. 7 | -------------------------------------------------------------------------------- /.changes/aliasIdToBech32.md: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | "nodejs-binding": patch 4 | --- 5 | 6 | Add `aliasIdToBech32()`. 7 | -------------------------------------------------------------------------------- /.changes/aliasoutputbuilder.md: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | "nodejs-binding": patch 4 | --- 5 | 6 | IAliasOutputBuilderOptions::stateMetadata is now a HexEncodedString instead of Uint8Array. -------------------------------------------------------------------------------- /.changes/basic-auth.md: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | "nodejs-binding": patch 4 | --- 5 | 6 | Merged `IAuth::{username, password}` into `IAuth::basicAuthNamePwd`; 7 | Set basic auth when provided; 8 | -------------------------------------------------------------------------------- /.changes/bech32-address.md: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | "nodejs-binding": patch 4 | --- 5 | 6 | Removed `IInputSigningData::bech32Address`; -------------------------------------------------------------------------------- /.changes/build-fix.md: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | "nodejs-binding": patch 4 | --- 5 | 6 | Run tsc before publishing. 7 | -------------------------------------------------------------------------------- /.changes/burn-interface.md: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | "nodejs-binding": patch 4 | --- 5 | 6 | Add `Burn` interface. 7 | Replace `IBuildBlockOptions::allowBurning` with `IBuildBlockOptions::burn`. 8 | -------------------------------------------------------------------------------- /.changes/computeAlias-NftId.md: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | "nodejs-binding": patch 4 | --- 5 | 6 | Add `computeAliasId()` and `computeNftId()` functions. 7 | -------------------------------------------------------------------------------- /.changes/computeFoundryId.md: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | "nodejs-binding": patch 4 | --- 5 | 6 | Add `computeFoundryId()`. 7 | -------------------------------------------------------------------------------- /.changes/enum-serialization-attributes.md: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | "nodejs-binding": patch 4 | --- 5 | 6 | Add `u8` representation to serialization and deserialization for `ParticipationEventType`. 7 | -------------------------------------------------------------------------------- /.changes/fix-build-script.md: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | "nodejs-binding": patch 4 | --- 5 | 6 | Fix build script filename. 7 | -------------------------------------------------------------------------------- /.changes/fix-burn-mismatch.md: -------------------------------------------------------------------------------- 1 | --- 2 | "nodejs-binding": patch 3 | --- 4 | 5 | `Burn` fields are now optional. 6 | `Burn::nativeTokens` is now an array. -------------------------------------------------------------------------------- /.changes/fix-rebuild-script.md: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | "nodejs-binding": patch 4 | --- 5 | 6 | Fix rebuild script. 7 | -------------------------------------------------------------------------------- /.changes/get-included-block-metadata.md: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | "nodejs-binding": patch 4 | --- 5 | 6 | Add `Client::getIncludedBlockMetadata`. 7 | -------------------------------------------------------------------------------- /.changes/hashTransactionEssence.md: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | "nodejs-binding": patch 4 | --- 5 | 6 | Add `Client::hashTransactionEssence()`; 7 | -------------------------------------------------------------------------------- /.changes/input-signing-data.md: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | "nodejs-binding": patch 4 | --- 5 | 6 | Fixed returned JSON value for `IInputSigningData`; 7 | Renamed `IInputSigningData::outputMetaData` to `IInputSigningData::outputMetadata`; 8 | Changed `ISegment::bs` from `Uint8Array` to `number[]` so that the serialization corresponds to what is expected; 9 | -------------------------------------------------------------------------------- /.changes/install.md: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | "nodejs-binding": patch 4 | --- 5 | 6 | Fix install command; -------------------------------------------------------------------------------- /.changes/ledger-nano-prompt.md: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | "nodejs-binding": patch 4 | --- 5 | 6 | Rename `IGenerateAddressOptions` to `IGenerateAddressOptions` and replace its syncing field with ledgerNanoPrompt. 7 | -------------------------------------------------------------------------------- /.changes/mqtt.md: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | "nodejs-binding": patch 4 | --- 5 | 6 | Fix MQTT multiple events when .listen() is called multiple times. 7 | Made `Client::listen()` async. 8 | Added `Client::clearListeners()`. -------------------------------------------------------------------------------- /.changes/networkinfo.md: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | "nodejs-binding": patch 4 | --- 5 | 6 | Fix types in networkInfo. -------------------------------------------------------------------------------- /.changes/nftIdToBech32.md: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | "nodejs-binding": patch 4 | --- 5 | 6 | Add `nftIdToBech32()`. 7 | -------------------------------------------------------------------------------- /.changes/node-sync-health.md: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | "nodejs-binding": patch 4 | --- 5 | 6 | Replaced `nodeSyncEnabled` by `ignoreNodeHealth`. 7 | -------------------------------------------------------------------------------- /.changes/outputIds.md: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | "nodejs-binding": patch 4 | --- 5 | 6 | ### Added 7 | 8 | - `OutputIdsResponse`; 9 | 10 | ### Changed 11 | 12 | - `Client::{aliasOutputIds, basicOutputIds, foundryOutputIds, nftOutputIds}` will not do automatic pagination if `QueryParameter::Cursor(_)` is provided and return type from `string[]` to `OutputIdsResponse`; -------------------------------------------------------------------------------- /.changes/pow.md: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | "nodejs-binding": patch 4 | --- 5 | 6 | Fix infinite loop when the minimum PoW score is 0 (often in private tangles). 7 | -------------------------------------------------------------------------------- /.changes/pre.json: -------------------------------------------------------------------------------- 1 | { 2 | "tag": "rc", 3 | "changes": [ 4 | ".changes/alias-nft-unlock.md", 5 | ".changes/aliasIdToBech32.md", 6 | ".changes/basic-auth.md", 7 | ".changes/build-fix.md", 8 | ".changes/burn-interface.md", 9 | ".changes/computeAlias-NftId.md", 10 | ".changes/computeFoundryId.md", 11 | ".changes/enum-serialization-attributes.md", 12 | ".changes/fix-build-script.md", 13 | ".changes/fix-rebuild-script.md", 14 | ".changes/get-included-block-metadata.md", 15 | ".changes/input-signing-data.md", 16 | ".changes/ledger-nano-prompt.md", 17 | ".changes/mqtt.md", 18 | ".changes/networkinfo.md", 19 | ".changes/nftIdToBech32.md", 20 | ".changes/node-sync-health.md", 21 | ".changes/pow.md", 22 | ".changes/prebuilds.md", 23 | ".changes/protocol-parameters.md", 24 | ".changes/signatureUnlock.md", 25 | ".changes/switch-to-napi-6.md", 26 | ".changes/unhealthy-nodes.md" 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /.changes/prebuilds.md: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | "nodejs-binding": patch 4 | --- 5 | 6 | Fix prebuild scripts. 7 | -------------------------------------------------------------------------------- /.changes/protocol-parameters.md: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | "nodejs-binding": patch 4 | --- 5 | 6 | Add `getTokenSupply` and `getProtocolParameters`. 7 | -------------------------------------------------------------------------------- /.changes/signatureUnlock.md: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | "nodejs-binding": patch 4 | --- 5 | 6 | Add `signatureUnlock()`. 7 | -------------------------------------------------------------------------------- /.changes/switch-to-napi-6.md: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | "nodejs-binding": patch 4 | --- 5 | 6 | Move to N-API 6 builds. 7 | -------------------------------------------------------------------------------- /.changes/unhealthy-nodes.md: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | "nodejs-binding": patch 4 | --- 5 | 6 | Update network info from unhealty nodes if ignoreNodeHealth is set to true. 7 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Discord 4 | url: https://discord.iota.org/ 5 | about: Please ask and answer questions here. 6 | - name: Security vulnerabilities 7 | url: security@iota.org 8 | about: Please report security vulnerabilities here. 9 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Request a feature for iota.rs 3 | about: Request a feature 4 | --- 5 | 6 | ## Description 7 | 8 | Briefly describe the feature that you are requesting. 9 | 10 | ## Motivation 11 | 12 | Explain why this feature is needed. 13 | 14 | ## Requirements 15 | 16 | Write a list of what you want this feature to do. 17 | 18 | 1. 19 | 2. 20 | 3. 21 | 22 | ## Open questions (optional) 23 | 24 | Use this section to ask any questions that are related to the feature. 25 | 26 | ## Are you planning to do it yourself in a pull request? 27 | 28 | Yes/No. 29 | -------------------------------------------------------------------------------- /.github/actions/private-tangle/tear-down/action.yml: -------------------------------------------------------------------------------- 1 | name: 'private-tangle-tear-down' 2 | description: 'tear-down a private tangle' 3 | runs: 4 | using: "composite" 5 | steps: 6 | - name: Tear down private tangle 7 | shell: bash 8 | run: | 9 | # TODO: use next line when a working hornet release is published 10 | #cd private_tangle 11 | 12 | # TODO: remove next line when a working hornet release is published 13 | sudo ./cleanup.sh 14 | working-directory: hornet/private_tangle 15 | -------------------------------------------------------------------------------- /.github/actions/setup-clang/action.yml: -------------------------------------------------------------------------------- 1 | name: Set Up Clang/LLVM 2 | description: "This composite action installs Clang/LLVM to the runner's temporary directory and sets LIBCLANG_PATH for the following steps, which is required for bindgen to work on Windows. See: https://github.com/rust-lang/rust-bindgen/issues/1797." 3 | inputs: 4 | version: 5 | description: The version of Clang/LLVM to install. 6 | type: string 7 | required: false 8 | default: '13' 9 | 10 | runs: 11 | using: composite 12 | steps: 13 | - name: Install Clang/LLVM 14 | uses: KyleMayes/install-llvm-action@v1 15 | with: 16 | version: ${{ inputs.version }} 17 | directory: ${{ runner.temp }}/llvm/ 18 | 19 | - name: Set LIBCLANG_PATH 20 | shell: pwsh 21 | run: Add-Content -Path "$Env:GITHUB_ENV" -Value "LIBCLANG_PATH=$Env:LLVM_PATH\bin" 22 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | # Description of change 2 | 3 | Please write a summary of your changes and why you made them. 4 | 5 | ## Links to any relevant issues 6 | 7 | Be sure to reference any related issues by adding `fixes #issue_number`. 8 | 9 | ## Type of change 10 | 11 | Choose a type of change, and delete any options that are not relevant. 12 | 13 | - Bug fix (a non-breaking change which fixes an issue) 14 | - Enhancement (a non-breaking change which adds functionality) 15 | - Breaking change (fix or feature that would cause existing functionality to not work as expected) 16 | - Documentation Fix 17 | 18 | ## How the change has been tested 19 | 20 | Describe the tests that you ran to verify your changes. 21 | 22 | Make sure to provide instructions for the maintainer as well as any relevant configurations. 23 | 24 | ## Change checklist 25 | 26 | Tick the boxes that are relevant to your changes, and delete any items that are not. 27 | 28 | - [ ] I have followed the contribution guidelines for this project 29 | - [ ] I have performed a self-review of my own code 30 | - [ ] I have commented my code, particularly in hard-to-understand areas 31 | - [ ] I have made corresponding changes to the documentation 32 | - [ ] I have added tests that prove my fix is effective or that my feature works 33 | - [ ] I have checked that new and existing unit tests pass locally with my changes 34 | -------------------------------------------------------------------------------- /.github/workflows/bindings-wasm-release.yml: -------------------------------------------------------------------------------- 1 | name: Wasm bindings release 2 | 3 | on: workflow_dispatch 4 | 5 | jobs: 6 | publish-wasm: 7 | runs-on: ubuntu-latest 8 | 9 | defaults: 10 | run: 11 | working-directory: client/bindings/wasm 12 | 13 | steps: 14 | - uses: actions/checkout@v3 15 | 16 | - name: Install stable toolchain 17 | uses: actions-rs/toolchain@v1 18 | with: 19 | toolchain: stable 20 | override: true 21 | target: "wasm32-unknown-unknown" 22 | 23 | # Download a pre-compiled wasm-bindgen binary. 24 | - name: Install wasm-bindgen-cli 25 | uses: jetli/wasm-bindgen-action@24ba6f9fff570246106ac3f80f35185600c3f6c9 26 | with: 27 | version: "0.2.84" 28 | 29 | - name: Set up Node.js 30 | uses: actions/setup-node@v2 31 | with: 32 | node-version: "16.x" 33 | registry-url: "https://registry.npmjs.org" 34 | 35 | - name: Install Yarn 36 | run: npm i -g yarn 37 | 38 | - name: Install JS dependencies 39 | run: yarn 40 | 41 | - name: Build project 42 | run: yarn build 43 | 44 | - name: Publish WASM bindings to NPM 45 | shell: sh 46 | env: 47 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} 48 | run: npm publish --access public 49 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/target 2 | **/*.rs.bk 3 | .idea 4 | .vscode 5 | .DS_Store 6 | book 7 | .env 8 | *.ipynb 9 | address.json 10 | prepared_transaction.json 11 | signed_transaction.json 12 | iota.rs.log 13 | *.stronghold 14 | client.log -------------------------------------------------------------------------------- /.license_template: -------------------------------------------------------------------------------- 1 | // Copyright {20\d{2}(-20\d{2})?} IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | resolver = "2" 3 | members = [ 4 | "client", 5 | "client/bindings/java/lib/native", 6 | "client/bindings/nodejs", 7 | "client/bindings/python", 8 | "client/bindings/wasm", 9 | "pow", 10 | "types", 11 | ] 12 | 13 | [profile.dev] 14 | panic = "abort" 15 | 16 | [profile.release] 17 | panic = "abort" 18 | 19 | [profile.production] 20 | codegen-units = 1 21 | inherits = "release" 22 | lto = true 23 | panic = "abort" 24 | strip = "symbols" -------------------------------------------------------------------------------- /client/.env.example: -------------------------------------------------------------------------------- 1 | NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1="endorse answer radar about source reunion marriage tag sausage weekend frost daring base attack because joke dream slender leisure group reason prepare broken river" 2 | NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_2="width scatter jaguar sponsor erosion enable cave since ancient first garden royal luggage exchange ritual exotic play wall clinic ride autumn divert spin exchange" 3 | NON_SECURE_USE_OF_DEVELOPMENT_SEED_1=0x256a818b2aac458941f7274985a410e57fb750f3a3a67969ece5bd9ae7eef5b2 4 | NON_SECURE_USE_OF_DEVELOPMENT_SEED_2=0x256a818b2aac458941f7274985a410e57fb750f3a3a67969ece5bd9ae7eef5b3 5 | NODE_URL="http://localhost:14265" 6 | FAUCET_URL="http://localhost:8091/api/enqueue" 7 | EXPLORER_URL="https://explorer.shimmer.network/testnet" 8 | -------------------------------------------------------------------------------- /client/bindings/java/.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | gradle.properties 3 | lib/build 4 | lib/bin 5 | src/native/target 6 | examples/build/ 7 | examples/bin/ -------------------------------------------------------------------------------- /client/bindings/java/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'io.github.gradle-nexus.publish-plugin' version '1.1.0' 3 | } 4 | 5 | group 'org.iota' 6 | version = '1.0.0-rc.2' 7 | 8 | nexusPublishing { 9 | repositories { 10 | sonatype() 11 | } 12 | } -------------------------------------------------------------------------------- /client/bindings/java/examples/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'application' 3 | } 4 | 5 | repositories { 6 | mavenCentral() 7 | } 8 | 9 | dependencies { 10 | implementation project(':lib') 11 | implementation group: 'commons-codec', name: 'commons-codec', version: '1.15' 12 | implementation 'com.google.code.gson:gson:2.10' 13 | } 14 | 15 | application { 16 | mainClassName = project.findProperty("example").toString() 17 | } 18 | 19 | sourceSets.main.java.srcDirs = ['src'] -------------------------------------------------------------------------------- /client/bindings/java/examples/src/CreateBlock.java: -------------------------------------------------------------------------------- 1 | import org.iota.Client; 2 | import org.iota.types.Block; 3 | import org.iota.types.ClientConfig; 4 | import org.iota.types.expections.ClientException; 5 | import org.iota.types.expections.InitializeClientException; 6 | import org.iota.types.ids.BlockId; 7 | 8 | import java.util.Map; 9 | 10 | public class CreateBlock { 11 | public static void main(String[] args) throws ClientException, InitializeClientException { 12 | // Build the client. 13 | Client client = new Client(new ClientConfig().withNodes(new String[]{"https://api.testnet.shimmer.network"})); 14 | 15 | // Create the most simple block. 16 | Map.Entry b = client.buildAndPostBlock(null, null); 17 | 18 | // Print the block. 19 | System.out.println(b); 20 | } 21 | } -------------------------------------------------------------------------------- /client/bindings/java/examples/src/GenerateMnemonic.java: -------------------------------------------------------------------------------- 1 | import org.iota.Client; 2 | import org.iota.types.ClientConfig; 3 | import org.iota.types.expections.ClientException; 4 | import org.iota.types.expections.InitializeClientException; 5 | 6 | public class GenerateMnemonic { 7 | public static void main(String[] args) throws ClientException, InitializeClientException { 8 | // Build the client. 9 | Client client = new Client(new ClientConfig().withNodes(new String[]{"https://api.testnet.shimmer.network"})); 10 | 11 | // Generate a mnemonic. 12 | String mnemonic = client.generateMnemonic(); 13 | 14 | // Print the mnemonic. 15 | System.out.println(mnemonic); 16 | } 17 | } -------------------------------------------------------------------------------- /client/bindings/java/examples/src/GetBlock.java: -------------------------------------------------------------------------------- 1 | import org.iota.Client; 2 | import org.iota.types.Block; 3 | import org.iota.types.ClientConfig; 4 | import org.iota.types.expections.ClientException; 5 | import org.iota.types.expections.InitializeClientException; 6 | import org.iota.types.ids.BlockId; 7 | 8 | public class GetBlock { 9 | public static void main(String[] args) throws ClientException, InitializeClientException { 10 | // Build the client. 11 | Client client = new Client(new ClientConfig().withNodes(new String[]{"https://api.testnet.shimmer.network"})); 12 | 13 | // Set up a block ID for this example. 14 | BlockId blockId = ExampleUtils.setUpBlockId(client); 15 | 16 | // Get the block. 17 | Block block = client.getBlock(blockId); 18 | 19 | // Print the block. 20 | System.out.println(block); 21 | } 22 | } -------------------------------------------------------------------------------- /client/bindings/java/examples/src/GetBlockMetadata.java: -------------------------------------------------------------------------------- 1 | import org.iota.Client; 2 | import org.iota.types.BlockMetadata; 3 | import org.iota.types.ClientConfig; 4 | import org.iota.types.expections.ClientException; 5 | import org.iota.types.expections.InitializeClientException; 6 | import org.iota.types.ids.BlockId; 7 | 8 | public class GetBlockMetadata { 9 | public static void main(String[] args) throws ClientException, InitializeClientException { 10 | // Build the client. 11 | Client client = new Client(new ClientConfig().withNodes(new String[]{"https://api.testnet.shimmer.network"})); 12 | 13 | // Set up a block ID for this example. 14 | BlockId blockId = ExampleUtils.setUpBlockId(client); 15 | 16 | // Get the block metadata. 17 | BlockMetadata blockMetadata = client.getBlockMetadata(blockId); 18 | 19 | // Print the block metadata. 20 | System.out.println(blockMetadata); 21 | } 22 | } -------------------------------------------------------------------------------- /client/bindings/java/examples/src/GetBlockRaw.java: -------------------------------------------------------------------------------- 1 | import org.apache.commons.codec.binary.Hex; 2 | import org.iota.Client; 3 | import org.iota.types.ClientConfig; 4 | import org.iota.types.expections.ClientException; 5 | import org.iota.types.expections.InitializeClientException; 6 | import org.iota.types.ids.BlockId; 7 | 8 | public class GetBlockRaw { 9 | public static void main(String[] args) throws ClientException, InitializeClientException { 10 | // Build the client. 11 | Client client = new Client(new ClientConfig().withNodes(new String[]{"https://api.testnet.shimmer.network"})); 12 | 13 | // Set up a block ID for this example. 14 | BlockId blockId = ExampleUtils.setUpBlockId(client); 15 | 16 | // Get the block bytes. 17 | byte[] blockBytes = client.getBlockRaw(blockId); 18 | 19 | // Print the block bytes. 20 | System.out.println(Hex.encodeHex(blockBytes)); 21 | } 22 | } -------------------------------------------------------------------------------- /client/bindings/java/examples/src/GetHealth.java: -------------------------------------------------------------------------------- 1 | import org.iota.Client; 2 | import org.iota.types.ClientConfig; 3 | import org.iota.types.expections.ClientException; 4 | import org.iota.types.expections.InitializeClientException; 5 | 6 | public class GetHealth { 7 | public static void main(String[] args) throws ClientException, InitializeClientException { 8 | // Build the client. 9 | Client client = new Client(new ClientConfig().withNodes(new String[]{"https://api.testnet.shimmer.network"})); 10 | 11 | // Get the health of the given node. 12 | boolean health = client.getHealth("https://api.testnet.shimmer.network"); 13 | 14 | // Print the response. 15 | System.out.println(health); 16 | } 17 | } -------------------------------------------------------------------------------- /client/bindings/java/examples/src/GetInfo.java: -------------------------------------------------------------------------------- 1 | import org.iota.Client; 2 | import org.iota.types.ClientConfig; 3 | import org.iota.types.expections.ClientException; 4 | import org.iota.types.expections.InitializeClientException; 5 | import org.iota.types.responses.NodeInfoResponse; 6 | 7 | public class GetInfo { 8 | public static void main(String[] args) throws ClientException, InitializeClientException { 9 | // Build the client. 10 | Client client = new Client(new ClientConfig().withNodes(new String[]{"https://api.testnet.shimmer.network"})); 11 | 12 | // Get the node information for a given node. 13 | NodeInfoResponse response = client.getNodeInfo(); 14 | 15 | // Print the URL of the node that was requested. 16 | System.out.println(response.getNodeUrl()); 17 | 18 | // Print the node information for the requested node. 19 | System.out.println(response.getNodeInfo()); 20 | } 21 | } -------------------------------------------------------------------------------- /client/bindings/java/examples/src/GetMilestoneById.java: -------------------------------------------------------------------------------- 1 | import org.iota.Client; 2 | import org.iota.types.ClientConfig; 3 | import org.iota.types.expections.ClientException; 4 | import org.iota.types.MilestonePayload; 5 | import org.iota.types.expections.InitializeClientException; 6 | import org.iota.types.ids.MilestoneId; 7 | 8 | public class GetMilestoneById { 9 | public static void main(String[] args) throws ClientException, InitializeClientException { 10 | // Build the client. 11 | Client client = new Client(new ClientConfig().withNodes(new String[]{"https://api.testnet.shimmer.network"})); 12 | 13 | // Set up a milestone ID for this example. 14 | MilestoneId milestoneId = ExampleUtils.setUpMilestoneId(client); 15 | 16 | // Get the milestone. 17 | MilestonePayload milestone = client.getMilestoneById(milestoneId); 18 | 19 | // Print the milestone. 20 | System.out.println(milestone); 21 | } 22 | } -------------------------------------------------------------------------------- /client/bindings/java/examples/src/GetMilestoneByIdRaw.java: -------------------------------------------------------------------------------- 1 | import org.apache.commons.codec.binary.Hex; 2 | import org.iota.Client; 3 | import org.iota.types.ClientConfig; 4 | import org.iota.types.expections.ClientException; 5 | import org.iota.types.expections.InitializeClientException; 6 | import org.iota.types.ids.MilestoneId; 7 | 8 | public class GetMilestoneByIdRaw { 9 | public static void main(String[] args) throws ClientException, InitializeClientException { 10 | // Build the client. 11 | Client client = new Client(new ClientConfig().withNodes(new String[]{"https://api.testnet.shimmer.network"})); 12 | 13 | // Set up a milestone ID for this example. 14 | MilestoneId milestoneId = ExampleUtils.setUpMilestoneId(client); 15 | 16 | // Get the milestone bytes. 17 | byte[] milestoneBytes = client.getMilestoneByIdRaw(milestoneId); 18 | 19 | // Print the milestone bytes. 20 | System.out.println(Hex.encodeHex(milestoneBytes)); 21 | } 22 | } -------------------------------------------------------------------------------- /client/bindings/java/examples/src/GetMilestoneByIndex.java: -------------------------------------------------------------------------------- 1 | import org.iota.Client; 2 | import org.iota.types.ClientConfig; 3 | import org.iota.types.expections.ClientException; 4 | import org.iota.types.MilestonePayload; 5 | import org.iota.types.expections.InitializeClientException; 6 | 7 | public class GetMilestoneByIndex { 8 | public static void main(String[] args) throws ClientException, InitializeClientException { 9 | // Build the client. 10 | Client client = new Client(new ClientConfig().withNodes(new String[]{"https://api.testnet.shimmer.network"})); 11 | 12 | // Set up a milestone index for this example. 13 | int milestoneIndex = ExampleUtils.setUpMilestoneIndex(client); 14 | 15 | // Get the milestone. 16 | MilestonePayload milestone = client.getMilestoneByIndex(milestoneIndex); 17 | 18 | // Print the milestone. 19 | System.out.println(milestone); 20 | } 21 | } -------------------------------------------------------------------------------- /client/bindings/java/examples/src/GetMilestoneByIndexRaw.java: -------------------------------------------------------------------------------- 1 | import org.apache.commons.codec.binary.Hex; 2 | import org.iota.Client; 3 | import org.iota.types.ClientConfig; 4 | import org.iota.types.expections.ClientException; 5 | import org.iota.types.expections.InitializeClientException; 6 | 7 | public class GetMilestoneByIndexRaw { 8 | public static void main(String[] args) throws ClientException, InitializeClientException { 9 | // Build the client. 10 | Client client = new Client(new ClientConfig().withNodes(new String[]{"https://api.testnet.shimmer.network"})); 11 | 12 | // Set up a milestone index for this example. 13 | int milestoneIndex = ExampleUtils.setUpMilestoneIndex(client); 14 | 15 | // Get the milestone bytes. 16 | byte[] milestoneBytes = client.getMilestoneByIndexRaw(milestoneIndex); 17 | 18 | // Print the milestone bytes. 19 | System.out.println(Hex.encodeHex(milestoneBytes)); 20 | } 21 | } -------------------------------------------------------------------------------- /client/bindings/java/examples/src/GetOutputs.java: -------------------------------------------------------------------------------- 1 | import org.iota.Client; 2 | import org.iota.types.ClientConfig; 3 | import org.iota.types.expections.ClientException; 4 | import org.iota.types.Output; 5 | import org.iota.types.OutputMetadata; 6 | import org.iota.types.expections.InitializeClientException; 7 | import org.iota.types.ids.OutputId; 8 | 9 | import java.util.Map; 10 | 11 | public class GetOutputs { 12 | public static void main(String[] args) throws ClientException, InitializeClientException { 13 | // Build the client. 14 | Client client = new Client(new ClientConfig().withNodes(new String[]{"https://api.testnet.shimmer.network"})); 15 | 16 | // Set up a output ID for this example. 17 | OutputId outputId = ExampleUtils.setUpOutputId(client); 18 | 19 | // Get the output for the given output id. 20 | Map.Entry outputData = client.getOutput(outputId); 21 | 22 | // Print the output and its metadata. 23 | System.out.println(outputData.getKey()); 24 | System.out.println(outputData.getValue()); 25 | } 26 | } -------------------------------------------------------------------------------- /client/bindings/java/examples/src/GetReceipts.java: -------------------------------------------------------------------------------- 1 | import org.iota.Client; 2 | import org.iota.types.ClientConfig; 3 | import org.iota.types.expections.ClientException; 4 | import org.iota.types.Receipt; 5 | import org.iota.types.expections.InitializeClientException; 6 | 7 | public class GetReceipts { 8 | public static void main(String[] args) throws ClientException, InitializeClientException { 9 | // Build the client. 10 | Client client = new Client(new ClientConfig().withNodes(new String[]{"https://api.testnet.shimmer.network"})); 11 | 12 | // Get the receipts. 13 | Receipt[] receipts = client.getReceipts(); 14 | 15 | // Print the receipts. 16 | for (Receipt receipt : receipts) 17 | System.out.println(receipt); 18 | } 19 | } -------------------------------------------------------------------------------- /client/bindings/java/examples/src/GetReceiptsMigratedAt.java: -------------------------------------------------------------------------------- 1 | import org.iota.Client; 2 | import org.iota.types.ClientConfig; 3 | import org.iota.types.expections.ClientException; 4 | import org.iota.types.Receipt; 5 | import org.iota.types.expections.InitializeClientException; 6 | 7 | public class GetReceiptsMigratedAt { 8 | public static void main(String[] args) throws ClientException, InitializeClientException { 9 | // Build the client. 10 | Client client = new Client(new ClientConfig().withNodes(new String[]{"https://api.testnet.shimmer.network"})); 11 | 12 | // Set up a milestone index for this example. 13 | int milestoneIndex = ExampleUtils.setUpMilestoneIndex(client); 14 | 15 | // Get the receipts at the specific milestone index. 16 | Receipt[] receipts = client.getReceiptsMigratedAt(milestoneIndex); 17 | 18 | // Print the receipts. 19 | for (Receipt receipt : receipts) 20 | System.out.println(receipt); 21 | } 22 | } -------------------------------------------------------------------------------- /client/bindings/java/examples/src/GetTips.java: -------------------------------------------------------------------------------- 1 | import org.iota.Client; 2 | import org.iota.types.ClientConfig; 3 | import org.iota.types.expections.ClientException; 4 | import org.iota.types.expections.InitializeClientException; 5 | import org.iota.types.ids.BlockId; 6 | 7 | public class GetTips { 8 | public static void main(String[] args) throws ClientException, InitializeClientException { 9 | // Build the client. 10 | Client client = new Client(new ClientConfig().withNodes(new String[]{"https://api.testnet.shimmer.network"})); 11 | 12 | // Get the tips. 13 | BlockId[] tips = client.getTips(); 14 | 15 | // Print the tips. 16 | for (BlockId id : tips) 17 | System.out.println(id); 18 | } 19 | } -------------------------------------------------------------------------------- /client/bindings/java/examples/src/GetTreasury.java: -------------------------------------------------------------------------------- 1 | import org.iota.Client; 2 | import org.iota.types.ClientConfig; 3 | import org.iota.types.expections.ClientException; 4 | import org.iota.types.expections.InitializeClientException; 5 | import org.iota.types.responses.TreasuryResponse; 6 | 7 | public class GetTreasury { 8 | public static void main(String[] args) throws ClientException, InitializeClientException { 9 | // Build the client. 10 | Client client = new Client(new ClientConfig().withNodes(new String[]{"https://api.testnet.shimmer.network"})); 11 | 12 | // Get the treasury. 13 | TreasuryResponse response = client.getTreasury(); 14 | 15 | // Print the amount. 16 | System.out.println(response.getAmount()); 17 | 18 | // Print the milestone ID. 19 | System.out.println(response.getMilestoneId()); 20 | } 21 | } -------------------------------------------------------------------------------- /client/bindings/java/examples/src/GetUtxoChangesById.java: -------------------------------------------------------------------------------- 1 | import org.iota.Client; 2 | import org.iota.types.ClientConfig; 3 | import org.iota.types.expections.ClientException; 4 | import org.iota.types.expections.InitializeClientException; 5 | import org.iota.types.ids.MilestoneId; 6 | import org.iota.types.ids.OutputId; 7 | import org.iota.types.responses.UtxoChangesResponse; 8 | 9 | public class GetUtxoChangesById { 10 | public static void main(String[] args) throws ClientException, InitializeClientException { 11 | // Build the client. 12 | Client client = new Client(new ClientConfig().withNodes(new String[]{"https://api.testnet.shimmer.network"})); 13 | 14 | // Set up a milestone ID for this example. 15 | MilestoneId milestoneId = ExampleUtils.setUpMilestoneId(client); 16 | 17 | // Get the UTXO changes. 18 | UtxoChangesResponse response = client.getUtxoChangesById(milestoneId); 19 | 20 | // Print the milestone index. 21 | System.out.println(response.getIndex()); 22 | 23 | // Print the created outputs. 24 | for (OutputId outputId : response.getCreatedOutputs()) 25 | System.out.println(outputId); 26 | 27 | // Print the consumed outputs. 28 | for (OutputId outputId : response.getConsumedOutputs()) 29 | System.out.println(outputId); 30 | } 31 | } -------------------------------------------------------------------------------- /client/bindings/java/examples/src/GetUtxoChangesByIndex.java: -------------------------------------------------------------------------------- 1 | import org.iota.Client; 2 | import org.iota.types.ClientConfig; 3 | import org.iota.types.expections.ClientException; 4 | import org.iota.types.expections.InitializeClientException; 5 | import org.iota.types.ids.OutputId; 6 | import org.iota.types.responses.UtxoChangesResponse; 7 | 8 | public class GetUtxoChangesByIndex { 9 | public static void main(String[] args) throws ClientException, InitializeClientException { 10 | // Build the client. 11 | Client client = new Client(new ClientConfig().withNodes(new String[]{"https://api.testnet.shimmer.network"})); 12 | 13 | // Set up a milestone index for this example. 14 | int milestoneIndex = ExampleUtils.setUpMilestoneIndex(client); 15 | 16 | // Get the UTXO changes. 17 | UtxoChangesResponse response = client.getUtxoChangesByIndex(milestoneIndex); 18 | 19 | // Print the milestone index. 20 | System.out.println(response.getIndex()); 21 | 22 | // Print the created outputs. 23 | for (OutputId outputId : response.getCreatedOutputs()) 24 | System.out.println(outputId); 25 | 26 | // Print the consumed outputs. 27 | for (OutputId outputId : response.getConsumedOutputs()) 28 | System.out.println(outputId); 29 | } 30 | } -------------------------------------------------------------------------------- /client/bindings/java/examples/src/PostBlock.java: -------------------------------------------------------------------------------- 1 | import org.iota.Client; 2 | import org.iota.types.Block; 3 | import org.iota.types.ClientConfig; 4 | import org.iota.types.expections.ClientException; 5 | import org.iota.types.expections.InitializeClientException; 6 | import org.iota.types.ids.BlockId; 7 | 8 | public class PostBlock { 9 | public static void main(String[] args) throws ClientException, InitializeClientException { 10 | // Build the client. 11 | Client client = new Client(new ClientConfig().withNodes(new String[]{"https://api.testnet.shimmer.network"})); 12 | 13 | // Set up a block for this example. 14 | Block b = ExampleUtils.setUpBlock(client); 15 | 16 | // Post the block. 17 | BlockId id = client.postBlock(b); 18 | 19 | // Print the id of the created block. 20 | System.out.println(id); 21 | } 22 | } -------------------------------------------------------------------------------- /client/bindings/java/examples/src/PostBlockRaw.java: -------------------------------------------------------------------------------- 1 | import org.iota.Client; 2 | import org.iota.types.ClientConfig; 3 | import org.iota.types.expections.ClientException; 4 | import org.iota.types.expections.InitializeClientException; 5 | import org.iota.types.ids.BlockId; 6 | 7 | public class PostBlockRaw { 8 | public static void main(String[] args) throws ClientException, InitializeClientException { 9 | // Build the client. 10 | Client client = new Client(new ClientConfig().withNodes(new String[]{"https://api.testnet.shimmer.network"})); 11 | 12 | // Set up a block for this example. 13 | byte[] blockBytes = ExampleUtils.setUpBlockRaw(client); 14 | 15 | // Post the block. 16 | BlockId id = client.postBlockRaw(blockBytes); 17 | 18 | // Print the id of the created block. 19 | System.out.println(id); 20 | } 21 | } -------------------------------------------------------------------------------- /client/bindings/java/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/iota.rs/e906ef3737f8c2b9ec910e466ec1d1c3be9a3b14/client/bindings/java/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /client/bindings/java/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /client/bindings/java/lib/native/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "iota-client-java" 3 | version = "0.1.0" 4 | authors = [ "IOTA Stiftung" ] 5 | edition = "2021" 6 | description = "Java bindings for the IOTA client library" 7 | documentation = "https://wiki.iota.org/iota.rs/welcome" 8 | homepage = "https://www.iota.org/" 9 | repository = "https://github.com/iotaledger/iota.rs" 10 | license = "Apache-2.0" 11 | keywords = [ "iota", "tangle", "client", "java" ] 12 | publish = false 13 | 14 | [lib] 15 | name = "iota_client" 16 | crate-type = [ "cdylib" ] 17 | 18 | [dependencies] 19 | iota-client = { path = "../../../..", features = [ "message_interface", "stronghold", "tls" ] } 20 | 21 | futures = { version = "0.3.26", default-features = false } 22 | jni = { version = "0.21.0", default-features = false } 23 | lazy_static = { version = "1.4.0", default-features = false } 24 | once_cell = { version = "1.17.1", default-features = false } 25 | serde_json = { version = "1.0.94", default-features = false } 26 | tokio = { version = "1.26.0", default-features = false, features = [ "macros" ] } 27 | 28 | [features] 29 | ledger_nano = [ "iota-client/ledger_nano" ] -------------------------------------------------------------------------------- /client/bindings/java/lib/native/src/main.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | fn main() {} 5 | -------------------------------------------------------------------------------- /client/bindings/java/lib/src/main/java/org/iota/apis/ClientCommand.java: -------------------------------------------------------------------------------- 1 | package org.iota.apis; 2 | 3 | import com.google.gson.JsonElement; 4 | import com.google.gson.JsonObject; 5 | 6 | public class ClientCommand { 7 | 8 | private String methodName; 9 | private JsonElement methodParams; 10 | 11 | public ClientCommand(String methodName) { 12 | this.methodName = methodName; 13 | } 14 | 15 | public ClientCommand(String methodName, JsonElement methodParams) { 16 | this.methodName = methodName; 17 | this.methodParams = methodParams; 18 | } 19 | 20 | public String getMethodName() { 21 | return methodName; 22 | } 23 | 24 | @Override 25 | public String toString() { 26 | JsonObject message = new JsonObject(); 27 | message.addProperty("name", methodName); 28 | message.add("data", methodParams); 29 | 30 | return message.toString(); 31 | } 32 | } -------------------------------------------------------------------------------- /client/bindings/java/lib/src/main/java/org/iota/types/Block.java: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package org.iota.types; 5 | 6 | import com.google.gson.JsonObject; 7 | 8 | public class Block extends AbstractObject { 9 | 10 | public Block(JsonObject jsonObject) { 11 | super(jsonObject); 12 | } 13 | 14 | public Block(String jsonObject) { 15 | super(jsonObject); 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /client/bindings/java/lib/src/main/java/org/iota/types/BlockMetadata.java: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package org.iota.types; 5 | 6 | import com.google.gson.JsonObject; 7 | 8 | public class BlockMetadata extends AbstractObject { 9 | 10 | public BlockMetadata(JsonObject jsonObject) { 11 | super(jsonObject); 12 | } 13 | 14 | public BlockMetadata(String jsonObject) { 15 | super(jsonObject); 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /client/bindings/java/lib/src/main/java/org/iota/types/BlockPayload.java: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package org.iota.types; 5 | 6 | import com.google.gson.JsonObject; 7 | 8 | public abstract class BlockPayload extends AbstractObject { 9 | 10 | public BlockPayload(JsonObject jsonObject) { 11 | super(jsonObject); 12 | } 13 | 14 | public BlockPayload(String jsonObject) { 15 | super(jsonObject); 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /client/bindings/java/lib/src/main/java/org/iota/types/Burn.java: -------------------------------------------------------------------------------- 1 | // Copyright 2023 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package org.iota.types; 5 | 6 | import com.google.gson.JsonObject; 7 | 8 | public class Burn extends AbstractObject { 9 | 10 | public Burn(JsonObject jsonObject) { 11 | super(jsonObject); 12 | } 13 | 14 | public Burn(String jsonObject) { 15 | super(jsonObject); 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /client/bindings/java/lib/src/main/java/org/iota/types/Feature.java: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package org.iota.types; 5 | 6 | import com.google.gson.JsonObject; 7 | 8 | public class Feature extends AbstractObject { 9 | 10 | public Feature(JsonObject jsonObject) { 11 | super(jsonObject); 12 | } 13 | 14 | public Feature(String jsonObject) { 15 | super(jsonObject); 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /client/bindings/java/lib/src/main/java/org/iota/types/LedgerNanoStatus.java: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package org.iota.types; 5 | 6 | import com.google.gson.JsonObject; 7 | 8 | public class LedgerNanoStatus extends AbstractObject { 9 | 10 | public LedgerNanoStatus(JsonObject jsonObject) { 11 | super(jsonObject); 12 | } 13 | 14 | public LedgerNanoStatus(String jsonObject) { 15 | super(jsonObject); 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /client/bindings/java/lib/src/main/java/org/iota/types/MilestonePayload.java: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package org.iota.types; 5 | 6 | import com.google.gson.JsonObject; 7 | 8 | public class MilestonePayload extends BlockPayload { 9 | 10 | public MilestonePayload(JsonObject jsonObject) { 11 | super(jsonObject); 12 | } 13 | 14 | public MilestonePayload(String jsonObject) { 15 | super(jsonObject); 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /client/bindings/java/lib/src/main/java/org/iota/types/NativeToken.java: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package org.iota.types; 5 | 6 | import com.google.gson.JsonObject; 7 | 8 | public class NativeToken extends AbstractObject { 9 | 10 | public NativeToken(JsonObject jsonObject) { 11 | super(jsonObject); 12 | } 13 | 14 | public NativeToken(String jsonObject) { 15 | super(jsonObject); 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /client/bindings/java/lib/src/main/java/org/iota/types/Node.java: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package org.iota.types; 5 | 6 | import com.google.gson.JsonObject; 7 | 8 | public class Node extends AbstractObject { 9 | 10 | public Node(JsonObject jsonObject) { 11 | super(jsonObject); 12 | } 13 | 14 | public Node(String jsonObject) { 15 | super(jsonObject); 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /client/bindings/java/lib/src/main/java/org/iota/types/Output.java: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package org.iota.types; 5 | 6 | import com.google.gson.JsonObject; 7 | 8 | public class Output extends AbstractObject { 9 | 10 | public Output(JsonObject jsonObject) { 11 | super(jsonObject); 12 | } 13 | 14 | public Output(String jsonObject) { 15 | super(jsonObject); 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /client/bindings/java/lib/src/main/java/org/iota/types/OutputMetadata.java: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package org.iota.types; 5 | 6 | import com.google.gson.JsonObject; 7 | 8 | public class OutputMetadata extends AbstractObject { 9 | 10 | public OutputMetadata(JsonObject jsonObject) { 11 | super(jsonObject); 12 | } 13 | 14 | public OutputMetadata(String jsonObject) { 15 | super(jsonObject); 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /client/bindings/java/lib/src/main/java/org/iota/types/Peer.java: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package org.iota.types; 5 | 6 | import com.google.gson.JsonObject; 7 | 8 | public class Peer extends AbstractObject { 9 | 10 | public Peer(JsonObject jsonObject) { 11 | super(jsonObject); 12 | } 13 | 14 | public Peer(String jsonObject) { 15 | super(jsonObject); 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /client/bindings/java/lib/src/main/java/org/iota/types/PreparedTransactionData.java: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package org.iota.types; 5 | 6 | import com.google.gson.JsonObject; 7 | 8 | public class PreparedTransactionData extends AbstractObject { 9 | 10 | public PreparedTransactionData(JsonObject jsonObject) { 11 | super(jsonObject); 12 | } 13 | 14 | public PreparedTransactionData(String jsonObject) { 15 | super(jsonObject); 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /client/bindings/java/lib/src/main/java/org/iota/types/Receipt.java: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package org.iota.types; 5 | 6 | import com.google.gson.JsonObject; 7 | 8 | public class Receipt extends AbstractObject { 9 | 10 | public Receipt(JsonObject jsonObject) { 11 | super(jsonObject); 12 | } 13 | 14 | public Receipt(String jsonObject) { 15 | super(jsonObject); 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /client/bindings/java/lib/src/main/java/org/iota/types/TaggedDataPayload.java: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package org.iota.types; 5 | 6 | import com.google.gson.JsonObject; 7 | 8 | public class TaggedDataPayload extends BlockPayload { 9 | 10 | public TaggedDataPayload(JsonObject jsonObject) { 11 | super(jsonObject); 12 | } 13 | 14 | public TaggedDataPayload(String jsonObject) { 15 | super(jsonObject); 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /client/bindings/java/lib/src/main/java/org/iota/types/TokenScheme.java: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package org.iota.types; 5 | 6 | import com.google.gson.JsonObject; 7 | 8 | public class TokenScheme extends AbstractObject { 9 | 10 | public TokenScheme(JsonObject jsonObject) { 11 | super(jsonObject); 12 | } 13 | 14 | public TokenScheme(String jsonObject) { 15 | super(jsonObject); 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /client/bindings/java/lib/src/main/java/org/iota/types/TransactionPayload.java: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package org.iota.types; 5 | 6 | import com.google.gson.JsonObject; 7 | 8 | public class TransactionPayload extends BlockPayload { 9 | 10 | public TransactionPayload(JsonObject jsonObject) { 11 | super(jsonObject); 12 | } 13 | 14 | public TransactionPayload(String jsonObject) { 15 | super(jsonObject); 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /client/bindings/java/lib/src/main/java/org/iota/types/UnlockCondition.java: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package org.iota.types; 5 | 6 | import com.google.gson.JsonObject; 7 | 8 | public class UnlockCondition extends AbstractObject { 9 | 10 | public UnlockCondition(JsonObject jsonObject) { 11 | super(jsonObject); 12 | } 13 | 14 | public UnlockCondition(String jsonObject) { 15 | super(jsonObject); 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /client/bindings/java/lib/src/main/java/org/iota/types/UtxoInput.java: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package org.iota.types; 5 | 6 | import com.google.gson.JsonObject; 7 | 8 | public class UtxoInput extends AbstractObject { 9 | 10 | public UtxoInput(JsonObject jsonObject) { 11 | super(jsonObject); 12 | } 13 | 14 | public UtxoInput(String jsonObject) { 15 | super(jsonObject); 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /client/bindings/java/lib/src/main/java/org/iota/types/expections/ClientException.java: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package org.iota.types.expections; 5 | 6 | public class ClientException extends Exception { 7 | 8 | private String methodName; 9 | 10 | public ClientException(String methodName, String message) { 11 | super(message); 12 | } 13 | 14 | public String getMethodName() { 15 | return methodName; 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /client/bindings/java/lib/src/main/java/org/iota/types/expections/InitializeClientException.java: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package org.iota.types.expections; 5 | 6 | public class InitializeClientException extends Exception { 7 | 8 | public InitializeClientException(String message) { 9 | super(message); 10 | } 11 | 12 | } -------------------------------------------------------------------------------- /client/bindings/java/lib/src/main/java/org/iota/types/expections/NoFundsReceivedFromFaucetException.java: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package org.iota.types.expections; 5 | 6 | public class NoFundsReceivedFromFaucetException extends Exception { 7 | 8 | public NoFundsReceivedFromFaucetException() { 9 | super(); 10 | } 11 | 12 | } 13 | 14 | -------------------------------------------------------------------------------- /client/bindings/java/lib/src/main/java/org/iota/types/ids/AbstractId.java: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package org.iota.types.ids; 5 | 6 | import java.util.Objects; 7 | 8 | public class AbstractId { 9 | 10 | private String id; 11 | 12 | protected AbstractId(String id) { 13 | this.id = id; 14 | } 15 | 16 | @Override 17 | public boolean equals(Object o) { 18 | if (this == o) return true; 19 | if (o == null || getClass() != o.getClass()) return false; 20 | AbstractId other = (AbstractId) o; 21 | return Objects.equals(this.id, other.id); 22 | } 23 | 24 | @Override 25 | public int hashCode() { 26 | return Objects.hash(id); 27 | } 28 | 29 | @Override 30 | public String toString() { 31 | return id; 32 | } 33 | 34 | } -------------------------------------------------------------------------------- /client/bindings/java/lib/src/main/java/org/iota/types/ids/AliasId.java: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package org.iota.types.ids; 5 | 6 | public class AliasId extends AbstractId { 7 | public AliasId(String id) { 8 | super(id); 9 | } 10 | } -------------------------------------------------------------------------------- /client/bindings/java/lib/src/main/java/org/iota/types/ids/BlockId.java: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package org.iota.types.ids; 5 | 6 | public class BlockId extends AbstractId { 7 | public BlockId(String id) { 8 | super(id); 9 | } 10 | } -------------------------------------------------------------------------------- /client/bindings/java/lib/src/main/java/org/iota/types/ids/FoundryId.java: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package org.iota.types.ids; 5 | 6 | public class FoundryId extends AbstractId { 7 | public FoundryId(String id) { 8 | super(id); 9 | } 10 | } -------------------------------------------------------------------------------- /client/bindings/java/lib/src/main/java/org/iota/types/ids/MilestoneId.java: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package org.iota.types.ids; 5 | 6 | public class MilestoneId extends AbstractId { 7 | public MilestoneId(String id) { 8 | super(id); 9 | } 10 | } -------------------------------------------------------------------------------- /client/bindings/java/lib/src/main/java/org/iota/types/ids/NftId.java: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package org.iota.types.ids; 5 | 6 | public class NftId extends AbstractId { 7 | public NftId(String id) { 8 | super(id); 9 | } 10 | } -------------------------------------------------------------------------------- /client/bindings/java/lib/src/main/java/org/iota/types/ids/OutputId.java: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package org.iota.types.ids; 5 | 6 | public class OutputId extends AbstractId { 7 | public OutputId(String id) { 8 | super(id); 9 | } 10 | } -------------------------------------------------------------------------------- /client/bindings/java/lib/src/main/java/org/iota/types/ids/TransactionId.java: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package org.iota.types.ids; 5 | 6 | public class TransactionId extends AbstractId { 7 | public TransactionId(String id) { 8 | super(id); 9 | } 10 | } -------------------------------------------------------------------------------- /client/bindings/java/lib/src/main/java/org/iota/types/responses/NodeInfoResponse.java: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package org.iota.types.responses; 5 | 6 | import com.google.gson.JsonObject; 7 | 8 | public class NodeInfoResponse { 9 | 10 | private String nodeUrl; 11 | private JsonObject nodeInfo; 12 | 13 | public NodeInfoResponse(JsonObject response) { 14 | this.nodeUrl = response.get("url").getAsString(); 15 | this.nodeInfo = response.get("nodeInfo").getAsJsonObject(); 16 | } 17 | 18 | public String getNodeUrl() { 19 | return nodeUrl; 20 | } 21 | 22 | public JsonObject getNodeInfo() { 23 | return nodeInfo; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /client/bindings/java/lib/src/main/java/org/iota/types/responses/OutputIdsResponse.java: -------------------------------------------------------------------------------- 1 | // Copyright 2023 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package org.iota.types.responses; 5 | 6 | import com.google.gson.JsonArray; 7 | import com.google.gson.JsonObject; 8 | import org.iota.types.ids.OutputId; 9 | 10 | public class OutputIdsResponse { 11 | 12 | private int ledgerIndex; 13 | private String cursor; 14 | private OutputId[] items; 15 | 16 | public OutputIdsResponse(JsonObject response) { 17 | this.ledgerIndex = response.get("ledgerIndex").getAsInt(); 18 | if (!response.get("cursor").isJsonNull()) { 19 | this.cursor = response.get("cursor").getAsString(); 20 | } 21 | 22 | JsonArray items = response.getAsJsonArray("items"); 23 | this.items = new OutputId[items.size()]; 24 | for (int i = 0; i < items.size(); i++) { 25 | this.items[i] = new OutputId(items.get(i).getAsString()); 26 | } 27 | } 28 | 29 | public int getLedgerIndex() { 30 | return ledgerIndex; 31 | } 32 | 33 | public String getCursor() { 34 | return cursor; 35 | } 36 | 37 | public OutputId[] getItems() { 38 | return items; 39 | } 40 | 41 | } -------------------------------------------------------------------------------- /client/bindings/java/lib/src/main/java/org/iota/types/responses/TreasuryResponse.java: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package org.iota.types.responses; 5 | 6 | import com.google.gson.JsonObject; 7 | import org.iota.types.ids.MilestoneId; 8 | 9 | public class TreasuryResponse { 10 | 11 | private MilestoneId milestoneId; 12 | private int amount; 13 | 14 | public TreasuryResponse(JsonObject response) { 15 | milestoneId = new MilestoneId(response.get("milestoneId").getAsString()); 16 | amount = response.get("amount").getAsInt(); 17 | } 18 | 19 | public MilestoneId getMilestoneId() { 20 | return milestoneId; 21 | } 22 | 23 | public int getAmount() { 24 | return amount; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /client/bindings/java/lib/src/main/java/org/iota/types/secret/LedgerNanoSecretManager.java: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package org.iota.types.secret; 5 | 6 | import com.google.gson.JsonObject; 7 | 8 | public class LedgerNanoSecretManager extends SecretManager { 9 | private boolean isSimulator; 10 | 11 | public LedgerNanoSecretManager(boolean isSimulator) { 12 | this.isSimulator = isSimulator; 13 | } 14 | 15 | @Override 16 | public JsonObject getJson() { 17 | JsonObject o = new JsonObject(); 18 | o.addProperty("ledgerNano", isSimulator); 19 | 20 | return o; 21 | } 22 | } 23 | 24 | 25 | -------------------------------------------------------------------------------- /client/bindings/java/lib/src/main/java/org/iota/types/secret/MnemonicSecretManager.java: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package org.iota.types.secret; 5 | 6 | import com.google.gson.JsonObject; 7 | 8 | public class MnemonicSecretManager extends SecretManager { 9 | private String mnemonic; 10 | 11 | public MnemonicSecretManager(String mnemonic) { 12 | this.mnemonic = mnemonic; 13 | } 14 | 15 | @Override 16 | public JsonObject getJson() { 17 | JsonObject o = new JsonObject(); 18 | o.addProperty("mnemonic", mnemonic); 19 | 20 | return o; 21 | } 22 | } 23 | 24 | 25 | -------------------------------------------------------------------------------- /client/bindings/java/lib/src/main/java/org/iota/types/secret/PlaceholderSecretManager.java: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package org.iota.types.secret; 5 | 6 | import com.google.gson.JsonElement; 7 | import com.google.gson.JsonPrimitive; 8 | 9 | public class PlaceholderSecretManager extends SecretManager { 10 | @Override 11 | public JsonElement getJson() { 12 | return new JsonPrimitive("placeholder"); 13 | } 14 | } 15 | 16 | 17 | -------------------------------------------------------------------------------- /client/bindings/java/lib/src/main/java/org/iota/types/secret/Range.java: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package org.iota.types.secret; 5 | 6 | import com.google.gson.JsonObject; 7 | 8 | public class Range { 9 | private int start; 10 | private int end; 11 | 12 | public Range(int start, int end) { 13 | this.start = start; 14 | this.end = end; 15 | } 16 | 17 | public int getStart() { 18 | return start; 19 | } 20 | 21 | public void setStart(int start) { 22 | this.start = start; 23 | } 24 | 25 | public int getEnd() { 26 | return end; 27 | } 28 | 29 | public void setEnd(int end) { 30 | this.end = end; 31 | } 32 | 33 | public JsonObject getAsJson() { 34 | JsonObject o = new JsonObject(); 35 | o.addProperty("start", start); 36 | o.addProperty("end", end); 37 | 38 | return o; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /client/bindings/java/lib/src/main/java/org/iota/types/secret/SecretManager.java: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package org.iota.types.secret; 5 | 6 | import com.google.gson.JsonElement; 7 | 8 | public abstract class SecretManager { 9 | public abstract JsonElement getJson(); 10 | } 11 | 12 | 13 | -------------------------------------------------------------------------------- /client/bindings/java/lib/src/main/java/org/iota/types/secret/SeedSecretManager.java: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package org.iota.types.secret; 5 | 6 | import com.google.gson.JsonObject; 7 | 8 | public class SeedSecretManager extends SecretManager { 9 | 10 | private String hexSeed; 11 | 12 | public SeedSecretManager(String hexSeed) { 13 | this.hexSeed = hexSeed; 14 | } 15 | 16 | @Override 17 | public JsonObject getJson() { 18 | JsonObject o = new JsonObject(); 19 | o.addProperty("hexSeed", hexSeed); 20 | 21 | return o; 22 | } 23 | } 24 | 25 | 26 | -------------------------------------------------------------------------------- /client/bindings/java/lib/src/main/java/org/iota/types/secret/StrongholdSecretManager.java: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package org.iota.types.secret; 5 | 6 | import com.google.gson.JsonObject; 7 | 8 | public class StrongholdSecretManager extends SecretManager { 9 | 10 | private String password; 11 | private String timeout; 12 | private String snapshotPath; 13 | 14 | public StrongholdSecretManager withPassword(String password) { 15 | this.password = password; 16 | return this; 17 | } 18 | 19 | public StrongholdSecretManager withTimeout(String timeout) { 20 | this.timeout = timeout; 21 | return this; 22 | } 23 | 24 | public StrongholdSecretManager withSnapshotPath(String snapshotPath) { 25 | this.snapshotPath = snapshotPath; 26 | return this; 27 | } 28 | 29 | @Override 30 | public JsonObject getJson() { 31 | JsonObject dto = new JsonObject(); 32 | dto.addProperty("password", password); 33 | dto.addProperty("timeout", timeout); 34 | dto.addProperty("snapshotPath", snapshotPath); 35 | 36 | JsonObject o = new JsonObject(); 37 | o.add("stronghold", dto); 38 | 39 | return o; 40 | } 41 | } 42 | 43 | 44 | -------------------------------------------------------------------------------- /client/bindings/java/lib/src/main/java/org/iota/types/secret/WrongSeedConversionSecretManager.java: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package org.iota.types.secret; 5 | 6 | import org.apache.commons.codec.binary.Hex; 7 | 8 | /* 9 | An incorrect seed conversion from Java to Rust in February 2022 resulted in incorrectly derived addresses. See https://github.com/iotaledger/iota.rs/pull/800 for more details. 10 | This secret manager gives access to the funds located on the incorrectly derived addresses. 11 | */ 12 | public class WrongSeedConversionSecretManager extends SeedSecretManager { 13 | 14 | public WrongSeedConversionSecretManager(String hexSeed) { 15 | // Remove hex prefix and add it later again 16 | super("0x"+Hex.encodeHexString(hexSeed.replace("0x", "").getBytes())); 17 | } 18 | 19 | } -------------------------------------------------------------------------------- /client/bindings/java/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'iota-client' 2 | include('lib') 3 | include('examples') 4 | -------------------------------------------------------------------------------- /client/bindings/nodejs/.env.example: -------------------------------------------------------------------------------- 1 | NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1="endorse answer radar about source reunion marriage tag sausage weekend frost daring base attack because joke dream slender leisure group reason prepare broken river" 2 | NODE_URL="https://api.testnet.shimmer.network" 3 | FAUCET_URL="https://faucet.testnet.shimmer.network/api/enqueue" 4 | EXPLORER_URL="https://explorer.shimmer.network/testnet" 5 | STRONGHOLD_PASSWORD="some_hopefully_secure_password" -------------------------------------------------------------------------------- /client/bindings/nodejs/.eslintignore: -------------------------------------------------------------------------------- 1 | scripts 2 | target 3 | **/node_modules/ 4 | **/out/ 5 | **/tests/ 6 | **/dist 7 | package.json -------------------------------------------------------------------------------- /client/bindings/nodejs/.eslintrc.js: -------------------------------------------------------------------------------- 1 | const typescriptEslintRules = { 2 | '@typescript-eslint/ban-ts-comment': [ 3 | 'error', 4 | { 'ts-ignore': 'allow-with-description' }, 5 | ], 6 | '@typescript-eslint/no-empty-interface': 'off', 7 | '@typescript-eslint/no-var-requires': 'off', // cleanest way to set dotenv path 8 | }; 9 | 10 | module.exports = { 11 | env: { 12 | commonjs: true, 13 | es2019: true, 14 | }, 15 | plugins: ['@typescript-eslint'], 16 | extends: [ 17 | 'eslint:recommended', 18 | 'plugin:@typescript-eslint/recommended', 19 | 'prettier', 20 | ], 21 | parser: '@typescript-eslint/parser', 22 | parserOptions: { 23 | ecmaVersion: 12, 24 | sourceType: 'module', 25 | }, 26 | rules: typescriptEslintRules, 27 | }; 28 | -------------------------------------------------------------------------------- /client/bindings/nodejs/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | index.node 3 | **/*~ 4 | **/node_modules 5 | **/.DS_Store 6 | build 7 | out/ 8 | **/dist 9 | **/client.log 10 | stronghold 11 | package-lock.json 12 | prebuilds/ -------------------------------------------------------------------------------- /client/bindings/nodejs/.npmignore: -------------------------------------------------------------------------------- 1 | target 2 | **/*~ 3 | **/node_modules 4 | **/.DS_Store 5 | build 6 | test -------------------------------------------------------------------------------- /client/bindings/nodejs/.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | semi: true, 3 | singleQuote: true, 4 | tabWidth: 4, 5 | useTabs: false, 6 | trailingComma: 'all', 7 | bracketSpacing: true, 8 | arrowParens: 'always', 9 | }; 10 | -------------------------------------------------------------------------------- /client/bindings/nodejs/binding.gyp: -------------------------------------------------------------------------------- 1 | { 2 | "targets": [ 3 | { 4 | "target_name": "index", 5 | 'defines': [ 6 | "NAPI_VERSION=<(napi_build_version)", 7 | ], 8 | "win_delay_load_hook": "true", 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /client/bindings/nodejs/examples/01_mnemonic.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import { Client, initLogger } from '@iota/client'; 5 | 6 | // Run with command: 7 | // node ./dist/01_mnemonic.js 8 | 9 | // In this example we will generate a random BIP39 mnemonic 10 | async function run() { 11 | initLogger(); 12 | 13 | const client = new Client({}); 14 | 15 | try { 16 | const mnemonic = await client.generateMnemonic(); 17 | 18 | console.log('Mnemonic: ' + mnemonic); 19 | // Example output: 20 | // Mnemonic: endorse answer radar about source reunion marriage tag sausage weekend frost daring base attack because joke dream slender leisure group reason prepare broken river 21 | } catch (error) { 22 | console.error('Error: ', error); 23 | } 24 | } 25 | 26 | run().then(() => process.exit()); 27 | -------------------------------------------------------------------------------- /client/bindings/nodejs/examples/04_get_output.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import { Client, initLogger } from '@iota/client'; 5 | require('dotenv').config({ path: '../.env' }); 6 | 7 | // Run with command: 8 | // node ./dist/04_get_output.js 9 | 10 | // In this example we will get output from a known outputId 11 | async function run() { 12 | initLogger(); 13 | if (!process.env.NODE_URL) { 14 | throw new Error('.env NODE_URL is undefined, see .env.example'); 15 | } 16 | 17 | const client = new Client({ 18 | // Insert your node URL in the .env. 19 | nodes: [process.env.NODE_URL], 20 | localPow: true, 21 | }); 22 | 23 | try { 24 | const output = await client.getOutput( 25 | '0xa0b9ad3f5aa2bfcaed30cde6e1d572e93b7e8bb5a417f5a7ef3502889b5dbcb40000', 26 | ); 27 | console.log('Output: ', output); 28 | } catch (error) { 29 | console.error('Error: ', error); 30 | } 31 | } 32 | 33 | run().then(() => process.exit()); 34 | -------------------------------------------------------------------------------- /client/bindings/nodejs/examples/06_simple_block.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import { Client, initLogger } from '@iota/client'; 5 | require('dotenv').config({ path: '../.env' }); 6 | 7 | // Run with command: 8 | // node ./dist/06_simple_block.js 9 | 10 | // In this example we will send a block without a payload 11 | async function run() { 12 | initLogger(); 13 | if (!process.env.NODE_URL) { 14 | throw new Error('.env NODE_URL is undefined, see .env.example'); 15 | } 16 | 17 | const client = new Client({ 18 | // Insert your node URL in the .env. 19 | nodes: [process.env.NODE_URL], 20 | localPow: true, 21 | }); 22 | 23 | try { 24 | // Create block with no payload 25 | const blockIdAndBlock = await client.buildAndPostBlock(); 26 | console.log('Block:', blockIdAndBlock, '\n'); 27 | 28 | console.log( 29 | `Empty block sent: ${process.env.EXPLORER_URL}/block/${blockIdAndBlock[0]}`, 30 | ); 31 | } catch (error) { 32 | console.error('Error: ', error); 33 | } 34 | } 35 | 36 | run().then(() => process.exit()); 37 | -------------------------------------------------------------------------------- /client/bindings/nodejs/examples/07_get_block_data.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import { Client, initLogger } from '@iota/client'; 5 | require('dotenv').config({ path: '../.env' }); 6 | 7 | // Run with command: 8 | // node ./dist/07_get_block_data.js 9 | 10 | // In this example we will send a block and get the data and metadata for it 11 | async function run() { 12 | initLogger(); 13 | if (!process.env.NODE_URL) { 14 | throw new Error('.env NODE_URL is undefined, see .env.example'); 15 | } 16 | 17 | const client = new Client({ 18 | // Insert your node URL in the .env. 19 | nodes: [process.env.NODE_URL], 20 | }); 21 | 22 | try { 23 | // Create block with no payload. 24 | const blockIdAndBlock = await client.buildAndPostBlock(); 25 | console.log('Block:', blockIdAndBlock, '\n'); 26 | 27 | // Get the metadata for the block. 28 | const blockMetadata = await client.getBlockMetadata(blockIdAndBlock[0]); 29 | console.log('Block metadata: ', blockMetadata, '\n'); 30 | 31 | // Request the block by its id. 32 | const blockData = await client.getBlock(blockIdAndBlock[0]); 33 | console.log('Block data: ', blockData, '\n'); 34 | } catch (error) { 35 | console.error('Error: ', error); 36 | } 37 | } 38 | 39 | run().then(() => process.exit()); 40 | -------------------------------------------------------------------------------- /client/bindings/nodejs/examples/12_get_raw_block.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import { Client, initLogger } from '@iota/client'; 5 | require('dotenv').config({ path: '../.env' }); 6 | 7 | // Run with command: 8 | // node ./dist/12_get_raw_block.js 9 | 10 | // In this example we will get the raw bytes of a block. 11 | async function run() { 12 | initLogger(); 13 | if (!process.env.NODE_URL) { 14 | throw new Error('.env NODE_URL is undefined, see .env.example'); 15 | } 16 | 17 | const client = new Client({ 18 | // Insert your node URL in the .env. 19 | nodes: [process.env.NODE_URL], 20 | }); 21 | 22 | try { 23 | // Get a random block ID. 24 | const blockId = (await client.getTips())[0]; 25 | 26 | const rawBytes = await client.getBlockRaw(blockId); 27 | console.log('Block bytes: ', rawBytes); 28 | } catch (error) { 29 | console.error('Error: ', error); 30 | } 31 | } 32 | 33 | run().then(() => process.exit()); 34 | -------------------------------------------------------------------------------- /client/bindings/nodejs/examples/offline_signing/example_address.json: -------------------------------------------------------------------------------- 1 | ["rms1qpllaj0pyveqfkwxmnngz2c488hfdtmfrj3wfkgxtk4gtyrax0jaxzt70zy"] 2 | -------------------------------------------------------------------------------- /client/bindings/nodejs/examples/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "examples", 3 | "version": "1.0.0", 4 | "main": "dist/index.js", 5 | "private": true, 6 | "scripts": { 7 | "build": "tsc" 8 | }, 9 | "dependencies": { 10 | "@iota/client": "../", 11 | "dotenv": "^16.0.0" 12 | }, 13 | "devDependencies": { 14 | "@types/node": "^17.0.26", 15 | "typescript": "^4.6.3" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /client/bindings/nodejs/examples/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2019", 4 | "module": "commonjs", 5 | "sourceMap": true, 6 | "strict": true, 7 | "moduleResolution": "node", 8 | "importsNotUsedAsValues": "error", 9 | "noImplicitAny": true, 10 | "removeComments": true, 11 | "skipLibCheck": true, 12 | "outDir": "dist" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /client/bindings/nodejs/examples/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@iota/client@file:..": 6 | "resolved" "file:.." 7 | "version" "3.0.0-alpha.9" 8 | dependencies: 9 | "@iota/types" "^1.0.0-beta.11" 10 | "@types/node" "^18.6.4" 11 | "cargo-cp-artifact" "^0.1.5" 12 | "prebuild-install" "^7.1.1" 13 | "typescript" "^4.8.3" 14 | 15 | "@types/node@^17.0.26": 16 | "integrity" "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==" 17 | "resolved" "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz" 18 | "version" "17.0.45" 19 | 20 | "dotenv@^16.0.0": 21 | "integrity" "sha512-JvpYKUmzQhYoIFgK2MOnF3bciIZoItIIoryihy0rIA+H4Jy0FmgyKYAHCTN98P5ybGSJcIFbh6QKeJdtZd1qhA==" 22 | "resolved" "https://registry.npmjs.org/dotenv/-/dotenv-16.0.2.tgz" 23 | "version" "16.0.2" 24 | 25 | "typescript@^4.6.3": 26 | "integrity" "sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig==" 27 | "resolved" "https://registry.npmjs.org/typescript/-/typescript-4.8.3.tgz" 28 | "version" "4.8.3" 29 | -------------------------------------------------------------------------------- /client/bindings/nodejs/jest.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */ 2 | module.exports = { 3 | preset: 'ts-jest', 4 | testEnvironment: 'node', 5 | testMatch: ['/test/**/*.(test|spec).ts'], 6 | moduleNameMapper: { 7 | 'index.node': '/build/Release/index.node', 8 | }, 9 | }; 10 | -------------------------------------------------------------------------------- /client/bindings/nodejs/lib/MessageHandler.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import { sendMessageAsync, messageHandlerNew, listen } from './bindings'; 5 | import type { IClientOptions, __ClientMessages__ } from '../types'; 6 | 7 | /** The MessageHandler which sends the commands to the Rust side. */ 8 | export class MessageHandler { 9 | messageHandler: MessageHandler; 10 | 11 | constructor(options: IClientOptions) { 12 | this.messageHandler = messageHandlerNew(JSON.stringify(options)); 13 | } 14 | 15 | async sendMessage(message: __ClientMessages__): Promise { 16 | return sendMessageAsync(JSON.stringify(message), this.messageHandler); 17 | } 18 | 19 | // MQTT 20 | async listen( 21 | topics: string[], 22 | callback: (error: Error, result: string) => void, 23 | ): Promise { 24 | return listen(topics, callback, this.messageHandler); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /client/bindings/nodejs/lib/bindings.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import type { MessageHandler } from './MessageHandler'; 5 | 6 | // @ts-ignore: path is set to match runtime transpiled js path 7 | import addon = require('../../build/Release/index.node'); 8 | 9 | const { initLogger, sendMessage, messageHandlerNew, listen } = addon; 10 | 11 | const sendMessageAsync = ( 12 | message: string, 13 | handler: MessageHandler, 14 | ): Promise => 15 | new Promise((resolve, reject) => { 16 | sendMessage(message, handler, (error: Error, result: string) => { 17 | if (error) { 18 | reject(error); 19 | } else { 20 | resolve(result); 21 | } 22 | }); 23 | }); 24 | 25 | export { initLogger, sendMessageAsync, messageHandlerNew, listen }; 26 | -------------------------------------------------------------------------------- /client/bindings/nodejs/lib/constants.ts: -------------------------------------------------------------------------------- 1 | export const IOTA_BECH32_HRP = 'iota'; 2 | export const IOTA_TESTNET_BECH32_HRP = 'atoi'; 3 | export const SHIMMER_BECH32_HRP = 'smr'; 4 | export const SHIMMER_TESTNET_BECH32_HRP = 'rms'; 5 | 6 | /** BIP44 Coin Types for IOTA and Shimmer. */ 7 | export enum CoinType { 8 | IOTA = 4218, 9 | Shimmer = 4219, 10 | } 11 | -------------------------------------------------------------------------------- /client/bindings/nodejs/lib/index.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | export * from './MessageHandler'; 5 | export * from './Client'; 6 | export * from './constants'; 7 | export * from './utils'; 8 | export * from './logger'; 9 | export * from '../types'; 10 | -------------------------------------------------------------------------------- /client/bindings/nodejs/lib/logger.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import type { ILoggerConfig } from '../types/loggerConfig'; 5 | import { initLogger as initLoggerBinding } from './bindings'; 6 | 7 | const defaultLoggerConfig: ILoggerConfig = { 8 | colorEnabled: true, 9 | name: './client.log', 10 | levelFilter: 'debug', 11 | }; 12 | 13 | /** Initialize logger, if no arguments are provided a default config will be used. */ 14 | export const initLogger = (config: ILoggerConfig = defaultLoggerConfig) => 15 | initLoggerBinding(JSON.stringify(config)); 16 | -------------------------------------------------------------------------------- /client/bindings/nodejs/lib/utils.ts: -------------------------------------------------------------------------------- 1 | /** Convert UTF8 string to an array of bytes */ 2 | export const utf8ToBytes = (utf8: string) => { 3 | const utf8Encode = new TextEncoder(); 4 | return Array.from(utf8Encode.encode(utf8)); 5 | }; 6 | 7 | /** Convert hex encoded string to UTF8 string */ 8 | export const hexToUtf8 = (hex: string) => 9 | decodeURIComponent(hex.replace('0x', '').replace(/[0-9a-f]{2}/g, '%$&')); 10 | 11 | /** Convert UTF8 string to hex encoded string */ 12 | export const utf8ToHex = (utf8: string) => 13 | '0x' + Buffer.from(utf8, 'utf8').toString('hex'); 14 | -------------------------------------------------------------------------------- /client/bindings/nodejs/scripts/move-artifact.js: -------------------------------------------------------------------------------- 1 | const { existsSync, mkdirSync, renameSync } = require('fs'); 2 | const { resolve } = require('path'); 3 | 4 | // Prebuild requires that the binary be in `build/Release` as though it was built with node-gyp 5 | 6 | const moveArtifact = () => { 7 | const path = resolve(__dirname, '../build/Release'); 8 | 9 | if (!existsSync(path)) { 10 | mkdirSync(path, { recursive: true }); 11 | } 12 | renameSync(resolve(__dirname, '../index.node'), resolve(path, 'index.node')); 13 | }; 14 | 15 | module.exports = moveArtifact; 16 | -------------------------------------------------------------------------------- /client/bindings/nodejs/scripts/neon-build.js: -------------------------------------------------------------------------------- 1 | const { resolve } = require('path'); 2 | const { spawnSync } = require('child_process'); 3 | const moveArtifact = require('./move-artifact'); 4 | 5 | // Passing "--prepack 'yarn build:neon'" causes problems on Windows, so this is a workaround 6 | 7 | const { status } = spawnSync(process.platform === 'win32' ? 'yarn.cmd' : 'yarn', ['build:neon'], { 8 | stdio: 'inherit', 9 | cwd: resolve(__dirname, '../'), 10 | }); 11 | 12 | if (status === null) { 13 | process.exit(1); 14 | } else if (status > 0) { 15 | process.exit(status); 16 | } 17 | 18 | moveArtifact(); 19 | -------------------------------------------------------------------------------- /client/bindings/nodejs/scripts/strip.js: -------------------------------------------------------------------------------- 1 | const { resolve } = require('path'); 2 | const { spawnSync } = require('child_process'); 3 | 4 | // Based on https://github.com/prebuild/prebuild/blob/master/strip.js 5 | // Prebuild requires that the binary is in `build/Release` as though it was built with node-gyp 6 | 7 | const binaryPath = resolve(__dirname, '../build/Release/index.node'); 8 | const stripArgs = process.platform === 'darwin' ? '-Sx' : '--strip-all'; 9 | spawnSync('strip', [stripArgs, binaryPath], { stdio: 'inherit' }); 10 | -------------------------------------------------------------------------------- /client/bindings/nodejs/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | #![allow(clippy::needless_borrow)] 5 | 6 | mod message_handler; 7 | 8 | use fern_logger::{logger_init, LoggerConfig, LoggerOutputConfigBuilder}; 9 | use neon::prelude::*; 10 | use once_cell::sync::Lazy; 11 | use tokio::runtime::Runtime; 12 | 13 | pub use self::message_handler::*; 14 | 15 | pub static RUNTIME: Lazy = Lazy::new(|| Runtime::new().unwrap()); 16 | 17 | pub fn init_logger(mut cx: FunctionContext) -> JsResult { 18 | let config = cx.argument::(0)?.value(&mut cx); 19 | let output_config: LoggerOutputConfigBuilder = serde_json::from_str(&config).expect("invalid logger config"); 20 | let config = LoggerConfig::build().with_output(output_config).finish(); 21 | logger_init(config).expect("failed to init logger"); 22 | Ok(cx.undefined()) 23 | } 24 | 25 | #[neon::main] 26 | fn main(mut cx: ModuleContext) -> NeonResult<()> { 27 | // Message handler methods. 28 | cx.export_function("sendMessage", message_handler::send_message)?; 29 | cx.export_function("messageHandlerNew", message_handler::message_handler_new)?; 30 | 31 | // MQTT 32 | cx.export_function("listen", message_handler::listen)?; 33 | 34 | cx.export_function("initLogger", init_logger)?; 35 | Ok(()) 36 | } 37 | -------------------------------------------------------------------------------- /client/bindings/nodejs/test/fixtures/addresses.ts: -------------------------------------------------------------------------------- 1 | export const addresses = [ 2 | 'rms1qpllaj0pyveqfkwxmnngz2c488hfdtmfrj3wfkgxtk4gtyrax0jaxzt70zy', 3 | 'rms1qzzk86qv30l4e85ljtccxa0ruy8y7u8zn2dle3g8dv2tl2m4cu227a7n2wj', 4 | 'rms1qqjrtmslm36l3lyd8086w9qdxd9mudu2z2qyywlltpycn2ftxsdmu9ulj47', 5 | 'rms1qzz75j5h7vd5melxwersz49jja36m2vvnawedu0l6rlhg70ylzqp52lx8zf', 6 | 'rms1qzvs2rvq5ef79vhuel354mnvzfz049gyyf808zmjculuatt56u92vc4v4p3', 7 | 'rms1qpk0dj5lmv5r8d64f3x0qwx3jccredwa42xscdreqma73f3dxymaqdy645t', 8 | 'rms1qqlp6nurrz459jvvvuhv6t965v6cmlata57kf6auv6955uyp77uyw0egzgn', 9 | 'rms1qq2tu523zqzjxgdl69au8a9yewmd9ztctssv40dsv7lfd0tp36w4xdfzcyr', 10 | 'rms1qpw904c253cc9yn2dkhxx89u6r5j9vzezfatchrlugrkcvvhed3hckx6h2u', 11 | 'rms1qpa646cegkqsx9eht793nmux2vjwa63jrenqe87xq8j5wysfhu4l28k4ep9', 12 | ]; 13 | -------------------------------------------------------------------------------- /client/bindings/nodejs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": ["es2019", "DOM"], 4 | "declaration": true, 5 | "target": "es2019", 6 | "module": "commonjs", 7 | "sourceMap": true, 8 | "strict": true, 9 | "moduleResolution": "node", 10 | "importsNotUsedAsValues": "error", 11 | "noImplicitAny": true, 12 | "preserveConstEnums": true, 13 | "resolveJsonModule": true, 14 | "outDir": "out" 15 | }, 16 | "include": ["lib/**/*", "types/**/*", "test"] 17 | } 18 | -------------------------------------------------------------------------------- /client/bindings/nodejs/types/blockId.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | /** A block identifier, the BLAKE2b-256 hash of the block bytes. 5 | * See for more information. 6 | */ 7 | export type BlockId = string; 8 | -------------------------------------------------------------------------------- /client/bindings/nodejs/types/buildBlockOptions.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import type { IUTXOInput, OutputTypes } from '@iota/types'; 5 | import type { CoinType } from '../lib'; 6 | import type { IRange } from './range'; 7 | import type { Burn } from './burn'; 8 | 9 | /** Options to build a new block, possibly with payloads */ 10 | export interface IBuildBlockOptions { 11 | coinType?: CoinType; 12 | accountIndex?: number; 13 | initialAddressIndex?: number; 14 | inputs?: IUTXOInput[]; 15 | inputRange?: IRange; 16 | /** Bech32 encoded output address and amount */ 17 | output?: IClientBlockBuilderOutputAddress; 18 | /** Hex encoded output address and amount */ 19 | outputHex?: IClientBlockBuilderOutputAddress; 20 | outputs?: OutputTypes[]; 21 | customRemainderAddress?: string; 22 | tag?: string; 23 | data?: string; 24 | /** Parent block IDs */ 25 | parents?: string[]; 26 | /** Explicit burning of aliases, nfts, foundries and native tokens */ 27 | burn?: Burn; 28 | } 29 | 30 | /** Address with base coin amount */ 31 | export interface IClientBlockBuilderOutputAddress { 32 | address: string; 33 | amount: string; 34 | } 35 | -------------------------------------------------------------------------------- /client/bindings/nodejs/types/burn.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2023 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import type { INativeToken } from '@iota/types'; 5 | 6 | /** A DTO for [`Burn`] */ 7 | export interface Burn { 8 | /** Aliases to burn */ 9 | aliases?: string[]; 10 | /** NFTs to burn */ 11 | nfts?: string[]; 12 | /** Foundries to burn */ 13 | foundries?: string[]; 14 | /** Amounts of native tokens to burn */ 15 | nativeTokens?: INativeToken[]; 16 | } 17 | -------------------------------------------------------------------------------- /client/bindings/nodejs/types/generateAddressesOptions.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | import type { CoinType } from '../lib'; 4 | import type { IRange } from './range'; 5 | 6 | /** 7 | * Input options for GenerateAddresses 8 | */ 9 | export interface IGenerateAddressesOptions { 10 | coinType?: CoinType; 11 | accountIndex?: number; 12 | range?: IRange; 13 | /** 14 | * Internal addresses 15 | */ 16 | internal?: boolean; 17 | /** 18 | * Bech32 human readable part 19 | */ 20 | bech32Hrp?: string; 21 | options?: IGenerateAddressOptions; 22 | } 23 | 24 | /** 25 | * Options provided to Generate Address 26 | */ 27 | export interface IGenerateAddressOptions { 28 | /** 29 | * Display the address on ledger devices. 30 | */ 31 | ledgerNanoPrompt: boolean; 32 | } 33 | -------------------------------------------------------------------------------- /client/bindings/nodejs/types/index.ts: -------------------------------------------------------------------------------- 1 | export * from './blockId'; 2 | export * from './bridge'; 3 | export * from './buildBlockOptions'; 4 | export * from './burn'; 5 | export * from './clientOptions'; 6 | export * from './generateAddressesOptions'; 7 | export * from './ledgerNanoStatus'; 8 | export * from './network'; 9 | export * from './nodeInfo'; 10 | export * from './outputIdsResponse'; 11 | export * from './outputBuilderOptions'; 12 | export * from './preparedTransactionData'; 13 | export * from './queryParameters'; 14 | export * from './range'; 15 | export * from './secretManager'; 16 | -------------------------------------------------------------------------------- /client/bindings/nodejs/types/ledgerNanoStatus.ts: -------------------------------------------------------------------------------- 1 | /** The status of a Ledger Nano */ 2 | export interface LedgerNanoStatus { 3 | connected: boolean; 4 | locked: boolean; 5 | blindSigningEnabled: boolean; 6 | app?: LedgerApp; 7 | device?: LedgerDeviceType; 8 | bufferSize?: number; 9 | } 10 | 11 | /** The current opened app */ 12 | export interface LedgerApp { 13 | name: string; 14 | version: string; 15 | } 16 | 17 | /** The Ledger Device Type */ 18 | export enum LedgerDeviceType { 19 | LedgerNanoS = 'ledgerNanoS', 20 | LedgerNanoX = 'ledgerNanoX', 21 | LedgerNanoSPlus = 'ledgerNanoSPlus', 22 | } 23 | -------------------------------------------------------------------------------- /client/bindings/nodejs/types/loggerConfig.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | /** Logger output configuration. */ 5 | export interface ILoggerConfig { 6 | /** Name of an output file, or `stdout` for standard output.*/ 7 | name?: string; 8 | /** Log level filter of an output.*/ 9 | levelFilter?: 'off' | 'error' | 'warn' | 'info' | 'debug' | 'trace'; 10 | /** Log target filters of an output.*/ 11 | targetFilter?: string[]; 12 | /** Log target exclusions of an output.*/ 13 | targetExclusions?: string[]; 14 | /** Color flag of an output.*/ 15 | colorEnabled?: boolean; 16 | } 17 | -------------------------------------------------------------------------------- /client/bindings/nodejs/types/nodeInfo.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | import type { INodeInfo } from '@iota/types'; 4 | 5 | /** NodeInfo wrapper which contains the node info and the url from the node (useful when multiple nodes are used) */ 6 | export interface INodeInfoWrapper { 7 | /** The node info */ 8 | nodeInfo: INodeInfo; 9 | /** The url of the node */ 10 | url: string; 11 | } 12 | -------------------------------------------------------------------------------- /client/bindings/nodejs/types/outputBuilderOptions/aliasOutputOptions.ts: -------------------------------------------------------------------------------- 1 | import type { FeatureTypes, HexEncodedString } from '@iota/types'; 2 | import type { IBasicOutputBuilderOptions } from './basicOutputOptions'; 3 | 4 | /** 5 | * Options for building an Alias Output 6 | */ 7 | export interface IAliasOutputBuilderOptions extends IBasicOutputBuilderOptions { 8 | aliasId: HexEncodedString; 9 | stateIndex?: number; 10 | stateMetadata?: HexEncodedString; 11 | foundryCounter?: number; 12 | immutableFeatures?: FeatureTypes[]; 13 | } 14 | -------------------------------------------------------------------------------- /client/bindings/nodejs/types/outputBuilderOptions/basicOutputOptions.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | FeatureTypes, 3 | INativeToken, 4 | UnlockConditionTypes, 5 | } from '@iota/types'; 6 | 7 | /** 8 | * Options for building a Basic Output 9 | */ 10 | export interface IBasicOutputBuilderOptions { 11 | /** 12 | * If not provided, minimum storage deposit will be used 13 | */ 14 | amount?: string; 15 | /** 16 | * The native tokens to be held by the output. 17 | */ 18 | nativeTokens?: INativeToken[]; 19 | /** 20 | * The unlock conditions for the output. 21 | */ 22 | unlockConditions: UnlockConditionTypes[]; 23 | /** 24 | * Features to be contained by the output. 25 | */ 26 | features?: FeatureTypes[]; 27 | } 28 | -------------------------------------------------------------------------------- /client/bindings/nodejs/types/outputBuilderOptions/foundryOutputOptions.ts: -------------------------------------------------------------------------------- 1 | import type { FeatureTypes, ISimpleTokenScheme } from '@iota/types'; 2 | import type { IBasicOutputBuilderOptions } from './basicOutputOptions'; 3 | 4 | /** 5 | * Options for building a Foundry Output 6 | */ 7 | export interface IFoundryOutputBuilderOptions 8 | extends IBasicOutputBuilderOptions { 9 | /** 10 | * The serial number of the foundry with respect to the controlling alias. 11 | */ 12 | serialNumber: number; 13 | tokenScheme: ISimpleTokenScheme; 14 | immutableFeatures?: FeatureTypes[]; 15 | } 16 | -------------------------------------------------------------------------------- /client/bindings/nodejs/types/outputBuilderOptions/index.ts: -------------------------------------------------------------------------------- 1 | import type { IBasicOutputBuilderOptions } from './basicOutputOptions'; 2 | import type { IAliasOutputBuilderOptions } from './aliasOutputOptions'; 3 | import type { IFoundryOutputBuilderOptions } from './foundryOutputOptions'; 4 | import type { INftOutputBuilderOptions } from './nftOutputOptions'; 5 | 6 | export { 7 | IBasicOutputBuilderOptions, 8 | IAliasOutputBuilderOptions, 9 | IFoundryOutputBuilderOptions, 10 | INftOutputBuilderOptions, 11 | }; 12 | -------------------------------------------------------------------------------- /client/bindings/nodejs/types/outputBuilderOptions/nftOutputOptions.ts: -------------------------------------------------------------------------------- 1 | import type { FeatureTypes, HexEncodedString } from '@iota/types'; 2 | import type { IBasicOutputBuilderOptions } from './basicOutputOptions'; 3 | 4 | /** 5 | * Options for building an Nft Output 6 | */ 7 | export interface INftOutputBuilderOptions extends IBasicOutputBuilderOptions { 8 | nftId: HexEncodedString; 9 | immutableFeatures?: FeatureTypes[]; 10 | } 11 | -------------------------------------------------------------------------------- /client/bindings/nodejs/types/outputIdsResponse.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2023 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | /** 5 | * OutputIdsResponse. 6 | */ 7 | export interface OutputIdsResponse { 8 | ledgerIndex: number; 9 | cursor?: string; 10 | items: string[]; 11 | } 12 | -------------------------------------------------------------------------------- /client/bindings/nodejs/types/range.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | /** A range with start and end values. */ 5 | export interface IRange { 6 | start: number; 7 | end: number; 8 | } 9 | -------------------------------------------------------------------------------- /client/bindings/nodejs/types/secretManager.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | /** Secret manager that uses a Ledger Nano hardware wallet or Speculos simulator. */ 5 | export interface LedgerNanoSecretManager { 6 | /** boolean indicates whether it's a simulator or not. */ 7 | ledgerNano: boolean; 8 | } 9 | 10 | /** Secret manager that uses a mnemonic in plain memory. It's not recommended for production use. Use LedgerNano or Stronghold instead.. */ 11 | export interface MnemonicSecretManager { 12 | mnemonic: string; 13 | } 14 | 15 | /** Secret manager that uses Stronghold. */ 16 | export interface StrongholdSecretManager { 17 | stronghold: { 18 | password?: string; 19 | snapshotPath: string; 20 | }; 21 | } 22 | 23 | /** Supported secret managers */ 24 | export type SecretManager = 25 | | LedgerNanoSecretManager 26 | | MnemonicSecretManager 27 | | StrongholdSecretManager; 28 | -------------------------------------------------------------------------------- /client/bindings/python/.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | dist 3 | iota_client.egg-info 4 | .tox 5 | iota_client_venv -------------------------------------------------------------------------------- /client/bindings/python/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 7 | 8 | 21 | 22 | ## 1.0.0-rc.3 - 2023-MM-DD 23 | 24 | ### Added 25 | 26 | - `Client::hash_transaction_essence()`; 27 | 28 | ### Changed 29 | 30 | - Changes from the Rust library; 31 | - `Client::build_alias_output()` state_metadata parameter is now a string; 32 | 33 | ### Fixed 34 | 35 | - Error raising; 36 | - Don't panic for wrong messages; 37 | 38 | ## 1.0.0-rc.2 - 2023-02-09 39 | 40 | ### Added 41 | 42 | - `NodeCoreAPI::get_included_block_metadata`; 43 | - `SeedSecretManager` class; 44 | 45 | ### Changed 46 | 47 | - Updated dependencies; 48 | 49 | ## 1.0.0-rc.1 - 2022-12-14 50 | 51 | Initial release of the Python bindings. -------------------------------------------------------------------------------- /client/bindings/python/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "iota-client-python" 3 | version = "1.0.0-rc.3" 4 | authors = [ "IOTA Stiftung" ] 5 | edition = "2021" 6 | description = "Python bindings for the IOTA client library" 7 | documentation = "https://wiki.iota.org/iota.rs/welcome" 8 | homepage = "https://www.iota.org/" 9 | repository = "https://github.com/iotaledger/iota.rs" 10 | license = "Apache-2.0" 11 | keywords = [ "iota", "tangle", "client", "python" ] 12 | categories = [ "cryptography::cryptocurrencies" ] 13 | publish = false 14 | 15 | [lib] 16 | name = "iota_client" 17 | crate-type = [ "cdylib" ] 18 | 19 | [dependencies] 20 | iota-client = { path = "../../", default-features = false, features = [ "ledger_nano", "message_interface", "stronghold", "tls" ] } 21 | 22 | fern-logger = { version = "0.5.0", default-features = false } 23 | futures = { version = "0.3.26", default-features = false } 24 | once_cell = { version = "1.17.1", default-features = false, features = [ "std" ] } 25 | pyo3 = { version = "0.18.1", default-features = false, features = [ "macros", "extension-module" ] } 26 | serde_json = { version = "1.0.94", default-features = false } 27 | tokio = { version = "1.26.0", default-features = false, features = [ "macros" ] } 28 | -------------------------------------------------------------------------------- /client/bindings/python/MANIFEST.in: -------------------------------------------------------------------------------- 1 | include pyproject.toml Cargo.toml 2 | recursive-include src * -------------------------------------------------------------------------------- /client/bindings/python/examples/00_get_info.py: -------------------------------------------------------------------------------- 1 | from iota_client import IotaClient 2 | 3 | # Create an IotaClient instance 4 | client = IotaClient({'nodes': ['https://api.testnet.shimmer.network']}) 5 | 6 | # Get the node info 7 | node_info = client.get_info() 8 | print(f'{node_info}') 9 | -------------------------------------------------------------------------------- /client/bindings/python/examples/01_mnemonic.py: -------------------------------------------------------------------------------- 1 | from iota_client import IotaClient 2 | 3 | # Create an IotaClient instance 4 | client = IotaClient() 5 | 6 | # Generate a random BIP39 mnemonic 7 | mnemonic = client.generate_mnemonic() 8 | print(f'Mnemonic: {mnemonic}') 9 | -------------------------------------------------------------------------------- /client/bindings/python/examples/03_get_address_outputs.py: -------------------------------------------------------------------------------- 1 | from iota_client import IotaClient 2 | 3 | # Create an IotaClient instance 4 | client = IotaClient({'nodes': ['https://api.testnet.shimmer.network']}) 5 | 6 | # Get output ids of basic outputs that can be controlled by this address without further unlock constraints 7 | output_ids_response = client.basic_output_ids([{"address": 'rms1qpllaj0pyveqfkwxmnngz2c488hfdtmfrj3wfkgxtk4gtyrax0jaxzt70zy'}, 8 | {"hasExpiration": False}, 9 | {"hasTimelock": False}, 10 | {"hasStorageDepositReturn": False}, ]) 11 | print(f'{output_ids_response}') 12 | 13 | # Get the outputs by their id 14 | outputs = client.get_outputs(output_ids_response['items']) 15 | print(f'{outputs}') 16 | -------------------------------------------------------------------------------- /client/bindings/python/examples/04_get_output.py: -------------------------------------------------------------------------------- 1 | from iota_client import IotaClient 2 | 3 | # Create an IotaClient instance 4 | client = IotaClient({'nodes': ['https://api.testnet.shimmer.network']}) 5 | 6 | # Get an outputs by its id 7 | output = client.get_output('0x1e857d380f813d8035e487b6dfd2ff4740b6775273ba1b576f01381ba2a1a44c0000') 8 | print(f'{output}') 9 | -------------------------------------------------------------------------------- /client/bindings/python/examples/05_get_address_balance.py: -------------------------------------------------------------------------------- 1 | from iota_client import IotaClient 2 | 3 | # Create an IotaClient instance 4 | client = IotaClient({'nodes': ['https://api.testnet.shimmer.network']}) 5 | 6 | address = 'rms1qpllaj0pyveqfkwxmnngz2c488hfdtmfrj3wfkgxtk4gtyrax0jaxzt70zy' 7 | 8 | # Get output ids of basic outputs that can be controlled by this address without further unlock constraints 9 | output_ids_response = client.basic_output_ids([{"address": address}, 10 | {"hasExpiration": False}, 11 | {"hasTimelock": False}, 12 | {"hasStorageDepositReturn": False}, ]) 13 | print(f'{output_ids_response}') 14 | 15 | # Get the outputs by their id 16 | outputs = client.get_outputs(output_ids_response['items']) 17 | print(f'{outputs}') 18 | 19 | 20 | # Calculate the total amount and native tokens 21 | total_amount = 0 22 | native_tokens = [] 23 | for output_response in outputs: 24 | output = output_response['output'] 25 | total_amount += int(output['amount']) 26 | if 'nativeTokens' in output: 27 | native_tokens.append(output['nativeTokens']) 28 | 29 | print( 30 | f'Outputs controlled by {address} have {total_amount} glow and native tokens: {native_tokens}') 31 | -------------------------------------------------------------------------------- /client/bindings/python/examples/06_simple_block.py: -------------------------------------------------------------------------------- 1 | from iota_client import IotaClient 2 | 3 | # Create an IotaClient instance 4 | client = IotaClient({'nodes': ['https://api.testnet.shimmer.network']}) 5 | 6 | # Create and post a block without payload 7 | block = client.build_and_post_block() 8 | print(f'{block}') 9 | -------------------------------------------------------------------------------- /client/bindings/python/examples/07_get_block_data.py: -------------------------------------------------------------------------------- 1 | from iota_client import IotaClient 2 | 3 | # Create an IotaClient instance 4 | client = IotaClient({'nodes': ['https://api.testnet.shimmer.network']}) 5 | 6 | # Create and post a block without payload 7 | blockIdAndBlock = client.build_and_post_block() 8 | print(f'{blockIdAndBlock}') 9 | 10 | # Get the metadata for the block 11 | metadata = client.get_block_metadata(blockIdAndBlock[0]) 12 | print(f'{metadata}') 13 | 14 | # Request the block by its id 15 | block = client.get_block_data(blockIdAndBlock[0]) 16 | print(f'{block}') 17 | -------------------------------------------------------------------------------- /client/bindings/python/examples/08_data_block.py: -------------------------------------------------------------------------------- 1 | from iota_client import IotaClient 2 | 3 | # Create an IotaClient instance 4 | client = IotaClient({'nodes': ['https://api.testnet.shimmer.network']}) 5 | 6 | options = { 7 | # `hello` hex encoded 8 | "tag": '0x68656c6c6f', 9 | "data": '0x68656c6c6f', 10 | } 11 | 12 | # Create and post a block with a tagged data payload 13 | block = client.build_and_post_block(None, options) 14 | print(f'{block}') 15 | -------------------------------------------------------------------------------- /client/bindings/python/examples/09_transaction.py: -------------------------------------------------------------------------------- 1 | from iota_client import IotaClient, MnemonicSecretManager 2 | 3 | # Create an IotaClient instance 4 | client = IotaClient({'nodes': ['https://api.testnet.shimmer.network']}) 5 | 6 | secret_manager = MnemonicSecretManager("flame fever pig forward exact dash body idea link scrub tennis minute " + 7 | "surge unaware prosper over waste kitten ceiling human knife arch situate civil") 8 | 9 | options = { 10 | "output": { 11 | "address": 'rms1qzpf0tzpf8yqej5zyhjl9k3km7y6j0xjnxxh7m2g3jtj2z5grej67sl6l46', 12 | "amount": '1000000', 13 | } 14 | } 15 | 16 | # Create and post a block with a transaction 17 | block = client.build_and_post_block(secret_manager, options) 18 | print(f'{block}') 19 | -------------------------------------------------------------------------------- /client/bindings/python/examples/README.md: -------------------------------------------------------------------------------- 1 | # Guild to Run the Python Examples 2 | 3 | ## Build the wheel file 4 | 5 | - Go to `iota.rs/bindings/python` 6 | - `python3 setup.py bdist_wheel` 7 | 8 | ## Create a virtual environment and use it (optional) 9 | 10 | - `python3 -m venv .venv` 11 | - `source .venv/bin/activate` 12 | 13 | ## Install the wheel file 14 | 15 | `python3 -m pip install dist/[your built wheel file]` 16 | 17 | Example: 18 | 19 | - `python3 -m pip install dist/iota_client-0.1.0-cp310-cp310-linux_x86_64.whl` 20 | 21 | Use `--force-reinstall` when already installed 22 | 23 | Example: 24 | 25 | - `python3 -m pip install dist/iota_client-0.1.0-cp310-cp310-linux_x86_64.whl --force-reinstall` 26 | 27 | ## Run examples 28 | 29 | `python3 example/[example file]` 30 | 31 | Example: 32 | 33 | - `python3 examples/00_get_info.py` 34 | 35 | ## To deactivate the virtual environment (optional) 36 | 37 | - `deactivate` 38 | 39 | ## All in one example 40 | 41 | `python3 setup.py bdist_wheel && python3 -m pip install dist/iota_client-0.1.0-cp310-cp310-linux_x86_64.whl --force-reinstall && python3 examples/00_get_info.py` 42 | 43 | ## Build docs 44 | 45 | `pydoc-markdown -p iota_client > README.md` -------------------------------------------------------------------------------- /client/bindings/python/examples/build_foundry.py: -------------------------------------------------------------------------------- 1 | from iota_client import IotaClient, MnemonicSecretManager 2 | 3 | # Create an IotaClient instance 4 | client = IotaClient({'nodes': ['https://api.testnet.shimmer.network']}) 5 | 6 | # Configure foundry output 7 | # TODO: replace with your own values 8 | serial_number = 1 9 | token_scheme = { 'type': 0, 'meltedTokens': '0x0', 'mintedTokens': '0x32', 'maximumSupply': '0x64' } 10 | unlock_conditions = [{ 'type': 6, 'address': { 'type': 8, 'aliasId': "0xa5c28d5baa951de05e375fb19134ea51a918f03acc2d0cee011a42b298d3effa" }}] 11 | 12 | # Configure and build and foundry output 13 | output = client.build_foundry_output( 14 | 1, 15 | token_scheme, 16 | unlock_conditions, 17 | ) 18 | 19 | # Print the output 20 | print(output) 21 | 22 | -------------------------------------------------------------------------------- /client/bindings/python/examples/get_raw_block.py: -------------------------------------------------------------------------------- 1 | from iota_client import IotaClient, MnemonicSecretManager 2 | 3 | # Create an IotaClient instance 4 | client = IotaClient({'nodes': ['https://api.testnet.shimmer.network']}) 5 | 6 | # Create and post a block without payload 7 | block_id = client.build_and_post_block()[0] 8 | print(f'{block_id}') 9 | 10 | # Get block raw 11 | block_raw = client.get_block_raw(block_id) 12 | 13 | # Print block raw 14 | print(f'{block_raw}') -------------------------------------------------------------------------------- /client/bindings/python/examples/ledger_nano.py: -------------------------------------------------------------------------------- 1 | from iota_client import IotaClient, LedgerNanoSecretManager 2 | 3 | # In this example we will get the ledger status and generate an address 4 | # To use the ledger nano simulator clone https://github.com/iotaledger/ledger-shimmer-app, run `git submodule init && git submodule update --recursive`, 5 | # then `./build.sh -m nanos|nanox|nanosplus -s` and use `True` in `LedgerNanoSecretManager(True)`. 6 | 7 | # Create an IotaClient instance 8 | client = IotaClient({'nodes': ['https://api.testnet.shimmer.network']}) 9 | 10 | is_simulator = True 11 | 12 | secret_manager = LedgerNanoSecretManager(is_simulator) 13 | 14 | # Get the Ledger Nano status. 15 | ledger_nano_status = client.get_ledger_nano_status(is_simulator) 16 | 17 | print(f'Ledger Nano status: {ledger_nano_status}') 18 | 19 | # Generate public address with custom account index and range. 20 | address = client.generate_addresses(secret_manager, { 21 | "accountIndex": 0, 22 | "range": { 23 | "start": 0, 24 | "end": 1, 25 | }, 26 | }) 27 | 28 | print(f'Address: {address[0]}') -------------------------------------------------------------------------------- /client/bindings/python/examples/logger.py: -------------------------------------------------------------------------------- 1 | from iota_client import IotaClient, init_logger 2 | import json 3 | 4 | # Create the log configuration, the log will be outputted in 'iota.rs.log' 5 | log_config = { 6 | 'name': 'iota.rs.log', 7 | 'levelFilter': 'debug', 8 | 'targetExclusions': ["h2", "hyper", "rustls"] 9 | } 10 | 11 | log_config_str = json.dumps(log_config) 12 | 13 | init_logger(log_config_str) 14 | 15 | # Create an IotaClient instance 16 | client = IotaClient({'nodes': ['https://api.testnet.shimmer.network']}) 17 | 18 | # Get the node info 19 | node_info = client.get_info() 20 | print(f'{node_info}') 21 | -------------------------------------------------------------------------------- /client/bindings/python/examples/post_raw_block.py: -------------------------------------------------------------------------------- 1 | from iota_client import IotaClient, MnemonicSecretManager 2 | 3 | # Create an IotaClient instance 4 | client = IotaClient({'nodes': ['https://api.testnet.shimmer.network']}) 5 | 6 | # Create and post a block without payload 7 | block_id = client.build_and_post_block()[0] 8 | blockBytes = client.get_block_raw(block_id) 9 | 10 | # Post raw block 11 | result = client.post_block_raw(blockBytes) 12 | 13 | # Print block raw 14 | print(f'{result}') -------------------------------------------------------------------------------- /client/bindings/python/examples/stronghold.py: -------------------------------------------------------------------------------- 1 | from iota_client import IotaClient, StrongholdSecretManager 2 | 3 | # Create an IotaClient instance 4 | client = IotaClient({'nodes': ['https://api.testnet.shimmer.network']}) 5 | 6 | secret_manager = StrongholdSecretManager("client.stronghold", "some_hopefully_secure_password") 7 | 8 | # Store the mnemonic in the Stronghold snapshot, this needs to be done only the first time. 9 | # The mnemonic can't be retrieved from the Stronghold file, so make a backup in a secure place! 10 | result = client.store_mnemonic(secret_manager, "flame fever pig forward exact dash body idea link scrub tennis minute " + 11 | "surge unaware prosper over waste kitten ceiling human knife arch situate civil") 12 | 13 | # Generate public address with custom account index and range. 14 | address = client.generate_addresses(secret_manager, { 15 | "account_index": 0, 16 | "range": { 17 | "start": 0, 18 | "end": 1, 19 | }, 20 | }) 21 | 22 | print(f'Address: {address[0]}') -------------------------------------------------------------------------------- /client/bindings/python/iota_client/__init__.py: -------------------------------------------------------------------------------- 1 | from .iota_client import * 2 | from .client import IotaClient 3 | from .secret_manager import * -------------------------------------------------------------------------------- /client/bindings/python/iota_client/_base_api.py: -------------------------------------------------------------------------------- 1 | from iota_client.common import send_message_routine 2 | 3 | 4 | class BaseAPI(): 5 | 6 | @send_message_routine 7 | def send_message(self, name, data=None): 8 | message = { 9 | 'name': name, 10 | 'data': data 11 | } 12 | 13 | return message 14 | -------------------------------------------------------------------------------- /client/bindings/python/iota_client/common.py: -------------------------------------------------------------------------------- 1 | import iota_client 2 | import json 3 | from json import dumps 4 | 5 | 6 | def send_message_routine(func): 7 | """The routine of dump json string and call send_message() 8 | """ 9 | def wrapper(*args, **kwargs): 10 | message = func(*args, **kwargs) 11 | message = dumps(message) 12 | 13 | # Send message to the Rust library 14 | response = iota_client.send_message(args[0].handle, message) 15 | 16 | json_response = json.loads(response) 17 | 18 | if "type" in json_response: 19 | if json_response["type"] == "error": 20 | raise IotaClientError(json_response['payload']) 21 | 22 | if "payload" in json_response: 23 | return json_response['payload'] 24 | else: 25 | return response 26 | return wrapper 27 | 28 | class IotaClientError(Exception): 29 | """iota-client error""" 30 | pass 31 | -------------------------------------------------------------------------------- /client/bindings/python/pydoc-markdown.yml: -------------------------------------------------------------------------------- 1 | loaders: 2 | - type: python 3 | processors: 4 | - type: filter 5 | skip_empty_modules: true 6 | - type: smart 7 | - type: crossref 8 | renderer: 9 | type: docusaurus 10 | docs_base_path: ./docs 11 | relative_output_path: references 12 | 13 | markdown: 14 | use_fixed_header_levels: true 15 | header_level_by_type: 16 | Module: 1 17 | Class: 2 18 | Method: 3 19 | Function: 3 20 | Data: 3 -------------------------------------------------------------------------------- /client/bindings/python/pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["maturin>=1.0.0b4"] 3 | build-backend = "maturin" 4 | 5 | [project] 6 | name = "iota-client" 7 | 8 | [tool.maturin] 9 | python-packages = ["iota_client"] -------------------------------------------------------------------------------- /client/bindings/python/requirements-dev.txt: -------------------------------------------------------------------------------- 1 | pytest>=7.2.1 2 | setuptools-rust>=1.5.2 3 | wheel>=0.38.4 -------------------------------------------------------------------------------- /client/bindings/python/setup.py: -------------------------------------------------------------------------------- 1 | 2 | import sys 3 | import platform 4 | 5 | from setuptools import setup 6 | from setuptools_rust import RustExtension 7 | 8 | 9 | def get_py_version_cfgs(): 10 | # For now each Cfg Py_3_X flag is interpreted as "at least 3.X" 11 | version = sys.version_info[0:3] 12 | py3_min = 8 13 | out_cfg = [] 14 | for minor in range(py3_min, version[1] + 1): 15 | out_cfg.append("--cfg=Py_3_%d" % minor) 16 | 17 | if platform.python_implementation() == "PyPy": 18 | out_cfg.append("--cfg=PyPy") 19 | 20 | return out_cfg 21 | 22 | 23 | setup( 24 | name="iota_client", 25 | version="1.0.0-rc.3", 26 | classifiers=[ 27 | "License :: SPDX-License-Identifier :: Apache-2.0", 28 | "Intended Audience :: Developers", 29 | "Programming Language :: Python", 30 | "Programming Language :: Rust", 31 | "Operating System :: POSIX", 32 | "Operating System :: MacOS :: MacOS X", 33 | ], 34 | packages=["iota_client"], 35 | rust_extensions=[ 36 | RustExtension( 37 | "iota_client.iota_client", 38 | rustc_flags=get_py_version_cfgs(), 39 | debug=False, 40 | ), 41 | ], 42 | include_package_data=True, 43 | zip_safe=False, 44 | ) 45 | -------------------------------------------------------------------------------- /client/bindings/python/src/types/handler.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | use iota_client::message_interface::ClientMessageHandler as RustClientMessageHandler; 5 | use pyo3::prelude::*; 6 | 7 | #[pyclass] 8 | /// The Client Message Handler for message sending. 9 | pub struct ClientMessageHandler { 10 | /// The client message handler. 11 | pub client_message_handler: RustClientMessageHandler, 12 | } 13 | -------------------------------------------------------------------------------- /client/bindings/python/src/types/mod.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | mod error; 5 | mod handler; 6 | 7 | pub use self::{error::*, handler::*}; 8 | -------------------------------------------------------------------------------- /client/bindings/python/tests/__pycache__/test_addresses.cpython-310-pytest-7.1.2.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/iota.rs/e906ef3737f8c2b9ec910e466ec1d1c3be9a3b14/client/bindings/python/tests/__pycache__/test_addresses.cpython-310-pytest-7.1.2.pyc -------------------------------------------------------------------------------- /client/bindings/python/tests/test_addresses.py: -------------------------------------------------------------------------------- 1 | 2 | # Copyright 2022 IOTA Stiftung 3 | # SPDX-License-Identifier: Apache-2.0 4 | 5 | from iota_client import IotaClient, MnemonicSecretManager 6 | import json 7 | 8 | # Read the test vector 9 | tv = dict() 10 | with open('../../tests/fixtures/test_vectors.json') as json_file: 11 | tv = json.load(json_file) 12 | 13 | client = IotaClient() 14 | 15 | def test_mnemonic_address_generation(): 16 | mnemonic_address_test_cases = tv['general']['address_generations'] 17 | 18 | for test in mnemonic_address_test_cases: 19 | secret_manager = MnemonicSecretManager(test['mnemonic']) 20 | 21 | generated_address = client.generate_addresses(secret_manager, { 22 | "coinType": test['coin_type'], 23 | "accountIndex": test['account_index'], 24 | "bech32Hrp": test['bech32_hrp'], 25 | "internal": test['internal'], 26 | "range": { 27 | "start": test['address_index'], 28 | "end": test['address_index']+1, 29 | }, 30 | }) 31 | 32 | assert test['bech32_address'] == generated_address[0] 33 | -------------------------------------------------------------------------------- /client/bindings/python/tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | # can't install from sdist because local pyo3 repo can't be included in the sdist 3 | skipsdist = true 4 | envlist = py39, py310 5 | 6 | [gh-actions] 7 | python = 8 | 3.9: py39 9 | 3.10: py310 10 | 11 | [testenv] 12 | description = Run the unit tests under {basepython} 13 | passenv = * 14 | deps = -rrequirements-dev.txt 15 | commands = 16 | pip install . 17 | pytest -------------------------------------------------------------------------------- /client/bindings/wasm/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "wasm32-unknown-unknown" 3 | -------------------------------------------------------------------------------- /client/bindings/wasm/.eslintignore: -------------------------------------------------------------------------------- 1 | build_scripts/ 2 | target/ 3 | **/node_modules/ 4 | **/out/ 5 | **/tests/ 6 | **/dist 7 | node/ 8 | web/ 9 | -------------------------------------------------------------------------------- /client/bindings/wasm/.eslintrc.js: -------------------------------------------------------------------------------- 1 | const typescriptEslintRules = { 2 | '@typescript-eslint/ban-ts-comment': [ 3 | 'error', 4 | { 'ts-ignore': 'allow-with-description' }, 5 | ], 6 | }; 7 | 8 | module.exports = { 9 | env: { 10 | commonjs: true, 11 | es2019: true, 12 | }, 13 | plugins: ['@typescript-eslint'], 14 | extends: [ 15 | 'eslint:recommended', 16 | 'plugin:@typescript-eslint/recommended', 17 | 'prettier', 18 | ], 19 | parser: '@typescript-eslint/parser', 20 | parserOptions: { 21 | ecmaVersion: 12, 22 | sourceType: 'module', 23 | }, 24 | rules: typescriptEslintRules, 25 | }; 26 | -------------------------------------------------------------------------------- /client/bindings/wasm/.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | **/*~ 3 | **/node_modules 4 | **/.DS_Store 5 | build/ 6 | out/ 7 | **/dist 8 | **/client.log 9 | stronghold 10 | package-lock.json 11 | web/ 12 | node/ 13 | lib/bindings.js 14 | -------------------------------------------------------------------------------- /client/bindings/wasm/.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | semi: true, 3 | singleQuote: true, 4 | tabWidth: 4, 5 | useTabs: false, 6 | trailingComma: 'all', 7 | bracketSpacing: true, 8 | arrowParens: 'always', 9 | }; 10 | -------------------------------------------------------------------------------- /client/bindings/wasm/build_scripts/copyNodejsDefs.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const fse = require('fs-extra'); 3 | 4 | // Copy the TypeScript definitions from the Node.js bindings. 5 | const nodejsBindingsDir = path.join(__dirname, '..', '..', 'nodejs'); 6 | const outDir = path.join(__dirname, '..', 'out'); 7 | const folders = ['lib', 'types', 'test']; 8 | for (const folder of folders) { 9 | const sourceDir = path.join(nodejsBindingsDir, folder); 10 | const destDir = path.join(outDir, folder); 11 | fse.copySync(sourceDir, destDir, { 'overwrite': true }); 12 | } 13 | 14 | // Overwrite the Node.js `bindings.ts` file with one which links to Wasm functions instead. 15 | const bindingsSrc = path.join(__dirname, '..', 'lib', 'bindings.ts'); 16 | const bindingsDest = path.join(__dirname, '..', 'out', 'lib', 'bindings.ts'); 17 | fse.copySync(bindingsSrc, bindingsDest, { 'overwrite': true }); 18 | -------------------------------------------------------------------------------- /client/bindings/wasm/build_scripts/node.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const fs = require('fs'); 3 | const { lintAll } = require('./lints'); 4 | const generatePackage = require('./utils/generatePackage'); 5 | 6 | const rustPackageName = "iota_client_wasm"; 7 | 8 | const RELEASE_FOLDER = path.join(__dirname, '../node/wasm/'); 9 | const entryFilePathNode = path.join(RELEASE_FOLDER, rustPackageName + '.js'); 10 | const entryFileNode = fs.readFileSync(entryFilePathNode).toString(); 11 | 12 | // copy TypeScript files into temporary directory. 13 | // replace bindings.ts with local version. 14 | 15 | lintAll(entryFileNode); 16 | 17 | // Add node-fetch polyfill (https://github.com/seanmonstar/reqwest/issues/910). 18 | let changedFileNode = entryFileNode.replace( 19 | "let imports = {};", 20 | `if (!globalThis.fetch) { 21 | const fetch = require('node-fetch') 22 | globalThis.Headers = fetch.Headers 23 | globalThis.Request = fetch.Request 24 | globalThis.Response = fetch.Response 25 | globalThis.fetch = fetch 26 | } 27 | let imports = {};`); 28 | 29 | fs.writeFileSync( 30 | entryFilePathNode, 31 | changedFileNode 32 | ); 33 | 34 | const newPackage = generatePackage({ 35 | main: 'lib/index.js', 36 | types: 'lib/index.d.ts', 37 | }); 38 | 39 | fs.writeFileSync(path.join(RELEASE_FOLDER + "../", 'package.json'), JSON.stringify(newPackage, null, 2)); 40 | -------------------------------------------------------------------------------- /client/bindings/wasm/build_scripts/utils/generatePackage.js: -------------------------------------------------------------------------------- 1 | const rootPackage = require('../../package.json') 2 | 3 | module.exports = (options) => { 4 | 5 | const newPackage = { 6 | name: rootPackage.name, 7 | description: rootPackage.description, 8 | version: rootPackage.version, 9 | license: rootPackage.license, 10 | repository: rootPackage.repository, 11 | main: options.main, 12 | module: options.module, 13 | homepage: rootPackage.homepage, 14 | types: options.types, 15 | } 16 | 17 | // remove empty keys 18 | Object.keys(newPackage).forEach(key => newPackage[key] === undefined && delete newPackage[key]) 19 | 20 | return newPackage; 21 | 22 | } -------------------------------------------------------------------------------- /client/bindings/wasm/jest.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */ 2 | module.exports = { 3 | preset: 'ts-jest', 4 | testEnvironment: 'node', 5 | testMatch: ['/test/**/*.(test|spec).ts'], 6 | moduleNameMapper: { 7 | 'index.node': '/index.node', 8 | }, 9 | }; 10 | -------------------------------------------------------------------------------- /client/bindings/wasm/lib/bindings.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // This file overwrites the `bindings.ts` file from `bindings/nodejs/lib`, to link the Wasm `MessageHandler` interface. 5 | // The rest of the TypeScript definitions are copied as-is to the `out` directory before being compiled. 6 | 7 | // Import needs to be in a single line, otherwise it breaks 8 | // prettier-ignore 9 | // @ts-ignore: path is set to match runtime transpiled js path when bundled. 10 | import { initLogger, sendMessageAsync, messageHandlerNew, listen } from '../wasm/iota_client_wasm'; 11 | 12 | export { initLogger, sendMessageAsync, messageHandlerNew, listen }; 13 | -------------------------------------------------------------------------------- /client/bindings/wasm/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | #![forbid(unsafe_code)] 5 | 6 | pub mod message_handler; 7 | 8 | use wasm_bindgen::{prelude::wasm_bindgen, JsValue}; 9 | 10 | /// Initializes the console error panic hook for better panic messages. 11 | #[wasm_bindgen(start)] 12 | pub fn start() -> Result<(), JsValue> { 13 | console_error_panic_hook::set_once(); 14 | Ok(()) 15 | } 16 | 17 | /// The Wasm bindings do not support internal logging yet. 18 | /// 19 | /// Calling this is a no-op, only included for compatibility with the Node.js bindings TypeScript definitions. 20 | #[wasm_bindgen(js_name = initLogger)] 21 | pub fn init_logger(_config: JsValue) { 22 | // TODO 23 | } 24 | -------------------------------------------------------------------------------- /client/bindings/wasm/tsconfig.base.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": ["ES2020", "DOM"], 4 | "declaration": true, 5 | "sourceMap": true, 6 | "strict": true, 7 | "moduleResolution": "node", 8 | "importsNotUsedAsValues": "error", 9 | "noImplicitAny": true, 10 | "preserveConstEnums": true, 11 | "resolveJsonModule": true, 12 | "forceConsistentCasingInFileNames": true 13 | }, 14 | "include": ["out/**/*"], 15 | "exclude": ["node_modules", "out/test/*"] 16 | } 17 | -------------------------------------------------------------------------------- /client/bindings/wasm/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.base.json", 3 | "compilerOptions": { 4 | "target": "ES2020", 5 | "module": "commonjs" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /client/bindings/wasm/tsconfig.web.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "ES2020" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /client/examples/00_generate_mnemonic.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! cargo run --example generate_mnemonic --release 5 | 6 | use iota_client::{Client, Result}; 7 | 8 | #[tokio::main] 9 | async fn main() -> Result<()> { 10 | let mnemonic = Client::generate_mnemonic()?; 11 | 12 | println!("Mnemonic: {mnemonic}"); 13 | 14 | Ok(()) 15 | } 16 | -------------------------------------------------------------------------------- /client/examples/03_simple_block.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! cargo run --example 03_simple_block --release 5 | //! In this example we will send a block without a payload. 6 | 7 | use iota_client::{Client, Result}; 8 | 9 | #[tokio::main] 10 | async fn main() -> Result<()> { 11 | dotenv::dotenv().ok(); 12 | 13 | let node_url = std::env::var("NODE_URL").unwrap(); 14 | 15 | let client = Client::builder() 16 | .with_node(&node_url)? 17 | .with_pow_worker_count(1) 18 | .finish()?; 19 | 20 | let block = client.block().finish().await?; 21 | 22 | println!( 23 | "Empty block sent: {}/block/{}", 24 | std::env::var("EXPLORER_URL").unwrap(), 25 | block.id() 26 | ); 27 | Ok(()) 28 | } 29 | -------------------------------------------------------------------------------- /client/examples/block/00_block_no_payload.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! This example sends a block with no payload. 5 | //! Run: `cargo run --example block_no_payload --release -- [NODE URL]`. 6 | 7 | use iota_client::{Client, Result}; 8 | 9 | #[tokio::main] 10 | async fn main() -> Result<()> { 11 | // Take the node URL from command line argument or use one from env as default. 12 | let node_url = std::env::args().nth(1).unwrap_or_else(|| { 13 | // This example uses dotenv, which is not safe for use in production. 14 | dotenv::dotenv().ok(); 15 | std::env::var("NODE_URL").unwrap() 16 | }); 17 | 18 | // Create a client with that node. 19 | let client = Client::builder().with_node(&node_url)?.finish()?; 20 | 21 | // Create and send the block. 22 | let block = client.block().finish().await?; 23 | 24 | println!("{block:#?}"); 25 | 26 | println!( 27 | "Block with no payload sent: {}/block/{}", 28 | std::env::var("EXPLORER_URL").unwrap(), 29 | block.id() 30 | ); 31 | 32 | Ok(()) 33 | } 34 | -------------------------------------------------------------------------------- /client/examples/block/02_block_custom_parents.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! This example sends a block, with custom parents, which can be used for promoting. 5 | //! Run: `cargo run --example block_custom_parents --release -- [NODE URL]`. 6 | 7 | use iota_client::{Client, Result}; 8 | 9 | #[tokio::main] 10 | async fn main() -> Result<()> { 11 | // Take the node URL from command line argument or use one from env as default. 12 | let node_url = std::env::args().nth(1).unwrap_or_else(|| { 13 | // This example uses dotenv, which is not safe for use in production. 14 | dotenv::dotenv().ok(); 15 | std::env::var("NODE_URL").unwrap() 16 | }); 17 | 18 | // Create a client with that node. 19 | let client = Client::builder().with_node(&node_url)?.finish()?; 20 | 21 | // Use tips as custom parents. 22 | let parents = client.get_tips().await?; 23 | 24 | // Create and send the block with custom parents. 25 | let block = client.block().with_parents(parents)?.finish().await?; 26 | 27 | println!("{block:#?}"); 28 | 29 | println!( 30 | "Block with custom parents sent: {}/block/{}", 31 | std::env::var("EXPLORER_URL").unwrap(), 32 | block.id() 33 | ); 34 | 35 | Ok(()) 36 | } 37 | -------------------------------------------------------------------------------- /client/examples/client_config.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! cargo run --example client_config --release 5 | //! In this example we will create a client from a JSON config. 6 | 7 | use iota_client::{Client, Result}; 8 | 9 | #[tokio::main] 10 | async fn main() -> Result<()> { 11 | // Create a client instance 12 | let client = Client::builder() 13 | .from_json( 14 | r#"{ 15 | "nodes":[ 16 | { 17 | "url":"http://localhost:14265/", 18 | "auth":null, 19 | "disabled":false 20 | }, 21 | { 22 | "url":"https://api.testnet.shimmer.network", 23 | "auth":null, 24 | "disabled":false 25 | } 26 | ], 27 | "localPow":true, 28 | "apiTimeout":{ 29 | "secs":20, 30 | "nanos":0 31 | } 32 | }"#, 33 | )? 34 | .finish()?; 35 | 36 | let info = client.get_info().await?; 37 | println!("Node Info: {info:?}"); 38 | 39 | Ok(()) 40 | } 41 | -------------------------------------------------------------------------------- /client/examples/get_funds.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! cargo run --example get_funds --release 5 | 6 | use iota_client::{secret::SecretManager, utils::request_funds_from_faucet, Client, Result}; 7 | 8 | #[tokio::main] 9 | async fn main() -> Result<()> { 10 | // This example uses dotenv, which is not safe for use in production 11 | dotenv::dotenv().ok(); 12 | 13 | let node_url = std::env::var("NODE_URL").unwrap(); 14 | let faucet_url = std::env::var("FAUCET_URL").unwrap(); 15 | 16 | // Create a client instance 17 | let client = Client::builder() 18 | .with_node(&node_url)? // Insert the node here 19 | .finish()?; 20 | 21 | let secret_manager = 22 | SecretManager::try_from_mnemonic(&std::env::var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC_1").unwrap())?; 23 | 24 | let addresses = client 25 | .get_addresses(&secret_manager) 26 | .with_account_index(0) 27 | .with_range(0..1) 28 | .finish() 29 | .await?; 30 | println!("{}", addresses[0]); 31 | 32 | let faucet_response = request_funds_from_faucet(&faucet_url, &addresses[0]).await?; 33 | 34 | println!("{faucet_response}"); 35 | Ok(()) 36 | } 37 | -------------------------------------------------------------------------------- /client/examples/high_level/inputs_from_transaction_id.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! cargo run --example inputs_from_transaction_id --release 5 | 6 | use iota_client::{block::payload::transaction::TransactionId, Client, Result}; 7 | 8 | /// In this example we will fetch all inputs from a given transaction id. 9 | 10 | #[tokio::main] 11 | async fn main() -> Result<()> { 12 | dotenv::dotenv().ok(); 13 | 14 | let node_url = std::env::var("NODE_URL").unwrap(); 15 | 16 | let client = Client::builder() 17 | .with_node(&node_url)? 18 | .finish()?; 19 | 20 | let transaction_id = 21 | "0xaf7579fb57746219561072c2cc0e4d0fbb8d493d075bd21bf25ae81a450c11ef".parse::()?; 22 | 23 | let inputs = client.inputs_from_transaction_id(&transaction_id).await?; 24 | 25 | println!("Transaction inputs {:?}", inputs); 26 | 27 | Ok(()) 28 | } 29 | -------------------------------------------------------------------------------- /client/examples/logger.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! cargo run --example logger --release 5 | 6 | use iota_client::{Client, Result}; 7 | 8 | #[tokio::main] 9 | async fn main() -> Result<()> { 10 | // Generates a client.log file with logs for debugging 11 | let logger_output_config = fern_logger::LoggerOutputConfigBuilder::new() 12 | .name("client.log") 13 | .target_exclusions(&["h2", "hyper", "rustls"]) 14 | .level_filter(log::LevelFilter::Debug); 15 | let config = fern_logger::LoggerConfig::build() 16 | .with_output(logger_output_config) 17 | .finish(); 18 | fern_logger::logger_init(config).unwrap(); 19 | 20 | // Take the node URL from command line argument or use one from env as default. 21 | let node_url = std::env::args().nth(1).unwrap_or_else(|| { 22 | // This example uses dotenv, which is not safe for use in production. 23 | dotenv::dotenv().ok(); 24 | std::env::var("NODE_URL").unwrap() 25 | }); 26 | 27 | // Create a client with that node. 28 | let client = Client::builder().with_node(&node_url)?.finish()?; 29 | 30 | // Get node info. 31 | let info = client.get_info().await?; 32 | 33 | println!("{info:#?}"); 34 | 35 | Ok(()) 36 | } 37 | -------------------------------------------------------------------------------- /client/examples/node_api_core/00_get_health.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Calls `GET /health`. 5 | //! Returns the health of the node. 6 | //! Run: `cargo run --example node_api_core_get_health --release -- [NODE URL]`. 7 | 8 | use iota_client::{Client, Result}; 9 | 10 | #[tokio::main] 11 | async fn main() -> Result<()> { 12 | // Take the node URL from command line argument or use one from env as default. 13 | let node_url = std::env::args().nth(1).unwrap_or_else(|| { 14 | // This example uses dotenv, which is not safe for use in production. 15 | dotenv::dotenv().ok(); 16 | std::env::var("NODE_URL").unwrap() 17 | }); 18 | 19 | // Create a client with that node. 20 | let client = Client::builder() 21 | .with_node(&node_url)? 22 | .with_ignore_node_health() 23 | .finish()?; 24 | 25 | // Get node health. 26 | let health = client.get_health(&node_url).await?; 27 | 28 | println!("Health: {health}"); 29 | 30 | Ok(()) 31 | } 32 | -------------------------------------------------------------------------------- /client/examples/node_api_core/01_get_routes.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Calls `GET /api/routes`. 5 | //! Returns the available API route groups of the node. 6 | //! Run: `cargo run --example node_api_core_get_routes --release -- [NODE URL]`. 7 | 8 | use iota_client::{Client, Result}; 9 | 10 | #[tokio::main] 11 | async fn main() -> Result<()> { 12 | // Take the node URL from command line argument or use one from env as default. 13 | let node_url = std::env::args().nth(1).unwrap_or_else(|| { 14 | // This example uses dotenv, which is not safe for use in production. 15 | dotenv::dotenv().ok(); 16 | std::env::var("NODE_URL").unwrap() 17 | }); 18 | 19 | // Create a client with that node. 20 | let client = Client::builder() 21 | .with_node(&node_url)? 22 | .with_ignore_node_health() 23 | .finish()?; 24 | 25 | // Get routes. 26 | let routes = client.get_routes().await?; 27 | 28 | println!("{routes:#?}"); 29 | 30 | Ok(()) 31 | } 32 | -------------------------------------------------------------------------------- /client/examples/node_api_core/02_get_info.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Calls `GET /api/core/v2/info`. 5 | //! Returns general information about the node. 6 | //! Run: `cargo run --example node_api_core_get_info --release -- [NODE URL]`. 7 | 8 | use iota_client::{Client, Result}; 9 | 10 | #[tokio::main] 11 | async fn main() -> Result<()> { 12 | // Take the node URL from command line argument or use one from env as default. 13 | let node_url = std::env::args().nth(1).unwrap_or_else(|| { 14 | // This example uses dotenv, which is not safe for use in production. 15 | dotenv::dotenv().ok(); 16 | std::env::var("NODE_URL").unwrap() 17 | }); 18 | 19 | // Create a client with that node. 20 | let client = Client::builder() 21 | .with_node(&node_url)? 22 | .with_ignore_node_health() 23 | .finish()?; 24 | 25 | // Get node info. 26 | let info = client.get_info().await?; 27 | 28 | println!("{info:#?}"); 29 | 30 | Ok(()) 31 | } 32 | -------------------------------------------------------------------------------- /client/examples/node_api_core/03_get_tips.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Calls `GET /api/core/v2/tips`. 5 | //! Returns tips that are ideal for attaching a block. 6 | //! Run: `cargo run --example node_api_core_get_tips --release -- [NODE URL]`. 7 | 8 | use iota_client::{Client, Result}; 9 | 10 | #[tokio::main] 11 | async fn main() -> Result<()> { 12 | // Take the node URL from command line argument or use one from env as default. 13 | let node_url = std::env::args().nth(1).unwrap_or_else(|| { 14 | // This example uses dotenv, which is not safe for use in production. 15 | dotenv::dotenv().ok(); 16 | std::env::var("NODE_URL").unwrap() 17 | }); 18 | 19 | // Create a client with that node. 20 | let client = Client::builder().with_node(&node_url)?.finish()?; 21 | 22 | // Get tips. 23 | let tips = client.get_tips().await?; 24 | 25 | println!("Tips: {tips:#?}"); 26 | 27 | Ok(()) 28 | } 29 | -------------------------------------------------------------------------------- /client/examples/node_api_core/04_post_block.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Calls `POST /api/core/v2/blocks`. 5 | //! Submits a block as a JSON payload. 6 | //! Run: `cargo run --example node_api_core_post_block --release -- [NODE URL]`. 7 | 8 | use iota_client::{Client, Result}; 9 | 10 | #[tokio::main] 11 | async fn main() -> Result<()> { 12 | // Take the node URL from command line argument or use one from env as default. 13 | let node_url = std::env::args().nth(1).unwrap_or_else(|| { 14 | // This example uses dotenv, which is not safe for use in production. 15 | dotenv::dotenv().ok(); 16 | std::env::var("NODE_URL").unwrap() 17 | }); 18 | 19 | // Create a client with that node. 20 | let client = Client::builder().with_node(&node_url)?.finish()?; 21 | 22 | // Create the block. 23 | let block = client.block().finish().await?; 24 | // Post the block. 25 | let block_id = client.post_block(&block).await?; 26 | 27 | println!("Posted: {block_id:?}"); 28 | 29 | Ok(()) 30 | } 31 | -------------------------------------------------------------------------------- /client/examples/node_api_core/05_post_block_raw.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Calls `POST /api/core/v2/blocks`. 5 | //! Submits a block as raw bytes. 6 | //! Run: `cargo run --example node_api_core_post_block_raw --release -- [NODE URL]`. 7 | 8 | use iota_client::{Client, Result}; 9 | 10 | #[tokio::main] 11 | async fn main() -> Result<()> { 12 | // Take the node URL from command line argument or use one from env as default. 13 | let node_url = std::env::args().nth(1).unwrap_or_else(|| { 14 | // This example uses dotenv, which is not safe for use in production. 15 | dotenv::dotenv().ok(); 16 | std::env::var("NODE_URL").unwrap() 17 | }); 18 | 19 | // Create a client with that node. 20 | let client = Client::builder().with_node(&node_url)?.finish()?; 21 | 22 | // Create the block. 23 | let block = client.block().finish().await?; 24 | // Post the block as raw bytes. 25 | let block_id = client.post_block_raw(&block).await?; 26 | 27 | println!("Posted: {block_id:?}"); 28 | 29 | Ok(()) 30 | } 31 | -------------------------------------------------------------------------------- /client/examples/node_api_core/06_get_block.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Calls `GET /api/core/v2/blocks/{blockId}`. 5 | //! Returns block data as JSON by its identifier. 6 | //! Run: `cargo run --example node_api_core_get_block --release -- [NODE URL] [BLOCK ID]`. 7 | 8 | use std::str::FromStr; 9 | 10 | use iota_client::{block::BlockId, Client, Result}; 11 | 12 | #[tokio::main] 13 | async fn main() -> Result<()> { 14 | // Take the node URL from command line argument or use one from env as default. 15 | let node_url = std::env::args().nth(1).unwrap_or_else(|| { 16 | // This example uses dotenv, which is not safe for use in production. 17 | dotenv::dotenv().ok(); 18 | std::env::var("NODE_URL").unwrap() 19 | }); 20 | 21 | // Create a client with that node. 22 | let client = Client::builder().with_node(&node_url)?.finish()?; 23 | 24 | // Take the block ID from command line argument or... 25 | let block_id = if let Some(Ok(block_id)) = std::env::args().nth(2).map(|s| BlockId::from_str(&s)) { 26 | block_id 27 | } else { 28 | // ... fetch one from the node. 29 | client.get_tips().await?[0] 30 | }; 31 | 32 | // Get the block. 33 | let block = client.get_block(&block_id).await?; 34 | 35 | println!("{block:#?}"); 36 | 37 | Ok(()) 38 | } 39 | -------------------------------------------------------------------------------- /client/examples/node_api_core/08_get_block_metadata.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Calls `GET /api/core/v2/blocks/{blockId}/metadata`. 5 | //! Finds the metadata of a given block. 6 | //! Run: `cargo run --example node_api_core_get_block_metadata --release -- [NODE URL]`. 7 | 8 | use iota_client::{Client, Result}; 9 | 10 | #[tokio::main] 11 | async fn main() -> Result<()> { 12 | // Take the node URL from command line argument or use one from env as default. 13 | let node_url = std::env::args().nth(1).unwrap_or_else(|| { 14 | // This example uses dotenv, which is not safe for use in production. 15 | dotenv::dotenv().ok(); 16 | std::env::var("NODE_URL").unwrap() 17 | }); 18 | 19 | // Create a client with that node. 20 | let client = Client::builder().with_node(&node_url)?.finish()?; 21 | 22 | // Fetch a block ID from the node. 23 | let block_id = client.get_tips().await?[0]; 24 | // Send the request. 25 | let block_metadata = client.get_block_metadata(&block_id).await?; 26 | 27 | println!("{block_metadata:#?}"); 28 | 29 | Ok(()) 30 | } 31 | -------------------------------------------------------------------------------- /client/examples/node_api_core/09_get_output.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Calls `GET /api/core/v2/outputs/{outputId}`. 5 | //! Find an output, as JSON, by its identifier. 6 | //! Run: `cargo run --example node_api_core_get_output --release -- [NODE URL] [OUTPUT ID]`. 7 | 8 | use std::str::FromStr; 9 | 10 | use iota_client::{block::output::OutputId, Client, Result}; 11 | 12 | #[tokio::main] 13 | async fn main() -> Result<()> { 14 | // Take the node URL from command line argument or use one from env as default. 15 | let node_url = std::env::args().nth(1).unwrap_or_else(|| { 16 | // This example uses dotenv, which is not safe for use in production. 17 | dotenv::dotenv().ok(); 18 | std::env::var("NODE_URL").unwrap() 19 | }); 20 | 21 | // Create a client with that node. 22 | let client = Client::builder().with_node(&node_url)?.finish()?; 23 | 24 | // Take the output ID from command line argument or use a default one. 25 | let output_id = 26 | OutputId::from_str(&std::env::args().nth(2).unwrap_or_else(|| { 27 | String::from("0xb66fd384cb5755668f1890ea2e41d699db9cf32f3bc422ad3c24ffeb9c7f01d00000") 28 | }))?; 29 | 30 | // Get the output. 31 | let output = client.get_output(&output_id).await?; 32 | 33 | println!("{output:#?}"); 34 | 35 | Ok(()) 36 | } 37 | -------------------------------------------------------------------------------- /client/examples/node_api_core/12_get_receipts.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Calls `GET /api/core/v2/receipts`. 5 | //! Returns all stored receipts. 6 | //! Run: `cargo run --example node_api_core_get_receipts --release -- [NODE URL]`. 7 | 8 | use iota_client::{Client, Result}; 9 | 10 | #[tokio::main] 11 | async fn main() -> Result<()> { 12 | // Take the node URL from command line argument or use one from env as default. 13 | let node_url = std::env::args().nth(1).unwrap_or_else(|| { 14 | // This example uses dotenv, which is not safe for use in production. 15 | dotenv::dotenv().ok(); 16 | std::env::var("NODE_URL").unwrap() 17 | }); 18 | 19 | // Create a client with that node. 20 | let client = Client::builder().with_node(&node_url)?.finish()?; 21 | 22 | // Send the request. 23 | let receipts = client.get_receipts().await?; 24 | 25 | println!("{receipts:#?}"); 26 | 27 | Ok(()) 28 | } 29 | -------------------------------------------------------------------------------- /client/examples/node_api_core/13_get_receipts_migrated_at.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Calls `GET /api/core/v2/receipts/{migratedAt}`. 5 | //! Returns all stored receipts for a given migration index. 6 | //! Run: `cargo run --example node_api_core_get_receipts_migrated_at --release -- [NODE URL]`. 7 | 8 | use iota_client::{Client, Result}; 9 | 10 | #[tokio::main] 11 | async fn main() -> Result<()> { 12 | // Take the node URL from command line argument or use one from env as default. 13 | let node_url = std::env::args().nth(1).unwrap_or_else(|| { 14 | // This example uses dotenv, which is not safe for use in production. 15 | dotenv::dotenv().ok(); 16 | std::env::var("NODE_URL").unwrap() 17 | }); 18 | 19 | // Create a client with that node. 20 | let client = Client::builder().with_node(&node_url)?.finish()?; 21 | 22 | // Send the request. 23 | let receipts = client.get_receipts_migrated_at(1_000_000).await?; 24 | 25 | println!("{receipts:#?}"); 26 | 27 | Ok(()) 28 | } 29 | -------------------------------------------------------------------------------- /client/examples/node_api_core/14_get_treasury.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Calls `GET /api/core/v2/treasury`. 5 | //! Returns information about the treasury. 6 | //! Run: `cargo run --example node_api_core_get_treasury --release -- [NODE URL]`. 7 | 8 | use iota_client::{Client, Result}; 9 | 10 | #[tokio::main] 11 | async fn main() -> Result<()> { 12 | // Take the node URL from command line argument or use one from env as default. 13 | let node_url = std::env::args().nth(1).unwrap_or_else(|| { 14 | // This example uses dotenv, which is not safe for use in production. 15 | dotenv::dotenv().ok(); 16 | std::env::var("NODE_URL").unwrap() 17 | }); 18 | 19 | // Create a client with that node. 20 | let client = Client::builder().with_node(&node_url)?.finish()?; 21 | 22 | // Send the request. 23 | let treasury = client.get_treasury().await?; 24 | 25 | println!("{treasury:#?}"); 26 | 27 | Ok(()) 28 | } 29 | -------------------------------------------------------------------------------- /client/examples/node_api_core/15_get_included_block.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Calls `GET /api/core/v2/transactions/{transactionId}/included-block`. 5 | //! Returns the included block, as JSON, of a transaction. 6 | //! Run: `cargo run --example node_api_core_get_included_block --release -- [NODE URL]`. 7 | 8 | use std::str::FromStr; 9 | 10 | use iota_client::{block::payload::transaction::TransactionId, Client, Result}; 11 | 12 | #[tokio::main] 13 | async fn main() -> Result<()> { 14 | // Take the node URL from command line argument or use one from env as default. 15 | let node_url = std::env::args().nth(1).unwrap_or_else(|| { 16 | // This example uses dotenv, which is not safe for use in production. 17 | dotenv::dotenv().ok(); 18 | std::env::var("NODE_URL").unwrap() 19 | }); 20 | 21 | // Create a client with that node. 22 | let client = Client::builder().with_node(&node_url)?.finish()?; 23 | 24 | // Transactions get pruned from the node after some time, replace with a new TransactionId. 25 | let transaction_id = TransactionId::from_str("0xb66fd384cb5755668f1890ea2e41d699db9cf32f3bc422ad3c24ffeb9c7f01d0")?; 26 | // Send the request. 27 | let block = client.get_included_block(&transaction_id).await?; 28 | 29 | println!("{block:#?}"); 30 | 31 | Ok(()) 32 | } 33 | -------------------------------------------------------------------------------- /client/examples/node_api_core/16_get_included_block_raw.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Calls `GET /api/core/v2/transactions/{transactionId}/included-block`. 5 | //! Returns the included block, as raw bytes, of a transaction. 6 | //! Run: `cargo run --example node_api_core_get_included_block_raw --release -- [NODE URL]`. 7 | 8 | use std::str::FromStr; 9 | 10 | use iota_client::{block::payload::transaction::TransactionId, Client, Result}; 11 | 12 | #[tokio::main] 13 | async fn main() -> Result<()> { 14 | // Take the node URL from command line argument or use one from env as default. 15 | let node_url = std::env::args().nth(1).unwrap_or_else(|| { 16 | // This example uses dotenv, which is not safe for use in production. 17 | dotenv::dotenv().ok(); 18 | std::env::var("NODE_URL").unwrap() 19 | }); 20 | 21 | // Create a client with that node. 22 | let client = Client::builder().with_node(&node_url)?.finish()?; 23 | 24 | // Transactions get pruned from the node after some time, replace with a new TransactionId. 25 | let transaction_id = TransactionId::from_str("0xb66fd384cb5755668f1890ea2e41d699db9cf32f3bc422ad3c24ffeb9c7f01d0")?; 26 | // Send the request. 27 | let block_bytes = client.get_included_block_raw(&transaction_id).await?; 28 | 29 | println!("Block bytes: {block_bytes:?}"); 30 | 31 | Ok(()) 32 | } 33 | -------------------------------------------------------------------------------- /client/examples/node_api_core/17_get_milestone_by_id.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Calls `GET /api/core/v2/milestones/{milestoneId}`. 5 | //! Returns milestone data as JSON by its identifier. 6 | //! Run: `cargo run --example node_api_core_get_milestone_by_id --release -- [NODE URL]`. 7 | 8 | use std::str::FromStr; 9 | 10 | use iota_client::{block::payload::milestone::MilestoneId, Client, Result}; 11 | 12 | #[tokio::main] 13 | async fn main() -> Result<()> { 14 | // Take the node URL from command line argument or use one from env as default. 15 | let node_url = std::env::args().nth(1).unwrap_or_else(|| { 16 | // This example uses dotenv, which is not safe for use in production. 17 | dotenv::dotenv().ok(); 18 | std::env::var("NODE_URL").unwrap() 19 | }); 20 | 21 | // Create a client with that node. 22 | let client = Client::builder().with_node(&node_url)?.finish()?; 23 | 24 | // Fetch the latest milestone ID from the node. 25 | let info = client.get_info().await?; 26 | let milestone_id = MilestoneId::from_str(&info.node_info.status.latest_milestone.milestone_id.unwrap())?; 27 | // Send the request. 28 | let milestone = client.get_milestone_by_id(&milestone_id).await?; 29 | 30 | println!("{milestone:#?}"); 31 | 32 | Ok(()) 33 | } 34 | -------------------------------------------------------------------------------- /client/examples/node_api_core/18_get_milestone_by_id_raw.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Calls `GET /api/core/v2/milestones/{milestoneId}`. 5 | //! Returns milestone data as raw bytes by its identifier. 6 | //! Run: `cargo run --example node_api_core_get_milestone_by_id_raw --release -- [NODE URL]`. 7 | 8 | use std::str::FromStr; 9 | 10 | use iota_client::{block::payload::milestone::MilestoneId, Client, Result}; 11 | 12 | #[tokio::main] 13 | async fn main() -> Result<()> { 14 | // Take the node URL from command line argument or use one from env as default. 15 | let node_url = std::env::args().nth(1).unwrap_or_else(|| { 16 | // This example uses dotenv, which is not safe for use in production. 17 | dotenv::dotenv().ok(); 18 | std::env::var("NODE_URL").unwrap() 19 | }); 20 | 21 | // Create a client with that node. 22 | let client = Client::builder().with_node(&node_url)?.finish()?; 23 | 24 | // Fetch the latest milestone ID from the node. 25 | let info = client.get_info().await?; 26 | let milestone_id = MilestoneId::from_str(&info.node_info.status.latest_milestone.milestone_id.unwrap())?; 27 | // Send the request. 28 | let milestone = client.get_milestone_by_id_raw(&milestone_id).await?; 29 | 30 | println!("{milestone:?}"); 31 | 32 | Ok(()) 33 | } 34 | -------------------------------------------------------------------------------- /client/examples/node_api_core/19_get_utxo_changes_by_id.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Calls `GET /api/core/v2/milestones/{milestoneId}/utxo-changes`. 5 | //! Gets all UTXO changes of a given milestone by milestone identifier. 6 | //! Run: `cargo run --example node_api_core_get_utxo_changes_by_id --release -- [NODE URL]`. 7 | 8 | use std::str::FromStr; 9 | 10 | use iota_client::{block::payload::milestone::MilestoneId, Client, Result}; 11 | 12 | #[tokio::main] 13 | async fn main() -> Result<()> { 14 | // Take the node URL from command line argument or use one from env as default. 15 | let node_url = std::env::args().nth(1).unwrap_or_else(|| { 16 | // This example uses dotenv, which is not safe for use in production. 17 | dotenv::dotenv().ok(); 18 | std::env::var("NODE_URL").unwrap() 19 | }); 20 | 21 | // Create a client with that node. 22 | let client = Client::builder().with_node(&node_url)?.finish()?; 23 | 24 | // Fetch the latest milestone ID from the node. 25 | let info = client.get_info().await?; 26 | let milestone_id = MilestoneId::from_str(&info.node_info.status.latest_milestone.milestone_id.unwrap())?; 27 | // Send the request. 28 | let utxo_changes = client.get_utxo_changes_by_id(&milestone_id).await?; 29 | 30 | println!("{utxo_changes:#?}"); 31 | 32 | Ok(()) 33 | } 34 | -------------------------------------------------------------------------------- /client/examples/node_api_core/20_get_milestone_by_index.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Calls `GET /api/core/v2/milestones/by-index/{index}`. 5 | //! Returns milestone data as JSON by its index. 6 | //! Run: `cargo run --example node_api_core_get_milestone_by_index --release -- [NODE URL]`. 7 | 8 | use iota_client::{Client, Result}; 9 | 10 | #[tokio::main] 11 | async fn main() -> Result<()> { 12 | // Take the node URL from command line argument or use one from env as default. 13 | let node_url = std::env::args().nth(1).unwrap_or_else(|| { 14 | // This example uses dotenv, which is not safe for use in production. 15 | dotenv::dotenv().ok(); 16 | std::env::var("NODE_URL").unwrap() 17 | }); 18 | 19 | // Create a client with that node. 20 | let client = Client::builder().with_node(&node_url)?.finish()?; 21 | 22 | // Fetch the latest milestone index from the node. 23 | let info = client.get_info().await?; 24 | let milestone_index = info.node_info.status.latest_milestone.index; 25 | // Send the request. 26 | let milestone = client.get_milestone_by_index(milestone_index).await?; 27 | 28 | println!("{milestone:#?}"); 29 | 30 | Ok(()) 31 | } 32 | -------------------------------------------------------------------------------- /client/examples/node_api_core/21_get_milestone_by_index_raw.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Calls `GET /api/core/v2/milestones/by-index/{index}`. 5 | //! Returns milestone data as raw bytes by its index. 6 | //! Run: `cargo run --example node_api_core_get_milestone_by_index_raw --release -- [NODE URL]`. 7 | 8 | use iota_client::{Client, Result}; 9 | 10 | #[tokio::main] 11 | async fn main() -> Result<()> { 12 | // Take the node URL from command line argument or use one from env as default. 13 | let node_url = std::env::args().nth(1).unwrap_or_else(|| { 14 | // This example uses dotenv, which is not safe for use in production. 15 | dotenv::dotenv().ok(); 16 | std::env::var("NODE_URL").unwrap() 17 | }); 18 | 19 | // Create a client with that node. 20 | let client = Client::builder().with_node(&node_url)?.finish()?; 21 | 22 | // Fetch the latest milestone index from the node. 23 | let info = client.get_info().await?; 24 | let milestone_index = info.node_info.status.latest_milestone.index; 25 | // Send the request. 26 | let milestone = client.get_milestone_by_index_raw(milestone_index).await?; 27 | 28 | println!("{milestone:?}"); 29 | 30 | Ok(()) 31 | } 32 | -------------------------------------------------------------------------------- /client/examples/node_api_core/22_get_utxo_changes_by_index.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Calls `GET /api/core/v2/milestones/by-index/{index}/utxo-changes`. 5 | //! Gets all UTXO changes of a given milestone by milestone index. 6 | //! Run: `cargo run --example node_api_core_get_utxo_changes_by_index --release -- [NODE URL]`. 7 | 8 | use iota_client::{Client, Result}; 9 | 10 | #[tokio::main] 11 | async fn main() -> Result<()> { 12 | // Take the node URL from command line argument or use one from env as default. 13 | let node_url = std::env::args().nth(1).unwrap_or_else(|| { 14 | // This example uses dotenv, which is not safe for use in production. 15 | dotenv::dotenv().ok(); 16 | std::env::var("NODE_URL").unwrap() 17 | }); 18 | 19 | // Create a client with that node. 20 | let client = Client::builder().with_node(&node_url)?.finish()?; 21 | 22 | // Fetch the latest milestone index from the node. 23 | let info = client.get_info().await?; 24 | let milestone_index = info.node_info.status.latest_milestone.index; 25 | // Send the request. 26 | let utxo_changes = client.get_utxo_changes_by_index(milestone_index).await?; 27 | 28 | println!("{utxo_changes:#?}"); 29 | 30 | Ok(()) 31 | } 32 | -------------------------------------------------------------------------------- /client/examples/tagged_data_to_utf8.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! cargo run --example tagged_data_to_utf8 --release 5 | //! In this example we will UTF-8 encode the tag and the data of an `TaggedDataPayload`. 6 | 7 | use iota_client::{block::payload::TaggedDataPayload, Client, Result}; 8 | 9 | #[tokio::main] 10 | async fn main() -> Result<()> { 11 | // `hello` in hexadecimal. 12 | let tag = prefix_hex::decode("0x68656c6c6f")?; 13 | // `world` in hexadecimal. 14 | let data = prefix_hex::decode("0x776f726c64")?; 15 | 16 | let (tag_utf8, data_utf8) = Client::tagged_data_to_utf8(&TaggedDataPayload::new(tag, data)?)?; 17 | 18 | println!("tag: {tag_utf8}\ndata: {data_utf8}"); 19 | 20 | Ok(()) 21 | } 22 | -------------------------------------------------------------------------------- /client/src/api/block_builder/input_selection/core/requirement/issuer.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2023 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | use super::{Error, InputSelection, Requirement}; 5 | use crate::{ 6 | block::{address::Address, output::AliasTransition}, 7 | secret::types::InputSigningData, 8 | }; 9 | 10 | impl InputSelection { 11 | /// Fulfills an issuer requirement by fulfilling the equivalent sender requirement. 12 | /// Potentially converts the error for a more accurate one. 13 | pub(crate) fn fulfill_issuer_requirement( 14 | &mut self, 15 | address: Address, 16 | ) -> Result)>, Error> { 17 | log::debug!("Treating {address:?} issuer requirement as a sender requirement"); 18 | 19 | match self.fulfill_sender_requirement(address) { 20 | Ok(res) => Ok(res), 21 | Err(Error::UnfulfillableRequirement(Requirement::Sender(_))) => { 22 | Err(Error::UnfulfillableRequirement(Requirement::Issuer(address))) 23 | } 24 | Err(e) => Err(e), 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /client/src/api/block_builder/input_selection/mod.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Input selection for transactions 5 | 6 | mod automatic; 7 | mod core; 8 | mod helpers; 9 | mod manual; 10 | mod sender_issuer; 11 | mod utxo_chains; 12 | 13 | pub(crate) use self::core::is_alias_transition; 14 | pub use self::{ 15 | core::{Burn, BurnDto, Error, InputSelection, Requirement, Selected}, 16 | helpers::minimum_storage_deposit_basic_output, 17 | }; 18 | -------------------------------------------------------------------------------- /client/src/api/mod.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! High level APIs 5 | 6 | mod address; 7 | mod block_builder; 8 | mod consolidation; 9 | mod high_level; 10 | mod types; 11 | 12 | pub use self::{address::*, block_builder::*, types::*}; 13 | 14 | const ADDRESS_GAP_RANGE: u32 = 20; 15 | -------------------------------------------------------------------------------- /client/src/message_interface/mod.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Message interface for bindings 5 | 6 | mod message; 7 | mod message_handler; 8 | mod response; 9 | 10 | pub use self::{message::Message, message_handler::ClientMessageHandler, response::Response}; 11 | use crate::{ClientBuilder, Result}; 12 | 13 | /// Create message handler with client options 14 | pub fn create_message_handler(client_config: Option) -> Result { 15 | let client = match client_config { 16 | Some(options) => ClientBuilder::new().from_json(&options)?.finish()?, 17 | None => ClientBuilder::new().finish()?, 18 | }; 19 | Ok(ClientMessageHandler::with_client(client)) 20 | } 21 | -------------------------------------------------------------------------------- /client/src/node_api/mod.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! node API modules 5 | 6 | pub mod core; 7 | pub mod indexer; 8 | #[cfg(feature = "mqtt")] 9 | #[cfg_attr(docsrs, doc(cfg(feature = "mqtt")))] 10 | pub mod mqtt; 11 | #[cfg(feature = "participation")] 12 | #[cfg_attr(docsrs, doc(cfg(feature = "participation")))] 13 | pub mod participation; 14 | -------------------------------------------------------------------------------- /client/src/node_api/mqtt/error.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2023 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | /// MQTT related errors. 5 | #[derive(Debug, thiserror::Error)] 6 | #[allow(clippy::large_enum_variant)] 7 | pub enum Error { 8 | /// Client error. 9 | #[error("client error {0}")] 10 | Client(#[from] rumqttc::ClientError), 11 | /// Connection not found. 12 | #[error("connection not found")] 13 | ConnectionNotFound, 14 | /// Crypto error. 15 | #[error("crypto error {0}")] 16 | Crypto(#[from] crypto::Error), 17 | /// Invalid topic. 18 | #[error("invalid topic {0}")] 19 | InvalidTopic(String), 20 | } 21 | -------------------------------------------------------------------------------- /client/src/secret/stronghold.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Stronghold-as-a-Secret-Manager. 5 | 6 | use crate::stronghold::StrongholdAdapter; 7 | 8 | /// Secret manager that uses [`iota_stronghold`] as the backing storage. 9 | /// 10 | /// This is just an alias to the all-in-one [StrongholdAdapter]. 11 | pub type StrongholdSecretManager = StrongholdAdapter; 12 | -------------------------------------------------------------------------------- /client/src/storage/mod.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Database provider interfaces and implementations. 5 | 6 | #[cfg(feature = "stronghold")] 7 | #[cfg_attr(docsrs, doc(cfg(feature = "stronghold")))] 8 | mod stronghold; 9 | 10 | use async_trait::async_trait; 11 | 12 | #[cfg(feature = "stronghold")] 13 | pub use self::stronghold::StrongholdStorageProvider; 14 | use crate::Result; 15 | 16 | /// The interface for database providers. 17 | #[async_trait] 18 | pub trait StorageProvider { 19 | /// Get a value out of the database. 20 | async fn get(&mut self, k: &[u8]) -> Result>>; 21 | 22 | /// Insert a value into the database. 23 | /// 24 | /// If there exists a record under the same key as `k`, it will be replaced by the new value (`v`) and returned. 25 | async fn insert(&mut self, k: &[u8], v: &[u8]) -> Result>>; 26 | 27 | /// Delete a value from the database. 28 | /// 29 | /// The deleted value is returned. 30 | async fn delete(&mut self, k: &[u8]) -> Result>>; 31 | } 32 | -------------------------------------------------------------------------------- /client/src/storage/stronghold.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Stronghold-as-a-Database implementation. 5 | 6 | use crate::stronghold::StrongholdAdapter; 7 | 8 | /// Stronghold as a database provider. 9 | /// 10 | /// This is just an alias to the all-in-one [StrongholdAdapter]. 11 | pub type StrongholdStorageProvider = StrongholdAdapter; 12 | -------------------------------------------------------------------------------- /client/tests/common/constants.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2023 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | pub static NODE_LOCAL: &str = "http://localhost:14265"; 5 | 6 | pub static FAUCET_URL: &str = "http://localhost:8091/api/enqueue"; 7 | -------------------------------------------------------------------------------- /client/tests/input_selection/mod.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | #![allow(clippy::type_complexity)] 5 | 6 | mod alias_outputs; 7 | mod basic_outputs; 8 | mod burn; 9 | mod expiration; 10 | mod foundry_outputs; 11 | mod native_tokens; 12 | mod nft_outputs; 13 | mod outputs; 14 | mod storage_deposit_return; 15 | mod timelock; 16 | -------------------------------------------------------------------------------- /client/tests/mqtt/mod.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2023 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | mod topic; 5 | -------------------------------------------------------------------------------- /pow/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "iota-pow" 3 | version = "1.0.0-rc.4" 4 | authors = [ "IOTA Stiftung" ] 5 | edition = "2021" 6 | description = "Provides proof of work implementations and scoring for the IOTA protocol" 7 | readme = "README.md" 8 | repository = "https://github.com/iotaledger/iota.rs" 9 | license = "Apache-2.0" 10 | keywords = [ "iota", "tangle", "client", "pow" ] 11 | homepage = "https://www.iota.org" 12 | 13 | [package.metadata.docs.rs] 14 | # To build locally: `RUSTDOCFLAGS="--cfg docsrs" cargo +nightly doc --all-features --no-deps --open` 15 | all-features = true 16 | rustdoc-args = [ "--cfg", "docsrs" ] 17 | 18 | [dependencies] 19 | iota-crypto = { version = "0.15.3", default-features = false, features = [ "blake2b", "digest", "curl-p", "ternary_encoding" ] } 20 | num_cpus = { version = "1.15.0", default-features = false } 21 | 22 | [target.'cfg(target_family = "wasm")'.dependencies] 23 | instant = { version = "0.1.12", default-features = false, features = [ "wasm-bindgen" ] } 24 | 25 | [dev-dependencies] 26 | iota-types = { path = "../types", default-features = false, features = [ "rand", "block" ] } 27 | -------------------------------------------------------------------------------- /pow/README.md: -------------------------------------------------------------------------------- 1 | # iota-pow 2 | 3 | Provides proof of work implementations and scoring for the IOTA protocol 4 | -------------------------------------------------------------------------------- /pow/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020-2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Provides proof of work implementations and scoring for the IOTA protocol. 5 | //! TIP . 6 | 7 | #![cfg_attr(docsrs, feature(doc_cfg))] 8 | #![deny(clippy::nursery, missing_docs, rust_2018_idioms, warnings)] 9 | #![allow( 10 | clippy::redundant_pub_crate, 11 | clippy::module_name_repetitions, 12 | clippy::missing_const_for_fn, 13 | clippy::significant_drop_in_scrutinee 14 | )] 15 | 16 | pub mod miner; 17 | pub mod score; 18 | #[cfg(target_family = "wasm")] 19 | pub mod wasm_miner; 20 | 21 | // Precomputed natural logarithm of 3 for performance reasons. 22 | // See https://oeis.org/A002391. 23 | const LN_3: f64 = 1.098_612_288_668_109; 24 | -------------------------------------------------------------------------------- /pow/tests/score.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020-2021 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // Tests are from: 5 | // https://github.com/iotaledger/tips/blob/main/tips/TIP-0012/tip-0012.md#example 6 | // https://github.com/Wollac/iota-crypto-demo/blob/master/pkg/pow/pow_test.go#L26 7 | 8 | use iota_pow::score::PowScorer; 9 | 10 | #[test] 11 | fn pow_score() { 12 | let mut pow = PowScorer::default(); 13 | 14 | let block: [u8; 21] = [ 15 | 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x21, 0x5e, 0xe6, 0xaa, 0xaa, 0xaa, 16 | 0xaa, 0xaa, 0xaa, 17 | ]; 18 | 19 | assert!((pow.score(&block) - 937.2857142857143).abs() < f64::EPSILON); 20 | 21 | let block: [u8; 8] = [0, 0, 0, 0, 0, 0, 0, 0]; 22 | 23 | assert!((pow.score(&block) - 3u128.pow(1) as f64 / 8_f64).abs() < f64::EPSILON); 24 | 25 | let block: [u8; 8] = [203, 124, 2, 0, 0, 0, 0, 0]; 26 | 27 | assert!((pow.score(&block) - 3u128.pow(10) as f64 / 8_f64).abs() < f64::EPSILON); 28 | 29 | let block: [u8; 8] = [65, 235, 119, 85, 85, 85, 85, 85]; 30 | 31 | assert!((pow.score(&block) - 3u128.pow(14) as f64 / 8_f64).abs() < f64::EPSILON); 32 | 33 | let block: [u8; 10000] = [0; 10000]; 34 | 35 | assert!((pow.score(&block) - 3u128.pow(0) as f64 / 10000_f64).abs() < f64::EPSILON); 36 | } 37 | -------------------------------------------------------------------------------- /rustfmt.toml: -------------------------------------------------------------------------------- 1 | version = "Two" 2 | comment_width = 120 3 | edition = "2021" 4 | format_code_in_doc_comments = true 5 | group_imports = "StdExternalCrate" 6 | imports_granularity = "Crate" 7 | max_width = 120 8 | normalize_comments = true 9 | normalize_doc_attributes = true 10 | wrap_comments = true 11 | -------------------------------------------------------------------------------- /types/README.md: -------------------------------------------------------------------------------- 1 | # `api` module 2 | 3 | Common types required by nodes and clients APIs like bodies, errors, responses and DTOs. 4 | 5 | # `block` module 6 | 7 | Strict implementations of: 8 | - [TIP-0011: Bech32 Address Format](https://github.com/iotaledger/tips/blob/main/tips/TIP-0011/tip-0011.md) 9 | - [TIP-0018: Multi-Asset Ledger and ISC Support](https://github.com/lzpap/tips/blob/master/tips/TIP-0018/tip-0018.md) 10 | - [TIP-0019: Dust Protection Based on Byte Costs](https://github.com/muXxer/protocol-rfcs/blob/master/tips/TIP-0019/tip-0019.md) 11 | - [TIP-0020: Transaction Payload with TIP-18 Output Types](https://github.com/lzpap/tips/blob/tx-updates/tips/TIP-0020/tip-0020.md) 12 | - [TIP-0023: Tagged Data Payload](https://github.com/Wollac/protocol-rfcs/blob/tagged-data/tips/TIP-0023/tip-0023.md) 13 | - [TIP-0024: Tangle Block](https://github.com/Wollac/protocol-rfcs/blob/tangle-message-data/tips/TIP-0024/tip-0024.md) 14 | - [TIP-0029: Milestone Payload](https://github.com/iotaledger/tips/blob/milestone-with-signature-blocks/tips/TIP-0029/tip-0029.md) 15 | -------------------------------------------------------------------------------- /types/fuzz/.gitignore: -------------------------------------------------------------------------------- 1 | artifacts 2 | corpus 3 | target 4 | -------------------------------------------------------------------------------- /types/fuzz/fuzz_targets/fuzz_address.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020-2021 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | #![no_main] 5 | 6 | use iota_types::block::address::Address; 7 | 8 | use libfuzzer_sys::fuzz_target; 9 | use packable::PackableExt; 10 | 11 | fuzz_target!(|data: &[u8]| { 12 | let _ = Address::unpack_verified(data.to_vec().as_slice()); 13 | }); 14 | -------------------------------------------------------------------------------- /types/fuzz/fuzz_targets/fuzz_block.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020-2021 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | #![no_main] 5 | 6 | use iota_types::block::Block; 7 | 8 | use libfuzzer_sys::fuzz_target; 9 | use packable::PackableExt; 10 | 11 | fuzz_target!(|data: &[u8]| { 12 | let _ = Block::unpack_strict(data.to_vec().as_slice(), &()); 13 | }); 14 | -------------------------------------------------------------------------------- /types/fuzz/fuzz_targets/fuzz_feature.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020-2021 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | #![no_main] 5 | 6 | use iota_types::block::output::Feature; 7 | 8 | use libfuzzer_sys::fuzz_target; 9 | use packable::PackableExt; 10 | 11 | fuzz_target!(|data: &[u8]| { 12 | let _ = Feature::unpack_verified(data.to_vec().as_slice()); 13 | }); 14 | -------------------------------------------------------------------------------- /types/fuzz/fuzz_targets/fuzz_input.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020-2021 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | #![no_main] 5 | 6 | use iota_types::block::input::Input; 7 | 8 | use libfuzzer_sys::fuzz_target; 9 | use packable::PackableExt; 10 | 11 | fuzz_target!(|data: &[u8]| { 12 | let _ = Input::unpack_verified(data.to_vec().as_slice()); 13 | }); 14 | -------------------------------------------------------------------------------- /types/fuzz/fuzz_targets/fuzz_output.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020-2021 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | #![no_main] 5 | 6 | use iota_types::block::output::Output; 7 | 8 | use libfuzzer_sys::fuzz_target; 9 | use packable::PackableExt; 10 | 11 | fuzz_target!(|data: &[u8]| { 12 | let _ = Output::unpack_verified(data.to_vec().as_slice()); 13 | }); 14 | -------------------------------------------------------------------------------- /types/fuzz/fuzz_targets/fuzz_payload.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020-2021 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | #![no_main] 5 | 6 | use iota_types::block::payload::Payload; 7 | 8 | use libfuzzer_sys::fuzz_target; 9 | use packable::PackableExt; 10 | 11 | fuzz_target!(|data: &[u8]| { 12 | let _ = Payload::unpack_verified(data.to_vec().as_slice()); 13 | }); 14 | -------------------------------------------------------------------------------- /types/fuzz/fuzz_targets/fuzz_signature.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020-2021 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | #![no_main] 5 | 6 | use iota_types::block::signature::Signature; 7 | 8 | use libfuzzer_sys::fuzz_target; 9 | use packable::PackableExt; 10 | 11 | fuzz_target!(|data: &[u8]| { 12 | let _ = Signature::unpack_verified(data.to_vec().as_slice()); 13 | }); 14 | -------------------------------------------------------------------------------- /types/fuzz/fuzz_targets/fuzz_unlock.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020-2021 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | #![no_main] 5 | 6 | use iota_types::block::unlock::Unlock; 7 | 8 | use libfuzzer_sys::fuzz_target; 9 | use packable::PackableExt; 10 | 11 | fuzz_target!(|data: &[u8]| { 12 | let _ = Unlock::unpack_verified(data.to_vec().as_slice()); 13 | }); 14 | -------------------------------------------------------------------------------- /types/fuzz/fuzz_targets/fuzz_unlock_condition.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020-2021 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | #![no_main] 5 | 6 | use iota_types::block::output::UnlockCondition; 7 | 8 | use libfuzzer_sys::fuzz_target; 9 | use packable::PackableExt; 10 | 11 | fuzz_target!(|data: &[u8]| { 12 | let _ = UnlockCondition::unpack_verified(data.to_vec().as_slice()); 13 | }); 14 | -------------------------------------------------------------------------------- /types/fuzz/src/fuzz_sorter.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | use iota_types::block::Block; 5 | 6 | use packable::{error::UnpackError, PackableExt}; 7 | 8 | use core::{ 9 | fs::{self, File, OpenOptions}, 10 | io::{self, prelude::*}, 11 | }; 12 | 13 | fn main() -> io::Result<()> { 14 | let paths = fs::read_dir("./corpus/fuzz_block")?; 15 | core::fs::create_dir_all("./corpus/errors")?; 16 | 17 | for path in paths { 18 | let file_name = format!( 19 | "{}", 20 | path.as_ref().unwrap().path().file_name().unwrap().to_str().unwrap() 21 | ); 22 | let mut file = File::open(path?.path())?; 23 | let mut buffer = Vec::new(); 24 | 25 | file.read_to_end(&mut buffer)?; 26 | 27 | if let Err(err) = Block::unpack_strict(buffer.as_slice(), &()) { 28 | if !matches!(err, UnpackError::Unpacker(..)) { 29 | let mut file = OpenOptions::new() 30 | .write(true) 31 | .truncate(true) 32 | .create(true) 33 | .open(format!("./corpus/errors/{}", file_name))?; 34 | file.write_all(&buffer)?; 35 | println!("{:?}", err); 36 | } 37 | } 38 | } 39 | 40 | Ok(()) 41 | } 42 | -------------------------------------------------------------------------------- /types/src/api/core/error.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020-2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | use crate::block::Error as BlockError; 5 | 6 | #[derive(Debug)] 7 | pub enum Error { 8 | InvalidField(&'static str), 9 | Block(BlockError), 10 | } 11 | 12 | impl core::fmt::Display for Error { 13 | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 14 | match self { 15 | Self::InvalidField(field) => write!(f, "invalid field \"{field}\""), 16 | Self::Block(error) => write!(f, "{error}"), 17 | } 18 | } 19 | } 20 | 21 | impl From for Error { 22 | fn from(error: BlockError) -> Self { 23 | Self::Block(error) 24 | } 25 | } 26 | 27 | #[cfg(feature = "std")] 28 | impl std::error::Error for Error {} 29 | -------------------------------------------------------------------------------- /types/src/api/core/mod.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020-2023 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Core API-related types like responses and DTOs. 5 | 6 | pub mod dto; 7 | pub mod error; 8 | pub mod response; 9 | -------------------------------------------------------------------------------- /types/src/api/mod.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2023 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! API-related types like responses and DTOs. 5 | 6 | #![allow(missing_docs)] 7 | 8 | pub mod core; 9 | pub mod plugins; 10 | -------------------------------------------------------------------------------- /types/src/api/plugins/indexer.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2023 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Node indexer responses. 5 | 6 | use core::ops::Deref; 7 | 8 | use serde::{Deserialize, Serialize}; 9 | 10 | use crate::block::output::OutputId; 11 | 12 | /// Response of GET /api/indexer/v1/* 13 | /// Returns the output_ids for the provided query parameters. 14 | #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] 15 | pub struct OutputIdsResponse { 16 | /// The ledger index at which the outputs were collected 17 | #[serde(rename = "ledgerIndex")] 18 | pub ledger_index: u32, 19 | /// Cursor confirmationMS+outputId.pageSize 20 | pub cursor: Option, 21 | /// The output ids 22 | pub items: Vec, 23 | } 24 | 25 | impl Deref for OutputIdsResponse { 26 | type Target = Vec; 27 | fn deref(&self) -> &Self::Target { 28 | &self.items 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /types/src/api/plugins/mod.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2023 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! INX plugin API-related types like responses and DTOs. 5 | 6 | pub mod indexer; 7 | pub mod participation; 8 | -------------------------------------------------------------------------------- /types/src/api/plugins/participation/error.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2023 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | #[derive(Debug)] 5 | pub enum Error { 6 | /// Invalid participations error 7 | InvalidParticipations, 8 | /// IO error 9 | Io(std::io::Error), 10 | } 11 | 12 | impl core::fmt::Display for Error { 13 | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 14 | match self { 15 | Self::InvalidParticipations => write!(f, "invalid participations"), 16 | Self::Io(error) => write!(f, "{error}"), 17 | } 18 | } 19 | } 20 | 21 | impl From for Error { 22 | fn from(error: std::io::Error) -> Self { 23 | Self::Io(error) 24 | } 25 | } 26 | 27 | #[cfg(feature = "std")] 28 | impl std::error::Error for Error {} 29 | -------------------------------------------------------------------------------- /types/src/api/plugins/participation/mod.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2023 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Node participation API. 5 | //! 6 | 7 | pub mod error; 8 | pub mod responses; 9 | pub mod types; 10 | -------------------------------------------------------------------------------- /types/src/block/block_id.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020-2021 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | impl_id!( 5 | pub BlockId, 6 | 32, 7 | "A block identifier, the BLAKE2b-256 hash of the block bytes. See for more information." 8 | ); 9 | 10 | #[cfg(feature = "serde")] 11 | string_serde_impl!(BlockId); 12 | -------------------------------------------------------------------------------- /types/src/block/dto.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | use primitive_types::U256; 5 | use serde::{Deserialize, Serialize}; 6 | 7 | /// Describes a U256. 8 | #[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)] 9 | pub struct U256Dto(pub String); 10 | 11 | impl From<&U256> for U256Dto { 12 | fn from(value: &U256) -> Self { 13 | Self(prefix_hex::encode(*value)) 14 | } 15 | } 16 | 17 | impl TryFrom<&U256Dto> for U256 { 18 | type Error = prefix_hex::Error; 19 | 20 | fn try_from(value: &U256Dto) -> Result { 21 | prefix_hex::decode(&value.0) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /types/src/block/helper.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | use crypto::hashes::{blake2b::Blake2b256, Digest}; 5 | 6 | /// Hashes a string network name to a digit network ID. 7 | pub fn network_name_to_id(network_name: &str) -> u64 { 8 | // PANIC: indexing and unwrapping is fine as a Blake2b256 digest has 32 bytes, we ask for 8 of them and we convert 9 | // that slice to an array of 8 bytes. 10 | u64::from_le_bytes(Blake2b256::digest(network_name.as_bytes())[0..8].try_into().unwrap()) 11 | } 12 | -------------------------------------------------------------------------------- /types/src/block/output/alias_id.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | use crate::block::output::OutputId; 5 | 6 | impl_id!(pub AliasId, 32, "TODO."); 7 | 8 | #[cfg(feature = "serde")] 9 | string_serde_impl!(AliasId); 10 | 11 | impl From<&OutputId> for AliasId { 12 | fn from(output_id: &OutputId) -> Self { 13 | Self::from(output_id.hash()) 14 | } 15 | } 16 | 17 | impl AliasId { 18 | /// 19 | pub fn or_from_output_id(self, output_id: &OutputId) -> Self { 20 | if self.is_null() { Self::from(output_id) } else { self } 21 | } 22 | } 23 | 24 | #[cfg(feature = "dto")] 25 | #[allow(missing_docs)] 26 | pub mod dto { 27 | use serde::{Deserialize, Serialize}; 28 | 29 | use super::*; 30 | use crate::block::error::dto::DtoError; 31 | 32 | #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] 33 | pub struct AliasIdDto(pub String); 34 | 35 | impl From<&AliasId> for AliasIdDto { 36 | fn from(value: &AliasId) -> Self { 37 | Self(value.to_string()) 38 | } 39 | } 40 | 41 | impl TryFrom<&AliasIdDto> for AliasId { 42 | type Error = DtoError; 43 | 44 | fn try_from(value: &AliasIdDto) -> Result { 45 | value.0.parse::().map_err(|_| DtoError::InvalidField("alias id")) 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /types/src/block/output/feature/issuer.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | use derive_more::From; 5 | 6 | use crate::block::address::Address; 7 | 8 | /// Identifies the validated issuer of the UTXO state machine. 9 | #[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, From, packable::Packable)] 10 | #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 11 | pub struct IssuerFeature(Address); 12 | 13 | impl IssuerFeature { 14 | /// The [`Feature`](crate::block::output::Feature) kind of an [`IssuerFeature`]. 15 | pub const KIND: u8 = 1; 16 | 17 | /// Creates a new [`IssuerFeature`]. 18 | #[inline(always)] 19 | pub fn new(address: Address) -> Self { 20 | Self(address) 21 | } 22 | 23 | /// Returns the issuer [`Address`]. 24 | #[inline(always)] 25 | pub fn address(&self) -> &Address { 26 | &self.0 27 | } 28 | } 29 | 30 | #[cfg(feature = "dto")] 31 | #[allow(missing_docs)] 32 | pub mod dto { 33 | use serde::{Deserialize, Serialize}; 34 | 35 | use crate::block::address::dto::AddressDto; 36 | 37 | #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] 38 | pub struct IssuerFeatureDto { 39 | #[serde(rename = "type")] 40 | pub kind: u8, 41 | pub address: AddressDto, 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /types/src/block/output/feature/sender.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | use derive_more::From; 5 | 6 | use crate::block::address::Address; 7 | 8 | /// Identifies the validated sender of an output. 9 | #[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, From, packable::Packable)] 10 | #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 11 | pub struct SenderFeature(Address); 12 | 13 | impl SenderFeature { 14 | /// The [`Feature`](crate::block::output::Feature) kind of a [`SenderFeature`]. 15 | pub const KIND: u8 = 0; 16 | 17 | /// Creates a new [`SenderFeature`]. 18 | #[inline(always)] 19 | pub fn new(address: Address) -> Self { 20 | Self(address) 21 | } 22 | 23 | /// Returns the sender [`Address`]. 24 | #[inline(always)] 25 | pub fn address(&self) -> &Address { 26 | &self.0 27 | } 28 | } 29 | 30 | #[cfg(feature = "dto")] 31 | #[allow(missing_docs)] 32 | pub mod dto { 33 | use serde::{Deserialize, Serialize}; 34 | 35 | use crate::block::address::dto::AddressDto; 36 | 37 | #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] 38 | pub struct SenderFeatureDto { 39 | #[serde(rename = "type")] 40 | pub kind: u8, 41 | pub address: AddressDto, 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /types/src/block/output/nft_id.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | use crate::block::output::OutputId; 5 | 6 | impl_id!(pub NftId, 32, "TODO."); 7 | 8 | #[cfg(feature = "serde")] 9 | string_serde_impl!(NftId); 10 | 11 | impl From<&OutputId> for NftId { 12 | fn from(output_id: &OutputId) -> Self { 13 | Self::from(output_id.hash()) 14 | } 15 | } 16 | 17 | impl NftId { 18 | /// 19 | pub fn or_from_output_id(self, output_id: &OutputId) -> Self { 20 | if self.is_null() { Self::from(output_id) } else { self } 21 | } 22 | } 23 | 24 | #[cfg(feature = "dto")] 25 | #[allow(missing_docs)] 26 | pub mod dto { 27 | use serde::{Deserialize, Serialize}; 28 | 29 | use super::*; 30 | use crate::block::error::dto::DtoError; 31 | 32 | #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] 33 | pub struct NftIdDto(pub String); 34 | 35 | impl From<&NftId> for NftIdDto { 36 | fn from(value: &NftId) -> Self { 37 | Self(value.to_string()) 38 | } 39 | } 40 | 41 | impl TryFrom<&NftIdDto> for NftId { 42 | type Error = DtoError; 43 | 44 | fn try_from(value: &NftIdDto) -> Result { 45 | value.0.parse::().map_err(|_| DtoError::InvalidField("NFT id")) 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /types/src/block/output/token_id.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | use crate::block::output::FoundryId; 5 | 6 | impl_id!(pub TokenId, 38, "TODO."); 7 | 8 | #[cfg(feature = "serde")] 9 | string_serde_impl!(TokenId); 10 | 11 | impl From for TokenId { 12 | fn from(foundry_id: FoundryId) -> Self { 13 | Self::new(*foundry_id) 14 | } 15 | } 16 | 17 | #[cfg(feature = "dto")] 18 | #[allow(missing_docs)] 19 | pub mod dto { 20 | use serde::{Deserialize, Serialize}; 21 | 22 | use super::*; 23 | use crate::block::error::dto::DtoError; 24 | 25 | /// Describes a token id. 26 | #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] 27 | pub struct TokenIdDto(pub String); 28 | 29 | impl From<&TokenId> for TokenIdDto { 30 | fn from(value: &TokenId) -> Self { 31 | Self(prefix_hex::encode(**value)) 32 | } 33 | } 34 | 35 | impl TryFrom<&TokenIdDto> for TokenId { 36 | type Error = DtoError; 37 | 38 | fn try_from(value: &TokenIdDto) -> Result { 39 | Ok(Self::new( 40 | prefix_hex::decode(&value.0).map_err(|_e| DtoError::InvalidField("tokenId"))?, 41 | )) 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /types/src/block/payload/milestone/milestone_id.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020-2021 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | impl_id!( 5 | pub MilestoneId, 6 | 32, 7 | "A milestone identifier, the BLAKE2b-256 hash of the milestone bytes. See for more information." 8 | ); 9 | 10 | #[cfg(feature = "serde")] 11 | string_serde_impl!(MilestoneId); 12 | -------------------------------------------------------------------------------- /types/src/block/payload/transaction/transaction_id.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020-2021 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | use core::ops::Deref; 5 | 6 | use crate::block::payload::milestone::MilestoneId; 7 | 8 | impl_id!( 9 | pub TransactionId, 10 | 32, 11 | "A transaction identifier, the BLAKE2b-256 hash of the transaction bytes. See for more information." 12 | ); 13 | 14 | #[cfg(feature = "serde")] 15 | string_serde_impl!(TransactionId); 16 | 17 | impl From for TransactionId { 18 | fn from(milestone_id: MilestoneId) -> Self { 19 | Self::new(*milestone_id.deref()) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /types/src/block/rand/address.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020-2021 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | use crate::block::{ 5 | address::{Address, AliasAddress, Ed25519Address, NftAddress}, 6 | output::{AliasId, NftId}, 7 | rand::{bytes::rand_bytes_array, number::rand_number}, 8 | }; 9 | 10 | /// Generates a random Ed25519 address. 11 | pub fn rand_ed25519_address() -> Ed25519Address { 12 | Ed25519Address::new(rand_bytes_array()) 13 | } 14 | 15 | /// Generates a random alias address. 16 | pub fn rand_alias_address() -> AliasAddress { 17 | AliasAddress::new(AliasId::from(rand_bytes_array())) 18 | } 19 | 20 | /// Generates a random NFT address. 21 | pub fn rand_nft_address() -> NftAddress { 22 | NftAddress::new(NftId::from(rand_bytes_array())) 23 | } 24 | 25 | /// Generates a random address. 26 | pub fn rand_address() -> Address { 27 | #[allow(clippy::modulo_one)] 28 | match rand_number::() % 3 { 29 | 0 => rand_ed25519_address().into(), 30 | 1 => rand_alias_address().into(), 31 | 2 => rand_nft_address().into(), 32 | _ => unreachable!(), 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /types/src/block/rand/block.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020-2021 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | use crate::block::{ 5 | parent::Parents, 6 | rand::{bytes::rand_bytes_array, number::rand_number, parents::rand_parents, payload::rand_payload_for_block}, 7 | Block, BlockBuilder, BlockId, 8 | }; 9 | 10 | /// Generates a random block id. 11 | pub fn rand_block_id() -> BlockId { 12 | BlockId::new(rand_bytes_array()) 13 | } 14 | 15 | /// Generates a vector of random block ids of a given length. 16 | pub fn rand_block_ids(len: usize) -> Vec { 17 | let mut parents = (0..len).map(|_| rand_block_id()).collect::>(); 18 | parents.sort_by(|a, b| a.as_ref().cmp(b.as_ref())); 19 | parents 20 | } 21 | 22 | /// Generates a random block with given parents. 23 | pub fn rand_block_with_parents(parents: Parents) -> Block { 24 | BlockBuilder::new(parents) 25 | .with_payload(rand_payload_for_block()) 26 | .with_nonce(rand_number()) 27 | .finish() 28 | .unwrap() 29 | } 30 | 31 | /// Generates a random block. 32 | pub fn rand_block() -> Block { 33 | rand_block_with_parents(rand_parents()) 34 | } 35 | -------------------------------------------------------------------------------- /types/src/block/rand/bool.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020-2021 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | use rand::Rng; 5 | 6 | /// Generates a random boolean. 7 | pub fn rand_bool() -> bool { 8 | rand::thread_rng().gen::() 9 | } 10 | -------------------------------------------------------------------------------- /types/src/block/rand/bytes.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020-2021 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | use rand::Rng; 5 | 6 | /// Generates a [`Vec`] of random bytes with a given length. 7 | pub fn rand_bytes(len: usize) -> Vec { 8 | (0..len).map(|_| rand::random::()).collect() 9 | } 10 | 11 | /// Generates an array of random bytes of length N. 12 | pub fn rand_bytes_array() -> [u8; N] { 13 | rand::thread_rng().gen::<[u8; N]>() 14 | } 15 | -------------------------------------------------------------------------------- /types/src/block/rand/input.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020-2021 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | use crate::block::{ 5 | input::{Input, TreasuryInput, UtxoInput}, 6 | rand::{milestone::rand_milestone_id, number::rand_number, output::rand_output_id}, 7 | }; 8 | 9 | /// Generates a random Utxo input. 10 | pub fn rand_utxo_input() -> UtxoInput { 11 | rand_output_id().into() 12 | } 13 | 14 | /// Generates a random treasury input. 15 | pub fn rand_treasury_input() -> TreasuryInput { 16 | TreasuryInput::new(rand_milestone_id()) 17 | } 18 | 19 | /// Generates a random input. 20 | pub fn rand_input() -> Input { 21 | match rand_number::() % 2 { 22 | 0 => rand_utxo_input().into(), 23 | 1 => rand_treasury_input().into(), 24 | _ => unreachable!(), 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /types/src/block/rand/milestone.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020-2021 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | use crate::block::{ 5 | payload::milestone::{MerkleRoot, MilestoneId, MilestoneIndex}, 6 | rand::{bytes::rand_bytes_array, number::rand_number}, 7 | }; 8 | 9 | /// Generates a random milestone index. 10 | pub fn rand_milestone_index() -> MilestoneIndex { 11 | MilestoneIndex::from(rand_number::()) 12 | } 13 | 14 | /// Generates a random milestone id. 15 | pub fn rand_milestone_id() -> MilestoneId { 16 | MilestoneId::new(rand_bytes_array()) 17 | } 18 | 19 | /// Generates a random merkle root. 20 | pub fn rand_merkle_root() -> MerkleRoot { 21 | MerkleRoot::from(rand_bytes_array()) 22 | } 23 | -------------------------------------------------------------------------------- /types/src/block/rand/milestone_option.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020-2021 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | use crate::block::{ 5 | payload::milestone::ReceiptMilestoneOption, 6 | rand::{ 7 | bool::rand_bool, milestone::rand_milestone_index, payload::rand_treasury_transaction_payload, 8 | receipt::rand_migrated_funds_entry, 9 | }, 10 | }; 11 | 12 | /// Generates a random receipt milestone option. 13 | pub fn rand_receipt_milestone_option(token_supply: u64) -> ReceiptMilestoneOption { 14 | ReceiptMilestoneOption::new( 15 | rand_milestone_index(), 16 | rand_bool(), 17 | vec![rand_migrated_funds_entry(token_supply)], 18 | rand_treasury_transaction_payload(token_supply), 19 | token_supply, 20 | ) 21 | .unwrap() 22 | } 23 | -------------------------------------------------------------------------------- /types/src/block/rand/mod.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020-2021 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | /// Module providing random address generation utilities. 5 | pub mod address; 6 | /// Module providing random block generation utilities. 7 | pub mod block; 8 | /// Module providing random boolean generation utilities. 9 | pub mod bool; 10 | /// Module providing random byte generation utilities. 11 | pub mod bytes; 12 | /// Module providing random input generation utilities. 13 | pub mod input; 14 | /// Module providing random milestone generation utilities. 15 | pub mod milestone; 16 | /// Module providing random milestone option generation utilities. 17 | pub mod milestone_option; 18 | /// Module providing random number generation utilities. 19 | pub mod number; 20 | /// Module providing random option generation utilities. 21 | pub mod option; 22 | /// Module providing random output generation utilities. 23 | pub mod output; 24 | /// Module providing random parents generation utilities. 25 | pub mod parents; 26 | /// Module providing random payload generation utilities. 27 | pub mod payload; 28 | /// Module providing random receipt generation utilities. 29 | pub mod receipt; 30 | /// Module providing random string generation utilities. 31 | pub mod string; 32 | /// Module providing random transaction generation utilities. 33 | pub mod transaction; 34 | -------------------------------------------------------------------------------- /types/src/block/rand/number.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020-2021 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | use rand::{ 5 | distributions::{ 6 | uniform::{SampleRange, SampleUniform}, 7 | Distribution, Standard, 8 | }, 9 | Rng, 10 | }; 11 | 12 | /// Generates a random number. 13 | pub fn rand_number() -> T 14 | where 15 | Standard: Distribution, 16 | { 17 | rand::thread_rng().gen() 18 | } 19 | 20 | /// Generates a random number within a given range. 21 | pub fn rand_number_range(range: R) -> T 22 | where 23 | T: SampleUniform + PartialOrd, 24 | R: SampleRange, 25 | { 26 | rand::thread_rng().gen_range(range) 27 | } 28 | -------------------------------------------------------------------------------- /types/src/block/rand/option.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020-2021 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | use crate::block::rand::bool::rand_bool; 5 | 6 | /// Generates a random generic option. 7 | pub fn rand_option(inner: T) -> Option { 8 | if rand_bool() { Some(inner) } else { None } 9 | } 10 | -------------------------------------------------------------------------------- /types/src/block/rand/parents.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020-2021 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | use crate::block::{ 5 | parent::Parents, 6 | rand::{block::rand_block_ids, number::rand_number_range}, 7 | }; 8 | 9 | /// Generates random parents. 10 | pub fn rand_parents() -> Parents { 11 | Parents::new(rand_block_ids(rand_number_range(Parents::COUNT_RANGE).into())).unwrap() 12 | } 13 | -------------------------------------------------------------------------------- /types/src/block/rand/receipt.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020-2021 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | use bytemuck::cast_slice; 5 | use crypto::encoding::ternary::{T5B1Buf, Tryte, TryteBuf}; 6 | 7 | use crate::block::{ 8 | payload::milestone::option::{MigratedFundsEntry, TailTransactionHash}, 9 | rand::{address::rand_address, number::rand_number_range, string::rand_string_charset}, 10 | }; 11 | 12 | /// Generates a random tail transaction hash. 13 | pub fn rand_tail_transaction_hash() -> TailTransactionHash { 14 | let bytes = rand_string_charset("ABCDEFGHIJKLMNOPQRSTUVWXYZ9", 81) 15 | .chars() 16 | .map(Tryte::try_from) 17 | .collect::>() 18 | .unwrap() 19 | .as_trits() 20 | .encode::(); 21 | 22 | TailTransactionHash::new(cast_slice(bytes.as_slice().as_i8_slice()).try_into().unwrap()).unwrap() 23 | } 24 | 25 | /// Generates a random migrated funds entry. 26 | pub fn rand_migrated_funds_entry(token_supply: u64) -> MigratedFundsEntry { 27 | MigratedFundsEntry::new( 28 | rand_tail_transaction_hash(), 29 | rand_address(), 30 | rand_number_range(MigratedFundsEntry::AMOUNT_MIN..token_supply), 31 | token_supply, 32 | ) 33 | .unwrap() 34 | } 35 | -------------------------------------------------------------------------------- /types/src/block/rand/string.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020-2021 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | use rand::{distributions::Alphanumeric, thread_rng, Rng}; 5 | 6 | /// Generates a random string with a given charset. 7 | pub fn rand_string_charset(charset: &str, len: usize) -> String { 8 | let charset = charset.as_bytes(); 9 | let mut rng = rand::thread_rng(); 10 | 11 | (0..len) 12 | .map(|_| charset[rng.gen_range(0..charset.len())] as char) 13 | .collect() 14 | } 15 | 16 | /// Generates a random string. 17 | pub fn rand_string(len: usize) -> String { 18 | String::from_utf8(thread_rng().sample_iter(&Alphanumeric).take(len).collect()).unwrap() 19 | } 20 | -------------------------------------------------------------------------------- /types/src/block/rand/transaction.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020-2021 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | use crate::block::{payload::transaction::TransactionId, rand::bytes::rand_bytes_array}; 5 | 6 | /// Generates a random transaction id. 7 | pub fn rand_transaction_id() -> TransactionId { 8 | TransactionId::new(rand_bytes_array()) 9 | } 10 | -------------------------------------------------------------------------------- /types/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020-2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Common types required by nodes and clients APIs like blocks, responses and DTOs. 5 | 6 | #![cfg_attr(not(feature = "std"), no_std)] 7 | #![cfg_attr(docsrs, feature(doc_cfg))] 8 | #![deny(clippy::nursery, missing_docs, rust_2018_idioms, warnings)] 9 | #![allow( 10 | clippy::redundant_pub_crate, 11 | clippy::module_name_repetitions, 12 | clippy::missing_const_for_fn, 13 | clippy::significant_drop_in_scrutinee 14 | )] 15 | 16 | extern crate alloc; 17 | #[cfg(feature = "std")] 18 | extern crate std; 19 | 20 | #[cfg(feature = "api")] 21 | pub mod api; 22 | #[cfg(feature = "block")] 23 | pub mod block; 24 | -------------------------------------------------------------------------------- /types/tests/address/mod.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020-2021 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | mod alias; 5 | mod ed25519; 6 | mod nft; 7 | 8 | use iota_types::block::{address::Address, Error}; 9 | 10 | const ED25519_ADDRESS_INVALID: &str = "0x52fdfc072182654f163f5f0f9a621d729566c74d10037c4d7bbb0407d1e2c64x"; 11 | 12 | #[test] 13 | fn invalid_bech32() { 14 | let address = Address::try_from_bech32(ED25519_ADDRESS_INVALID); 15 | 16 | assert!(matches!(address, Err(Error::InvalidAddress))); 17 | } 18 | -------------------------------------------------------------------------------- /types/tests/api/mod.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2023 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | mod participation; 5 | -------------------------------------------------------------------------------- /types/tests/ed25519_signature.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020-2021 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | use iota_types::block::signature::Ed25519Signature; 5 | use packable::PackableExt; 6 | 7 | const ED25519_PUBLIC_KEY: &str = "0x1da5ddd11ba3f961acab68fafee3177d039875eaa94ac5fdbff8b53f0c50bfb9"; 8 | const ED25519_SIGNATURE: &str = "0xc6a40edf9a089f42c18f4ebccb35fe4b578d93b879e99b87f63573324a710d3456b03fb6d1fcc027e6401cbd9581f790ee3ed7a3f68e9c225fcb9f1cd7b7110d"; 9 | 10 | #[test] 11 | fn kind() { 12 | assert_eq!(Ed25519Signature::KIND, 0); 13 | } 14 | 15 | #[test] 16 | fn packed_len() { 17 | let pub_key_bytes: [u8; 32] = prefix_hex::decode(ED25519_PUBLIC_KEY).unwrap(); 18 | let sig_bytes: [u8; 64] = prefix_hex::decode(ED25519_SIGNATURE).unwrap(); 19 | let sig = Ed25519Signature::new(pub_key_bytes, sig_bytes); 20 | 21 | assert_eq!(sig.packed_len(), 32 + 64); 22 | assert_eq!(sig.pack_to_vec().len(), 32 + 64); 23 | } 24 | 25 | #[test] 26 | fn pack_unpack_valid() { 27 | let pub_key_bytes: [u8; 32] = prefix_hex::decode(ED25519_PUBLIC_KEY).unwrap(); 28 | let sig_bytes: [u8; 64] = prefix_hex::decode(ED25519_SIGNATURE).unwrap(); 29 | let sig = Ed25519Signature::new(pub_key_bytes, sig_bytes); 30 | let sig_packed = sig.pack_to_vec(); 31 | 32 | assert_eq!(sig, PackableExt::unpack_verified(sig_packed.as_slice(), &()).unwrap()); 33 | } 34 | -------------------------------------------------------------------------------- /types/tests/foundry_id.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | use core::str::FromStr; 5 | 6 | use iota_types::block::{ 7 | address::AliasAddress, 8 | output::{AliasId, FoundryId, SimpleTokenScheme, TokenScheme}, 9 | }; 10 | use primitive_types::U256; 11 | 12 | #[test] 13 | fn getters() { 14 | let alias_address = AliasAddress::from( 15 | AliasId::from_str("0x52fdfc072182654f163f5f0f9a621d729566c74d10037c4d7bbb0407d1e2c649").unwrap(), 16 | ); 17 | let serial_number = 42; 18 | let token_scheme = 19 | TokenScheme::from(SimpleTokenScheme::new(U256::from(100u8), U256::from(0u8), U256::from(100u8)).unwrap()); 20 | let foundry_id = FoundryId::build(&alias_address, serial_number, token_scheme.kind()); 21 | 22 | assert_eq!(foundry_id.alias_address(), alias_address); 23 | assert_eq!(foundry_id.serial_number(), serial_number); 24 | assert_eq!(foundry_id.token_scheme_kind(), token_scheme.kind()); 25 | assert_eq!( 26 | foundry_id, 27 | FoundryId::from_str("0x0852fdfc072182654f163f5f0f9a621d729566c74d10037c4d7bbb0407d1e2c6492a00000000").unwrap() 28 | ); 29 | } 30 | -------------------------------------------------------------------------------- /types/tests/input/mod.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2023 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | mod treasury; 5 | mod utxo; 6 | -------------------------------------------------------------------------------- /types/tests/milestone_index.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020-2021 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | pub use iota_types::block::payload::milestone::MilestoneIndex; 5 | pub use packable::PackableExt; 6 | 7 | #[test] 8 | fn debug_impl() { 9 | assert_eq!(format!("{:?}", MilestoneIndex::new(0)), "MilestoneIndex(0)",); 10 | } 11 | 12 | #[test] 13 | fn display_impl() { 14 | assert_eq!(format!("{}", MilestoneIndex::new(0)), "0"); 15 | } 16 | 17 | #[test] 18 | fn unpack() { 19 | let packed = 0u32.pack_to_vec(); 20 | assert_eq!( 21 | MilestoneIndex::unpack_verified(packed.as_slice(), &()).unwrap(), 22 | MilestoneIndex(0) 23 | ); 24 | } 25 | 26 | #[test] 27 | fn add_u32() { 28 | let sum = MilestoneIndex(1) + 2; 29 | assert_eq!(sum, MilestoneIndex(3)); 30 | } 31 | 32 | #[test] 33 | fn add_other() { 34 | let sum = MilestoneIndex(1) + MilestoneIndex(2); 35 | assert_eq!(sum, MilestoneIndex(3)); 36 | } 37 | 38 | #[test] 39 | fn sub_u32() { 40 | let sub = MilestoneIndex(3) - 2; 41 | assert_eq!(sub, MilestoneIndex(1)); 42 | } 43 | 44 | #[test] 45 | fn sub_other() { 46 | let sub = MilestoneIndex(3) - MilestoneIndex(2); 47 | assert_eq!(sub, MilestoneIndex(1)); 48 | } 49 | -------------------------------------------------------------------------------- /types/tests/mod.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2023 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | mod address; 5 | mod api; 6 | mod input; 7 | -------------------------------------------------------------------------------- /types/tests/rent.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 IOTA Stiftung 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | use iota_types::block::{ 5 | output::{Output, Rent, RentStructure}, 6 | protocol::protocol_parameters, 7 | rand::output::{rand_alias_output, rand_basic_output, rand_foundry_output, rand_nft_output}, 8 | }; 9 | 10 | const BYTE_COST: u32 = 1; 11 | const FACTOR_KEY: u8 = 10; 12 | const FACTOR_DATA: u8 = 1; 13 | 14 | fn config() -> RentStructure { 15 | RentStructure::new(BYTE_COST, FACTOR_KEY, FACTOR_DATA) 16 | } 17 | 18 | fn output_in_range(output: Output, range: std::ops::RangeInclusive) { 19 | let cost = output.rent_cost(&config()); 20 | assert!(range.contains(&cost), "{output:#?} has a required byte cost of {cost}"); 21 | } 22 | 23 | #[test] 24 | fn valid_rent_cost_range() { 25 | let token_supply = protocol_parameters().token_supply(); 26 | 27 | output_in_range(Output::Alias(rand_alias_output(token_supply)), 445..=29_620); 28 | output_in_range(Output::Basic(rand_basic_output(token_supply)), 414..=13_485); 29 | output_in_range(Output::Foundry(rand_foundry_output(token_supply)), 496..=21_365); 30 | output_in_range(Output::Nft(rand_nft_output(token_supply)), 435..=21_734); 31 | } 32 | --------------------------------------------------------------------------------