├── .github ├── dependabot.yml └── workflows │ └── pr-checks.yml ├── .gitignore ├── .gitmodules ├── .nvmrc ├── Cargo.toml ├── LICENSE ├── LICENSE-EMURGO ├── LICENSE-IOHK ├── README.md ├── README.rst ├── build-and-test.sh ├── chain ├── README.md ├── rust │ ├── Cargo.toml │ └── src │ │ ├── address.rs │ │ ├── assets │ │ ├── cbor_encodings.rs │ │ ├── mod.rs │ │ ├── serialization.rs │ │ └── utils.rs │ │ ├── auxdata │ │ ├── cbor_encodings.rs │ │ ├── metadata.rs │ │ ├── mod.rs │ │ ├── serialization.rs │ │ └── utils.rs │ │ ├── block │ │ ├── cbor_encodings.rs │ │ ├── mod.rs │ │ └── serialization.rs │ │ ├── builders │ │ ├── certificate_builder.rs │ │ ├── input_builder.rs │ │ ├── mint_builder.rs │ │ ├── mod.rs │ │ ├── output_builder.rs │ │ ├── proposal_builder.rs │ │ ├── redeemer_builder.rs │ │ ├── tx_builder.rs │ │ ├── utils.rs │ │ ├── vote_builder.rs │ │ ├── withdrawal_builder.rs │ │ └── witness_builder.rs │ │ ├── byron │ │ ├── base58.rs │ │ ├── crc32.rs │ │ ├── mod.rs │ │ ├── serialization.rs │ │ └── utils.rs │ │ ├── cbor_encodings.rs │ │ ├── certs │ │ ├── cbor_encodings.rs │ │ ├── mod.rs │ │ ├── serialization.rs │ │ └── utils.rs │ │ ├── crypto │ │ ├── cbor_encodings.rs │ │ ├── hash.rs │ │ ├── mod.rs │ │ ├── serialization.rs │ │ └── utils.rs │ │ ├── deposit.rs │ │ ├── fees.rs │ │ ├── genesis │ │ ├── byron │ │ │ ├── config.rs │ │ │ ├── mod.rs │ │ │ ├── parse.rs │ │ │ ├── raw.rs │ │ │ └── test_data │ │ │ │ ├── 5f20df933584822601f9e3f8c024eb5eb252fe8cefb24d1317dc3d432e940ebb.json │ │ │ │ ├── 96fceff972c2c06bd3bb5243c39215333be6d56aaf4823073dca31afe5038471.json │ │ │ │ ├── b7f76950bc4866423538ab7764fc1c7020b24a5f717a5bee3109ff2796567214.json │ │ │ │ └── c6a004d3d178f600cd8caa10abbebe1549bef878f0665aea2903472d5abf7323.json │ │ ├── mod.rs │ │ ├── network_info.rs │ │ └── shelley │ │ │ ├── config.rs │ │ │ ├── mod.rs │ │ │ ├── parse.rs │ │ │ ├── raw.rs │ │ │ └── test_data │ │ │ ├── test-yaci.json │ │ │ └── test.json │ │ ├── governance │ │ ├── cbor_encodings.rs │ │ ├── mod.rs │ │ ├── serialization.rs │ │ └── utils.rs │ │ ├── json │ │ ├── json_serialize.rs │ │ ├── metadatums.rs │ │ ├── mod.rs │ │ └── plutus_datums.rs │ │ ├── legacy_address │ │ └── hdpayload.rs │ │ ├── lib.rs │ │ ├── min_ada.rs │ │ ├── plutus │ │ ├── cbor_encodings.rs │ │ ├── mod.rs │ │ ├── serialization.rs │ │ └── utils.rs │ │ ├── serialization.rs │ │ ├── transaction │ │ ├── cbor_encodings.rs │ │ ├── mod.rs │ │ ├── serialization.rs │ │ └── utils.rs │ │ └── utils.rs └── wasm │ ├── Cargo.toml │ ├── README.md │ ├── json-gen │ ├── Cargo.toml │ ├── custom_schemas │ │ ├── PlutusData │ │ └── TransactionMetadatum │ └── src │ │ ├── lib.rs │ │ └── main.rs │ └── src │ ├── address.rs │ ├── assets │ ├── mod.rs │ └── utils.rs │ ├── auxdata │ ├── metadata.rs │ ├── mod.rs │ └── utils.rs │ ├── block │ └── mod.rs │ ├── builders │ ├── certificate_builder.rs │ ├── input_builder.rs │ ├── mint_builder.rs │ ├── mod.rs │ ├── output_builder.rs │ ├── proposal_builder.rs │ ├── redeemer_builder.rs │ ├── tx_builder.rs │ ├── vote_builder.rs │ ├── withdrawal_builder.rs │ └── witness_builder.rs │ ├── byron │ ├── crc32.rs │ ├── mod.rs │ └── utils.rs │ ├── certs │ ├── mod.rs │ └── utils.rs │ ├── crypto │ ├── hash.rs │ ├── mod.rs │ └── utils.rs │ ├── deposit.rs │ ├── fees.rs │ ├── genesis │ ├── mod.rs │ └── network_info.rs │ ├── governance │ ├── mod.rs │ └── utils.rs │ ├── json │ ├── metadatums.rs │ ├── mod.rs │ └── plutus_datums.rs │ ├── lib.rs │ ├── min_ada.rs │ ├── plutus │ ├── mod.rs │ └── utils.rs │ ├── transaction │ ├── mod.rs │ └── utils.rs │ └── utils.rs ├── cip25 ├── .gitignore ├── rust │ ├── Cargo.toml │ └── src │ │ ├── lib.rs │ │ ├── serialization.rs │ │ └── utils.rs └── wasm │ ├── Cargo.toml │ ├── README.md │ ├── json-gen │ ├── Cargo.toml │ └── src │ │ ├── lib.rs │ │ └── main.rs │ └── src │ ├── lib.rs │ └── utils.rs ├── cip36 ├── rust │ ├── Cargo.toml │ └── src │ │ ├── cbor_encodings.rs │ │ ├── error.rs │ │ ├── lib.rs │ │ ├── serialization.rs │ │ └── utils.rs └── wasm │ ├── Cargo.toml │ ├── json-gen │ ├── Cargo.toml │ └── src │ │ ├── lib.rs │ │ └── main.rs │ └── src │ ├── lib.rs │ └── utils.rs ├── cml ├── README.md └── wasm │ ├── Cargo.toml │ ├── json-gen │ ├── Cargo.toml │ └── src │ │ └── main.rs │ ├── package.json │ └── src │ └── lib.rs ├── core ├── README.md ├── rust │ ├── Cargo.toml │ └── src │ │ ├── error.rs │ │ ├── lib.rs │ │ ├── network.rs │ │ ├── ordered_hash_map.rs │ │ └── serialization.rs └── wasm │ ├── Cargo.toml │ └── src │ ├── lib.rs │ └── wasm_wrappers.rs ├── crypto ├── README.md ├── rust │ ├── Cargo.toml │ └── src │ │ ├── chain_core │ │ ├── abor.rs │ │ ├── mempack.rs │ │ ├── mod.rs │ │ ├── packer.rs │ │ └── property.rs │ │ ├── chain_crypto │ │ ├── algorithms │ │ │ ├── ed25519.rs │ │ │ ├── ed25519_derive.rs │ │ │ ├── ed25519_extended.rs │ │ │ ├── legacy_daedalus.rs │ │ │ └── mod.rs │ │ ├── bech32.rs │ │ ├── byron_proxy_key.rs │ │ ├── byron_tags.rs │ │ ├── derive.rs │ │ ├── digest.rs │ │ ├── hash.rs │ │ ├── key.rs │ │ ├── mod.rs │ │ ├── securemem.rs │ │ ├── sign.rs │ │ └── testing.rs │ │ ├── emip3.rs │ │ ├── impl_mockchain │ │ ├── key.rs │ │ └── mod.rs │ │ ├── lib.rs │ │ └── typed_bytes │ │ ├── builder.rs │ │ └── mod.rs └── wasm │ ├── Cargo.toml │ ├── README.md │ └── src │ ├── emip3.rs │ └── lib.rs ├── docs ├── .gitattributes ├── .gitignore ├── README.md ├── babel.config.js ├── crowdin.yml ├── docs │ ├── crate_architecture.mdx │ ├── enums.mdx_bak │ ├── getting_started.mdx │ ├── index.md │ ├── modules │ │ ├── CIP25.mdx │ │ ├── _category_.json │ │ ├── builders │ │ │ ├── _category_.json │ │ │ ├── generating_transactions.mdx │ │ │ └── index.mdx │ │ ├── cbor.mdx │ │ ├── chain │ │ │ ├── _category_.json │ │ │ └── index.md │ │ ├── cip36.mdx │ │ ├── core │ │ │ ├── _category_.json │ │ │ └── index.md │ │ ├── crypto │ │ │ ├── _category_.json │ │ │ ├── generating_keys.mdx │ │ │ └── index.mdx │ │ ├── json.mdx │ │ ├── metadata.mdx │ │ ├── multi-era │ │ │ ├── _category_.json │ │ │ └── index.md │ │ └── wasm.mdx │ └── type_definitions.mdx_bak ├── docusaurus.config.js ├── package.json ├── postcss.config.js ├── sidebars.js ├── src │ ├── css │ │ └── custom.css │ └── fonts │ │ ├── Manrope-Bold.ttf │ │ ├── Manrope-Light.ttf │ │ ├── Manrope-Medium.ttf │ │ ├── Manrope-Regular.ttf │ │ └── Manrope-SemiBold.ttf ├── static │ ├── icons │ │ ├── danger-icon.svg │ │ └── info-icon.svg │ └── img │ │ ├── favicon.svg │ │ ├── output.png │ │ ├── output2.png │ │ ├── output3.png │ │ ├── output4.png │ │ └── output5.png ├── tailwind.config.js └── yarn.lock ├── example ├── .eslintrc.js ├── .gitignore ├── .mocharc.js ├── index.spec.ts ├── index.ts ├── package-lock.json ├── package.json ├── tsconfig.json └── wallaby.conf.js ├── examples └── wasm-browser │ ├── README.md │ ├── bootstrap.js │ ├── favicon.ico │ ├── index.html │ ├── index.js │ ├── package-lock.json │ ├── package.json │ └── webpack.config.js ├── multi-era ├── rust │ ├── Cargo.toml │ └── src │ │ ├── allegra │ │ ├── cbor_encodings.rs │ │ ├── mod.rs │ │ ├── serialization.rs │ │ └── utils.rs │ │ ├── alonzo │ │ ├── cbor_encodings.rs │ │ ├── mod.rs │ │ ├── serialization.rs │ │ └── utils.rs │ │ ├── babbage │ │ ├── cbor_encodings.rs │ │ ├── mod.rs │ │ ├── serialization.rs │ │ └── utils.rs │ │ ├── byron │ │ ├── block │ │ │ ├── mod.rs │ │ │ └── serialization.rs │ │ ├── delegation │ │ │ ├── mod.rs │ │ │ └── serialization.rs │ │ ├── mod.rs │ │ ├── mpc │ │ │ ├── mod.rs │ │ │ └── serialization.rs │ │ ├── serialization.rs │ │ ├── transaction │ │ │ ├── mod.rs │ │ │ ├── serialization.rs │ │ │ └── utils.rs │ │ ├── update │ │ │ ├── mod.rs │ │ │ └── serialization.rs │ │ └── utils.rs │ │ ├── lib.rs │ │ ├── mary │ │ ├── cbor_encodings.rs │ │ ├── mod.rs │ │ ├── serialization.rs │ │ └── utils.rs │ │ ├── serialization.rs │ │ ├── shelley │ │ ├── cbor_encodings.rs │ │ ├── mod.rs │ │ ├── serialization.rs │ │ └── utils.rs │ │ └── utils.rs └── wasm │ ├── Cargo.toml │ ├── json-gen │ ├── Cargo.toml │ └── src │ │ ├── lib.rs │ │ └── main.rs │ ├── package.json │ └── src │ ├── allegra │ └── mod.rs │ ├── alonzo │ └── mod.rs │ ├── babbage │ └── mod.rs │ ├── byron │ ├── block │ │ └── mod.rs │ ├── delegation │ │ └── mod.rs │ ├── mod.rs │ ├── mpc │ │ └── mod.rs │ ├── transaction │ │ └── mod.rs │ ├── update │ │ └── mod.rs │ └── utils.rs │ ├── lib.rs │ ├── mary │ └── mod.rs │ ├── shelley │ └── mod.rs │ └── utils.rs ├── package-lock.json ├── package.json ├── release.sh ├── scripts ├── .eslintrc.js ├── json-ts-types.js ├── legacy │ └── wasm-to-asm.js ├── publish-helper.js ├── run-json2ts.js └── wasm-to-asm.js ├── specs ├── README.md ├── byron.cddl ├── byron_minimal.cddl ├── cip25.cddl ├── cip36.cddl ├── conway │ ├── address.cddl │ ├── assets.cddl │ ├── auxdata.cddl │ ├── block.cddl │ ├── certs.cddl │ ├── crypto.cddl │ ├── governance.cddl │ ├── lib.cddl │ ├── plutus.cddl │ └── transaction.cddl ├── multiera-byron │ ├── byron │ │ ├── block.cddl │ │ ├── delegation.cddl │ │ ├── mod.cddl │ │ ├── mpc.cddl │ │ ├── transaction.cddl │ │ └── update.cddl │ ├── cml_chain │ │ └── byron.cddl │ └── lib.cddl ├── multiera │ ├── _CDDL_CODEGEN_EXTERN_DEPS_DIR_ │ │ └── cml_chain │ │ │ ├── address.cddl │ │ │ ├── assets.cddl │ │ │ ├── auxdata.cddl │ │ │ ├── block.cddl │ │ │ ├── byron.cddl │ │ │ ├── certs.cddl │ │ │ ├── crypto.cddl │ │ │ ├── mod.cddl │ │ │ ├── plutus.cddl │ │ │ └── transaction.cddl │ ├── allegra │ │ └── mod.cddl │ ├── alonzo │ │ └── mod.cddl │ ├── babbage │ │ └── mod.cddl │ ├── lib.cddl │ ├── mary │ │ └── mod.cddl │ └── shelley │ │ └── mod.cddl └── shelley.cddl ├── test.sh ├── test ├── 1.cbor └── 1.diag └── tools ├── metadata-cddl-checker ├── Cargo.toml └── src │ └── main.rs └── plutus-datum-codegen ├── Cargo.toml ├── README.md ├── prelude ├── _CDDL_CODEGEN_EXTERN_DEPS_DIR_ │ └── cml_chain │ │ ├── address.cddl │ │ ├── assets.cddl │ │ ├── auxdata.cddl │ │ ├── crypto.cddl │ │ ├── lib.cddl │ │ ├── plutus.cddl │ │ └── transaction.cddl └── prelude.cddl └── src ├── cli.rs ├── dep_graph.rs ├── main.rs └── utils.rs /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: cargo 4 | directory: "/rust" 5 | schedule: 6 | interval: monthly 7 | timezone: PST8PDT 8 | open-pull-requests-limit: 99 9 | ignore: 10 | - dependency-name: wasm-bindgen 11 | versions: 12 | - 0.2.69 13 | - 0.2.70 14 | - dependency-name: cryptoxide 15 | versions: 16 | - 0.3.0 17 | - dependency-name: serde_json 18 | versions: 19 | - 1.0.61 20 | rebase-strategy: disabled 21 | -------------------------------------------------------------------------------- /.github/workflows/pr-checks.yml: -------------------------------------------------------------------------------- 1 | name: PR Checks 2 | 3 | on: 4 | push: 5 | branches: [ develop ] 6 | pull_request: 7 | branches: [ develop ] 8 | 9 | jobs: 10 | test-and-build: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v2 14 | with: 15 | submodules: 'recursive' 16 | - uses: actions/setup-node@v4 17 | with: 18 | node-version: 'lts/iron' 19 | - name: Cache node modules 20 | uses: actions/cache@v1 21 | with: 22 | path: ~/.npm # npm cache files are stored in `~/.npm` on Linux/macOS 23 | key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} 24 | restore-keys: | 25 | ${{ runner.os }}-build-${{ env.cache-name }}- 26 | ${{ runner.os }}-build- 27 | ${{ runner.os }}- 28 | - name: prepare-rust 29 | run: | 30 | rustup install stable 31 | rustup target add wasm32-unknown-unknown --toolchain stable 32 | curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh 33 | - name: install 34 | run: | 35 | npm install 36 | - name: rust:test 37 | run: | 38 | npm run rust:test 39 | - name: rust:build-nodejs 40 | run: | 41 | npm run rust:build-nodejs 42 | - name: rust:build-browser 43 | run: | 44 | npm run rust:build-browser 45 | - name: cargo-fmt 46 | uses: actions-rs/cargo@v1 47 | with: 48 | command: fmt 49 | args: --all -- --check 50 | - name: cargo-clippy 51 | uses: actions-rs/cargo@v1 52 | with: 53 | command: clippy 54 | args: --workspace --all-features --all-targets -- --deny "clippy::all" 55 | - name: all:test 56 | run: cargo test 57 | - name: cml:install 58 | working-directory: cml/wasm 59 | run: npm install 60 | - name: cml:rust:build-nodejs 61 | working-directory: cml/wasm 62 | run: npm run rust:build-nodejs 63 | - name: cml:rust:build-browser 64 | working-directory: cml/wasm 65 | run: npm run rust:build-browser 66 | - name: multi-era:install 67 | working-directory: multi-era/wasm 68 | run: npm install 69 | - name: multi-era:rust:build-nodejs 70 | working-directory: multi-era/wasm 71 | run: npm run rust:build-nodejs 72 | - name: multi-era:rust:build-browser 73 | working-directory: multi-era/wasm 74 | run: npm run rust:build-browser 75 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Legacy code 2 | node_modules/ 3 | publish/ 4 | rust/target 5 | .vscode/ 6 | .idea 7 | rust/.idea 8 | binaryen/ 9 | 10 | target/ 11 | 12 | 13 | # New split architecture 14 | Cargo.lock 15 | 16 | chain/rust/target/** 17 | chain/rust/Cargo.lock 18 | chain/wasm/target/** 19 | chain/wasm/Cargo.lock 20 | chain/wasm/pkg/** 21 | chain/wasm/json-gen/target/** 22 | chain/wasm/json-gen/output/** 23 | chain/wasm/json-gen/schemas/** 24 | 25 | cip25/rust/target/** 26 | cip25/rust/Cargo.lock 27 | cip25/wasm/target/** 28 | cip25/wasm/Cargo.lock 29 | cip25/wasm/pkg/** 30 | cip25/wasm/json-gen/target/** 31 | cip25/wasm/json-gen/output/** 32 | cip25/wasm/json-gen/schemas/** 33 | 34 | cip36/rust/target/** 35 | cip36/rust/Cargo.lock 36 | cip36/wasm/target/** 37 | cip36/wasm/Cargo.lock 38 | cip36/wasm/pkg/** 39 | cip36/wasm/json-gen/target/** 40 | cip36/wasm/json-gen/output/** 41 | cip36/wasm/json-gen/schemas/** 42 | 43 | core/rust/target/** 44 | core/rust/Cargo.lock 45 | core/wasm/target/** 46 | core/wasm/Cargo.lock 47 | core/wasm/pkg/** 48 | 49 | crypto/rust/target/** 50 | crypto/rust/Cargo.lock 51 | crypto/wasm/target/** 52 | crypto/wasm/Cargo.lock 53 | crypto/wasm/pkg/** 54 | 55 | multi-era/rust/target/** 56 | multi-era/rust/Cargo.lock 57 | multi-era/wasm/target/** 58 | multi-era/wasm/Cargo.lock 59 | multi-era/wasm/pkg/** 60 | multi-era/wasm/json-gen/target/** 61 | multi-era/wasm/json-gen/output/** 62 | multi-era/wasm/json-gen/schemas/** 63 | multi-era/wasm/node_modules/** 64 | 65 | cml/wasm/json-gen/target/** 66 | cml/wasm/json-gen/output/** 67 | cml/wasm/json-gen/schemas/** 68 | cml/wasm/node_modules/** 69 | 70 | tools/metadata-cddl-checker/Cargo.lock 71 | 72 | # Docs 73 | docs/node_modules/ 74 | docs/.docusaurus/ 75 | 76 | # Examples 77 | examples/wasm-browser/node_modules/ 78 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "binaryen"] 2 | path = binaryen 3 | url = https://github.com/WebAssembly/binaryen.git 4 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | lts/iron -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | 3 | # this is for the new crate structure. The legacy code (current CML) still resides in the `rust` directory. 4 | members = [ 5 | "chain/rust", 6 | "chain/wasm", 7 | "chain/wasm/json-gen", 8 | "cip25/rust", 9 | "cip25/wasm", 10 | "cip25/wasm/json-gen", 11 | "cip36/rust", 12 | "cip36/wasm", 13 | "cip36/wasm/json-gen", 14 | "cml/wasm", 15 | "cml/wasm/json-gen", 16 | "core/rust", 17 | "core/wasm", 18 | "crypto/rust", 19 | "crypto/wasm", 20 | "multi-era/rust", 21 | "multi-era/wasm", 22 | "multi-era/wasm/json-gen" 23 | ] 24 | 25 | # exclude old crate structure to avoid error in it 26 | exclude = [ 27 | "rust", 28 | "rust/json-gen", 29 | "tools/metadata-cddl-checker", 30 | "tools/plutus-datum-codegen" 31 | ] 32 | 33 | [profile.release] 34 | lto = true 35 | opt-level = "z" -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 dcSpark 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /LICENSE-EMURGO: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 EMURGO 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | Includes other software related under the MIT license: 24 | - chain-libs, Copyright 2018-2019 IOHK. For licensing see /LICENSE-IOHK 25 | -------------------------------------------------------------------------------- /LICENSE-IOHK: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018-2019 Input Output HK 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Cardano Multiplatform Lib 2 | 3 | This is a library, written in Rust, that can be deployed to multiple platforms (Rust crate, JS, Typescript, WASM, etc). It handles: 4 | - Serialization & deserialization of core data structures 5 | - Useful utility functions for dApps & wallets 6 | 7 | ##### NPM packages 8 | 9 | - browser: [link](https://www.npmjs.com/package/@dcspark/cardano-multiplatform-lib-browser) 10 | - nodejs: [link](https://www.npmjs.com/package/@dcspark/cardano-multiplatform-lib-nodejs) 11 | - asm.js (strongly discouraged): [link](https://www.npmjs.com/package/@dcspark/cardano-multiplatform-lib-asmjs) 12 | 13 | ##### Rust crates 14 | 15 | - crates: [link](https://crates.io/crates/cardano-multiplatform-lib) 16 | 17 | ##### Mobile bindings 18 | 19 | We recommend using Ionic + Capacitor or an equivalent setup to have the WASM bindings working in mobile 20 | 21 | ## Documentation 22 | 23 | https://dcSpark.github.io/cardano-multiplatform-lib/ 24 | 25 | -------------------------------------------------------------------------------- /build-and-test.sh: -------------------------------------------------------------------------------- 1 | set -eu 2 | . test.sh && npm run rust:build-nodejs -------------------------------------------------------------------------------- /chain/README.md: -------------------------------------------------------------------------------- 1 | # Chain 2 | 3 | This is the core cardano-multiplatform-lib crate for all on-chain data types. 4 | This was generated from the `specs/babbage/` CDDL specs using cddl-codegen. 5 | -------------------------------------------------------------------------------- /chain/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cml-chain" 3 | version = "6.2.0" 4 | edition = "2018" 5 | authors = ["dcSpark"] 6 | license = "MIT" 7 | description = "Multiplatform SDK for main Cardano blockchain functionality" 8 | documentation = "https://github.com/dcSpark/cardano-multiplatform-lib/docs" 9 | repository = "https://github.com/dcSpark/cardano-multiplatform-lib" 10 | readme = "../../README.md" 11 | keywords = ["cardano"] 12 | 13 | [lib] 14 | crate-type = ["cdylib", "rlib"] 15 | 16 | [features] 17 | used_from_wasm = ["wasm-bindgen"] 18 | 19 | [dependencies] 20 | cml-core = { "path" = "../../core/rust", version = "6.2.0" } 21 | cml-crypto = { "path" = "../../crypto/rust", version = "6.2.0" } 22 | cbor_event = "2.2.0" 23 | linked-hash-map = "0.5.3" 24 | derivative = "2.2.0" 25 | serde = { version = "1.0", features = ["derive"] } 26 | serde_json = { version = "1.0.57", features = ["arbitrary_precision"] } 27 | schemars = "0.8.8" 28 | 29 | bech32 = "0.7.2" 30 | hex = "0.4.0" 31 | itertools = "0.10.1" 32 | getrandom = { version = "0.2.3", features = ["js"] } 33 | rand = "0.8.5" 34 | fraction = "0.10.0" 35 | base64 = "0.21.5" 36 | num-bigint = "0.4.0" 37 | num-integer = "0.1.45" 38 | thiserror = "1.0.37" 39 | num = "0.4" 40 | unicode-segmentation = "1.10.1" 41 | chrono = "0.4.38" 42 | 43 | # non-wasm 44 | noop_proc_macro = { version = "0.3.0", optional = false } 45 | 46 | # wasm 47 | wasm-bindgen = { version = "0.2.87", optional = true } 48 | 49 | 50 | [dev-dependencies] 51 | quickcheck = "0.9.2" 52 | quickcheck_macros = "0.9.1" 53 | rand_chacha = "0.3.1" 54 | flaky_test = "0.1.0" 55 | -------------------------------------------------------------------------------- /chain/rust/src/assets/cbor_encodings.rs: -------------------------------------------------------------------------------- 1 | // This file was code-generated using an experimental CDDL to rust tool: 2 | // https://github.com/dcSpark/cddl-codegen 3 | 4 | use cml_core::serialization::StringEncoding; 5 | 6 | #[derive(Clone, Debug, Default)] 7 | pub struct AssetNameEncoding { 8 | pub inner_encoding: StringEncoding, 9 | } 10 | -------------------------------------------------------------------------------- /chain/rust/src/assets/serialization.rs: -------------------------------------------------------------------------------- 1 | // This file was code-generated using an experimental CDDL to rust tool: 2 | // https://github.com/dcSpark/cddl-codegen 3 | 4 | use super::cbor_encodings::*; 5 | use super::*; 6 | use cbor_event::de::Deserializer; 7 | use cbor_event::se::Serializer; 8 | use cml_core::error::*; 9 | use cml_core::serialization::*; 10 | use std::io::{BufRead, Seek, Write}; 11 | 12 | impl Serialize for AssetName { 13 | fn serialize<'se, W: Write>( 14 | &self, 15 | serializer: &'se mut Serializer, 16 | force_canonical: bool, 17 | ) -> cbor_event::Result<&'se mut Serializer> { 18 | serializer.write_bytes_sz( 19 | &self.inner, 20 | self.encodings 21 | .as_ref() 22 | .map(|encs| encs.inner_encoding.clone()) 23 | .unwrap_or_default() 24 | .to_str_len_sz(self.inner.len() as u64, force_canonical), 25 | ) 26 | } 27 | } 28 | 29 | impl Deserialize for AssetName { 30 | fn deserialize(raw: &mut Deserializer) -> Result { 31 | let (inner, inner_encoding) = raw 32 | .bytes_sz() 33 | .map(|(bytes, enc)| (bytes, StringEncoding::from(enc)))?; 34 | if inner.len() > 32 { 35 | return Err(DeserializeError::new( 36 | "AssetName", 37 | DeserializeFailure::RangeCheck { 38 | found: inner.len() as isize, 39 | min: Some(0), 40 | max: Some(32), 41 | }, 42 | )); 43 | } 44 | Ok(Self { 45 | inner, 46 | encodings: Some(AssetNameEncoding { inner_encoding }), 47 | }) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /chain/rust/src/auxdata/cbor_encodings.rs: -------------------------------------------------------------------------------- 1 | // This file was code-generated using an experimental CDDL to rust tool: 2 | // https://github.com/dcSpark/cddl-codegen 3 | 4 | use cml_core::serialization::LenEncoding; 5 | 6 | #[derive(Clone, Debug, Default)] 7 | pub struct ConwayFormatAuxDataEncoding { 8 | pub len_encoding: LenEncoding, 9 | pub tag_encoding: Option, 10 | pub orig_deser_order: Vec, 11 | pub metadata_key_encoding: Option, 12 | pub native_scripts_encoding: LenEncoding, 13 | pub native_scripts_key_encoding: Option, 14 | pub plutus_v1_scripts_encoding: LenEncoding, 15 | pub plutus_v1_scripts_key_encoding: Option, 16 | pub plutus_v2_scripts_encoding: LenEncoding, 17 | pub plutus_v2_scripts_key_encoding: Option, 18 | pub plutus_v3_scripts_encoding: LenEncoding, 19 | pub plutus_v3_scripts_key_encoding: Option, 20 | } 21 | 22 | #[derive(Clone, Debug, Default)] 23 | pub struct ShelleyMAFormatAuxDataEncoding { 24 | pub len_encoding: LenEncoding, 25 | pub auxiliary_scripts_encoding: LenEncoding, 26 | } 27 | -------------------------------------------------------------------------------- /chain/rust/src/auxdata/mod.rs: -------------------------------------------------------------------------------- 1 | // This file was code-generated using an experimental CDDL to rust tool: 2 | // https://github.com/dcSpark/cddl-codegen 3 | 4 | pub mod cbor_encodings; 5 | pub mod metadata; 6 | pub mod serialization; 7 | pub mod utils; 8 | 9 | use crate::plutus::{PlutusV1Script, PlutusV2Script, PlutusV3Script}; 10 | use crate::transaction::NativeScript; 11 | use cbor_encodings::{ConwayFormatAuxDataEncoding, ShelleyMAFormatAuxDataEncoding}; 12 | 13 | pub use metadata::*; 14 | 15 | #[derive(Clone, Debug, serde::Deserialize, serde::Serialize, schemars::JsonSchema)] 16 | pub enum AuxiliaryData { 17 | Shelley(ShelleyFormatAuxData), 18 | ShelleyMA(ShelleyMAFormatAuxData), 19 | Conway(ConwayFormatAuxData), 20 | } 21 | 22 | impl AuxiliaryData { 23 | pub fn new_shelley(shelley: ShelleyFormatAuxData) -> Self { 24 | Self::Shelley(shelley) 25 | } 26 | 27 | pub fn new_shelley_ma(shelley_ma: ShelleyMAFormatAuxData) -> Self { 28 | Self::ShelleyMA(shelley_ma) 29 | } 30 | 31 | pub fn new_conway(conway: ConwayFormatAuxData) -> Self { 32 | Self::Conway(conway) 33 | } 34 | } 35 | 36 | #[derive(Clone, Debug, serde::Deserialize, serde::Serialize, schemars::JsonSchema)] 37 | pub struct ConwayFormatAuxData { 38 | pub metadata: Option, 39 | pub native_scripts: Option>, 40 | pub plutus_v1_scripts: Option>, 41 | pub plutus_v2_scripts: Option>, 42 | pub plutus_v3_scripts: Option>, 43 | #[serde(skip)] 44 | pub encodings: Option, 45 | } 46 | 47 | impl ConwayFormatAuxData { 48 | pub fn new() -> Self { 49 | Self { 50 | metadata: None, 51 | native_scripts: None, 52 | plutus_v1_scripts: None, 53 | plutus_v2_scripts: None, 54 | plutus_v3_scripts: None, 55 | encodings: None, 56 | } 57 | } 58 | } 59 | 60 | impl Default for ConwayFormatAuxData { 61 | fn default() -> Self { 62 | Self::new() 63 | } 64 | } 65 | 66 | pub type ShelleyFormatAuxData = Metadata; 67 | 68 | #[derive(Clone, Debug, serde::Deserialize, serde::Serialize, schemars::JsonSchema)] 69 | pub struct ShelleyMAFormatAuxData { 70 | pub transaction_metadata: Metadata, 71 | pub auxiliary_scripts: Vec, 72 | #[serde(skip)] 73 | pub encodings: Option, 74 | } 75 | 76 | impl ShelleyMAFormatAuxData { 77 | pub fn new(transaction_metadata: Metadata, auxiliary_scripts: Vec) -> Self { 78 | Self { 79 | transaction_metadata, 80 | auxiliary_scripts, 81 | encodings: None, 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /chain/rust/src/block/cbor_encodings.rs: -------------------------------------------------------------------------------- 1 | // This file was code-generated using an experimental CDDL to rust tool: 2 | // https://github.com/dcSpark/cddl-codegen 3 | 4 | use cml_core::serialization::{LenEncoding, StringEncoding}; 5 | use std::collections::BTreeMap; 6 | 7 | #[derive(Clone, Debug, Default)] 8 | pub struct BlockEncoding { 9 | pub len_encoding: LenEncoding, 10 | pub transaction_bodies_encoding: LenEncoding, 11 | pub transaction_witness_sets_encoding: LenEncoding, 12 | pub auxiliary_data_set_encoding: LenEncoding, 13 | pub auxiliary_data_set_key_encodings: BTreeMap>, 14 | pub invalid_transactions_encoding: LenEncoding, 15 | pub invalid_transactions_elem_encodings: Vec>, 16 | } 17 | 18 | #[derive(Clone, Debug, Default)] 19 | pub struct HeaderBodyEncoding { 20 | pub len_encoding: LenEncoding, 21 | pub block_number_encoding: Option, 22 | pub slot_encoding: Option, 23 | pub prev_hash_encoding: StringEncoding, 24 | pub issuer_vkey_encoding: StringEncoding, 25 | pub vrf_vkey_encoding: StringEncoding, 26 | pub block_body_size_encoding: Option, 27 | pub block_body_hash_encoding: StringEncoding, 28 | } 29 | 30 | #[derive(Clone, Debug, Default)] 31 | pub struct HeaderEncoding { 32 | pub len_encoding: LenEncoding, 33 | } 34 | 35 | #[derive(Clone, Debug, Default)] 36 | pub struct OperationalCertEncoding { 37 | pub len_encoding: LenEncoding, 38 | pub hot_vkey_encoding: StringEncoding, 39 | pub sequence_number_encoding: Option, 40 | pub kes_period_encoding: Option, 41 | pub sigma_encoding: StringEncoding, 42 | } 43 | 44 | #[derive(Clone, Debug, Default)] 45 | pub struct ProtocolVersionEncoding { 46 | pub len_encoding: LenEncoding, 47 | pub major_encoding: Option, 48 | pub minor_encoding: Option, 49 | } 50 | -------------------------------------------------------------------------------- /chain/rust/src/builders/mint_builder.rs: -------------------------------------------------------------------------------- 1 | use crate::builders::witness_builder::{InputAggregateWitnessData, PartialPlutusWitness}; 2 | 3 | use super::witness_builder::{NativeScriptWitnessInfo, RequiredWitnessSet}; 4 | 5 | use cml_core::ordered_hash_map::OrderedHashMap; 6 | 7 | use crate::{assets::AssetName, NativeScript, PolicyId, RequiredSigners}; 8 | 9 | #[derive(Clone)] 10 | pub struct MintBuilderResult { 11 | pub policy_id: PolicyId, 12 | pub assets: OrderedHashMap, 13 | pub aggregate_witness: Option, 14 | pub required_wits: RequiredWitnessSet, 15 | } 16 | 17 | #[derive(Clone)] 18 | pub struct SingleMintBuilder { 19 | assets: OrderedHashMap, 20 | } 21 | 22 | impl SingleMintBuilder { 23 | pub fn new(assets: OrderedHashMap) -> Self { 24 | Self { assets } 25 | } 26 | 27 | pub fn new_single_asset(asset: AssetName, amount: i64) -> Self { 28 | let mut assets = OrderedHashMap::new(); 29 | assets.insert(asset, amount); 30 | Self { assets } 31 | } 32 | 33 | pub fn native_script( 34 | self, 35 | native_script: NativeScript, 36 | witness_info: NativeScriptWitnessInfo, 37 | ) -> MintBuilderResult { 38 | let mut required_wits = RequiredWitnessSet::default(); 39 | let script_hash = native_script.hash(); 40 | required_wits.add_script_hash(script_hash); 41 | 42 | MintBuilderResult { 43 | assets: self.assets, 44 | policy_id: script_hash, 45 | aggregate_witness: Some(InputAggregateWitnessData::NativeScript( 46 | native_script, 47 | witness_info, 48 | )), 49 | required_wits, 50 | } 51 | } 52 | 53 | pub fn plutus_script( 54 | self, 55 | partial_witness: PartialPlutusWitness, 56 | required_signers: RequiredSigners, 57 | ) -> MintBuilderResult { 58 | let mut required_wits = RequiredWitnessSet::default(); 59 | 60 | let script_hash = partial_witness.script.hash(); 61 | required_signers 62 | .iter() 63 | .for_each(|required_signer| required_wits.add_vkey_key_hash(*required_signer)); 64 | required_wits.add_script_hash(script_hash); 65 | 66 | MintBuilderResult { 67 | assets: self.assets, 68 | policy_id: script_hash, 69 | aggregate_witness: Some(InputAggregateWitnessData::PlutusScript( 70 | partial_witness, 71 | required_signers, 72 | None, 73 | )), 74 | required_wits, 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /chain/rust/src/builders/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod certificate_builder; 2 | pub mod input_builder; 3 | pub mod mint_builder; 4 | pub mod output_builder; 5 | pub mod proposal_builder; 6 | pub mod redeemer_builder; 7 | pub mod tx_builder; 8 | mod utils; 9 | pub mod vote_builder; 10 | pub mod withdrawal_builder; 11 | pub mod witness_builder; 12 | -------------------------------------------------------------------------------- /chain/rust/src/builders/utils.rs: -------------------------------------------------------------------------------- 1 | use crate::RequiredSigners; 2 | 3 | use super::witness_builder::RequiredWitnessSet; 4 | 5 | pub(crate) fn required_wits_from_required_signers( 6 | required_signers: &RequiredSigners, 7 | ) -> RequiredWitnessSet { 8 | let mut required_wits = RequiredWitnessSet::default(); 9 | required_signers 10 | .as_ref() 11 | .iter() 12 | .for_each(|required_signer| required_wits.add_vkey_key_hash(*required_signer)); 13 | required_wits 14 | } 15 | -------------------------------------------------------------------------------- /chain/rust/src/crypto/cbor_encodings.rs: -------------------------------------------------------------------------------- 1 | // This file was code-generated using an experimental CDDL to rust tool: 2 | // https://github.com/dcSpark/cddl-codegen 3 | 4 | use cml_core::serialization::{LenEncoding, StringEncoding}; 5 | 6 | #[derive(Clone, Debug, Default)] 7 | pub struct BootstrapWitnessEncoding { 8 | pub len_encoding: LenEncoding, 9 | pub public_key_encoding: StringEncoding, 10 | pub signature_encoding: StringEncoding, 11 | pub chain_code_encoding: StringEncoding, 12 | pub attributes_bytes_encoding: StringEncoding, 13 | } 14 | 15 | #[derive(Clone, Debug, Default)] 16 | pub struct KESSignatureEncoding { 17 | pub inner_encoding: StringEncoding, 18 | } 19 | 20 | #[derive(Clone, Debug, Default)] 21 | pub struct VRFCertEncoding { 22 | pub len_encoding: LenEncoding, 23 | pub output_encoding: StringEncoding, 24 | pub proof_encoding: StringEncoding, 25 | } 26 | 27 | #[derive(Clone, Debug, Default)] 28 | pub struct VkeywitnessEncoding { 29 | pub len_encoding: LenEncoding, 30 | pub vkey_encoding: StringEncoding, 31 | pub ed25519_signature_encoding: StringEncoding, 32 | } 33 | -------------------------------------------------------------------------------- /chain/rust/src/crypto/utils.rs: -------------------------------------------------------------------------------- 1 | use std::convert::{TryFrom, TryInto}; 2 | 3 | use super::{BootstrapWitness, Vkeywitness}; 4 | use crate::byron::AddressContent; 5 | 6 | use cml_crypto::{ 7 | chain_crypto::{self, derive::combine_pk_and_chaincode}, 8 | CryptoError, PrivateKey, RawBytesEncoding, TransactionHash, 9 | }; 10 | 11 | impl BootstrapWitness { 12 | // pub fn to_public_key(&self) -> Result { 13 | // crypto::chain_crypto::PublicKey::::try_from(self.clone()) 14 | // .map(crypto::Bip32PublicKey) 15 | // .map_err(Into::into) 16 | // } 17 | 18 | pub fn to_address(&self) -> Result { 19 | AddressContent::try_from(self.clone()).map_err(Into::into) 20 | } 21 | } 22 | 23 | impl TryInto> 24 | for BootstrapWitness 25 | { 26 | type Error = CryptoError; 27 | 28 | fn try_into( 29 | self, 30 | ) -> Result, Self::Error> 31 | { 32 | combine_pk_and_chaincode(self.public_key.0, &self.chain_code).map_err(Into::into) 33 | } 34 | } 35 | 36 | impl TryFrom for AddressContent { 37 | type Error = CryptoError; 38 | 39 | fn try_from(wit: BootstrapWitness) -> Result { 40 | let protocol_magic = wit.attributes.protocol_magic; 41 | let key: chain_crypto::PublicKey = 42 | wit.try_into()?; 43 | let address_content = 44 | AddressContent::new_simple(cml_crypto::Bip32PublicKey::from(key), protocol_magic); 45 | Ok(address_content) 46 | } 47 | } 48 | 49 | pub fn make_vkey_witness(tx_body_hash: &TransactionHash, sk: &PrivateKey) -> Vkeywitness { 50 | let sig = sk.sign(tx_body_hash.to_raw_bytes()); 51 | Vkeywitness::new(sk.to_public(), sig) 52 | } 53 | -------------------------------------------------------------------------------- /chain/rust/src/genesis/byron/config.rs: -------------------------------------------------------------------------------- 1 | //! Blockchain network specific config (ProtocolMagic) 2 | //! 3 | //! there are some settings that need to be set in order to guarantee 4 | //! operability with the appropriate network or different option. 5 | //! 6 | 7 | use std::{ 8 | collections::BTreeMap, 9 | time::{Duration, SystemTime}, 10 | }; 11 | 12 | use crate::{ 13 | byron::{ByronAddress, ProtocolMagic, StakeholderId}, 14 | fees::LinearFee, 15 | Coin, 16 | }; 17 | use cml_crypto::{ 18 | chain_crypto::{self, Ed25519, Ed25519Bip32}, 19 | BlockHeaderHash, 20 | }; 21 | 22 | /// Configuration for the wallet-crypto 23 | #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] 24 | #[cfg_attr(feature = "generic-serialization", derive(Serialize, Deserialize))] 25 | pub struct Config { 26 | pub protocol_magic: ProtocolMagic, 27 | } 28 | impl Config { 29 | pub fn new(protocol_magic: ProtocolMagic) -> Self { 30 | Config { protocol_magic } 31 | } 32 | } 33 | impl Default for Config { 34 | fn default() -> Self { 35 | Config::new(ProtocolMagic::default()) 36 | } 37 | } 38 | 39 | /// A subset of the genesis data. The genesis data is a JSON file 40 | /// whose canonicalized form has the hash 'genesis_prev', which is the 41 | /// parent of the genesis block of epoch 0. (Note that "genesis data" 42 | /// is something completely different from a epoch genesis block. The 43 | /// genesis data is not stored in the chain as a block.) 44 | #[derive(Debug, Clone, PartialEq, Eq)] 45 | pub struct GenesisData { 46 | // FIXME: genesis_prev shouldn't be here since it's computed *from* the GenesisData. 47 | pub genesis_prev: BlockHeaderHash, 48 | pub epoch_stability_depth: usize, // a.k.a. 'k' 49 | pub start_time: SystemTime, 50 | pub slot_duration: Duration, 51 | pub protocol_magic: ProtocolMagic, 52 | pub fee_policy: LinearFee, 53 | pub avvm_distr: BTreeMap, Coin>, // AVVM = Ada Voucher Vending Machine 54 | // note: order of the keys here is unspecified in the spec (anything order is valid) 55 | pub non_avvm_balances: BTreeMap, 56 | pub boot_stakeholders: BTreeMap, 57 | } 58 | 59 | #[derive(Debug, Clone, PartialEq, Eq)] 60 | pub struct BootStakeholder { 61 | pub weight: BootStakeWeight, 62 | pub issuer_pk: chain_crypto::PublicKey, 63 | pub delegate_pk: chain_crypto::PublicKey, 64 | pub cert: chain_crypto::Signature<(), Ed25519Bip32>, 65 | } 66 | 67 | pub type BootStakeWeight = u16; 68 | -------------------------------------------------------------------------------- /chain/rust/src/genesis/byron/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod config; 2 | pub mod parse; 3 | pub mod raw; 4 | -------------------------------------------------------------------------------- /chain/rust/src/genesis/byron/raw.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | use std::collections::HashMap; 3 | 4 | use super::config; 5 | 6 | #[allow(non_snake_case)] 7 | #[derive(Serialize, Deserialize, Debug)] 8 | pub struct GenesisData { 9 | pub avvmDistr: HashMap, 10 | pub nonAvvmBalances: HashMap, 11 | pub bootStakeholders: HashMap, 12 | pub heavyDelegation: HashMap, 13 | pub protocolConsts: ProtocolConsts, 14 | pub startTime: u64, 15 | pub blockVersionData: BlockVersionData, 16 | } 17 | 18 | #[allow(non_snake_case)] 19 | #[derive(Serialize, Deserialize, Debug)] 20 | pub struct ProtocolConsts { 21 | pub k: usize, 22 | pub protocolMagic: u32, 23 | //pub vssMaxTTL: u32, 24 | //pub vssMinTTL: u32, 25 | } 26 | 27 | #[allow(non_snake_case)] 28 | #[derive(Serialize, Deserialize, Debug)] 29 | pub struct BlockVersionData { 30 | //pub heavyDelThd: String, 31 | //pub maxBlockSize: String, 32 | //pub maxHeaderSize: String, 33 | //pub maxProposalSize: String, 34 | //pub maxTxSize: String, 35 | //pub mpcThd: String, 36 | //pub scriptVersion: u32, 37 | pub slotDuration: String, 38 | //pub softforkRule: SoftforkRule, 39 | pub txFeePolicy: TxFeePolicy, 40 | //pub unlockStakeEpoch: String, 41 | //pub updateImplicit: String, 42 | //pub updateProposalThd: String, 43 | //pub updateVoteThd: String, 44 | } 45 | 46 | #[allow(non_snake_case)] 47 | #[derive(Serialize, Deserialize, Debug)] 48 | pub struct TxFeePolicy { 49 | pub summand: String, 50 | pub multiplier: String, 51 | } 52 | 53 | #[allow(non_snake_case)] 54 | #[derive(Serialize, Deserialize, Debug)] 55 | pub struct SoftforkRule { 56 | pub initThd: String, 57 | pub minThd: String, 58 | pub thdDecrement: String, 59 | } 60 | 61 | #[allow(non_snake_case)] 62 | #[derive(Serialize, Deserialize, Debug)] 63 | pub struct HeavyDelegation { 64 | pub issuerPk: String, 65 | pub delegatePk: String, 66 | pub cert: String, 67 | } 68 | -------------------------------------------------------------------------------- /chain/rust/src/genesis/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod byron; 2 | pub mod network_info; 3 | pub mod shelley; 4 | -------------------------------------------------------------------------------- /chain/rust/src/genesis/shelley/config.rs: -------------------------------------------------------------------------------- 1 | use cml_crypto::{Ed25519KeyHash, VRFKeyHash}; 2 | use fraction::Fraction; 3 | use std::collections::BTreeMap; 4 | 5 | use crate::{address::Address, block::ProtocolVersion, Coin}; 6 | 7 | /// A subset of the Shelley genesis data. The genesis data is a JSON file 8 | /// is something completely different from a epoch genesis block and the Byron genesis block 9 | #[derive(Debug, Clone)] 10 | pub struct ShelleyGenesisData { 11 | pub active_slots_coeff: Fraction, 12 | pub epoch_length: u64, 13 | pub gen_delegs: BTreeMap, 14 | pub initial_funds: BTreeMap, 15 | pub max_kes_evolutions: u64, 16 | pub max_lovelace_supply: Coin, 17 | pub network_id: u64, 18 | pub network_magic: u64, 19 | pub protocol_params: ShelleyGenesisProtocolParameters, 20 | pub security_param: u64, 21 | pub slot_length: Fraction, 22 | pub slots_per_kes_period: u64, 23 | pub staking: Option, 24 | pub system_start: chrono::DateTime, 25 | pub update_quorum: u64, 26 | } 27 | 28 | #[derive(Debug, Clone)] 29 | pub struct ShelleyGenesisDelegations { 30 | pub delegate: Ed25519KeyHash, 31 | pub vrf: VRFKeyHash, 32 | } 33 | 34 | #[derive(Debug, Clone)] 35 | pub struct ShelleyGenesisStaking { 36 | pub pools: BTreeMap, 37 | // initial delegations of staking key -> pool id 38 | pub stake: BTreeMap, 39 | } 40 | 41 | #[derive(Debug, Clone)] 42 | pub struct ShelleyGenesisProtocolParameters { 43 | pub a0: Fraction, 44 | pub decentralisation_param: Fraction, 45 | pub e_max: u64, 46 | pub extra_entropy: ShelleyGenesisExtraEntropy, 47 | pub key_deposit: Coin, 48 | pub max_block_body_size: u64, 49 | pub max_block_header_size: u64, 50 | pub max_tx_size: u64, 51 | pub min_fee_a: Coin, 52 | pub min_fee_b: Coin, 53 | pub min_pool_cost: Coin, 54 | pub min_utxo_value: Coin, 55 | pub n_opt: u64, 56 | pub pool_deposit: Coin, 57 | pub protocol_version: ProtocolVersion, 58 | pub rho: Fraction, 59 | pub tau: Fraction, 60 | } 61 | 62 | #[derive(Debug, Clone)] 63 | pub struct ShelleyGenesisExtraEntropy { 64 | pub tag: String, 65 | } 66 | -------------------------------------------------------------------------------- /chain/rust/src/genesis/shelley/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod config; 2 | pub mod parse; 3 | pub mod raw; 4 | -------------------------------------------------------------------------------- /chain/rust/src/governance/cbor_encodings.rs: -------------------------------------------------------------------------------- 1 | // This file was code-generated using an experimental CDDL to rust tool: 2 | // https://github.com/dcSpark/cddl-codegen 3 | 4 | use crate::address::RewardAccount; 5 | use crate::certs::Credential; 6 | use cml_core::serialization::{LenEncoding, StringEncoding}; 7 | use std::collections::BTreeMap; 8 | 9 | #[derive(Clone, Debug, Default)] 10 | pub struct AnchorEncoding { 11 | pub len_encoding: LenEncoding, 12 | pub anchor_doc_hash_encoding: StringEncoding, 13 | } 14 | 15 | #[derive(Clone, Debug, Default)] 16 | pub struct ConstitutionEncoding { 17 | pub len_encoding: LenEncoding, 18 | pub script_hash_encoding: StringEncoding, 19 | } 20 | 21 | #[derive(Clone, Debug, Default)] 22 | pub struct GovActionIdEncoding { 23 | pub len_encoding: LenEncoding, 24 | pub transaction_id_encoding: StringEncoding, 25 | pub gov_action_index_encoding: Option, 26 | } 27 | 28 | #[derive(Clone, Debug, Default)] 29 | pub struct HardForkInitiationActionEncoding { 30 | pub len_encoding: LenEncoding, 31 | pub tag_encoding: Option, 32 | } 33 | 34 | #[derive(Clone, Debug, Default)] 35 | pub struct NewConstitutionEncoding { 36 | pub len_encoding: LenEncoding, 37 | pub tag_encoding: Option, 38 | } 39 | 40 | #[derive(Clone, Debug, Default)] 41 | pub struct NoConfidenceEncoding { 42 | pub len_encoding: LenEncoding, 43 | pub tag_encoding: Option, 44 | } 45 | 46 | #[derive(Clone, Debug, Default)] 47 | pub struct ParameterChangeActionEncoding { 48 | pub len_encoding: LenEncoding, 49 | pub tag_encoding: Option, 50 | pub policy_hash_encoding: StringEncoding, 51 | } 52 | 53 | #[derive(Clone, Debug, Default)] 54 | pub struct ProposalProcedureEncoding { 55 | pub len_encoding: LenEncoding, 56 | pub deposit_encoding: Option, 57 | } 58 | 59 | #[derive(Clone, Debug, Default)] 60 | pub struct TreasuryWithdrawalsActionEncoding { 61 | pub len_encoding: LenEncoding, 62 | pub tag_encoding: Option, 63 | pub withdrawal_encoding: LenEncoding, 64 | pub withdrawal_value_encodings: BTreeMap>, 65 | pub policy_hash_encoding: StringEncoding, 66 | } 67 | 68 | #[derive(Clone, Debug, Default)] 69 | pub struct UpdateCommitteeEncoding { 70 | pub len_encoding: LenEncoding, 71 | pub tag_encoding: Option, 72 | pub credentials_encoding: LenEncoding, 73 | pub credentials_value_encodings: BTreeMap>, 74 | } 75 | 76 | #[derive(Clone, Debug, Default)] 77 | pub struct VotingProcedureEncoding { 78 | pub len_encoding: LenEncoding, 79 | pub vote_encoding: Option, 80 | } 81 | -------------------------------------------------------------------------------- /chain/rust/src/governance/utils.rs: -------------------------------------------------------------------------------- 1 | use cml_crypto::{Ed25519KeyHash, ScriptHash}; 2 | 3 | use super::{GovAction, Voter}; 4 | 5 | impl GovAction { 6 | pub fn script_hash(&self) -> Option<&ScriptHash> { 7 | match self { 8 | Self::ParameterChangeAction(action) => action.policy_hash.as_ref(), 9 | Self::HardForkInitiationAction(_action) => None, 10 | Self::TreasuryWithdrawalsAction(action) => action.policy_hash.as_ref(), 11 | Self::NoConfidence(_action) => None, 12 | // TODO: unsure if these count? they can be credentials but maybe it's not needed to sign 13 | Self::UpdateCommittee(_action) => None, 14 | // TODO: unsure if this counts? 15 | //Self::NewConstitution(action) => action.constitution.script_hash, 16 | Self::NewConstitution(_action) => None, 17 | Self::InfoAction { .. } => None, 18 | } 19 | } 20 | } 21 | 22 | impl Voter { 23 | pub fn key_hash(&self) -> Option<&Ed25519KeyHash> { 24 | match self { 25 | Self::ConstitutionalCommitteeHotKeyHash { 26 | ed25519_key_hash, .. 27 | } => Some(ed25519_key_hash), 28 | Self::ConstitutionalCommitteeHotScriptHash { .. } => None, 29 | Self::DRepKeyHash { 30 | ed25519_key_hash, .. 31 | } => Some(ed25519_key_hash), 32 | Self::DRepScriptHash { .. } => None, 33 | Self::StakingPoolKeyHash { 34 | ed25519_key_hash, .. 35 | } => Some(ed25519_key_hash), 36 | } 37 | } 38 | 39 | pub fn script_hash(&self) -> Option<&ScriptHash> { 40 | match self { 41 | Self::ConstitutionalCommitteeHotKeyHash { .. } => None, 42 | Self::ConstitutionalCommitteeHotScriptHash { script_hash, .. } => Some(script_hash), 43 | Self::DRepKeyHash { .. } => None, 44 | Self::DRepScriptHash { script_hash, .. } => Some(script_hash), 45 | Self::StakingPoolKeyHash { .. } => None, 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /chain/rust/src/json/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod json_serialize; 2 | pub mod metadatums; 3 | pub mod plutus_datums; 4 | -------------------------------------------------------------------------------- /chain/rust/src/plutus/cbor_encodings.rs: -------------------------------------------------------------------------------- 1 | // This file was code-generated using an experimental CDDL to rust tool: 2 | // https://github.com/dcSpark/cddl-codegen 3 | 4 | use cml_core::serialization::{LenEncoding, StringEncoding}; 5 | use std::collections::BTreeMap; 6 | 7 | #[derive(Clone, Debug, Default)] 8 | pub struct CostModelsEncoding { 9 | pub inner_encoding: LenEncoding, 10 | pub inner_key_encodings: BTreeMap>, 11 | pub inner_value_encodings: BTreeMap>)>, 12 | } 13 | 14 | #[derive(Clone, Debug, Default)] 15 | pub struct ExUnitPricesEncoding { 16 | pub len_encoding: LenEncoding, 17 | } 18 | 19 | #[derive(Clone, Debug, Default)] 20 | pub struct ExUnitsEncoding { 21 | pub len_encoding: LenEncoding, 22 | pub mem_encoding: Option, 23 | pub steps_encoding: Option, 24 | } 25 | 26 | #[derive(Clone, Debug, Default)] 27 | pub struct LegacyRedeemerEncoding { 28 | pub len_encoding: LenEncoding, 29 | pub tag_encoding: Option, 30 | pub index_encoding: Option, 31 | } 32 | 33 | #[derive(Clone, Debug, Default)] 34 | pub struct PlutusV1ScriptEncoding { 35 | pub inner_encoding: StringEncoding, 36 | } 37 | 38 | #[derive(Clone, Debug, Default)] 39 | pub struct PlutusV2ScriptEncoding { 40 | pub inner_encoding: StringEncoding, 41 | } 42 | 43 | #[derive(Clone, Debug, Default)] 44 | pub struct PlutusV3ScriptEncoding { 45 | pub inner_encoding: StringEncoding, 46 | } 47 | 48 | #[derive(Clone, Debug, Default)] 49 | pub struct RedeemerKeyEncoding { 50 | pub len_encoding: LenEncoding, 51 | pub tag_encoding: Option, 52 | pub index_encoding: Option, 53 | } 54 | 55 | #[derive(Clone, Debug, Default)] 56 | pub struct RedeemerValEncoding { 57 | pub len_encoding: LenEncoding, 58 | } 59 | -------------------------------------------------------------------------------- /chain/wasm/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cml-chain-wasm" 3 | version = "6.2.0" 4 | edition = "2018" 5 | authors = ["dcSpark"] 6 | license = "MIT" 7 | description = "Multiplatform WASM SDK for main Cardano blockchain functionality" 8 | documentation = "https://github.com/dcSpark/cardano-multiplatform-lib/docs" 9 | repository = "https://github.com/dcSpark/cardano-multiplatform-lib" 10 | readme = "../../README.md" 11 | keywords = ["cardano"] 12 | 13 | [lib] 14 | crate-type = ["cdylib", "rlib"] 15 | 16 | [dependencies] 17 | cml-chain = { path = "../rust", version = "6.2.0", features = ["used_from_wasm"] } 18 | cml-core = { path = "../../core/rust", version = "6.2.0" } 19 | cml-core-wasm = { path = "../../core/wasm", version = "6.2.0" } 20 | # TODO: remove this dependency if possible to reduce confusion? maybe pub export necessary things in crypto-wasm? 21 | cml-crypto = { path = "../../crypto/rust", version = "6.2.0" } 22 | cml-crypto-wasm = { path = "../../crypto/wasm", version = "6.2.0" } 23 | cbor_event = "2.4.0" 24 | hex = "0.4.0" 25 | wasm-bindgen = { version = "0.2.87" } 26 | linked-hash-map = "0.5.3" 27 | serde_json = "1.0.57" 28 | serde-wasm-bindgen = "0.4.5" 29 | -------------------------------------------------------------------------------- /chain/wasm/README.md: -------------------------------------------------------------------------------- 1 | # wasm 2 | 3 | WASM bindings covering the `chain` crate. Includes the `crypto` crate as a dependency so you do not need to use both as both are output in WASM builds. 4 | -------------------------------------------------------------------------------- /chain/wasm/json-gen/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cml-chain-json-schema-gen" 3 | version = "6.2.0" 4 | edition = "2018" 5 | keywords = ["cardano"] 6 | 7 | [dependencies] 8 | serde_json = "1.0.57" 9 | schemars = "0.8.8" 10 | cml-chain = { path = "../../rust" } 11 | cml-crypto = { path = "../../../crypto/rust" } 12 | -------------------------------------------------------------------------------- /chain/wasm/json-gen/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | cml_chain_json_schema_gen::export_schemas(); 3 | } 4 | -------------------------------------------------------------------------------- /chain/wasm/src/assets/mod.rs: -------------------------------------------------------------------------------- 1 | use wasm_bindgen::prelude::wasm_bindgen; 2 | 3 | pub mod utils; 4 | 5 | pub use utils::{Mint, MultiAsset, Value}; 6 | 7 | pub use cml_chain::assets::{Coin, NonZeroInt64, PositiveCoin}; 8 | 9 | use cml_core_wasm::{impl_wasm_cbor_json_api, impl_wasm_conversions}; 10 | 11 | // Code below here was code-generated using an experimental CDDL to rust tool: 12 | // https://github.com/dcSpark/cddl-codegen 13 | 14 | #[derive(Clone, Debug)] 15 | #[wasm_bindgen] 16 | pub struct AssetName(cml_chain::assets::AssetName); 17 | 18 | impl_wasm_cbor_json_api!(AssetName); 19 | 20 | impl_wasm_conversions!(cml_chain::assets::AssetName, AssetName); 21 | -------------------------------------------------------------------------------- /chain/wasm/src/auxdata/utils.rs: -------------------------------------------------------------------------------- 1 | use crate::{NativeScriptList, PlutusV1ScriptList, PlutusV2ScriptList}; 2 | use wasm_bindgen::prelude::wasm_bindgen; 3 | 4 | use super::{AuxiliaryData, Metadata}; 5 | 6 | #[wasm_bindgen] 7 | impl AuxiliaryData { 8 | pub fn new() -> Self { 9 | cml_chain::auxdata::AuxiliaryData::new().into() 10 | } 11 | 12 | pub fn metadata(&self) -> Option { 13 | self.0.metadata().map(|m| m.clone().into()) 14 | } 15 | 16 | pub fn native_scripts(&self) -> Option { 17 | self.0.native_scripts().cloned().map(Into::into) 18 | } 19 | 20 | pub fn plutus_v1_scripts(&self) -> Option { 21 | self.0.plutus_v1_scripts().cloned().map(Into::into) 22 | } 23 | 24 | pub fn plutus_v2_scripts(&self) -> Option { 25 | self.0.plutus_v2_scripts().cloned().map(Into::into) 26 | } 27 | 28 | /// Warning: overwrites any conflicting metadatum labels present 29 | pub fn add_metadata(&mut self, other: &Metadata) { 30 | self.0.add_metadata(other.clone().into()) 31 | } 32 | 33 | /// Warning: does not check for duplicates and may migrate eras 34 | pub fn add_native_scripts(&mut self, scripts: &NativeScriptList) { 35 | self.0.add_native_scripts(scripts.clone().into()) 36 | } 37 | 38 | /// Warning: does not check for duplicates and may migrate eras 39 | pub fn add_plutus_v1_scripts(&mut self, scripts: &PlutusV1ScriptList) { 40 | self.0.add_plutus_v1_scripts(scripts.clone().into()) 41 | } 42 | 43 | /// Warning: does not check for duplicates and may migrate eras 44 | pub fn add_plutus_v2_scripts(&mut self, scripts: &PlutusV2ScriptList) { 45 | self.0.add_plutus_v2_scripts(scripts.clone().into()) 46 | } 47 | 48 | /// Adds everything present in other to self 49 | /// May change the era the aux data is in if necessary 50 | /// Warning: overwrites any metadatum labels present 51 | /// also does not check for duplicates in scripts 52 | pub fn add(&mut self, other: &AuxiliaryData) { 53 | self.0.add(other.clone().into()) 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /chain/wasm/src/builders/certificate_builder.rs: -------------------------------------------------------------------------------- 1 | use crate::builders::witness_builder::PartialPlutusWitness; 2 | use crate::*; 3 | use cml_core_wasm::impl_wasm_conversions; 4 | use wasm_bindgen::prelude::{wasm_bindgen, JsError}; 5 | 6 | use super::witness_builder::NativeScriptWitnessInfo; 7 | 8 | use crate::{certs::Certificate, RequiredSigners}; 9 | 10 | #[wasm_bindgen] 11 | #[derive(Clone)] 12 | pub struct CertificateBuilderResult( 13 | cml_chain::builders::certificate_builder::CertificateBuilderResult, 14 | ); 15 | 16 | impl_wasm_conversions!( 17 | cml_chain::builders::certificate_builder::CertificateBuilderResult, 18 | CertificateBuilderResult 19 | ); 20 | 21 | #[wasm_bindgen] 22 | #[derive(Clone)] 23 | pub struct SingleCertificateBuilder( 24 | cml_chain::builders::certificate_builder::SingleCertificateBuilder, 25 | ); 26 | 27 | impl_wasm_conversions!( 28 | cml_chain::builders::certificate_builder::SingleCertificateBuilder, 29 | SingleCertificateBuilder 30 | ); 31 | 32 | #[wasm_bindgen] 33 | impl SingleCertificateBuilder { 34 | pub fn new(cert: &Certificate) -> Self { 35 | cml_chain::builders::certificate_builder::SingleCertificateBuilder::new(cert.clone().into()) 36 | .into() 37 | } 38 | 39 | /// note: particularly useful for StakeRegistration which doesn't require witnessing 40 | pub fn skip_witness(&self) -> CertificateBuilderResult { 41 | self.0.clone().skip_witness().into() 42 | } 43 | 44 | pub fn payment_key(&self) -> Result { 45 | self.0 46 | .clone() 47 | .payment_key() 48 | .map(Into::into) 49 | .map_err(Into::into) 50 | } 51 | 52 | /** Signer keys don't have to be set. You can leave it empty and then add the required witnesses later */ 53 | pub fn native_script( 54 | &self, 55 | native_script: &NativeScript, 56 | witness_info: &NativeScriptWitnessInfo, 57 | ) -> Result { 58 | self.0 59 | .clone() 60 | .native_script(native_script.clone().into(), witness_info.clone().into()) 61 | .map(Into::into) 62 | .map_err(Into::into) 63 | } 64 | 65 | pub fn plutus_script( 66 | self, 67 | partial_witness: &PartialPlutusWitness, 68 | required_signers: &RequiredSigners, 69 | ) -> Result { 70 | self.0 71 | .plutus_script( 72 | partial_witness.clone().into(), 73 | required_signers.clone().into(), 74 | ) 75 | .map(Into::into) 76 | .map_err(Into::into) 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /chain/wasm/src/builders/mint_builder.rs: -------------------------------------------------------------------------------- 1 | use crate::builders::witness_builder::{NativeScriptWitnessInfo, PartialPlutusWitness}; 2 | 3 | use cml_core_wasm::impl_wasm_conversions; 4 | use wasm_bindgen::prelude::wasm_bindgen; 5 | 6 | use crate::{AssetName, MapAssetNameToNonZeroInt64, NativeScript, RequiredSigners}; 7 | 8 | #[wasm_bindgen] 9 | #[derive(Clone)] 10 | pub struct MintBuilderResult(cml_chain::builders::mint_builder::MintBuilderResult); 11 | 12 | impl_wasm_conversions!( 13 | cml_chain::builders::mint_builder::MintBuilderResult, 14 | MintBuilderResult 15 | ); 16 | 17 | #[wasm_bindgen] 18 | #[derive(Clone)] 19 | pub struct SingleMintBuilder(cml_chain::builders::mint_builder::SingleMintBuilder); 20 | 21 | impl_wasm_conversions!( 22 | cml_chain::builders::mint_builder::SingleMintBuilder, 23 | SingleMintBuilder 24 | ); 25 | 26 | #[wasm_bindgen] 27 | impl SingleMintBuilder { 28 | pub fn new(assets: &MapAssetNameToNonZeroInt64) -> Self { 29 | cml_chain::builders::mint_builder::SingleMintBuilder::new(assets.clone().into()).into() 30 | } 31 | 32 | pub fn new_single_asset(asset: &AssetName, amount: i64) -> Self { 33 | cml_chain::builders::mint_builder::SingleMintBuilder::new_single_asset( 34 | asset.clone().into(), 35 | amount, 36 | ) 37 | .into() 38 | } 39 | 40 | pub fn native_script( 41 | self, 42 | native_script: &NativeScript, 43 | witness_info: &NativeScriptWitnessInfo, 44 | ) -> MintBuilderResult { 45 | self.0 46 | .native_script(native_script.clone().into(), witness_info.clone().into()) 47 | .into() 48 | } 49 | 50 | pub fn plutus_script( 51 | self, 52 | partial_witness: &PartialPlutusWitness, 53 | required_signers: &RequiredSigners, 54 | ) -> MintBuilderResult { 55 | self.0 56 | .plutus_script( 57 | partial_witness.clone().into(), 58 | required_signers.clone().into(), 59 | ) 60 | .into() 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /chain/wasm/src/builders/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod certificate_builder; 2 | pub mod input_builder; 3 | pub mod mint_builder; 4 | pub mod output_builder; 5 | pub mod proposal_builder; 6 | pub mod redeemer_builder; 7 | pub mod tx_builder; 8 | pub mod vote_builder; 9 | pub mod withdrawal_builder; 10 | pub mod witness_builder; 11 | -------------------------------------------------------------------------------- /chain/wasm/src/builders/withdrawal_builder.rs: -------------------------------------------------------------------------------- 1 | use crate::builders::witness_builder::PartialPlutusWitness; 2 | use crate::*; 3 | use cml_core_wasm::impl_wasm_conversions; 4 | use wasm_bindgen::prelude::{wasm_bindgen, JsError}; 5 | 6 | use super::witness_builder::NativeScriptWitnessInfo; 7 | 8 | use crate::{address::RewardAddress, RequiredSigners}; 9 | 10 | #[wasm_bindgen] 11 | #[derive(Clone)] 12 | pub struct WithdrawalBuilderResult( 13 | cml_chain::builders::withdrawal_builder::WithdrawalBuilderResult, 14 | ); 15 | 16 | impl_wasm_conversions!( 17 | cml_chain::builders::withdrawal_builder::WithdrawalBuilderResult, 18 | WithdrawalBuilderResult 19 | ); 20 | 21 | #[wasm_bindgen] 22 | #[derive(Clone)] 23 | pub struct SingleWithdrawalBuilder( 24 | cml_chain::builders::withdrawal_builder::SingleWithdrawalBuilder, 25 | ); 26 | 27 | impl_wasm_conversions!( 28 | cml_chain::builders::withdrawal_builder::SingleWithdrawalBuilder, 29 | SingleWithdrawalBuilder 30 | ); 31 | 32 | #[wasm_bindgen] 33 | impl SingleWithdrawalBuilder { 34 | pub fn new(address: &RewardAddress, amount: Coin) -> Self { 35 | cml_chain::builders::withdrawal_builder::SingleWithdrawalBuilder::new( 36 | address.clone().into(), 37 | amount, 38 | ) 39 | .into() 40 | } 41 | 42 | pub fn payment_key(&self) -> Result { 43 | self.0 44 | .clone() 45 | .payment_key() 46 | .map(Into::into) 47 | .map_err(Into::into) 48 | } 49 | 50 | pub fn native_script( 51 | self, 52 | native_script: &NativeScript, 53 | witness_info: &NativeScriptWitnessInfo, 54 | ) -> Result { 55 | self.0 56 | .native_script(native_script.as_ref(), witness_info.as_ref()) 57 | .map(Into::into) 58 | .map_err(Into::into) 59 | } 60 | 61 | pub fn plutus_script( 62 | self, 63 | partial_witness: PartialPlutusWitness, 64 | required_signers: RequiredSigners, 65 | ) -> Result { 66 | self.0 67 | .plutus_script(partial_witness.into(), required_signers.into()) 68 | .map(Into::into) 69 | .map_err(Into::into) 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /chain/wasm/src/byron/crc32.rs: -------------------------------------------------------------------------------- 1 | use wasm_bindgen::prelude::wasm_bindgen; 2 | 3 | #[wasm_bindgen] 4 | #[derive(Clone, Copy)] 5 | pub struct Crc32(cml_chain::byron::Crc32); 6 | 7 | #[wasm_bindgen] 8 | impl Crc32 { 9 | /// initialise a new CRC32 state 10 | #[inline] 11 | pub fn new() -> Self { 12 | Self(cml_chain::byron::Crc32::new()) 13 | } 14 | 15 | /// update the CRC32 with the given bytes. 16 | /// 17 | /// beware that the order in which you update the Crc32 18 | /// matter 19 | pub fn update(&mut self, bytes: &[u8]) { 20 | self.0.update(bytes); 21 | } 22 | 23 | /// finalize the CRC32, recovering the computed value 24 | pub fn finalize(&self) -> u32 { 25 | self.0.finalize() 26 | } 27 | } 28 | 29 | impl From for Crc32 { 30 | fn from(native: cml_chain::byron::Crc32) -> Self { 31 | Self(native) 32 | } 33 | } 34 | 35 | impl From for cml_chain::byron::Crc32 { 36 | fn from(wasm: Crc32) -> Self { 37 | wasm.0 38 | } 39 | } 40 | 41 | impl AsRef for Crc32 { 42 | fn as_ref(&self) -> &cml_chain::byron::Crc32 { 43 | &self.0 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /chain/wasm/src/certs/utils.rs: -------------------------------------------------------------------------------- 1 | use wasm_bindgen::prelude::wasm_bindgen; 2 | use super::{Ipv4, Ipv6, StakeCredential}; 3 | 4 | #[wasm_bindgen] 5 | impl StakeCredential { 6 | // we don't implement RawBytesEncoding as from_raw_bytes() would be unable to distinguish 7 | pub fn to_raw_bytes(&self) -> Vec { 8 | self.0.to_raw_bytes().into() 9 | } 10 | } 11 | 12 | #[wasm_bindgen] 13 | impl Ipv4 { 14 | pub fn to_str(&self) -> String { 15 | self.0.to_string() 16 | } 17 | 18 | #[allow(clippy::should_implement_trait)] 19 | pub fn from_str(s: &str) -> Result { 20 | cml_chain::certs::Ipv4::from_str(s).map(Into::into).map_err(Into::into) 21 | } 22 | } 23 | 24 | #[wasm_bindgen] 25 | impl Ipv6 { 26 | pub fn to_str(&self) -> String { 27 | self.0.to_string() 28 | } 29 | 30 | #[allow(clippy::should_implement_trait)] 31 | pub fn from_str(s: &str) -> Result { 32 | cml_chain::certs::Ipv6::from_str(s).map(Into::into).map_err(Into::into) 33 | } 34 | } -------------------------------------------------------------------------------- /chain/wasm/src/crypto/utils.rs: -------------------------------------------------------------------------------- 1 | use wasm_bindgen::prelude::{wasm_bindgen, JsError}; 2 | 3 | use crate::{byron::AddressContent, crypto::BootstrapWitness, Vkeywitness}; 4 | 5 | use cml_crypto_wasm::{PrivateKey, TransactionHash}; 6 | 7 | #[wasm_bindgen] 8 | impl BootstrapWitness { 9 | pub fn to_address(&self) -> Result { 10 | self.0.to_address().map(Into::into).map_err(Into::into) 11 | } 12 | } 13 | 14 | #[wasm_bindgen] 15 | pub fn make_vkey_witness(tx_body_hash: &TransactionHash, sk: &PrivateKey) -> Vkeywitness { 16 | cml_chain::crypto::utils::make_vkey_witness(tx_body_hash.as_ref(), sk.as_ref()).into() 17 | } 18 | -------------------------------------------------------------------------------- /chain/wasm/src/deposit.rs: -------------------------------------------------------------------------------- 1 | use wasm_bindgen::prelude::{wasm_bindgen, JsError}; 2 | 3 | use crate::{ 4 | assets::{Coin, Value}, 5 | transaction::TransactionBody, 6 | }; 7 | 8 | #[wasm_bindgen] 9 | pub fn get_implicit_input( 10 | txbody: &TransactionBody, 11 | pool_deposit: Coin, // // protocol parameter 12 | key_deposit: Coin, // protocol parameter 13 | ) -> Result { 14 | cml_chain::deposit::get_implicit_input(txbody.as_ref(), pool_deposit, key_deposit) 15 | .map(Into::into) 16 | .map_err(Into::into) 17 | } 18 | 19 | #[wasm_bindgen] 20 | pub fn get_deposit( 21 | txbody: &TransactionBody, 22 | pool_deposit: Coin, // // protocol parameter 23 | key_deposit: Coin, // protocol parameter 24 | ) -> Result { 25 | cml_chain::deposit::get_deposit(txbody.as_ref(), pool_deposit, key_deposit).map_err(Into::into) 26 | } 27 | -------------------------------------------------------------------------------- /chain/wasm/src/genesis/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod network_info; 2 | -------------------------------------------------------------------------------- /chain/wasm/src/genesis/network_info.rs: -------------------------------------------------------------------------------- 1 | use crate::byron::utils::ProtocolMagic; 2 | use cml_core_wasm::impl_wasm_conversions; 3 | use wasm_bindgen::prelude::wasm_bindgen; 4 | use cml_crypto_wasm::TransactionHash; 5 | 6 | #[wasm_bindgen] 7 | pub struct NetworkInfo(cml_chain::genesis::network_info::NetworkInfo); 8 | 9 | impl_wasm_conversions!(cml_chain::genesis::network_info::NetworkInfo, NetworkInfo); 10 | 11 | #[wasm_bindgen] 12 | impl NetworkInfo { 13 | pub fn new(network_id: u8, protocol_magic: &ProtocolMagic) -> Self { 14 | cml_chain::genesis::network_info::NetworkInfo::new(network_id, *protocol_magic.as_ref()) 15 | .into() 16 | } 17 | 18 | pub fn network_id(&self) -> u8 { 19 | self.0.network_id() 20 | } 21 | 22 | pub fn protocol_magic(&self) -> ProtocolMagic { 23 | self.0.protocol_magic().into() 24 | } 25 | 26 | /// This is the old testnet - most likely you want to use preview()/preprod() 27 | pub fn testnet() -> Self { 28 | cml_chain::genesis::network_info::NetworkInfo::testnet().into() 29 | } 30 | 31 | pub fn mainnet() -> Self { 32 | cml_chain::genesis::network_info::NetworkInfo::mainnet().into() 33 | } 34 | 35 | pub fn preview() -> Self { 36 | cml_chain::genesis::network_info::NetworkInfo::preview().into() 37 | } 38 | 39 | pub fn preprod() -> Self { 40 | cml_chain::genesis::network_info::NetworkInfo::preprod().into() 41 | } 42 | 43 | pub fn sancho_testnet() -> Self { 44 | cml_chain::genesis::network_info::NetworkInfo::sancho_testnet().into() 45 | } 46 | } 47 | 48 | #[wasm_bindgen] 49 | pub struct ByronGenesisRedeem(pub (crate) (cml_crypto::TransactionHash, cml_chain::byron::ByronAddress)); 50 | 51 | #[wasm_bindgen] 52 | impl ByronGenesisRedeem { 53 | pub fn new(txid: &TransactionHash, address: &crate::byron::ByronAddress) -> Self { 54 | ByronGenesisRedeem((txid.clone().into(), address.clone().into())) 55 | } 56 | 57 | pub fn txid(&self) -> TransactionHash { 58 | self.0.0.into() 59 | } 60 | 61 | pub fn address(&self) -> crate::byron::ByronAddress { 62 | self.0.1.clone().into() 63 | } 64 | } 65 | 66 | 67 | #[wasm_bindgen] 68 | pub fn genesis_txid_byron(pubkey: &cml_crypto_wasm::PublicKey, protocol_magic: Option) -> ByronGenesisRedeem { 69 | let redeem = cml_chain::genesis::byron::parse::redeem_pubkey_to_txid( 70 | &pubkey.clone().as_ref().0, 71 | protocol_magic.map(|pm| ProtocolMagic::new(pm).into()) 72 | ); 73 | ByronGenesisRedeem(redeem) 74 | } 75 | 76 | #[wasm_bindgen] 77 | pub fn genesis_txid_shelley(address: &crate::address::Address) -> TransactionHash { 78 | TransactionHash::from(cml_chain::genesis::shelley::parse::redeem_address_to_txid(&address.clone().into())) 79 | } 80 | -------------------------------------------------------------------------------- /chain/wasm/src/governance/utils.rs: -------------------------------------------------------------------------------- 1 | use wasm_bindgen::prelude::wasm_bindgen; 2 | 3 | use cml_crypto_wasm::{Ed25519KeyHash, ScriptHash}; 4 | 5 | use super::{GovAction, Voter}; 6 | 7 | #[wasm_bindgen] 8 | impl GovAction { 9 | pub fn script_hash(&self) -> Option { 10 | self.0.script_hash().map(|hash| (*hash).into()) 11 | } 12 | } 13 | 14 | #[wasm_bindgen] 15 | impl Voter { 16 | pub fn key_hash(&self) -> Option { 17 | self.0.key_hash().map(|hash| (*hash).into()) 18 | } 19 | 20 | pub fn script_hash(&self) -> Option { 21 | self.0.script_hash().map(|hash| (*hash).into()) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /chain/wasm/src/json/metadatums.rs: -------------------------------------------------------------------------------- 1 | use crate::auxdata::TransactionMetadatum; 2 | pub use cml_chain::json::metadatums::MetadataJsonSchema; 3 | use wasm_bindgen::prelude::{wasm_bindgen, JsError}; 4 | 5 | /// Converts JSON to Metadata according to MetadataJsonSchema 6 | #[wasm_bindgen] 7 | pub fn encode_json_str_to_metadatum( 8 | json: &str, 9 | schema: MetadataJsonSchema, 10 | ) -> Result { 11 | cml_chain::json::metadatums::encode_json_str_to_metadatum(json, schema) 12 | .map(Into::into) 13 | .map_err(Into::into) 14 | } 15 | 16 | /// Converts Metadata to JSON according to MetadataJsonSchema 17 | #[wasm_bindgen] 18 | pub fn decode_metadatum_to_json_str( 19 | metadatum: &TransactionMetadatum, 20 | schema: MetadataJsonSchema, 21 | ) -> Result { 22 | cml_chain::json::metadatums::decode_metadatum_to_json_str(metadatum.as_ref(), schema) 23 | .map_err(Into::into) 24 | } 25 | -------------------------------------------------------------------------------- /chain/wasm/src/json/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod metadatums; 2 | pub mod plutus_datums; 3 | -------------------------------------------------------------------------------- /chain/wasm/src/json/plutus_datums.rs: -------------------------------------------------------------------------------- 1 | pub use cml_chain::json::plutus_datums::CardanoNodePlutusDatumSchema; 2 | 3 | use crate::plutus::PlutusData; 4 | 5 | use wasm_bindgen::prelude::{wasm_bindgen, JsError}; 6 | 7 | #[wasm_bindgen] 8 | pub fn encode_json_str_to_plutus_datum( 9 | json: &str, 10 | schema: CardanoNodePlutusDatumSchema, 11 | ) -> Result { 12 | cml_chain::json::plutus_datums::encode_json_str_to_plutus_datum(json, schema) 13 | .map(Into::into) 14 | .map_err(Into::into) 15 | } 16 | 17 | #[wasm_bindgen] 18 | pub fn decode_plutus_datum_to_json_str( 19 | datum: &PlutusData, 20 | schema: CardanoNodePlutusDatumSchema, 21 | ) -> Result { 22 | cml_chain::json::plutus_datums::decode_plutus_datum_to_json_str(datum.as_ref(), schema) 23 | .map_err(Into::into) 24 | } 25 | -------------------------------------------------------------------------------- /chain/wasm/src/min_ada.rs: -------------------------------------------------------------------------------- 1 | use wasm_bindgen::prelude::{wasm_bindgen, JsError}; 2 | 3 | use crate::{assets::Coin, transaction::TransactionOutput}; 4 | 5 | #[wasm_bindgen] 6 | pub fn min_ada_required( 7 | output: &TransactionOutput, 8 | coins_per_utxo_byte: Coin, // protocol parameter (in lovelace) 9 | ) -> Result { 10 | cml_chain::min_ada::min_ada_required(output.as_ref(), coins_per_utxo_byte).map_err(Into::into) 11 | } 12 | -------------------------------------------------------------------------------- /cip25/.gitignore: -------------------------------------------------------------------------------- 1 | rust/target/** 2 | 3 | wasm/target/** 4 | wasm/json-gen/target/** 5 | wasm/json-gen/output/** 6 | wasm/json-gen/schemas/** 7 | -------------------------------------------------------------------------------- /cip25/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cml-cip25" 3 | version = "6.2.0" 4 | edition = "2018" 5 | authors = ["dcSpark"] 6 | license = "MIT" 7 | description = "Multiplatform SDK for CIP25 Cardano NFT Metadata functionality" 8 | documentation = "https://github.com/dcSpark/cardano-multiplatform-lib/docs" 9 | repository = "https://github.com/dcSpark/cardano-multiplatform-lib" 10 | readme = "../../README.md" 11 | keywords = ["cardano", "cip25"] 12 | 13 | [lib] 14 | crate-type = ["cdylib", "rlib"] 15 | 16 | [dependencies] 17 | cml-chain = { "path" = "../../chain/rust", version = "6.2.0" } 18 | cml-core = { "path" = "../../core/rust", version = "6.2.0" } 19 | cml-crypto = { "path" = "../../crypto/rust", version = "6.2.0" } 20 | cbor_event = "2.2.0" 21 | hex = "0.4.0" 22 | schemars = "0.8.8" 23 | serde = { version = "1.0", features = ["derive"] } 24 | serde_json = "1.0.57" 25 | thiserror = "1.0.37" 26 | # for enums 27 | wasm-bindgen = { version = "0.2.87" } 28 | -------------------------------------------------------------------------------- /cip25/wasm/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cml-cip25-wasm" 3 | version = "6.2.0" 4 | edition = "2018" 5 | authors = ["dcSpark"] 6 | license = "MIT" 7 | description = "Multiplatform WASM SDK for CIP25 Cardano NFT Metadata functionality" 8 | documentation = "https://github.com/dcSpark/cardano-multiplatform-lib/docs" 9 | repository = "https://github.com/dcSpark/cardano-multiplatform-lib" 10 | readme = "../../README.md" 11 | keywords = ["cardano", "cip25"] 12 | 13 | [lib] 14 | crate-type = ["cdylib", "rlib"] 15 | 16 | [dependencies] 17 | cbor_event = "2.2.0" 18 | cml-chain = { path = "../../chain/rust", version = "6.2.0", features = ["used_from_wasm"] } 19 | cml-chain-wasm = { path = "../../chain/wasm", version = "6.2.0" } 20 | cml-core = { path = "../../core/rust", version = "6.2.0" } 21 | cml-core-wasm = { path = "../../core/wasm", version = "6.2.0" } 22 | cml-cip25 = { path = "../rust", version = "6.2.0" } 23 | hex = "0.4.0" 24 | linked-hash-map = "0.5.3" 25 | serde_json = "1.0.57" 26 | serde-wasm-bindgen = "0.4.5" 27 | wasm-bindgen = { version = "0.2.87" } 28 | -------------------------------------------------------------------------------- /cip25/wasm/README.md: -------------------------------------------------------------------------------- 1 | # cml-cip25 2 | 3 | Multiplatform SDK for CIP25 (Cardano NFT Metadata) 4 | 5 | This can be used for both parsing and creating CIP25-compatible metadata. 6 | 7 | Parsing can either be done directly from metadata bytes: 8 | 9 | ```javascript 10 | let schema = wasm.CIP25.CIP25Metadata.from_bytes(Buffer.from("a11902d1a26464617461a144baadf00da144cafed00da5646e616d656d4d65746164617461204e616d656566696c657382a3637372636473726331646e616d656966696c656e616d6531696d65646961547970656966696c657479706531a3637372636473726332646e616d656966696c656e616d6532696d65646961547970656966696c65747970653265696d6167657821687474733a2f2f736f6d652e776562736974652e636f6d2f696d6167652e706e67696d656469615479706567696d6167652f2a6b6465736372697074696f6e776465736372697074696f6e206f662074686973204e46546776657273696f6e02", "hex")); 11 | 12 | // the above CBOR hex is for a V2 CIP25 schema. You should check which type it is first 13 | // as as_label_metadata_v2() will return None (undefined) if it's a v1 schema 14 | let v2Schema = schema.key_721().as_label_metadata_v2().data(); 15 | let policies = v2Schema.keys(); 16 | for (var i = 0; i < policies.len(); ++i) { 17 | let policy = policies.get(i); 18 | let assets = v2Schema.get(policy); 19 | let assetNames = assets.keys(); 20 | for (var j = 0; j < assetNames.len(); ++j) { 21 | let assetName = assetNames.get(j); 22 | let details = assets.get(assetName); 23 | console.log(`CIP25 NFT ${policy.toString("hex")}.${asset_name.toString("hex")} found:`); 24 | console.log(` name: ${details.name().to_str()}`); 25 | console.log(` image: ${details.image().to_string()}`); 26 | let mediaType = details.media_type(); 27 | if (mediaType != null) { 28 | console.log(` media_type: ${mediaType.to_str()}`); 29 | } 30 | let description = details.media_type(); 31 | if (description != null) { 32 | console.log(` description: ${description.to_str()}`); 33 | } 34 | let files = details.files(); 35 | if (files != null) { 36 | console.log(` files:`); 37 | for (var k = 0; k < files.len(); ++k) { 38 | let file = files.get(k); 39 | console.log(` file #${k + 1}:`); 40 | console.log(` name: ${file.name().to_str()}`); 41 | console.log(` media_type: ${file.media_type().to_str()}`); 42 | console.log(` src: ${file.src().to_string()}`); 43 | } 44 | } 45 | } 46 | } 47 | ``` 48 | 49 | We also support loose NFT parsing to try and parse key information out of potentially incorrectly formatted CIP25 50 | 51 | ```typescript 52 | const details = wasm.CIP25.MiniMetadataDetails.loose_parse(Buffer.from("a1646e616d65694d6574617665727365", "hex")); 53 | console.log(details.name()); 54 | ``` -------------------------------------------------------------------------------- /cip25/wasm/json-gen/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cml-cip25-json-schema-gen" 3 | version = "6.2.0" 4 | edition = "2018" 5 | keywords = ["cardano"] 6 | 7 | [dependencies] 8 | serde_json = "1.0.57" 9 | schemars = "0.8.8" 10 | cml-cip25 = { path = "../../rust", version = "6.2.0" } 11 | -------------------------------------------------------------------------------- /cip25/wasm/json-gen/src/lib.rs: -------------------------------------------------------------------------------- 1 | macro_rules! gen_json_schema { 2 | ($name:ty) => { 3 | let dest_path = 4 | std::path::Path::new(&"schemas").join(&format!("{}.json", stringify!($name))); 5 | std::fs::write( 6 | &dest_path, 7 | serde_json::to_string_pretty(&schemars::schema_for!($name)).unwrap(), 8 | ) 9 | .unwrap(); 10 | }; 11 | } 12 | 13 | pub fn export_schemas() { 14 | let schema_path = std::path::Path::new(&"schemas"); 15 | if !schema_path.exists() { 16 | std::fs::create_dir(schema_path).unwrap(); 17 | } 18 | gen_json_schema!(cml_cip25::CIP25Metadata); 19 | gen_json_schema!(cml_cip25::CIP25Version); 20 | gen_json_schema!(cml_cip25::CIP25ChunkableString); 21 | gen_json_schema!(cml_cip25::CIP25FilesDetails); 22 | gen_json_schema!(cml_cip25::CIP25LabelMetadata); 23 | gen_json_schema!(cml_cip25::CIP25MetadataDetails); 24 | gen_json_schema!(cml_cip25::CIP25String64); 25 | } 26 | -------------------------------------------------------------------------------- /cip25/wasm/json-gen/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | cml_cip25_json_schema_gen::export_schemas(); 3 | } 4 | -------------------------------------------------------------------------------- /cip36/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cml-cip36" 3 | version = "6.2.0" 4 | edition = "2018" 5 | authors = ["dcSpark"] 6 | license = "MIT" 7 | description = "Multiplatform SDK for CIP36 Catalyst voting functionality" 8 | documentation = "https://github.com/dcSpark/cardano-multiplatform-lib/docs" 9 | repository = "https://github.com/dcSpark/cardano-multiplatform-lib" 10 | readme = "../../README.md" 11 | keywords = ["cardano", "cip36"] 12 | 13 | [lib] 14 | crate-type = ["cdylib", "rlib"] 15 | 16 | [dependencies] 17 | cml-core = { "path" = "../../core/rust", version = "6.2.0" } 18 | cml-crypto = { "path" = "../../crypto/rust", version = "6.2.0" } 19 | cml-chain = { "path" = "../../chain/rust", version = "6.2.0" } 20 | cbor_event = "2.2.0" 21 | linked-hash-map = "0.5.3" 22 | derivative = "2.2.0" 23 | serde = { version = "1.0", features = ["derive"] } 24 | serde_json = "1.0.57" 25 | schemars = "0.8.8" 26 | hex = "0.4.0" 27 | thiserror = "1.0.37" -------------------------------------------------------------------------------- /cip36/rust/src/cbor_encodings.rs: -------------------------------------------------------------------------------- 1 | // This file was code-generated using an experimental CDDL to rust tool: 2 | // https://github.com/dcSpark/cddl-codegen 3 | 4 | use cml_core::serialization::{LenEncoding, StringEncoding}; 5 | 6 | #[derive(Clone, Debug, Default)] 7 | pub struct CIP36DelegationEncoding { 8 | pub len_encoding: LenEncoding, 9 | pub voting_pub_key_encoding: StringEncoding, 10 | pub weight_encoding: Option, 11 | } 12 | 13 | #[derive(Clone, Debug, Default)] 14 | pub struct CIP36DeregistrationCborEncoding { 15 | pub len_encoding: LenEncoding, 16 | pub orig_deser_order: Vec, 17 | pub key_deregistration_key_encoding: Option, 18 | pub deregistration_witness_key_encoding: Option, 19 | } 20 | 21 | #[derive(Clone, Debug, Default)] 22 | pub struct CIP36DeregistrationWitnessEncoding { 23 | pub len_encoding: LenEncoding, 24 | pub orig_deser_order: Vec, 25 | pub stake_witness_encoding: StringEncoding, 26 | pub stake_witness_key_encoding: Option, 27 | } 28 | 29 | #[derive(Clone, Debug, Default)] 30 | pub struct CIP36KeyDeregistrationEncoding { 31 | pub len_encoding: LenEncoding, 32 | pub orig_deser_order: Vec, 33 | pub stake_credential_encoding: StringEncoding, 34 | pub stake_credential_key_encoding: Option, 35 | pub nonce_encoding: Option, 36 | pub nonce_key_encoding: Option, 37 | pub voting_purpose_encoding: Option, 38 | pub voting_purpose_default_present: bool, 39 | pub voting_purpose_key_encoding: Option, 40 | } 41 | 42 | #[derive(Clone, Debug, Default)] 43 | pub struct CIP36KeyRegistrationEncoding { 44 | pub len_encoding: LenEncoding, 45 | pub orig_deser_order: Vec, 46 | pub delegation_key_encoding: Option, 47 | pub stake_credential_encoding: StringEncoding, 48 | pub stake_credential_key_encoding: Option, 49 | pub address_key_encoding: Option, 50 | pub nonce_encoding: Option, 51 | pub nonce_key_encoding: Option, 52 | pub voting_purpose_encoding: Option, 53 | pub voting_purpose_default_present: bool, 54 | pub voting_purpose_key_encoding: Option, 55 | } 56 | 57 | #[derive(Clone, Debug, Default)] 58 | pub struct CIP36RegistrationCborEncoding { 59 | pub len_encoding: LenEncoding, 60 | pub orig_deser_order: Vec, 61 | pub key_registration_key_encoding: Option, 62 | pub registration_witness_key_encoding: Option, 63 | } 64 | 65 | #[derive(Clone, Debug, Default)] 66 | pub struct CIP36RegistrationWitnessEncoding { 67 | pub len_encoding: LenEncoding, 68 | pub orig_deser_order: Vec, 69 | pub stake_witness_encoding: StringEncoding, 70 | pub stake_witness_key_encoding: Option, 71 | } 72 | -------------------------------------------------------------------------------- /cip36/rust/src/error.rs: -------------------------------------------------------------------------------- 1 | #[derive(Debug, thiserror::Error)] 2 | pub enum CIP36Error { 3 | #[error("Empty delegation array")] 4 | EmptyDelegationArray, 5 | // TODO: can we check this somehow against anything? I don't believe so, so maybe remove this 6 | // #[error("Reward wrong network")] 7 | // RewardWrongNetwork, 8 | #[error("Invalid delegation weights")] 9 | DelegationWeightsZero, 10 | } 11 | -------------------------------------------------------------------------------- /cip36/wasm/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cml-cip36-wasm" 3 | version = "6.2.0" 4 | edition = "2018" 5 | authors = ["dcSpark"] 6 | license = "MIT" 7 | description = "Multiplatform WASM SDK for CIP36 Catalyst voting functionality" 8 | documentation = "https://github.com/dcSpark/cardano-multiplatform-lib/docs" 9 | repository = "https://github.com/dcSpark/cardano-multiplatform-lib" 10 | readme = "../../README.md" 11 | keywords = ["cardano", "cip36"] 12 | 13 | [lib] 14 | crate-type = ["cdylib", "rlib"] 15 | 16 | [dependencies] 17 | cml-cip36 = { path = "../rust", version = "6.2.0" } 18 | cml-crypto = { path = "../../crypto/rust", version = "6.2.0" } 19 | cml-crypto-wasm = { path = "../../crypto/wasm", version = "6.2.0" } 20 | cml-chain = { path = "../../chain/rust", version = "6.2.0" } 21 | cml-chain-wasm = { path = "../../chain/wasm", version = "6.2.0" } 22 | cml-core = { path = "../../core/rust", version = "6.2.0" } 23 | cml-core-wasm = { path = "../../core/wasm", version = "6.2.0" } 24 | cbor_event = "2.2.0" 25 | hex = "0.4.0" 26 | wasm-bindgen = { version = "0.2.87" } 27 | linked-hash-map = "0.5.3" 28 | serde_json = "1.0.57" 29 | serde-wasm-bindgen = "0.4.5" 30 | -------------------------------------------------------------------------------- /cip36/wasm/json-gen/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cml-cip36-json-schema-gen" 3 | version = "6.2.0" 4 | edition = "2018" 5 | 6 | 7 | [dependencies] 8 | serde_json = "1.0.57" 9 | schemars = "0.8.8" 10 | cml-cip36 = { path = "../../rust" } 11 | -------------------------------------------------------------------------------- /cip36/wasm/json-gen/src/lib.rs: -------------------------------------------------------------------------------- 1 | macro_rules! gen_json_schema { 2 | ($name:ty) => { 3 | let dest_path = 4 | std::path::Path::new(&"schemas").join(&format!("{}.json", stringify!($name))); 5 | std::fs::write( 6 | &dest_path, 7 | serde_json::to_string_pretty(&schemars::schema_for!($name)).unwrap(), 8 | ) 9 | .unwrap(); 10 | }; 11 | } 12 | 13 | pub fn export_schemas() { 14 | let schema_path = std::path::Path::new(&"schemas"); 15 | if !schema_path.exists() { 16 | std::fs::create_dir(schema_path).unwrap(); 17 | } 18 | gen_json_schema!(cml_cip36::CIP36Delegation); 19 | gen_json_schema!(cml_cip36::CIP36DelegationDistribution); 20 | gen_json_schema!(cml_cip36::CIP36DeregistrationCbor); 21 | gen_json_schema!(cml_cip36::CIP36DeregistrationWitness); 22 | gen_json_schema!(cml_cip36::CIP36KeyDeregistration); 23 | gen_json_schema!(cml_cip36::CIP36KeyRegistration); 24 | gen_json_schema!(cml_cip36::CIP36RegistrationCbor); 25 | gen_json_schema!(cml_cip36::CIP36RegistrationWitness); 26 | } 27 | -------------------------------------------------------------------------------- /cip36/wasm/json-gen/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | cml_cip36_json_schema_gen::export_schemas(); 3 | } 4 | -------------------------------------------------------------------------------- /cml/README.md: -------------------------------------------------------------------------------- 1 | This crate is for the general-purpose WASM package. We don't have WASM packages for every single crate due to shared dependencies not being possible, so using, for example, cml-cip25-wasm + cml-cip36-wasm + cml-chain-wasm together would result in 3 copies of cml-chain-wasm that are not compatible with each other. This crate combines all wasm crates except for cml-multi-era-wasm (due to size reasons) together in one place and as such has no equivalent rust crate. -------------------------------------------------------------------------------- /cml/wasm/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cardano-multiplatform-lib" 3 | version = "6.2.0" 4 | edition = "2018" 5 | keywords = ["cardano"] 6 | license = "MIT" 7 | description = "Multiplatform WASM SDK containing the most common CML crates for Cardano blockchain functionality" 8 | documentation = "https://github.com/dcSpark/cardano-multiplatform-lib/docs" 9 | repository = "https://github.com/dcSpark/cardano-multiplatform-lib" 10 | readme = "../../README.md" 11 | 12 | [lib] 13 | crate-type = ["cdylib", "rlib"] 14 | 15 | [dependencies] 16 | cml-chain-wasm = { path = "../../chain/wasm", version = "6.2.0" } 17 | cml-cip25-wasm = { path = "../../cip25/wasm", version = "6.2.0" } 18 | cml-cip36-wasm = { path = "../../cip36/wasm", version = "6.2.0" } 19 | cml-crypto-wasm = { path = "../../crypto/wasm", version = "6.2.0" } 20 | cml-core-wasm = { path = "../../core/wasm", version = "6.2.0" } 21 | cbor_event = "2.4.0" 22 | hex = "0.4.0" 23 | linked-hash-map = "0.5.3" 24 | serde_json = "1.0.57" 25 | serde-wasm-bindgen = "0.4.5" 26 | wasm-bindgen = { version = "0.2.87" } 27 | -------------------------------------------------------------------------------- /cml/wasm/json-gen/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cardano-multiplatform-lib-json-schema-gen" 3 | version = "0.0.1" 4 | edition = "2018" 5 | 6 | 7 | [dependencies] 8 | serde_json = "1.0.57" 9 | schemars = "0.8.8" 10 | cml-chain-json-schema-gen = { path = "../../../chain/wasm/json-gen" } 11 | cml-cip25-json-schema-gen = { path = "../../../cip25/wasm/json-gen" } 12 | cml-cip36-json-schema-gen = { path = "../../../cip36/wasm/json-gen" } 13 | -------------------------------------------------------------------------------- /cml/wasm/json-gen/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | cml_cip25_json_schema_gen::export_schemas(); 3 | cml_cip36_json_schema_gen::export_schemas(); 4 | cml_chain_json_schema_gen::export_schemas(); 5 | } 6 | -------------------------------------------------------------------------------- /cml/wasm/src/lib.rs: -------------------------------------------------------------------------------- 1 | // In order to have wasm-bindgen export types we need to import at least one type 2 | // from each other crate. 3 | // We can't use pub use cml_foo_wasm::*; as that will generate a warning due to 4 | // multiple of them including a utils module so we just import an arbitrary type. 5 | // We don't need to worry about cml_core_wasm and cml_crypto_wasm since they 6 | // will be exported by the other crates here. 7 | pub use cml_chain_wasm::AssetNameList; 8 | pub use cml_cip25_wasm::CIP25Metadata; 9 | pub use cml_cip36_wasm::CIP36DeregistrationCbor; 10 | -------------------------------------------------------------------------------- /core/README.md: -------------------------------------------------------------------------------- 1 | # Core 2 | 3 | The most core types for cardano-multiplatform-lib. Used for core serialization types, errors, etc that will be used by other consuming crates within cardano-multiplatform-lib. End users should never have to use this crate directly. 4 | -------------------------------------------------------------------------------- /core/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cml-core" 3 | version = "6.2.0" 4 | edition = "2018" 5 | authors = ["dcSpark"] 6 | license = "MIT" 7 | description = "Multiplatform SDK for core Cardano blockchain functionality" 8 | documentation = "https://github.com/dcSpark/cardano-multiplatform-lib/docs" 9 | repository = "https://github.com/dcSpark/cardano-multiplatform-lib" 10 | readme = "../../README.md" 11 | keywords = ["cardano"] 12 | 13 | [lib] 14 | crate-type = ["cdylib", "rlib"] 15 | 16 | [dependencies] 17 | cbor_event = "2.2.0" 18 | linked-hash-map = "0.5.3" 19 | derivative = "2.2.0" 20 | serde = { version = "1.0", features = ["derive"] } 21 | serde_json = "1.0.57" 22 | schemars = "0.8.8" 23 | 24 | bech32 = "0.7.2" 25 | hex = "0.4.0" 26 | itertools = "0.10.1" 27 | getrandom = { version = "0.2.3", features = ["js"] } 28 | rand = "0.8.5" 29 | fraction = "0.10.0" 30 | base64 = "0.13" 31 | num-bigint = "0.4.0" 32 | num-integer = "0.1.45" 33 | #rand_os = "0.1" 34 | thiserror = "1.0.37" 35 | cfg-if = "1" 36 | 37 | 38 | [dev-dependencies] 39 | quickcheck = "0.9.2" 40 | quickcheck_macros = "0.9.1" 41 | rand_chacha = "0.3.1" 42 | -------------------------------------------------------------------------------- /core/rust/src/network.rs: -------------------------------------------------------------------------------- 1 | use crate::{error::DeserializeError, serialization::Deserialize}; 2 | use cbor_event::de::Deserializer; 3 | use cbor_event::se::Serializer; 4 | use schemars::JsonSchema; 5 | use std::io::{BufRead, Write}; 6 | 7 | pub static BYRON_MAINNET_NETWORK_MAGIC: u32 = 764824073; 8 | pub static BYRON_TESTNET_NETWORK_MAGIC: u32 = 1097911063; 9 | pub static SANCHO_TESTNET_NETWORK_MAGIC: u32 = 4; 10 | pub static PREPROD_NETWORK_MAGIC: u32 = 1; 11 | pub static PREVIEW_NETWORK_MAGIC: u32 = 2; 12 | 13 | impl std::fmt::Display for ProtocolMagic { 14 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 15 | write!(f, "{}", self.0) 16 | } 17 | } 18 | 19 | #[derive( 20 | Clone, 21 | Copy, 22 | Debug, 23 | Eq, 24 | Ord, 25 | PartialEq, 26 | PartialOrd, 27 | Hash, 28 | serde::Serialize, 29 | serde::Deserialize, 30 | JsonSchema, 31 | )] 32 | pub struct ProtocolMagic(u32); 33 | 34 | impl From for u32 { 35 | fn from(val: ProtocolMagic) -> Self { 36 | val.0 37 | } 38 | } 39 | 40 | impl From for ProtocolMagic { 41 | fn from(inner: u32) -> Self { 42 | ProtocolMagic(inner) 43 | } 44 | } 45 | 46 | impl ::std::ops::Deref for ProtocolMagic { 47 | type Target = u32; 48 | fn deref(&self) -> &Self::Target { 49 | &self.0 50 | } 51 | } 52 | 53 | impl Default for ProtocolMagic { 54 | fn default() -> Self { 55 | Self(764824073) 56 | } 57 | } 58 | 59 | impl cbor_event::se::Serialize for ProtocolMagic { 60 | fn serialize<'se, W: Write>( 61 | &self, 62 | serializer: &'se mut Serializer, 63 | ) -> cbor_event::Result<&'se mut Serializer> { 64 | serializer.write_unsigned_integer(self.0 as u64) 65 | } 66 | } 67 | 68 | impl Deserialize for ProtocolMagic { 69 | fn deserialize(raw: &mut Deserializer) -> Result { 70 | Ok(Self(raw.unsigned_integer()? as u32)) 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /core/wasm/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cml-core-wasm" 3 | version = "6.2.0" 4 | edition = "2018" 5 | keywords = ["cardano"] 6 | license = "MIT" 7 | description = "Multiplatform WASM SDK for core Cardano blockchain functionality" 8 | documentation = "https://github.com/dcSpark/cardano-multiplatform-lib/docs" 9 | repository = "https://github.com/dcSpark/cardano-multiplatform-lib" 10 | readme = "../../README.md" 11 | 12 | [lib] 13 | crate-type = ["cdylib", "rlib"] 14 | 15 | [dependencies] 16 | cml-core = { path = "../rust", version = "6.2.0" } 17 | cbor_event = "2.2.0" 18 | hex = "0.4.0" 19 | wasm-bindgen = { version = "0.2.87" } 20 | linked-hash-map = "0.5.3" 21 | serde_json = "1.0.57" 22 | serde-wasm-bindgen = "0.4.5" 23 | -------------------------------------------------------------------------------- /core/wasm/src/lib.rs: -------------------------------------------------------------------------------- 1 | use wasm_bindgen::prelude::{wasm_bindgen, JsValue}; 2 | 3 | use cml_core::serialization::{Deserialize, Serialize}; 4 | 5 | // re-export to make macros easier to use 6 | pub use cml_core::serialization::RawBytesEncoding; 7 | 8 | #[macro_use] 9 | pub mod wasm_wrappers; 10 | 11 | #[wasm_bindgen] 12 | #[derive(Clone, Debug)] 13 | pub struct Int(cml_core::Int); 14 | 15 | #[wasm_bindgen] 16 | 17 | impl Int { 18 | pub fn to_cbor_bytes(&self) -> Vec { 19 | Serialize::to_cbor_bytes(&self.0) 20 | } 21 | 22 | pub fn from_cbor_bytes(cbor_bytes: &[u8]) -> Result { 23 | Deserialize::from_cbor_bytes(cbor_bytes) 24 | .map(Self) 25 | .map_err(|e| JsValue::from_str(&format!("from_bytes: {e}"))) 26 | } 27 | 28 | pub fn to_json(&self) -> Result { 29 | serde_json::to_string_pretty(&self.0) 30 | .map_err(|e| JsValue::from_str(&format!("to_json: {e}"))) 31 | } 32 | 33 | pub fn to_json_value(&self) -> Result { 34 | serde_wasm_bindgen::to_value(&self.0) 35 | .map_err(|e| JsValue::from_str(&format!("to_js_value: {e}"))) 36 | } 37 | 38 | pub fn from_json(json: &str) -> Result { 39 | serde_json::from_str(json) 40 | .map(Self) 41 | .map_err(|e| JsValue::from_str(&format!("from_json: {e}"))) 42 | } 43 | 44 | pub fn new(x: i64) -> Self { 45 | if x >= 0 { 46 | Self(cml_core::Int::new_uint(x as u64)) 47 | } else { 48 | Self(cml_core::Int::new_nint((x + 1).unsigned_abs())) 49 | } 50 | } 51 | 52 | pub fn to_str(&self) -> String { 53 | self.0.to_string() 54 | } 55 | 56 | #[allow(clippy::should_implement_trait)] 57 | pub fn from_str(string: &str) -> Result { 58 | // have to redefine so it's visible in WASM 59 | std::str::FromStr::from_str(string) 60 | .map(Self) 61 | .map_err(|e| JsValue::from_str(&format!("Int.from_str({string}): {e:?}"))) 62 | } 63 | } 64 | 65 | impl From for Int { 66 | fn from(native: cml_core::Int) -> Self { 67 | Self(native) 68 | } 69 | } 70 | 71 | impl From for cml_core::Int { 72 | fn from(wasm: Int) -> Self { 73 | wasm.0 74 | } 75 | } 76 | 77 | impl AsRef for Int { 78 | fn as_ref(&self) -> &cml_core::Int { 79 | &self.0 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /crypto/README.md: -------------------------------------------------------------------------------- 1 | # Crypto 2 | 3 | Cryptography-related components for cardano-serialization-lib. 4 | -------------------------------------------------------------------------------- /crypto/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cml-crypto" 3 | version = "6.2.0" 4 | edition = "2018" 5 | authors = ["dcSpark"] 6 | license = "MIT" 7 | description = "Multiplatform SDK for Cardano-related cryptographic functionality" 8 | documentation = "https://github.com/dcSpark/cardano-multiplatform-lib/docs" 9 | repository = "https://github.com/dcSpark/cardano-multiplatform-lib" 10 | readme = "../../README.md" 11 | keywords = ["cardano"] 12 | 13 | [lib] 14 | crate-type = ["cdylib", "rlib"] 15 | 16 | [dependencies] 17 | cml-core = { "path" = "../../core/rust", version = "6.2.0" } 18 | base64 = "0.21.5" 19 | cbor_event = "2.2.0" 20 | cryptoxide = "0.4.2" 21 | ed25519-bip32 = "0.4.1" 22 | sha2 = "^0.9" 23 | digest = "^0.9" 24 | bech32 = "0.7.2" 25 | hex = "0.4.0" 26 | thiserror = "1.0.37" 27 | rand = "0.8.5" 28 | cfg-if = "1" 29 | 30 | derivative = "2.2.0" 31 | serde = { version = "1.0", features = ["derive"] } 32 | serde_json = "1.0.57" 33 | schemars = "0.8.8" 34 | 35 | [dev-dependencies] 36 | quickcheck = "0.9.2" 37 | quickcheck_macros = "0.9.1" 38 | rand_chacha = "0.3.1" 39 | -------------------------------------------------------------------------------- /crypto/rust/src/chain_core/mod.rs: -------------------------------------------------------------------------------- 1 | cfg_if! { 2 | if #[cfg(test)] { 3 | extern crate quickcheck; 4 | } else if #[cfg(feature = "property-test-api")] { 5 | extern crate quickcheck; 6 | } 7 | } 8 | 9 | pub mod abor; 10 | pub mod mempack; 11 | pub mod packer; 12 | pub mod property; 13 | -------------------------------------------------------------------------------- /crypto/rust/src/chain_crypto/algorithms/ed25519_extended.rs: -------------------------------------------------------------------------------- 1 | use crate::chain_crypto::key::{ 2 | AsymmetricKey, AsymmetricPublicKey, SecretKeyError, SecretKeySizeStatic, 3 | }; 4 | use crate::chain_crypto::sign::SigningAlgorithm; 5 | 6 | use super::ed25519 as ei; 7 | 8 | use cryptoxide::ed25519; 9 | use rand::{CryptoRng, RngCore}; 10 | 11 | use ed25519_bip32::{XPrv, XPRV_SIZE}; 12 | 13 | /// ED25519 Signing Algorithm with extended secret key 14 | pub struct Ed25519Extended; 15 | 16 | #[derive(Clone)] 17 | pub struct ExtendedPriv([u8; ed25519::EXTENDED_KEY_LENGTH]); 18 | 19 | impl AsRef<[u8]> for ExtendedPriv { 20 | fn as_ref(&self) -> &[u8] { 21 | &self.0[..] 22 | } 23 | } 24 | 25 | impl ExtendedPriv { 26 | pub fn from_xprv(xprv: &XPrv) -> Self { 27 | let mut buf = [0; ed25519::EXTENDED_KEY_LENGTH]; 28 | xprv.get_extended_mut(&mut buf); 29 | ExtendedPriv(buf) 30 | } 31 | } 32 | 33 | impl AsymmetricKey for Ed25519Extended { 34 | type Secret = ExtendedPriv; 35 | type PubAlg = ei::Ed25519; 36 | 37 | const SECRET_BECH32_HRP: &'static str = "ed25519e_sk"; 38 | 39 | fn generate(mut rng: T) -> Self::Secret { 40 | let mut priv_bytes = [0u8; XPRV_SIZE]; 41 | rng.fill_bytes(&mut priv_bytes); 42 | let xprv = XPrv::normalize_bytes_force3rd(priv_bytes); 43 | 44 | let mut out = [0u8; ed25519::EXTENDED_KEY_LENGTH]; 45 | xprv.get_extended_mut(&mut out); 46 | ExtendedPriv(out) 47 | } 48 | 49 | fn compute_public(key: &Self::Secret) -> ::Public { 50 | let pk = ed25519::extended_to_public(&key.0); 51 | ei::Pub(pk) 52 | } 53 | 54 | fn secret_from_binary(data: &[u8]) -> Result { 55 | if data.len() != ed25519::EXTENDED_KEY_LENGTH { 56 | return Err(SecretKeyError::SizeInvalid); 57 | } 58 | let mut buf = [0; ed25519::EXTENDED_KEY_LENGTH]; 59 | buf.clone_from_slice(data); 60 | // TODO structure check 61 | Ok(ExtendedPriv(buf)) 62 | } 63 | } 64 | 65 | impl SecretKeySizeStatic for Ed25519Extended { 66 | const SECRET_KEY_SIZE: usize = ed25519::PRIVATE_KEY_LENGTH; 67 | } 68 | 69 | impl SigningAlgorithm for Ed25519Extended { 70 | fn sign(key: &Self::Secret, msg: &[u8]) -> ei::Sig { 71 | ei::Sig(ed25519::signature_extended(msg, &key.0)) 72 | } 73 | } 74 | 75 | #[cfg(test)] 76 | mod test { 77 | use super::*; 78 | 79 | use crate::chain_crypto::key::KeyPair; 80 | use crate::chain_crypto::sign::test::{keypair_signing_ko, keypair_signing_ok}; 81 | use quickcheck_macros::quickcheck; 82 | 83 | #[quickcheck] 84 | fn sign_ok(input: (KeyPair, Vec)) -> bool { 85 | keypair_signing_ok(input) 86 | } 87 | 88 | #[quickcheck] 89 | fn sign_ko(input: (KeyPair, KeyPair, Vec)) -> bool { 90 | keypair_signing_ko(input) 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /crypto/rust/src/chain_crypto/algorithms/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod ed25519; 2 | pub mod ed25519_derive; 3 | pub mod ed25519_extended; 4 | pub mod legacy_daedalus; 5 | 6 | pub use ed25519::Ed25519; 7 | pub use ed25519_derive::Ed25519Bip32; 8 | pub use ed25519_extended::Ed25519Extended; 9 | pub use legacy_daedalus::LegacyDaedalus; 10 | -------------------------------------------------------------------------------- /crypto/rust/src/chain_crypto/bech32.rs: -------------------------------------------------------------------------------- 1 | use bech32::{Error as Bech32Error, FromBase32, ToBase32}; 2 | use std::error::Error as StdError; 3 | use std::fmt; 4 | use std::result::Result as StdResult; 5 | 6 | pub type Result = StdResult; 7 | 8 | pub trait Bech32 { 9 | const BECH32_HRP: &'static str; 10 | 11 | fn try_from_bech32_str(bech32_str: &str) -> Result 12 | where 13 | Self: Sized; 14 | 15 | fn to_bech32_str(&self) -> String; 16 | } 17 | 18 | pub fn to_bech32_from_bytes(bytes: &[u8]) -> String { 19 | bech32::encode(B::BECH32_HRP, bytes.to_base32()) 20 | .unwrap_or_else(|e| panic!("Failed to build bech32: {}", e)) 21 | } 22 | 23 | pub fn try_from_bech32_to_bytes(bech32_str: &str) -> Result> { 24 | let (hrp, bech32_data) = bech32::decode(bech32_str)?; 25 | if hrp != B::BECH32_HRP { 26 | return Err(Error::HrpInvalid { 27 | expected: B::BECH32_HRP, 28 | actual: hrp, 29 | }); 30 | } 31 | Vec::::from_base32(&bech32_data).map_err(Into::into) 32 | } 33 | 34 | #[derive(Debug)] 35 | pub enum Error { 36 | Bech32Malformed(Bech32Error), 37 | HrpInvalid { 38 | expected: &'static str, 39 | actual: String, 40 | }, 41 | DataInvalid(Box), 42 | } 43 | 44 | impl Error { 45 | pub fn data_invalid(cause: impl StdError + Send + Sync + 'static) -> Self { 46 | Error::DataInvalid(Box::new(cause)) 47 | } 48 | } 49 | 50 | impl From for Error { 51 | fn from(error: Bech32Error) -> Self { 52 | Error::Bech32Malformed(error) 53 | } 54 | } 55 | 56 | impl fmt::Display for Error { 57 | fn fmt(&self, f: &mut fmt::Formatter) -> StdResult<(), fmt::Error> { 58 | match self { 59 | Error::Bech32Malformed(_) => write!(f, "Failed to parse bech32, invalid data format"), 60 | Error::HrpInvalid { expected, actual } => write!( 61 | f, 62 | "Parsed bech32 has invalid HRP prefix '{actual}', expected '{expected}'" 63 | ), 64 | Error::DataInvalid(_) => write!(f, "Failed to parse data decoded from bech32"), 65 | } 66 | } 67 | } 68 | 69 | impl StdError for Error { 70 | fn source(&self) -> Option<&(dyn StdError + 'static)> { 71 | match self { 72 | Error::Bech32Malformed(cause) => Some(cause), 73 | Error::DataInvalid(cause) => Some(&**cause), 74 | _ => None, 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /crypto/rust/src/chain_crypto/byron_tags.rs: -------------------------------------------------------------------------------- 1 | pub enum SigningTag { 2 | Tx = 0x01, 3 | RedeemTx = 0x02, 4 | VssCert = 0x03, 5 | USProposal = 0x04, 6 | Commitment = 0x05, 7 | USVote = 0x06, 8 | MainBlock = 0x07, 9 | MainBlockLight = 0x08, 10 | MainBlockHeavy = 0x09, 11 | ProxySK = 0x0a, 12 | } 13 | -------------------------------------------------------------------------------- /crypto/rust/src/chain_crypto/derive.rs: -------------------------------------------------------------------------------- 1 | use crate::chain_crypto::algorithms::{ 2 | ed25519::Pub, ed25519_derive::Ed25519Bip32, ed25519_extended::ExtendedPriv, Ed25519, 3 | }; 4 | use crate::chain_crypto::key::{PublicKey, SecretKey}; 5 | use crate::chain_crypto::Ed25519Extended; 6 | use cryptoxide::hmac::Hmac; 7 | use cryptoxide::pbkdf2::pbkdf2; 8 | use cryptoxide::sha2::Sha512; 9 | use ed25519_bip32::{DerivationError, DerivationScheme, PublicKeyError}; 10 | use ed25519_bip32::{XPrv, XPRV_SIZE}; 11 | 12 | pub fn derive_sk_ed25519(key: &SecretKey, index: u32) -> SecretKey { 13 | let new_key = key.0.derive(DerivationScheme::V2, index); 14 | SecretKey(new_key) 15 | } 16 | 17 | pub fn derive_pk_ed25519( 18 | key: &PublicKey, 19 | index: u32, 20 | ) -> Result, DerivationError> { 21 | key.0.derive(DerivationScheme::V2, index).map(PublicKey) 22 | } 23 | 24 | pub fn to_raw_sk(key: &SecretKey) -> SecretKey { 25 | SecretKey(ExtendedPriv::from_xprv(&key.0)) 26 | } 27 | 28 | pub fn to_raw_pk(key: &PublicKey) -> PublicKey { 29 | PublicKey(Pub::from_xpub(&key.0)) 30 | } 31 | 32 | pub fn combine_pk_and_chaincode( 33 | key: PublicKey, 34 | chaincode: &[u8], 35 | ) -> Result, PublicKeyError> { 36 | let mut buf = [0; ed25519_bip32::XPUB_SIZE]; 37 | buf[0..cryptoxide::ed25519::PUBLIC_KEY_LENGTH].clone_from_slice(key.as_ref()); 38 | buf[cryptoxide::ed25519::PUBLIC_KEY_LENGTH..ed25519_bip32::XPUB_SIZE] 39 | .clone_from_slice(chaincode); 40 | let xpub = ed25519_bip32::XPub::from_slice(&buf)?; 41 | Ok(PublicKey(xpub)) 42 | } 43 | 44 | pub fn from_bip39_entropy(entropy: &[u8], password: &[u8]) -> SecretKey { 45 | let mut pbkdf2_result = [0; XPRV_SIZE]; 46 | 47 | const ITER: u32 = 4096; 48 | let mut mac = Hmac::new(Sha512::new(), password); 49 | pbkdf2(&mut mac, entropy, ITER, &mut pbkdf2_result); 50 | 51 | SecretKey(XPrv::normalize_bytes_force3rd(pbkdf2_result)) 52 | } 53 | -------------------------------------------------------------------------------- /crypto/rust/src/chain_crypto/mod.rs: -------------------------------------------------------------------------------- 1 | cfg_if! { 2 | if #[cfg(test)] { 3 | mod testing; 4 | } else if #[cfg(feature = "property-test-api")] { 5 | pub mod testing; 6 | } 7 | } 8 | 9 | pub mod algorithms; 10 | pub mod bech32; 11 | pub mod byron_proxy_key; 12 | pub mod byron_tags; 13 | pub mod derive; 14 | pub mod digest; 15 | pub mod hash; 16 | mod key; 17 | pub(crate) mod securemem; 18 | mod sign; 19 | 20 | pub use algorithms::*; 21 | pub use hash::{Blake2b256, Sha3_256}; 22 | pub use key::{ 23 | AsymmetricKey, AsymmetricPublicKey, KeyPair, PublicKey, PublicKeyError, PublicKeyFromStrError, 24 | SecretKey, SecretKeyError, SecretKeyFromStrError, SecretKeySizeStatic, 25 | }; 26 | pub use sign::{ 27 | Signature, SignatureError, SignatureFromStrError, SigningAlgorithm, Verification, 28 | VerificationAlgorithm, 29 | }; 30 | -------------------------------------------------------------------------------- /crypto/rust/src/chain_crypto/securemem.rs: -------------------------------------------------------------------------------- 1 | /// zero the given slice. 2 | /// 3 | /// We assume the compiler won't optimise out the call to this function 4 | pub fn _zero(to_zero: &mut [u8]) { 5 | // the unsafety of this call is bounded to the existence of the pointer 6 | // and the accuracy of the length of the array. 7 | // 8 | // since to_zero existence is bound to live at least as long as the call 9 | // of this function and that we use the length (in bytes) of the given 10 | // slice, this call is safe. 11 | unsafe { ::std::ptr::write_bytes(to_zero.as_mut_ptr(), 0, to_zero.len()) } 12 | } 13 | -------------------------------------------------------------------------------- /crypto/rust/src/impl_mockchain/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod key; 2 | -------------------------------------------------------------------------------- /crypto/wasm/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cml-crypto-wasm" 3 | version = "6.2.0" 4 | edition = "2018" 5 | authors = ["dcSpark"] 6 | license = "MIT" 7 | description = "Multiplatform WASM SDK for Cardano-related cryptographic functionality" 8 | documentation = "https://github.com/dcSpark/cardano-multiplatform-lib/docs" 9 | repository = "https://github.com/dcSpark/cardano-multiplatform-lib" 10 | readme = "../../README.md" 11 | keywords = ["cardano"] 12 | 13 | [lib] 14 | crate-type = ["cdylib", "rlib"] 15 | 16 | [dependencies] 17 | cml-core-wasm = { path = "../../core/wasm", version = "6.2.0" } 18 | cml-crypto = { path = "../rust", version = "6.2.0" } 19 | cbor_event = "2.2.0" 20 | wasm-bindgen = { version = "0.2.87" } 21 | linked-hash-map = "0.5.3" 22 | serde_json = "1.0.57" 23 | -------------------------------------------------------------------------------- /crypto/wasm/README.md: -------------------------------------------------------------------------------- 1 | # crypto-wasm 2 | 3 | WASM bindings covering the `crypto-wasm` crate. On-chain crypto primitives are still in the `wasm` crate. 4 | -------------------------------------------------------------------------------- /crypto/wasm/src/emip3.rs: -------------------------------------------------------------------------------- 1 | use wasm_bindgen::prelude::{wasm_bindgen, JsError}; 2 | 3 | /// Encrypt using Emip3: https://github.com/Emurgo/EmIPs/blob/master/specs/emip-003.md 4 | #[wasm_bindgen] 5 | pub fn emip3_encrypt_with_password( 6 | password: &str, 7 | salt: &str, 8 | nonce: &str, 9 | data: &str, 10 | ) -> Result { 11 | cml_crypto::emip3::emip3_encrypt_with_password(password, salt, nonce, data).map_err(Into::into) 12 | } 13 | 14 | /// Decrypt using Emip3: https://github.com/Emurgo/EmIPs/blob/master/specs/emip-003.md 15 | #[wasm_bindgen] 16 | pub fn emip3_decrypt_with_password(password: &str, data: &str) -> Result { 17 | cml_crypto::emip3::emip3_decrypt_with_password(password, data).map_err(Into::into) 18 | } 19 | -------------------------------------------------------------------------------- /docs/.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | ### Installation 2 | 3 | ``` 4 | $ npm install 5 | ``` 6 | 7 | ### Local Development 8 | 9 | ``` 10 | $ npm run start 11 | ``` 12 | 13 | This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. 14 | 15 | ### Build 16 | 17 | ``` 18 | $ npm run build 19 | ``` 20 | 21 | This command generates static content into the `build` directory and can be served using any static contents hosting service. 22 | -------------------------------------------------------------------------------- /docs/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [require.resolve('@docusaurus/core/lib/babel/preset')], 3 | }; 4 | -------------------------------------------------------------------------------- /docs/crowdin.yml: -------------------------------------------------------------------------------- 1 | preserve_hierarchy: true 2 | files: 3 | - source: /i18n/en/**/* 4 | translation: /i18n/%two_letters_code%/**/%original_file_name% 5 | - source: /docs/**/* 6 | translation: /i18n/%two_letters_code%/docusaurus-plugin-content-docs/current/**/%original_file_name% 7 | -------------------------------------------------------------------------------- /docs/docs/crate_architecture.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 3 3 | --- 4 | 5 | 6 | # Crate Architecture 7 | 8 | - **Core** - Core types common throughout all CML crates. 9 | 10 | - **Chain** - Current era on-chain types, plus utility functionality and builders for creating these types. This is likely the crate most users will want to use. 11 | 12 | - **Crypto** - Crypto primitives used throughout CML. Keys, signatures, etc. 13 | 14 | - **CIP25** - Library for working with CIP25 NFT metadata. 15 | 16 | - **CIP36** - Library for working with CIP36 (catalyst) registration types. 17 | 18 | - **Multi-Era** - On-chain types for previous eras (Byron, Shelley, Alonzo, Babbage, etc) plus era-agnostic wrappers around this for parsing historical blockchain data. -------------------------------------------------------------------------------- /docs/docs/enums.mdx_bak: -------------------------------------------------------------------------------- 1 | # Enums 2 | 3 | ## Certificate 4 | 5 | ### CertificateEnum 6 | 7 | ```rust 8 | pub enum CertificateEnum { 9 | StakeRegistration(StakeRegistration), 10 | StakeDeregistration(StakeDeregistration), 11 | StakeDelegation(StakeDelegation), 12 | PoolRegistration(PoolRegistration), 13 | PoolRetirement(PoolRetirement), 14 | GenesisKeyDelegation(GenesisKeyDelegation), 15 | MoveInstantaneousRewardsCert(MoveInstantaneousRewardsCert), 16 | } 17 | ``` 18 | 19 | ### CertificateKind 20 | 21 | ```rust 22 | pub enum CertificateKind { 23 | StakeRegistration, 24 | StakeDeregistration, 25 | StakeDelegation, 26 | PoolRegistration, 27 | PoolRetirement, 28 | GenesisKeyDelegation, 29 | MoveInstantaneousRewardsCert, 30 | } 31 | ``` 32 | 33 | ## Datum 34 | 35 | ### DatumKind 36 | 37 | ```rust 38 | pub enum DatumKind { 39 | Hash, 40 | Inline, 41 | } 42 | ``` 43 | 44 | ## MIR 45 | 46 | ### MIREnum 47 | 48 | ```rust 49 | pub enum MIREnum { 50 | ToOtherPot(Coin), 51 | ToStakeCredentials(MIRToStakeCredentials), 52 | } 53 | ``` 54 | 55 | ### MIRKind 56 | 57 | ```rust 58 | pub enum MIRKind { 59 | ToOtherPot, 60 | ToStakeCredentials, 61 | } 62 | ``` 63 | 64 | 65 | ### MIRPot 66 | 67 | ```rust 68 | pub enum MIRPot { 69 | Reserves, 70 | Treasury, 71 | } 72 | ``` 73 | 74 | ## NativeScript 75 | 76 | ### NativeScriptEnum 77 | 78 | ```rust 79 | pub enum NativeScriptEnum { 80 | ScriptPubkey(ScriptPubkey), 81 | ScriptAll(ScriptAll), 82 | ScriptAny(ScriptAny), 83 | ScriptNOfK(ScriptNOfK), 84 | TimelockStart(TimelockStart), 85 | TimelockExpiry(TimelockExpiry), 86 | } 87 | ``` 88 | 89 | 90 | ### NativeScriptKind 91 | 92 | ```rust 93 | pub enum NativeScriptKind { 94 | ScriptPubkey, 95 | ScriptAll, 96 | ScriptAny, 97 | ScriptNOfK, 98 | TimelockStart, 99 | TimelockExpiry, 100 | } 101 | ``` 102 | 103 | ## NetworkId 104 | 105 | ### NetworkIdKind 106 | 107 | ```rust 108 | pub enum NetworkIdKind { 109 | Testnet, 110 | Mainnet, 111 | } 112 | ``` 113 | 114 | ## Relay 115 | 116 | ### RelayEnum 117 | 118 | ```rust 119 | pub enum RelayEnum { 120 | SingleHostAddr(SingleHostAddr), 121 | SingleHostName(SingleHostName), 122 | MultiHostName(MultiHostName), 123 | } 124 | ``` 125 | 126 | 127 | ### RelayKind 128 | 129 | ```rust 130 | pub enum RelayKind { 131 | SingleHostAddr, 132 | SingleHostName, 133 | MultiHostName, 134 | } 135 | ``` 136 | -------------------------------------------------------------------------------- /docs/docs/getting_started.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | --- 4 | 5 | # Installation & Getting Started 6 | 7 | 8 | ## Install 9 | 10 | 11 | ```bash 12 | todo 13 | ``` 14 | 15 | 16 | ## Run Example 17 | 18 | 19 | ```bash 20 | todo 21 | ``` 22 | 23 | 24 | ## Build 25 | 26 | ```bash 27 | todo 28 | ``` 29 | 30 | 31 | ## Test 32 | 33 | ```bash 34 | nvm i && npm i && npm run rust:test 35 | ``` 36 | -------------------------------------------------------------------------------- /docs/docs/modules/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Modules", 3 | "position": 4, 4 | "link": { 5 | "type": "generated-index" 6 | }, 7 | "collapsed": false 8 | } 9 | -------------------------------------------------------------------------------- /docs/docs/modules/builders/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Builders", 3 | "position": 4, 4 | "link": { 5 | "type": "generated-index" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /docs/docs/modules/chain/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Chain", 3 | "position": 2, 4 | "link": { 5 | "type": "generated-index" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /docs/docs/modules/chain/index.md: -------------------------------------------------------------------------------- 1 | # Chain 2 | 3 | This crate contains all of the on-chain types used in the current Cardano era. All of these types can be serialized and deserialized from their on-chain CBOR encodings. Also included are some utility funtionality for working with them, as well as builders for creating them. -------------------------------------------------------------------------------- /docs/docs/modules/cip36.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 4 3 | --- 4 | # CIP36 5 | 6 | -------------------------------------------------------------------------------- /docs/docs/modules/core/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Core", 3 | "position": 1, 4 | "link": { 5 | "type": "generated-index" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /docs/docs/modules/core/index.md: -------------------------------------------------------------------------------- 1 | # Core 2 | 3 | This crate is for core features and traits common to all CML crates. Most users likely won't need to directly use this module except for possibly pulling in traits used with other cml crates. If you are using CML from WASM/typescript this module will not be needed as any used types will be re-exported in the crates (e.g. cml-chain-wasm, cml-cip25-wasm, etc) that use it. -------------------------------------------------------------------------------- /docs/docs/modules/crypto/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Crypto", 3 | "position": 2, 4 | "link": { 5 | "type": "generated-index" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /docs/docs/modules/crypto/index.mdx: -------------------------------------------------------------------------------- 1 | # crypto 2 | 3 | AuxiliaryDataHash 4 | 5 | Bip32PrivateKey 6 | 7 | Bip32PublicKey 8 | 9 | BlockBodyHash 10 | 11 | BlockHeaderHash 12 | 13 | BootstrapWitness 14 | 15 | BootstrapWitnesses 16 | 17 | DataHash 18 | 19 | Ed25519KeyHash 20 | 21 | Ed25519Signature 22 | 23 | GenesisDelegateHash 24 | 25 | GenesisHash 26 | 27 | KESSignature 28 | 29 | KESVKey 30 | 31 | LegacyDaedalusPrivateKey 32 | 33 | Nonce 34 | 35 | PoolMetadataHash 36 | 37 | PrivateKey 38 | 39 | PublicKey ED25519 key used as public key 40 | 41 | PublicKeys 42 | 43 | ScriptDataHash 44 | 45 | ScriptHash 46 | 47 | TransactionHash 48 | 49 | VRFCert 50 | 51 | VRFKeyHash 52 | 53 | VRFVKey 54 | 55 | Vkey 56 | 57 | Vkeys 58 | 59 | Vkeywitness 60 | 61 | Vkeywitnesses -------------------------------------------------------------------------------- /docs/docs/modules/multi-era/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Multi-Era", 3 | "position": 2, 4 | "link": { 5 | "type": "generated-index" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /docs/docs/modules/multi-era/index.md: -------------------------------------------------------------------------------- 1 | # Multi-Era 2 | 3 | This crate contains all the on-chain types for previous eras (Byron, Shelley, Alonzo, Babbage, etc). There are also wrappers around this era if you need era-agnostic types e.g. parsing all blocks from genesis. The wrappers support the current era as well. 4 | 5 | ## Parsing blocks across eras 6 | 7 | `MultiEraBlock` can be used for this. Take care about the format you are giving it. Some tools (e.g. Pallas/Oura) won't give you the block format from the binary spec directly, but will instead have it wrapped in some network wrapper array containing the explicit era tag. If your CBOR looks like `[uint, ]` (likely starting with `82` in hex e.g. `8201`, `8204`, `8207`, etc) then you should use `MultiEraBlock.from_explicit_network_cbor_bytes()` instead of `MultiEraBlock.from_cbor_bytes()`. -------------------------------------------------------------------------------- /docs/docs/modules/wasm.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 6 3 | --- 4 | 5 | # WASM Usage 6 | 7 | ## Memory Management 8 | 9 | If you are using CML from the browser this section is likely irrelevant for you. 10 | Using CML from a javascript environment with weakrefs enabled should have automatic memory cleanup. 11 | If this is not the case (e.g. non-javascript/typescript WASM environment), or you are using CML inside of a very tight loop that is executed hundreds of thousands of times in a short period it might be advisable to explicitly call `.free()` on any CML types after they are used. 12 | This is because while from an environment with weakrefs the types will eventually be freed automatically, 13 | it is still possible to use excessive memory or run out if, for example, large CML types are created in a constant loop that runs many times (e.g. hundreds of thousands of times without a break), as the automatic cleanup will not be run in time. Do not worry about this for normal CML usage. 14 | Do not call `.free()` on a type or use it after `.free()` has been called on it already. 15 | WASM types passed into other CML APIs will be done so by reference and will not have their `.free()` method called just by doing so, but will still eventually be cleaned up if weakrefs are available. -------------------------------------------------------------------------------- /docs/docs/type_definitions.mdx_bak: -------------------------------------------------------------------------------- 1 | # Type Definitions 2 | 3 | ## PolicyID 4 | 5 | ```rust 6 | pub type PolicyID = ScriptHash; 7 | ``` 8 | 9 | ## PolicyIDs 10 | 11 | ```rust 12 | pub type PolicyIDs = ScriptHashes; 13 | ``` 14 | 15 | ## Requires Signers 16 | 17 | ```rust 18 | pub type RequiredSigners = Ed25519KeyHashes; 19 | ``` 20 | 21 | ## RequiredSignersSet 22 | 23 | ```rust 24 | pub type RequiredSignersSet = BTreeSet; 25 | ``` 26 | -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cddl-codegen-documentation", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "docusaurus": "docusaurus", 7 | "start": "docusaurus start", 8 | "swizzle": "docusaurus swizzle", 9 | "deploy": "docusaurus deploy", 10 | "clear": "docusaurus clear", 11 | "serve": "docusaurus serve", 12 | "write-translations": "docusaurus write-translations", 13 | "write-heading-ids": "docusaurus write-heading-ids", 14 | "crowdin": "crowdin", 15 | "build": "docusaurus build" 16 | }, 17 | "dependencies": { 18 | "@crowdin/cli": "^3.15.0", 19 | "@docusaurus/core": "^3.0.1", 20 | "@docusaurus/preset-classic": "^3.0.1", 21 | "@easyops-cn/docusaurus-search-local": "^0.40.0", 22 | "@mdx-js/react": "^3.0.0", 23 | "clsx": "^2.0.0", 24 | "prism-react-renderer": "^2.3.1", 25 | "react": "^18.2.0", 26 | "react-dom": "^18.2.0" 27 | }, 28 | "devDependencies": { 29 | "@docusaurus/module-type-aliases": "^3.0.1", 30 | "autoprefixer": "^10.4.16", 31 | "postcss": "^8.4.32", 32 | "tailwindcss": "^3.4.0" 33 | }, 34 | "browserslist": { 35 | "production": [ 36 | ">0.5%", 37 | "not dead", 38 | "not op_mini all" 39 | ], 40 | "development": [ 41 | "last 1 chrome version", 42 | "last 1 firefox version", 43 | "last 1 safari version" 44 | ] 45 | }, 46 | "engines": { 47 | "node": ">=18.17" 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /docs/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /docs/sidebars.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Creating a sidebar enables you to: 3 | - create an ordered group of docs 4 | - render a sidebar for each doc of that group 5 | - provide next/previous navigation 6 | 7 | The sidebars can be generated from the filesystem, or explicitly defined here. 8 | 9 | Create as many sidebars as you want. 10 | */ 11 | 12 | // @ts-check 13 | 14 | /** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ 15 | const sidebars = { 16 | // By default, Docusaurus generates a sidebar from the docs folder structure 17 | tutorialSidebar: [{ type: "autogenerated", dirName: "." }], 18 | 19 | // But you can create a sidebar manually 20 | /* 21 | tutorialSidebar: [ 22 | { 23 | type: 'category', 24 | label: 'Tutorial', 25 | items: ['hello'], 26 | }, 27 | ], 28 | */ 29 | }; 30 | 31 | module.exports = sidebars; 32 | -------------------------------------------------------------------------------- /docs/src/css/custom.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Any CSS included here will be global. The classic template 3 | * bundles Infima by default. Infima is a CSS framework designed to 4 | * work well for content-centric websites. 5 | */ 6 | 7 | /* You can override the default Infima variables here. */ 8 | @tailwind base; 9 | @tailwind components; 10 | @tailwind utilities; 11 | 12 | @font-face { 13 | font-family: 'Manrope'; 14 | src: url('../fonts/Manrope-Regular.ttf'); 15 | } 16 | 17 | :root { 18 | --ifm-color-primary: #356ddb; 19 | --ifm-color-primary-dark: #356ddb; 20 | --ifm-color-primary-darker: #356ddb; 21 | --ifm-color-primary-darkest: #356ddb; 22 | --ifm-color-primary-light: #356ddb; 23 | --ifm-color-primary-lighter: #356ddb; 24 | --ifm-color-primary-lightest: #356ddb; 25 | --ifm-code-font-size: 95%; 26 | --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); 27 | --ifm-spacing-horizontal: 40px; 28 | --ifm-font-color-base: #3b454e; 29 | --ifm-blockquote-border-left-width: 4px; 30 | --ifm-blockquote-color: #5c6975; 31 | --ifm-blockquote-padding-horizontal: 20px; 32 | --ifm-alert-padding-horizontal: 20px; 33 | --ifm-navbar-padding-horizontal: 16px; 34 | --tabs-bg-active: white; 35 | --tabs-text-inactive: rgb(156 163 175); 36 | --ifm-font-family-base: 'Manrope'; 37 | } 38 | 39 | /* For readability concerns, you should choose a lighter palette in dark mode. */ 40 | [data-theme="dark"] { 41 | --ifm-color-primary: #ff9828; 42 | --ifm-color-primary-dark: #ff9828; 43 | --ifm-color-primary-darker: #ff9828; 44 | --ifm-color-primary-darkest: #ff9828; 45 | --ifm-color-primary-light: #ff9828; 46 | --ifm-color-primary-lighter: #ff9828; 47 | --ifm-color-primary-lightest: #ff9828; 48 | --ifm-font-color-base: #fff; 49 | --ifm-blockquote-color: #c8c8c8; 50 | --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); 51 | --tabs-bg-active: #1c1c1d; 52 | --tabs-text-inactive: #bab0b0; 53 | } 54 | 55 | img { 56 | @apply max-w-[300px] mb-3; 57 | } 58 | 59 | .img-full { 60 | @apply w-full max-w-full; 61 | } 62 | 63 | .img-card { 64 | @apply max-w-[300px] mb-4; 65 | } 66 | .img-icon { 67 | @apply w-5 mb-0; 68 | } 69 | 70 | .tabs-container [role="tab"] { 71 | @apply rounded-t-md rounded-b-none border-[1px] border-solid border-gray-300 py-2 bg-[color:var(--tabs-bg-active)] border-b-0; 72 | } 73 | .tabs-container [role="tab"][aria-selected="false"] { 74 | @apply bg-[color:var(--tabs-bg)] text-gray-400; 75 | } 76 | .tabs-container [role="tabpanel"] { 77 | @apply border-[1px] border-solid border-gray-300 p-5 -mt-[17px]; 78 | } 79 | -------------------------------------------------------------------------------- /docs/src/fonts/Manrope-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dcSpark/cardano-multiplatform-lib/a34592e1e0d3c1e958d72f05c72282d788403aa5/docs/src/fonts/Manrope-Bold.ttf -------------------------------------------------------------------------------- /docs/src/fonts/Manrope-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dcSpark/cardano-multiplatform-lib/a34592e1e0d3c1e958d72f05c72282d788403aa5/docs/src/fonts/Manrope-Light.ttf -------------------------------------------------------------------------------- /docs/src/fonts/Manrope-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dcSpark/cardano-multiplatform-lib/a34592e1e0d3c1e958d72f05c72282d788403aa5/docs/src/fonts/Manrope-Medium.ttf -------------------------------------------------------------------------------- /docs/src/fonts/Manrope-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dcSpark/cardano-multiplatform-lib/a34592e1e0d3c1e958d72f05c72282d788403aa5/docs/src/fonts/Manrope-Regular.ttf -------------------------------------------------------------------------------- /docs/src/fonts/Manrope-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dcSpark/cardano-multiplatform-lib/a34592e1e0d3c1e958d72f05c72282d788403aa5/docs/src/fonts/Manrope-SemiBold.ttf -------------------------------------------------------------------------------- /docs/static/icons/danger-icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/static/icons/info-icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/static/img/output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dcSpark/cardano-multiplatform-lib/a34592e1e0d3c1e958d72f05c72282d788403aa5/docs/static/img/output.png -------------------------------------------------------------------------------- /docs/static/img/output2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dcSpark/cardano-multiplatform-lib/a34592e1e0d3c1e958d72f05c72282d788403aa5/docs/static/img/output2.png -------------------------------------------------------------------------------- /docs/static/img/output3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dcSpark/cardano-multiplatform-lib/a34592e1e0d3c1e958d72f05c72282d788403aa5/docs/static/img/output3.png -------------------------------------------------------------------------------- /docs/static/img/output4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dcSpark/cardano-multiplatform-lib/a34592e1e0d3c1e958d72f05c72282d788403aa5/docs/static/img/output4.png -------------------------------------------------------------------------------- /docs/static/img/output5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dcSpark/cardano-multiplatform-lib/a34592e1e0d3c1e958d72f05c72282d788403aa5/docs/static/img/output5.png -------------------------------------------------------------------------------- /docs/tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | content: ["./src/**/*.{js,jsx,ts,tsx}", "./docs/**/*.{md,mdx}"], 4 | theme: { 5 | extend: {}, 6 | }, 7 | plugins: [], 8 | corePlugins: { 9 | preflight: false, 10 | }, 11 | }; 12 | -------------------------------------------------------------------------------- /example/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "parser": "@typescript-eslint/parser", 3 | "parserOptions": { 4 | "project": "./tsconfig.json" 5 | }, 6 | "extends": [ 7 | "eslint:recommended", 8 | "plugin:@typescript-eslint/eslint-recommended", 9 | "plugin:@typescript-eslint/recommended", 10 | "plugin:@typescript-eslint/recommended-requiring-type-checking" 11 | ], 12 | "plugins": [ 13 | "@typescript-eslint" 14 | ], 15 | "globals": { 16 | }, 17 | "rules": { 18 | } 19 | } -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | dist/ 3 | tsconfig.tsbuildinfo 4 | -------------------------------------------------------------------------------- /example/.mocharc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | spec: "./**/*.spec.ts", 3 | require: ["ts-node/register", "source-map-support/register"], 4 | recursive: true, 5 | "watch-extensions": ['ts'], 6 | exit: true, 7 | }; 8 | -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cardano-multiplatform-lib-example", 3 | "version": "5.1.0", 4 | "description": "", 5 | "main": "dist/index.js", 6 | "keywords": [ 7 | "cardano" 8 | ], 9 | "scripts": { 10 | "js:build": "rm -rf dist && tsc", 11 | "js:dev": "rimraf ./dist && ts-node ./index.ts", 12 | "js:lint": "eslint \"./**/*.ts\"", 13 | "js:test:watch": "mocha -w", 14 | "js:test": "mocha" 15 | }, 16 | "repository": { 17 | "type": "git", 18 | "url": "git+https://github.com/dcSpark/cardano-multiplatform-lib.git" 19 | }, 20 | "author": "dcSpark", 21 | "license": "MIT", 22 | "bugs": { 23 | "url": "https://github.com/dcSpark/cardano-multiplatform-lib/issues" 24 | }, 25 | "type": "module", 26 | "homepage": "https://github.com/dcSpark/cardano-multiplatform-lib#readme", 27 | "dependencies": {}, 28 | "devDependencies": { 29 | "@types/chai": "4.2.11", 30 | "@types/mocha": "8.0.0", 31 | "@typescript-eslint/eslint-plugin": "3.6.1", 32 | "@typescript-eslint/parser": "3.6.1", 33 | "bip39": "3.0.2", 34 | "chai": "4.2.0", 35 | "eslint": "7.4.0", 36 | "mocha": "8.0.1", 37 | "rust-lib": "file:../rust/pkg", 38 | "source-map-support": "0.5.19", 39 | "ts-node": "8.10.2", 40 | "typescript": "3.9.7" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /example/wallaby.conf.js: -------------------------------------------------------------------------------- 1 | module.exports = function () { 2 | return { 3 | files: [ 4 | './**/*.ts', 5 | '!./**/*.spec.ts' 6 | ], 7 | 8 | tests: [ 9 | './**/*.spec.ts' 10 | ], 11 | env: { 12 | type: 'node' 13 | }, 14 | testFramework: 'mocha' 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /examples/wasm-browser/README.md: -------------------------------------------------------------------------------- 1 | # Token Mint Example 2 | 3 | Connects to Flint via CIP30 and mints a token locked by the wallet's change address's key. -------------------------------------------------------------------------------- /examples/wasm-browser/bootstrap.js: -------------------------------------------------------------------------------- 1 | // A dependency graph that contains any wasm must all be imported 2 | // asynchronously. This `bootstrap.js` file does the single async import, so 3 | // that no one else needs to worry about it again. 4 | import("./index.js") 5 | .catch(e => console.error("Error importing `index.js`:", e)); 6 | -------------------------------------------------------------------------------- /examples/wasm-browser/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dcSpark/cardano-multiplatform-lib/a34592e1e0d3c1e958d72f05c72282d788403aa5/examples/wasm-browser/favicon.ico -------------------------------------------------------------------------------- /examples/wasm-browser/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Cardano Test dApp 7 | 8 | 9 |
Wallet not connected
10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/wasm-browser/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-cml-dapp", 3 | "version": "5.1.0", 4 | "description": "test dApp to interact with CIP-30 compatible wallets (e.g. Flint)", 5 | "main": "index.js", 6 | "bin": { 7 | "test-cml-dapp": ".bin/test-cml-dapp.js" 8 | }, 9 | "scripts": { 10 | "build": "webpack --config webpack.config.js", 11 | "start": "webpack-dev-server" 12 | }, 13 | "dependencies": { 14 | "cml-chain-wasm": "file:../../chain/wasm/pkg", 15 | "cml-cip25-wasm": "file:../../cip25/wasm/pkg", 16 | "copy-webpack-plugin": "11.0.0", 17 | "webpack": "5.1.0", 18 | "webpack-cli": "5.0.0", 19 | "webpack-dev-server": "4.0.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /examples/wasm-browser/webpack.config.js: -------------------------------------------------------------------------------- 1 | const CopyWebpackPlugin = require("copy-webpack-plugin"); 2 | const path = require('path'); 3 | 4 | module.exports = { 5 | entry: "./bootstrap.js", 6 | output: { 7 | path: path.resolve(__dirname, "dist"), 8 | filename: "bootstrap.js", 9 | }, 10 | mode: "development", 11 | plugins: [ 12 | new CopyWebpackPlugin({ patterns: ['index.html', 'favicon.ico'] }) 13 | ], 14 | experiments: { asyncWebAssembly: true }, 15 | }; 16 | -------------------------------------------------------------------------------- /multi-era/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cml-multi-era" 3 | version = "6.2.0" 4 | edition = "2018" 5 | authors = ["dcSpark"] 6 | license = "MIT" 7 | description = "Multiplatform SDK for era-agnostic Cardano blockchain parsing" 8 | documentation = "https://github.com/dcSpark/cardano-multiplatform-lib/docs" 9 | repository = "https://github.com/dcSpark/cardano-multiplatform-lib" 10 | readme = "../../README.md" 11 | keywords = ["cardano"] 12 | 13 | [lib] 14 | crate-type = ["cdylib", "rlib"] 15 | 16 | [features] 17 | used_from_wasm = ["wasm-bindgen"] 18 | 19 | [dependencies] 20 | cml-core = { path = "../../core/rust", version = "6.2.0" } 21 | cml-crypto = { path = "../../crypto/rust", version = "6.2.0" } 22 | cml-chain = { path = "../../chain/rust", version = "6.2.0" } 23 | cbor_event = "2.4.0" 24 | linked-hash-map = "0.5.3" 25 | derivative = "2.2.0" 26 | serde = { version = "1.0", features = ["derive"] } 27 | serde_json = "1.0.57" 28 | schemars = "0.8.8" 29 | 30 | # only for declaring hash types 31 | bech32 = "0.7.2" 32 | hex = "0.4.0" 33 | 34 | # non-wasm 35 | noop_proc_macro = { version = "0.3.0" } 36 | 37 | # wasm 38 | wasm-bindgen = { version = "0.2.87", optional = true } -------------------------------------------------------------------------------- /multi-era/rust/src/allegra/cbor_encodings.rs: -------------------------------------------------------------------------------- 1 | // This file was code-generated using an experimental CDDL to rust tool: 2 | // https://github.com/dcSpark/cddl-codegen 3 | 4 | use cml_chain::address::RewardAccount; 5 | use cml_core::serialization::{LenEncoding, StringEncoding}; 6 | use std::collections::BTreeMap; 7 | 8 | #[derive(Clone, Debug, Default)] 9 | pub struct AllegraBlockEncoding { 10 | pub len_encoding: LenEncoding, 11 | pub transaction_bodies_encoding: LenEncoding, 12 | pub transaction_witness_sets_encoding: LenEncoding, 13 | pub auxiliary_data_set_encoding: LenEncoding, 14 | pub auxiliary_data_set_key_encodings: BTreeMap>, 15 | } 16 | 17 | #[derive(Clone, Debug, Default)] 18 | pub struct AllegraTransactionBodyEncoding { 19 | pub len_encoding: LenEncoding, 20 | pub orig_deser_order: Vec, 21 | pub inputs_encoding: LenEncoding, 22 | pub inputs_key_encoding: Option, 23 | pub outputs_encoding: LenEncoding, 24 | pub outputs_key_encoding: Option, 25 | pub fee_encoding: Option, 26 | pub fee_key_encoding: Option, 27 | pub ttl_encoding: Option, 28 | pub ttl_key_encoding: Option, 29 | pub certs_encoding: LenEncoding, 30 | pub certs_key_encoding: Option, 31 | pub withdrawals_encoding: LenEncoding, 32 | pub withdrawals_value_encodings: BTreeMap>, 33 | pub withdrawals_key_encoding: Option, 34 | pub update_key_encoding: Option, 35 | pub auxiliary_data_hash_encoding: StringEncoding, 36 | pub auxiliary_data_hash_key_encoding: Option, 37 | pub validity_interval_start_encoding: Option, 38 | pub validity_interval_start_key_encoding: Option, 39 | } 40 | 41 | #[derive(Clone, Debug, Default)] 42 | pub struct AllegraTransactionEncoding { 43 | pub len_encoding: LenEncoding, 44 | } 45 | 46 | #[derive(Clone, Debug, Default)] 47 | pub struct AllegraTransactionWitnessSetEncoding { 48 | pub len_encoding: LenEncoding, 49 | pub orig_deser_order: Vec, 50 | pub vkeywitnesses_encoding: LenEncoding, 51 | pub vkeywitnesses_key_encoding: Option, 52 | pub native_scripts_encoding: LenEncoding, 53 | pub native_scripts_key_encoding: Option, 54 | pub bootstrap_witnesses_encoding: LenEncoding, 55 | pub bootstrap_witnesses_key_encoding: Option, 56 | } 57 | 58 | #[derive(Clone, Debug, Default)] 59 | pub struct MoveInstantaneousRewardEncoding { 60 | pub len_encoding: LenEncoding, 61 | pub pot_encoding: Option, 62 | } 63 | 64 | #[derive(Clone, Debug, Default)] 65 | pub struct MoveInstantaneousRewardsCertEncoding { 66 | pub len_encoding: LenEncoding, 67 | pub tag_encoding: Option, 68 | } 69 | -------------------------------------------------------------------------------- /multi-era/rust/src/allegra/utils.rs: -------------------------------------------------------------------------------- 1 | use cml_chain::{auxdata::AuxiliaryData, transaction::TransactionWitnessSet}; 2 | 3 | use super::{AllegraAuxiliaryData, AllegraTransactionBody, AllegraTransactionWitnessSet}; 4 | 5 | use cml_core::serialization::Serialize; 6 | use cml_crypto::{blake2b256, TransactionHash}; 7 | 8 | impl AllegraTransactionBody { 9 | pub fn hash(&self) -> TransactionHash { 10 | blake2b256(&self.to_cbor_bytes()).into() 11 | } 12 | } 13 | 14 | impl From for AuxiliaryData { 15 | fn from(aux: AllegraAuxiliaryData) -> Self { 16 | match aux { 17 | AllegraAuxiliaryData::Shelley(md) => AuxiliaryData::new_shelley(md), 18 | AllegraAuxiliaryData::ShelleyMA(md) => AuxiliaryData::new_shelley_ma(md), 19 | } 20 | } 21 | } 22 | 23 | impl From for TransactionWitnessSet { 24 | fn from(wits: AllegraTransactionWitnessSet) -> Self { 25 | let mut new_wits = TransactionWitnessSet::new(); 26 | new_wits.vkeywitnesses = wits.vkeywitnesses.map(Into::into); 27 | new_wits.native_scripts = wits.native_scripts.map(Into::into); 28 | new_wits.bootstrap_witnesses = wits.bootstrap_witnesses.map(Into::into); 29 | new_wits 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /multi-era/rust/src/alonzo/utils.rs: -------------------------------------------------------------------------------- 1 | use cml_chain::{ 2 | auxdata::{AuxiliaryData, ConwayFormatAuxData}, 3 | plutus::{LegacyRedeemer, RedeemerTag, Redeemers}, 4 | transaction::TransactionWitnessSet, 5 | }; 6 | 7 | use super::{ 8 | AlonzoAuxiliaryData, AlonzoRedeemer, AlonzoRedeemerTag, AlonzoTransactionBody, 9 | AlonzoTransactionWitnessSet, 10 | }; 11 | 12 | use cml_core::serialization::Serialize; 13 | use cml_crypto::{blake2b256, TransactionHash}; 14 | 15 | impl AlonzoTransactionBody { 16 | pub fn hash(&self) -> TransactionHash { 17 | blake2b256(&self.to_cbor_bytes()).into() 18 | } 19 | } 20 | 21 | impl From for AuxiliaryData { 22 | fn from(aux: AlonzoAuxiliaryData) -> Self { 23 | match aux { 24 | AlonzoAuxiliaryData::Shelley(md) => AuxiliaryData::new_shelley(md.clone()), 25 | AlonzoAuxiliaryData::ShelleyMA(md) => AuxiliaryData::new_shelley_ma(md.clone()), 26 | AlonzoAuxiliaryData::Alonzo(md) => AuxiliaryData::new_conway({ 27 | let mut conway = ConwayFormatAuxData::new(); 28 | conway.metadata.clone_from(&md.metadata); 29 | conway.native_scripts.clone_from(&md.native_scripts); 30 | conway.plutus_v1_scripts.clone_from(&md.plutus_v1_scripts); 31 | conway 32 | }), 33 | } 34 | } 35 | } 36 | 37 | impl From for TransactionWitnessSet { 38 | fn from(wits: AlonzoTransactionWitnessSet) -> Self { 39 | let mut new_wits = TransactionWitnessSet::new(); 40 | new_wits.vkeywitnesses = wits.vkeywitnesses.map(Into::into); 41 | new_wits.native_scripts = wits.native_scripts.map(Into::into); 42 | new_wits.bootstrap_witnesses = wits.bootstrap_witnesses.map(Into::into); 43 | new_wits.redeemers = wits 44 | .redeemers 45 | .map(|r| Redeemers::new_arr_legacy_redeemer(r.into_iter().map(Into::into).collect())); 46 | new_wits.plutus_datums = wits.plutus_datums.map(Into::into); 47 | new_wits.plutus_v1_scripts = wits.plutus_v1_scripts.map(Into::into); 48 | new_wits 49 | } 50 | } 51 | 52 | impl From for LegacyRedeemer { 53 | fn from(redeemer: AlonzoRedeemer) -> Self { 54 | Self { 55 | tag: match redeemer.tag { 56 | AlonzoRedeemerTag::Cert => RedeemerTag::Cert, 57 | AlonzoRedeemerTag::Mint => RedeemerTag::Mint, 58 | AlonzoRedeemerTag::Reward => RedeemerTag::Reward, 59 | AlonzoRedeemerTag::Spend => RedeemerTag::Spend, 60 | }, 61 | index: redeemer.index, 62 | data: redeemer.data, 63 | ex_units: redeemer.ex_units, 64 | encodings: None, 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /multi-era/rust/src/byron/delegation/mod.rs: -------------------------------------------------------------------------------- 1 | // This file was code-generated using an experimental CDDL to rust tool: 2 | // https://github.com/dcSpark/cddl-codegen 3 | 4 | pub mod serialization; 5 | 6 | use crate::byron::{ByronPubKey, ByronSignature, EpochId}; 7 | 8 | #[derive(Clone, Debug, serde::Deserialize, serde::Serialize, schemars::JsonSchema)] 9 | pub struct ByronDelegation { 10 | pub epoch: EpochId, 11 | pub issuer: ByronPubKey, 12 | pub delegate: ByronPubKey, 13 | pub certificate: ByronSignature, 14 | } 15 | 16 | impl ByronDelegation { 17 | pub fn new( 18 | epoch: EpochId, 19 | issuer: ByronPubKey, 20 | delegate: ByronPubKey, 21 | certificate: ByronSignature, 22 | ) -> Self { 23 | Self { 24 | epoch, 25 | issuer, 26 | delegate, 27 | certificate, 28 | } 29 | } 30 | } 31 | 32 | #[derive(Clone, Debug, serde::Deserialize, serde::Serialize, schemars::JsonSchema)] 33 | pub struct ByronDelegationSignature { 34 | pub byron_delegation: ByronDelegation, 35 | pub byron_signature: ByronSignature, 36 | } 37 | 38 | impl ByronDelegationSignature { 39 | pub fn new(byron_delegation: ByronDelegation, byron_signature: ByronSignature) -> Self { 40 | Self { 41 | byron_delegation, 42 | byron_signature, 43 | } 44 | } 45 | } 46 | 47 | #[derive(Clone, Debug, serde::Deserialize, serde::Serialize, schemars::JsonSchema)] 48 | pub struct EpochRange { 49 | pub epoch_id: EpochId, 50 | pub epoch_id2: EpochId, 51 | } 52 | 53 | impl EpochRange { 54 | pub fn new(epoch_id: EpochId, epoch_id2: EpochId) -> Self { 55 | Self { 56 | epoch_id, 57 | epoch_id2, 58 | } 59 | } 60 | } 61 | 62 | #[derive(Clone, Debug, serde::Deserialize, serde::Serialize, schemars::JsonSchema)] 63 | pub struct LightWeightDelegationSignature { 64 | pub light_weight_dlg: LightWeightDlg, 65 | pub byron_signature: ByronSignature, 66 | } 67 | 68 | impl LightWeightDelegationSignature { 69 | pub fn new(light_weight_dlg: LightWeightDlg, byron_signature: ByronSignature) -> Self { 70 | Self { 71 | light_weight_dlg, 72 | byron_signature, 73 | } 74 | } 75 | } 76 | 77 | #[derive(Clone, Debug, serde::Deserialize, serde::Serialize, schemars::JsonSchema)] 78 | pub struct LightWeightDlg { 79 | pub epoch_range: EpochRange, 80 | pub issuer: ByronPubKey, 81 | pub delegate: ByronPubKey, 82 | pub certificate: ByronSignature, 83 | } 84 | 85 | impl LightWeightDlg { 86 | pub fn new( 87 | epoch_range: EpochRange, 88 | issuer: ByronPubKey, 89 | delegate: ByronPubKey, 90 | certificate: ByronSignature, 91 | ) -> Self { 92 | Self { 93 | epoch_range, 94 | issuer, 95 | delegate, 96 | certificate, 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /multi-era/rust/src/byron/mod.rs: -------------------------------------------------------------------------------- 1 | // This file was code-generated using an experimental CDDL to rust tool: 2 | // https://github.com/dcSpark/cddl-codegen 3 | 4 | pub mod block; 5 | pub mod delegation; 6 | pub mod mpc; 7 | pub mod serialization; 8 | pub mod transaction; 9 | pub mod update; 10 | pub mod utils; 11 | 12 | use cml_crypto::TransactionHash; 13 | pub use utils::*; 14 | 15 | pub type ByronBlockId = Blake2b256; 16 | 17 | pub type ByronPubKey = Vec; 18 | 19 | pub type ByronSignature = Vec; 20 | 21 | #[derive(Clone, Debug, serde::Deserialize, serde::Serialize, schemars::JsonSchema)] 22 | pub struct ByronSlotId { 23 | pub epoch: EpochId, 24 | pub slot: u64, 25 | } 26 | 27 | impl ByronSlotId { 28 | pub fn new(epoch: EpochId, slot: u64) -> Self { 29 | Self { epoch, slot } 30 | } 31 | } 32 | 33 | pub type ByronTxId = TransactionHash; 34 | 35 | pub type ByronUpdateId = Blake2b256; 36 | 37 | pub type EpochId = u64; 38 | -------------------------------------------------------------------------------- /multi-era/rust/src/byron/serialization.rs: -------------------------------------------------------------------------------- 1 | // This file was code-generated using an experimental CDDL to rust tool: 2 | // https://github.com/dcSpark/cddl-codegen 3 | 4 | use super::*; 5 | use cbor_event; 6 | use cbor_event::de::Deserializer; 7 | use cbor_event::se::Serializer; 8 | use cml_core::error::*; 9 | use cml_core::serialization::*; 10 | use std::io::{BufRead, Seek, Write}; 11 | 12 | impl cbor_event::se::Serialize for ByronSlotId { 13 | fn serialize<'se, W: Write>( 14 | &self, 15 | serializer: &'se mut Serializer, 16 | ) -> cbor_event::Result<&'se mut Serializer> { 17 | serializer.write_array(cbor_event::Len::Len(2))?; 18 | serializer.write_unsigned_integer(self.epoch)?; 19 | serializer.write_unsigned_integer(self.slot)?; 20 | Ok(serializer) 21 | } 22 | } 23 | 24 | impl Deserialize for ByronSlotId { 25 | fn deserialize(raw: &mut Deserializer) -> Result { 26 | let len = raw.array()?; 27 | let mut read_len = CBORReadLen::from(len); 28 | read_len.read_elems(2)?; 29 | read_len.finish()?; 30 | (|| -> Result<_, DeserializeError> { 31 | let epoch = 32 | Ok(raw.unsigned_integer()?).map_err(|e: DeserializeError| e.annotate("epoch"))?; 33 | let slot = 34 | Ok(raw.unsigned_integer()?).map_err(|e: DeserializeError| e.annotate("slot"))?; 35 | match len { 36 | cbor_event::Len::Len(_) => (), 37 | cbor_event::Len::Indefinite => match raw.special()? { 38 | cbor_event::Special::Break => (), 39 | _ => return Err(DeserializeFailure::EndingBreakMissing.into()), 40 | }, 41 | } 42 | Ok(ByronSlotId { epoch, slot }) 43 | })() 44 | .map_err(|e| e.annotate("ByronSlotId")) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /multi-era/rust/src/byron/transaction/utils.rs: -------------------------------------------------------------------------------- 1 | use super::ByronTx; 2 | use cml_core::serialization::ToBytes; 3 | use cml_crypto::{blake2b256, TransactionHash}; 4 | 5 | impl ByronTx { 6 | pub fn hash(&self) -> TransactionHash { 7 | blake2b256(&self.to_bytes()).into() 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /multi-era/rust/src/mary/cbor_encodings.rs: -------------------------------------------------------------------------------- 1 | // This file was code-generated using an experimental CDDL to rust tool: 2 | // https://github.com/dcSpark/cddl-codegen 3 | 4 | use cml_chain::{address::RewardAccount, assets::AssetName, PolicyId}; 5 | use cml_core::serialization::{LenEncoding, StringEncoding}; 6 | use std::collections::BTreeMap; 7 | 8 | #[derive(Clone, Debug, Default)] 9 | pub struct MaryBlockEncoding { 10 | pub len_encoding: LenEncoding, 11 | pub transaction_bodies_encoding: LenEncoding, 12 | pub transaction_witness_sets_encoding: LenEncoding, 13 | pub auxiliary_data_set_encoding: LenEncoding, 14 | pub auxiliary_data_set_key_encodings: BTreeMap>, 15 | } 16 | 17 | #[derive(Clone, Debug, Default)] 18 | pub struct MaryTransactionBodyEncoding { 19 | pub len_encoding: LenEncoding, 20 | pub orig_deser_order: Vec, 21 | pub inputs_encoding: LenEncoding, 22 | pub inputs_key_encoding: Option, 23 | pub outputs_encoding: LenEncoding, 24 | pub outputs_key_encoding: Option, 25 | pub fee_encoding: Option, 26 | pub fee_key_encoding: Option, 27 | pub ttl_encoding: Option, 28 | pub ttl_key_encoding: Option, 29 | pub certs_encoding: LenEncoding, 30 | pub certs_key_encoding: Option, 31 | pub withdrawals_encoding: LenEncoding, 32 | pub withdrawals_value_encodings: BTreeMap>, 33 | pub withdrawals_key_encoding: Option, 34 | pub update_key_encoding: Option, 35 | pub auxiliary_data_hash_encoding: StringEncoding, 36 | pub auxiliary_data_hash_key_encoding: Option, 37 | pub validity_interval_start_encoding: Option, 38 | pub validity_interval_start_key_encoding: Option, 39 | pub mint_encoding: LenEncoding, 40 | pub mint_key_encodings: BTreeMap, 41 | pub mint_value_encodings: 42 | BTreeMap>)>, 43 | pub mint_key_encoding: Option, 44 | } 45 | 46 | #[derive(Clone, Debug, Default)] 47 | pub struct MaryTransactionEncoding { 48 | pub len_encoding: LenEncoding, 49 | } 50 | 51 | #[derive(Clone, Debug, Default)] 52 | pub struct MaryTransactionOutputEncoding { 53 | pub len_encoding: LenEncoding, 54 | } 55 | -------------------------------------------------------------------------------- /multi-era/rust/src/mary/utils.rs: -------------------------------------------------------------------------------- 1 | use super::MaryTransactionBody; 2 | use cml_core::serialization::Serialize; 3 | use cml_crypto::{blake2b256, TransactionHash}; 4 | 5 | impl MaryTransactionBody { 6 | pub fn hash(&self) -> TransactionHash { 7 | blake2b256(&self.to_cbor_bytes()).into() 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /multi-era/wasm/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cml-multi-era-wasm" 3 | version = "6.2.0" 4 | edition = "2018" 5 | authors = ["dcSpark"] 6 | license = "MIT" 7 | description = "Multiplatform WASM SDK for era-agnostic Cardano blockchain parsing" 8 | documentation = "https://github.com/dcSpark/cardano-multiplatform-lib/docs" 9 | repository = "https://github.com/dcSpark/cardano-multiplatform-lib" 10 | readme = "../../README.md" 11 | keywords = ["cardano"] 12 | 13 | [lib] 14 | crate-type = ["cdylib", "rlib"] 15 | 16 | [dependencies] 17 | cml-chain = { path = "../../chain/rust", version = "6.2.0", features = ["used_from_wasm"] } 18 | cml-chain-wasm = { path = "../../chain/wasm", version = "6.2.0" } 19 | cml-crypto = { path = "../../crypto/rust", version = "6.2.0" } 20 | cml-crypto-wasm = { path = "../../crypto/wasm", version = "6.2.0" } 21 | cml-core = { path = "../../core/rust", version = "6.2.0" } 22 | cml-core-wasm = { path = "../../core/wasm", version = "6.2.0" } 23 | cml-multi-era = { path = "../rust", version = "6.2.0", features = ["used_from_wasm"] } 24 | cbor_event = "2.4.0" 25 | hex = "0.4.0" 26 | linked-hash-map = "0.5.3" 27 | serde_json = "1.0.57" 28 | serde-wasm-bindgen = "0.4.5" 29 | wasm-bindgen = { version = "0.2.87" } 30 | # not actual multi-era dependencies but we re-export these for the wasm builds 31 | cml-cip25-wasm = { path = "../../cip25/wasm", version = "6.2.0" } 32 | cml-cip36-wasm = { path = "../../cip36/wasm", version = "6.2.0" } 33 | -------------------------------------------------------------------------------- /multi-era/wasm/json-gen/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cml-multi-era-json-schema-gen" 3 | version = "6.2.0" 4 | edition = "2018" 5 | 6 | 7 | [dependencies] 8 | serde_json = "1.0.57" 9 | schemars = "0.8.8" 10 | cml-chain-json-schema-gen = { path = "../../../chain/wasm/json-gen" } 11 | cml-multi-era = { path = "../../rust" } 12 | -------------------------------------------------------------------------------- /multi-era/wasm/json-gen/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | cml_multi_era_json_schema_gen::export_schemas(); 3 | // We export ALL of the JSON types included in cml-chain 4 | cml_chain_json_schema_gen::export_schemas(); 5 | } 6 | -------------------------------------------------------------------------------- /multi-era/wasm/src/byron/utils.rs: -------------------------------------------------------------------------------- 1 | // use cml_core_wasm::impl_wasm_list; 2 | 3 | // // these weren't generated due to it being _CDDL_CODEGEN_EXTERN_TYPE_ 4 | // impl_wasm_list!(cml_chain::byron::AddressId, cml_chain_wasm::byron::AddressId, AddressIdList); 5 | // impl_wasm_list!(, VssPubKeyList); 6 | 7 | use wasm_bindgen::prelude::wasm_bindgen; 8 | 9 | use cml_core_wasm::impl_wasm_conversions; 10 | use cml_crypto_wasm::impl_hash_type_ext; 11 | 12 | impl_hash_type_ext!(cml_multi_era::byron::Blake2b224, Blake2b224); 13 | impl_hash_type_ext!(cml_multi_era::byron::Blake2b256, Blake2b256); 14 | 15 | #[derive(Debug, Clone)] 16 | #[wasm_bindgen] 17 | pub struct ByronAny(cml_multi_era::byron::ByronAny); 18 | 19 | // more methods on ByronAny to inspect it aren't offered as we don't encounter anything 20 | // useful on-chain for this. It's either not present or is an empty array 21 | 22 | impl_wasm_conversions!(cml_multi_era::byron::ByronAny, ByronAny); 23 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cardano-multiplatform-lib", 3 | "version": "6.2.0", 4 | "description": "Cardano Multiplatform SDK for core Cardano blockchain functionality", 5 | "keywords": [ 6 | "cardano" 7 | ], 8 | "scripts": { 9 | "rust:test": "cargo test", 10 | "rust:build-nodejs": "(cd cml/wasm && npm run rust:build-nodejs) && (cd multi-era/wasm && npm run rust:build-nodejs)", 11 | "rust:build-browser": "(cd cml/wasm && npm run rust:build-browser) && (cd multi-era/wasm && npm run rust:build-browser)", 12 | "rust:build-web": "(cd cml/wasm && npm run rust:build-web) && (cd multi-era/wasm && npm run rust:build-web)", 13 | "rust:build-asm": "(cd cml/wasm && npm run rust:build-asm) && (cd multi-era/wasm && npm run rust:build-asm)", 14 | "js:publish-nodejs:prod": "(cd cml/wasm && npm run js:publish-nodejs:prod) && (cd multi-era/wasm && npm run js:publish-nodejs:prod)", 15 | "js:publish-nodejs:beta": "(cd cml/wasm && npm run js:publish-nodejs:beta) && (cd multi-era/wasm && npm run js:publish-nodejs:beta)", 16 | "js:publish-browser:prod": "(cd cml/wasm && npm run js:publish-browser:prod) && (cd multi-era/wasm && npm run js:publish-browser:prod)", 17 | "js:publish-browser:beta": "(cd cml/wasm && npm run js:publish-browser:beta) && (cd multi-era/wasm && npm run js:publish-browser:beta)", 18 | "js:publish-asm:prod": "(cd cml/wasm && npm run js:publish-asm:prod) && (cd multi-era/wasm && npm run js:publish-asm:prod)", 19 | "js:publish-asm:beta": "(cd cml/wasm && npm run js:publish-asm:beta) && (cd multi-era/wasm && npm run js:publish-asm:beta)", 20 | "all:publish": "./release.sh prod", 21 | "postinstall": "git submodule update --init --recursive && cd binaryen; cmake . && make" 22 | }, 23 | "husky": { 24 | "hooks": { 25 | "pre-push": "npm run rust:test && npm run rust:build-nodejs" 26 | } 27 | }, 28 | "author": "dcSpark", 29 | "license": "MIT", 30 | "repository": { 31 | "type": "git", 32 | "url": "git+https://github.com/dcSpark/cardano-multiplatform-lib.git" 33 | }, 34 | "devDependencies": { 35 | "flowgen": "1.11.0", 36 | "cross-env": "^7.0.3", 37 | "husky": "4.2.5", 38 | "json-schema-to-typescript": "^10.1.5", 39 | "rimraf": "3.0.2" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /release.sh: -------------------------------------------------------------------------------- 1 | set -eu 2 | if [ $1 = "prod" ]; 3 | then RELEASE_TYPE="prod" 4 | elif [ $1 = "beta" ]; 5 | then RELEASE_TYPE="beta" 6 | else 7 | echo "First parameter is expected 'prod' or 'beta'" 8 | return 1 9 | fi 10 | 11 | echo "Preparing ${RELEASE_TYPE} release" 12 | 13 | . build-and-test.sh 14 | 15 | # publish on crates.io 16 | cargo publish -p cml-core 17 | cargo publish -p cml-crypto 18 | cargo publish -p cml-chain 19 | cargo publish -p cml-cip25 20 | cargo publish -p cml-cip36 21 | cargo publish -p cml-multi-era 22 | cargo publish -p cml-core-wasm 23 | cargo publish -p cml-crypto-wasm 24 | cargo publish -p cml-chain-wasm 25 | cargo publish -p cml-cip25-wasm 26 | cargo publish -p cml-cip36-wasm 27 | cargo publish -p cml-multi-era-wasm 28 | cargo publish -p cardano-multiplatform-lib 29 | 30 | # publish on NPM 31 | npm run js:publish-nodejs:${RELEASE_TYPE} 32 | npm run js:publish-browser:${RELEASE_TYPE} 33 | # asmjs builds broken for now 34 | # npm run js:publish-asm:${RELEASE_TYPE} 35 | -------------------------------------------------------------------------------- /scripts/.eslintrc.js: -------------------------------------------------------------------------------- 1 | { 2 | "parserOptions": { 3 | "ecmaVersion": 6, 4 | "sourceType": "module", 5 | }, 6 | "extends": [ 7 | "eslint:recommended", 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /scripts/json-ts-types.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path') 3 | 4 | const crateName = process.argv.slice(2)[0]; 5 | const pathToRepo = path.join(__dirname, '..', crateName, 'wasm'); 6 | const hyphenRepoName = process.argv.slice(2)[1].replaceAll('_', '-'); 7 | const underscoreRepoName = hyphenRepoName.replaceAll('-', '_'); 8 | 9 | const inputFile = fs.readFileSync(`${pathToRepo}/pkg/${underscoreRepoName}.d.ts`, 'utf8').split(/\r?\n/); 10 | 11 | //console.log(inputFile); 12 | let currentClass = null; 13 | for (let i = 0; i < inputFile.length; ++i) { 14 | let line = inputFile[i]; 15 | //const r = /export class ([a-zA-Z]+){/.exec(line); 16 | const classDef = /export class(.*){/.exec(line); 17 | if (classDef != null && classDef.length > 1) { 18 | currentClass = classDef[1].trim(); 19 | //console.log(`reading class ${currentClass}`); 20 | continue; 21 | } 22 | //const toJson = /\sto_json\(\): any;/.exec(line); 23 | //console.log(toJson); 24 | inputFile[i] = line.replace(/(\s?to_js_value\(\)\s?:\s?)(any)(;)/, `$1${currentClass}JSON$3`); 25 | if (line != inputFile[i]) { 26 | continue; 27 | } 28 | // TODO: we might want to make sure we don't have other cases where this would replace 29 | // things it shouldn't. We'd have to do some go-back-a-few-lines replace to only do this 30 | // for to_json() comments. 31 | inputFile[i] = line.replace(/(\s?\*\s?\@returns\s\{)(any)(\})/, `$1${currentClass}JSON$3`); 32 | //const m = /(\s?\*\s?\@returns\s\{)(any)(\})/.exec(line); 33 | //console.log(`${m} | ${line}`); 34 | } 35 | const jsonDefs = fs.readFileSync('./json-gen/output/json-types.d.ts', 'utf8'); 36 | fs.writeFile( 37 | `${pathToRepo}/pkg/${underscoreRepoName}_wasm.d.ts`, 38 | `${inputFile.join('\n')}\n${jsonDefs}`, 39 | (err) => { 40 | if (err != null) { 41 | console.log(`err writing file: ${err}`) 42 | } 43 | } 44 | ); 45 | -------------------------------------------------------------------------------- /scripts/legacy/wasm-to-asm.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | 3 | const paths = [ 4 | './rust/pkg/cardano_multiplatform_lib_bg.js', 5 | './rust/pkg/cardano_multiplatform_lib.js' 6 | ] 7 | 8 | paths.forEach((path) => { 9 | fs.readFile(path, 'utf8', (err,data) => { 10 | if (err) { 11 | return console.log(err); 12 | } 13 | 14 | const result = data.replace(/_bg.wasm/g, '.asm.js'); 15 | 16 | fs.writeFile(path, result, 'utf8', (err) => { 17 | if (err) return console.log(err); 18 | }); 19 | }); 20 | }) 21 | 22 | fs.unlinkSync('./rust/pkg/cardano_multiplatform_lib_bg.wasm') 23 | -------------------------------------------------------------------------------- /scripts/publish-helper.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path') 3 | 4 | const crateName = process.argv.slice(2)[0]; 5 | const hyphenRepoName = process.argv.slice(2)[1].replaceAll('_', '-'); 6 | const buildType /* : '-browser' | '-asmjs' | '-nodejs' */ = process.argv.slice(2)[2]; 7 | 8 | const underscoreRepoName = hyphenRepoName.replaceAll('-', '_'); 9 | const pathToRepo = path.join(__dirname, '..', crateName, 'wasm'); 10 | const oldPkg = require(`${pathToRepo}/publish/package.json`); 11 | 12 | const packageNameRoot = hyphenRepoName.split("-wasm")[0]; 13 | oldPkg.name = '@dcspark/' + packageNameRoot + buildType; 14 | if (buildType === '-browser' || buildType === '-asmjs') { 15 | // due to a bug in wasm-pack, this file is missing from browser builds 16 | const missingFile = `${underscoreRepoName}_bg.js`; 17 | if (oldPkg.files.find(entry => entry === missingFile) == null) { 18 | oldPkg.files.push(missingFile); 19 | } 20 | } 21 | if (buildType === '-asmjs') { 22 | // need to replace WASM with ASM package 23 | const missingFile = `${underscoreRepoName}_bg.wasm`; 24 | oldPkg.files = [ 25 | `${underscoreRepoName}.asm.js`, 26 | ...oldPkg.files.filter(file => file !== `${underscoreRepoName}_bg.wasm`) 27 | ]; 28 | } 29 | 30 | oldPkg.repository = { 31 | type: "git", 32 | url: "git+https://github.com/dcSpark/cardano-multiplatform-lib.git" 33 | }; 34 | oldPkg.author = "dcSpark"; 35 | oldPkg.license = "MIT"; 36 | console.log(oldPkg); 37 | fs.writeFileSync(`${pathToRepo}/publish/package.json`, JSON.stringify(oldPkg, null, 2)); 38 | -------------------------------------------------------------------------------- /scripts/wasm-to-asm.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | 3 | const pkgModName = process.argv.slice(2)[0]; 4 | 5 | const repoName = `cml`; 6 | 7 | const paths = [ 8 | `./pkg/${repoName}_${pkgModName}_bg.js`, 9 | `./pkg/${repoName}_${pkgModName}.js` 10 | ] 11 | 12 | paths.forEach((path) => { 13 | fs.readFile(path, 'utf8', (err,data) => { 14 | if (err) { 15 | return console.log(err); 16 | } 17 | 18 | const result = data.replace(/_bg.wasm/g, '.asm.js'); 19 | 20 | fs.writeFile(path, result, 'utf8', (err) => { 21 | if (err) return console.log(err); 22 | }); 23 | }); 24 | }) 25 | 26 | fs.unlinkSync(`./pkg/${repoName}_${pkgModName}_bg.wasm`) 27 | -------------------------------------------------------------------------------- /specs/README.md: -------------------------------------------------------------------------------- 1 | # Generating from these specs 2 | 3 | We generate using [cddl-codegen](https://github.com/dcSpark/cddl-codegen) using the following arguments: 4 | 5 | For `chain`: 6 | 7 | ``` 8 | --input=specs/babbage --output=CML_CHAIN_DIR --preserve-encodings=true --canonical-form=true --json-serde-derives=true --json-schema-export=true 9 | ``` 10 | 11 | For `cip36`: 12 | 13 | ``` 14 | --input=specs/cip36.cddl --output=CML_CIP36_DIR --preserve-encodings=true --canonical-form=true --json-serde-derives=true --json-schema-export=true 15 | ``` 16 | 17 | For `cip25`: 18 | 19 | ``` 20 | --input=specs/cip25.cddl --output=CML_CIP25_DIR --json-serde-derives=true --json-schema-export=true 21 | ``` 22 | 23 | To run from the cddl-codegen directory this would be prefixed with `cargo run -- --input=specs/...` 24 | 25 | # Generating CDDL instances 26 | 27 | First you need to install `cddl` 28 | ``` 29 | sudo apt install ruby 30 | sudo gem install cddl 31 | sudo gem install cbor-diag 32 | ``` 33 | 34 | You can generate new tests with 35 | 1) `cddl specs/shelley.cddl generate 1 > test/name_here.diag` 36 | 2) `diag2cbor.rb test/name_here.diag > test/name_here.cbor` 37 | 38 | You can combine these together with `cddl specs/shelley.cddl generate 1 | diag2cbor.rb > test/name_here.cbor` 39 | -------------------------------------------------------------------------------- /specs/byron_minimal.cddl: -------------------------------------------------------------------------------- 1 | ; Basic Cardano Types 2 | 3 | ; blake2b224 = bytes .size 28 4 | ; bip32_public_key = bytes .size 64 5 | ; script = bytes .size 32 6 | ; public_key = bytes .size 32 7 | 8 | blake2b224 = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 9 | bip32_public_key = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 10 | byron_script = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 11 | public_key = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 12 | 13 | ; blake2b224 of sha256 of cbor(byron_addr_type, spending_data, addr_attributes) 14 | address_id = _CDDL_CODEGEN_RAW_BYTES_TYPE_ ; blake2b224 15 | stakeholder_id = _CDDL_CODEGEN_RAW_BYTES_TYPE_; blake2b224 16 | crc32 = _CDDL_CODEGEN_EXTERN_TYPE_ ; uint .size 4 ; @newtype 17 | protocol_magic = _CDDL_CODEGEN_EXTERN_TYPE_ ; uint .size 4 ; @newtype 18 | hd_address_payload = bytes ; @newtype 19 | 20 | ; Addresses 21 | 22 | ; cddl had bootstrap as (1, uint) but byron/mod.rs had no uint field. 23 | stake_distribution = [ 24 | ; @name SingleKey 25 | tag: 0, stakeholder_id // 26 | ; @name BootstrapEra 27 | bootstrap_era: 1 28 | ] 29 | 30 | spending_data = [ 31 | ; @name SpendingDataPubKey 32 | tag: 0, pubkey: bip32_public_key // 33 | ; @name SpendingDataScript 34 | tag: 1, script: byron_script // 35 | ; @name SpendingDataRedeem 36 | tag: 2, redeem: public_key 37 | ] 38 | 39 | 40 | byron_addr_type = 0 ; @name PublicKey 41 | / 1 ; @name Script 42 | / 2 ; @name Redeem 43 | 44 | addr_attributes = { 45 | ? 0 : bytes .cbor stake_distribution, ; @name stake_distribution 46 | ; strictly speaking, this may contain anything: 47 | ? 1 : bytes .cbor hd_address_payload, ; @name derivation_path 48 | ? 2 : bytes .cbor protocol_magic, ; @name protocol_magic 49 | } 50 | 51 | address_content = [address_id, addr_attributes, byron_addr_type] 52 | 53 | byron_address = [ 54 | content: #6.24(bytes .cbor address_content), 55 | crc: crc32, 56 | ] 57 | byron_tx_out = [ 58 | address: byron_address, 59 | amount: uint, 60 | ] -------------------------------------------------------------------------------- /specs/cip25.cddl: -------------------------------------------------------------------------------- 1 | CIP25_string64 = text .size (0..64) 2 | 3 | CIP25_files_details = 4 | { 5 | name : CIP25_string64, 6 | mediaType : CIP25_string64, 7 | src : CIP25_chunkable_string 8 | } 9 | 10 | 11 | CIP25_chunkable_string = 12 | CIP25_string64 ; @name single 13 | / 14 | [* CIP25_string64] ; @name chunked 15 | 16 | CIP25_metadata_details = 17 | { 18 | name : CIP25_string64, 19 | image : CIP25_chunkable_string, 20 | ? mediaType : CIP25_string64, 21 | ? description : CIP25_chunkable_string, 22 | ? files : [* CIP25_files_details] 23 | } 24 | 25 | CIP25_metadata = { 721 : CIP25_label_metadata } 26 | 27 | 28 | 29 | ; original two version cddl used to generate the initial serialization code: 30 | ; policy_id_v1 = string64 ; @newtype 31 | ; asset_name_v1 = string64 ; @newtype utf-8 32 | ; policy_id_v2 = bytes ; @newtype no longer in text 33 | ; asset_name_v2 = bytes ; @newtype no longer in text and utf-8 34 | ; label_metadata_v1 = { * policy_id_v1 => { * asset_name_v1 => metadata_details } } 35 | ; data = { * policy_id_v2 => { * asset_name_v2 => metadata_details } } 36 | ; label_metadata_v2 = { data: data, version: 2 } ; version 2 37 | ; label_metadata = label_metadata_v1 / label_metadata_v2 38 | 39 | ; all of those above are replaced by one partially hand-written type: 40 | ; the serialization code was mostly ripped from the code generated by the types above though 41 | 42 | CIP25_label_metadata = _CDDL_CODEGEN_EXTERN_TYPE_ 43 | 44 | ; this was hand-edited due to: 45 | ; a) avoid all these redundant types that only impact serialization and make it harder to integrate with the rest of CIP25 (PolicyId/AssetName) 46 | ; b) we need permissive parsing so even if we avoided it for a) we would still end up modfiying it -------------------------------------------------------------------------------- /specs/cip36.cddl: -------------------------------------------------------------------------------- 1 | CIP36_registration_cbor = { 2 | 61284: CIP36_key_registration, ; @name key_registration 3 | 61285: CIP36_registration_witness, ; @name registration_witness 4 | } 5 | 6 | public_key = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 7 | 8 | CIP36_voting_pub_key = public_key 9 | payment_address = _CDDL_CODEGEN_EXTERN_TYPE_ 10 | CIP36_nonce = uint 11 | CIP36_weight = uint .size 4 12 | CIP36_voting_purpose = uint 13 | CIP36_legacy_key_registration = CIP36_voting_pub_key 14 | CIP36_delegation = [ 15 | voting_pub_key: CIP36_voting_pub_key, 16 | weight: CIP36_weight, 17 | ] 18 | 19 | ; May support other stake credentials in the future. 20 | ; Such additional credentials should be tagged at the CDDL/CBOR level 21 | ; so that parsing is not ambiguous and future proof. 22 | ; However, to avoid breaking changes, the simple key credential is 23 | ; left untagged. 24 | CIP36_stake_credential = CIP36_staking_pub_key 25 | CIP36_stake_witness = ed25519_signature 26 | ; A stake key credential, not tagged for backward compatibility 27 | CIP36_staking_pub_key = public_key 28 | ; Witness for a stake key credential, not tagged for backward compatibility 29 | ed25519_signature = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 30 | 31 | CIP36_delegation_distribution = 32 | [+CIP36_delegation] ; @name weighted 33 | / CIP36_legacy_key_registration ; @name legacy 34 | 35 | CIP36_key_registration = { 36 | 1 : CIP36_delegation_distribution, ; @name delegation 37 | 2 : CIP36_stake_credential, ; @name stake_credential 38 | 3 : payment_address, ; @name payment_address 39 | 4 : CIP36_nonce, ; @name nonce 40 | ? 5 : CIP36_voting_purpose .default 0, ; @name voting_purpose 41 | } 42 | 43 | 44 | CIP36_registration_witness = { 45 | 1 : CIP36_stake_witness, ; @name stake_witness 46 | } 47 | 48 | 49 | CIP36_deregistration_cbor = { 50 | 61286: CIP36_key_deregistration, ; @name key_deregistration 51 | 61285: CIP36_deregistration_witness, ; @name deregistration_witness 52 | } 53 | 54 | CIP36_key_deregistration = { 55 | 1 : CIP36_stake_credential, ; @name stake_credential 56 | 2 : CIP36_nonce, ; @name nonce 57 | ? 3 : CIP36_voting_purpose .default 0, ; @name voting_purpose 58 | } 59 | 60 | CIP36_deregistration_witness = { 61 | 1 : CIP36_stake_witness, ; @name stake_witness 62 | } 63 | -------------------------------------------------------------------------------- /specs/conway/address.cddl: -------------------------------------------------------------------------------- 1 | 2 | ; to force the generation of its own struct instead of bytes 3 | ; since we have our own handwritten address struct 4 | ; address = bytes 5 | address = _CDDL_CODEGEN_EXTERN_TYPE_ 6 | ; reward_account = bytes 7 | reward_account = _CDDL_CODEGEN_EXTERN_TYPE_ 8 | 9 | ; address format: 10 | ; [ 8 bit header | payload ]; 11 | ; 12 | ; shelley payment addresses: 13 | ; bit 7: 0 14 | ; bit 6: base/other 15 | ; bit 5: pointer/enterprise [for base: stake cred is keyhash/scripthash] 16 | ; bit 4: payment cred is keyhash/scripthash 17 | ; bits 3-0: network id 18 | ; 19 | ; reward addresses: 20 | ; bits 7-5: 111 21 | ; bit 4: credential is keyhash/scripthash 22 | ; bits 3-0: network id 23 | ; 24 | ; byron addresses: 25 | ; bits 7-4: 1000 26 | 27 | ; 0000: base address: keyhash28,keyhash28 28 | ; 0001: base address: scripthash28,keyhash28 29 | ; 0010: base address: keyhash28,scripthash28 30 | ; 0011: base address: scripthash28,scripthash28 31 | ; 0100: pointer address: keyhash28, 3 variable length uint 32 | ; 0101: pointer address: scripthash28, 3 variable length uint 33 | ; 0110: enterprise address: keyhash28 34 | ; 0111: enterprise address: scripthash28 35 | ; 1000: byron address 36 | ; 1110: reward account: keyhash28 37 | ; 1111: reward account: scripthash28 38 | ; 1001 - 1101: future formats 39 | -------------------------------------------------------------------------------- /specs/conway/assets.cddl: -------------------------------------------------------------------------------- 1 | coin = uint 2 | 3 | ; does not accept 0. to make things easy for now we'll keep it as a coin alias 4 | ; but possibly it could be its own type with bounds checking (!=0) 5 | positive_coin = coin 6 | 7 | asset_name = bytes .size (0..32) ; @doc Use TryFrom<&str> / TryInto<&str> for utf8 text conversion and RawBytesEncoding for direct bytes access 8 | 9 | ; these two are technically hand-written but we keep them here so that other code can 10 | ; continue thinking they're maps and handle them like so (encoding details, etc) 11 | ; they will just invoke the Deref trait on the hand-written object anyway. 12 | ; So the hand-written part is more of a wrapper over the type defined below 13 | ; NOTE: this means that after generation you must unfortunately manually remove Mint 14 | ; MultiAsset doesn't need removing since it's only referenced by Value which is also 15 | ; externally defined. 16 | multi_asset = { * policy_id => { * asset_name => uint } } 17 | mint = { * policy_id => { * asset_name => non_zero_int_64 } } 18 | 19 | int64 = -9223372036854775808 .. 9223372036854775807 ; @no_alias 20 | 21 | ; likewise to positive_coin we have nonZeroInt64 22 | non_zero_int_64 = -9223372036854775808 .. 9223372036854775807 23 | 24 | ; original def (hand-written due to be being such a common struct to improve API + match old CML): 25 | ; value = coin / [coin,multiasset] 26 | value = _CDDL_CODEGEN_EXTERN_TYPE_ -------------------------------------------------------------------------------- /specs/conway/auxdata.cddl: -------------------------------------------------------------------------------- 1 | ; this is done in cml-core: 2 | 3 | ; transaction_metadatum = 4 | ; { * transaction_metadatum => transaction_metadatum } ; @name map 5 | ; / [ * transaction_metadatum ] ; @name list 6 | ; / int 7 | ; / bytes .size (0..64) 8 | ; / text .size (0..64) 9 | 10 | ; metadata = { * transaction_metadatum_label => transaction_metadatum } 11 | ; the above is correct but we needed to hand-write it to allow for duplicate keys 12 | metadata = _CDDL_CODEGEN_EXTERN_TYPE_ 13 | 14 | shelley_format_aux_data = metadata 15 | shelley_MA_format_aux_data = [ transaction_metadata: metadata ; Shelley-ma 16 | , auxiliary_scripts: [ * native_script ] 17 | ] 18 | 19 | conway_format_aux_data = #6.259({ 20 | ? 0 => metadata, ; @name metadata 21 | ? 1 => [ * native_script ], ; @name native_scripts 22 | ? 2 => [ * plutus_v1_script ], ; @name plutus_v1_scripts 23 | ? 3 => [ * plutus_v2_script ], ; @name plutus_v2_scripts 24 | ? 4 => [ * plutus_v3_script ], ; @name plutus_v3_scripts 25 | }) 26 | 27 | auxiliary_data = 28 | shelley_format_aux_data ; @name shelley 29 | / shelley_MA_format_aux_data ; @name shelley_MA 30 | / conway_format_aux_data ; @name conway 31 | -------------------------------------------------------------------------------- /specs/conway/block.cddl: -------------------------------------------------------------------------------- 1 | block = 2 | [ header 3 | , transaction_bodies : [* transaction_body] 4 | , transaction_witness_sets : [* transaction_witness_set] 5 | , auxiliary_data_set : {* transaction_index => auxiliary_data } 6 | , invalid_transactions : [* transaction_index ] 7 | ]; Valid blocks must also satisfy the following two constraints: 8 | ; 1) the length of transaction_bodies and transaction_witness_sets 9 | ; must be the same 10 | ; 2) every transaction_index must be strictly smaller than the 11 | ; length of transaction_bodies 12 | 13 | header = 14 | [ header_body 15 | , body_signature : KES_signature 16 | ] 17 | 18 | header_body = [ 19 | block_number : uint, 20 | slot : uint, 21 | prev_hash : block_header_hash / null, 22 | issuer_vkey : $vkey, 23 | vrf_vkey : $VRF_vkey, 24 | vrf_result : $VRF_cert, ; New, replaces nonce_vrf and leader_vrf 25 | block_body_size : uint, 26 | block_body_hash : block_body_hash, ; merkle triple root 27 | operational_cert: [operational_cert], 28 | protocol_version: [protocol_version], 29 | ] 30 | 31 | operational_cert = 32 | ( hot_vkey : $KES_vkey 33 | , sequence_number : uint 34 | , kes_period : uint 35 | , sigma : ed25519_signature 36 | ) 37 | 38 | protocol_version = (major: uint, minor: uint) 39 | -------------------------------------------------------------------------------- /specs/conway/crypto.cddl: -------------------------------------------------------------------------------- 1 | ;$hash28 /= bytes .size 28 2 | ;$hash32 /= bytes .size 32 3 | 4 | ;$vkey /= bytes .size 8 5 | 6 | ;$vrf_vkey /= bytes .size 8 7 | ;natural = #6.2(bytes) 8 | 9 | ;$kes_vkey /= bytes .size 8 10 | 11 | ;$signature /= bytes .size 16 12 | 13 | ;addr_keyhash = $hash28 14 | ;genesis_delegate_hash = $hash28 15 | ;pool_keyhash = $hash28 16 | ;genesishash = $hash28 17 | 18 | ;vrf_keyhash = $hash32 19 | ;auxiliary_data_hash = $hash32 20 | ;pool_metadata_hash = $hash32 21 | 22 | ; To compute a script hash, note that you must prepend 23 | ; a tag to the bytes of the script before hashing. 24 | ; The tag is determined by the language. 25 | ; The tags in the Babbage era are: 26 | ; "\x00" for multisig scripts 27 | ; "\x01" for Plutus V1 scripts 28 | ; "\x02" for Plutus V2 scripts 29 | ;scripthash = $hash28 30 | 31 | ;datum_hash = $hash32 32 | 33 | KES_signature = bytes .size 448 34 | 35 | ; this isn't referenced anywhere else so we don't provide it. 36 | ; signkeyKES = bytes .size 64 37 | 38 | VRF_cert = [ 39 | output: bytes, 40 | proof: bytes .size 80 41 | ] 42 | 43 | nonce_hash = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 44 | 45 | nonce = [ 46 | ; @name identity 47 | tag: 0 // 48 | ; @name hash 49 | tag: 1, hash: nonce_hash 50 | ] 51 | 52 | vkeywitness = [ $vkey, ed25519_signature ] 53 | 54 | ; this is defined in the byron era: 55 | addr_attributes = _CDDL_CODEGEN_EXTERN_TYPE_ 56 | 57 | bootstrap_witness = 58 | [ public_key : vkey 59 | , signature : ed25519_signature 60 | , chain_code : bytes .size 32 61 | , attributes : bytes .cbor addr_attributes 62 | ] 63 | 64 | 65 | ; all types hand-coded here: 66 | vkey = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 67 | VRF_vkey = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 68 | natural = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 69 | KES_vkey = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 70 | ed25519_signature = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 71 | ed25519_key_hash = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 72 | genesis_delegate_hash = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 73 | genesis_hash = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 74 | VRF_key_hash = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 75 | auxiliary_data_hash = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 76 | pool_metadata_hash = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 77 | script_hash = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 78 | datum_hash = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 79 | block_body_hash = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 80 | block_header_hash = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 81 | transaction_hash = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 82 | script_data_hash = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 83 | anchor_doc_hash = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 84 | -------------------------------------------------------------------------------- /specs/conway/governance.cddl: -------------------------------------------------------------------------------- 1 | 2 | voting_procedures = { + voter => { + gov_action_id => voting_procedure } } 3 | 4 | voting_procedure = 5 | [ vote 6 | , anchor / null 7 | ] 8 | 9 | proposal_procedure = 10 | [ deposit : coin 11 | , reward_account 12 | , gov_action 13 | , anchor 14 | ] 15 | 16 | gov_action = [ 17 | parameter_change_action // 18 | hard_fork_initiation_action // 19 | treasury_withdrawals_action // 20 | no_confidence // 21 | update_committee // 22 | new_constitution // 23 | ; @name info_action 24 | 6 25 | ] 26 | 27 | parameter_change_action = ( 28 | tag: 0, 29 | action_id: gov_action_id / null, 30 | update: protocol_param_update, 31 | policy_hash: script_hash / null, 32 | ) 33 | 34 | hard_fork_initiation_action = ( 35 | tag: 1 36 | action_id: gov_action_id / null, 37 | version: [protocol_version] 38 | ) 39 | 40 | treasury_withdrawals_action = ( 41 | tag: 2, 42 | withdrawal: { $reward_account => coin }, 43 | policy_hash: script_hash / null, 44 | ) 45 | 46 | no_confidence = ( 47 | tag: 3, 48 | action_id: gov_action_id / null 49 | ) 50 | 51 | update_committee = ( 52 | tag: 4, 53 | action_id: gov_action_id / null, 54 | cold_credentials: set, 55 | credentials: { * committee_cold_credential => epoch }, 56 | unit_interval 57 | ) 58 | 59 | new_constitution = ( 60 | tag: 5, 61 | action_id: gov_action_id / null, 62 | constitution 63 | ) 64 | 65 | constitution = [ 66 | anchor, 67 | script_hash / null, 68 | ] 69 | 70 | voter = [ 71 | ; @name constitutional_committee_hot_key_hash 72 | 0, ed25519_key_hash // 73 | ; @name constitutional_committee_hot_script_hash 74 | 1, script_hash // 75 | ; @name d_rep_key_hash 76 | 2, ed25519_key_hash // 77 | ; @name d_rep_script_hash 78 | 3, script_hash // 79 | ; @name staking_pool_key_hash 80 | 4, ed25519_key_hash 81 | ] 82 | 83 | anchor = [ 84 | anchor_url : url, 85 | anchor_doc_hash, 86 | ] 87 | 88 | vote = 0 ; @name no 89 | / 1 ; @name yes 90 | / 2 ; @name abstain 91 | 92 | gov_action_id = 93 | [ transaction_id : transaction_hash 94 | , gov_action_index : uint 95 | ] -------------------------------------------------------------------------------- /specs/conway/plutus.cddl: -------------------------------------------------------------------------------- 1 | ; bounded_bytes = bytes .size (0..64) 2 | ; ; the real bounded_bytes does not have this limit. it instead has a different 3 | ; ; limit which cannot be expressed in CDDL. 4 | ; ; The limit is as follows: 5 | ; ; - bytes with a definite-length encoding are limited to size 0..64 6 | ; ; - for bytes with an indefinite-length CBOR encoding, each chunk is 7 | ; ; limited to size 0..64 8 | ; ; ( reminder: in CBOR, the indefinite-length encoding of bytestrings 9 | ; ; consists of a token #2.31 followed by a sequence of definite-length 10 | ; ; encoded bytestrings and a stop code ) 11 | bounded_bytes = bytes ; @no_alias 12 | 13 | plutus_v1_script = bytes ; @newtype 14 | plutus_v2_script = bytes ; @newtype 15 | plutus_v3_script = bytes ; @newtype 16 | 17 | ; original def: 18 | ; { * plutus_data => plutus_data } 19 | ; we hand-code it to handle duplicates 20 | plutus_map = _CDDL_CODEGEN_EXTERN_TYPE_ 21 | 22 | plutus_data = 23 | constr_plutus_data 24 | / plutus_map ; @name map 25 | / [ * plutus_data ] ; @name list 26 | / big_integer ; @name integer 27 | / bounded_bytes ; @name bytes 28 | 29 | big_integer = _CDDL_CODEGEN_EXTERN_TYPE_ 30 | 31 | ; original definition not used to avoid hundreds of variants: 32 | ; constr = 33 | ; #6.121([* a]) 34 | ; / #6.122([* a]) 35 | ; / #6.123([* a]) 36 | ; / #6.124([* a]) 37 | ; / #6.125([* a]) 38 | ; / #6.126([* a]) 39 | ; / #6.127([* a]) 40 | ; ; similarly for tag range: 6.1280 .. 6.1400 inclusive 41 | ; / #6.102([alternative: uint, fields: [* a]]) 42 | constr_plutus_data = _CDDL_CODEGEN_EXTERN_TYPE_ 43 | 44 | redeemer_key = [ tag: redeemer_tag, index: uint ] 45 | 46 | redeemer_val = [ data: plutus_data, ex_units: ex_units ] 47 | 48 | legacy_redeemer = [ tag: redeemer_tag, index: uint, data: plutus_data, ex_units: ex_units ] 49 | 50 | ; Flat Array support is included for backwards compatibility and will be removed in the next era. 51 | ; It is recommended for tools to adopt using a Map instead of Array going forward. 52 | redeemers = 53 | ; @name LegacyFlatFormat @doc This format will be deprecated in the next era 54 | [ + legacy_redeemer ] / 55 | ; @name MapFormat @doc New map format. Use this when possibe. 56 | { + redeemer_key => redeemer_val } 57 | 58 | redeemer_tag = 59 | 0 ; @name Spend 60 | / 1 ; @name Mint 61 | / 2 ; @name Cert 62 | / 3 ; @name Reward 63 | / 4 ; @name Voting 64 | / 5 ; @name Proposing 65 | 66 | ex_units = [mem: uint, steps: uint] 67 | 68 | ex_unit_prices = 69 | [ mem_price: sub_coin, step_price: sub_coin ] 70 | 71 | language = 0 ; @name plutus_v1 72 | / 1 ; @name plutus_v2 73 | / 2 ; @name plutus_v3 74 | 75 | cost_models = { * uint => [* int64] } ; @newtype 76 | ;cost_models = { 77 | ; ? 0 : [ 166*166 int ], ; @name plutus_v1 78 | ; ? 1 : [ 175*175 int ], ; @name plutus_v2 79 | ; ? 2 : [ 233*233 int ], ; @name plutus_v3 80 | ;} 81 | -------------------------------------------------------------------------------- /specs/multiera-byron/byron/block.cddl: -------------------------------------------------------------------------------- 1 | ; Blocks 2 | 3 | byron_difficulty = [u64] 4 | 5 | byron_block_signature_normal = [tag: 0, signature: byron_signature] 6 | byron_block_signature_proxy_light = [tag: 1, signature: light_weight_delegation_signature] 7 | byron_block_signature_proxy_heavy = [tag: 2, signature: byron_delegation_signature] 8 | 9 | byron_block_signature = byron_block_signature_normal ; @name signature 10 | / byron_block_signature_proxy_light ; @name proxy_light 11 | / byron_block_signature_proxy_heavy ; @name proxy_heavy 12 | 13 | byron_block_consensus_data = [byron_slot_id, byron_pub_key, byron_difficulty, byron_block_signature] 14 | 15 | block_header_extra_data = [ 16 | block_version: byron_block_version, 17 | software_version: byron_software_version, 18 | byron_attributes: byron_attributes, 19 | extraProof: blake2b256, 20 | ] 21 | 22 | byron_body_proof = [ txProof : byron_tx_proof 23 | , sscProof : ssc_proof 24 | , dlgProof : blake2b256 25 | , updProof : blake2b256 26 | ] 27 | 28 | byron_block_header = [ protocol_magic : u32 29 | , prevBlock : byron_block_id 30 | , bodyProof : byron_body_proof 31 | , consensusData : byron_block_consensus_data 32 | , extraData : block_header_extra_data 33 | ] 34 | 35 | tx_aux = [ byron_tx 36 | , [* byron_tx_witness] ; @name witness 37 | ] 38 | tx_payload = [* tx_aux] 39 | byron_block_body = [ txPayload : tx_payload 40 | , sscPayload : ssc 41 | , dlgPayload : [* byron_delegation] 42 | , updPayload : byron_update 43 | ] 44 | 45 | ; Epoch Boundary Blocks 46 | 47 | ebb_consensus_data = [ epoch_id, byron_difficulty ] 48 | 49 | ebb_head = [ protocol_magic : u32 50 | , prevBlock : byron_block_id 51 | , bodyProof : blake2b256 52 | , consensusData : ebb_consensus_data 53 | , extraData : [* byron_attributes] 54 | ] 55 | 56 | ;byron_ebb_wrapper = [0, byron_eb_block] 57 | ;byron_main_block_wrapper = [1, byron_main_block] 58 | ;byron_block = ebb_wrapper 59 | ; / main_block_wrapper 60 | 61 | ; this doesn't match what we're getting. we're getting the inner block instead directly 62 | ;byron_block = [ 63 | ; ; @name ebb_wrapper 64 | ; tag: 0, block: byron_eb_block // 65 | ; ; @name main_block_wrapper 66 | ; tag: 1, block: byron_main_block 67 | ;] 68 | byron_block = byron_eb_block ; @name epoch_boundary 69 | / byron_main_block ; @name main 70 | 71 | byron_main_block = [ header : byron_block_header 72 | , body : byron_block_body 73 | , extra : [* byron_attributes] 74 | ] 75 | 76 | byron_eb_block = [ header : ebb_head 77 | , body : [+ stakeholder_id] 78 | , extra : [* byron_attributes] 79 | ] -------------------------------------------------------------------------------- /specs/multiera-byron/byron/delegation.cddl: -------------------------------------------------------------------------------- 1 | ; Delegation 2 | 3 | byron_delegation = [ epoch : epoch_id 4 | , issuer : byron_pub_key 5 | , delegate : byron_pub_key 6 | , certificate : byron_signature 7 | ] 8 | 9 | byron_delegation_signature = [byron_delegation, byron_signature] 10 | 11 | epoch_range = [epoch_id, epoch_id] 12 | light_weight_dlg = [ epochRange : epoch_range 13 | , issuer : byron_pub_key 14 | , delegate : byron_pub_key 15 | , certificate : byron_signature 16 | ] 17 | 18 | light_weight_delegation_signature = [light_weight_dlg, byron_signature] -------------------------------------------------------------------------------- /specs/multiera-byron/byron/mod.cddl: -------------------------------------------------------------------------------- 1 | ; Cardano Byron blockchain CBOR schema 2 | 3 | u8 = uint .lt 256 ; @no_alias 4 | u16 = uint .lt 65536 ; @no_alias 5 | u32 = uint .size 4 ; @no_alias 6 | u64 = uint .size 8 ; @no_alias 7 | 8 | ; Basic Cardano Types 9 | 10 | ; we could maybe replace these all with named hashes but too many things 11 | ; in the spec are still directly defined here and byron isn't a priority 12 | blake2b224 = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 13 | blake2b256 = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 14 | 15 | byron_tx_id = blake2b256 16 | byron_block_id = blake2b256 17 | byron_update_id = blake2b256 18 | 19 | 20 | epoch_id = u64 21 | byron_slot_id = [ epoch: epoch_id, slot : u64 ] 22 | 23 | ; TODO: are either of these things we could use from cml-crypto? I assume so 24 | ; we can replace them later on with _CDDL_CODEGEN_RAW_BYTES_TYPE_ later once 25 | ; we get blocks parsing 26 | byron_pub_key = bytes 27 | byron_signature = bytes -------------------------------------------------------------------------------- /specs/multiera-byron/byron/transaction.cddl: -------------------------------------------------------------------------------- 1 | ; Transactions 2 | 3 | ; Attributes - at the moment we do not bother deserialising these, since they 4 | ; don't contain anything 5 | byron_any = _CDDL_CODEGEN_EXTERN_TYPE_ 6 | byron_attributes = { * byron_any => byron_any} ; @name byron_attributes 7 | ;byron_attributes = {* any => any} 8 | 9 | 10 | byron_tx_out_ptr = [ byron_tx_id 11 | , u32 ; @name index 12 | ] 13 | 14 | byron_tx_in_regular = [ 0 15 | , #6.24(bytes .cbor (byron_tx_out_ptr)) 16 | ] 17 | ; TODO: better type 18 | byron_tx_in_genesis = [ 19 | u8 .ne 0, 20 | #6.24(bytes), 21 | ] 22 | byron_tx_in = byron_tx_in_regular / byron_tx_in_genesis 23 | 24 | byron_tx = [ 25 | inputs: [+ byron_tx_in], 26 | outputs: [+ byron_tx_out], 27 | attrs: byron_attributes, 28 | ] 29 | 30 | byron_tx_proof = [ u32 ; @name number - number of transactions in this tree 31 | , blake2b256 ; @name root - root of the merkle tree of transactions 32 | , blake2b256 ; @name witnesses_hash - hash of Sequence of TxWitnesses encoded in CBOR 33 | ] 34 | 35 | byron_pk_witness_entry = [byron_pub_key, byron_signature] 36 | ; TODO: what are these types? I think they were never used in mainnet 37 | byron_validator_script = [ u16 38 | , bytes 39 | ] 40 | ; TODO: what are these types? I think they were never used in mainnet 41 | byron_redeemer_script = [ u16 42 | , bytes 43 | ] 44 | byron_script_witness_entry = [byron_validator_script, byron_redeemer_script] 45 | byron_redeemer_witness_entry = [byron_pub_key, byron_signature] 46 | 47 | ; TODO: debug why cddl-codegen isn't emitting these normally 48 | ; byron_tx_witness = [0, #6.24(bytes .cbor (byron_pk_witness_entry))] ; @name pk_witness 49 | ; / [1, #6.24(bytes .cbor (byron_script_witness_entry))] ; @name script_witness 50 | ; / [2, #6.24(bytes .cbor (byron_redeemer_witness_entry))] ; @name redeem_witness 51 | 52 | byron_pk_witness = (0, #6.24(bytes .cbor (byron_pk_witness_entry))) 53 | byron_script_witness = (1, #6.24(bytes .cbor (byron_script_witness_entry))) 54 | byron_redeem_witness = (2, #6.24(bytes .cbor (byron_redeemer_witness_entry))) 55 | 56 | byron_tx_witness = [ 57 | byron_pk_witness 58 | // byron_script_witness 59 | // byron_redeem_witness 60 | ] -------------------------------------------------------------------------------- /specs/multiera-byron/byron/update.cddl: -------------------------------------------------------------------------------- 1 | ; Updates 2 | 3 | ; is this the same one? is big_integer here. is this the cbor prelude? 4 | big_integer = _CDDL_CODEGEN_EXTERN_TYPE_ 5 | 6 | byron_block_version = [ 7 | u16 ; @name major 8 | , u16 ; @name minor 9 | , u8 ; @name alt 10 | ] 11 | 12 | std_fee_policy = [ big_integer ; @name summand 13 | , big_integer ; @name multiplier 14 | ] 15 | byron_tx_fee_policy = [ 0 16 | , #6.24(bytes .cbor (std_fee_policy)) ; @name std_fee_policy 17 | ] 18 | 19 | coin_portion = u64 20 | soft_fork_rule = [ coin_portion ; @name init_threshold 21 | , coin_portion ; @name min_threshold 22 | , coin_portion ; @name threshold_decrement 23 | ] 24 | bvermod = [ scriptVersion : [? u16] 25 | , slotDuration : [? big_integer] 26 | , maxBlockSize : [? big_integer] 27 | , maxHeaderSize : [? big_integer] 28 | , maxTxSize : [? big_integer] 29 | , maxProposalSize : [? big_integer] 30 | , mpcThd : [? u64] 31 | , heavyDelThd : [? u64] 32 | , updateVoteThd : [? u64] 33 | , updateProposalThd : [? u64] 34 | , updateImplicit : [? u64] 35 | , softForkRule : [? soft_fork_rule] 36 | , txFeePolicy : [? byron_tx_fee_policy] 37 | , unlockStakeEpoch : [? epoch_id] 38 | ] 39 | 40 | byron_update_data = [ blake2b256 ; @name app_diff_hash 41 | , blake2b256 ; @name pkg_hash 42 | , blake2b256 ; @name updater_hash 43 | , blake2b256 ; @name metadata_hash 44 | ] 45 | 46 | byron_software_version = [ text ; @name application_name 47 | , u32 ; @name application_version 48 | ] 49 | 50 | ;byron_update_proposal_data_entry = [ text ; @name system_tag 51 | ; , byron_update_data 52 | ; ] 53 | system_tag = text 54 | 55 | byron_update_proposal = [ blockVersion : byron_block_version 56 | , blockVersionMod : bvermod 57 | , softwareVersion : byron_software_version 58 | ; this does not match the on-chain data I've seen 59 | ; , data : #6.258(byron_update_proposal_data_entry) 60 | ; this is what we're seeing: 61 | , data: { * system_tag => byron_update_data } 62 | , byron_attributes : byron_attributes 63 | , from : byron_pub_key 64 | , signature : byron_signature 65 | ] 66 | 67 | byron_update_vote = [ voter : byron_pub_key 68 | , proposalId : byron_update_id 69 | , vote : bool 70 | , signature : byron_signature 71 | ] 72 | 73 | byron_update = [ proposal : [? byron_update_proposal] 74 | , votes : [* byron_update_vote] 75 | ] 76 | -------------------------------------------------------------------------------- /specs/multiera-byron/cml_chain/byron.cddl: -------------------------------------------------------------------------------- 1 | ; Basic Cardano Types 2 | 3 | ; blake2b224 = bytes .size 28 4 | ; bip32_public_key = bytes .size 64 5 | ; script = bytes .size 32 6 | ; public_key = bytes .size 32 7 | 8 | bip32_public_key = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 9 | byron_script = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 10 | public_key = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 11 | 12 | ; blake2b224 of sha256 of cbor(byron_addr_type, spending_data, addr_attributes) 13 | address_id = _CDDL_CODEGEN_RAW_BYTES_TYPE_ ; blake2b224 14 | stakeholder_id = _CDDL_CODEGEN_RAW_BYTES_TYPE_; blake2b224 15 | crc32 = _CDDL_CODEGEN_EXTERN_TYPE_ ; uint .size 4 ; @newtype 16 | protocol_magic = _CDDL_CODEGEN_EXTERN_TYPE_ ; uint .size 4 ; @newtype 17 | hd_address_payload = _CDDL_CODEGEN_EXTERN_TYPE_ 18 | 19 | ; Addresses 20 | 21 | ; cddl had bootstrap as (1, uint) but byron/mod.rs had no uint field. 22 | stake_distribution = _CDDL_CODEGEN_EXTERN_TYPE_ 23 | 24 | spending_data = _CDDL_CODEGEN_EXTERN_TYPE_ 25 | 26 | 27 | byron_addr_type = 0 ; @name PublicKey 28 | / 1 ; @name Script 29 | / 2 ; @name Redeem 30 | 31 | addr_attributes = _CDDL_CODEGEN_EXTERN_TYPE_ 32 | 33 | address_content = _CDDL_CODEGEN_EXTERN_TYPE_ 34 | byron_address = _CDDL_CODEGEN_EXTERN_TYPE_ 35 | byron_tx_out = _CDDL_CODEGEN_EXTERN_TYPE_ -------------------------------------------------------------------------------- /specs/multiera-byron/lib.cddl: -------------------------------------------------------------------------------- 1 | ; note: this is in a separate directory due to byron not using the --preserve-encodings=true flag 2 | ; this is since: 3 | ; a) not supported for floats 4 | ; a) for consistency with what we generated before in cml-chain/byron module 5 | ; c) not needed since byron is all canonical -------------------------------------------------------------------------------- /specs/multiera/_CDDL_CODEGEN_EXTERN_DEPS_DIR_/cml_chain/address.cddl: -------------------------------------------------------------------------------- 1 | address = _CDDL_CODEGEN_EXTERN_TYPE_ 2 | reward_address = _CDDL_CODEGEN_EXTERN_TYPE_ 3 | reward_account = _CDDL_CODEGEN_EXTERN_TYPE_ -------------------------------------------------------------------------------- /specs/multiera/_CDDL_CODEGEN_EXTERN_DEPS_DIR_/cml_chain/assets.cddl: -------------------------------------------------------------------------------- 1 | value = _CDDL_CODEGEN_EXTERN_TYPE_ 2 | asset_name = _CDDL_CODEGEN_EXTERN_TYPE_ 3 | policy_id = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 4 | 5 | int64 = -9223372036854775808 .. 9223372036854775807 ; @no_alias 6 | mint = { * policy_id => { * asset_name => int64 } } 7 | coin = uint -------------------------------------------------------------------------------- /specs/multiera/_CDDL_CODEGEN_EXTERN_DEPS_DIR_/cml_chain/auxdata.cddl: -------------------------------------------------------------------------------- 1 | metadata = _CDDL_CODEGEN_EXTERN_TYPE_ 2 | shelley_format_aux_data = _CDDL_CODEGEN_EXTERN_TYPE_ 3 | shelley_MA_format_aux_data = _CDDL_CODEGEN_EXTERN_TYPE_ -------------------------------------------------------------------------------- /specs/multiera/_CDDL_CODEGEN_EXTERN_DEPS_DIR_/cml_chain/block.cddl: -------------------------------------------------------------------------------- 1 | protocol_version = ( 2 | major: uint, 3 | minor: uint, 4 | ) 5 | 6 | operational_cert = 7 | ( hot_vkey : $KES_vkey 8 | , sequence_number : uint 9 | , kes_period : uint 10 | , sigma : ed25519_signature 11 | ) 12 | 13 | header = _CDDL_CODEGEN_EXTERN_TYPE_ -------------------------------------------------------------------------------- /specs/multiera/_CDDL_CODEGEN_EXTERN_DEPS_DIR_/cml_chain/byron.cddl: -------------------------------------------------------------------------------- 1 | ; Basic Cardano Types 2 | 3 | ; blake2b224 = bytes .size 28 4 | ; bip32_public_key = bytes .size 64 5 | ; script = bytes .size 32 6 | ; public_key = bytes .size 32 7 | 8 | blake2b224 = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 9 | blake2b256 = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 10 | bip32_public_key = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 11 | byron_script = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 12 | public_key = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 13 | 14 | ; blake2b224 of sha256 of cbor(byron_addr_type, spending_data, addr_attributes) 15 | address_id = _CDDL_CODEGEN_RAW_BYTES_TYPE_ ; blake2b224 16 | stakeholder_id = _CDDL_CODEGEN_RAW_BYTES_TYPE_; blake2b224 17 | crc32 = _CDDL_CODEGEN_EXTERN_TYPE_ ; uint .size 4 ; @newtype 18 | protocol_magic = _CDDL_CODEGEN_EXTERN_TYPE_ ; uint .size 4 ; @newtype 19 | hd_address_payload = _CDDL_CODEGEN_EXTERN_TYPE_ 20 | 21 | ; Addresses 22 | 23 | ; cddl had bootstrap as (1, uint) but byron/mod.rs had no uint field. 24 | stake_distribution = _CDDL_CODEGEN_EXTERN_TYPE_ 25 | 26 | spending_data = _CDDL_CODEGEN_EXTERN_TYPE_ 27 | 28 | 29 | byron_addr_type = 0 ; @name PublicKey 30 | / 1 ; @name Script 31 | / 2 ; @name Redeem 32 | 33 | addr_attributes = _CDDL_CODEGEN_EXTERN_TYPE_ 34 | 35 | address_content = _CDDL_CODEGEN_EXTERN_TYPE_ 36 | byron_address = _CDDL_CODEGEN_EXTERN_TYPE_ 37 | byron_tx_out = _CDDL_CODEGEN_EXTERN_TYPE_ 38 | byron_tx = _CDDL_CODEGEN_EXTERN_TYPE_ -------------------------------------------------------------------------------- /specs/multiera/_CDDL_CODEGEN_EXTERN_DEPS_DIR_/cml_chain/certs.cddl: -------------------------------------------------------------------------------- 1 | stake_credential = _CDDL_CODEGEN_EXTERN_TYPE_ 2 | pool_metadata = _CDDL_CODEGEN_EXTERN_TYPE_ 3 | 4 | ; THESE CANNOT BE EXTERN SINCE THEY ARE PLAIN GROUPS SO DELETE THEM AFTER 5 | ipv4 = bytes .size 4 ; @custom_json 6 | ipv6 = bytes .size 16 ; @custom_json 7 | single_host_addr = ( tag: 0 8 | , port / null 9 | , ipv4 / null 10 | , ipv6 / null 11 | ) 12 | 13 | stake_registration = (tag: 0, stake_credential) 14 | stake_deregistration = (tag: 1, stake_credential) 15 | stake_delegation = ( 16 | tag: 2, 17 | stake_credential, 18 | ed25519_key_hash ; @name pool 19 | ) 20 | pool_retirement = ( 21 | tag: 4, 22 | ed25519_key_hash, ; @name pool 23 | epoch 24 | ) -------------------------------------------------------------------------------- /specs/multiera/_CDDL_CODEGEN_EXTERN_DEPS_DIR_/cml_chain/crypto.cddl: -------------------------------------------------------------------------------- 1 | vkeywitness = _CDDL_CODEGEN_EXTERN_TYPE_ 2 | bootstrap_witness = _CDDL_CODEGEN_EXTERN_TYPE_ 3 | nonce = _CDDL_CODEGEN_EXTERN_TYPE_ 4 | KES_signature = _CDDL_CODEGEN_EXTERN_TYPE_ 5 | VRF_cert = _CDDL_CODEGEN_EXTERN_TYPE_ 6 | 7 | vkey = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 8 | VRF_vkey = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 9 | natural = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 10 | KES_vkey = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 11 | ed25519_signature = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 12 | ed25519_key_hash = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 13 | genesis_delegate_hash = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 14 | genesis_hash = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 15 | VRF_key_hash = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 16 | auxiliary_data_hash = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 17 | pool_metadata_hash = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 18 | script_hash = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 19 | datum_hash = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 20 | block_body_hash = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 21 | block_header_hash = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 22 | transaction_hash = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 23 | script_data_hash = _CDDL_CODEGEN_RAW_BYTES_TYPE_ -------------------------------------------------------------------------------- /specs/multiera/_CDDL_CODEGEN_EXTERN_DEPS_DIR_/cml_chain/mod.cddl: -------------------------------------------------------------------------------- 1 | ; this module is structured so that imports won't have to be changed at all. 2 | ; just replace use crate::cml_chain::{foo, bar, etc...} with use cml_chain::{foo, bar, etc...} 3 | ; some types aren't _CDDL_CODEGEN_EXTERN_TYPE_ or _CDDL_CODEGEN_RAW_BYTES_TYPE_ 4 | ; and instead have their original definitions. 5 | ; this is in places where _CDDL_CODEGEN_EXTERN_TYPE_ needs the extra type info 6 | ; to be able to remember encodings (needs to know type and where to store the info 7 | ; since you can't just call member.serialize() generically and have it remember the encodings 8 | ; for when the encodings aren't interally stored (primtives mostly)). 9 | ; so just delete the cml_chain directory afterwards and change the import crate with ctrl-r. 10 | 11 | 12 | unit_interval = _CDDL_CODEGEN_EXTERN_TYPE_ 13 | rational = _CDDL_CODEGEN_EXTERN_TYPE_ 14 | 15 | 16 | delta_coin = _CDDL_CODEGEN_EXTERN_TYPE_ 17 | 18 | network_id = _CDDL_CODEGEN_EXTERN_TYPE_ 19 | 20 | epoch = uint 21 | port = uint .le 65535 22 | withdrawals = { * reward_account => coin } 23 | -------------------------------------------------------------------------------- /specs/multiera/_CDDL_CODEGEN_EXTERN_DEPS_DIR_/cml_chain/plutus.cddl: -------------------------------------------------------------------------------- 1 | plutus_data = _CDDL_CODEGEN_EXTERN_TYPE_ 2 | ex_units = _CDDL_CODEGEN_EXTERN_TYPE_ 3 | ex_unit_prices = _CDDL_CODEGEN_EXTERN_TYPE_ 4 | plutus_v1_script = _CDDL_CODEGEN_EXTERN_TYPE_ 5 | plutus_v2_script = _CDDL_CODEGEN_EXTERN_TYPE_ 6 | cost_models = _CDDL_CODEGEN_EXTERN_TYPE_ -------------------------------------------------------------------------------- /specs/multiera/_CDDL_CODEGEN_EXTERN_DEPS_DIR_/cml_chain/transaction.cddl: -------------------------------------------------------------------------------- 1 | transaction_input = _CDDL_CODEGEN_EXTERN_TYPE_ 2 | transaction_index = uint .size 2 3 | transaction_metadatum_label = uint 4 | transaction_metadatum = _CDDL_CODEGEN_EXTERN_TYPE_ 5 | transaction_body = _CDDL_CODEGEN_EXTERN_TYPE_ 6 | required_signers = [* ed25519_key_hash] 7 | native_script = _CDDL_CODEGEN_EXTERN_TYPE_ 8 | alonzo_format_tx_out = _CDDL_CODEGEN_EXTERN_TYPE_ 9 | datum_option = _CDDL_CODEGEN_EXTERN_TYPE_ -------------------------------------------------------------------------------- /specs/multiera/allegra/mod.cddl: -------------------------------------------------------------------------------- 1 | allegra_block = [ 2 | header: shelley_header, 3 | transaction_bodies : [* allegra_transaction_body], 4 | transaction_witness_sets : [* allegra_transaction_witness_set], 5 | auxiliary_data_set : 6 | { * transaction_index => allegra_auxiliary_data } 7 | ]; Valid blocks must also satisfy the following two constraints: 8 | ; 1) the length of transaction_bodies and transaction_witness_sets 9 | ; must be the same 10 | ; 2) every transaction_index must be strictly smaller than the 11 | ; length of transaction_bodies 12 | 13 | MIR_pot = 0 ; @name reserve 14 | / 1 ; @name treasury 15 | 16 | MIR_action = { * stake_credential => delta_coin } ; @name to_stake_credentials 17 | / coin ; @name to_other_pot 18 | 19 | move_instantaneous_reward = [ 20 | pot: MIR_pot, 21 | action: MIR_action, 22 | ] 23 | move_instantaneous_rewards_cert = (tag: 6, move_instantaneous_reward) 24 | 25 | allegra_certificate = [ 26 | stake_registration // 27 | stake_deregistration // 28 | stake_delegation // 29 | shelley_pool_registration // 30 | pool_retirement // 31 | genesis_key_delegation // 32 | move_instantaneous_rewards_cert 33 | ] 34 | 35 | allegra_transaction = [ 36 | body: allegra_transaction_body, 37 | witness_set: allegra_transaction_witness_set, 38 | auxiliary_data: allegra_auxiliary_data / null, 39 | ] 40 | 41 | allegra_transaction_witness_set = { 42 | ? 0: [* vkeywitness ], ; @name vkeywitnesses 43 | ? 1: [* native_script ], ; @name native_scripts 44 | ? 2: [* bootstrap_witness ], ; @name bootstrap_witnesses 45 | ; In the future, new kinds of witnesses can be added like this: 46 | ; , ? 4: [* foo_script ] 47 | ; , ? 5: [* plutus_script ] 48 | } 49 | 50 | 51 | 52 | allegra_auxiliary_data = 53 | shelley_format_aux_data ; @name shelley 54 | / shelley_MA_format_aux_data ; @name shelley_MA 55 | 56 | ; allegra differences 57 | allegra_transaction_body = { 58 | 0 : [* transaction_input], ; @name inputs 59 | 1 : [* shelley_transaction_output], ; @name outputs 60 | 2 : coin, ; @name fee 61 | ? 3 : uint, ; @name ttl 62 | ? 4 : [* allegra_certificate], ; @name certs 63 | ? 5 : withdrawals, ; @name withdrawals 64 | ? 6 : shelley_update, ; @name update 65 | ? 7 : auxiliary_data_hash, ; @name auxiliary_data_hash 66 | ? 8 : uint, ; @name validity_interval_start 67 | } 68 | -------------------------------------------------------------------------------- /specs/multiera/lib.cddl: -------------------------------------------------------------------------------- 1 | ; babbage block 2 | block = _CDDL_CODEGEN_EXTERN_TYPE_ 3 | 4 | byron_block = _CDDL_CODEGEN_EXTERN_TYPE_ 5 | 6 | multi_era_block = 7 | byron_block ; @name byron 8 | / shelley_block ; @name Shelley 9 | / allegra_block ; @name Allegra 10 | / mary_block ; @name Mary 11 | / alonzo_block ; @name Alonzo 12 | / babbage_block ; @name Babbage 13 | / block ; @name Conway 14 | 15 | multi_era_transaction_body = 16 | byron_tx ; @name byron 17 | / shelley_transaction_body ; @name Shelley 18 | / allegra_transaction_body ; @name Allegra 19 | / mary_transaction_body ; @name Mary 20 | / alonzo_transaction_body ; @name Alonzo 21 | / babbage_transaction_body ; @name Babbage 22 | / transaction_body ; @name Conway 23 | -------------------------------------------------------------------------------- /specs/multiera/mary/mod.cddl: -------------------------------------------------------------------------------- 1 | mary_block = [ 2 | header: shelley_header, 3 | transaction_bodies : [* mary_transaction_body], 4 | transaction_witness_sets : [* allegra_transaction_witness_set], 5 | auxiliary_data_set : 6 | { * transaction_index => allegra_auxiliary_data } 7 | ]; Valid blocks must also satisfy the following two constraints: 8 | ; 1) the length of transaction_bodies and transaction_witness_sets 9 | ; must be the same 10 | ; 2) every transaction_index must be strictly smaller than the 11 | ; length of transaction_bodies 12 | 13 | mary_transaction = [ 14 | body: mary_transaction_body, 15 | witness_set: allegra_transaction_witness_set, 16 | auxiliary_data: allegra_auxiliary_data / null, 17 | ] 18 | 19 | mary_transaction_output = [ 20 | address, 21 | amount : value, 22 | ] 23 | 24 | mary_transaction_body = { 25 | 0 : [* transaction_input], ; @name inputs 26 | 1 : [* mary_transaction_output], ; @name outputs 27 | 2 : coin, ; @name fee 28 | ? 3 : uint, ; @name ttl 29 | ? 4 : [* allegra_certificate], ; @name certs 30 | ? 5 : withdrawals, ; @name withdrawals 31 | ? 6 : shelley_update, ; @name update 32 | ? 7 : auxiliary_data_hash, ; @name auxiliary_data_hash 33 | ? 8 : uint, ; @name validity_interval_start 34 | ? 9 : mint, ; @name mint 35 | } 36 | 37 | 38 | -------------------------------------------------------------------------------- /test.sh: -------------------------------------------------------------------------------- 1 | set -eu 2 | nvm i && npm i && npm run rust:test -------------------------------------------------------------------------------- /test/1.cbor: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dcSpark/cardano-multiplatform-lib/a34592e1e0d3c1e958d72f05c72282d788403aa5/test/1.cbor -------------------------------------------------------------------------------- /test/1.diag: -------------------------------------------------------------------------------- 1 | [h'64616D6E696679', h'65787465726E697A6174696F6E', h'7374726570746F6E657572616C', 2309, 4432, h'647261667473776F6D616E73686970', 30([3427, 2195]), h'476C6F62756C61726961', 2687, 2821, h'73757065726163726F6D69616C', h'7365726F74696E65', h'696E69717569746F7573', 3685, 95, h'63686F6E64726F67656E79', 2111, 4529, 732, h'6D75636564696E65', [{0: 258([[h'666C756E6B79697368', 2523], [h'626564636C6F74686573', 3992], [h'76696E6567617265747465', 3046], [h'73616665626C6F77696E67', 4340]]), 1: [[3, h'73757363657074616E6365', h'64656772616475617465', 4688], [3, h'6170746E657373', h'666572726F7072696E74', 2032], [8, h'696E6465636F6D706F7361626C656E657373', 770], [6, h'73687275626C616E64', 2918]], 4: 3790, 5: 1502, 7: h'747261636B'}, {0: 258([[h'717569636B74686F726E', 1996]]), 1: [[2, h'6E6F6E6469766F726365', h'7079726F6C79746963', 3082], [1, h'7370656374726F70686F6E65', h'7175697A7A6963616C6C79', 2912]], 3: {[0, h'476F626965736F6369646165']: 2336, [2, h'64657874726F75736E657373']: 1038, [1, h'726570616E656C']: 4704}, 4: 1897, 5: 918, 6: [{}, {}]}], [0, [h'626162796F6C61747279', h'43617068'], 0, [h'726F756E64697368', h'7068797369636F6D65646963616C'], 4, [[h'6D617363756C79', h'636F6E73756C7461746F7279']], []], {1208: [[h'41737465726F73706F6E64796C69', h'7465726E65', -519], "uncommemorated"], 697: -523, 437: 3991}] 2 | -------------------------------------------------------------------------------- /tools/metadata-cddl-checker/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "metadata-cddl-checker" 3 | version = "6.2.0" 4 | edition = "2018" 5 | 6 | [dependencies] 7 | cddl = "0.5.2" 8 | -------------------------------------------------------------------------------- /tools/plutus-datum-codegen/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "plutus-datum-codegen" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | cddl = "0.9.1" 10 | cddl-codegen = { git = "https://github.com/dcSpark/cddl-codegen" } 11 | clap = { version = "4.3.12", features = ["derive"] } 12 | codegen = { git = "https://github.com/dcSpark/codegen", branch = "master" } -------------------------------------------------------------------------------- /tools/plutus-datum-codegen/README.md: -------------------------------------------------------------------------------- 1 | # Plutus Datum Codegen 2 | 3 | This is a tool that allows generating a rust/wasm library via cddl-codegen for parsing/creating Plutus datum specs. 4 | 5 | The resulting tool will be directly integrated into CML and will have the benefits over direct `PlutusData` that the structure verification will be automatically done for you, as well as the interface matching the spec. 6 | 7 | This tool will first verify that the input spec conforms to the plutus datum spec, and only if it does, will call cddl-codegen to generate it. 8 | 9 | ## How to use 10 | 11 | ``` 12 | cargo run -- --input=input.cddl --output=EXPORT --cddl-codegen=path/to/cddl-codegen --lib-name=plutus-datum-test 13 | ``` 14 | 15 | The input file must be a single file. Directories are not supported. If `--cddl-codegen` is a directory it will assume that this is the source code and `cargo run` will be run in that directory. If it is a file it will be assumed to be the compiled cddl-codegen binary, in which case `--static-dir` must be supplied e.g. the `/static/` dir of the `cddl-codegen` repo. 16 | 17 | ## Prelude 18 | 19 | ```cddl 20 | bounded_bytes = bytes ; @custom_serialize cml_chain::utils::write_bounded_bytes @custom_deserialize cml_chain::utils::read_bounded_bytes @no_alias 21 | ``` 22 | 23 | The bytes serialization format for plutus datums is slightly different than arbitrary CBOR bytes. Please use the alias `bounded_bytes` that hooks into the serialization code in CML. 24 | 25 | ```cddl 26 | utf8_text = text ; @custom_serialize crate::utils::serialize_utf8_bytes @custom_deserialize crate::utils::deserialize_utf8_bytes @no_alias 27 | 28 | ``` 29 | 30 | Plutus datums do not natively allow CBOR text, however, we provide a `utf8_bytes` alias that will be treated as `String` in the user-facing API with only the CBOR serialization logic converting to/from bytes using the utf8 byte representation. If this alias is used, the corresponding serialization functions will be exported into `utils.rs`. 31 | 32 | ## Example 33 | 34 | ```cddl 35 | ; tagged constructor (variant 2, concise fixed format) 36 | ; note that to the user this will be text, but on-chain it will be serialized to utf8 bytes 37 | foo = #6.123([* utf8_text]) 38 | 39 | ; regular array datum, but with specific struct structure forced on top 40 | abc = [ 41 | ; note that we MUST use bounded_bytes not regular bytes 42 | ; this is only an encoding detail (chunked into <=64-byte chunks) 43 | ; it is still regular bytes 44 | x: bounded_bytes, 45 | y: [* utf8_text], 46 | ] 47 | 48 | ; tagged constructor (arbitrary variant, generic format) 49 | bar = #6.102([ 50 | variant: uint, 51 | fields: [* abc] 52 | ]) 53 | ``` -------------------------------------------------------------------------------- /tools/plutus-datum-codegen/prelude/_CDDL_CODEGEN_EXTERN_DEPS_DIR_/cml_chain/address.cddl: -------------------------------------------------------------------------------- 1 | 2 | address = _CDDL_CODEGEN_EXTERN_TYPE_ 3 | 4 | reward_account = _CDDL_CODEGEN_EXTERN_TYPE_ 5 | -------------------------------------------------------------------------------- /tools/plutus-datum-codegen/prelude/_CDDL_CODEGEN_EXTERN_DEPS_DIR_/cml_chain/assets.cddl: -------------------------------------------------------------------------------- 1 | coin = uint 2 | 3 | positive_coin = coin 4 | 5 | value = _CDDL_CODEGEN_EXTERN_TYPE_ -------------------------------------------------------------------------------- /tools/plutus-datum-codegen/prelude/_CDDL_CODEGEN_EXTERN_DEPS_DIR_/cml_chain/auxdata.cddl: -------------------------------------------------------------------------------- 1 | metadata = _CDDL_CODEGEN_EXTERN_TYPE_ 2 | 3 | auxiliary_data = _CDDL_CODEGEN_EXTERN_TYPE_ -------------------------------------------------------------------------------- /tools/plutus-datum-codegen/prelude/_CDDL_CODEGEN_EXTERN_DEPS_DIR_/cml_chain/crypto.cddl: -------------------------------------------------------------------------------- 1 | vkey = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 2 | VRF_vkey = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 3 | natural = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 4 | KES_vkey = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 5 | ed25519_signature = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 6 | ed25519_key_hash = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 7 | genesis_delegate_hash = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 8 | genesis_hash = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 9 | VRF_key_hash = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 10 | auxiliary_data_hash = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 11 | pool_metadata_hash = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 12 | script_hash = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 13 | datum_hash = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 14 | block_body_hash = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 15 | block_header_hash = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 16 | transaction_hash = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 17 | script_data_hash = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 18 | anchor_doc_hash = _CDDL_CODEGEN_RAW_BYTES_TYPE_ 19 | -------------------------------------------------------------------------------- /tools/plutus-datum-codegen/prelude/_CDDL_CODEGEN_EXTERN_DEPS_DIR_/cml_chain/lib.cddl: -------------------------------------------------------------------------------- 1 | delta_coin = int 2 | transaction_index = uint .size 2 3 | port = uint .le 65535 4 | epoch = uint 5 | slot = uint 6 | transaction_metadatum_label = uint 7 | 8 | policy_id = script_hash 9 | 10 | network_id = uint ; @newtype -------------------------------------------------------------------------------- /tools/plutus-datum-codegen/prelude/_CDDL_CODEGEN_EXTERN_DEPS_DIR_/cml_chain/plutus.cddl: -------------------------------------------------------------------------------- 1 | plutus_v1_script = _CDDL_CODEGEN_EXTERN_TYPE_ 2 | plutus_v2_script = _CDDL_CODEGEN_EXTERN_TYPE_ 3 | plutus_v3_script = _CDDL_CODEGEN_EXTERN_TYPE_ 4 | 5 | plutus_data = _CDDL_CODEGEN_EXTERN_TYPE_ 6 | 7 | big_integer = _CDDL_CODEGEN_EXTERN_TYPE_ 8 | 9 | constr_plutus_data = _CDDL_CODEGEN_EXTERN_TYPE_ 10 | 11 | redeemer_tag = 12 | 0 ; @name Spend 13 | / 1 ; @name Mint 14 | / 2 ; @name Cert 15 | / 3 ; @name Reward 16 | / 4 ; @name Voting 17 | / 5 ; @name Proposing 18 | 19 | language = 0 ; @name plutus_v1 20 | / 1 ; @name plutus_v2 21 | / 2 ; @name plutus_v3 22 | -------------------------------------------------------------------------------- /tools/plutus-datum-codegen/prelude/_CDDL_CODEGEN_EXTERN_DEPS_DIR_/cml_chain/transaction.cddl: -------------------------------------------------------------------------------- 1 | transaction_input = [ transaction_id : transaction_hash 2 | , index : uint 3 | ] 4 | 5 | script = _CDDL_CODEGEN_EXTERN_TYPE_ 6 | 7 | native_script = _CDDL_CODEGEN_EXTERN_TYPE_ 8 | -------------------------------------------------------------------------------- /tools/plutus-datum-codegen/prelude/prelude.cddl: -------------------------------------------------------------------------------- 1 | ; plutus-specific types 2 | 3 | utf8_text = text ; @custom_serialize crate::utils::serialize_utf8_bytes @custom_deserialize crate::utils::deserialize_utf8_bytes @no_alias 4 | 5 | bounded_bytes = bytes ; @custom_serialize cml_chain::utils::write_bounded_bytes @custom_deserialize cml_chain::utils::read_bounded_bytes @no_alias 6 | -------------------------------------------------------------------------------- /tools/plutus-datum-codegen/src/cli.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | // TODO: make non-annotation generate different DeserializeError that is simpler 3 | // and works with From only 4 | 5 | #[derive(Debug, Default, Parser)] 6 | #[clap()] 7 | pub struct Cli { 8 | /// Location of cddl-codegen. e.g. ~/cddl-codegen/target/release/cddl-codegen (binary) or ~/cddl-codegen (repo) 9 | /// If it is a directory cargo run will be used and the /static/ dir there will be defaulted to. 10 | #[clap(short, long, value_parser, value_name = "CDDL_CODEGEN")] 11 | pub cddl_codegen: std::path::PathBuf, 12 | 13 | /// Input .cddl file to generate from. If this is a directory then it will read all *.cddl files and generate one output for each. 14 | #[clap(short, long, value_parser, value_name = "INPUT_FILE/INPUT_DIR")] 15 | pub input: std::path::PathBuf, 16 | 17 | /// Output directory for the generated code. 18 | #[clap(short, long, value_parser, value_name = "OUTPUT_DIR")] 19 | pub output: std::path::PathBuf, 20 | 21 | /// Change the directory of the static files. 22 | /// Does not need to be provided if --cddl-codegen is a directory, but will override that if it is. 23 | #[clap(short, long, value_parser, value_name = "STATIC_DIR")] 24 | pub static_dir: Option, 25 | 26 | /// Name to use for exported library. 27 | /// Will be used directly for rust lib and will have -wasm appended for the wasm bindings. 28 | /// This will appear EXACTLY as-is in the Cargo.toml's. use Cli::lib_name_code() for use in rust code 29 | #[clap( 30 | long, 31 | value_parser, 32 | value_name = "EXPORT_LIB_NAME", 33 | default_value = "cddl-lib" 34 | )] 35 | pub lib_name: String, 36 | 37 | /// Generates a wasm_bindgen crate for wasm bindings 38 | #[clap(long, value_parser, action = clap::ArgAction::Set, default_value_t = true)] 39 | pub wasm: bool, 40 | 41 | /// Derives serde::Serialize/serde::Deserialize for types to allow to/from JSON 42 | #[clap(long, value_parser, action = clap::ArgAction::Set, default_value_t = false)] 43 | pub json_serde_derives: bool, 44 | 45 | /// Tags types with sonSchema derives and generates a crate to export them 46 | #[clap(long, value_parser, action = clap::ArgAction::Set, default_value_t = false)] 47 | pub json_schema_export: bool, 48 | 49 | /// Generates a npm package.json along with build scripts 50 | #[clap(long, value_parser, action = clap::ArgAction::Set, default_value_t = false)] 51 | pub package_json: bool, 52 | } 53 | 54 | impl Cli { 55 | /// lib name from code i.e. with underscores 56 | pub fn lib_name_code(&self) -> String { 57 | self.lib_name.replace('-', "_") 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /tools/plutus-datum-codegen/src/utils.rs: -------------------------------------------------------------------------------- 1 | use std::path::{Path, PathBuf}; 2 | 3 | pub fn convert_to_camel_case(ident: &str) -> String { 4 | let mut camel_case = String::new(); 5 | let mut uppercase = true; 6 | for c in ident.chars() { 7 | match c { 8 | '_' | '-' => { 9 | uppercase = true; 10 | } 11 | '$' | '@' => { 12 | // ignored 13 | } 14 | c => { 15 | if uppercase { 16 | camel_case.push(c.to_ascii_uppercase()); 17 | uppercase = false; 18 | } else { 19 | camel_case.push(c); 20 | } 21 | } 22 | } 23 | } 24 | camel_case 25 | } 26 | 27 | pub fn copy_dir_all(from: &Path, to: &Path) -> std::io::Result<()> { 28 | std::fs::create_dir_all(to)?; 29 | for entry_res in std::fs::read_dir(from)? { 30 | let entry = entry_res?; 31 | if entry.file_type()?.is_dir() { 32 | copy_dir_all(&entry.path(), &to.join(entry.file_name()))?; 33 | } else { 34 | std::fs::copy(entry.path(), to.join(entry.file_name()))?; 35 | } 36 | } 37 | Ok(()) 38 | } 39 | 40 | pub fn read_dir_to_string_map( 41 | map: &mut Vec<(PathBuf, String)>, 42 | dir: impl AsRef, 43 | ) -> std::io::Result<()> { 44 | for entry_res in std::fs::read_dir(&dir)? { 45 | let entry = entry_res?; 46 | if entry.file_type()?.is_dir() { 47 | read_dir_to_string_map(map, entry.path())?; 48 | } else { 49 | map.push(( 50 | dir.as_ref().join(entry.file_name()).to_path_buf(), 51 | std::fs::read_to_string(entry.path())?, 52 | )); 53 | } 54 | } 55 | Ok(()) 56 | } 57 | --------------------------------------------------------------------------------