├── .clang-format
├── .cmake_format.yaml
├── .github
├── CODEOWNERS
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ ├── config.yml
│ └── feature_request.md
├── SECURITY.md
├── SUPPORT.md
├── pull_request_template.md
└── workflows
│ ├── format.yml
│ ├── simple_test.yml
│ ├── test-modules.yml
│ └── test.yml
├── .gitignore
├── .mbedignore
├── .readthedocs.yml
├── .vscode
├── README.md
├── extensions.json
├── launch.json
└── settings.json
├── CHANGELOG.md
├── CMakeLists.txt
├── LICENSE
├── README.md
├── benchmark
├── CMakeLists.txt
├── README.md
├── benchmark_config.h
├── client
│ ├── send_tagged_data.c
│ └── send_tagged_data_max.c
├── core
│ ├── create_transaction_basic_output.c
│ ├── create_transaction_basic_output_full.c
│ └── create_transaction_basic_output_max.c
├── measure_heap_consumers.py
└── run_benchmark.sh
├── cmake
├── blake2.cmake
├── cjson.cmake
├── ed25519_donna.cmake
├── jemalloc.cmake
├── mbedtls.cmake
├── mosquitto.cmake
├── sodium.cmake
├── unity.cmake
└── uthash.cmake
├── docs
├── Doxyfile
├── Makefile
├── _static
│ └── .gitkeep
├── _templates
│ └── .gitkeep
├── api
│ ├── core.md
│ ├── crypto.md
│ ├── events.md
│ ├── restful.md
│ └── wallet.md
├── arduino_esp32.md
├── conf.py
├── examples.md
├── img
│ ├── arduino_examples.png
│ ├── arduino_include_zip.png
│ ├── arduino_preferences_sketchbook_location.png
│ ├── client_application_architecture.jpg
│ ├── client_block_diagram.jpg
│ └── github_download_zip.png
├── index.md
├── introduction.md
├── make.bat
└── requirements.txt
├── examples
├── CMakeLists.txt
├── README.md
├── arduino_esp32_info
│ └── arduino_esp32_info.ino
├── arduino_esp32_token_transfer
│ └── arduino_esp32_token_transfer.ino
├── client
│ ├── encrypted_tagged_data_block.c
│ ├── get_block.c
│ ├── get_event_blocks.c
│ ├── node_info.c
│ └── tagged_data_block.c
└── wallet
│ ├── create_alias_output.c
│ ├── mint_native_tokens.c
│ ├── send_basic_output.c
│ └── send_native_tokens.c
├── functional-tests
├── CMakeLists.txt
├── README.md
├── config.json
├── functional_app.c
├── functional_cases.c
└── functional_cases.h
├── iota-c.png
├── library.json
├── library.properties
├── src
├── CMakeLists.txt
├── client
│ ├── CMakeLists.txt
│ ├── api
│ │ ├── events
│ │ │ ├── node_event.c
│ │ │ ├── node_event.h
│ │ │ ├── sub_blocks_metadata.c
│ │ │ ├── sub_blocks_metadata.h
│ │ │ ├── sub_milestone_payload.c
│ │ │ ├── sub_milestone_payload.h
│ │ │ ├── sub_outputs_payload.c
│ │ │ ├── sub_outputs_payload.h
│ │ │ ├── sub_serialized_output.c
│ │ │ └── sub_serialized_output.h
│ │ ├── json_parser
│ │ │ ├── block.c
│ │ │ ├── block.h
│ │ │ ├── common.c
│ │ │ ├── common.h
│ │ │ ├── inputs
│ │ │ │ ├── inputs.c
│ │ │ │ └── inputs.h
│ │ │ ├── json_keys.h
│ │ │ ├── json_utils.c
│ │ │ ├── json_utils.h
│ │ │ ├── outputs
│ │ │ │ ├── features.c
│ │ │ │ ├── features.h
│ │ │ │ ├── native_tokens.c
│ │ │ │ ├── native_tokens.h
│ │ │ │ ├── output_alias.c
│ │ │ │ ├── output_alias.h
│ │ │ │ ├── output_basic.c
│ │ │ │ ├── output_basic.h
│ │ │ │ ├── output_foundry.c
│ │ │ │ ├── output_foundry.h
│ │ │ │ ├── output_nft.c
│ │ │ │ ├── output_nft.h
│ │ │ │ ├── outputs.c
│ │ │ │ ├── outputs.h
│ │ │ │ ├── unlock_conditions.c
│ │ │ │ └── unlock_conditions.h
│ │ │ ├── payloads
│ │ │ │ ├── payloads.c
│ │ │ │ └── payloads.h
│ │ │ ├── unlocks.c
│ │ │ └── unlocks.h
│ │ └── restful
│ │ │ ├── faucet_enqueue.c
│ │ │ ├── faucet_enqueue.h
│ │ │ ├── get_block.c
│ │ │ ├── get_block.h
│ │ │ ├── get_block_metadata.c
│ │ │ ├── get_block_metadata.h
│ │ │ ├── get_health.c
│ │ │ ├── get_health.h
│ │ │ ├── get_milestone.c
│ │ │ ├── get_milestone.h
│ │ │ ├── get_node_info.c
│ │ │ ├── get_node_info.h
│ │ │ ├── get_output.c
│ │ │ ├── get_output.h
│ │ │ ├── get_outputs_id.c
│ │ │ ├── get_outputs_id.h
│ │ │ ├── get_tips.c
│ │ │ ├── get_tips.h
│ │ │ ├── get_transaction_included_block.c
│ │ │ ├── get_transaction_included_block.h
│ │ │ ├── response_error.c
│ │ │ ├── response_error.h
│ │ │ ├── send_block.c
│ │ │ ├── send_block.h
│ │ │ ├── send_tagged_data.c
│ │ │ └── send_tagged_data.h
│ ├── client_service.h
│ ├── constants.h
│ └── network
│ │ ├── http.h
│ │ ├── http_curl.c
│ │ ├── http_esp32.c
│ │ ├── http_zephyr.c
│ │ └── mqtt
│ │ ├── mqtt.h
│ │ ├── mqtt_esp32.c
│ │ └── mqtt_mosquitto.c
├── core
│ ├── CMakeLists.txt
│ ├── address.c
│ ├── address.h
│ ├── constants.h
│ ├── models
│ │ ├── block.c
│ │ ├── block.h
│ │ ├── inputs
│ │ │ ├── utxo_input.c
│ │ │ └── utxo_input.h
│ │ ├── outputs
│ │ │ ├── byte_cost_config.c
│ │ │ ├── byte_cost_config.h
│ │ │ ├── features.c
│ │ │ ├── features.h
│ │ │ ├── native_tokens.c
│ │ │ ├── native_tokens.h
│ │ │ ├── output_alias.c
│ │ │ ├── output_alias.h
│ │ │ ├── output_basic.c
│ │ │ ├── output_basic.h
│ │ │ ├── output_foundry.c
│ │ │ ├── output_foundry.h
│ │ │ ├── output_nft.c
│ │ │ ├── output_nft.h
│ │ │ ├── outputs.c
│ │ │ ├── outputs.h
│ │ │ ├── storage_deposit.c
│ │ │ ├── storage_deposit.h
│ │ │ ├── unlock_conditions.c
│ │ │ └── unlock_conditions.h
│ │ ├── payloads
│ │ │ ├── milestone.c
│ │ │ ├── milestone.h
│ │ │ ├── tagged_data.c
│ │ │ ├── tagged_data.h
│ │ │ ├── transaction.c
│ │ │ └── transaction.h
│ │ ├── signing.c
│ │ ├── signing.h
│ │ ├── unlocks.c
│ │ └── unlocks.h
│ └── utils
│ │ ├── allocator.h
│ │ ├── bech32.c
│ │ ├── bech32.h
│ │ ├── byte_buffer.c
│ │ ├── byte_buffer.h
│ │ ├── iota_str.c
│ │ ├── iota_str.h
│ │ ├── macros.h
│ │ ├── slip10.c
│ │ ├── slip10.h
│ │ ├── uint256.c
│ │ └── uint256.h
├── crypto
│ ├── CMakeLists.txt
│ ├── constants.h
│ ├── iota_crypto.c
│ └── iota_crypto.h
├── iota_client.h
└── wallet
│ ├── CMakeLists.txt
│ ├── bip39.c
│ ├── bip39.h
│ ├── output_alias.c
│ ├── output_alias.h
│ ├── output_basic.c
│ ├── output_basic.h
│ ├── output_foundry.c
│ ├── output_foundry.h
│ ├── wallet.c
│ ├── wallet.h
│ └── wordlists
│ ├── README.md
│ ├── chinese_simplified.h
│ ├── chinese_simplified.txt
│ ├── chinese_traditional.h
│ ├── chinese_traditional.txt
│ ├── czech.h
│ ├── czech.txt
│ ├── english.h
│ ├── english.txt
│ ├── french.h
│ ├── french.txt
│ ├── italian.h
│ ├── italian.txt
│ ├── japanese.h
│ ├── japanese.txt
│ ├── korean.h
│ ├── korean.txt
│ ├── portuguese.h
│ ├── portuguese.txt
│ ├── spanish.h
│ ├── spanish.txt
│ ├── word.h
│ └── wordlist_header.py
├── tests
├── CMakeLists.txt
├── client
│ ├── api_events
│ │ ├── test_blocks_events.c
│ │ ├── test_milestones_events.c
│ │ ├── test_outputs_payloads.c
│ │ └── test_serialized_blocks_events.c
│ ├── api_json_parser
│ │ ├── test_common.c
│ │ ├── test_features.c
│ │ ├── test_inputs.c
│ │ ├── test_native_tokens.c
│ │ ├── test_output_alias.c
│ │ ├── test_output_basic.c
│ │ ├── test_output_foundry.c
│ │ ├── test_output_nft.c
│ │ ├── test_outputs.c
│ │ ├── test_unlock_conditions.c
│ │ └── test_unlocks.c
│ ├── api_restful
│ │ ├── test_block_meta.c
│ │ ├── test_faucet_enqueue.c
│ │ ├── test_get_block.c
│ │ ├── test_get_health.c
│ │ ├── test_get_info.c
│ │ ├── test_get_milestone.c
│ │ ├── test_get_output.c
│ │ ├── test_get_tips.c
│ │ ├── test_get_transaction_included_block.c
│ │ ├── test_outputs_id.c
│ │ ├── test_response_error.c
│ │ ├── test_send_block.c
│ │ └── test_send_tagged_data.c
│ ├── test_http.c
│ └── test_json.c
├── core
│ ├── slip10_vector.h
│ ├── test_address.c
│ ├── test_allocator.c
│ ├── test_block.c
│ ├── test_byte_buffer.c
│ ├── test_byte_cost_config.c
│ ├── test_condition_blocks.c
│ ├── test_features.c
│ ├── test_inputs.c
│ ├── test_iota_str.c
│ ├── test_native_tokens.c
│ ├── test_output_alias.c
│ ├── test_output_basic.c
│ ├── test_output_foundry.c
│ ├── test_output_nft.c
│ ├── test_outputs.c
│ ├── test_slip10.c
│ ├── test_storage_deposit.c
│ ├── test_tagged_data.c
│ ├── test_transaction.c
│ ├── test_transaction_alias.c
│ ├── test_transaction_nft.c
│ ├── test_uint256.c
│ ├── test_unlocks.c
│ └── test_utils_bech32.c
├── crypto
│ ├── blake2b_data.h
│ ├── ed25519_sign.input
│ ├── ed25519_signature_edges.h
│ ├── pbkdf2_vectors.h
│ ├── pbkdf2_vectors.py
│ └── test_crypto.c
├── test_config.h
└── wallet
│ ├── mnemonic_vectors.h
│ ├── test_bip39.c
│ └── test_wallet.c
└── tools
├── ci_format_check
├── formatter
└── hooks
├── autohook.sh
├── pre-commit
└── 01-format-check
└── scripts
└── format_check
/.clang-format:
--------------------------------------------------------------------------------
1 | ---
2 | Language: Cpp
3 | # BasedOnStyle: Google
4 | AccessModifierOffset: -1
5 | AlignAfterOpenBracket: Align
6 | AlignConsecutiveAssignments: false
7 | AlignConsecutiveDeclarations: false
8 | AlignEscapedNewlines: Left
9 | AlignOperands: true
10 | AlignTrailingComments: true
11 | AllowAllParametersOfDeclarationOnNextLine: true
12 | AllowShortBlocksOnASingleLine: false
13 | AllowShortCaseLabelsOnASingleLine: false
14 | AllowShortFunctionsOnASingleLine: All
15 | AllowShortIfStatementsOnASingleLine: true
16 | AllowShortLoopsOnASingleLine: true
17 | AlwaysBreakAfterDefinitionReturnType: None
18 | AlwaysBreakAfterReturnType: None
19 | AlwaysBreakBeforeMultilineStrings: true
20 | AlwaysBreakTemplateDeclarations: true
21 | BinPackArguments: true
22 | BinPackParameters: true
23 | BraceWrapping:
24 | AfterClass: false
25 | AfterControlStatement: false
26 | AfterEnum: false
27 | AfterFunction: false
28 | AfterNamespace: false
29 | AfterObjCDeclaration: false
30 | AfterStruct: false
31 | AfterUnion: false
32 | BeforeCatch: false
33 | BeforeElse: false
34 | IndentBraces: false
35 | SplitEmptyFunction: true
36 | SplitEmptyRecord: true
37 | SplitEmptyNamespace: true
38 | BreakBeforeBinaryOperators: None
39 | BreakBeforeBraces: Attach
40 | BreakBeforeInheritanceComma: false
41 | BreakBeforeTernaryOperators: true
42 | BreakConstructorInitializersBeforeComma: false
43 | BreakConstructorInitializers: BeforeColon
44 | BreakAfterJavaFieldAnnotations: false
45 | BreakStringLiterals: true
46 | ColumnLimit: 120
47 | CommentPragmas: '^ IWYU pragma:'
48 | CompactNamespaces: false
49 | ConstructorInitializerAllOnOneLineOrOnePerLine: true
50 | ConstructorInitializerIndentWidth: 4
51 | ContinuationIndentWidth: 4
52 | Cpp11BracedListStyle: true
53 | DerivePointerAlignment: true
54 | DisableFormat: false
55 | ExperimentalAutoDetectBinPacking: false
56 | FixNamespaceComments: true
57 | ForEachMacros:
58 | - foreach
59 | - Q_FOREACH
60 | - BOOST_FOREACH
61 | IncludeCategories:
62 | - Regex: '^<.*\.h>'
63 | Priority: 1
64 | - Regex: '^<.*'
65 | Priority: 2
66 | - Regex: '.*'
67 | Priority: 3
68 | IncludeIsMainRegex: '([-_](test|unittest))?$'
69 | IndentCaseLabels: true
70 | IndentWidth: 2
71 | IndentWrappedFunctionNames: false
72 | JavaScriptQuotes: Leave
73 | JavaScriptWrapImports: true
74 | KeepEmptyLinesAtTheStartOfBlocks: false
75 | MacroBlockBegin: ''
76 | MacroBlockEnd: ''
77 | MaxEmptyLinesToKeep: 1
78 | NamespaceIndentation: None
79 | ObjCBlockIndentWidth: 2
80 | ObjCSpaceAfterProperty: false
81 | ObjCSpaceBeforeProtocolList: false
82 | PenaltyBreakAssignment: 2
83 | PenaltyBreakBeforeFirstCallParameter: 1
84 | PenaltyBreakComment: 300
85 | PenaltyBreakFirstLessLess: 120
86 | PenaltyBreakString: 1000
87 | PenaltyExcessCharacter: 1000000
88 | PenaltyReturnTypeOnItsOwnLine: 200
89 | PointerAlignment: Left
90 | ReflowComments: true
91 | SortIncludes: true
92 | SortUsingDeclarations: true
93 | SpaceAfterCStyleCast: false
94 | SpaceAfterTemplateKeyword: true
95 | SpaceBeforeAssignmentOperators: true
96 | SpaceBeforeParens: ControlStatements
97 | SpaceInEmptyParentheses: false
98 | SpacesBeforeTrailingComments: 2
99 | SpacesInAngles: false
100 | SpacesInContainerLiterals: true
101 | SpacesInCStyleCastParentheses: false
102 | SpacesInParentheses: false
103 | SpacesInSquareBrackets: false
104 | Standard: Auto
105 | TabWidth: 8
106 | UseTab: Never
107 | ---
108 |
--------------------------------------------------------------------------------
/.cmake_format.yaml:
--------------------------------------------------------------------------------
1 | _help_format: Options affecting formatting.
2 | format:
3 | _help_line_width:
4 | - How wide to allow formatted cmake files
5 | line_width: 120
6 | _help_tab_size:
7 | - How many spaces to tab for indent
8 | tab_size: 2
9 | _help_max_pargs_hwrap:
10 | - If a positional argument group contains more than this many
11 | - arguments, then force it to a vertical layout.
12 | max_pargs_hwrap: 4
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/about-codeowners/
2 | # for more details about CODEOWNERS file
3 |
4 | * @iotaledger/client-c
5 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Report a bug in the C client library
3 | about: Report a bug
4 | labels: bug
5 | ---
6 |
7 | ## Bug description
8 |
9 | Briefly describe the bug.
10 |
11 | ## Version
12 |
13 | Which version of the library are you running?
14 |
15 | - Version:
16 |
17 | ## IOTA network
18 |
19 | Which node are you connected to and which IOTA network is it in?
20 |
21 | - Node URL:
22 | - Network:
23 |
24 | ## Hardware specification
25 |
26 | What hardware are you using?
27 |
28 | - Operating system:
29 | - RAM:
30 | - Number of cores:
31 | - Device type:
32 | ## Compiler and build tool specification
33 |
34 | What compiler are you using?
35 |
36 | What build tool are you using?
37 | Bazel/Bazelisk/CMake
38 |
39 | ## Steps To reproduce the bug
40 |
41 | Explain how the maintainer can reproduce the bug.
42 |
43 | 1.
44 | 2.
45 | 3.
46 |
47 | ## Expected behaviour
48 |
49 | Describe what you expect to happen.
50 |
51 | ## Actual behaviour
52 |
53 | Describe what actually happens.
54 |
55 | ## Errors
56 |
57 | Paste any errors that you see.
58 |
--------------------------------------------------------------------------------
/.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.
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Request a feature for the C client library
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/SECURITY.md:
--------------------------------------------------------------------------------
1 |
Responsible disclosure policy
2 |
3 | At the IOTA Foundation, we consider the security of our systems a top priority. But no matter how much effort we put into system security, there can still be vulnerabilities present. If you've discovered a vulnerability, please follow the guidelines below to report it to our security team:
4 |
5 | - E-mail your findings to security@iota.org. If the report contains highly sensitive information, please consider encrypting your findings using our contact@iota.org (466385BD0B40D9550F93C04746A440CCE5664A64) PGP key.
6 |
7 | Please follow these rules when testing/reporting vulnerabilities:
8 |
9 | - Do not take advantage of the vulnerability you have discovered, for example by downloading more data than is necessary to demonstrate the vulnerability.
10 | - Do not read, modify or delete data that isn't your own.
11 | - We ask that you do not to disclosure the problem to third parties until it has been resolved.
12 | - The scope of the program is limited to technical vulnerabilities in IOTA Foundations's web applications and open source software packages distributed through GitHub, please do not try to test physical security or attempt phishing attacks against our employees, and so on.
13 | - Out of concern for the availability of our services to all users, please do not attempt to carry out DoS attacks, leverage black hat SEO techniques, spam people, and do other similarly questionable things. We also discourage the use of any vulnerability testing tools that automatically generate significant volumes of traffic.
14 |
15 | What we promise:
16 |
17 | - We will respond to your report within 3 business days with our evaluation of the report and an expected resolution date.
18 | - If you have followed the instructions above, we will not take any legal action against you in regard to the report.
19 | - We will keep you informed during all stages of resolving the problem.
20 | - To show our appreciation for your effort and cooperation during the report, we will list your name and a link to a personal website/social network profile on the page below so that the public can know you've helped keep the IOTA Foundation secure.
21 |
22 | We sincerely appreciate the efforts of security researchers in keeping our community safe.
23 |
24 |
--------------------------------------------------------------------------------
/.github/SUPPORT.md:
--------------------------------------------------------------------------------
1 | # Community resources
2 |
3 | If you have a general or technical question, you can use one of the following resources instead of submitting an issue:
4 |
5 | - [**Developer documentation:**](https://docs.iota.org/) For official information about developing with IOTA technology
6 | - [**Discord:**](https://discord.iota.org/) For real-time chats with the developers and community members
7 | - [**IOTA cafe:**](https://iota.cafe/) For technical discussions with the Research and Development Department at the IOTA Foundation
8 | - [**StackExchange:**](https://iota.stackexchange.com/) For technical and troubleshooting questions
--------------------------------------------------------------------------------
/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 | # Description of change
2 |
3 | Please write a summary of your changes and why you made them. Be sure to reference any related issues by adding `fixes # (issue)`.
4 |
5 | ## Type of change
6 |
7 | Choose a type of change, and delete any options that are not relevant.
8 |
9 | - Bugfix (a non-breaking change which fixes an issue)
10 | - Enhancement (a non-breaking change which adds functionality)
11 | - Breaking change (fix or feature that would cause existing functionality to not work as expected)
12 | - Documentation fix
13 |
14 | ## How the change has been tested
15 |
16 | Describe the tests that you ran to verify your changes.
17 |
18 | Make sure to provide instructions for the maintainer as well as any relevant configurations.
19 |
20 | ## Change checklist
21 |
22 | Add an `x` to the boxes that are relevant to your changes, and delete any items that are not.
23 |
24 | - [ ] My code follows the contribution guidelines for this project
25 | - [ ] I have performed a self-review of my own code
26 | - [ ] I have commented my code, particularly in hard-to-understand areas
27 | - [ ] I have made corresponding changes to the documentation
28 | - [ ] I have added tests using CTest that prove my fix is effective or that my feature works
29 | - [ ] New and existing unit tests pass locally with my changes
30 |
--------------------------------------------------------------------------------
/.github/workflows/format.yml:
--------------------------------------------------------------------------------
1 | # coding style and static checks
2 |
3 | name: coding-style
4 |
5 | on: [push, pull_request]
6 |
7 | jobs:
8 | coding_style:
9 | runs-on: ubuntu-20.04
10 |
11 | steps:
12 | - uses: actions/checkout@v2
13 |
14 | - name: install requirements
15 | run: |
16 | sudo apt update
17 | sudo apt install -y cppcheck clang-format-12
18 | sudo pip3 install cmakelang
19 |
20 | - name: Coding style check
21 | run: ./tools/ci_format_check src tests examples
22 |
23 | - name: Static analysis check
24 | run: |
25 | cppcheck --version
26 | cppcheck --force --error-exitcode=1 -q src tests examples
27 |
--------------------------------------------------------------------------------
/.github/workflows/simple_test.yml:
--------------------------------------------------------------------------------
1 | # a simple check
2 | name: simple_test
3 |
4 | on:
5 | push:
6 | branches:
7 | - tokenization-sc
8 | pull_request:
9 | branches:
10 | - tokenization-sc
11 | env:
12 | CTEST_OUTPUT_ON_FAILURE: TRUE
13 |
14 | jobs:
15 | simple_make_gcc_openssl:
16 | runs-on: ubuntu-20.04
17 |
18 | steps:
19 | - uses: actions/checkout@v2
20 |
21 | - name: install requirements
22 | run: |
23 | sudo apt update
24 | sudo apt install -y libcurl4-openssl-dev clang-format build-essential
25 |
26 | - name: Debug build
27 | run: |
28 | cmake --version
29 | gcc --version
30 | mkdir build && cd build
31 | cmake -DCMAKE_INSTALL_PREFIX=$PWD -DIOTA_TESTS=ON -DIOTA_ASAN_ENABLED=ON -DCryptoUse=openssl ..
32 | make -j8 && make test
33 |
34 | - name: Release build
35 | run: |
36 | rm -rf build && sync
37 | mkdir build && cd build
38 | cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD -DIOTA_TESTS=ON -DCryptoUse=openssl ..
39 | make -j8 && make test
40 |
--------------------------------------------------------------------------------
/.github/workflows/test-modules.yml:
--------------------------------------------------------------------------------
1 | # Build and test by modules
2 |
3 | name: test-modules
4 | on:
5 | push:
6 | branches:
7 | - production
8 | - staging
9 | - dev*
10 | pull_request:
11 | branches:
12 | - production
13 | - staging
14 | - dev*
15 | env:
16 | CTEST_OUTPUT_ON_FAILURE: TRUE
17 |
18 | jobs:
19 | ninja_clang_check_modules:
20 | runs-on: ubuntu-20.04
21 | steps:
22 | - uses: actions/checkout@v2
23 |
24 | - name: install requirements
25 | run: |
26 | sudo apt update
27 | sudo apt install -y ninja-build libcurl4-openssl-dev build-essential
28 |
29 | - name: Build Crypto
30 | run: |
31 | cmake --version
32 | clang --version
33 | mkdir build && cd build
34 | cmake -G Ninja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_INSTALL_PREFIX=$PWD -DCryptoUse=openssl -DIOTA_ASAN_ENABLED=ON -DIOTA_WALLET_ENABLE=OFF -DWITH_IOTA_CLIENT=OFF -DWITH_IOTA_CORE=OFF ..
35 | ninja -v && ninja test
36 |
37 | - name: Build Core
38 | run: |
39 | rm -rf build && sync
40 | mkdir build && cd build
41 | cmake -G Ninja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_INSTALL_PREFIX=$PWD -DCryptoUse=openssl -DIOTA_ASAN_ENABLED=ON -DIOTA_WALLET_ENABLE=OFF -DWITH_IOTA_CLIENT=OFF -DWITH_IOTA_CORE=ON ..
42 | ninja && ninja test
43 |
44 | - name: Build Client
45 | run: |
46 | rm -rf build && sync
47 | mkdir build && cd build
48 | cmake -G Ninja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_INSTALL_PREFIX=$PWD -DCryptoUse=openssl -DIOTA_ASAN_ENABLED=ON -DIOTA_WALLET_ENABLE=OFF -DWITH_IOTA_CLIENT=ON -DWITH_IOTA_CORE=OFF ..
49 | ninja && ninja test
50 |
51 | - name: Build Wallet
52 | run: |
53 | rm -rf build && sync
54 | mkdir build && cd build
55 | cmake -G Ninja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_INSTALL_PREFIX=$PWD -DCryptoUse=openssl -DIOTA_ASAN_ENABLED=ON -DIOTA_WALLET_ENABLE=ON -DWITH_IOTA_CLIENT=OFF -DWITH_IOTA_CORE=OFF ..
56 | ninja && ninja test
57 |
58 | - name: Build Examples
59 | run: |
60 | rm -rf build && sync
61 | mkdir build && cd build
62 | cmake -G Ninja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_INSTALL_PREFIX=$PWD -DCryptoUse=openssl -DIOTA_ASAN_ENABLED=ON -DIOTA_WALLET_ENABLE=ON -DWITH_IOTA_CLIENT=OFF -DWITH_IOTA_CORE=OFF -DIOTA_EXAMPLES=ON ..
63 | ninja && ninja test
64 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | # Build and Test with different crypto libs and compilers
2 |
3 | name: tests
4 | on:
5 | push:
6 | branches:
7 | - production
8 | - staging
9 | - dev*
10 | pull_request:
11 | branches:
12 | - production
13 | - staging
14 | - dev*
15 | env:
16 | CTEST_OUTPUT_ON_FAILURE: TRUE
17 |
18 | jobs:
19 | ninja_clang_sodium:
20 | runs-on: ubuntu-20.04
21 | steps:
22 | - uses: actions/checkout@v2
23 |
24 | - name: install requirements
25 | run: |
26 | sudo apt update
27 | sudo apt install -y ninja-build libcurl4-openssl-dev build-essential
28 |
29 | - name: Debug build
30 | run: |
31 | cmake --version
32 | clang --version
33 | mkdir build && cd build
34 | cmake -G Ninja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_INSTALL_PREFIX=$PWD -DCryptoUse=libsodium -DIOTA_ASAN_ENABLED=ON -DIOTA_WALLET_ENABLE=ON ..
35 | ninja -v && ninja test
36 |
37 | - name: Release build
38 | run: |
39 | rm -rf build && sync
40 | mkdir build && cd build
41 | cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_INSTALL_PREFIX=$PWD -DCryptoUse=libsodium -DIOTA_WALLET_ENABLE=ON ..
42 | ninja && ninja test
43 |
44 | make_gcc_openssl:
45 | runs-on: ubuntu-20.04
46 | steps:
47 | - uses: actions/checkout@v2
48 |
49 | - name: install requirements
50 | run: |
51 | sudo apt update
52 | sudo apt install -y libcurl4-openssl-dev clang-format build-essential
53 |
54 | - name: Debug build
55 | run: |
56 | cmake --version
57 | gcc --version
58 | mkdir build && cd build
59 | cmake -DCMAKE_INSTALL_PREFIX=$PWD -DIOTA_TESTS=ON -DIOTA_ASAN_ENABLED=ON -DCryptoUse=openssl ..
60 | make -j8 && make test
61 |
62 | - name: Release build
63 | run: |
64 | rm -rf build && sync
65 | mkdir build && cd build
66 | cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD -DIOTA_TESTS=ON -DCryptoUse=openssl ..
67 | make -j8 && make test
68 |
69 | make_gcc_mbedtls:
70 | runs-on: ubuntu-20.04
71 | steps:
72 | - uses: actions/checkout@v2
73 |
74 | - name: install requirements
75 | run: |
76 | sudo apt update
77 | sudo apt install -y libcurl4-openssl-dev clang-format build-essential
78 |
79 | - name: Debug build
80 | run: |
81 | cmake --version
82 | gcc --version
83 | mkdir build && cd build
84 | cmake -DCMAKE_INSTALL_PREFIX=$PWD -DIOTA_TESTS=ON -DIOTA_ASAN_ENABLED=ON -DCryptoUse=mbedtls ..
85 | make -j8 && make test
86 |
87 | - name: Release build
88 | run: |
89 | rm -rf build && sync
90 | mkdir build && cd build
91 | cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD -DIOTA_TESTS=ON -DCryptoUse=mbedtls ..
92 | make -j8 && make test
93 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Bazel
2 | bazel-*
3 | user.bazelrc
4 |
5 | # CMake
6 | build
7 |
8 | # VS Code
9 | .vscode
10 |
11 | # CLion
12 | .idea
13 |
14 | # Sphinx build dir
15 | docs/_build
16 | docs/doxygen_build
17 |
--------------------------------------------------------------------------------
/.mbedignore:
--------------------------------------------------------------------------------
1 | cmake/*
2 | docs/*
3 | examples/*
4 | tests/*
5 | tools/*
6 | src/client/*
7 | src/wallet/*
8 | library.json
9 |
--------------------------------------------------------------------------------
/.readthedocs.yml:
--------------------------------------------------------------------------------
1 | # .readthedocs.yml
2 | # Read the Docs configuration file
3 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
4 |
5 | # Required
6 | version: 2
7 |
8 | # Build documentation in the docs/ directory with Sphinx
9 | sphinx:
10 | configuration: docs/conf.py
11 |
12 | # Optionally build your docs in additional formats such as PDF
13 | formats:
14 | - pdf
15 |
16 | # Optionally set the version of Python and requirements required to build your docs
17 | python:
18 | version: 3.7
19 | install:
20 | - requirements: docs/requirements.txt
21 |
--------------------------------------------------------------------------------
/.vscode/README.md:
--------------------------------------------------------------------------------
1 | # VS Code Integration
2 |
3 | ## Extension Requirements
4 |
5 | * [CMake Tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools)
6 | * [C/C++ for Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools)
7 | * [Clang-Format](https://marketplace.visualstudio.com/items?itemName=xaver.clang-format)
8 | * [cmake-format](https://marketplace.visualstudio.com/items?itemName=cheshirekow.cmake-format)
9 |
10 | see `.vscode/extensions.json`
11 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "ms-vscode.cmake-tools",
4 | "ms-vscode.cpptools",
5 | "xaver.clang-format",
6 | "cheshirekow.cmake-format"
7 | ]
8 | }
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // Use IntelliSense to learn about possible attributes.
3 | // Hover to view descriptions of existing attributes.
4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 | "version": "0.2.0",
6 | "configurations": [
7 | {
8 | "name": "(gdb)launch",
9 | "type": "cppdbg",
10 | "request": "launch",
11 | "program": "${command:cmake.launchTargetPath}",
12 | "args": [],
13 | "stopAtEntry": true,
14 | "cwd": "${workspaceFolder}",
15 | "environment": [
16 | {
17 | "name": "PATH",
18 | "value": "$PATH:${command:cmake.launchTargetDirectory}"
19 | }
20 | ],
21 | "externalConsole": false,
22 | "MIMode": "gdb",
23 | "setupCommands": [
24 | {
25 | "description": "Enable pretty-printing for gdb",
26 | "text": "-enable-pretty-printing",
27 | "ignoreFailures": true
28 | }
29 | ]
30 | }
31 | ]
32 | }
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "editor.tabSize": 2,
3 | "cmake.installPrefix": "${workspaceFolder}/build",
4 | "cmake.buildDirectory": "${workspaceFolder}/build",
5 | "cmake.configureArgs": [
6 | "-DCryptoUse:STRING=openssl",
7 | "-DIOTA_TESTS:BOOL=TRUE",
8 | "-DIOTA_ASAN_ENABLED:BOOL=TRUE",
9 | "-DIOTA_WALLET_ENABLE:BOOL=TRUE"
10 | ],
11 | "cmakeFormat.args": [
12 | "--config-file",
13 | "${workspaceFolder}/.cmake_format.yaml"
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/benchmark/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | #[[
2 | // Copyright 2022 IOTA Stiftung
3 | // SPDX-License-Identifier: Apache-2.0
4 | ]]
5 |
6 | # function for benchmark cases
7 | function(add_iota_benchmark benchmark_name benchmark_src)
8 | add_executable(${benchmark_name} "${benchmark_src}")
9 | set_target_properties(${benchmark_name} PROPERTIES C_STANDARD_REQUIRED NO C_STANDARD 99)
10 | target_include_directories(${benchmark_name} PRIVATE ${PROJECT_SOURCE_DIR}/src ${PROJECT_SOURCE_DIR}/benchmark
11 | ${CMAKE_INSTALL_PREFIX}/include)
12 | target_compile_options(${benchmark_name} PRIVATE -Wall -Wextra)
13 | if(ENABLE_MTRACE)
14 | target_compile_definitions(${benchmark_name} PRIVATE MTRACE_ENABLED)
15 | endif()
16 | if(${benchmark_src} MATCHES "^core")
17 | add_dependencies(${benchmark_name} iota_core)
18 | target_link_libraries(${benchmark_name} PRIVATE iota_core)
19 | elseif(${benchmark_src} MATCHES "^client")
20 | add_dependencies(${benchmark_name} iota_client)
21 | target_link_libraries(${benchmark_name} PRIVATE iota_client)
22 | elseif(${benchmark_src} MATCHES "^wallet")
23 | add_dependencies(${benchmark_name} iota_wallet)
24 | target_link_libraries(${benchmark_name} PRIVATE iota_wallet)
25 | endif()
26 | # install directory for benchmark application
27 | install(TARGETS ${benchmark_name} RUNTIME DESTINATION "${PROJECT_SOURCE_DIR}/benchmark")
28 | endfunction(add_iota_benchmark)
29 |
30 | add_iota_benchmark(benchmark_create_transaction_basic_output "core/create_transaction_basic_output.c")
31 | add_iota_benchmark(benchmark_create_transaction_basic_output_full "core/create_transaction_basic_output_full.c")
32 | add_iota_benchmark(benchmark_create_transaction_basic_output_max "core/create_transaction_basic_output_max.c")
33 |
34 | if(WITH_IOTA_CLIENT)
35 | add_iota_benchmark(benchmark_send_tagged_data "client/send_tagged_data.c")
36 | add_iota_benchmark(benchmark_send_tagged_data_max "client/send_tagged_data_max.c")
37 | endif()
38 |
--------------------------------------------------------------------------------
/benchmark/benchmark_config.h:
--------------------------------------------------------------------------------
1 | // Copyright 2022 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __BENCHMARK_BENCHMARK_CONFIG_H__
5 | #define __BENCHMARK_BENCHMARK_CONFIG_H__
6 |
7 | // Node endpoint
8 | #define NODE_HOST "localhost"
9 | #define NODE_PORT 14265
10 |
11 | #endif
12 |
--------------------------------------------------------------------------------
/benchmark/client/send_tagged_data.c:
--------------------------------------------------------------------------------
1 | // Copyright 2022 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifdef MTRACE_ENABLED
5 | #include
6 | #endif
7 | #include
8 |
9 | #include "benchmark_config.h"
10 | #include "client/api/restful/get_node_info.h"
11 | #include "client/api/restful/send_tagged_data.h"
12 | #include "client/constants.h"
13 |
14 | int main() {
15 | #ifdef MTRACE_ENABLED
16 | // enable memory tracing
17 | mtrace();
18 | #endif
19 |
20 | iota_client_conf_t ctx = {.host = NODE_HOST, .port = NODE_PORT, .use_tls = false};
21 |
22 | res_node_info_t* info = res_node_info_new();
23 | if (!info) {
24 | printf("[%s:%d]: Can not create node info object!\n", __func__, __LINE__);
25 | return -1;
26 | }
27 |
28 | int result = get_node_info(&ctx, info);
29 | if (result != 0 || info->is_error || info->u.info == NULL) {
30 | printf("[%s:%d]: Can not received node info data!\n", __func__, __LINE__);
31 | res_node_info_free(info);
32 | return -1;
33 | }
34 |
35 | byte_t tag[] = "Test tag from a benchmark application.";
36 | byte_t tag_data[] = "Test tagged data from a benchmark application";
37 | res_send_block_t res = {0};
38 |
39 | result = send_tagged_data_block(&ctx, info->u.info->protocol_params.version, tag, sizeof(tag), tag_data,
40 | sizeof(tag_data), &res);
41 | if (result != 0 || res.is_error) {
42 | printf("[%s:%d]: Can not send tagged data block!\n", __func__, __LINE__);
43 | res_node_info_free(info);
44 | return -1;
45 | }
46 | res_node_info_free(info);
47 |
48 | printf("[%s:%d]: Tagged Data successfully send! URL: http://%s:%d%s/blocks/0x%s\n", __func__, __LINE__, NODE_HOST,
49 | NODE_PORT, CORE_API_ROUTE, res.u.blk_id);
50 |
51 | return 0;
52 | }
53 |
--------------------------------------------------------------------------------
/benchmark/client/send_tagged_data_max.c:
--------------------------------------------------------------------------------
1 | // Copyright 2022 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifdef MTRACE_ENABLED
5 | #include
6 | #endif
7 | #include
8 |
9 | #include "benchmark_config.h"
10 | #include "client/api/restful/get_node_info.h"
11 | #include "client/api/restful/send_tagged_data.h"
12 | #include "client/constants.h"
13 | #include "core/models/outputs/features.h"
14 |
15 | int main() {
16 | #ifdef MTRACE_ENABLED
17 | // enable memory tracing
18 | mtrace();
19 | #endif
20 |
21 | iota_client_conf_t ctx = {.host = NODE_HOST, .port = NODE_PORT, .use_tls = false};
22 |
23 | res_node_info_t* info = res_node_info_new();
24 | if (!info) {
25 | printf("[%s:%d]: Can not create node info object!\n", __func__, __LINE__);
26 | return -1;
27 | }
28 |
29 | int result = get_node_info(&ctx, info);
30 | if (result != 0 || info->is_error || info->u.info == NULL) {
31 | printf("[%s:%d]: Can not received node info data!\n", __func__, __LINE__);
32 | res_node_info_free(info);
33 | return -1;
34 | }
35 |
36 | byte_t tag[MAX_INDEX_TAG_BYTES] = "Test tagged data from a benchmark application. Test tagged dat";
37 | byte_t* tag_data = malloc(MAX_METADATA_LENGTH_BYTES);
38 | if (!tag_data) {
39 | printf("[%s:%d]: Can not create tag data object!\n", __func__, __LINE__);
40 | res_node_info_free(info);
41 | return -1;
42 | }
43 | res_send_block_t res = {0};
44 |
45 | result = send_tagged_data_block(&ctx, info->u.info->protocol_params.version, tag, sizeof(tag), tag_data,
46 | MAX_METADATA_LENGTH_BYTES, &res);
47 | if (result != 0 || res.is_error) {
48 | printf("[%s:%d]: Can not send tagged data block!\n", __func__, __LINE__);
49 | free(tag_data);
50 | res_node_info_free(info);
51 | return -1;
52 | }
53 | free(tag_data);
54 | res_node_info_free(info);
55 |
56 | printf("[%s:%d]: Tagged Data successfully send! URL: http://%s:%d%s/blocks/0x%s\n", __func__, __LINE__, NODE_HOST,
57 | NODE_PORT, CORE_API_ROUTE, res.u.blk_id);
58 |
59 | return 0;
60 | }
61 |
--------------------------------------------------------------------------------
/benchmark/measure_heap_consumers.py:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env python3
2 | import subprocess
3 | import fileinput
4 | import sys
5 | import re
6 | import os
7 |
8 | if len(sys.argv) < 2:
9 | print("Executable file is missing")
10 | print("Usage: python measure_heap_consumers.py executable_file")
11 | quit()
12 |
13 | demo_application = sys.argv[1]
14 | heap_consumers_file_path = os.getcwd() + "/heap_consumers.txt"
15 |
16 | print("Executing " + os.path.basename(demo_application) + " application...")
17 | process = subprocess.Popen("export MALLOC_TRACE=" + heap_consumers_file_path + ";" + demo_application,
18 | shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
19 | process.wait()
20 |
21 | if process.returncode == 0:
22 | print("Application executed successfully.")
23 | else:
24 | print("Failed to successfully execute application.")
25 | quit()
26 |
27 | print("Collecting results...")
28 |
29 | heap_memory_allocations = {}
30 |
31 | for line in fileinput.input(heap_consumers_file_path, inplace=True):
32 | # find address in memory map
33 | start = line.find('[')
34 | end = line.find(']')
35 |
36 | if start != -1 and end != -1 and line.find(demo_application) != -1 and line.find('+') != -1:
37 | address = line[start + 1:end]
38 | # get line in source code for address in memory map
39 | process = subprocess.Popen("addr2line -e " + demo_application + " " + address,
40 | shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
41 | process.wait()
42 | # replace address with line number
43 | addr2line = process.stdout.readline().decode("utf-8").rstrip()
44 | line = line.replace(address, addr2line).rstrip()
45 | # update line in a file with line number instead of an address
46 | print(line)
47 | # get size of memory allocation
48 | size_of_allocation = int(line[[m.start() for m in re.finditer(r"0x", line)][1] + 2: len(line)], 16)
49 | # update dictionary
50 | heap_memory_allocations[size_of_allocation] = heap_memory_allocations.get(size_of_allocation, 0) + 1
51 |
52 | print("Results for heap memory allocation are collected.\n")
53 |
54 | # print all heap memory allocations
55 | print("All heap memory allocation:")
56 | all_heap_memory_allocations = sorted(heap_memory_allocations.items(), key=lambda x: x[1], reverse=True)
57 | print("{:<12} {:<10}".format('Alloc.size', 'Occurrence'))
58 | for allocation in all_heap_memory_allocations:
59 | (size, occurrence) = allocation
60 | print("{:<12} {:<10}".format(str(size) + ' B', str(occurrence) + 'x'))
61 |
62 | # print TOP 5 heap memory allocations
63 | print("\nTOP 5 heap memory allocation:")
64 | top_5_heap_memory_allocations = sorted(heap_memory_allocations.items(), key=lambda x: x[0] * x[1], reverse=True)
65 | print("{:<12} {:<10}".format('Alloc.size', 'Occurrence'))
66 | for allocation in top_5_heap_memory_allocations[:5]:
67 | (size, occurrence) = allocation
68 | print("{:<12} {:<10}".format(str(size) + ' B', str(occurrence) + 'x'))
69 |
--------------------------------------------------------------------------------
/benchmark/run_benchmark.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | helpFunction()
4 | {
5 | echo ""
6 | echo "Usage: $0 executable_file"
7 | exit 1 # Exit script after printing help
8 | }
9 |
10 | # Print helpFunction in case a parameter is missing
11 | if [ -z "$1" ]
12 | then
13 | echo "Executable file is missing";
14 | helpFunction
15 | fi
16 |
17 | # Begin script in case executable file is present
18 | executable_file=$1
19 |
20 | echo "Executing memory benchmark for: $executable_file\n"
21 |
22 | echo "Memory benchmark with Valgrind and Massif heap profiler:"
23 | if valgrind --tool=massif --time-unit=B --threshold=0.1 --massif-out-file=massif.out $executable_file; then
24 | ms_print massif.out | head -33
25 | rm massif.out
26 | fi
27 |
--------------------------------------------------------------------------------
/cmake/blake2.cmake:
--------------------------------------------------------------------------------
1 | #[[
2 | // Copyright 2021 IOTA Stiftung
3 | // SPDX-License-Identifier: Apache-2.0
4 | ]]
5 |
6 | if (NOT __BLAKE2_INCLUDE)
7 | set(__BLAKE2_INCLUDE TRUE)
8 |
9 | ExternalProject_Add(
10 | blake2_download
11 | PREFIX ${PROJECT_BINARY_DIR}/blake2
12 | DOWNLOAD_DIR ${PROJECT_BINARY_DIR}/download
13 | DOWNLOAD_NAME 54f4faa4c16ea34bcd59d16e8da46a64b259fc07.tar.gz
14 | URL https://github.com/BLAKE2/BLAKE2/archive/54f4faa4c16ea34bcd59d16e8da46a64b259fc07.tar.gz
15 | URL_HASH SHA256=710753a61f3f67eff11bc1a4e3374651a266493e6c1691c70197e72c3c6379d9
16 | CONFIGURE_COMMAND ""
17 | INSTALL_COMMAND ""
18 | BUILD_COMMAND ""
19 | # for debug
20 | # LOG_DOWNLOAD 1
21 | )
22 |
23 | set(blake2_cmake_dir ${PROJECT_BINARY_DIR}/blake2/src/ext_blake2)
24 | set(blake2_src_dir ../blake2_download)
25 | set(blake2_install_include ${CMAKE_INSTALL_PREFIX}/include/)
26 | set(blake2_install_lib ${CMAKE_INSTALL_PREFIX}/lib)
27 |
28 | file(WRITE ${blake2_cmake_dir}/CMakeLists.txt
29 | "cmake_minimum_required(VERSION 3.15)\n"
30 | "project(blake2 C)\n"
31 | "add_library(blake2 STATIC)\n"
32 | "target_sources(\n"
33 | "blake2\n"
34 | "PRIVATE \"${blake2_src_dir}/ref/blake2-impl.h\"\n"
35 | " \"${blake2_src_dir}/ref/blake2b-ref.c\"\n"
36 | " \"${blake2_src_dir}/ref/blake2bp-ref.c\"\n"
37 | " \"${blake2_src_dir}/ref/blake2s-ref.c\"\n"
38 | " \"${blake2_src_dir}/ref/blake2sp-ref.c\"\n"
39 | " \"${blake2_src_dir}/ref/blake2xb-ref.c\"\n"
40 | " \"${blake2_src_dir}/ref/blake2xs-ref.c\"\n"
41 | "PUBLIC \"${blake2_src_dir}/ref/blake2.h\")\n"
42 | "target_include_directories(blake2 PUBLIC ${base58_src_dir})\n"
43 | "install(TARGETS blake2 DESTINATION ${blake2_install_lib})\n"
44 | "install(FILES ${blake2_src_dir}/ref/blake2.h DESTINATION ${blake2_install_include})\n"
45 | )
46 |
47 | ExternalProject_Add(
48 | ext_blake2
49 | PREFIX ${PROJECT_BINARY_DIR}/blake2
50 | DOWNLOAD_COMMAND ""
51 | BUILD_IN_SOURCE TRUE
52 | CMAKE_ARGS
53 | -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
54 | -DCMAKE_INSTALL_PREFIX:STRING=${CMAKE_INSTALL_PREFIX}
55 | -DCMAKE_C_COMPILER:FILEPATH=${CMAKE_C_COMPILER}
56 | # for debug
57 | # LOG_CONFIGURE 1
58 | # LOG_INSTALL 1
59 | )
60 | add_dependencies(ext_blake2 blake2_download)
61 |
62 | endif()
63 |
--------------------------------------------------------------------------------
/cmake/cjson.cmake:
--------------------------------------------------------------------------------
1 | #[[
2 | // Copyright 2020 IOTA Stiftung
3 | // SPDX-License-Identifier: Apache-2.0
4 | ]]
5 |
6 | if (NOT __CJSON_INCLUDED)
7 | set(__CJSON_INCLUDED TRUE)
8 |
9 | ExternalProject_Add(
10 | ext_cjson
11 | PREFIX ${PROJECT_BINARY_DIR}/cjson
12 | DOWNLOAD_DIR ${PROJECT_BINARY_DIR}/download
13 | DOWNLOAD_NAME cjson_v1.7.15.tar.gz
14 | URL https://github.com/DaveGamble/cJSON/archive/v1.7.15.tar.gz
15 | URL_HASH SHA256=5308fd4bd90cef7aa060558514de6a1a4a0819974a26e6ed13973c5f624c24b2
16 | BUILD_IN_SOURCE TRUE
17 | CMAKE_ARGS
18 | -DENABLE_CJSON_TEST:STRING=Off
19 | -DENABLE_CJSON_UTILS:STRING=Off
20 | -DBUILD_SHARED_LIBS:STRING=Off
21 | -DCMAKE_INSTALL_PREFIX:STRING=${CMAKE_INSTALL_PREFIX}
22 | -DCMAKE_C_COMPILER:FILEPATH=${CMAKE_C_COMPILER}
23 | -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
24 | # -DCMAKE_TOOLCHAIN_FILE:STRING=${CMAKE_TOOLCHAIN_FILE}
25 | # for debug
26 | # LOG_DOWNLOAD 1
27 | # LOG_CONFIGURE 1
28 | # LOG_INSTALL 1
29 | )
30 | endif()
31 |
--------------------------------------------------------------------------------
/cmake/jemalloc.cmake:
--------------------------------------------------------------------------------
1 | #[[
2 | // Copyright 2020 IOTA Stiftung
3 | // SPDX-License-Identifier: Apache-2.0
4 | ]]
5 |
6 | if (NOT __JEMALLOC_INCLUDED)
7 | set(__JEMALLOC_INCLUDED TRUE)
8 |
9 | set(jemalloc_src_dir ${PROJECT_BINARY_DIR}/jemalloc/src/jemalloc)
10 |
11 | if(${CMAKE_BUILD_TYPE} MATCHES Debug)
12 | ExternalProject_Add(
13 | jemalloc
14 | PREFIX ${PROJECT_BINARY_DIR}/jemalloc
15 | DOWNLOAD_DIR ${PROJECT_BINARY_DIR}/download
16 | DOWNLOAD_NAME jemalloc-5.2.1.tar.bz2
17 | URL https://github.com/jemalloc/jemalloc/releases/download/5.2.1/jemalloc-5.2.1.tar.bz2
18 | URL_HASH SHA256=34330e5ce276099e2e8950d9335db5a875689a4c6a56751ef3b1d8c537f887f6
19 | BUILD_IN_SOURCE TRUE
20 | CONFIGURE_COMMAND ${jemalloc_src_dir}/configure --enable-debug --enable-log --prefix=${CMAKE_INSTALL_PREFIX} CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER}
21 | BUILD_COMMAND make build_lib install_lib install_include -j10
22 | # INSTALL_COMMAND ""
23 | # for debug
24 | # LOG_DOWNLOAD 1
25 | )
26 | else()
27 | ExternalProject_Add(
28 | jemalloc
29 | PREFIX ${PROJECT_BINARY_DIR}/jemalloc
30 | DOWNLOAD_DIR ${PROJECT_BINARY_DIR}/download
31 | DOWNLOAD_NAME jemalloc-5.2.1.tar.bz2
32 | URL https://github.com/jemalloc/jemalloc/releases/download/5.2.1/jemalloc-5.2.1.tar.bz2
33 | URL_HASH SHA256=34330e5ce276099e2e8950d9335db5a875689a4c6a56751ef3b1d8c537f887f6
34 | BUILD_IN_SOURCE TRUE
35 | CONFIGURE_COMMAND ${jemalloc_src_dir}/configure --prefix=${CMAKE_INSTALL_PREFIX} CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER}
36 | BUILD_COMMAND make build_lib install_lib install_include -j10
37 | # INSTALL_COMMAND ""
38 | # for debug
39 | # LOG_DOWNLOAD 1
40 | )
41 | endif()
42 |
43 | # add_library(malloc::jemalloc ALIAS jemalloc)
44 |
45 | set(THREADS_PREFER_PTHREAD_FLAG ON)
46 | find_package(Threads REQUIRED)
47 | endif()
48 |
--------------------------------------------------------------------------------
/cmake/mbedtls.cmake:
--------------------------------------------------------------------------------
1 | #[[
2 | // Copyright 2021 IOTA Stiftung
3 | // SPDX-License-Identifier: Apache-2.0
4 | ]]
5 |
6 | if (NOT __MBEDTLS_INCLUDED)
7 | set(__MBEDTLS_INCLUDED TRUE)
8 |
9 | set(MBEDTLS_VERSION "v2.28.0")
10 |
11 | ExternalProject_Add(
12 | mbedtls_download
13 | PREFIX ${PROJECT_BINARY_DIR}/mbedtls
14 | SOURCE_DIR ${PROJECT_BINARY_DIR}/mbedtls/src/ext_mbedtls
15 | DOWNLOAD_DIR ${PROJECT_BINARY_DIR}/download
16 | DOWNLOAD_NAME mbedtls_${MBEDTLS_VERSION}.tar.gz
17 | URL https://github.com/ARMmbed/mbedtls/archive/refs/tags/${MBEDTLS_VERSION}.tar.gz
18 | URL_HASH SHA256=6519579b836ed78cc549375c7c18b111df5717e86ca0eeff4cb64b2674f424cc
19 | CONFIGURE_COMMAND ""
20 | INSTALL_COMMAND ""
21 | BUILD_COMMAND ""
22 | # for debug
23 | # LOG_DOWNLOAD 1
24 | )
25 |
26 | ExternalProject_Add(
27 | ext_mbedtls
28 | PREFIX ${PROJECT_BINARY_DIR}/mbedtls
29 | DOWNLOAD_COMMAND ""
30 | CMAKE_ARGS
31 | -DENABLE_TESTING=Off
32 | -DENABLE_PROGRAMS=Off
33 | -DCMAKE_INSTALL_PREFIX:STRING=${CMAKE_INSTALL_PREFIX}
34 | # -DCMAKE_TOOLCHAIN_FILE:STRING=${CMAKE_TOOLCHAIN_FILE}
35 | # for debug
36 | # LOG_CONFIGURE 1
37 | # LOG_INSTALL 1
38 | )
39 |
40 | add_dependencies(ext_mbedtls mbedtls_download)
41 |
42 | endif()
43 |
--------------------------------------------------------------------------------
/cmake/mosquitto.cmake:
--------------------------------------------------------------------------------
1 | #[[
2 | // Copyright 2021 IOTA Stiftung
3 | // SPDX-License-Identifier: Apache-2.0
4 | ]]
5 |
6 | if (NOT __MOSQUITTO_INCLUDED)
7 | set(__MOSQUITTO_INCLUDED TRUE)
8 |
9 | ExternalProject_Add(
10 | ext_mosquitto
11 | PREFIX ${PROJECT_BINARY_DIR}/mosquitto
12 | DOWNLOAD_DIR ${PROJECT_BINARY_DIR}/download
13 | DOWNLOAD_NAME mosquitto_v2.0.14.tar.gz
14 | URL https://github.com/eclipse/mosquitto/archive/v2.0.14.tar.gz
15 | URL_HASH SHA256=c0ce97b1911d1769ccfd65da237e919fd7eaa60209fd190c113d63fbd0c40347
16 | BUILD_IN_SOURCE TRUE
17 | CMAKE_ARGS
18 | -DWITH_CJSON:STRING=OFF
19 | -DWITH_TLS:STRING=OFF
20 | -DWITH_STATIC_LIBRARIES:STRING=ON
21 | -DWITH_THREADING:STRING=ON
22 | -DWITH_CLIENTS:STRING=OFF
23 | -DWITH_BROKER:STRING=OFF
24 | -DWITH_APPS:STRING=OFF
25 | -DWITH_PLUGINS:STRING=OFF
26 | -DDOCUMENTATION:STRING=OFF
27 | -DCMAKE_INSTALL_PREFIX:STRING=${CMAKE_INSTALL_PREFIX}
28 | -DCMAKE_C_COMPILER:FILEPATH=${CMAKE_C_COMPILER}
29 | -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
30 | # for debug
31 | # LOG_DOWNLOAD 1
32 | # LOG_CONFIGURE 1
33 | # LOG_INSTALL 1
34 | )
35 |
36 | endif()
37 |
--------------------------------------------------------------------------------
/cmake/sodium.cmake:
--------------------------------------------------------------------------------
1 | #[[
2 | // Copyright 2020 IOTA Stiftung
3 | // SPDX-License-Identifier: Apache-2.0
4 | ]]
5 |
6 | if (NOT __SODIUM_INCLUDED)
7 | set(__SODIUM_INCLUDED TRUE)
8 |
9 | set(sodium_src_dir ${PROJECT_BINARY_DIR}/libsodium/src/sodium)
10 |
11 | ExternalProject_Add(
12 | sodium
13 | PREFIX ${PROJECT_BINARY_DIR}/libsodium
14 | DOWNLOAD_DIR ${PROJECT_BINARY_DIR}/download
15 | DOWNLOAD_NAME libsodium-1.0.18-stable.tar.gz
16 | URL https://download.libsodium.org/libsodium/releases/libsodium-1.0.18-stable.tar.gz
17 | # URL_HASH SHA256=2ef4304dd844e274d78dfcf0201e1ba1a312eaba135bdc8affc56a3d80b58593
18 | BUILD_IN_SOURCE TRUE
19 | CONFIGURE_COMMAND ${sodium_src_dir}/configure --prefix=${CMAKE_INSTALL_PREFIX} --disable-shared CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER}
20 | # BUILD_COMMAND make
21 | # INSTALL_COMMAND ""
22 | # for debug
23 | # LOG_DOWNLOAD 1
24 | )
25 |
26 | endif()
27 |
--------------------------------------------------------------------------------
/cmake/unity.cmake:
--------------------------------------------------------------------------------
1 | #[[
2 | // Copyright 2020 IOTA Stiftung
3 | // SPDX-License-Identifier: Apache-2.0
4 | ]]
5 |
6 | if (NOT __UNITY_INCLUDED)
7 | set(__UNITY_INCLUDED TRUE)
8 |
9 | ExternalProject_Add(
10 | ext_unity
11 | PREFIX ${PROJECT_BINARY_DIR}/unity
12 | DOWNLOAD_DIR ${PROJECT_BINARY_DIR}/download
13 | DOWNLOAD_NAME unity_v2.5.2.tar.gz
14 | URL https://github.com/ThrowTheSwitch/Unity/archive/v2.5.2.tar.gz
15 | URL_HASH SHA256=3786de6c8f389be3894feae4f7d8680a02e70ed4dbcce36109c8f8646da2671a
16 | BUILD_IN_SOURCE TRUE
17 | CMAKE_ARGS
18 | -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
19 | -DCMAKE_INSTALL_PREFIX:STRING=${CMAKE_INSTALL_PREFIX}
20 | -DCMAKE_C_COMPILER:FILEPATH=${CMAKE_C_COMPILER}
21 | # for debug
22 | # LOG_CONFIGURE 1
23 | # LOG_INSTALL 1
24 | )
25 |
26 | endif()
27 |
--------------------------------------------------------------------------------
/cmake/uthash.cmake:
--------------------------------------------------------------------------------
1 | #[[
2 | // Copyright 2020 IOTA Stiftung
3 | // SPDX-License-Identifier: Apache-2.0
4 | ]]
5 |
6 | if (NOT __UTHASH_INCLUDED)
7 | set(__UTHASH_INCLUDED TRUE)
8 |
9 | ExternalProject_Add(
10 | ext_uthash
11 | PREFIX ${PROJECT_BINARY_DIR}/uthash
12 | DOWNLOAD_DIR ${PROJECT_BINARY_DIR}/download
13 | URL https://github.com/troydhanson/uthash/archive/v2.3.0.tar.gz
14 | URL_HASH SHA256=e10382ab75518bad8319eb922ad04f907cb20cccb451a3aa980c9d005e661acc
15 | CONFIGURE_COMMAND ""
16 | BUILD_COMMAND ""
17 | INSTALL_COMMAND ${CMAKE_COMMAND} -E copy_directory
18 | /src ${CMAKE_INSTALL_PREFIX}/include
19 | )
20 |
21 | endif()
22 |
--------------------------------------------------------------------------------
/docs/Makefile:
--------------------------------------------------------------------------------
1 | # Minimal makefile for Sphinx documentation
2 | #
3 |
4 | # You can set these variables from the command line, and also
5 | # from the environment for the first two.
6 | SPHINXOPTS ?=
7 | SPHINXBUILD ?= sphinx-build
8 | SOURCEDIR = .
9 | BUILDDIR = _build
10 |
11 | # Put it first so that "make" without argument is like "make help".
12 | help:
13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
14 |
15 | .PHONY: help Makefile
16 |
17 | # Catch-all target: route all unknown targets to Sphinx using the new
18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
19 | %: Makefile
20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
21 |
--------------------------------------------------------------------------------
/docs/_static/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iotaledger-archive/iota.c/bdcaf8e4e704fe32d0e8ed6ab7b75a90126eb390/docs/_static/.gitkeep
--------------------------------------------------------------------------------
/docs/_templates/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iotaledger-archive/iota.c/bdcaf8e4e704fe32d0e8ed6ab7b75a90126eb390/docs/_templates/.gitkeep
--------------------------------------------------------------------------------
/docs/api/crypto.md:
--------------------------------------------------------------------------------
1 | # Crypto API Reference
2 |
3 | The Crypto APIs provide an abstraction layer of cryptography functions.
4 |
5 | ## ED25519 Keypair
6 |
7 | ```{eval-rst}
8 | .. doxygenstruct:: ed25519_keypair_t
9 | :members:
10 | ```
11 |
12 | ## Random Bytes
13 |
14 | ```{eval-rst}
15 | .. doxygenfunction:: iota_crypto_randombytes
16 | ```
17 |
18 | ## ED25519 keypair
19 |
20 | ```{eval-rst}
21 | .. doxygenfunction:: iota_crypto_keypair
22 | ```
23 |
24 | ## ED25519 Signature
25 |
26 | ```{eval-rst}
27 | .. doxygenfunction:: iota_crypto_sign
28 | ```
29 |
30 | ```{eval-rst}
31 | .. doxygenfunction:: iota_crypto_sign_open
32 | ```
33 |
34 | ## HMAC-SHA-256
35 |
36 | ```{eval-rst}
37 | .. doxygenfunction:: iota_crypto_hmacsha256
38 | ```
39 |
40 | ## HMAC-SHA-512
41 |
42 | ```{eval-rst}
43 | .. doxygenfunction:: iota_crypto_hmacsha512
44 | ```
45 |
46 | ## SHA-256
47 |
48 | ```{eval-rst}
49 | .. doxygenfunction:: iota_crypto_sha256
50 | ```
51 |
52 | ## SHA-512
53 |
54 | ```{eval-rst}
55 | .. doxygenfunction:: iota_crypto_sha512
56 | ```
57 |
58 | ## Blake2b
59 |
60 | ```{eval-rst}
61 | .. doxygenfunction:: iota_blake2b_sum
62 | ```
63 |
64 | ```{eval-rst}
65 | .. doxygenfunction:: iota_blake2b_new_state
66 | ```
67 |
68 | ```{eval-rst}
69 | .. doxygenfunction:: iota_blake2b_free_state
70 | ```
71 |
72 | ```{eval-rst}
73 | .. doxygenfunction:: iota_blake2b_init
74 | ```
75 |
76 | ```{eval-rst}
77 | .. doxygenfunction:: iota_blake2b_update
78 | ```
79 |
80 | ```{eval-rst}
81 | .. doxygenfunction:: iota_blake2b_final
82 | ```
83 |
84 | ## PBKDF2 HMAC
85 |
86 | ```{eval-rst}
87 | .. doxygenfunction:: iota_crypto_pbkdf2_hmac_sha512
88 | ```
89 |
--------------------------------------------------------------------------------
/docs/api/events.md:
--------------------------------------------------------------------------------
1 | # Event API Reference
2 |
3 | The Event API is event subscribers based on [TIP-28 Node Event API](https://github.com/iotaledger/tips/pull/66), it provides an easy way to subscribe node events via MQTT protocol.
4 |
5 | ## Event Client Configuration
6 |
7 | ```{eval-rst}
8 | .. doxygenstruct:: event_client_config_t
9 | :members:
10 | ```
11 |
12 | ## Event IDs
13 |
14 | ```{eval-rst}
15 | .. doxygenenum:: event_client_event_id_t
16 | ```
17 |
18 | ## Initialize Event Service
19 |
20 | ```{eval-rst}
21 | .. doxygenfunction:: event_init
22 | ```
23 |
24 | ## Register Event Callback Handler
25 |
26 | ```{eval-rst}
27 | .. doxygenfunction:: event_register_cb
28 | ```
29 |
30 | ## Subscribe To A Topic
31 |
32 | ```{eval-rst}
33 | .. doxygenfunction:: event_subscribe
34 | ```
35 |
36 | ## Unsubscribe To A Topic
37 |
38 | ```{eval-rst}
39 | .. doxygenfunction:: event_unsubscribe
40 | ```
41 |
42 | ## Start Event Service
43 |
44 | ```{eval-rst}
45 | .. doxygenfunction:: event_start
46 | ```
47 |
48 | ## Stop Event Service
49 |
50 | ```{eval-rst}
51 | .. doxygenfunction:: event_stop
52 | ```
53 |
54 | ## Destroy Event Service
55 |
56 | ```{eval-rst}
57 | .. doxygenfunction:: event_destroy
58 | ```
59 |
60 | ## IOTA Event Topics
61 |
62 | ### milestone-info/latest
63 |
64 | Use `TOPIC_MILESTONE_LATEST`
65 |
66 | ```
67 | event_subscribe(event_client_handle_t client, int *mid, TOPIC_MS_LATEST, int qos);
68 | ```
69 |
70 | ### milestone-info/confirmed
71 |
72 | ```
73 | event_subscribe(event->client, NULL, TOPIC_MILESTONE_CONGIRMED, 1);
74 | ```
75 |
76 | ### milestones
77 |
78 | TODO
79 |
80 | ### blocks
81 |
82 | ```
83 | event_subscribe(event->client, NULL, TOPIC_BLOCKS, 1);
84 | ```
85 |
86 | ### blocks/transaction
87 |
88 | ```
89 | event_subscribe(event->client, NULL, TOPIC_BLK_TRANSACTION, 1);
90 | ```
91 |
92 | ### blocks/transaction/tagged-data
93 |
94 | TODO
95 |
96 | ### blocks/transaction/tagged-data/{tag}
97 |
98 | TODO
99 |
100 | ### blocks/tagged-data
101 |
102 | ```
103 | event_subscribe(event->client, NULL, TOPIC_BLK_TAGGED_DATA, 1);
104 | ```
105 |
106 | ### blocks/tagged-data/{tag}
107 |
108 | TODO
109 |
110 | ### transactions/{transaction ID}/included-block
111 |
112 | TODO
113 |
114 | ### block-metadata/{block ID}
115 |
116 | TODO
117 |
118 | ### block-metadata/referenced
119 |
120 | TODO
121 |
122 | ### outputs/{Output ID}
123 |
124 | ```{eval-rst}
125 | .. doxygenfunction:: event_sub_outputs_id
126 | ```
127 |
128 | ### outputs/nft/{NFT ID}
129 |
130 | ```{eval-rst}
131 | .. doxygenfunction:: event_sub_outputs_nft_id
132 | ```
133 |
134 | ### outputs/aliases/{Alias ID}
135 |
136 | ```{eval-rst}
137 | .. doxygenfunction:: event_sub_outputs_alias_id
138 | ```
139 |
140 | ### outputs/foundries/{Foundry ID}
141 |
142 | ```{eval-rst}
143 | .. doxygenfunction:: event_sub_outputs_foundry_id
144 | ```
145 |
146 | ### outputs/unlock/{condition}/{address}
147 |
148 | ```{eval-rst}
149 | .. doxygenfunction:: event_sub_outputs_unlock_address
150 | ```
151 |
152 | ### outputs/unlock/{condition}/{address}/spent
153 |
154 | ```{eval-rst}
155 | .. doxygenfunction:: event_sub_outputs_unlock_address_spent
156 | ```
157 |
158 |
--------------------------------------------------------------------------------
/docs/api/wallet.md:
--------------------------------------------------------------------------------
1 | # Wallet API Reference
2 |
3 | The Wallet API provides some helper methods for developers to create wallet alllications.
4 |
5 | ## Wallet Configuration
6 |
7 | ```{eval-rst}
8 | .. doxygenstruct:: iota_wallet_t
9 | :members:
10 | ```
11 |
12 | ## Create and Destory Methods
13 |
14 | ```{eval-rst}
15 | .. doxygenfunction:: wallet_create
16 | ```
17 |
18 | ```{eval-rst}
19 | .. doxygenfunction:: wallet_destroy
20 | ```
21 |
22 | ```{eval-rst}
23 | .. doxygenfunction:: wallet_set_endpoint
24 | ```
25 |
26 | ```{eval-rst}
27 | .. doxygenfunction:: wallet_update_node_config
28 | ```
29 |
30 | ## Address Methods
31 |
32 | ```{eval-rst}
33 | .. doxygenfunction:: wallet_ed25519_address_from_index
34 | ```
35 |
36 | ```{eval-rst}
37 | .. doxygenfunction:: wallet_get_address_and_keypair_from_index
38 | ```
39 |
40 | ## UTXO Methods
41 |
42 | ```{eval-rst}
43 | .. doxygenfunction:: wallet_is_collected_balance_sufficient
44 | ```
45 |
46 | ```{eval-rst}
47 | .. doxygenfunction:: wallet_calculate_remainder_amount
48 | ```
49 |
50 | ```{eval-rst}
51 | .. doxygenfunction:: wallet_send
52 | ```
53 |
54 | ```{eval-rst}
55 | .. doxygenfunction:: wallet_create_core_block
56 | ```
57 |
58 | ```{eval-rst}
59 | .. doxygenfunction:: wallet_send_block
60 | ```
61 |
62 | ```{eval-rst}
63 | .. doxygenfunction:: wallet_alias_output_create
64 | ```
65 |
66 | ```{eval-rst}
67 | .. doxygenfunction:: wallet_alias_output_state_transition
68 | ```
69 |
70 | ```{eval-rst}
71 | .. doxygenfunction:: wallet_alias_output_destroy
72 | ```
73 |
74 | ```{eval-rst}
75 | .. doxygenfunction:: wallet_basic_output_create
76 | ```
77 |
78 | ```{eval-rst}
79 | .. doxygenfunction:: wallet_get_unspent_basic_output_ids
80 | ```
81 |
82 | ```{eval-rst}
83 | .. doxygenfunction:: wallet_basic_output_send
84 | ```
85 |
86 | ```{eval-rst}
87 | .. doxygenfunction:: wallet_foundry_output_mint_native_tokens
88 | ```
89 |
90 | ## Mnemonic Sentence
91 |
92 | ```{eval-rst}
93 | .. doxygenenum:: ms_lan_t
94 | ```
95 |
96 | ```{eval-rst}
97 | .. doxygenenum:: ms_entropy_t
98 | ```
99 |
100 | ```{eval-rst}
101 | .. doxygenfunction:: mnemonic_to_seed
102 | ```
103 |
104 | ```{eval-rst}
105 | .. doxygenfunction:: mnemonic_generator
106 | ```
107 |
108 | ```{eval-rst}
109 | .. doxygenfunction:: mnemonic_encode
110 | ```
111 |
112 | ```{eval-rst}
113 | .. doxygenfunction:: mnemonic_decode
114 | ```
115 |
116 | ```{eval-rst}
117 | .. doxygenfunction:: mnemonic_convertor
118 | ```
119 |
120 | ```{eval-rst}
121 | .. doxygenfunction:: mnemonic_validation
122 | ```
123 |
--------------------------------------------------------------------------------
/docs/arduino_esp32.md:
--------------------------------------------------------------------------------
1 | # Arduino-ESP32 Integration
2 |
3 | Developers are able to write IOTA client and wallet applications with [arduino-esp32](https://github.com/espressif/arduino-esp32) framework via the [Arduino Desktop IDE](https://www.arduino.cc/en/software)
4 |
5 | Please follow the installation document to setup the IDE on your system
6 |
7 | - [Install Arduino Desktop IDE](https://www.arduino.cc/en/Guide)
8 | - [Install Arduino-ESP32 Support](https://docs.espressif.com/projects/arduino-esp32/en/latest/installing.html)
9 |
10 |
11 | Once the desktop IDE and arduino-esp32 support are installed, you are ready to add IOTA Client library into the Arduino Libraries.
12 |
13 | There are two packages are required:
14 |
15 | - [iota.c](https://github.com/iotaledger/iota.c)
16 | - [uthash](https://github.com/oopsmonk/uthash)
17 |
18 | ## Import IOTA Client packages
19 |
20 | Choose one way which your preferred to import packages into the Arduino IDE.
21 |
22 | ### Download Packages From GitHub
23 |
24 | Download ZIP files from the website and save to a folder.
25 |
26 | 
27 |
28 | Add packages into Arduino Libraries
29 |
30 | 
31 |
32 | ### Clone Packages From GitHub
33 |
34 | Clone repositories into the Arduino Libraries folder, the folder is under the Sketchbook location can be found in the preferences settings.
35 |
36 | 
37 |
38 | In my case, it is `/home/sam/Arduino/libraries`.
39 |
40 | ```bash
41 | cd /home/same/Arduino/libraries
42 | git clone https://github.com/iotaledger/iota.c.git
43 | git clone https://github.com/oopsmonk/uthash.git
44 | ```
45 |
46 | ### Import IOTA Client Library From Arduino Package Manager
47 |
48 | TODO
49 |
50 | ## Open Examples from IDE
51 |
52 | Once IOTA Client packages are imported to the Libraries folder, please restart Arduino IDE and you can find the examples in the IDE.
53 |
54 | 
55 |
56 |
--------------------------------------------------------------------------------
/docs/conf.py:
--------------------------------------------------------------------------------
1 | # Configuration file for the Sphinx documentation builder.
2 | #
3 | # This file only contains a selection of the most common options. For a full
4 | # list see the documentation:
5 | # https://www.sphinx-doc.org/en/master/usage/configuration.html
6 |
7 | # -- Path setup --------------------------------------------------------------
8 |
9 | # If extensions (or modules to document with autodoc) are in another directory,
10 | # add these directories to sys.path here. If the directory is relative to the
11 | # documentation root, use os.path.abspath to make it absolute, like shown here.
12 | #
13 | import os, sys, subprocess
14 | sys.path.insert(0, os.path.abspath('.'))
15 |
16 | if os.environ.get('READTHEDOCS', None) == 'True':
17 | subprocess.call('doxygen')
18 |
19 |
20 | # -- Project information -----------------------------------------------------
21 |
22 | project = 'IOTA C Client'
23 | copyright = '2022, IOTA Stiftung'
24 | author = 'Sam Chen'
25 |
26 | master_doc = "index"
27 | highlight_language = 'c'
28 | primary_domain = 'c'
29 | language = "en"
30 |
31 | # -- General configuration ---------------------------------------------------
32 |
33 | # Add any Sphinx extension module names here, as strings. They can be
34 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
35 | # ones.
36 | extensions = ['myst_parser', 'breathe']
37 |
38 | # Auto-generated header anchors
39 | myst_heading_anchors = 2
40 |
41 | # Add any paths that contain templates here, relative to this directory.
42 | templates_path = ['_templates']
43 |
44 | # List of patterns, relative to source directory, that match files and
45 | # directories to ignore when looking for source files.
46 | # This pattern also affects html_static_path and html_extra_path.
47 | exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
48 |
49 |
50 | # -- Options for HTML output -------------------------------------------------
51 |
52 | # The theme to use for HTML and HTML Help pages. See the documentation for
53 | # a list of builtin themes.
54 | #
55 | html_theme = 'sphinx_book_theme'
56 |
57 | # Add any paths that contain custom static files (such as style sheets) here,
58 | # relative to this directory. They are copied after the builtin static files,
59 | # so a file named "default.css" will overwrite the builtin "default.css".
60 | html_static_path = ['_static']
61 |
62 | ## myst-parser settings
63 |
64 | ## breathe settings
65 |
66 | breathe_default_project = 'iota.c'
67 | breathe_domain_by_extension = {'h' : 'c'}
68 | breathe_projects = { 'iota.c': './doxygen_build/xml/' }
69 |
--------------------------------------------------------------------------------
/docs/examples.md:
--------------------------------------------------------------------------------
1 | # Examples
2 |
3 | See [iota.c/examples](https://github.com/iotaledger/iota.c/tree/develop/examples)
4 |
--------------------------------------------------------------------------------
/docs/img/arduino_examples.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iotaledger-archive/iota.c/bdcaf8e4e704fe32d0e8ed6ab7b75a90126eb390/docs/img/arduino_examples.png
--------------------------------------------------------------------------------
/docs/img/arduino_include_zip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iotaledger-archive/iota.c/bdcaf8e4e704fe32d0e8ed6ab7b75a90126eb390/docs/img/arduino_include_zip.png
--------------------------------------------------------------------------------
/docs/img/arduino_preferences_sketchbook_location.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iotaledger-archive/iota.c/bdcaf8e4e704fe32d0e8ed6ab7b75a90126eb390/docs/img/arduino_preferences_sketchbook_location.png
--------------------------------------------------------------------------------
/docs/img/client_application_architecture.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iotaledger-archive/iota.c/bdcaf8e4e704fe32d0e8ed6ab7b75a90126eb390/docs/img/client_application_architecture.jpg
--------------------------------------------------------------------------------
/docs/img/client_block_diagram.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iotaledger-archive/iota.c/bdcaf8e4e704fe32d0e8ed6ab7b75a90126eb390/docs/img/client_block_diagram.jpg
--------------------------------------------------------------------------------
/docs/img/github_download_zip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iotaledger-archive/iota.c/bdcaf8e4e704fe32d0e8ed6ab7b75a90126eb390/docs/img/github_download_zip.png
--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------
1 | # IOTA C Client API Reference
2 |
3 | ## Welcome
4 |
5 | This is an IOTA Client library for IOTA Shimmer network.
6 | Learn more about IOTA, please visit [IOTA WiKi](https://wiki.iota.org/).
7 | This C Client is still a highly development project for POSIX systems and embedded development, such as STM32, Nordic, Arduino, and ESP32 MCUs, the repository can be found in [iotaledger/iota.c](https://github.com/iotaledger/iota.c).
8 |
9 |
10 | ```{toctree}
11 | ---
12 | maxdepth: 2
13 | caption: IOTA C Client
14 | ---
15 | introduction.md
16 | examples.md
17 | arduino_esp32.md
18 | ```
19 |
20 | ```{toctree}
21 | ---
22 | maxdepth: 1
23 | caption: API Reference
24 | ---
25 | api/wallet.md
26 | api/events.md
27 | api/restful.md
28 | api/core.md
29 | api/crypto.md
30 | ```
31 |
--------------------------------------------------------------------------------
/docs/introduction.md:
--------------------------------------------------------------------------------
1 | # Introduction
2 |
3 | The C Client library is built for embedded development and can be integrated to POSIX operating systems easily.
4 |
5 | It has integrated with Software Development Kits(SDK) and a STM32Cube expansion:
6 | * [esp32-client-sdk](https://github.com/iotaledger/esp32-client-sdk) - based on ESP-IDF for ESP32 series
7 | * [zephyr-client-sdk](https://github.com/iotaledger/zephyr-client-sdk) - based on ZephyrOS, supports hundreds of MCU out of the box, it works with nRF Connect SDK for Nordic microcontrollers as well.
8 | * [iota-mbed-studio](https://github.com/iotaledger/iota-mbed-studio) - based on ARM Mbed OS and [Mbed Studio IDE](https://os.mbed.com/studio/).
9 | * [X-CUBE-IOTA1](https://www.st.com/en/embedded-software/x-cube-iota1.html) - IOTA Distributed Ledger Technology software expansion for STM32Cube
10 |
11 | ## C Client Library Diagram
12 |
13 | The C Client library consists 4 abstraction layers:
14 | * Crypto - provides cryptographic functions
15 | * Core - implements components include address/block/UTXO...
16 | * Client - implements node REST APIs and Event APIs. (optional)
17 | * Wallet - implements simple wallet functions. (optional)
18 |
19 | As a client application, Client and Wallet modules could be an option as needed. For instance, the application can implement its own wallet logic or it uses the Core module to compose blocks then send blocks through another interface without the Client module.
20 |
21 | 
22 |
23 | The C Client library relies on some functionalities from the operating system API or external library:
24 | * HTTP/HTTPS Client
25 | * JSON parser
26 | * Crypto library
27 | * MQTT Client
28 |
29 | ## IOTA Application Architecture
30 |
31 | The real world application could be vary, here shows an example of an IOTA client application.
32 |
33 | 
34 |
35 | With this design, the application can interact with IOTA Tangle in order to:
36 | * Create data and transaction blocks
37 | * Send data and transaction blocks
38 | * Query blocks
39 | * Query the node status
40 | * Generate addresses
41 | * Subscribe to node events
42 |
43 |
--------------------------------------------------------------------------------
/docs/make.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 |
3 | pushd %~dp0
4 |
5 | REM Command file for Sphinx documentation
6 |
7 | if "%SPHINXBUILD%" == "" (
8 | set SPHINXBUILD=sphinx-build
9 | )
10 | set SOURCEDIR=.
11 | set BUILDDIR=_build
12 |
13 | if "%1" == "" goto help
14 |
15 | %SPHINXBUILD% >NUL 2>NUL
16 | if errorlevel 9009 (
17 | echo.
18 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
19 | echo.installed, then set the SPHINXBUILD environment variable to point
20 | echo.to the full path of the 'sphinx-build' executable. Alternatively you
21 | echo.may add the Sphinx directory to PATH.
22 | echo.
23 | echo.If you don't have Sphinx installed, grab it from
24 | echo.http://sphinx-doc.org/
25 | exit /b 1
26 | )
27 |
28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
29 | goto end
30 |
31 | :help
32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
33 |
34 | :end
35 | popd
36 |
--------------------------------------------------------------------------------
/docs/requirements.txt:
--------------------------------------------------------------------------------
1 | sphinx_book_theme
2 | breathe
3 | myst-parser
4 |
--------------------------------------------------------------------------------
/examples/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | #[[
2 | // Copyright 2020 IOTA Stiftung
3 | // SPDX-License-Identifier: Apache-2.0
4 | ]]
5 |
6 | # function for example cases
7 | function(add_iota_example example_name example_src)
8 | add_executable(${example_name} "${example_src}")
9 | set_target_properties(${example_name} PROPERTIES C_STANDARD_REQUIRED NO C_STANDARD 99)
10 | target_include_directories(${example_name} PRIVATE ${PROJECT_SOURCE_DIR}/src ${CMAKE_INSTALL_PREFIX}/include)
11 | target_compile_options(${example_name} PRIVATE -Wall -Wextra)
12 | if(IOTA_WALLET_ENABLE)
13 | add_dependencies(${example_name} iota_wallet)
14 | target_link_libraries(${example_name} PRIVATE iota_wallet)
15 | else()
16 | add_dependencies(${example_name} iota_client)
17 | target_link_libraries(${example_name} PRIVATE iota_client)
18 | endif()
19 | endfunction(add_iota_example)
20 |
21 | add_iota_example(encrypted_tagged_data_block "client/encrypted_tagged_data_block.c")
22 | add_iota_example(tagged_data_block "client/tagged_data_block.c")
23 | add_iota_example(get_block "client/get_block.c")
24 | add_iota_example(node_info "client/node_info.c")
25 |
26 | if(IOTA_WALLET_ENABLE)
27 | add_iota_example(send_basic_output "wallet/send_basic_output.c")
28 | add_iota_example(create_alias_output "wallet/create_alias_output.c")
29 | add_iota_example(mint_native_tokens "wallet/mint_native_tokens.c")
30 | add_iota_example(send_native_tokens "wallet/send_native_tokens.c")
31 | endif()
32 |
33 | if(MQTT_CLIENT_ENABLE)
34 | add_iota_example(get_event_blocks "client/get_event_blocks.c")
35 | endif()
36 |
--------------------------------------------------------------------------------
/examples/README.md:
--------------------------------------------------------------------------------
1 | # IOTA C Client Examples
2 |
3 | This folder contains simple examples for developing IOTA client applications.
4 | For building example, please enable example option, `-DIOTA_EXAMPLES=TRUE`, during CMake configuration.
5 |
6 | * `arduino_esp32_info` - fetch node info with Arduino IDE
7 | * `arduino_esp32_token_transfer` - transfer IOTA tokens with Arduino IDE
8 | * Client - examples use client APIs
9 | * `encrypted_tagged_data_block` - sending encrypted data to the Tangle
10 | * `tagged_data_block` - sending data to the Tangle
11 | * `get_block` - getting Block object by a given BlockID
12 | * `node_info` - fetching node info from the connected node
13 | * `get_event_blocks` - subscript event by Even APIs
14 | * Wallet - examples use wallet APIs
15 | * `create_alias_output` - Creating an Alias output
16 | * `int_native_tokens` - Minting a Native tokens
17 | * `send_basic_output` - Sending IOTA tokens to a receiver
18 | * `send_native_tokens` - Minting a Native tokens and send it to a receiver
19 |
20 |
--------------------------------------------------------------------------------
/examples/arduino_esp32_info/arduino_esp32_info.ino:
--------------------------------------------------------------------------------
1 | // Copyright 2022 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | /**
5 | * @brief A simple example of getting a node info.
6 | *
7 | */
8 |
9 | #include
10 | #include
11 |
12 | #include
13 |
14 | // please set your WiFi SSID and Password
15 | const char* ssid = "xxxxx";
16 | const char* passwd = "sssss";
17 |
18 | // please set the API endpoint of the IOTA node
19 | const char* node_host = "localhost";
20 | const uint16_t node_port = 14265;
21 | const bool node_use_tls = false;
22 |
23 | uint32_t chipId = 0;
24 |
25 | int fetch_node_info() {
26 | iota_client_conf_t ctx = {};
27 | strcpy(ctx.host, node_host);
28 | ctx.port = node_port;
29 | ctx.use_tls = node_use_tls;
30 |
31 | res_node_info_t* info = res_node_info_new();
32 | if (!info) {
33 | printf("Failed to create a response node info object!\n");
34 | return -1;
35 | }
36 |
37 | if (get_node_info(&ctx, info) != 0) {
38 | printf("Retrieving node info failed!\n");
39 | res_node_info_free(info);
40 | return -1;
41 | }
42 |
43 | if (info->is_error) {
44 | // got an error message from node.
45 | printf("Error: %s\n", info->u.error->msg);
46 | } else {
47 | node_info_print(info, 0);
48 | }
49 |
50 | res_node_info_free(info);
51 | return 0;
52 | }
53 |
54 | void setup() {
55 | Serial.begin(115200);
56 | delay(10);
57 |
58 | // connecting to WiFi
59 | WiFi.begin(ssid, passwd);
60 |
61 | while (WiFi.status() != WL_CONNECTED) {
62 | delay(500);
63 | Serial.print(".");
64 | }
65 |
66 | Serial.println("");
67 | Serial.print("IP address: ");
68 | Serial.println(WiFi.localIP());
69 | }
70 |
71 | void loop() {
72 | for (int i = 0; i < 17; i = i + 8) {
73 | chipId |= ((ESP.getEfuseMac() >> (40 - i)) & 0xff) << i;
74 | }
75 |
76 | delay(10000);
77 | Serial.printf("ESP32 Chip model = %s Rev %d\n", ESP.getChipModel(), ESP.getChipRevision());
78 | Serial.printf("This chip has %d cores\n", ESP.getChipCores());
79 | Serial.print("Chip ID: ");
80 | Serial.println(chipId);
81 | fetch_node_info();
82 | }
83 |
--------------------------------------------------------------------------------
/examples/client/get_block.c:
--------------------------------------------------------------------------------
1 | // Copyright 2021 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | /**
5 | * @brief A simple example of getting a block by its ID from the Tangle.
6 | *
7 | */
8 |
9 | #include
10 |
11 | #include "client/api/restful/get_block.h"
12 |
13 | // replace this block ID as needed
14 | // Milestone
15 | #define BLK_ID "c0192ab155b501d2b51d4342b32970360d03835cce84f3b5a8c58e5f0c403b57"
16 | // Tagged Data
17 | //#define BLK_ID "6fc54c980a7a7480d4cb029c64e9a73eb1d4c3a1df40a297b607e1e137322142"
18 | // Transaction
19 | //#define BLK_ID "e95846e997dc6dae80e9a6dea908577a167b5e7c53b9fd802a760486a8c90d0f"
20 |
21 | int main(void) {
22 | iota_client_conf_t ctx = {.host = "localhost", .port = 14265, .use_tls = false};
23 |
24 | res_block_t *blk = res_block_new();
25 | if (!blk) {
26 | printf("Failed to create a response block object!\n");
27 | return -1;
28 | }
29 |
30 | if (get_block_by_id(&ctx, (char const *)BLK_ID, blk) != 0) {
31 | printf("Retrieving block from a node failed!\n");
32 | res_block_free(blk);
33 | return -1;
34 | }
35 |
36 | if (blk->is_error) {
37 | printf("API response: %s\n", blk->u.error->msg);
38 | res_block_free(blk);
39 | return -1;
40 | }
41 |
42 | switch (blk->u.blk->payload_type) {
43 | case CORE_BLOCK_PAYLOAD_MILESTONE:
44 | printf("Milestone block received:\n");
45 | core_block_print(blk->u.blk, 0);
46 | break;
47 | case CORE_BLOCK_PAYLOAD_TAGGED:
48 | printf("Tagged Data block received:\n");
49 | core_block_print(blk->u.blk, 0);
50 | break;
51 | case CORE_BLOCK_PAYLOAD_TRANSACTION:
52 | printf("Transaction block received:\n");
53 | core_block_print(blk->u.blk, 0);
54 | break;
55 | default:
56 | printf("Unsupported type of a block received!\n");
57 | break;
58 | }
59 |
60 | res_block_free(blk);
61 |
62 | return 0;
63 | }
64 |
--------------------------------------------------------------------------------
/examples/client/node_info.c:
--------------------------------------------------------------------------------
1 | // Copyright 2021 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | /**
5 | * @brief A simple example of getting a node info.
6 | *
7 | */
8 |
9 | #include
10 |
11 | #include "client/api/restful/get_node_info.h"
12 |
13 | int main(void) {
14 | iota_client_conf_t ctx = {.host = "localhost", .port = 14265, .use_tls = false};
15 |
16 | res_node_info_t *info = res_node_info_new();
17 | if (!info) {
18 | printf("Failed to create a response node info object!\n");
19 | return -1;
20 | }
21 |
22 | if (get_node_info(&ctx, info) != 0) {
23 | printf("Retrieving node info failed!\n");
24 | res_node_info_free(info);
25 | return -1;
26 | }
27 |
28 | if (info->is_error) {
29 | // got an error message from node.
30 | printf("Error: %s\n", info->u.error->msg);
31 | } else {
32 | node_info_print(info, 0);
33 | }
34 |
35 | res_node_info_free(info);
36 |
37 | return 0;
38 | }
39 |
--------------------------------------------------------------------------------
/examples/client/tagged_data_block.c:
--------------------------------------------------------------------------------
1 | // Copyright 2021 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | /**
5 | * @brief A simple example of sending a data to the Tangle.
6 | *
7 | */
8 |
9 | #include
10 | #include
11 |
12 | #include "client/api/restful/get_block.h"
13 | #include "client/api/restful/send_tagged_data.h"
14 | #include "core/models/payloads/tagged_data.h"
15 | #include "core/utils/iota_str.h"
16 |
17 | #define TAG "iota.c\xF0\x9F\xA6\x8B"
18 | #define MESSAGE "Hello world"
19 |
20 | int main(void) {
21 | iota_client_conf_t ctx = {.host = "localhost", .port = 14265, .use_tls = false};
22 |
23 | res_send_block_t res = {0};
24 |
25 | // send Hello world to the Tangle
26 | printf("Sending data block to the Tangle...\n");
27 | if (send_tagged_data_block(&ctx, 2, (byte_t *)TAG, strlen(TAG), (byte_t *)MESSAGE, strlen(MESSAGE), &res) == 0) {
28 | if (res.is_error) {
29 | printf("API response: %s\n", res.u.error->msg);
30 | return -1;
31 | }
32 | } else {
33 | printf("Sending block failed!\n");
34 | return -1;
35 | }
36 |
37 | printf("Block successfully sent.\n");
38 | printf("Block ID: %s\n", res.u.blk_id);
39 |
40 | res_block_t *blk = res_block_new();
41 | if (!blk) {
42 | printf("Failed to create a response block object!\n");
43 | return -1;
44 | }
45 |
46 | // fetch block from the Tangle
47 | printf("Fetching block from the Tangle...\n");
48 | if (get_block_by_id(&ctx, res.u.blk_id, blk) == 0) {
49 | if (blk->is_error) {
50 | printf("API response: %s\n", blk->u.error->msg);
51 | res_block_free(blk);
52 | return -1;
53 | }
54 | } else {
55 | printf("Fetching block from a node failed!\n");
56 | res_block_free(blk);
57 | return -1;
58 | }
59 |
60 | printf("Block successfully fetched.\n");
61 |
62 | // check if fetched block is Tagged Data block
63 | if (blk->u.blk->payload_type != CORE_BLOCK_PAYLOAD_TAGGED) {
64 | printf("Fetched block is not a Tagged Data block!\n");
65 | res_block_free(blk);
66 | return -1;
67 | }
68 |
69 | // Convert byte arrays to a strings
70 | if (!byte_buf2str(((tagged_data_payload_t *)blk->u.blk->payload)->tag)) {
71 | printf("Failed to convert byte array to a string!\n");
72 | res_block_free(blk);
73 | return -1;
74 | }
75 | if (!byte_buf2str(((tagged_data_payload_t *)blk->u.blk->payload)->data)) {
76 | printf("Failed to convert byte array to a string!\n");
77 | res_block_free(blk);
78 | return -1;
79 | }
80 |
81 | // print fetched block
82 | printf("Tagged Data:\n");
83 | printf("\tTag: %s\n", ((tagged_data_payload_t *)blk->u.blk->payload)->tag->data);
84 | printf("\tData: %s\n", ((tagged_data_payload_t *)blk->u.blk->payload)->data->data);
85 |
86 | // clean up resources
87 | res_block_free(blk);
88 |
89 | return 0;
90 | }
91 |
--------------------------------------------------------------------------------
/functional-tests/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | if(IOTA_WALLET_ENABLE)
2 |
3 | add_executable(functional-tests "functional_app.c" "functional_cases.c")
4 |
5 | set_target_properties(functional-tests PROPERTIES C_STANDARD_REQUIRED NO C_STANDARD 99)
6 |
7 | target_include_directories(functional-tests PRIVATE "${PROJECT_SOURCE_DIR}/src" "${CMAKE_INSTALL_PREFIX}/include"
8 | "${CMAKE_INSTALL_PREFIX}/include/cjson")
9 |
10 | add_custom_command(
11 | TARGET functional-tests
12 | POST_BUILD
13 | COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/functional-tests/config.json
14 | ${CMAKE_CURRENT_BINARY_DIR}/config.json)
15 |
16 | add_dependencies(functional-tests iota_wallet)
17 | target_link_libraries(functional-tests PRIVATE iota_wallet)
18 | endif()
19 |
--------------------------------------------------------------------------------
/functional-tests/README.md:
--------------------------------------------------------------------------------
1 | # Functional Test Application
2 |
3 | The `functional-tests` is an application which test the functionality of iota.c by interacting with the IOTA network.
4 |
5 | # Usage
6 |
7 | Make sure `IOTA_TESTS` and `IOTA_WALLET_ENABLE` is enabled during CMake configuration, for example:
8 |
9 | ```
10 | git clone https://github.com/iotaledger/iota.c.git
11 | cd iota.c
12 | mkdir build && cd build
13 | cmake -DIOTA_TESTS=TRUE -DIOTA_WALLET_ENABLE=TRUE -DCryptoUse=libsodium -DCMAKE_INSTALL_PREFIX=$PWD ..
14 | make -j8
15 | ```
16 |
17 | After build without problems the application is in `build/functional-tests` folder.
18 |
19 | ```
20 | cd functional-tests
21 | ./functional-tests ./config.json
22 | ```
23 |
24 |
--------------------------------------------------------------------------------
/functional-tests/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "mnemonic": "acoustic trophy damage hint search taste love bicycle foster cradle brown govern endless depend situate athlete pudding blame question genius transfer van random vast",
3 | "sender_index": 0,
4 | "receiver_index": 1,
5 | "node":"localhost",
6 | "port": 14265,
7 | "use_tls": false,
8 | "faucet":"localhost",
9 | "faucet_port": 8091,
10 | "faucet_use_tls": false,
11 | "show_payload": true,
12 | "coin_type": 1,
13 | "delay": 10
14 | }
15 |
--------------------------------------------------------------------------------
/iota-c.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iotaledger-archive/iota.c/bdcaf8e4e704fe32d0e8ed6ab7b75a90126eb390/iota-c.png
--------------------------------------------------------------------------------
/library.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "iota_client",
3 | "version": "0.0.2",
4 | "keywords": "crypto, iota, client",
5 | "description": "IOTA C client library",
6 | "repository": {
7 | "type": "git",
8 | "url": "https://github.com/iotaledger/iota.c.git",
9 | "branch": "dev"
10 | },
11 | "authors": {
12 | "name": "Sam Chen",
13 | "email": "sam.chen@iota.org",
14 | "maintainer": true
15 | },
16 | "frameworks": "*",
17 | "platforms": "espressif32"
18 | }
19 |
--------------------------------------------------------------------------------
/library.properties:
--------------------------------------------------------------------------------
1 | name=IOTA ESP32 Client
2 | version=1.0.1
3 | author=Sam Chen , Rabin Muhammed , Matjaz Verbole
4 | maintainer=Sam Chen
5 | sentence=The IOTA client library for arduino-esp32
6 | paragraph=Communicating with IOTA node software, sending trandactions to the Tangle.
7 | category=Communication
8 | url=https://github.com/iotaledger/iota.c
9 | architectures=esp32
10 | includes=iota_client.h
11 | depends=uthash
12 |
--------------------------------------------------------------------------------
/src/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | #[[
2 | // Copyright 2020 IOTA Stiftung
3 | // SPDX-License-Identifier: Apache-2.0
4 | ]]
5 |
6 | if(IOTA_WALLET_ENABLE)
7 | add_subdirectory(wallet)
8 | endif(IOTA_WALLET_ENABLE)
9 |
10 | if(WITH_IOTA_CLIENT)
11 | add_subdirectory(client)
12 | endif()
13 |
14 | if(WITH_IOTA_CORE)
15 | add_subdirectory(core)
16 | endif()
17 |
18 | add_subdirectory(crypto)
19 |
--------------------------------------------------------------------------------
/src/client/api/events/sub_blocks_metadata.c:
--------------------------------------------------------------------------------
1 | // Copyright 2021 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #include
5 |
6 | #include "client/api/events/sub_blocks_metadata.h"
7 | #include "client/api/json_parser/json_utils.h"
8 | #include "client/constants.h"
9 | #include "client/network/mqtt/mqtt.h"
10 |
11 | int event_subscribe_blk_metadata(event_client_handle_t client, int *mid, char const blk_id[], int qos) {
12 | if (strlen(blk_id) != BIN_TO_HEX_BYTES(IOTA_BLOCK_ID_BYTES)) {
13 | printf("[%s:%d]: Block ID length is invalid\n", __func__, __LINE__);
14 | return -1;
15 | }
16 | // Buffer to store topic string : block-metadata/0x{blockid}
17 | char topic_buff[BIN_TO_HEX_BYTES(IOTA_BLOCK_ID_BYTES) + 20] = {0};
18 | // Prepare topic string
19 | sprintf(topic_buff, "block-metadata/0x%s", blk_id);
20 | // Call to MQTT network layer
21 | return event_subscribe(client, mid, topic_buff, qos);
22 | }
23 |
--------------------------------------------------------------------------------
/src/client/api/events/sub_blocks_metadata.h:
--------------------------------------------------------------------------------
1 | // Copyright 2021 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __SUB_BLOCKS_METADATA_H__
5 | #define __SUB_BLOCKS_METADATA_H__
6 |
7 | #include
8 | #include
9 |
10 | #include "client/api/events/node_event.h"
11 | #include "core/models/block.h"
12 | #include "core/utils/macros.h"
13 |
14 | #ifdef __cplusplus
15 | extern "C" {
16 | #endif
17 |
18 | /**
19 | * @brief Subscribes block-metadata/{blockid} event
20 | *
21 | * @param[in] client The event client instance
22 | * @param[out] mid If not NULL, mid will return the message id of the topic subscription
23 | * @param[in] msg_id A message id for the event
24 | * @param[in] qos A QoS level for the topic
25 | * @return int 0 If Success
26 | */
27 | int event_subscribe_blk_metadata(event_client_handle_t client, int *mid, char const msg_id[], int qos);
28 |
29 | #ifdef __cplusplus
30 | }
31 | #endif
32 |
33 | #endif
34 |
--------------------------------------------------------------------------------
/src/client/api/events/sub_milestone_payload.c:
--------------------------------------------------------------------------------
1 | // Copyright 2021 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #include
5 |
6 | #include "client/api/events/sub_milestone_payload.h"
7 | #include "client/api/json_parser/json_utils.h"
8 | #include "client/network/mqtt/mqtt.h"
9 |
10 | int parse_milestone_payload(char *data, events_milestone_payload_t *res) {
11 | if (res == NULL) {
12 | printf("[%s:%d] invalid parameters\n", __func__, __LINE__);
13 | return -1;
14 | }
15 |
16 | cJSON *json_obj = cJSON_Parse((char *)data);
17 | if (json_obj == NULL) {
18 | printf("[%s:%d] OOM\n", __func__, __LINE__);
19 | return -1;
20 | }
21 |
22 | // Parse index
23 | if (json_get_uint32(json_obj, JSON_KEY_MILESTONE_INDEX, &(res->index)) != 0) {
24 | printf("[%s:%d]: parse %s failed\n", __func__, __LINE__, JSON_KEY_INDEX);
25 | return -1;
26 | }
27 |
28 | // Parse timestamp
29 | if (json_get_uint32(json_obj, JSON_KEY_MILESTONE_TIMESTAMP, &(res->timestamp)) != 0) {
30 | printf("[%s:%d]: parse %s failed\n", __func__, __LINE__, JSON_KEY_TIMESTAMP);
31 | return -1;
32 | }
33 |
34 | // parsing last milestone ID
35 | if (json_get_hex_str_to_bin(json_obj, JSON_KEY_MILESTONE_ID, res->milestone_id, sizeof(res->milestone_id)) != 0) {
36 | printf("[%s:%d]: parsing %s hex string failed\n", __func__, __LINE__, JSON_KEY_MILESTONE_ID);
37 | return -1;
38 | }
39 |
40 | cJSON_Delete(json_obj);
41 | return 0;
42 | }
43 |
--------------------------------------------------------------------------------
/src/client/api/events/sub_milestone_payload.h:
--------------------------------------------------------------------------------
1 | // Copyright 2021 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __SUB_MILESTONE_LATEST_H__
5 | #define __SUB_MILESTONE_LATEST_H__
6 |
7 | #include
8 | #include
9 |
10 | #include "core/utils/byte_buffer.h"
11 | #include "crypto/iota_crypto.h"
12 |
13 | /**
14 | * @brief Stores timestamp and index
15 | *
16 | */
17 | typedef struct {
18 | uint32_t timestamp; ///< The timestamp of milestone payload
19 | uint32_t index; ///< The index of milestone payload
20 | byte_t milestone_id[CRYPTO_BLAKE2B_256_HASH_BYTES]; ///< The milestone id
21 | } events_milestone_payload_t;
22 |
23 | #ifdef __cplusplus
24 | extern "C" {
25 | #endif
26 |
27 | /**
28 | * @brief Parse milestone payload response
29 | * @param[in] data Response data to parse
30 | * @param[out] res Parsed response object
31 | * @return int 0 If success
32 | */
33 | int parse_milestone_payload(char *data, events_milestone_payload_t *res);
34 |
35 | #ifdef __cplusplus
36 | }
37 | #endif
38 |
39 | #endif
--------------------------------------------------------------------------------
/src/client/api/events/sub_serialized_output.c:
--------------------------------------------------------------------------------
1 | // Copyright 2021 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #include
5 |
6 | #include "client/api/events/sub_serialized_output.h"
7 | #include "core/address.h"
8 | #include "core/models/payloads/tagged_data.h"
9 | #include "core/utils/macros.h"
10 |
11 | int event_sub_txn_included_blk(event_client_handle_t client, int *mid, char const transaction_id[], int qos) {
12 | if (strlen(transaction_id) != BIN_TO_HEX_BYTES(IOTA_TRANSACTION_ID_BYTES)) {
13 | printf("[%s:%d]: Transaction id length is invalid\n", __func__, __LINE__);
14 | return -1;
15 | }
16 | // buffer for holding string "transactions/0x{transactionId}/included-block"
17 | char topic_buff[31 + BIN_TO_HEX_BYTES(IOTA_TRANSACTION_ID_BYTES)] = {0};
18 |
19 | sprintf(topic_buff, "transactions/0x%s/included-block", transaction_id);
20 |
21 | return event_subscribe(client, mid, topic_buff, qos);
22 | }
23 |
24 | int event_sub_tx_blk_tagged_data(event_client_handle_t client, int *mid, byte_t tag[], uint8_t tag_len, int qos) {
25 | if (tag_len > TAGGED_DATA_TAG_MAX_LENGTH_BYTES) {
26 | printf("[%s:%d]: Tag length is invalid\n", __func__, __LINE__);
27 | return -1;
28 | }
29 | // 34 is the max length for string blocks/transaction/tagged-data/0x, max hex-encoded-tag is 128
30 | char topic_buff[34 + BIN_TO_HEX_BYTES(TAGGED_DATA_TAG_MAX_LENGTH_BYTES)] = {0};
31 |
32 | // hex encoded tag string
33 | char tag_str[BIN_TO_HEX_STR_BYTES(TAGGED_DATA_TAG_MAX_LENGTH_BYTES)] = {0};
34 | if (bin_2_hex(tag, tag_len, NULL, tag_str, sizeof(tag_str)) != 0) {
35 | printf("[%s:%d] bin to hex tag conversion failed\n", __func__, __LINE__);
36 | return -1;
37 | }
38 |
39 | sprintf(topic_buff, "blocks/transaction/tagged-data/0x%s", tag_str);
40 |
41 | return event_subscribe(client, mid, topic_buff, qos);
42 | }
43 |
44 | int event_sub_blk_tagged_data(event_client_handle_t client, int *mid, byte_t tag[], uint8_t tag_len, int qos) {
45 | if (tag_len > TAGGED_DATA_TAG_MAX_LENGTH_BYTES) {
46 | printf("[%s:%d]: Tag length is invalid\n", __func__, __LINE__);
47 | return -1;
48 | }
49 |
50 | // hex encoded tag string
51 | char tag_str[BIN_TO_HEX_STR_BYTES(TAGGED_DATA_TAG_MAX_LENGTH_BYTES)] = {0};
52 | if (bin_2_hex(tag, tag_len, NULL, tag_str, sizeof(tag_str)) != 0) {
53 | printf("[%s:%d] bin to hex tag conversion failed\n", __func__, __LINE__);
54 | return -1;
55 | }
56 |
57 | // 22 is the max length for string blocks/tagged-data/0x, max hex-encoded-tag is 128
58 | char topic_buff[22 + BIN_TO_HEX_BYTES(TAGGED_DATA_TAG_MAX_LENGTH_BYTES)] = {0};
59 | sprintf(topic_buff, "%s/0x%s", TOPIC_BLK_TAGGED_DATA, tag_str);
60 |
61 | return event_subscribe(client, mid, topic_buff, qos);
62 | }
63 |
64 | int event_unsub_blk_tagged_data(event_client_handle_t client, int *mid, byte_t tag[], uint8_t tag_len) {
65 | if (tag_len > TAGGED_DATA_TAG_MAX_LENGTH_BYTES) {
66 | printf("[%s:%d]: Tag length is invalid\n", __func__, __LINE__);
67 | return -1;
68 | }
69 |
70 | // hex encoded tag string
71 | char tag_str[BIN_TO_HEX_STR_BYTES(TAGGED_DATA_TAG_MAX_LENGTH_BYTES)] = {0};
72 | if (bin_2_hex(tag, tag_len, NULL, tag_str, sizeof(tag_str)) != 0) {
73 | printf("[%s:%d] bin to hex tag conversion failed\n", __func__, __LINE__);
74 | return -1;
75 | }
76 |
77 | // 22 is the max length for string blocks/tagged-data/0x, max hex-encoded-tag is 128
78 | char topic_buff[22 + BIN_TO_HEX_BYTES(TAGGED_DATA_TAG_MAX_LENGTH_BYTES)] = {0};
79 | sprintf(topic_buff, "%s/0x%s", TOPIC_BLK_TAGGED_DATA, tag_str);
80 |
81 | return event_unsubscribe(client, mid, topic_buff);
82 | }
83 |
--------------------------------------------------------------------------------
/src/client/api/events/sub_serialized_output.h:
--------------------------------------------------------------------------------
1 | // Copyright 2021 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __SUB_SERIALIZED_OUTPUT_H__
5 | #define __SUB_SERIALIZED_OUTPUT_H__
6 |
7 | #include "client/api/events/node_event.h"
8 | #include "core/utils/byte_buffer.h"
9 |
10 | #ifdef __cplusplus
11 | extern "C" {
12 | #endif
13 |
14 | /**
15 | * @brief Subscribes transactions/{transactionId}/included_block topic
16 | *
17 | * @param[in] client The event client object
18 | * @param[out] mid If not NULL, mid will return the message id of the topic subscription
19 | * @param[in] transaction_id A transaction id
20 | * @param[in] qos The QoS level for the topic
21 | * @return int 0 If success
22 | */
23 | int event_sub_txn_included_blk(event_client_handle_t client, int *mid, char const transaction_id[], int qos);
24 |
25 | /**
26 | * @brief Subscribes blocks/transaction/tagged-data/{tag} topic for receiving transaction blocks with {tag}
27 | *
28 | * @param[in] client The event client object
29 | * @param[in] mid If not NULL, mid will return the message id of the topic subscription
30 | * @param[in] tag A tag to get transaction blocks
31 | * @param[in] tag_len The length of the tag in bytes
32 | * @param[in] qos The QoS level for the topic
33 | * @return int 0 If success
34 | */
35 | int event_sub_tx_blk_tagged_data(event_client_handle_t client, int *mid, byte_t tag[], uint8_t tag_len, int qos);
36 |
37 | /**
38 | * @brief Subscribes blocks/tagged-data/{tag} topic for receiving blocks with {tag}
39 | *
40 | * @param[in] client The event client object
41 | * @param[in] mid If not NULL, mid will return the message id of the topic subscription
42 | * @param[in] tag A tag to get blocks
43 | * @param[in] tag_len The length of the tag in bytes
44 | * @param[in] qos The QoS level for the topic
45 | * @return int 0 If success
46 | */
47 | int event_sub_blk_tagged_data(event_client_handle_t client, int *mid, byte_t tag[], uint8_t tag_len, int qos);
48 |
49 | /**
50 | * @brief Unsubscribes blocks/tagged-data/{tag} topic for receiving blocks with {tag}
51 | *
52 | * @param[in] client The event client object
53 | * @param[in] mid If not NULL, mid will return the message id of the topic subscription
54 | * @param[in] tag A tag to get blocks
55 | * @param[in] tag_len The length of the tag in bytes
56 | * @return int 0 If success
57 | */
58 | int event_unsub_blk_tagged_data(event_client_handle_t client, int *mid, byte_t tag[], uint8_t tag_len);
59 |
60 | #ifdef __cplusplus
61 | }
62 | #endif
63 |
64 | #endif
65 |
--------------------------------------------------------------------------------
/src/client/api/json_parser/block.h:
--------------------------------------------------------------------------------
1 | // Copyright 2022 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __CLIENT_API_JSON_PARSER_BLOCK_H__
5 | #define __CLIENT_API_JSON_PARSER_BLOCK_H__
6 |
7 | #include "cJSON.h"
8 | #include "core/models/block.h"
9 |
10 | #ifdef __cplusplus
11 | extern "C" {
12 | #endif
13 |
14 | /**
15 | * @brief Deserialize a JSON object to block
16 | *
17 | * @param[in] json_obj A JSON object
18 | * @param[out] blk The output block object
19 | * @return int 0 on success
20 | */
21 | int json_block_deserialize(cJSON* json_obj, core_block_t* blk);
22 |
23 | /**
24 | * @brief Serialize a block to JSON object
25 | *
26 | * @param[in] blk A block object
27 | * @return cJSON* NULL on errors
28 | */
29 | cJSON* json_block_serialize(core_block_t* blk);
30 |
31 | #ifdef __cplusplus
32 | }
33 | #endif
34 |
35 | #endif // __CLIENT_API_JSON_PARSER_BLOCK_H__
36 |
--------------------------------------------------------------------------------
/src/client/api/json_parser/common.h:
--------------------------------------------------------------------------------
1 | // Copyright 2022 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __CLIENT_API_JSON_PARSER_COMMON_H__
5 | #define __CLIENT_API_JSON_PARSER_COMMON_H__
6 |
7 | #include "client/api/json_parser/json_utils.h"
8 | #include "core/address.h"
9 |
10 | #ifdef __cplusplus
11 | extern "C" {
12 | #endif
13 |
14 | /**
15 | * @brief Deserialize JSON address data to address object
16 | *
17 | * @param[in] json_obj JSON object
18 | * @param[in] json_address_key JSON key for address
19 | * @param[out] address Deserialized address
20 | * @return int 0 on success
21 | */
22 | int json_parser_common_address_deserialize(cJSON *json_obj, char const *const json_address_key, address_t *address);
23 |
24 | /**
25 | * @brief Serialize An address to JSON object
26 | *
27 | * @param[in] address An address object
28 | * @return cJSON* NULL on error
29 | */
30 | cJSON *json_parser_common_address_serialize(address_t *address);
31 |
32 | #ifdef __cplusplus
33 | }
34 | #endif
35 |
36 | #endif // __CLIENT_API_JSON_PARSER_COMMON_H__
37 |
--------------------------------------------------------------------------------
/src/client/api/json_parser/inputs/inputs.h:
--------------------------------------------------------------------------------
1 | // Copyright 2022 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __CLIENT_API_JSON_PARSER_INPUTS_INPUTS_H__
5 | #define __CLIENT_API_JSON_PARSER_INPUTS_INPUTS_H__
6 |
7 | #include "client/api/json_parser/json_utils.h"
8 | #include "core/models/payloads/transaction.h"
9 |
10 | #ifdef __cplusplus
11 | extern "C" {
12 | #endif
13 |
14 | /**
15 | * @brief Deserialize JSON data to an utxo input list object
16 | *
17 | * @param[in] inputs_obj inputs JSON object
18 | * @param[out] inputs An utxo input list
19 | * @return int 0 on success
20 | */
21 | int json_inputs_deserialize(cJSON* inputs_obj, utxo_inputs_list_t** inputs);
22 |
23 | /**
24 | * @brief Serialize input list to JSON object
25 | *
26 | * @param[in] inputs An input list object
27 | * @return cJSON* NULL on errors
28 | */
29 | cJSON* json_inputs_serialize(utxo_inputs_list_t* inputs);
30 |
31 | #ifdef __cplusplus
32 | }
33 | #endif
34 |
35 | #endif // __CLIENT_API_JSON_PARSER_INPUTS_INPUTS_H__
36 |
--------------------------------------------------------------------------------
/src/client/api/json_parser/outputs/features.h:
--------------------------------------------------------------------------------
1 | // Copyright 2022 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __CLIENT_API_JSON_PARSER_OUTPUTS_FEATURES_H__
5 | #define __CLIENT_API_JSON_PARSER_OUTPUTS_FEATURES_H__
6 |
7 | #include "client/api/json_parser/json_utils.h"
8 | #include "core/models/outputs/features.h"
9 |
10 | #ifdef __cplusplus
11 | extern "C" {
12 | #endif
13 |
14 | /**
15 | * @brief Deserialize JSON sender feature to feature object
16 | *
17 | * @param[in] feat_obj Feature JSON object
18 | * @param[out] feat_list Features list object
19 | * @return int 0 on success
20 | */
21 | int json_feat_sender_deserialize(cJSON *feat_obj, feature_list_t **feat_list);
22 |
23 | /**
24 | * @brief Deserialize JSON issuer feature to feature object
25 | *
26 | * @param[in] feat_obj Feature JSON object
27 | * @param[out] feat_list Features list object
28 | * @return int 0 on success
29 | */
30 | int json_feat_issuer_deserialize(cJSON *feat_obj, feature_list_t **feat_list);
31 |
32 | /**
33 | * @brief Deserialize JSON metadata feature to feature object
34 | *
35 | * @param[in] feat_obj Feature JSON object
36 | * @param[out] feat_list Features list object
37 | * @return int 0 on success
38 | */
39 | int json_feat_metadata_deserialize(cJSON *feat_obj, feature_list_t **feat_list);
40 |
41 | /**
42 | * @brief Deserialize JSON tag feature to feature object
43 | *
44 | * @param[in] feat_obj Feature JSON object
45 | * @param[out] feat_list Features list object
46 | * @return int 0 on success
47 | */
48 | int json_feat_tag_deserialize(cJSON *feat_obj, feature_list_t **feat_list);
49 |
50 | /**
51 | * @brief Deserialize JSON data to features list object
52 | *
53 | * @param[in] output_obj Output JSON object
54 | * @param[in] immutable Flag which indicates if feature is immutable
55 | * @param[out] feat_list Features list object
56 | * @return int 0 on success
57 | */
58 | int json_features_deserialize(cJSON *output_obj, bool immutable, feature_list_t **feat_list);
59 |
60 | /**
61 | * @brief Serialize a feature list
62 | *
63 | * @param[in] feat_list A feature list
64 | * @return cJSON* NULL on errors
65 | */
66 | cJSON *json_features_serialize(feature_list_t *feat_list);
67 |
68 | #ifdef __cplusplus
69 | }
70 | #endif
71 |
72 | #endif // __CLIENT_API_JSON_PARSER_OUTPUTS_FEAT_BLOCKS_H__
73 |
--------------------------------------------------------------------------------
/src/client/api/json_parser/outputs/native_tokens.h:
--------------------------------------------------------------------------------
1 | // Copyright 2022 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __CLIENT_API_JSON_PARSER_OUTPUTS_NATIVE_TOKENS_H__
5 | #define __CLIENT_API_JSON_PARSER_OUTPUTS_NATIVE_TOKENS_H__
6 |
7 | #include "client/api/json_parser/json_utils.h"
8 | #include "core/models/outputs/native_tokens.h"
9 |
10 | #ifdef __cplusplus
11 | extern "C" {
12 | #endif
13 |
14 | /**
15 | * @brief Deserialize JSON data to native tokens object
16 | *
17 | * @param[in] output_obj Output JSON object
18 | * @param[out] native_tokens Transaction Native Tokens object
19 | * @return int 0 on success
20 | */
21 | int json_native_tokens_deserialize(cJSON *output_obj, native_tokens_list_t **native_tokens);
22 |
23 | /**
24 | * @brief Serialize native tokens
25 | *
26 | * @param[in] native_tokens
27 | * @return cJSON* NULL on errors
28 | */
29 | cJSON *json_native_tokens_serialize(native_tokens_list_t *native_tokens);
30 |
31 | #ifdef __cplusplus
32 | }
33 | #endif
34 |
35 | #endif // __CLIENT_API_JSON_PARSER_OUTPUTS_NATIVE_TOKENS_H__
36 |
--------------------------------------------------------------------------------
/src/client/api/json_parser/outputs/output_alias.h:
--------------------------------------------------------------------------------
1 | // Copyright 2022 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __CLIENT_API_JSON_PARSER_OUTPUTS_OUTPUT_ALIAS_H__
5 | #define __CLIENT_API_JSON_PARSER_OUTPUTS_OUTPUT_ALIAS_H__
6 |
7 | #include "client/api/json_parser/json_utils.h"
8 | #include "core/models/outputs/output_alias.h"
9 |
10 | #ifdef __cplusplus
11 | extern "C" {
12 | #endif
13 |
14 | /**
15 | * @brief Deserialize JSON data to output alias object
16 | *
17 | * @param[in] output_obj An output JSON object
18 | * @param[out] alias A new alias object
19 | * @return int 0 on success
20 | */
21 | int json_output_alias_deserialize(cJSON *output_obj, output_alias_t **alias);
22 |
23 | /**
24 | * @brief Serialize Alias output to JSON object
25 | *
26 | * @param[in] alias An alias output object
27 | * @return cJSON* NULL on errors
28 | */
29 | cJSON *json_output_alias_serialize(output_alias_t *alias);
30 |
31 | #ifdef __cplusplus
32 | }
33 | #endif
34 |
35 | #endif // __CLIENT_API_JSON_PARSER_OUTPUTS_OUTPUT_ALIAS_H__
36 |
--------------------------------------------------------------------------------
/src/client/api/json_parser/outputs/output_basic.h:
--------------------------------------------------------------------------------
1 | // Copyright 2022 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __CLIENT_API_JSON_PARSER_OUTPUTS_OUTPUT_BASIC_H__
5 | #define __CLIENT_API_JSON_PARSER_OUTPUTS_OUTPUT_BASIC_H__
6 |
7 | #include "client/api/json_parser/json_utils.h"
8 | #include "core/models/outputs/output_basic.h"
9 |
10 | #ifdef __cplusplus
11 | extern "C" {
12 | #endif
13 |
14 | /**
15 | * @brief Deserialize JSON data to output basic object
16 | *
17 | * @param[in] output_obj An output JSON object
18 | * @param[out] basic A new basic object
19 | * @return int 0 on success
20 | */
21 | int json_output_basic_deserialize(cJSON* output_obj, output_basic_t** basic);
22 |
23 | /**
24 | * @brief Serialize basic output to JSON object
25 | *
26 | * @param basic An basic output
27 | * @return cJSON* NULL on errors
28 | */
29 | cJSON* json_output_basic_serialize(output_basic_t* basic);
30 |
31 | #ifdef __cplusplus
32 | }
33 | #endif
34 |
35 | #endif // __CLIENT_API_JSON_PARSER_OUTPUTS_OUTPUT_BASIC_H__
36 |
--------------------------------------------------------------------------------
/src/client/api/json_parser/outputs/output_foundry.h:
--------------------------------------------------------------------------------
1 | // Copyright 2022 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __CLIENT_API_JSON_PARSER_OUTPUTS_OUTPUT_FOUNDRY_H__
5 | #define __CLIENT_API_JSON_PARSER_OUTPUTS_OUTPUT_FOUNDRY_H__
6 |
7 | #include "client/api/json_parser/json_utils.h"
8 | #include "core/models/outputs/output_foundry.h"
9 |
10 | #ifdef __cplusplus
11 | extern "C" {
12 | #endif
13 |
14 | /**
15 | * @brief Deserialize a JSON token scheme object
16 | *
17 | * @param[in] output_obj Output JSON object
18 | * @param[out] token_scheme A token scheme object
19 | * @return int 0 on success
20 | */
21 | int json_token_scheme_deserialize(cJSON *output_obj, token_scheme_t **token_scheme);
22 |
23 | /**
24 | * @brief Serialize token scheme
25 | *
26 | * @param[in] scheme A token scheme object
27 | * @return cJSON* NULL on errors
28 | */
29 | cJSON *json_token_scheme_serialize(token_scheme_t *scheme);
30 |
31 | /**
32 | * @brief Deserialize JSON data to output foundry object
33 | *
34 | * @param[in] output_obj An output JSON object
35 | * @param[out] foundry A new foundry object
36 | * @return int 0 on success
37 | */
38 | int json_output_foundry_deserialize(cJSON *output_obj, output_foundry_t **foundry);
39 |
40 | /**
41 | * @brief Serialize a foundry output to a JSON object
42 | *
43 | * @param[in] foundry A foundry output
44 | * @return cJSON* NULL on errors
45 | */
46 | cJSON *json_output_foundry_serialize(output_foundry_t *foundry);
47 |
48 | #ifdef __cplusplus
49 | }
50 | #endif
51 |
52 | #endif // __CLIENT_API_JSON_PARSER_OUTPUTS_OUTPUT_FOUNDRY_H__
53 |
--------------------------------------------------------------------------------
/src/client/api/json_parser/outputs/output_nft.h:
--------------------------------------------------------------------------------
1 | // Copyright 2022 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __CLIENT_API_JSON_PARSER_OUTPUTS_OUTPUT_NFT_H__
5 | #define __CLIENT_API_JSON_PARSER_OUTPUTS_OUTPUT_NFT_H__
6 |
7 | #include "client/api/json_parser/json_utils.h"
8 | #include "core/models/outputs/output_nft.h"
9 |
10 | #ifdef __cplusplus
11 | extern "C" {
12 | #endif
13 |
14 | /**
15 | * @brief Deserialize JSON data to output NFT object
16 | *
17 | * @param[in] output_obj Output JSON object
18 | * @param[out] nft A new NFT object
19 | * @return int 0 on success
20 | */
21 | int json_output_nft_deserialize(cJSON *output_obj, output_nft_t **nft);
22 |
23 | /**
24 | * @brief Serialize a NFT output to a JSON object
25 | *
26 | * @param[in] nft A NFT output
27 | * @return cJSON* NULL on errors
28 | */
29 | cJSON *json_output_nft_serialize(output_nft_t *nft);
30 |
31 | #ifdef __cplusplus
32 | }
33 | #endif
34 |
35 | #endif // __CLIENT_API_JSON_PARSER_OUTPUTS_OUTPUT_NFT_H__
36 |
--------------------------------------------------------------------------------
/src/client/api/json_parser/outputs/outputs.h:
--------------------------------------------------------------------------------
1 | // Copyright 2022 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __CLIENT_API_JSON_PARSER_OUTPUTS_OUTPUTS_H__
5 | #define __CLIENT_API_JSON_PARSER_OUTPUTS_OUTPUTS_H__
6 |
7 | #include "client/api/json_parser/json_utils.h"
8 | #include "core/models/outputs/outputs.h"
9 |
10 | #ifdef __cplusplus
11 | extern "C" {
12 | #endif
13 |
14 | /**
15 | * @brief Deserialize JSON data to outputs list object
16 | *
17 | * @param[in] outputs_obj An outputs JSON object
18 | * @param[out] outputs An output list object
19 | * @return int 0 on success
20 | */
21 | int json_outputs_deserialize(cJSON *outputs_obj, utxo_outputs_list_t **outputs);
22 |
23 | /**
24 | * @brief Serialise an output list to a JSON object
25 | *
26 | * @param[in] outputs An output list
27 | * @return cJSON* NULL on errors
28 | */
29 | cJSON *json_outputs_serialize(utxo_outputs_list_t *outputs);
30 |
31 | #ifdef __cplusplus
32 | }
33 | #endif
34 |
35 | #endif // __CLIENT_API_JSON_PARSER_OUTPUTS_OUTPUTS_H__
36 |
--------------------------------------------------------------------------------
/src/client/api/json_parser/outputs/unlock_conditions.h:
--------------------------------------------------------------------------------
1 | // Copyright 2022 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __CLIENT_API_JSON_PARSER_OUTPUTS_UNLOCK_CONDITIONS_H__
5 | #define __CLIENT_API_JSON_PARSER_OUTPUTS_UNLOCK_CONDITIONS_H__
6 |
7 | #include "client/api/json_parser/json_utils.h"
8 | #include "core/models/outputs/unlock_conditions.h"
9 |
10 | #ifdef __cplusplus
11 | extern "C" {
12 | #endif
13 |
14 | /**
15 | * @brief Deserialize JSON address unlock condition to unlock condition object
16 | *
17 | * @param[in] unlock_cond_obj Unlock conditions JSON object
18 | * @param[out] cond_list Unlock conditions list object
19 | * @return int 0 on success
20 | */
21 | int json_condition_addr_deserialize(cJSON *unlock_cond_obj, unlock_cond_list_t **cond_list);
22 |
23 | /**
24 | * @brief Deserialize JSON storage deposit return unlock condition to unlock condition object
25 | *
26 | * @param[in] unlock_cond_obj Unlock conditions JSON object
27 | * @param[out] cond_list Unlock conditions list object
28 | * @return int 0 on success
29 | */
30 | int json_condition_storage_deserialize(cJSON *unlock_cond_obj, unlock_cond_list_t **cond_list);
31 |
32 | /**
33 | * @brief Deserialize JSON timelock unlock condition to unlock condition object
34 | *
35 | * @param[in] unlock_cond_obj Unlock conditions JSON object
36 | * @param[out] cond_list Unlock conditions list object
37 | * @return int 0 on success
38 | */
39 | int json_condition_timelock_deserialize(cJSON *unlock_cond_obj, unlock_cond_list_t **cond_list);
40 |
41 | /**
42 | * @brief Deserialize JSON expiration unlock condition to unlock condition object
43 | *
44 | * @param[in] unlock_cond_obj Unlock conditions JSON object
45 | * @param[out] cond_list Unlock conditions list object
46 | * @return int 0 on success
47 | */
48 | int json_condition_expir_deserialize(cJSON *unlock_cond_obj, unlock_cond_list_t **cond_list);
49 |
50 | /**
51 | * @brief Deserialize JSON state controller address unlock condition to unlock condition object
52 | *
53 | * @param[in] unlock_cond_obj Unlock conditions JSON object
54 | * @param[out] cond_list Unlock conditions list object
55 | * @return int 0 on success
56 | */
57 | int json_condition_state_deserialize(cJSON *unlock_cond_obj, unlock_cond_list_t **cond_list);
58 |
59 | /**
60 | * @brief Deserialize JSON governor address unlock condition to unlock condition object
61 | *
62 | * @param[in] unlock_cond_obj Unlock conditions JSON object
63 | * @param[out] cond_list Unlock conditions list object
64 | * @return int 0 on success
65 | */
66 | int json_condition_governor_deserialize(cJSON *unlock_cond_obj, unlock_cond_list_t **cond_list);
67 |
68 | /**
69 | * @brief Deserialize JSON immutable alias address unlock condition to unlock condition object
70 | *
71 | * @param[in] unlock_cond_obj Unlock conditions JSON object
72 | * @param[out] cond_list Unlock conditions list object
73 | * @return int 0 on success
74 | */
75 | int json_condition_immut_alias_deserialize(cJSON *unlock_cond_obj, unlock_cond_list_t **cond_list);
76 |
77 | /**
78 | * @brief Deserialize JSON unlock conditions list to unlock conditions list object
79 | *
80 | * @param[in] output_obj Output JSON object
81 | * @param[out] cond_list Unlock conditions list object
82 | * @return int 0 on success
83 | */
84 | int json_condition_list_deserialize(cJSON *output_obj, unlock_cond_list_t **cond_list);
85 |
86 | /**
87 | * @brief Serialize unlock conditions
88 | *
89 | * @param[in] cond_list An unlock conditions object
90 | * @return cJSON* NULL on errors
91 | */
92 | cJSON *json_condition_list_serialize(unlock_cond_list_t *cond_list);
93 |
94 | #ifdef __cplusplus
95 | }
96 | #endif
97 |
98 | #endif // __CLIENT_API_JSON_PARSER_OUTPUTS_UNLOCK_CONDITIONS_H__
99 |
--------------------------------------------------------------------------------
/src/client/api/json_parser/payloads/payloads.h:
--------------------------------------------------------------------------------
1 | // Copyright 2022 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __CLIENT_API_JSON_PARSER_PAYLOADS_PAYLOADS_H__
5 | #define __CLIENT_API_JSON_PARSER_PAYLOADS_PAYLOADS_H__
6 |
7 | #include "cJSON.h"
8 | #include "core/models/payloads/milestone.h"
9 | #include "core/models/payloads/tagged_data.h"
10 | #include "core/models/payloads/transaction.h"
11 |
12 | #ifdef __cplusplus
13 | extern "C" {
14 | #endif
15 |
16 | /**
17 | * @brief Deserialize JSON payload to transaction payload object
18 | *
19 | * @param[in] payload A payload JSON object
20 | * @param[out] tx A transaction payload object
21 | * @return int 0 on success
22 | */
23 | int json_transaction_deserialize(cJSON* payload, transaction_payload_t* tx);
24 |
25 | /**
26 | * @brief Serialize a transaction payload object to JSON object
27 | *
28 | * @param[in] tx A transaction payload object
29 | * @return cJSON* NULL on errors
30 | */
31 | cJSON* json_transaction_serialize(transaction_payload_t* tx);
32 |
33 | /**
34 | * @brief Deserialize JSON payload to milestone payload object
35 | *
36 | * @param[in] payload A payload JSON object
37 | * @param[out] ms A milestone payload object
38 | * @return int 0 on success
39 | */
40 | int milestone_deserialize(cJSON* payload, milestone_payload_t* ms);
41 |
42 | /**
43 | * @brief Deserialize JSON data to tagged data object
44 | *
45 | * @param[in] payload A payload JSON object
46 | * @param[out] tagged_data A tagged data object
47 | * @return int 0 on success
48 | */
49 | int json_tagged_deserialize(cJSON* payload, tagged_data_payload_t** tagged_data);
50 |
51 | /**
52 | * @brief Serialize a tagged data payload object to JSON object
53 | *
54 | * @param[in] tagged_data A tagged data object
55 | * @return cJSON* NULL on errors
56 | */
57 | cJSON* json_tagged_serialize(tagged_data_payload_t* tagged_data);
58 |
59 | #ifdef __cplusplus
60 | }
61 | #endif
62 |
63 | #endif // __CLIENT_API_JSON_PARSER_PAYLOADS_PAYLOADS_H__
64 |
--------------------------------------------------------------------------------
/src/client/api/json_parser/unlocks.h:
--------------------------------------------------------------------------------
1 | // Copyright 2022 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __CLIENT_API_JSON_PARSER_UNLOCKS_H__
5 | #define __CLIENT_API_JSON_PARSER_UNLOCKS_H__
6 |
7 | #include "client/api/json_parser/json_utils.h"
8 | #include "core/models/unlocks.h"
9 |
10 | #ifdef __cplusplus
11 | extern "C" {
12 | #endif
13 |
14 | /**
15 | * @brief Deserialize JSON data to an unlock list object
16 | *
17 | * @param[in] unlocks_obj Unlocks JSON object
18 | * @param[out] unlock_list Unlocks object
19 | * @return int 0 on success
20 | */
21 | int json_unlocks_deserialize(cJSON* unlocks_obj, unlock_list_t** unlock_list);
22 |
23 | /**
24 | * @brief Serialize an unlock list to a JSON object
25 | *
26 | * @param[in] unlock_list An unlock list
27 | * @return cJSON* NULL on errors
28 | */
29 | cJSON* json_unlocks_serialize(unlock_list_t* unlock_list);
30 |
31 | #ifdef __cplusplus
32 | }
33 | #endif
34 |
35 | #endif // __CLIENT_API_JSON_PARSER_UNLOCKS_H__
36 |
--------------------------------------------------------------------------------
/src/client/api/restful/faucet_enqueue.h:
--------------------------------------------------------------------------------
1 | // Copyright 2022 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __CLIENT_FAUCET_ENQUEUE_H__
5 | #define __CLIENT_FAUCET_ENQUEUE_H__
6 |
7 | #include
8 |
9 | #include "client/api/restful/response_error.h"
10 | #include "client/client_service.h"
11 | #include "core/address.h"
12 | #include "core/utils/macros.h"
13 |
14 | /**
15 | * @brief Store address and waiting requests count returned in response of faucet enqueue request
16 | *
17 | */
18 | typedef struct {
19 | char bech32_address[BIN_TO_HEX_STR_BYTES(ED25519_PUBKEY_BYTES)]; ///< The Bech32 encoded address that is
20 | ///< returned in response
21 | uint32_t waiting_reqs_count; ///< The number of requests in faucet queue
22 | } faucet_enqueue_t;
23 |
24 | /**
25 | * @brief The response of faucet enqueue request
26 | *
27 | */
28 | typedef struct {
29 | bool is_error; ///< True if got an error from the node.
30 | union {
31 | res_err_t *error; ///< Error message if is_error is True
32 | faucet_enqueue_t req_res; ///< Faucet enqueue response if is_error is False
33 | } u;
34 | } res_faucet_enqueue_t;
35 |
36 | #ifdef __cplusplus
37 | extern "C" {
38 | #endif
39 |
40 | /**
41 | * @brief Faucet enqueue response JSON deserialization
42 | *
43 | * @param[in] j_str A string of the JSON object
44 | * @param[out] res A response object
45 | * @return int 0 on success
46 | */
47 | int deser_faucet_enqueue_response(char const *const j_str, res_faucet_enqueue_t *res);
48 |
49 | /**
50 | * @brief Request tokens to address from faucet
51 | * @param[in] conf The client endpoint configuration
52 | * @param[in] addr_bech32 The Bech32 address to which the tokens needs to be requested from faucet
53 | * @param[out] res The faucet enqueue response object
54 | *
55 | * @return res_faucet_enqueue_t*
56 | */
57 | int req_tokens_to_addr_from_faucet(iota_client_conf_t const *conf, char const addr_bech32[], res_faucet_enqueue_t *res);
58 |
59 | #ifdef __cplusplus
60 | }
61 | #endif
62 |
63 | #endif
64 |
--------------------------------------------------------------------------------
/src/client/api/restful/get_block.h:
--------------------------------------------------------------------------------
1 | // Copyright 2020 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __CLIENT_API_RESTFUL_GET_MSG_H__
5 | #define __CLIENT_API_RESTFUL_GET_MSG_H__
6 |
7 | #include
8 | #include
9 |
10 | #include "client/api/restful/response_error.h"
11 | #include "client/client_service.h"
12 | #include "core/models/block.h"
13 |
14 | /**
15 | * @brief The response of get block
16 | *
17 | */
18 | typedef struct {
19 | bool is_error; ///< True if got an error from the node.
20 | union {
21 | res_err_t *error; ///< Error message if is_error is True
22 | core_block_t *blk; ///< a block object if is_error is False
23 | } u;
24 | } res_block_t;
25 |
26 | #ifdef __cplusplus
27 | extern "C" {
28 | #endif
29 |
30 | /**
31 | * @brief Allocate a block for API response
32 | *
33 | * @return res_block_t*
34 | */
35 | res_block_t *res_block_new();
36 |
37 | /**
38 | * @brief Free a block object
39 | *
40 | * @param[in] blk A block object
41 | */
42 | void res_block_free(res_block_t *blk);
43 |
44 | /**
45 | * @brief The block response deserialization
46 | *
47 | * @param[in] j_str A string of the JSON object
48 | * @param[out] res the block object
49 | * @return int 0 on success
50 | */
51 | int deser_get_block(char const *const j_str, res_block_t *res);
52 |
53 | /**
54 | * @brief Get the block data from a given block ID
55 | *
56 | * @param[in] conf The client endpoint configuration
57 | * @param[in] blk_id A block ID to query
58 | * @param[out] res The block body of the given ID
59 | * @return int 0 on success
60 | */
61 | int get_block_by_id(iota_client_conf_t const *conf, char const blk_id[], res_block_t *res);
62 |
63 | #ifdef __cplusplus
64 | }
65 | #endif
66 |
67 | #endif
68 |
--------------------------------------------------------------------------------
/src/client/api/restful/get_health.c:
--------------------------------------------------------------------------------
1 | // Copyright 2020 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #include
5 | #include
6 |
7 | #include "client/api/restful/get_health.h"
8 | #include "client/network/http.h"
9 | #include "core/utils/iota_str.h"
10 |
11 | int get_health(iota_client_conf_t const *conf, bool *health) {
12 | int ret = -1;
13 | long st = 0;
14 | byte_buf_t *http_res = NULL;
15 |
16 | // http client configuration
17 | http_client_config_t http_conf = {
18 | .host = conf->host, .path = "/health", .use_tls = conf->use_tls, .port = conf->port};
19 |
20 | if ((http_res = byte_buf_new()) == NULL) {
21 | printf("[%s:%d]: OOM\n", __func__, __LINE__);
22 | goto done;
23 | }
24 |
25 | ret = http_client_get(&http_conf, http_res, &st);
26 | if (st == 200 && ret == 0) {
27 | *health = true;
28 | } else {
29 | *health = false;
30 | }
31 |
32 | done:
33 | // cleanup command
34 | byte_buf_free(http_res);
35 |
36 | return ret;
37 | }
38 |
--------------------------------------------------------------------------------
/src/client/api/restful/get_health.h:
--------------------------------------------------------------------------------
1 | // Copyright 2020 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __CLIENT_API_RESTFUL_HEALTH_H__
5 | #define __CLIENT_API_RESTFUL_HEALTH_H__
6 |
7 | #include
8 | #include
9 |
10 | #include "client/client_service.h"
11 |
12 | #ifdef __cplusplus
13 | extern "C" {
14 | #endif
15 |
16 | /**
17 | * @brief Returns the health of the node.
18 | *
19 | * A node considers itself healthy if its current confirmed milestone is at most two delta away from the latest known
20 | * milestone, has at least one ongoing gossip stream and the latest known milestone is newer than 5 minutes.
21 | *
22 | * @param[in] conf The endpoint configuration
23 | * @param[out] health Is node health?
24 | * @return int 0 on success
25 | */
26 | int get_health(iota_client_conf_t const *conf, bool *health);
27 |
28 | #ifdef __cplusplus
29 | }
30 | #endif
31 |
32 | #endif
33 |
--------------------------------------------------------------------------------
/src/client/api/restful/get_tips.h:
--------------------------------------------------------------------------------
1 | // Copyright 2020 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __CLIENT_API_RESTFUL_TIPS_H__
5 | #define __CLIENT_API_RESTFUL_TIPS_H__
6 |
7 | #include
8 | #include
9 |
10 | #include "client/api/restful/response_error.h"
11 | #include "client/client_service.h"
12 | #include "client/network/http.h"
13 | #include "utarray.h"
14 |
15 | typedef UT_array get_tips_t;
16 |
17 | /**
18 | * @brief The response of get tips
19 | *
20 | */
21 | typedef struct {
22 | bool is_error; ///< True if got an error from the node.
23 | union {
24 | res_err_t *error; ///< Error message if is_error is True
25 | get_tips_t *tips; ///< list of tips if is_error is False
26 | } u;
27 | } res_tips_t;
28 |
29 | #ifdef __cplusplus
30 | extern "C" {
31 | #endif
32 |
33 | /**
34 | * @brief Allocate a res_tips_t response object
35 | *
36 | * @return res_tips_t*
37 | */
38 | res_tips_t *res_tips_new();
39 |
40 | /**
41 | * @brief Free a res_tips_t response object
42 | *
43 | * @param[in] tips a response object
44 | */
45 | void res_tips_free(res_tips_t *tips);
46 |
47 | /**
48 | * @brief Gets tips for attaching to a block
49 | *
50 | * Returns tips that are ideal for attaching to a block. The tips can be considered as `non-lazy` and are therefore
51 | * ideal for attaching a block.
52 | *
53 | * @param[in] conf The client endpoint configuration
54 | * @param[out] res A response object of tips object
55 | * @return int 0 on success
56 | */
57 | int get_tips(iota_client_conf_t const *conf, res_tips_t *res);
58 |
59 | /**
60 | * @brief Tips response deserialization
61 | *
62 | * @param[in] j_str A string of the JSON object
63 | * @param[out] res A response object of tips object
64 | * @return int 0 on success
65 | */
66 | int get_tips_deserialize(char const *const j_str, res_tips_t *res);
67 |
68 | /**
69 | * @brief Gets the number of block IDs
70 | *
71 | * @param[in] tips A response object
72 | * @return size_t
73 | */
74 | size_t get_tips_id_count(res_tips_t *tips);
75 |
76 | /**
77 | * @brief Gets a block ID by a given index
78 | *
79 | * @param[in] tips A response object
80 | * @param[in] index A index of a block ID
81 | * @return char*
82 | */
83 | char *get_tips_id(res_tips_t *tips, size_t index);
84 |
85 | #ifdef __cplusplus
86 | }
87 | #endif
88 |
89 | #endif
90 |
--------------------------------------------------------------------------------
/src/client/api/restful/get_transaction_included_block.c:
--------------------------------------------------------------------------------
1 | // Copyright 2020 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #include "client/api/restful/get_transaction_included_block.h"
5 | #include "client/constants.h"
6 | #include "client/network/http.h"
7 | #include "core/models/inputs/utxo_input.h"
8 | #include "core/utils/iota_str.h"
9 | #include "core/utils/macros.h"
10 |
11 | int get_transaction_included_block_by_id(iota_client_conf_t const *conf, char const tx_id[], res_block_t *res) {
12 | if (conf == NULL || tx_id == NULL || res == NULL) {
13 | printf("[%s:%d] invalid parameter\n", __func__, __LINE__);
14 | return -1;
15 | }
16 |
17 | if (strlen(tx_id) != BIN_TO_HEX_BYTES(IOTA_TRANSACTION_ID_BYTES)) {
18 | printf("[%s:%d]: invalid transaction id length: %zu\n", __func__, __LINE__, strlen(tx_id));
19 | return -1;
20 | }
21 |
22 | int ret = -1;
23 | byte_buf_t *http_res = NULL;
24 |
25 | iota_str_t *cmd = NULL;
26 | char const *const cmd_pre = "/transactions/0x";
27 | char const *const cmd_post = "/included-block";
28 |
29 | cmd = iota_str_reserve(strlen(CORE_API_ROUTE) + strlen(cmd_pre) + strlen(cmd_post) +
30 | BIN_TO_HEX_BYTES(IOTA_TRANSACTION_ID_BYTES) + 1);
31 | if (cmd == NULL) {
32 | printf("[%s:%d]: allocate command buffer failed\n", __func__, __LINE__);
33 | return -1;
34 | }
35 |
36 | // composing API command
37 | snprintf(cmd->buf, cmd->cap, "%s%s%s%s", CORE_API_ROUTE, cmd_pre, tx_id, cmd_post);
38 | cmd->len = strlen(cmd->buf);
39 |
40 | // http client configuration
41 | http_client_config_t http_conf = {.host = conf->host, .path = cmd->buf, .use_tls = conf->use_tls, .port = conf->port};
42 |
43 | if ((http_res = byte_buf_new()) == NULL) {
44 | printf("[%s:%d]: OOM\n", __func__, __LINE__);
45 | goto done;
46 | }
47 |
48 | // send request via http client
49 | long status = 0;
50 | if ((ret = http_client_get(&http_conf, http_res, &status)) == 0) {
51 | byte_buf2str(http_res);
52 | // json deserialization
53 | ret = deser_get_block((char const *const)http_res->data, res);
54 | }
55 |
56 | done:
57 | // cleanup command
58 | iota_str_destroy(cmd);
59 | byte_buf_free(http_res);
60 | return ret;
61 | }
62 |
63 | int deser_get_transaction_included_block(char const *const j_str, res_block_t *res) {
64 | if (j_str == NULL || res == NULL) {
65 | printf("[%s:%d] invalid parameter\n", __func__, __LINE__);
66 | return -1;
67 | }
68 |
69 | if (deser_get_block(j_str, res) != 0) {
70 | return -1;
71 | }
72 |
73 | // only transaction payload is a valid payload for a deserialized block
74 | if (!res->is_error && res->u.blk->payload_type != CORE_BLOCK_PAYLOAD_TRANSACTION) {
75 | return -1;
76 | }
77 |
78 | return 0;
79 | }
80 |
--------------------------------------------------------------------------------
/src/client/api/restful/get_transaction_included_block.h:
--------------------------------------------------------------------------------
1 | // Copyright 2020 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __CLIENT_API_RESTFUL_TRANSACTION_INCLUDED_BLOCK_H__
5 | #define __CLIENT_API_RESTFUL_TRANSACTION_INCLUDED_BLOCK_H__
6 |
7 | #include "client/api/restful/get_block.h"
8 |
9 | #ifdef __cplusplus
10 | extern "C" {
11 | #endif
12 |
13 | /**
14 | * @brief Get included block data from a given transaction ID
15 | *
16 | * @param[in] conf The client endpoint configuration
17 | * @param[in] tx_id A transaction ID to query
18 | * @param[out] res The block body of the given ID
19 | * @return int 0 on success
20 | */
21 | int get_transaction_included_block_by_id(iota_client_conf_t const *conf, char const tx_id[], res_block_t *res);
22 |
23 | /**
24 | * @brief The block response deserialization
25 | *
26 | * @param[in] j_str A string of the JSON object
27 | * @param[out] res the block object
28 | * @return int 0 on success
29 | */
30 | int deser_get_transaction_included_block(char const *const j_str, res_block_t *res);
31 |
32 | #ifdef __cplusplus
33 | }
34 | #endif
35 |
36 | #endif // __CLIENT_API_V1_TRANSACTION_INCLUDED_BLOCK_H__
37 |
--------------------------------------------------------------------------------
/src/client/api/restful/response_error.c:
--------------------------------------------------------------------------------
1 | // Copyright 2021 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #include
5 | #include
6 |
7 | #include "client/api/json_parser/json_keys.h"
8 | #include "client/api/restful/response_error.h"
9 | #include "core/utils/allocator.h"
10 |
11 | void res_err_free(res_err_t *err) {
12 | if (err) {
13 | if (err->code) {
14 | free(err->code);
15 | }
16 |
17 | if (err->msg) {
18 | free(err->msg);
19 | }
20 |
21 | free(err);
22 | }
23 | }
24 |
25 | res_err_t *deser_error(cJSON *j_obj) {
26 | if (j_obj == NULL) {
27 | printf("[%s:%d] invalid parameter\n", __func__, __LINE__);
28 | return NULL;
29 | }
30 |
31 | // check if it is an error response;
32 | cJSON *err_obj = cJSON_GetObjectItemCaseSensitive(j_obj, JSON_KEY_ERROR);
33 | if (err_obj == NULL) {
34 | // it is not exactly an error
35 | // printf("INFO [%s:%d]: error object not found in this response\n", __func__, __LINE__);
36 | return NULL;
37 | }
38 |
39 | cJSON *err_code = cJSON_GetObjectItemCaseSensitive(err_obj, JSON_KEY_CODE);
40 | if (!err_code) {
41 | printf("[%s:%d]: error code found\n", __func__, __LINE__);
42 | return NULL;
43 | }
44 | if (!cJSON_IsString(err_code) || (err_code->valuestring == NULL)) {
45 | printf("[%s:%d] error message is not a string\n", __func__, __LINE__);
46 | return NULL;
47 | }
48 |
49 | cJSON *err_msg = cJSON_GetObjectItemCaseSensitive(err_obj, JSON_KEY_MSG);
50 | if (err_msg == NULL) {
51 | printf("[%s:%d] error message not found\n", __func__, __LINE__);
52 | return NULL;
53 | }
54 | if (!cJSON_IsString(err_msg) || (err_msg->valuestring == NULL)) {
55 | printf("[%s:%d] error message is not a string\n", __func__, __LINE__);
56 | return NULL;
57 | }
58 |
59 | res_err_t *res_err = malloc(sizeof(res_err_t));
60 | if (res_err == NULL) {
61 | printf("[%s:%d] OOM\n", __func__, __LINE__);
62 | return NULL;
63 | }
64 |
65 | size_t len = strlen(err_msg->valuestring);
66 | res_err->msg = malloc(len + 1);
67 | if (res_err->msg == NULL) {
68 | res_err_free(res_err);
69 | printf("[%s:%d] OOM\n", __func__, __LINE__);
70 | return NULL;
71 | }
72 | strncpy(res_err->msg, err_msg->valuestring, len);
73 | res_err->msg[len] = '\0';
74 |
75 | len = strlen(err_code->valuestring);
76 | res_err->code = malloc(len + 1);
77 | if (res_err->code == NULL) {
78 | res_err_free(res_err);
79 | printf("[%s:%d] OOM\n", __func__, __LINE__);
80 | return NULL;
81 | }
82 | strncpy(res_err->code, err_code->valuestring, len);
83 | res_err->code[len] = '\0';
84 |
85 | return res_err;
86 | }
--------------------------------------------------------------------------------
/src/client/api/restful/response_error.h:
--------------------------------------------------------------------------------
1 | // Copyright 2021 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __CLIENT_API_RESTFUL_RES_ERR_H__
5 | #define __CLIENT_API_RESTFUL_RES_ERR_H__
6 |
7 | #include
8 |
9 | #include "cJSON.h"
10 |
11 | /**
12 | * @brief Node API error response
13 | *
14 | */
15 | typedef struct {
16 | char *code; ///< an error code from node response
17 | char *msg; ///< a error message from node response
18 | } res_err_t;
19 |
20 | #ifdef __cplusplus
21 | extern "C" {
22 | #endif
23 |
24 | /**
25 | * @brief Free an error response object
26 | *
27 | * @param err The error response
28 | */
29 | void res_err_free(res_err_t *err);
30 |
31 | /**
32 | * @brief The error object deserialization
33 | *
34 | * @param j_obj A string of the JSON object
35 | *
36 | * @return res_err_t*
37 | */
38 | res_err_t *deser_error(cJSON *j_obj);
39 |
40 | #ifdef __cplusplus
41 | }
42 | #endif
43 |
44 | #endif
45 |
--------------------------------------------------------------------------------
/src/client/api/restful/send_block.h:
--------------------------------------------------------------------------------
1 | // Copyright 2020 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __CLIENT_API_RESTFUL_SEND_BLOCK_H__
5 | #define __CLIENT_API_RESTFUL_SEND_BLOCK_H__
6 |
7 | #include
8 | #include
9 |
10 | #include "client/api/restful/response_error.h"
11 | #include "client/client_service.h"
12 | #include "client/constants.h"
13 | #include "core/models/block.h"
14 | #include "core/utils/macros.h"
15 |
16 | /**
17 | * @brief The response of send block
18 | *
19 | */
20 | typedef struct {
21 | bool is_error; ///< True if got an error from the node.
22 | union {
23 | res_err_t* error; ///< Error message if is_error is True
24 | char blk_id[BIN_TO_HEX_STR_BYTES(IOTA_BLOCK_ID_BYTES)]; ///< a block IDs string if is_error is False
25 | } u;
26 | } res_send_block_t;
27 |
28 | #ifdef __cplusplus
29 | extern "C" {
30 | #endif
31 |
32 | /**
33 | * @brief Deserialize the response of send_block
34 | *
35 | * @param[in] json_str The response string
36 | * @param[out] res The response object
37 | * @return int 0 on success
38 | */
39 | int deser_send_block_response(char const* json_str, res_send_block_t* res);
40 |
41 | /**
42 | * @brief Send block thought core block object
43 | *
44 | * @param[in] conf The client endpoint configuration
45 | * @param[in] blk A Block object
46 | * @param[out] res An error or block ID
47 | * @return int 0 on success
48 | */
49 | int send_core_block(iota_client_conf_t const* const conf, core_block_t* blk, res_send_block_t* res);
50 |
51 | #ifdef __cplusplus
52 | }
53 | #endif
54 |
55 | #endif
56 |
--------------------------------------------------------------------------------
/src/client/api/restful/send_tagged_data.h:
--------------------------------------------------------------------------------
1 | // Copyright 2022 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __CLIENT_API_RESTFUL_SEND_TAGGED_DATA_H__
5 | #define __CLIENT_API_RESTFUL_SEND_TAGGED_DATA_H__
6 |
7 | #include "client/api/restful/send_block.h"
8 | #include "core/utils/byte_buffer.h"
9 |
10 | #ifdef __cplusplus
11 | extern "C" {
12 | #endif
13 |
14 | /**
15 | * @brief Send tagged data block
16 | *
17 | * @param[in] conf The client endpoint configuration
18 | * @param[in] ver The protocol version
19 | * @param[in] tag The binary tag of the tagged data payload
20 | * @param[in] tag_len The length of the binary tag
21 | * @param[in] data The binary data of the tagged data payload
22 | * @param[in] data_len The length of the tagged data payload binary data
23 | * @param[out] res An error or block ID
24 | * @return int 0 on success
25 | */
26 | int send_tagged_data_block(iota_client_conf_t const* conf, uint8_t ver, byte_t tag[], uint8_t tag_len, byte_t data[],
27 | uint32_t data_len, res_send_block_t* res);
28 |
29 | #ifdef __cplusplus
30 | }
31 | #endif
32 |
33 | #endif
34 |
--------------------------------------------------------------------------------
/src/client/client_service.h:
--------------------------------------------------------------------------------
1 | // Copyright 2021 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __CLIENT_SERVICE_H__
5 | #define __CLIENT_SERVICE_H__
6 |
7 | #include
8 | #include
9 | #include
10 |
11 | #include "client/constants.h"
12 |
13 | /**
14 | * @brief Client endpoint configuration
15 | *
16 | */
17 | typedef struct {
18 | char host[IOTA_ENDPOINT_MAX_LEN]; ///< domain name or IP as string
19 | uint16_t port; ///< port to connect
20 | bool use_tls; ///< Use TLS or not
21 | } iota_client_conf_t;
22 |
23 | #ifdef __cplusplus
24 | extern "C" {
25 | #endif
26 |
27 | #ifdef __cplusplus
28 | }
29 | #endif
30 |
31 | #endif
32 |
--------------------------------------------------------------------------------
/src/client/constants.h:
--------------------------------------------------------------------------------
1 | // Copyright 2022 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __CLIENT_CONSTANTS_H__
5 | #define __CLIENT_CONSTANTS_H__
6 |
7 | #include "core/constants.h"
8 |
9 | // supported protoocl version of this client library
10 | #define SUPPORTED_PROTOCOL_VERSION 2
11 | // Core API route prefix of the node
12 | #define CORE_API_ROUTE "/api/core/v2"
13 | // Indexer API route prefix of the node
14 | #define INDEXER_API_ROUTE "/api/indexer/v1"
15 |
16 | #define IOTA_ENDPOINT_MAX_LEN 256
17 |
18 | #endif
19 |
--------------------------------------------------------------------------------
/src/client/network/http.h:
--------------------------------------------------------------------------------
1 | // Copyright 2021 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __CLIENT_NETWORK_HTTP_H__
5 | #define __CLIENT_NETWORK_HTTP_H__
6 |
7 | /**
8 | * @brief Abstract layer of http client for IOTA client
9 | *
10 | */
11 |
12 | #include
13 | #include
14 |
15 | #include "core/utils/byte_buffer.h"
16 |
17 | typedef struct {
18 | char const* url; ///< HTTP URL, it overrides fields below, if any
19 | char const* host; ///< Domain name or IP as string
20 | char const* path; ///< HTTP path
21 | char const* query; ///< HTTP query
22 | char const* cert_pem; ///< SSL certification in PEM format
23 | uint16_t port; ///< port to connect
24 | bool use_tls; ///< Use TLS or not
25 | } http_client_config_t;
26 |
27 | #ifdef __cplusplus
28 | extern "C" {
29 | #endif
30 |
31 | /**
32 | * @brief Inits http client instance
33 | *
34 | */
35 | void http_client_init();
36 |
37 | /**
38 | * @brief Clean up http client instance
39 | *
40 | */
41 | void http_client_clean();
42 |
43 | /**
44 | * @brief Performs http POST
45 | *
46 | * @param[in] url The server url
47 | * @param[in] request The request of body
48 | * @param[out] response The response data
49 | * @param[out] status HTTP status code
50 | * @return int 0 on success
51 | */
52 | int http_client_post(http_client_config_t const* const config, byte_buf_t const* const request,
53 | byte_buf_t* const response, long* status);
54 |
55 | /**
56 | * @brief Performs http GET
57 | *
58 | * @param[in] url The server url
59 | * @param[out] response The response data
60 | * @param[out] status HTTP status code
61 | * @return int 0 on success
62 | */
63 | int http_client_get(http_client_config_t const* const config, byte_buf_t* const response, long* status);
64 |
65 | #ifdef __cplusplus
66 | }
67 | #endif
68 |
69 | #endif
70 |
--------------------------------------------------------------------------------
/src/core/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | #[[
2 | // Copyright 2020 IOTA Stiftung
3 | // SPDX-License-Identifier: Apache-2.0
4 | ]]
5 |
6 | add_library(iota_core STATIC)
7 | # the required minimum C standard
8 | set_target_properties(iota_core PROPERTIES C_STANDARD_REQUIRED NO C_STANDARD 99)
9 |
10 | target_sources(
11 | iota_core
12 | PRIVATE "address.c"
13 | "utils/iota_str.c"
14 | "utils/byte_buffer.c"
15 | "utils/slip10.c"
16 | "utils/bech32.c"
17 | "utils/uint256.c"
18 | "utils/macros.h"
19 | "models/inputs/utxo_input.c"
20 | "models/outputs/byte_cost_config.c"
21 | "models/outputs/features.c"
22 | "models/outputs/output_alias.c"
23 | "models/outputs/output_basic.c"
24 | "models/outputs/output_foundry.c"
25 | "models/outputs/output_nft.c"
26 | "models/outputs/native_tokens.c"
27 | "models/outputs/outputs.c"
28 | "models/outputs/storage_deposit.c"
29 | "models/outputs/unlock_conditions.c"
30 | "models/payloads/transaction.c"
31 | "models/payloads/tagged_data.c"
32 | "models/payloads/milestone.c"
33 | "models/block.c"
34 | "models/signing.c"
35 | "models/unlocks.c"
36 | PUBLIC "address.h"
37 | "constants.h"
38 | "utils/iota_str.h"
39 | "utils/byte_buffer.h"
40 | "utils/slip10.h"
41 | "utils/bech32.h"
42 | "utils/uint256.h"
43 | "utils/macros.h"
44 | "models/inputs/utxo_input.h"
45 | "models/outputs/byte_cost_config.h"
46 | "models/outputs/features.h"
47 | "models/outputs/output_alias.h"
48 | "models/outputs/output_basic.h"
49 | "models/outputs/output_foundry.h"
50 | "models/outputs/output_nft.h"
51 | "models/outputs/native_tokens.h"
52 | "models/outputs/outputs.h"
53 | "models/outputs/storage_deposit.h"
54 | "models/outputs/unlock_conditions.h"
55 | "models/payloads/transaction.h"
56 | "models/payloads/tagged_data.h"
57 | "models/payloads/milestone.h"
58 | "models/block.h"
59 | "models/signing.h"
60 | "models/unlocks.h")
61 |
62 | target_include_directories(iota_core PUBLIC "${PROJECT_SOURCE_DIR}/src" "${CMAKE_INSTALL_PREFIX}/include")
63 |
64 | add_dependencies(iota_core iota_crypto ext_uthash)
65 |
66 | target_compile_options(iota_core PRIVATE -Wall -Wextra)
67 |
68 | target_link_libraries(iota_core PUBLIC iota_crypto)
69 |
70 | if(__JEMALLOC_INCLUDED)
71 | add_dependencies(iota_core jemalloc)
72 | target_link_libraries(iota_core PUBLIC jemalloc${CMAKE_STATIC_LIBRARY_SUFFIX} Threads::Threads)
73 | target_compile_definitions(iota_core PUBLIC USE_JEMALLOC)
74 | target_link_options(iota_core PUBLIC -Wl,--no-as-needed -ldl)
75 | endif()
76 |
77 | # install client lib and headers
78 | install(TARGETS iota_core DESTINATION "${CMAKE_INSTALL_PREFIX}/lib")
79 | install(
80 | DIRECTORY "${PROJECT_SOURCE_DIR}/src/core/"
81 | DESTINATION "${CMAKE_INSTALL_PREFIX}/include/core"
82 | FILES_MATCHING
83 | PATTERN "*.h")
84 |
--------------------------------------------------------------------------------
/src/core/constants.h:
--------------------------------------------------------------------------------
1 | // Copyright 2022 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __CORE_CONSTANTS_H__
5 | #define __CORE_CONSTANTS_H__
6 |
7 | #include
8 |
9 | #include "crypto/constants.h"
10 |
11 | /****** Constants related to Block******/
12 | // Block ID length in binary form
13 | #define IOTA_BLOCK_ID_BYTES 32
14 |
15 | /****** Constants related to transactions ******/
16 | // Transaction ID bytes
17 | #define IOTA_TRANSACTION_ID_BYTES 32
18 | // OUTPUT ID bytes = 34 (IOTA_TRANSACTION_ID + OUTPUT INDEX)
19 | #define IOTA_OUTPUT_ID_BYTES (IOTA_TRANSACTION_ID_BYTES + sizeof(uint16_t))
20 | // Have one transaction essence type only which is 1
21 | #define TRANSACTION_ESSENCE_TYPE 1
22 |
23 | /****** Constants related to addresses ******/
24 | // An Ed25519 address is the Blake2b-256 hash of an Ed25519 public key.
25 | #define ED25519_PUBKEY_BYTES ED_PUBLIC_KEY_BYTES
26 | // An Alias address is the Blake2b-256 hash of the OutputID which created it.
27 | #define ALIAS_ID_BYTES CRYPTO_BLAKE2B_256_HASH_BYTES
28 | // A NFT address is the Blake2b-256 hash of the OutputID which created it.
29 | #define NFT_ID_BYTES CRYPTO_BLAKE2B_256_HASH_BYTES
30 | // The genral hash lengh of address which is equal to ED25519_PUBKEY_BYTES, ALIAS_ID_BYTES, and NFT_ID_BYTES
31 | #define ADDRESS_HASH_BYTES 32
32 | // The number of bytes a serialized address can hold.
33 | #define ADDRESS_SERIALIZED_BYTES (1 + ADDRESS_HASH_BYTES)
34 |
35 | /****** Constants related to unlocks ******/
36 | // ed25519 signature object = signature type + public key + signature
37 | #define ED25519_SIGNATURE_BLOCK_BYTES (1 + ED_PUBLIC_KEY_BYTES + ED_SIGNATURE_BYTES) // 97 bytes
38 | // unlock_type_t + reference = 1 + 2
39 | #define UNLOCK_REFERENCE_SERIALIZE_BYTES (1 + sizeof(uint16_t))
40 | // unlock_type_t + signature type + pub_key + signature
41 | #define UNLOCK_SIGNATURE_SERIALIZE_BYTES (1 + ED25519_SIGNATURE_BLOCK_BYTES)
42 | // unlock_type_t + alias index = 1 + 2
43 | #define UNLOCK_ALIAS_SERIALIZE_BYTES (1 + sizeof(uint16_t))
44 | // unlock_type_t + NFT index = 1 + 2
45 | #define UNLOCK_NFT_SERIALIZE_BYTES (1 + sizeof(uint16_t))
46 |
47 | /****** Constants related to tagged data ******/
48 | // Maximum length of tag in bytes
49 | #define TAGGED_DATA_TAG_MAX_LENGTH_BYTES 64
50 |
51 | /****** Constants related to features ******/
52 | // Maximum possible length in bytes of a Tag
53 | #define MAX_INDEX_TAG_BYTES 64
54 | // Maximun possible length in bytes of Metadata
55 | #define MAX_METADATA_LENGTH_BYTES 8192
56 | // Maximun Features in a list
57 | #define MAX_FEATURE_BLOCK_COUNT 4
58 |
59 | /****** Constants related to native tokens ******/
60 | // Maximum number of Native Tokens in an output
61 | #define NATIVE_TOKENS_MAX_COUNT 64
62 | // Native Token ID length in bytes
63 | #define NATIVE_TOKEN_ID_BYTES 38
64 | // Serialized bytes = token ID(38 bytes) + amount(uint256_t)
65 | #define NATIVE_TOKENS_SERIALIZED_BYTES (NATIVE_TOKEN_ID_BYTES + 32)
66 |
67 | /****** Constants related to foundry output ******/
68 | // The concatenation of Address || Serial Number || Token Scheme Type
69 | #define FOUNDRY_ID_BYTES 38
70 |
71 | /****** Constants related to UTXO output ******/
72 | // Maximum number of outputs in a transaction payload.
73 | #define UTXO_OUTPUT_MAX_COUNT 128
74 | // Maximum IOTA token supply
75 | static const uint64_t MAX_IOTA_SUPPLY = 2779530283277761;
76 |
77 | /****** Constants related to unlock conditions ******/
78 | // Maximun Unlock Conditions in a list
79 | #define MAX_UNLOCK_CONDITION_BLOCK_COUNT 4
80 |
81 | /****** Constants related to UTXO inputs ******/
82 | // Maximum number of inputs in a transaction payload.
83 | #define UTXO_INPUT_MAX_COUNT 128
84 |
85 | #endif
86 |
--------------------------------------------------------------------------------
/src/core/models/outputs/byte_cost_config.c:
--------------------------------------------------------------------------------
1 | // Copyright 2022 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #include
5 |
6 | #include "core/models/inputs/utxo_input.h"
7 | #include "core/models/outputs/byte_cost_config.h"
8 |
9 | // Defines the rent of a single virtual byte denoted in IOTA tokens
10 | #define DEFAULT_BYTE_COST 500
11 | // Defines the multiplier for data fields
12 | #define DEFAULT_BYTE_COST_FACTOR_DATA 1
13 | // Defines the multiplier for fields which can act as keys for lookups
14 | #define DEFAULT_BYTE_COST_FACTOR_KEY 10
15 |
16 | byte_cost_config_t *byte_cost_config_new(uint16_t byte_cost, uint8_t byte_factor_data, uint8_t byte_factor_key) {
17 | byte_cost_config_t *config = malloc(sizeof(byte_cost_config_t));
18 | if (!config) {
19 | printf("[%s:%d] can not create storage config\n", __func__, __LINE__);
20 | return NULL;
21 | }
22 |
23 | config->v_byte_cost = byte_cost;
24 | config->v_byte_factor_data = byte_factor_data;
25 | config->v_byte_factor_key = byte_factor_key;
26 |
27 | // size of: output ID + Block ID + confirmation milestone index + confirmation unix timestamp
28 | config->v_byte_offset = (IOTA_OUTPUT_ID_BYTES * byte_factor_key) + // output ID
29 | (IOTA_BLOCK_ID_BYTES * byte_factor_data) + // Block ID
30 | (sizeof(uint32_t) * byte_factor_data) + // confirmation milestone index
31 | (sizeof(uint32_t) * byte_factor_data); // confirmation unix timestamp
32 |
33 | return config;
34 | }
35 |
36 | byte_cost_config_t *byte_cost_config_default_new() {
37 | return byte_cost_config_new(DEFAULT_BYTE_COST, DEFAULT_BYTE_COST_FACTOR_DATA, DEFAULT_BYTE_COST_FACTOR_KEY);
38 | }
39 |
40 | void byte_cost_config_free(byte_cost_config_t *config) {
41 | if (config) {
42 | free(config);
43 | }
44 | }
45 |
46 | void byte_cost_config_set(byte_cost_config_t *config, uint16_t byte_cost, uint8_t byte_factor_data,
47 | uint8_t byte_factor_key) {
48 | if (config) {
49 | config->v_byte_cost = byte_cost;
50 | config->v_byte_factor_data = byte_factor_data;
51 | config->v_byte_factor_key = byte_factor_key;
52 |
53 | // size of: output ID + Block ID + confirmation milestone index + confirmation unix timestamp
54 | config->v_byte_offset = (IOTA_OUTPUT_ID_BYTES * byte_factor_key) + // output ID
55 | (IOTA_BLOCK_ID_BYTES * byte_factor_data) + // Block ID
56 | (sizeof(uint32_t) * byte_factor_data) + // confirmation milestone index
57 | (sizeof(uint32_t) * byte_factor_data); // confirmation unix timestamp
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/core/models/outputs/byte_cost_config.h:
--------------------------------------------------------------------------------
1 | // Copyright 2022 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __CORE_MODELS_OUTPUTS_BYTE_COST_CONFIG_H__
5 | #define __CORE_MODELS_OUTPUTS_BYTE_COST_CONFIG_H__
6 |
7 | #include
8 |
9 | /**
10 | * @brief Specifies the current parameters for the byte cost computation
11 | *
12 | */
13 | typedef struct {
14 | uint16_t v_byte_cost; ///< Defines the rent of a single virtual byte denoted in IOTA tokens
15 | uint8_t v_byte_factor_data; ///< Defines the multiplier for data fields
16 | uint8_t v_byte_factor_key; ///< Defines the multiplier for fields which can act as keys for lookups
17 | uint16_t v_byte_offset; ///< Additional virtual bytes that are caused by additional data that has to be stored in the
18 | ///< database but is not part of the output itself
19 | } byte_cost_config_t;
20 |
21 | #ifdef __cplusplus
22 | extern "C" {
23 | #endif
24 |
25 | /**
26 | * @brief Create new byte cost configuration
27 | *
28 | * @param[in] byte_cost Rent of a single virtual byte denoted in IOTA tokens
29 | * @param[in] byte_factor_data Multiplier for data fields
30 | * @param[in] byte_factor_key Multiplier for key fields
31 | * @return *byte_cost_config_t
32 | */
33 | byte_cost_config_t *byte_cost_config_new(uint16_t byte_cost, uint8_t byte_factor_data, uint8_t byte_factor_key);
34 |
35 | /**
36 | * @brief Create new default byte cost configuration
37 | *
38 | * @return *byte_cost_config_t
39 | */
40 | byte_cost_config_t *byte_cost_config_default_new();
41 |
42 | /**
43 | * @brief Free byte cost configuration
44 | *
45 | * @param[in] config A byte cost configuration
46 | */
47 | void byte_cost_config_free(byte_cost_config_t *config);
48 |
49 | /**
50 | * @brief Set byte cost configuration
51 | *
52 | * @param[in, out] config A pointer to byte cost config object
53 | * @param[in] byte_cost Rent of a single virtual byte denoted in IOTA tokens
54 | * @param[in] byte_factor_data Multiplier for data fields
55 | * @param[in] byte_factor_key Multiplier for key fields
56 | */
57 | void byte_cost_config_set(byte_cost_config_t *config, uint16_t byte_cost, uint8_t byte_factor_data,
58 | uint8_t byte_factor_key);
59 |
60 | #ifdef __cplusplus
61 | }
62 | #endif
63 |
64 | #endif // __CORE_MODELS_OUTPUTS_BYTE_COST_CONFIG_H__
65 |
--------------------------------------------------------------------------------
/src/core/models/outputs/output_basic.h:
--------------------------------------------------------------------------------
1 | // Copyright 2021 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __CORE_MODELS_OUTPUT_BASIC_H__
5 | #define __CORE_MODELS_OUTPUT_BASIC_H__
6 |
7 | #include
8 |
9 | #include "core/address.h"
10 | #include "core/models/outputs/features.h"
11 | #include "core/models/outputs/native_tokens.h"
12 | #include "core/models/outputs/unlock_conditions.h"
13 |
14 | /**
15 | * @brief An output type which can hold native tokens and features
16 | *
17 | */
18 | typedef struct {
19 | uint64_t amount; ///< The amount of IOTA tokens to held by the output
20 | native_tokens_list_t* native_tokens; ///< The native tokens held by the output
21 | unlock_cond_list_t* unlock_conditions; ///< Define how the output can be unlocked and spent
22 | feature_list_t* features; ///< The features which modulate the constraints on the output
23 | } output_basic_t;
24 |
25 | #ifdef __cplusplus
26 | extern "C" {
27 | #endif
28 |
29 | /**
30 | * @brief Create new Basic Output object
31 | *
32 | * @param[in] amount The amount of IOTA tokens to held by the output
33 | * @param[in] tokens List of native tokens held by the output
34 | * @param[in] cond_list Set of unlock conditions
35 | * @param[in] features List of features
36 | *
37 | * @return output_basic_t* or NULL on failure
38 | */
39 | output_basic_t* output_basic_new(uint64_t amount, native_tokens_list_t* tokens, unlock_cond_list_t* cond_list,
40 | feature_list_t* features);
41 |
42 | /**
43 | * @brief Free Basic Output object
44 | *
45 | * @param[in] output Basic Output object
46 | */
47 | void output_basic_free(output_basic_t* output);
48 |
49 | /**
50 | * @brief Get the length of a serialized Basic Output
51 | *
52 | * @param[in] output Basic Output object
53 | * @return size_t The number of bytes of serialized data
54 | */
55 | size_t output_basic_serialize_len(output_basic_t* output);
56 |
57 | /**
58 | * @brief Serialize Basic Output to a binary data
59 | *
60 | * @param[in] output Basic Output object
61 | * @param[out] buf A buffer holds the serialized data
62 | * @param[in] buf_len The length of buffer
63 | * @return size_t The bytes written is returned, 0 on errors
64 | */
65 | size_t output_basic_serialize(output_basic_t* output, byte_t buf[], size_t buf_len);
66 |
67 | /**
68 | * @brief Deserialize a binary data to a Basic Output object
69 | *
70 | * @param[in] buf The basic output data in binary
71 | * @param[in] buf_len The length of the data
72 | * @return output_basic_t* or NULL on failure
73 | */
74 | output_basic_t* output_basic_deserialize(byte_t buf[], size_t buf_len);
75 |
76 | /**
77 | * @brief Clone Basic Output object, it should be freed after use.
78 | *
79 | * @param[in] output Basic Output object for clone
80 | * @return output_basic_t* New Basic Output object
81 | */
82 | output_basic_t* output_basic_clone(output_basic_t const* const output);
83 |
84 | /**
85 | * @brief Print Basic Output
86 | *
87 | * @param[in] output Basic Output object
88 | * @param[in] indentation Tab indentation when printing Basic Output
89 | */
90 | void output_basic_print(output_basic_t* output, uint8_t indentation);
91 |
92 | /**
93 | * @brief Basic Output syntactic validation
94 | *
95 | * @param[in] output A Basic output
96 | * @return true Valid
97 | * @return false Invalid
98 | */
99 | bool output_basic_syntactic(output_basic_t* output);
100 |
101 | #ifdef __cplusplus
102 | }
103 | #endif
104 |
105 | #endif
106 |
--------------------------------------------------------------------------------
/src/core/models/outputs/storage_deposit.h:
--------------------------------------------------------------------------------
1 | // Copyright 2022 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __CORE_MODELS_OUTPUT_STORAGE_DEPOSIT_H__
5 | #define __CORE_MODELS_OUTPUT_STORAGE_DEPOSIT_H__
6 |
7 | #include "core/models/outputs/byte_cost_config.h"
8 | #include "core/models/outputs/outputs.h"
9 |
10 | #ifdef __cplusplus
11 | extern "C" {
12 | #endif
13 |
14 | /**
15 | * @brief Calculate minimum storage deposit for the given output
16 | *
17 | * @param[in] config A byte cost configuration
18 | * @param[in] output_type UTXO output type
19 | * @param[in] output Pointer to an output
20 | * @return true if output has enough storage deposit amount
21 | */
22 | uint64_t calc_minimum_output_deposit(byte_cost_config_t *config, utxo_output_type_t output_type, void *output);
23 |
24 | /**
25 | * @brief Check if a sufficient storage deposit was made for the given output
26 | *
27 | * @param[in] config A byte cost configuration
28 | * @param[in] output_type UTXO output type
29 | * @param[in] output Pointer to an output
30 | * @return true if output has enough storage deposit amount
31 | */
32 | bool storage_deposit_check(byte_cost_config_t *config, utxo_output_type_t output_type, void *output);
33 |
34 | #ifdef __cplusplus
35 | }
36 | #endif
37 |
38 | #endif // __CORE_MODELS_OUTPUT_STORAGE_DEPOSIT_H__
39 |
--------------------------------------------------------------------------------
/src/core/models/payloads/tagged_data.h:
--------------------------------------------------------------------------------
1 | // Copyright 2022 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __CORE_MODELS_PL_TAGGED_DATA_H__
5 | #define __CORE_MODELS_PL_TAGGED_DATA_H__
6 |
7 | #include
8 |
9 | #include "core/utils/byte_buffer.h"
10 |
11 | /**
12 | * @brief Tagged data structure
13 | *
14 | * The payload type of tagged data is 5
15 | */
16 | typedef struct {
17 | byte_buf_t *tag; ///< The tag of the data
18 | byte_buf_t *data; ///< Binary data
19 | } tagged_data_payload_t;
20 |
21 | #ifdef __cplusplus
22 | extern "C" {
23 | #endif
24 |
25 | /**
26 | * @brief Create a tagged data object with tag and binary data
27 | *
28 | * @param[in] tag The binary tag in tagged data payload
29 | * @param[in] tag_len The length of the binary tag
30 | * @param[in] data The binary data in tagged data payload
31 | * @param[in] data_len The length of the binary data
32 | * @return tagged_data_payload_t* A pointer to tagged data object
33 | */
34 | tagged_data_payload_t *tagged_data_new(byte_t tag[], uint8_t tag_len, byte_t data[], uint32_t data_len);
35 |
36 | /**
37 | * @brief Free a tagged data object
38 | *
39 | * @param[in] tagged_data A tagged data object
40 | */
41 | void tagged_data_free(tagged_data_payload_t *tagged_data);
42 |
43 | /**
44 | * @brief Get a serialized length of a tagged data
45 | *
46 | * @param[in] tagged_data A tagged data object
47 | * @return size_t The number of bytes of serialized data
48 | */
49 | size_t tagged_data_serialize_len(tagged_data_payload_t *tagged_data);
50 |
51 | /**
52 | * @brief Serialize a tagged data to a binary data
53 | *
54 | * @param[in] tagged_data A tagged data object
55 | * @param[out] buf A buffer holds the serialized data
56 | * @param[in] buf_len The length of buffer
57 | * @return size_t The bytes written is returned, 0 on errors
58 | */
59 | size_t tagged_data_serialize(tagged_data_payload_t *tagged_data, byte_t buf[], size_t buf_len);
60 |
61 | /**
62 | * @brief Deserialize a binary data to a tagged data object
63 | *
64 | * @param[in] buf The block data in binary
65 | * @param[in] buf_len The length of the data
66 | * @return tagged_data_payload_t* or NULL on failure
67 | */
68 | tagged_data_payload_t *tagged_data_deserialize(byte_t buf[], size_t buf_len);
69 |
70 | /**
71 | * @brief Clone tagged data object, it should be freed after use.
72 | *
73 | * @param[in] tagged_data tagged data object for clone
74 | * @return tagged_data_payload_t* New tagged data object
75 | */
76 | tagged_data_payload_t *tagged_data_clone(tagged_data_payload_t const *const tagged_data);
77 |
78 | /**
79 | * @brief Print a tagged data object
80 | *
81 | * @param[in] tagged_data A tagged data object
82 | * @param[in] indentation Tab indentation when printing a tagged data
83 | */
84 | void tagged_data_print(tagged_data_payload_t *tagged_data, uint8_t indentation);
85 |
86 | #ifdef __cplusplus
87 | }
88 | #endif
89 |
90 | #endif
91 |
--------------------------------------------------------------------------------
/src/core/models/signing.h:
--------------------------------------------------------------------------------
1 | // Copyright 2022 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __CORE_MODELS_SIGNING_H__
5 | #define __CORE_MODELS_SIGNING_H__
6 |
7 | #include
8 |
9 | #include "core/address.h"
10 | #include "core/models/inputs/utxo_input.h"
11 | #include "core/models/unlocks.h"
12 |
13 | /**
14 | * @brief A signing data structure. This data is needed when unlocks are creating and transaction gets signed.
15 | *
16 | */
17 | typedef struct {
18 | address_t unlock_address; ///< Address in Unlock Condition (Address, Governor, State Controller) - ED25519/NFT/Alias
19 | byte_t hash[CRYPTO_BLAKE2B_256_HASH_BYTES]; ///< Optional, a NFT/Alias ID in the utxo_output
20 | ed25519_keypair_t* keypair; ///< Optional, ed25519 keypair (this is for ed25519 address)
21 | } signing_data_t;
22 |
23 | /**
24 | * @brief A list of signing data.
25 | *
26 | * This list needs to have the same order of signing data for unspent outputs as in utxo_inputs_list_t.
27 | *
28 | */
29 | typedef struct signing_data_list {
30 | signing_data_t* sign_data; //< Points to a current signing data
31 | struct signing_data_list* next; //< Points to a next signing data list
32 | } signing_data_list_t;
33 |
34 | #ifdef __cplusplus
35 | extern "C" {
36 | #endif
37 |
38 | /**
39 | * @brief Initialize a signing data list
40 | *
41 | * @return a NULL pointer
42 | */
43 | signing_data_list_t* signing_new();
44 |
45 | /**
46 | * @brief Free a signing data list
47 | *
48 | * @param[in] signing_data_list Signing data list
49 | */
50 | void signing_free(signing_data_list_t* signing_data_list);
51 |
52 | /**
53 | * @brief Add a signing data into the list
54 | *
55 | * @param[in] unlock_address Address Unlock Condition Address - ED25519/NFT/Alias
56 | * @param[in] hash Optional, a NFT/Alias ID in the utxo_output
57 | * @param[in] hash_len A length of hash array, 0 if hash is NULL
58 | * @param[in] keypair Optional, ed25519 keypair of this input (this is for ed25519 address)
59 | * @param[out] sign_data_list Signing data list which will be populated by a new element
60 | * @return int 0 on success
61 | */
62 | int signing_data_add(address_t* unlock_address, byte_t hash[], uint8_t hash_len, ed25519_keypair_t* keypair,
63 | signing_data_list_t** sign_data_list);
64 |
65 | /**
66 | * @brief Get number of elements in a signing data list
67 | *
68 | * @param[in] signing_data_list Signing data list
69 | * @return uint8_t Number of elements
70 | */
71 | uint8_t signing_data_count(signing_data_list_t* signing_data_list);
72 |
73 | /**
74 | * @brief Find a signing data by a given index
75 | *
76 | * @param[in] signing_data_list Signing data list
77 | * @param[in] index An index in the list
78 | * @return signing_data_t* or NULL pointer
79 | */
80 | signing_data_t* signing_get_data_by_index(signing_data_list_t* signing_data_list, uint8_t index);
81 |
82 | /**
83 | * @brief Create unlocks and sign transaction
84 | *
85 | * @param[in] essence_hash An essence hash
86 | * @param[in] essence_hash_len Length of an essence hash array
87 | * @param[in] inputs An UTXO input list
88 | * @param[in] sign_data_list Signing data list
89 | * @param[out] unlock_list A list of unlocks which will be created
90 | * @return int 0 on success
91 | */
92 | int signing_transaction_sign(byte_t essence_hash[], uint8_t essence_hash_len, utxo_inputs_list_t* inputs,
93 | signing_data_list_t* sign_data_list, unlock_list_t** unlock_list);
94 |
95 | #ifdef __cplusplus
96 | }
97 | #endif
98 |
99 | #endif // __CORE_MODELS_SIGNING_H__
100 |
--------------------------------------------------------------------------------
/src/core/utils/allocator.h:
--------------------------------------------------------------------------------
1 | // Copyright 2021 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __CORE_UTILS_ALLOCATOR_H__
5 | #define __CORE_UTILS_ALLOCATOR_H__
6 |
7 | /**
8 | * @brief Memory Allocator abstract layer
9 | *
10 | */
11 |
12 | #ifdef USE_JEMALLOC
13 | #warning "Use jemalloc allocator"
14 | #include "jemalloc/jemalloc.h"
15 | #else
16 | #include
17 | #endif
18 |
19 | #ifdef __cplusplus
20 | extern "C" {
21 | #endif
22 |
23 | #ifdef __cplusplus
24 | }
25 | #endif
26 |
27 | #endif
28 |
--------------------------------------------------------------------------------
/src/core/utils/bech32.h:
--------------------------------------------------------------------------------
1 | // Copyright 2020 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __CORE_UTILS_BECH32_H__
5 | #define __CORE_UTILS_BECH32_H__
6 |
7 | #include
8 | #include
9 | #include
10 |
11 | // A Bech32[2] string is at most 90 characters long and consists of: [HRP, "1", data]
12 | #define BECH32_MAX_STRING_LEN 90
13 |
14 | #ifdef __cplusplus
15 | extern "C" {
16 | #endif
17 |
18 | /**
19 | * @brief bech32 encode
20 | *
21 | * @param[out] output The output bech32 string
22 | * @param[in] hrp A human-readable string
23 | * @param[in] data The encode data in bytes
24 | * @param[in] data_len The length of data
25 | * @return int 1 on success
26 | */
27 | int bech32_encode(char *output, const char *hrp, const uint8_t *data, size_t data_len);
28 |
29 | /**
30 | * @brief bech32 decode
31 | *
32 | * @param[out] hrp The human-readable part
33 | * @param[out] data The data in bytes
34 | * @param[out] data_len The length of data
35 | * @param[in] input A bech32 string
36 | * @return int 1 on success
37 | */
38 | int bech32_decode(char *hrp, uint8_t *data, size_t *data_len, const char *input);
39 |
40 | /**
41 | * @brief Convert raw binary to X bit per byte encoded byte string.
42 | *
43 | * @param[out] out A outout buffer hold the encoded string
44 | * @param[in] outlen The length of output buffer
45 | * @param[in] outbits The output bits per byte
46 | * @param[in] in The input data buffer
47 | * @param[in] inlen The length of input buffer
48 | * @param[in] inbits The input bits per byte
49 | * @param[in] pad set 1 to add padding
50 | * @return int 1 on success
51 | */
52 | int bech32_convert_bits(uint8_t *out, size_t *outlen, int outbits, const uint8_t *in, size_t inlen, int inbits,
53 | int pad);
54 |
55 | /**
56 | * @brief Validates Bech32 address length
57 | *
58 | * https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki
59 | * the length of Bech32 should be (HRP length) < x <= 90, where the HRP length is 1 to 83 ASCII characters
60 | *
61 | * @param[in] addr A string of Bech32 address
62 | * @return true Valid Bech32 address
63 | * @return false Invalid Bech32 address
64 | */
65 | bool is_valid_bech32_len(char const *const addr);
66 |
67 | #ifdef __cplusplus
68 | }
69 | #endif
70 |
71 | #endif
72 |
--------------------------------------------------------------------------------
/src/core/utils/iota_str.c:
--------------------------------------------------------------------------------
1 | // Copyright 2021 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #include "core/utils/iota_str.h"
5 | #include "core/utils/allocator.h"
6 |
7 | iota_str_t *iota_str_new(char const s[]) {
8 | iota_str_t *istr = malloc(sizeof(iota_str_t));
9 | if (!istr) {
10 | return NULL;
11 | }
12 |
13 | istr->len = strlen(s);
14 | istr->cap = istr->len + 1;
15 | istr->buf = malloc(istr->cap);
16 | if (!istr->buf) {
17 | free(istr);
18 | return NULL;
19 | }
20 |
21 | memcpy(istr->buf, s, istr->len);
22 | istr->buf[istr->len] = '\0';
23 | return istr;
24 | }
25 |
26 | void iota_str_destroy(iota_str_t *istr) {
27 | if (istr) {
28 | if (istr->buf) {
29 | free(istr->buf);
30 | }
31 | free(istr);
32 | }
33 | }
34 |
35 | int iota_str_appendn(iota_str_t *istr, char const s[], size_t len) {
36 | // needed capacity
37 | size_t needed_cap = istr->len + len + 1;
38 |
39 | if (needed_cap > istr->cap) {
40 | // request more buffer
41 | istr->buf = realloc(istr->buf, needed_cap);
42 | if (istr->buf == NULL) {
43 | return -1;
44 | }
45 | istr->cap = needed_cap;
46 | }
47 |
48 | // copy c_string to buffer
49 | memcpy(istr->buf + istr->len, s, len);
50 | istr->len += len;
51 | // append terminator
52 | istr->buf[istr->len] = '\0';
53 | return 0;
54 | }
55 |
56 | iota_str_t *iota_str_clonen(iota_str_t *istr, size_t len) {
57 | iota_str_t *clone = malloc(sizeof(iota_str_t));
58 | if (!clone) {
59 | return NULL;
60 | }
61 |
62 | clone->len = len;
63 | clone->cap = len + 1;
64 | clone->buf = malloc(istr->cap);
65 | if (!clone->buf) {
66 | free(clone);
67 | return NULL;
68 | }
69 |
70 | memcpy(clone->buf, istr->buf, len);
71 | clone->buf[clone->len] = '\0';
72 | return clone;
73 | }
74 |
75 | iota_str_t *iota_str_reserve(size_t len) {
76 | iota_str_t *istr = malloc(sizeof(iota_str_t));
77 | if (!istr) {
78 | return NULL;
79 | }
80 |
81 | istr->len = 0;
82 | istr->cap = len;
83 | istr->buf = malloc(istr->cap);
84 | if (!istr->buf) {
85 | free(istr);
86 | return NULL;
87 | }
88 |
89 | return istr;
90 | }
--------------------------------------------------------------------------------
/src/core/utils/iota_str.h:
--------------------------------------------------------------------------------
1 | // Copyright 2021 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __CORE_UTILS_IOTA_STR_H__
5 | #define __CORE_UTILS_IOTA_STR_H__
6 |
7 | #include
8 | #include
9 | #include
10 |
11 | /**
12 | * @brief A mutable string buffer.
13 | *
14 | */
15 | typedef struct {
16 | char *buf; /**< string pointer */
17 | size_t cap; /**< allocated capacity */
18 | size_t len; /**< string length */
19 | } iota_str_t;
20 |
21 | #ifdef __cplusplus
22 | extern "C" {
23 | #endif
24 |
25 | /**
26 | * @brief New a string object from c_string.
27 | *
28 | * @param[in] s A c_string
29 | * @return iota_str_t* The pointer to string object, NULL on failed.
30 | */
31 | iota_str_t *iota_str_new(char const *s);
32 |
33 | /**
34 | * @brief Appends a sized c_string
35 | *
36 | * @param[out] istr A pointer to a string object
37 | * @param[in] s A c_string
38 | * @param[in] len the size of characters
39 | * @return int 0 on success
40 | */
41 | int iota_str_appendn(iota_str_t *istr, char const s[], size_t len);
42 |
43 | /**
44 | * @brief Appends a c_string
45 | *
46 | * @param[out] istr A pointer to a string object
47 | * @param[in] s A c_string
48 | * @return int 0 on success
49 | */
50 | static inline int iota_str_append(iota_str_t *istr, char const s[]) { return iota_str_appendn(istr, s, strlen(s)); }
51 |
52 | /**
53 | * @brief Appends a char
54 | *
55 | * @param[out] istr A pointer to a string object
56 | * @param[in] c A character
57 | * @return int 0 on success
58 | */
59 | static inline int iota_str_append_char(iota_str_t *istr, char c) { return iota_str_appendn(istr, &c, 1); }
60 |
61 | /**
62 | * @brief Deallocates the string object
63 | *
64 | * @param[in] istr the string object
65 | */
66 | void iota_str_destroy(iota_str_t *istr);
67 |
68 | /**
69 | * @brief Clones a string with a length
70 | *
71 | * @param[in] istr A pointer to a string object
72 | * @param[in] len the length for clone
73 | * @return iota_str_t* A cloned string object
74 | */
75 | iota_str_t *iota_str_clonen(iota_str_t *istr, size_t len);
76 |
77 | /**
78 | * @brief Clones a string object
79 | *
80 | * @param[in] istr A pointer to a string object
81 | * @return iota_str_t* A cloned string object
82 | */
83 | static inline iota_str_t *iota_str_clone(iota_str_t *istr) { return iota_str_clonen(istr, istr->len); }
84 |
85 | /**
86 | * @brief Compare two strings
87 | *
88 | * Comparing NULL string or string without null terminator are undefined behaviours.
89 | *
90 | * @param[in] a string A
91 | * @param[in] b string B
92 | * @return int
93 | */
94 | static inline int iota_str_cmp(iota_str_t const *a, iota_str_t const *b) { return strcmp(a->buf, b->buf); };
95 |
96 | /**
97 | * @brief New a string object and reserves a specific length
98 | *
99 | * @param[in] len the length to reserve
100 | * @return iota_str_t*
101 | */
102 | iota_str_t *iota_str_reserve(size_t len);
103 |
104 | #ifdef __cplusplus
105 | }
106 | #endif
107 |
108 | #endif
109 |
--------------------------------------------------------------------------------
/src/core/utils/macros.h:
--------------------------------------------------------------------------------
1 | // Copyright 2022 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __CORE_UTILS_MACROS_H__
5 | #define __CORE_UTILS_MACROS_H__
6 |
7 | #include
8 | #include
9 |
10 | // Macro for unused function arguments
11 | #ifndef UNUSED
12 | #define UNUSED(x) (void)(x)
13 | #endif
14 |
15 | // Get the hex bytes of the given binary
16 | #define BIN_TO_HEX_BYTES(x) (x * 2)
17 | // Get the hex string bytes of the given binary
18 | #define BIN_TO_HEX_STR_BYTES(x) (BIN_TO_HEX_BYTES(x) + 1)
19 | // Get the string bytes of the given binary
20 | #define BIN_TO_STR_BYTES(x) (x + 1)
21 |
22 | /* clang-format off */
23 | /**
24 | * @brief Returns string representing tabulator indentation
25 | *
26 | * @param[in] i Indentation level. The range of i is between 0 and 5.
27 | */
28 | #define PRINT_INDENTATION(i) \
29 | ((i) == 0 ? "\0" \
30 | : (i) == 1 ? "\t\0" \
31 | : (i) == 2 ? "\t\t\0" \
32 | : (i) == 3 ? "\t\t\t\0" \
33 | : (i) == 4 ? "\t\t\t\t\0" \
34 | : (i) == 5 ? "\t\t\t\t\t\0" \
35 | : "\0")
36 | /* clang-format on */
37 |
38 | #endif
39 |
--------------------------------------------------------------------------------
/src/core/utils/slip10.h:
--------------------------------------------------------------------------------
1 | // Copyright 2020 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __CORE_UTILS_SLIP10_H__
5 | #define __CORE_UTILS_SLIP10_H__
6 |
7 | #include
8 |
9 | #include "core/utils/byte_buffer.h"
10 |
11 | #define BIP32_HARDENED (1UL << 31)
12 | #define MAX_BIP32_PATH 32
13 | #define SLIP10_PUBLIC_KEY_BYTES 33
14 | #define SLIP10_PRIVATE_KEY_BYTES 32
15 | #define SLIP10_CHAIN_CODE_BYTES 32
16 |
17 | typedef enum { SECP256K1_CURVE, NIST_P256_CURVE, ED25519_CURVE } slip10_curve_t;
18 |
19 | /**
20 | * @brief Slip10 key structure
21 | *
22 | */
23 | typedef struct {
24 | byte_t key[SLIP10_PRIVATE_KEY_BYTES]; ///< private key, 32 bytes
25 | byte_t chain_code[SLIP10_CHAIN_CODE_BYTES]; ///< chain code, 32 bytes
26 | } slip10_key_t;
27 |
28 | /**
29 | * @brief BIP32 path structure
30 | *
31 | */
32 | typedef struct {
33 | uint32_t path[MAX_BIP32_PATH]; ///< the string of path, 32 bytes
34 | int len; ///< the length of the path
35 | } bip32_path_t;
36 |
37 | #ifdef __cplusplus
38 | extern "C" {
39 | #endif
40 |
41 | /**
42 | * @brief Gets bip32 path from string
43 | *
44 | * @param[in] str A bip32 path string
45 | * @param[out] path The output path
46 | * @return int 0 on successful
47 | */
48 | int slip10_parse_path(char str[], bip32_path_t* path);
49 |
50 | /**
51 | * @brief Derives key from given seed and path
52 | *
53 | * @param[in] seed A seed in byte array
54 | * @param[in] seed_len The length of seed
55 | * @param[in] path The string of path
56 | * @param[in] curve The type of curve, only support ed25519
57 | * @param[out] key The derived key
58 | * @return int 0 on successful
59 | */
60 | int slip10_key_from_path(byte_t seed[], size_t seed_len, char path[], slip10_curve_t curve, slip10_key_t* key);
61 |
62 | /**
63 | * @brief Get public key from the derived key
64 | *
65 | * @param[in] curve The type of curve, only support ed25519
66 | * @param[in] key A slip-10 key
67 | * @param[out] pub_key The public key
68 | * @return int 0 on successful
69 | */
70 | int slip10_public_key(slip10_curve_t curve, slip10_key_t* key, byte_t pub_key[]);
71 |
72 | #ifdef __cplusplus
73 | }
74 | #endif
75 |
76 | #endif
77 |
--------------------------------------------------------------------------------
/src/core/utils/uint256.h:
--------------------------------------------------------------------------------
1 | // Copyright 2021 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __CORE_UTILS_UINT256_H__
5 | #define __CORE_UTILS_UINT256_H__
6 |
7 | #include
8 | #include
9 |
10 | // Maximum possible length of a string representing 256-bit number. 78 characters + string termination character
11 | #define STRING_NUMBER_MAX_CHARACTERS 79
12 |
13 | /**
14 | * @brief A 256 bit number object.
15 | *
16 | * Custom implementation for 256 bit number representation.
17 | * Only a little endian format is supported at the moment.
18 | *
19 | */
20 | typedef struct {
21 | uint64_t bits[4]; ///< 256 bit number represented in a little endian format
22 | } uint256_t;
23 |
24 | #ifdef __cplusplus
25 | extern "C" {
26 | #endif
27 |
28 | /**
29 | * @brief New uint256 object from c_string representing a 256 bit number.
30 | *
31 | * @param[in] str A c_string representing a 256 bit number.
32 | * @return uint256_t* Pointer to uint256 object, NULL on failed.
33 | */
34 | uint256_t *uint256_from_str(char const *str);
35 |
36 | /**
37 | * @brief New uint256 object from hex c_string representing a 256 bit number.
38 | *
39 | * @param[in] str A hex c_string representing a 256 bit number.
40 | * @return uint256_t* Pointer to uint256 object, NULL on failed.
41 | */
42 | uint256_t *uint256_from_hex_str(char const *str);
43 |
44 | /**
45 | * @brief Perform addition on two uint256 numbers.
46 | *
47 | * @param[out] sum The sum of two numbers.
48 | * @param[in] a The summand A.
49 | * @param[in] b The summand B.
50 | * @return true On success
51 | * @return false On failed
52 | */
53 | bool uint256_add(uint256_t *sum, uint256_t *a, uint256_t *b);
54 |
55 | /**
56 | * @brief Perform subtraction on two uint256 numbers.
57 | *
58 | * @param[out] diff The difference of two numbers.
59 | * @param[in] min The minuend.
60 | * @param[in] sub The subtrahend.
61 | * @return true On success
62 | * @return false On failed
63 | */
64 | bool uint256_sub(uint256_t *diff, uint256_t *min, uint256_t *sub);
65 |
66 | /**
67 | * @brief Compare two uint256 objects (numbers)
68 | *
69 | * @param[in] a A pointer to uint256 object
70 | * @param[in] b A pointer to uint256 object
71 | * @return int < 0 if a is smaller then b
72 | * @return int > 0 if a is greater than b
73 | * @return int 0 if a is equal to b
74 | */
75 | int uint256_equal(uint256_t const *a, uint256_t const *b);
76 |
77 | /**
78 | * @brief Converts uint256 number to a string
79 | *
80 | * @param[in] num A pointer to uint256 object
81 | * @return Pointer to string object, NULL on failed.
82 | */
83 | char *uint256_to_str(uint256_t *num);
84 |
85 | /**
86 | * @brief Converts uint256 number to a hex string
87 | *
88 | * @param[in] num A pointer to uint256 object
89 | * @return Pointer to string object, NULL on failed.
90 | */
91 | char *uint256_to_hex_str(uint256_t *num);
92 |
93 | /**
94 | * @brief Clone uint256 object, it should be freed after use.
95 | *
96 | * @param[in] num A pointer to uint256 object for clone
97 | * @return uint256_t* New uint256 object
98 | */
99 | uint256_t *uint256_clone(uint256_t const *const num);
100 |
101 | /**
102 | * @brief Free a unit256_t object
103 | *
104 | * @param[in] num A pointer to uint256 object
105 | */
106 | void uint256_free(uint256_t *num);
107 |
108 | #ifdef __cplusplus
109 | }
110 | #endif
111 |
112 | #endif
113 |
--------------------------------------------------------------------------------
/src/crypto/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | #[[
2 | // Copyright 2020 IOTA Stiftung
3 | // SPDX-License-Identifier: Apache-2.0
4 | ]]
5 |
6 | add_library(iota_crypto STATIC)
7 | # the required minimum C standard
8 | set_target_properties(iota_crypto PROPERTIES C_STANDARD_REQUIRED NO C_STANDARD 99)
9 |
10 | target_sources(
11 | iota_crypto
12 | PRIVATE "iota_crypto.c"
13 | PUBLIC "iota_crypto.h" "constants.h")
14 |
15 | target_include_directories(iota_crypto PUBLIC "${PROJECT_SOURCE_DIR}/src" "${CMAKE_INSTALL_PREFIX}/include")
16 |
17 | target_compile_options(iota_crypto PRIVATE -Wall -Wextra)
18 |
19 | if(__ED25519_INCLUDE)
20 | target_compile_definitions(iota_crypto PUBLIC CRYPTO_USE_ED25519_DONNA)
21 | target_link_libraries(iota_crypto INTERFACE ed25519_donna)
22 | add_dependencies(iota_crypto ext_ed25519)
23 | endif()
24 |
25 | if(__BLAKE2_INCLUDE)
26 | target_compile_definitions(iota_crypto PUBLIC CRYPTO_USE_BLAKE2B_REF)
27 | target_link_libraries(iota_crypto INTERFACE blake2)
28 | add_dependencies(iota_crypto ext_blake2)
29 | endif()
30 |
31 | if(CryptoUse STREQUAL "openssl")
32 | target_compile_definitions(iota_crypto PUBLIC CRYPTO_USE_OPENSSL)
33 | target_include_directories(iota_crypto PUBLIC "${OPENSSL_INCLUDE_DIR}")
34 | target_link_libraries(iota_crypto INTERFACE ${OPENSSL_LIBRARIES})
35 | elseif(CryptoUse STREQUAL "libsodium")
36 | target_compile_definitions(iota_crypto PUBLIC CRYPTO_USE_SODIUM)
37 | add_dependencies(iota_crypto sodium)
38 | target_link_libraries(iota_crypto INTERFACE sodium)
39 | elseif(CryptoUse STREQUAL "mbedtls")
40 | target_compile_definitions(iota_crypto PUBLIC CRYPTO_USE_MBEDTLS)
41 | add_dependencies(iota_crypto ext_mbedtls)
42 | target_link_libraries(iota_crypto INTERFACE mbedcrypto mbedtls mbedx509)
43 | endif()
44 |
45 | if(__JEMALLOC_INCLUDED)
46 | add_dependencies(iota_crypto jemalloc)
47 | target_link_libraries(iota_crypto PUBLIC jemalloc${CMAKE_STATIC_LIBRARY_SUFFIX} Threads::Threads)
48 | target_compile_definitions(iota_crypto PUBLIC USE_JEMALLOC)
49 | target_link_options(iota_crypto PUBLIC -Wl,--no-as-needed -ldl)
50 | endif()
51 |
52 | # install headers
53 | install(TARGETS iota_crypto DESTINATION "${CMAKE_INSTALL_PREFIX}/lib")
54 | install(FILES "${PROJECT_SOURCE_DIR}/src/crypto/iota_crypto.h" DESTINATION "${CMAKE_INSTALL_PREFIX}/include/crypto")
55 |
--------------------------------------------------------------------------------
/src/crypto/constants.h:
--------------------------------------------------------------------------------
1 | // Copyright 2022 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __CRYPTO_CONSTANTS_H__
5 | #define __CRYPTO_CONSTANTS_H__
6 |
7 | #define ED_SEED_BYTES 32 // ed25519 seed bytes
8 | #define ED_PUBLIC_KEY_BYTES 32 // ed2519 public key bytes
9 | #define ED_PRIVATE_KEY_BYTES 64 // ed25519 secret/private key bytes
10 | #define ED_SIGNATURE_BYTES 64 // ed25519 signature bytes
11 |
12 | #define CRYPTO_SHA512_KEY_BYTES 32 // crypto_auth_hmacsha512_KEYBYTES
13 | #define CRYPTO_SHA512_HASH_BYTES 64 // crypto_auth_hmacsha512_BYTES
14 | #define CRYPTO_SHA256_KEY_BYTES 32 // crypto_auth_hmacsha256_KEYBYTES
15 | #define CRYPTO_SHA256_HASH_BYTES 32 // crypto_auth_hmacsha256_BYTES
16 | #define CRYPTO_BLAKE2B_256_HASH_BYTES 32 // crypto_generichash_blake2b_BYTES
17 | #define CRYPTO_BLAKE2B_160_HASH_BYTES 20 // crypto_generichash_blake2b-160_BYTES
18 |
19 | #endif
20 |
--------------------------------------------------------------------------------
/src/iota_client.h:
--------------------------------------------------------------------------------
1 | // Copyright 2022 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __IOTA_CLIENT_H__
5 | #define __IOTA_CLIENT_H__
6 |
7 | #include "client/api/restful/get_block.h"
8 | #include "client/api/restful/get_block_metadata.h"
9 | #include "client/api/restful/get_milestone.h"
10 | #include "client/api/restful/get_node_info.h"
11 | #include "client/api/restful/get_output.h"
12 | #include "client/api/restful/get_outputs_id.h"
13 | #include "client/api/restful/get_tips.h"
14 | #include "client/api/restful/get_transaction_included_block.h"
15 | #include "client/api/restful/response_error.h"
16 | #include "client/api/restful/send_block.h"
17 | #include "client/api/restful/send_tagged_data.h"
18 | #include "core/address.h"
19 | #include "core/utils/bech32.h"
20 | #include "core/utils/byte_buffer.h"
21 | #include "core/utils/iota_str.h"
22 | #include "core/utils/macros.h"
23 | #include "core/utils/uint256.h"
24 | #include "crypto/iota_crypto.h"
25 | #include "wallet/output_alias.h"
26 | #include "wallet/output_basic.h"
27 | #include "wallet/output_foundry.h"
28 | #include "wallet/wallet.h"
29 |
30 | #endif
31 |
--------------------------------------------------------------------------------
/src/wallet/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | #[[
2 | // Copyright 2020 IOTA Stiftung
3 | // SPDX-License-Identifier: Apache-2.0
4 | ]]
5 |
6 | add_library(iota_wallet STATIC)
7 |
8 | # the required minimum C standard
9 | set_target_properties(iota_wallet PROPERTIES C_STANDARD_REQUIRED NO C_STANDARD 99)
10 |
11 | target_sources(
12 | iota_wallet
13 | PRIVATE "wallet.c"
14 | "output_basic.c"
15 | "output_alias.c"
16 | "output_foundry.c"
17 | "bip39.c"
18 | PUBLIC "wallet.h" "output_basic.h" "output_alias.h" "output_foundry.h")
19 |
20 | target_include_directories(
21 | iota_wallet PUBLIC "${PROJECT_SOURCE_DIR}/src" "${CURL_INCLUDE_DIRS}"
22 | "${CMAKE_INSTALL_PREFIX}/include/cjson" # for esp32 compatibility
23 | )
24 |
25 | add_dependencies(iota_wallet iota_client)
26 |
27 | target_compile_options(iota_wallet PRIVATE -Wall -Wextra)
28 |
29 | if(BIP39_ENGLISH_ONLY)
30 | target_compile_definitions(iota_wallet PUBLIC BIP39_ENGLISH_ONLY)
31 | endif()
32 |
33 | target_link_libraries(iota_wallet PUBLIC iota_client)
34 |
35 | # install client lib and headers
36 | install(TARGETS iota_wallet DESTINATION "${CMAKE_INSTALL_PREFIX}/lib")
37 | install(
38 | DIRECTORY "${PROJECT_SOURCE_DIR}/src/wallet/"
39 | DESTINATION "${CMAKE_INSTALL_PREFIX}/include/wallet"
40 | FILES_MATCHING
41 | PATTERN "*.h")
42 |
--------------------------------------------------------------------------------
/src/wallet/output_alias.h:
--------------------------------------------------------------------------------
1 | // Copyright 2022 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __WALLET_OUTPUT_ALIAS_H__
5 | #define __WALLET_OUTPUT_ALIAS_H__
6 |
7 | #include
8 |
9 | #include "wallet/wallet.h"
10 |
11 | #ifdef __cplusplus
12 | extern "C" {
13 | #endif
14 |
15 | /**
16 | * @brief Send transaction which creates a new alias output
17 | *
18 | * @param[in] w A wallet instance
19 | * @param[in] sender_change A sender change index which is {0, 1}, also known as a wallet chain
20 | * @param[in] sender_index A sender address index
21 | * @param[in] send_amount An amount to transfer
22 | * @param[in] state_ctrl_addr A state controller address
23 | * @param[in] govern_addr A governor address
24 | * @param[in] foundry_counter A foundry counter
25 | * @param[out] alias_addr A newly created alias address
26 | * @param[out] blk_res A response of a transfer
27 | *
28 | * @return int 0 on success
29 | */
30 | int wallet_alias_output_create(iota_wallet_t* w, bool sender_change, uint32_t sender_index, uint64_t const send_amount,
31 | address_t* state_ctrl_addr, address_t* govern_addr, uint32_t foundry_counter,
32 | address_t* alias_addr, res_send_block_t* blk_res);
33 |
34 | /**
35 | * @brief Send alias state transition transaction
36 | *
37 | * @param[in] w A wallet instance
38 | * @param[in] alias_id An alias identifier
39 | * @param[in] state_ctrl_change A state controller change index which is {0, 1}, also known as a wallet chain
40 | * @param[in] state_ctrl_index A state controller address index
41 | * @param[in] govern_addr A governor address
42 | * @param[in] foundry_counter A foundry counter number
43 | * @param[in] send_amount An amount to transfer
44 | * @param[in] outputs An outputs which will be created in a transaction in addition of possible remainder output
45 | * @param[in] minted_native_tokens A list of minted native tokens which will be created in a transaction
46 | * @param[out] blk_res A response of a transfer
47 | *
48 | * @return int 0 on success
49 | */
50 | int wallet_alias_output_state_transition(iota_wallet_t* w, byte_t alias_id[], bool state_ctrl_change,
51 | uint32_t state_ctrl_index, address_t* govern_addr, uint32_t foundry_counter,
52 | uint64_t send_amount, utxo_outputs_list_t* outputs,
53 | native_tokens_list_t* minted_native_tokens, res_send_block_t* blk_res);
54 |
55 | /**
56 | * @brief Send transaction which destroys alias output
57 | *
58 | * @param[in] w A wallet instance
59 | * @param[in] alias_id An alias identifier
60 | * @param[in] govern_change A governor change index which is {0, 1}, also known as a wallet chain
61 | * @param[in] govern_index A governor address index
62 | * @param[in] recv_addr A receiver address
63 | * @param[out] blk_res A response of a transfer
64 | *
65 | * @return int 0 on success
66 | */
67 | int wallet_alias_output_destroy(iota_wallet_t* w, byte_t alias_id[], bool govern_change, uint32_t govern_index,
68 | address_t* recv_addr, res_send_block_t* blk_res);
69 |
70 | #ifdef __cplusplus
71 | }
72 | #endif
73 |
74 | #endif // __WALLET_OUTPUT_ALIAS_H__
75 |
--------------------------------------------------------------------------------
/src/wallet/output_basic.h:
--------------------------------------------------------------------------------
1 | // Copyright 2022 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __WALLET_OUTPUT_BASIC_H__
5 | #define __WALLET_OUTPUT_BASIC_H__
6 |
7 | #include
8 |
9 | #include "client/api/restful/get_outputs_id.h"
10 | #include "core/models/outputs/output_basic.h"
11 | #include "core/models/signing.h"
12 | #include "wallet/wallet.h"
13 |
14 | #ifdef __cplusplus
15 | extern "C" {
16 | #endif
17 |
18 | /**
19 | * @brief Create and return a basic output
20 | *
21 | * @param[in] recv_addr A receiver address
22 | * @param[in] amount An amount to sent
23 | * @param[in] native_tokens A native tokens to sent
24 | *
25 | * @return output_basic_t* or NULL on failure
26 | */
27 | output_basic_t* wallet_basic_output_create(address_t* recv_addr, uint64_t amount, native_tokens_list_t* native_tokens);
28 |
29 | /**
30 | * @brief Get all senders unspent basic output IDs from a network
31 | *
32 | * @param[in] w A wallet instance
33 | * @param[in] send_addr A sender address
34 | *
35 | * @return res_outputs_id_t* or NULL on failure
36 | */
37 | res_outputs_id_t* wallet_get_unspent_basic_output_ids(iota_wallet_t* w, address_t* send_addr);
38 |
39 | /**
40 | * @brief Send basic transaction which transfers IOTA tokens to an address
41 | *
42 | * @param[in] w A wallet instance
43 | * @param[in] sender_change A sender change index which is {0, 1}, also known as a wallet chain
44 | * @param[in] sender_index A sender address index
45 | * @param[in] send_amount An amount to sent
46 | * @param[in] send_native_tokens A native tokens to sent
47 | * @param[in] recv_addr A receiver address
48 | * @param[out] blk_res A response of a block transfer
49 | *
50 | * @return int 0 on success
51 | */
52 | int wallet_basic_output_send(iota_wallet_t* w, bool sender_change, uint32_t sender_index, uint64_t send_amount,
53 | native_tokens_list_t* send_native_tokens, address_t* recv_addr, res_send_block_t* blk_res);
54 |
55 | #ifdef __cplusplus
56 | }
57 | #endif
58 |
59 | #endif // __WALLET_OUTPUT_BASIC_H__
60 |
--------------------------------------------------------------------------------
/src/wallet/output_foundry.h:
--------------------------------------------------------------------------------
1 | // Copyright 2022 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __WALLET_OUTPUT_FOUNDRY_H__
5 | #define __WALLET_OUTPUT_FOUNDRY_H__
6 |
7 | #include "core/utils/uint256.h"
8 | #include "wallet/wallet.h"
9 |
10 | #ifdef __cplusplus
11 | extern "C" {
12 | #endif
13 |
14 | /**
15 | * @brief Send mint native token transaction
16 | *
17 | * @param[in] w A wallet instance
18 | * @param[in] alias_addr The alias address
19 | * @param[in] state_ctrl_change The state controller change index which is {0, 1}, also known as wallet chain
20 | * @param[in] state_ctrl_index The state controller address index
21 | * @param[in] govern_addr The governor address
22 | * @param[in] receiver_addr The receiver address to which newly minted native tokens will be transferred
23 | * @param[in] max_supply The maximum supply of newly minted native tokens
24 | * @param[in] minted_tokens The number of newly minted native tokens
25 | * @param[in] serial_number The serial number of new foundry
26 | * @param[in] foundry_counter The foundry counter number
27 | * @param[out] blk_res The response of the transfer
28 | *
29 | * @return int 0 on success
30 | */
31 | int wallet_foundry_output_mint_native_tokens(iota_wallet_t* w, address_t* alias_addr, bool state_ctrl_change,
32 | uint32_t state_ctrl_index, address_t* govern_addr,
33 | address_t* receiver_addr, uint256_t* max_supply, uint256_t* minted_tokens,
34 | uint32_t serial_number, uint32_t foundry_counter,
35 | res_send_block_t* blk_res);
36 |
37 | #ifdef __cplusplus
38 | }
39 | #endif
40 |
41 | #endif // __WALLET_OUTPUT_FOUNDRY_H__
42 |
--------------------------------------------------------------------------------
/src/wallet/wordlists/README.md:
--------------------------------------------------------------------------------
1 | Wordlists are from [bips/bd943663/bip-0039](https://github.com/bitcoin/bips/tree/bd943663d6908679ca4f94276589ef402f865739/bip-0039)
2 |
3 | Support Languages:
4 |
5 | | Language | ISO 639-1 |
6 | |:--------:|:---------:|
7 | | English | en |
8 | | Japanese | ja |
9 | | Korean | ko |
10 | | Spanish | es |
11 | | Chinese Traditional | zh_hant |
12 | | Chinese Simplified | zh_hans |
13 | | French | fr |
14 | | Italian | it |
15 | | Czech | cs |
16 | | Portuguese | pt |
17 |
18 |
19 | Language header files are auto-generated by wordlists_header.py script
20 |
21 | ```
22 | ./wordlist_header.py english.txt en > english.h
23 | ./wordlist_header.py japanese.txt ja > japanese.h
24 | ./wordlist_header.py korean.txt ko > korean.h
25 | ./wordlist_header.py spanish.txt es > spanish.h
26 | ./wordlist_header.py chinese_traditional.txt zh_hant > chinese_traditional.h
27 | ./wordlist_header.py chinese_simplified.txt zh_hans > chinese_simplified.h
28 | ./wordlist_header.py french.txt fr > french.h
29 | ./wordlist_header.py italian.txt it > italian.h
30 | ./wordlist_header.py czech.txt cs > czech.h
31 | ./wordlist_header.py portuguese.txt pt > portuguese.h
32 | ```
33 |
--------------------------------------------------------------------------------
/src/wallet/wordlists/word.h:
--------------------------------------------------------------------------------
1 | // Copyright 2021 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __WALLE__WORDLISTS_WORD_H__
5 | #define __WALLE__WORDLISTS_WORD_H__
6 |
7 | #include
8 |
9 | /**
10 | * @brief The word object for wordlist tables.
11 | *
12 | */
13 | typedef struct word {
14 | char *p; ///< a pointer to the string
15 | size_t len; ///< the length of string, null terminator is excluded
16 | } word_t;
17 |
18 | #endif
--------------------------------------------------------------------------------
/src/wallet/wordlists/wordlist_header.py:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env python3
2 |
3 | # Copyright 2021 IOTA Stiftung
4 | # SPDX-License-Identifier: Apache-2.0
5 |
6 | import sys
7 | import os.path
8 | import datetime
9 |
10 |
11 | def main():
12 | w_file = sys.argv[1]
13 | lan_prefix = sys.argv[2]
14 | with open(w_file, mode='r', encoding="utf-8") as wf:
15 | word_list = [l.strip() for l in wf.readlines()]
16 |
17 | if len(word_list) != 2048:
18 | print("must have 2048 words in the wordlist")
19 | sys.exit()
20 |
21 | # print(word_list)
22 | print("/* ===Auto Generated via " +
23 | os.path.basename(sys.argv[0]) + " do not modify!!=== */\n")
24 | print("// Copyright " + str(datetime.datetime.now().year) + " IOTA Stiftung")
25 | print("// SPDX-License-Identifier: Apache-2.0\n")
26 | print("#ifndef __WALLE__WORDLISTS_" + lan_prefix.upper() + "_H__")
27 | print("#define __WALLE__WORDLISTS_" + lan_prefix.upper() + "_H__\n")
28 | print('#include "wallet/wordlists/word.h"\n')
29 | print('static word_t ' + lan_prefix + '_word[] = {')
30 | for w in word_list:
31 | print(' {"'+w+'", ' + str(len(w.encode('utf-8'))) + '},')
32 | print('};\n')
33 | print("#endif\n")
34 |
35 |
36 | if __name__ == "__main__":
37 | main()
38 |
--------------------------------------------------------------------------------
/tests/client/api_json_parser/test_common.c:
--------------------------------------------------------------------------------
1 | // Copyright 2022 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #include
5 |
6 | #include "client/api/json_parser/common.h"
7 | #include "client/constants.h"
8 | #include "core/utils/macros.h"
9 | #include "unity/unity.h"
10 |
11 | void setUp(void) {}
12 |
13 | void tearDown(void) {}
14 |
15 | void test_parse_ed25519_address() {
16 | char const* const json_res =
17 | "{\"address\":{\"type\":0,\"pubKeyHash\":"
18 | "\"0x194eb32b9b6c61207192c7073562a0b3adf50a7c1f268182b552ec8999380acb\"}}";
19 | cJSON* json_obj = cJSON_Parse(json_res);
20 | TEST_ASSERT_NOT_NULL(json_obj);
21 |
22 | address_t address;
23 | int result = json_parser_common_address_deserialize(json_obj, JSON_KEY_ADDR, &address);
24 | TEST_ASSERT_EQUAL_INT(0, result);
25 |
26 | address_t test_addr;
27 | test_addr.type = ADDRESS_TYPE_ED25519;
28 | hex_2_bin("194eb32b9b6c61207192c7073562a0b3adf50a7c1f268182b552ec8999380acb", BIN_TO_HEX_BYTES(ED25519_PUBKEY_BYTES),
29 | NULL, test_addr.address, ED25519_PUBKEY_BYTES);
30 | TEST_ASSERT_TRUE(address_equal(&test_addr, &address));
31 |
32 | cJSON_Delete(json_obj);
33 | }
34 |
35 | void test_parse_alias_address() {
36 | char const* const json_res =
37 | "{\"address\":{\"type\":8,\"aliasId\":"
38 | "\"0x01aa8d202a51b575eb9248b2d580dc6149508ff094fc0ed79c25486935597248\"}}";
39 | cJSON* json_obj = cJSON_Parse(json_res);
40 | TEST_ASSERT_NOT_NULL(json_obj);
41 |
42 | address_t address;
43 | int result = json_parser_common_address_deserialize(json_obj, JSON_KEY_ADDR, &address);
44 | TEST_ASSERT_EQUAL_INT(0, result);
45 |
46 | address_t test_addr;
47 | test_addr.type = ADDRESS_TYPE_ALIAS;
48 | hex_2_bin("01aa8d202a51b575eb9248b2d580dc6149508ff094fc0ed79c25486935597248", BIN_TO_HEX_BYTES(ALIAS_ID_BYTES), NULL,
49 | test_addr.address, ALIAS_ID_BYTES);
50 | TEST_ASSERT_TRUE(address_equal(&test_addr, &address));
51 |
52 | cJSON_Delete(json_obj);
53 | }
54 |
55 | void test_parse_nft_address() {
56 | char const* const json_res =
57 | "{\"address\":{\"type\":16,\"nftId\":"
58 | "\"0x19c82b32761fd8729a1a6c77f7c17597e4b9b01759794e52381f6a0050b0c11f\"}}";
59 | cJSON* json_obj = cJSON_Parse(json_res);
60 | TEST_ASSERT_NOT_NULL(json_obj);
61 |
62 | address_t address;
63 | int result = json_parser_common_address_deserialize(json_obj, JSON_KEY_ADDR, &address);
64 | TEST_ASSERT_EQUAL_INT(0, result);
65 |
66 | address_t test_addr;
67 | test_addr.type = ADDRESS_TYPE_NFT;
68 | hex_2_bin("19c82b32761fd8729a1a6c77f7c17597e4b9b01759794e52381f6a0050b0c11f", BIN_TO_HEX_BYTES(NFT_ID_BYTES), NULL,
69 | test_addr.address, NFT_ID_BYTES);
70 | TEST_ASSERT_TRUE(address_equal(&test_addr, &address));
71 |
72 | cJSON_Delete(json_obj);
73 | }
74 |
75 | void test_parse_unsupported_address_type() {
76 | char const* const json_res =
77 | "{\"address\":{\"type\":10,\"address\":"
78 | "\"0x19c82b32761fd8729a1a6c77f7c17597e4b9b01759794e52381f6a0050b0c11f\"}}";
79 | cJSON* json_obj = cJSON_Parse(json_res);
80 | TEST_ASSERT_NOT_NULL(json_obj);
81 |
82 | address_t address;
83 | int result = json_parser_common_address_deserialize(json_obj, JSON_KEY_ADDR, &address);
84 | TEST_ASSERT_EQUAL_INT(-1, result);
85 |
86 | cJSON_Delete(json_obj);
87 | }
88 |
89 | int main() {
90 | UNITY_BEGIN();
91 |
92 | RUN_TEST(test_parse_ed25519_address);
93 | RUN_TEST(test_parse_alias_address);
94 | RUN_TEST(test_parse_nft_address);
95 | RUN_TEST(test_parse_unsupported_address_type);
96 |
97 | return UNITY_END();
98 | }
99 |
--------------------------------------------------------------------------------
/tests/client/api_restful/test_faucet_enqueue.c:
--------------------------------------------------------------------------------
1 | // Copyright 2022 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #include
5 | #include
6 |
7 | #include "client/api/restful/faucet_enqueue.h"
8 | #include "test_config.h"
9 | #include "unity/unity.h"
10 |
11 | void setUp(void) {}
12 |
13 | void tearDown(void) {}
14 |
15 | void test_faucet_enqueue(void) {
16 | const char *const address_bech32 = "atoi1qqs7y6ec5vcg6cnz46vjrar2epc52lhksyar3a4zua7fg7ca08y5ymep8aa";
17 | const char *const address_bech32_invalid = "pqoi1qqs7y6ec5vcg6cnz46vjrar2epc52lhksyar3a4zua7fg7ca08y5ymep8ab";
18 | const char *const address_bech32_invalid_len = "atoi1qqs7y6ec5vcg6cnz46vjrar2epc52lhksyar3a4zua7fg7ca08y5";
19 |
20 | iota_client_conf_t ctx = {.host = TEST_FAUCET_HOST, .port = TEST_FAUCET_PORT, .use_tls = TEST_IS_HTTPS};
21 |
22 | res_faucet_enqueue_t res = {};
23 |
24 | // Test NULL inputs
25 | TEST_ASSERT_EQUAL_INT(-1, req_tokens_to_addr_from_faucet(NULL, address_bech32, &res));
26 | TEST_ASSERT_EQUAL_INT(-1, req_tokens_to_addr_from_faucet(&ctx, NULL, &res));
27 | TEST_ASSERT_EQUAL_INT(-1, req_tokens_to_addr_from_faucet(&ctx, address_bech32, NULL));
28 |
29 | // Test bech32 address with invalid len
30 | TEST_ASSERT_EQUAL_INT(0, req_tokens_to_addr_from_faucet(&ctx, address_bech32_invalid_len, &res));
31 | TEST_ASSERT(res.is_error == true);
32 | res_err_free(res.u.error);
33 |
34 | // Test for invalid bech32 address
35 | res.is_error = false;
36 | TEST_ASSERT_EQUAL_INT(0, req_tokens_to_addr_from_faucet(&ctx, address_bech32_invalid, &res));
37 | TEST_ASSERT(res.is_error == true);
38 | res_err_free(res.u.error);
39 |
40 | // Test for valid bech32
41 | res.is_error = false;
42 | TEST_ASSERT_EQUAL_INT(0, req_tokens_to_addr_from_faucet(&ctx, address_bech32, &res));
43 | TEST_ASSERT(res.is_error == false);
44 | printf("Address : %s\n", res.u.req_res.bech32_address);
45 | printf("Waiting Requests : %d\n", res.u.req_res.waiting_reqs_count);
46 | }
47 |
48 | int main() {
49 | UNITY_BEGIN();
50 | #if TEST_TANGLE_ENABLE
51 | RUN_TEST(test_faucet_enqueue);
52 | #endif
53 | return UNITY_END();
54 | }
55 |
--------------------------------------------------------------------------------
/tests/client/api_restful/test_get_health.c:
--------------------------------------------------------------------------------
1 | // Copyright 2020 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #include
5 | #include
6 |
7 | #include "test_config.h"
8 |
9 | #include "client/api/restful/get_health.h"
10 |
11 | void setUp(void) {}
12 |
13 | void tearDown(void) {}
14 |
15 | void test_get_health() {
16 | iota_client_conf_t ctx = {.host = TEST_NODE_HOST, .port = TEST_NODE_PORT, .use_tls = TEST_IS_HTTPS};
17 | bool health = false;
18 | TEST_ASSERT(get_health(&ctx, &health) == 0);
19 | }
20 |
21 | int main() {
22 | UNITY_BEGIN();
23 |
24 | #if TEST_TANGLE_ENABLE
25 | RUN_TEST(test_get_health);
26 | #endif
27 |
28 | return UNITY_END();
29 | }
--------------------------------------------------------------------------------
/tests/client/api_restful/test_get_tips.c:
--------------------------------------------------------------------------------
1 | // Copyright 2020 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #include
5 |
6 | #include "client/api/restful/get_tips.h"
7 | #include "test_config.h"
8 | #include "unity/unity.h"
9 |
10 | void setUp(void) {}
11 |
12 | void tearDown(void) {}
13 |
14 | void test_get_tips() {
15 | iota_client_conf_t ctx = {.host = TEST_NODE_HOST, .port = TEST_NODE_PORT, .use_tls = TEST_IS_HTTPS};
16 |
17 | res_tips_t* res_tips = res_tips_new();
18 | TEST_ASSERT_NOT_NULL(res_tips);
19 |
20 | TEST_ASSERT(get_tips(&ctx, res_tips) == 0);
21 | if (res_tips->is_error == true) {
22 | printf("Error: %s\n", res_tips->u.error->msg);
23 | } else {
24 | TEST_ASSERT(get_tips_id_count(res_tips) > 0);
25 | }
26 |
27 | res_tips_free(res_tips);
28 | }
29 |
30 | void test_deser_get_tips() {
31 | char const* const json_tips =
32 | "{\"tips\":[\"0x0a7c22aa43620d938146bcfc94a40804b26a5aaf3913bdc51b2836c47650de5c\","
33 | "\"0x3a3ca52a4c7d96fed4eef037db4421231f09e63a817bcf913f33c0806e565de9\","
34 | "\"0xa714ca72bb21d1e69b49a272713b9a1edc4d5679695680b5f36b907c0ed0d445\","
35 | "\"0xea878b98a3eb38154993ea27d597e6cbb8fda0cd7b71cc2eb345b6c62140a6bf\"]}";
36 |
37 | res_tips_t* res_tips = res_tips_new();
38 | TEST_ASSERT_NOT_NULL(res_tips);
39 |
40 | TEST_ASSERT(get_tips_deserialize(json_tips, res_tips) == 0);
41 | TEST_ASSERT(res_tips->is_error == false);
42 | TEST_ASSERT_EQUAL_INT(4, get_tips_id_count(res_tips));
43 | TEST_ASSERT_EQUAL_STRING("0a7c22aa43620d938146bcfc94a40804b26a5aaf3913bdc51b2836c47650de5c",
44 | get_tips_id(res_tips, 0));
45 | TEST_ASSERT_EQUAL_STRING("3a3ca52a4c7d96fed4eef037db4421231f09e63a817bcf913f33c0806e565de9",
46 | get_tips_id(res_tips, 1));
47 | TEST_ASSERT_EQUAL_STRING("a714ca72bb21d1e69b49a272713b9a1edc4d5679695680b5f36b907c0ed0d445",
48 | get_tips_id(res_tips, 2));
49 | TEST_ASSERT_EQUAL_STRING("ea878b98a3eb38154993ea27d597e6cbb8fda0cd7b71cc2eb345b6c62140a6bf",
50 | get_tips_id(res_tips, 3));
51 |
52 | res_tips_free(res_tips);
53 | }
54 |
55 | void test_deser_tips_err() {
56 | char const* const json_err =
57 | "{\"error\":{\"code\":\"service_unavailable\",\"message\":\"unable to handle the request\"}}";
58 |
59 | res_tips_t* res_tips = res_tips_new();
60 | TEST_ASSERT_NOT_NULL(res_tips);
61 |
62 | TEST_ASSERT(get_tips_deserialize(json_err, res_tips) == 0);
63 | TEST_ASSERT(res_tips->is_error == true);
64 | TEST_ASSERT_EQUAL_STRING(res_tips->u.error->code, "service_unavailable");
65 | TEST_ASSERT_EQUAL_STRING(res_tips->u.error->msg, "unable to handle the request");
66 |
67 | res_tips_free(res_tips);
68 | }
69 |
70 | int main() {
71 | UNITY_BEGIN();
72 |
73 | #if TEST_TANGLE_ENABLE
74 | RUN_TEST(test_get_tips);
75 | #endif
76 | RUN_TEST(test_deser_get_tips);
77 | RUN_TEST(test_deser_tips_err);
78 |
79 | return UNITY_END();
80 | }
81 |
--------------------------------------------------------------------------------
/tests/client/api_restful/test_get_transaction_included_block.c:
--------------------------------------------------------------------------------
1 | // Copyright 2020 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #include
5 |
6 | #include "client/api/restful/get_transaction_included_block.h"
7 | #include "core/models/payloads/transaction.h"
8 | #include "test_config.h"
9 | #include "unity/unity.h"
10 |
11 | /**
12 | * @brief This API has no deserialization tests because the response object is a block object which is tested in
13 | * test_get_block.c
14 | *
15 | */
16 |
17 | void setUp(void) {}
18 |
19 | void tearDown(void) {}
20 |
21 | void test_get_transaction_included_block() {
22 | char const* const tx_id = "5e753f69b44870aa6a90adf2c366dccac00097c41d5c884dd81ef7cf29eefdd7";
23 | iota_client_conf_t ctx = {.host = TEST_NODE_HOST, .port = TEST_NODE_PORT, .use_tls = TEST_IS_HTTPS};
24 |
25 | res_block_t* msg = res_block_new();
26 | TEST_ASSERT_NOT_NULL(msg);
27 | TEST_ASSERT(get_transaction_included_block_by_id(&ctx, tx_id, msg) == 0);
28 | if (msg->is_error) {
29 | printf("API response: %s\n", msg->u.error->msg);
30 | } else {
31 | // It must be a transaction block
32 | TEST_ASSERT(core_block_get_payload_type(msg->u.blk) == CORE_BLOCK_PAYLOAD_TRANSACTION);
33 | // Print transaction block
34 | core_block_print((msg->u.blk), 0);
35 | }
36 | res_block_free(msg);
37 | }
38 |
39 | int main() {
40 | UNITY_BEGIN();
41 | #if TEST_TANGLE_ENABLE
42 | RUN_TEST(test_get_transaction_included_block);
43 | #endif
44 | return UNITY_END();
45 | }
46 |
--------------------------------------------------------------------------------
/tests/client/api_restful/test_response_error.c:
--------------------------------------------------------------------------------
1 | // Copyright 2020 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #include
5 | #include
6 |
7 | #include "client/api/restful/response_error.h"
8 |
9 | void setUp(void) {}
10 |
11 | void tearDown(void) {}
12 |
13 | void test_deser_res_err() {
14 | char const* const json_err =
15 | "{\"error\":{\"code\":\"service_unavailable\",\"message\":\"unable to handle the request\"}}";
16 |
17 | cJSON* json_obj = cJSON_Parse(json_err);
18 | TEST_ASSERT_NOT_NULL(json_obj);
19 | res_err_t* r = deser_error(json_obj);
20 | TEST_ASSERT_NOT_NULL(r);
21 |
22 | TEST_ASSERT_EQUAL_STRING("service_unavailable", r->code);
23 | TEST_ASSERT_EQUAL_STRING("unable to handle the request", r->msg);
24 |
25 | res_err_free(r);
26 | cJSON_Delete(json_obj);
27 | }
28 |
29 | void test_deser_err_msg_not_str() {
30 | char const* const json_err = "{ \"error\": { \"code\": 400, \"message\": 1234 } }";
31 |
32 | cJSON* json_obj = cJSON_Parse(json_err);
33 | TEST_ASSERT_NOT_NULL(json_obj);
34 | res_err_t* r = deser_error(json_obj);
35 | TEST_ASSERT_NULL(r);
36 |
37 | cJSON_Delete(json_obj);
38 | }
39 |
40 | void test_deser_err_not_obj() {
41 | char const* const json_err = "{ \"error\": \"invalid data provided\" }";
42 |
43 | cJSON* json_obj = cJSON_Parse(json_err);
44 | TEST_ASSERT_NOT_NULL(json_obj);
45 | res_err_t* r = deser_error(json_obj);
46 | TEST_ASSERT_NULL(r);
47 |
48 | cJSON_Delete(json_obj);
49 | }
50 |
51 | int main() {
52 | UNITY_BEGIN();
53 |
54 | // correct json format
55 | RUN_TEST(test_deser_res_err);
56 | // error message is not a string
57 | RUN_TEST(test_deser_err_msg_not_str);
58 | // error element not a json object
59 | RUN_TEST(test_deser_err_not_obj);
60 |
61 | return UNITY_END();
62 | }
63 |
--------------------------------------------------------------------------------
/tests/core/test_allocator.c:
--------------------------------------------------------------------------------
1 | // Copyright 2021 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | #include "core/utils/allocator.h"
9 |
10 | void setUp(void) {}
11 |
12 | void tearDown(void) {}
13 |
14 | void test_allocator() {
15 | char *str = "Hello";
16 | char *m = malloc(strlen(str) + 1);
17 | strcpy(m, str);
18 | printf("%s: %s\n", JEMALLOC_VERSION, m);
19 | free(m);
20 | }
21 |
22 | int main() {
23 | UNITY_BEGIN();
24 |
25 | RUN_TEST(test_allocator);
26 |
27 | return UNITY_END();
28 | }
--------------------------------------------------------------------------------
/tests/core/test_byte_buffer.c:
--------------------------------------------------------------------------------
1 | // Copyright 2021 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #include
5 | #include
6 |
7 | #include "core/utils/byte_buffer.h"
8 | #include "unity/unity.h"
9 |
10 | void setUp(void) {}
11 |
12 | void tearDown(void) {}
13 |
14 | void test_byte_buf() {
15 | // create a byte buffer
16 | byte_buf_t *buf = byte_buf_new();
17 | TEST_ASSERT_NOT_NULL(buf);
18 | TEST_ASSERT_NULL(buf->data);
19 | TEST_ASSERT(buf->cap == 0);
20 | TEST_ASSERT(buf->len == 0);
21 |
22 | // append two data sets to the buffer
23 | TEST_ASSERT_TRUE(byte_buf_append(buf, (byte_t *)"ABCDE", 5));
24 | TEST_ASSERT(buf->cap == 5);
25 | TEST_ASSERT(buf->len == 5);
26 | TEST_ASSERT_TRUE(byte_buf_append(buf, (byte_t *)"FGHIJ", 5));
27 | TEST_ASSERT(buf->cap == 10);
28 | TEST_ASSERT(buf->len == 10);
29 | // set data to the buffer
30 | TEST_ASSERT_TRUE(byte_buf_set(buf, (byte_t *)"VWXZY", 5));
31 | TEST_ASSERT(buf->cap == 10);
32 | TEST_ASSERT(buf->len == 5);
33 | // byte_buf_print(buf);
34 |
35 | // append an null terminator to buffer data
36 | byte_buf2str(buf);
37 | TEST_ASSERT(buf->cap == 10);
38 | TEST_ASSERT(buf->len == 6);
39 | // should not append the null terminator again
40 | byte_buf2str(buf);
41 | TEST_ASSERT(buf->cap == 10);
42 | TEST_ASSERT(buf->len == 6);
43 | // printf("%s\n", buf->data);
44 |
45 | // reserve size smaller than capacity
46 | TEST_ASSERT_TRUE(byte_buf_reserve(buf, 5));
47 | TEST_ASSERT(buf->cap == 10);
48 | TEST_ASSERT(buf->len == 6);
49 |
50 | // reserve size bigger than capacity
51 | TEST_ASSERT_TRUE(byte_buf_reserve(buf, 100));
52 | TEST_ASSERT(buf->cap == 100);
53 | TEST_ASSERT(buf->len == 6);
54 |
55 | // byte_buf_print(buf);
56 |
57 | // duplicates a byte buffer
58 | byte_buf_t *c = byte_buf_clone(buf);
59 | TEST_ASSERT(c->cap == 6);
60 | TEST_ASSERT(c->len == 6);
61 | TEST_ASSERT(c != buf);
62 | TEST_ASSERT(c->data != buf->data);
63 | TEST_ASSERT_EQUAL_MEMORY(c->data, buf->data, buf->len);
64 |
65 | byte_buf_free(buf);
66 | byte_buf_free(c);
67 | }
68 |
69 | void test_hex_convertor() {
70 | char const *exp_str = "Hello world!";
71 | char const *exp_hex = "48656c6c6f20776f726c6421";
72 |
73 | byte_buf_t *buf = byte_buf_new_with_data((byte_t *)exp_str, strlen(exp_str));
74 | byte_buf_t *hex = byte_buf_str2hex(buf);
75 | TEST_ASSERT_EQUAL_STRING(exp_hex, hex->data);
76 | byte_buf_free(buf);
77 | buf = NULL;
78 | byte_buf_free(hex);
79 |
80 | buf = byte_buf_new_with_data((byte_t *)exp_hex, strlen(exp_hex));
81 | byte_buf_t *str = byte_buf_hex2str(buf);
82 | TEST_ASSERT_EQUAL_STRING(exp_str, str->data);
83 | byte_buf_free(buf);
84 | byte_buf_free(str);
85 | }
86 |
87 | void test_hex_bin() {
88 | char const *exp_hex = "48656c6c6f20776f726c6421";
89 | byte_t exp_bin[12] = {0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x21};
90 | byte_t bin[12] = {};
91 |
92 | // hex2bin
93 | TEST_ASSERT(hex_2_bin(exp_hex, strlen(exp_hex), NULL, bin, 12) == 0);
94 | TEST_ASSERT_EQUAL_MEMORY(exp_bin, bin, 12);
95 |
96 | // bin2hex
97 | char hex_str[(12 * 2) + 1] = {};
98 | TEST_ASSERT(bin_2_hex(bin, 12, NULL, hex_str, sizeof(hex_str)) == 0);
99 | TEST_ASSERT_EQUAL_STRING(exp_hex, hex_str);
100 | }
101 |
102 | int main() {
103 | UNITY_BEGIN();
104 |
105 | RUN_TEST(test_byte_buf);
106 | RUN_TEST(test_hex_convertor);
107 | RUN_TEST(test_hex_bin);
108 |
109 | return UNITY_END();
110 | }
111 |
--------------------------------------------------------------------------------
/tests/core/test_byte_cost_config.c:
--------------------------------------------------------------------------------
1 | // Copyright 2022 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #include "core/models/inputs/utxo_input.h"
5 | #include "core/models/outputs/byte_cost_config.h"
6 | #include "unity/unity.h"
7 |
8 | void setUp(void) {}
9 |
10 | void tearDown(void) {}
11 |
12 | void test_byte_cost_config_create_new_config() {
13 | uint16_t byte_cost = (uint16_t)123456;
14 | uint8_t byte_factor_data = 111;
15 | uint8_t byte_factor_key = 222;
16 | uint16_t byte_offset = (IOTA_OUTPUT_ID_BYTES * byte_factor_key) + (IOTA_BLOCK_ID_BYTES * byte_factor_data) +
17 | (sizeof(uint32_t) * byte_factor_data) + (sizeof(uint32_t) * byte_factor_data);
18 |
19 | byte_cost_config_t* config = byte_cost_config_new(byte_cost, byte_factor_data, byte_factor_key);
20 |
21 | TEST_ASSERT_EQUAL_UINT16(byte_cost, config->v_byte_cost);
22 | TEST_ASSERT_EQUAL_UINT8(byte_factor_data, config->v_byte_factor_data);
23 | TEST_ASSERT_EQUAL_UINT8(byte_factor_key, config->v_byte_factor_key);
24 | TEST_ASSERT_EQUAL_UINT16(byte_offset, config->v_byte_offset);
25 |
26 | byte_cost_config_free(config);
27 | }
28 |
29 | void test_byte_cost_config_create_new_default_config() {
30 | byte_cost_config_t* config = byte_cost_config_default_new();
31 |
32 | TEST_ASSERT_EQUAL_UINT16(500, config->v_byte_cost);
33 | TEST_ASSERT_EQUAL_UINT8(1, config->v_byte_factor_data);
34 | TEST_ASSERT_EQUAL_UINT8(10, config->v_byte_factor_key);
35 | TEST_ASSERT_EQUAL_UINT16(380, config->v_byte_offset);
36 |
37 | byte_cost_config_free(config);
38 | }
39 |
40 | int main() {
41 | UNITY_BEGIN();
42 |
43 | RUN_TEST(test_byte_cost_config_create_new_config);
44 | RUN_TEST(test_byte_cost_config_create_new_default_config);
45 |
46 | return UNITY_END();
47 | }
48 |
--------------------------------------------------------------------------------
/tests/core/test_iota_str.c:
--------------------------------------------------------------------------------
1 | // Copyright 2021 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #include
5 |
6 | #include "core/utils/iota_str.h"
7 | #include "unity/unity.h"
8 |
9 | void setUp(void) {}
10 |
11 | void tearDown(void) {}
12 |
13 | void test_iota_str() {
14 | char* c_str1 = "hello";
15 | // test new
16 | iota_str_t* str1 = iota_str_new(c_str1);
17 | TEST_ASSERT_NOT_NULL(str1);
18 | TEST_ASSERT_NOT_NULL(str1->buf);
19 | TEST_ASSERT_EQUAL_INT(strlen(c_str1), str1->len);
20 | TEST_ASSERT_EQUAL_INT(strlen(c_str1) + 1, str1->cap);
21 | TEST_ASSERT(strcmp(str1->buf, c_str1) == 0);
22 |
23 | // test append
24 | int ret = iota_str_append(str1, " world!");
25 | TEST_ASSERT(ret == 0);
26 | TEST_ASSERT(strcmp(str1->buf, "hello world!") == 0);
27 |
28 | ret = iota_str_appendn(str1, " world!", 3);
29 | TEST_ASSERT(ret == 0);
30 | TEST_ASSERT(strcmp(str1->buf, "hello world! wo") == 0);
31 |
32 | ret = iota_str_append_char(str1, 'W');
33 | TEST_ASSERT(ret == 0);
34 | TEST_ASSERT(strcmp(str1->buf, "hello world! woW") == 0);
35 |
36 | // test clone
37 | iota_str_t* str2 = iota_str_clone(str1);
38 | TEST_ASSERT_NOT_NULL(str2);
39 | TEST_ASSERT_NOT_NULL(str2->buf);
40 | TEST_ASSERT(strcmp(str1->buf, str2->buf) == 0);
41 | TEST_ASSERT_EQUAL_INT32(str1->len, str2->len);
42 | // test cmp
43 | TEST_ASSERT(iota_str_cmp(str1, str2) == 0);
44 |
45 | // test n clone
46 | iota_str_t* str3 = iota_str_clonen(str1, strlen(c_str1));
47 | TEST_ASSERT_NOT_NULL(str3);
48 | TEST_ASSERT_NOT_NULL(str3->buf);
49 | TEST_ASSERT_EQUAL_INT(strlen(c_str1), str3->len);
50 | TEST_ASSERT_EQUAL_INT(strlen(c_str1) + 1, str3->cap);
51 | TEST_ASSERT(strcmp(str3->buf, c_str1) == 0);
52 |
53 | iota_str_destroy(str1);
54 | iota_str_destroy(str2);
55 | iota_str_destroy(str3);
56 | }
57 |
58 | int main() {
59 | UNITY_BEGIN();
60 |
61 | RUN_TEST(test_iota_str);
62 |
63 | return UNITY_END();
64 | }
--------------------------------------------------------------------------------
/tests/core/test_slip10.c:
--------------------------------------------------------------------------------
1 | // Copyright 2020 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | #include "core/utils/byte_buffer.h"
9 | #include "core/utils/slip10.h"
10 | #include "crypto/iota_crypto.h"
11 | #include "slip10_vector.h"
12 |
13 | void setUp(void) {}
14 |
15 | void tearDown(void) {}
16 |
17 | void test_bip32path() {
18 | bip32_path_t path = {};
19 | size_t test_cases = sizeof(bip32path_set) / sizeof(test_bip32path_t);
20 | for (size_t i = 0; i < test_cases; i++) {
21 | printf("bip32 path: %s\n", bip32path_set[i].str);
22 | int ret = slip10_parse_path(bip32path_set[i].str, &path);
23 | TEST_ASSERT(ret == bip32path_set[i].err);
24 | if (ret == 0) {
25 | TEST_ASSERT(bip32path_set[i].path_len == (size_t)path.len);
26 | TEST_ASSERT_EQUAL_MEMORY(bip32path_set[i].exp_path, path.path, path.len);
27 | }
28 | }
29 | }
30 |
31 | void test_derive_key_from_path() {
32 | byte_t tmp_seed[64] = {};
33 | slip10_key_t key = {};
34 | byte_t tmp_pub[SLIP10_PUBLIC_KEY_BYTES] = {};
35 |
36 | for (size_t i = 0; i < sizeof(slip10_set) / sizeof(test_slip10_t); i++) {
37 | printf("slip10: %s, %s\n", slip10_set[i].seed, slip10_set[i].path);
38 | size_t seed_len = strlen(slip10_set[i].seed) / 2;
39 | // hex seed to bin seed
40 | TEST_ASSERT(hex_2_bin(slip10_set[i].seed, strlen(slip10_set[i].seed), NULL, tmp_seed, seed_len) == 0);
41 |
42 | // key derivation
43 | int ret = slip10_key_from_path(tmp_seed, seed_len, slip10_set[i].path, ED25519_CURVE, &key);
44 | TEST_ASSERT(ret == slip10_set[i].err);
45 |
46 | if (ret == 0) {
47 | // validating chain code
48 | TEST_ASSERT_EQUAL_MEMORY(slip10_set[i].chain_code, key.chain_code, SLIP10_CHAIN_CODE_BYTES);
49 | // validating private key
50 | TEST_ASSERT_EQUAL_MEMORY(slip10_set[i].private, key.key, SLIP10_PRIVATE_KEY_BYTES);
51 | // validating public key
52 | TEST_ASSERT(slip10_public_key(ED25519_CURVE, &key, tmp_pub) == 0);
53 | TEST_ASSERT_EQUAL_MEMORY(slip10_set[i].public, tmp_pub, SLIP10_PUBLIC_KEY_BYTES);
54 | }
55 | }
56 | }
57 |
58 | int main() {
59 | UNITY_BEGIN();
60 |
61 | RUN_TEST(test_bip32path);
62 | RUN_TEST(test_derive_key_from_path);
63 |
64 | return UNITY_END();
65 | }
66 |
--------------------------------------------------------------------------------
/tests/core/test_utils_bech32.c:
--------------------------------------------------------------------------------
1 | // Copyright 2020 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #include
5 |
6 | #include "core/utils/bech32.h"
7 | #include "unity/unity.h"
8 |
9 | static const char *valid_checksum[] = {
10 | "A12UEL5L",
11 | "an83characterlonghumanreadablepartthatcontainsthenumber1andtheexcludedcharactersbio1tt5tgs",
12 | "abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw",
13 | "11qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqc8247j",
14 | "split1checkupstagehandshakeupstreamerranterredcaperred2y9e3w",
15 | };
16 |
17 | static const char *invalid_checksum[] = {
18 | " 1nwldj5", ("\x7f"),
19 | "1axkwrx", "an84characterslonghumanreadablepartthatcontainsthenumber1andtheexcludedcharactersbio1569pvx",
20 | "pzry9x0s0muk", "1pzry9x0s0muk",
21 | "x1b4n0q5v", "li1dgmt3",
22 | "de1lg7wt\xff",
23 | };
24 |
25 | static int my_strncasecmp(const char *s1, const char *s2, size_t n) {
26 | size_t i = 0;
27 | while (i < n) {
28 | char c1 = s1[i];
29 | char c2 = s2[i];
30 | if (c1 >= 'A' && c1 <= 'Z') c1 = (c1 - 'A') + 'a';
31 | if (c2 >= 'A' && c2 <= 'Z') c2 = (c2 - 'A') + 'a';
32 | if (c1 < c2) return -1;
33 | if (c1 > c2) return 1;
34 | if (c1 == 0) return 0;
35 | ++i;
36 | }
37 | return 0;
38 | }
39 |
40 | void setUp(void) {}
41 |
42 | void tearDown(void) {}
43 |
44 | void test_bech32_decode_encode() {
45 | for (size_t i = 0; i < sizeof(valid_checksum) / sizeof(valid_checksum[0]); ++i) {
46 | uint8_t data[82] = {};
47 | char rebuild[92] = {};
48 | char hrp[84] = {};
49 | size_t data_len = 0;
50 | TEST_ASSERT(bech32_decode(hrp, data, &data_len, valid_checksum[i]) == 1);
51 | TEST_ASSERT(bech32_encode(rebuild, hrp, data, data_len) == 1);
52 | TEST_ASSERT(my_strncasecmp(rebuild, valid_checksum[i], 92) == 0);
53 | }
54 |
55 | for (size_t i = 0; i < sizeof(invalid_checksum) / sizeof(invalid_checksum[0]); ++i) {
56 | uint8_t data[82] = {};
57 | char hrp[84] = {};
58 | size_t data_len = 0;
59 | TEST_ASSERT(bech32_decode(hrp, data, &data_len, invalid_checksum[i]) == 0);
60 | }
61 | }
62 |
63 | int main() {
64 | UNITY_BEGIN();
65 |
66 | RUN_TEST(test_bech32_decode_encode);
67 |
68 | return UNITY_END();
69 | }
70 |
--------------------------------------------------------------------------------
/tests/crypto/pbkdf2_vectors.py:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env python3
2 |
3 | """
4 | Script to auto-generate PBKDF2 test vectors
5 | Usage: ./pbkdf2_vectors.py > pbkdf2_vectors.h
6 |
7 | Vectors from https://datatracker.ietf.org/doc/html/rfc6070
8 | """
9 |
10 | import sys
11 | import os.path
12 | import datetime
13 | import hashlib
14 |
15 |
16 | def print_vector(pwd, salt, iteration, dkLen):
17 | # key calculation
18 | vecSHA1 = hashlib.pbkdf2_hmac("sha1", pwd, salt, iteration, dkLen)
19 | vecSHA256 = hashlib.pbkdf2_hmac("sha256", pwd, salt, iteration, dkLen)
20 | vecSHA512 = hashlib.pbkdf2_hmac("sha512", pwd, salt, iteration, dkLen)
21 |
22 | # add as a struct element
23 | elm = ' {' + str(iteration) + ', ' + str(dkLen) + ',\n'
24 | elm = elm + ' "' + pwd.hex() + '",\n'
25 | elm = elm + ' "' + salt.hex() + '",\n'
26 | elm = elm + ' "' + vecSHA1.hex() + '",\n'
27 | elm = elm + ' "' + vecSHA256.hex() + '",\n'
28 | elm = elm + ' "' + vecSHA512.hex() + '"},'
29 | print(elm)
30 |
31 |
32 | def pbkdf2_vectors():
33 | print("/* ===auto-generated by " +
34 | os.path.basename(sys.argv[0]) + " DO NOT EDIT!!=== */\n")
35 | print("// Copyright " + str(datetime.datetime.now().year) + " IOTA Stiftung")
36 | print("// SPDX-License-Identifier: Apache-2.0\n")
37 | print("#ifndef __TEST_CRYPTO_PBKDF2_H__")
38 | print("#define __TEST_CRYPTO_PBKDF2_H__\n")
39 | print("#include \n")
40 | print("// PBKDF2 test vectors from https://datatracker.ietf.org/doc/html/rfc6070")
41 |
42 | vector_struct = """typedef struct {
43 | size_t iter; ///< iteration
44 | size_t dk_len; ///< length of derived key
45 | char *pwd; ///< point to the password
46 | char *salt; ///< point to the salt
47 | char *sha1; ///< derived key from sha1
48 | char *sha256; ///< derived key from sha256
49 | char *sha512; ///< derived key from sha512
50 | } pbkdf2_vector_t;
51 | """
52 | print(vector_struct)
53 |
54 | print('// clang-format off')
55 | print('static pbkdf2_vector_t pbkdf2[] = {')
56 | # test vectors
57 | print_vector(b"password", b"salt", 1, 20)
58 | print_vector(b"password", b"salt", 2, 20)
59 | print_vector(b"password", b"salt", 2, 16)
60 | print_vector(b"password", b"salt", 2, 32)
61 | print_vector(b"password", b"salt", 2, 64)
62 | print_vector(b"password", b"salt", 2, 127)
63 | print_vector(b"password", b"salt", 2, 128)
64 | print_vector(b"password", b"salt", 2, 129)
65 | print_vector(b"password", b"salt", 2, 256)
66 | print_vector(b"password", b"salt", 4096, 20)
67 | print_vector(b"passwordPASSWORDpassword",
68 | b"saltSALTsaltSALTsaltSALTsaltSALTsalt", 4096, 25)
69 | print_vector(b"pass\0word", b"sa\0lt", 4096, 16)
70 | print('};')
71 | print('// clang-format on\n')
72 | print("#endif\n")
73 |
74 |
75 | if __name__ == "__main__":
76 | pbkdf2_vectors()
77 |
--------------------------------------------------------------------------------
/tests/test_config.h:
--------------------------------------------------------------------------------
1 | // Copyright 2021 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #ifndef __TEST_CLIENT_API_CONFIG_H__
5 | #define __TEST_CLIENT_API_CONFIG_H__
6 |
7 | // Test with private tangle or not
8 | // Set to 1 for debugging individual test cases only
9 | #define TEST_TANGLE_ENABLE 0
10 |
11 | #define TEST_IS_HTTPS 0
12 | // Node
13 | #define TEST_NODE_HOST "localhost"
14 | #define TEST_NODE_PORT 14265
15 |
16 | // Faucet
17 | #define TEST_FAUCET_HOST "localhost"
18 | #define TEST_FAUCET_PORT 14265
19 |
20 | // MQTT
21 | #define TEST_EVENTS_HOST "localhost"
22 | #define TEST_EVENTS_PORT 1883
23 | #define TEST_EVENTS_CLIENT_ID "iota_test_2"
24 | #define TEST_EVENTS_KEEP_ALIVE 60
25 |
26 | #define TEST_TIMEOUT_SECONDS 30
27 |
28 | // Wallet
29 |
30 | // using SLIP44_COIN_TYPE_TEST as default coin type
31 | // uncomment one to choose another coin type
32 | // #define NETWORK_TYPE_SHIMMER
33 | // #define NETWORK_TYPE_MAINNET
34 |
35 | // predefined coin types
36 | #if defined(NETWORK_TYPE_SHIMMER)
37 | #define SLIP44_COIN_TYPE SLIP44_COIN_TYPE_SHIMMER
38 | #elif defined(NETWORK_TYPE_MAINNET)
39 | #define SLIP44_COIN_TYPE SLIP44_COIN_TYPE_IOTA
40 | #else
41 | #define SLIP44_COIN_TYPE SLIP44_COIN_TYPE_TEST
42 | #endif
43 |
44 | #endif
45 |
--------------------------------------------------------------------------------
/tests/wallet/test_bip39.c:
--------------------------------------------------------------------------------
1 | // Copyright 2022 IOTA Stiftung
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | #include "core/utils/byte_buffer.h"
9 | #include "unity/unity.h"
10 | #include "wallet/bip39.h"
11 |
12 | #include "mnemonic_vectors.h"
13 |
14 | // max entropy input size is 32
15 | #define ENT_BUF_LEN 32
16 | // depends on the chosen language
17 | #define MS_BUF_SIZE 1024
18 | // wrt bip39 spec, should be bigger than 33 bytes
19 | #define ENT_OUT_BUF_LEN 64
20 |
21 | // buffers used by test_bip39_en and test_bip39_languages
22 | byte_t entropy[ENT_BUF_LEN] = {};
23 | char ms_out[MS_BUF_SIZE] = {};
24 | char ms_zh_out[MS_BUF_SIZE] = {};
25 | byte_t out_ent[ENT_OUT_BUF_LEN] = {};
26 |
27 | void setUp(void) {}
28 |
29 | void tearDown(void) {}
30 |
31 | // validate encode/decode/ms with English
32 | void test_bip39_vectors() {
33 | for (size_t i = 0; i < sizeof(vectors) / sizeof(ms_vectors_t); i++) {
34 | printf("validating BIP39 vector[%zu]: %s\n", i, vectors[i].ent);
35 | // encode
36 | size_t entropy_str_len = strlen(vectors[i].ent);
37 | size_t entropy_bin_len = entropy_str_len / 2;
38 | hex_2_bin(vectors[i].ent, entropy_str_len, NULL, entropy, sizeof(entropy));
39 | mnemonic_encode(entropy, entropy_bin_len, MS_LAN_EN, ms_out, MS_BUF_SIZE);
40 | TEST_ASSERT_EQUAL_MEMORY(vectors[i].ms, ms_out, strlen(vectors[i].ms));
41 | printf("%s\n", ms_out);
42 |
43 | // decode
44 | size_t len = mnemonic_decode(ms_out, MS_LAN_EN, out_ent, sizeof(out_ent));
45 | TEST_ASSERT(len != 0);
46 | TEST_ASSERT_EQUAL_MEMORY(entropy, out_ent, entropy_bin_len);
47 | // dump_hex_str(out_ent, len);
48 | }
49 | }
50 |
51 | // validate encode/decode with other languages
52 | void test_bip39_languages() {
53 | #ifndef BIP39_ENGLISH_ONLY
54 | for (ms_lan_t lan = MS_LAN_KO; lan <= MS_LAN_PT; lan++) {
55 | printf("validating BIP39 language ID %d...\n", lan);
56 | for (size_t i = 0; i < sizeof(vectors) / sizeof(ms_vectors_t); i++) {
57 | printf("\tBIP39 vector[%zu]: %s\n", i, vectors[i].ent);
58 | // encode
59 | size_t entropy_str_len = strlen(vectors[i].ent);
60 | size_t entropy_bin_len = entropy_str_len / 2;
61 | TEST_ASSERT(hex_2_bin(vectors[i].ent, entropy_str_len, NULL, entropy, sizeof(entropy)) == 0);
62 | TEST_ASSERT(mnemonic_encode(entropy, entropy_bin_len, lan, ms_out, MS_BUF_SIZE) == 0);
63 | printf("\t%s\n", ms_out);
64 | // decode
65 | size_t len = mnemonic_decode(ms_out, lan, out_ent, sizeof(out_ent));
66 | TEST_ASSERT(len != 0);
67 | // we don't check the ms but validate encode/decode entropy
68 | TEST_ASSERT_EQUAL_MEMORY(entropy, out_ent, entropy_bin_len);
69 | }
70 | }
71 | #endif
72 | }
73 |
74 | void test_bip39_seed() {
75 | byte_t seed[64] = {};
76 | byte_t exp_seed[64] = {};
77 | for (size_t i = 0; i < sizeof(vectors) / sizeof(ms_vectors_t); i++) {
78 | TEST_ASSERT(mnemonic_to_seed(vectors[i].ms, "TREZOR", seed, sizeof(seed)) == 0);
79 | hex_2_bin(vectors[i].seed, strlen(vectors[i].seed), NULL, exp_seed, sizeof(exp_seed));
80 | TEST_ASSERT_EQUAL_MEMORY(exp_seed, seed, sizeof(exp_seed));
81 | }
82 | }
83 |
84 | int main() {
85 | UNITY_BEGIN();
86 |
87 | RUN_TEST(test_bip39_vectors);
88 | RUN_TEST(test_bip39_languages);
89 | RUN_TEST(test_bip39_seed);
90 |
91 | return UNITY_END();
92 | }
93 |
--------------------------------------------------------------------------------
/tools/ci_format_check:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | root=$(git rev-parse --show-toplevel)
4 | status=0
5 |
6 | # dump tool versions
7 | clang_fmt_version=$(clang-format-12 --version)
8 | echo -e "\e[32m${clang_fmt_version} \e[39m"
9 | cmake_fmt_version=$(cmake-format --version)
10 | echo -e "\e[32mcmake-format version ${cmake_fmt_version} \e[39m"
11 |
12 | # check source files
13 | for file in $(find "${@}" -type f | grep -E "\.(c|cc|cpp|h|hh|hpp)\$")
14 | do
15 | filepath="$root/$file"
16 | output=$(diff <(cat $filepath) <(clang-format-12 -style=file -fallback-style=none $filepath))
17 | if [ $? -ne 0 ]
18 | then
19 | echo -e "\nFile \e[31m\""$file"\"\e[39m is not compliant with the coding style"
20 | echo "$output"
21 | status=1
22 | fi
23 | done
24 |
25 | # checking CMake scripts
26 | for file in $(find ${root} ! -path "*/build/*"| grep -E "CMakeLists.txt")
27 | do
28 | cmake-format -c ${root}/.cmake_format.yaml --check ${file} 2> /dev/null
29 | if [ $? -ne 0 ]
30 | then
31 | echo -e "\nFile \e[31m\""$file"\"\e[39m is not compliant with cmake-format"
32 | echo "$output"
33 | status=2
34 | fi
35 | done
36 |
37 | exit $status
38 |
--------------------------------------------------------------------------------
/tools/formatter:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | project_root=$(git rev-parse --show-toplevel)
3 | for file in $(find ${project_root} ! -path "*/build/*" | grep -E "\.(c|cc|cpp|h|hh|hpp|m|mm)\$")
4 | do
5 | clang-format -style=file -fallback-style=none -i ${file}
6 | done
7 |
8 | for file in $(find ${project_root} ! -path "*/build/*"| grep -E "CMakeLists.txt")
9 | do
10 | cmake-format -c ${project_root}/.cmake_format.yaml -i ${file}
11 | done
12 |
--------------------------------------------------------------------------------
/tools/hooks/pre-commit/01-format-check:
--------------------------------------------------------------------------------
1 | ../scripts/format_check
--------------------------------------------------------------------------------
/tools/hooks/scripts/format_check:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | root=$(git rev-parse --show-toplevel)
4 | status=0
5 | for file in $(git diff --staged --name-only | grep -E "^(src|tests|examples)" | grep -E "\.(c|cc|cpp|h|hh|hpp)\$")
6 | do
7 | filepath="$root/$file"
8 | output=$(diff <(cat $filepath) <(clang-format -style=file -fallback-style=none $filepath))
9 | if [ $? -ne 0 ]
10 | then
11 | echo -e "\nFile \""$file"\" is not compliant with the coding style"
12 | echo "$output"
13 | status=1
14 | fi
15 | done
16 | exit $status
17 |
--------------------------------------------------------------------------------