From 950113e6fbeda2d8c8ca0dd8f8acfa92705c1971 Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Mon, 4 Nov 2024 16:54:36 -0300 Subject: [PATCH 01/42] init refactor --- .gitignore | 6 +- .gitmodules | 4 +- Cargo.lock | 2565 ++------------ Cargo.toml | 13 +- packages/kos-crypto/Cargo.toml | 33 - packages/kos-crypto/src/blake2b.rs | 218 -- packages/kos-crypto/src/cipher.rs | 355 -- packages/kos-crypto/src/ed25519.rs | 154 - packages/kos-crypto/src/hash.rs | 31 - packages/kos-crypto/src/keypair.rs | 139 - packages/kos-crypto/src/lib.rs | 7 - packages/kos-crypto/src/mnemonic.rs | 16 - packages/kos-crypto/src/secp256k1.rs | 141 - packages/kos-crypto/src/serde_util.rs | 116 - packages/kos-mobile/Cargo.toml | 6 +- packages/kos-mobile/src/lib.rs | 106 +- packages/kos-proto/Cargo.toml | 38 - packages/kos-proto/build.rs | 182 - .../include/google/api/annotations.proto | 29 - .../proto/include/google/api/http.proto | 281 -- .../kos-proto/proto/klever/transaction.proto | 161 - .../proto/klever/userAccountData.proto | 43 - packages/kos-proto/proto/tron | 1 - packages/kos-proto/src/lib.rs | 71 - packages/kos-proto/src/options.rs | 436 --- packages/kos-sdk/Cargo.toml | 58 - packages/kos-sdk/build.rs | 9 - packages/kos-sdk/env.nodes.example | 7 - packages/kos-sdk/src/chain.rs | 248 -- packages/kos-sdk/src/chains/bitcoin/mod.rs | 551 --- .../kos-sdk/src/chains/bitcoin/requests.rs | 193 - .../kos-sdk/src/chains/bitcoin/transaction.rs | 265 -- packages/kos-sdk/src/chains/default/mod.rs | 133 - .../kos-sdk/src/chains/ethereum/address.rs | 193 - packages/kos-sdk/src/chains/ethereum/mod.rs | 749 ---- .../kos-sdk/src/chains/ethereum/request.rs | 121 - .../src/chains/ethereum/transaction.rs | 281 -- packages/kos-sdk/src/chains/evm20.rs | 82 - packages/kos-sdk/src/chains/klever/address.rs | 157 - .../kos-sdk/src/chains/klever/klever_test.rs | 250 -- packages/kos-sdk/src/chains/klever/mod.rs | 303 -- packages/kos-sdk/src/chains/klever/models.rs | 148 - .../kos-sdk/src/chains/klever/requests.rs | 89 - packages/kos-sdk/src/chains/mod.rs | 19 - packages/kos-sdk/src/chains/polygon/mod.rs | 357 -- packages/kos-sdk/src/chains/tron/address.rs | 196 -- packages/kos-sdk/src/chains/tron/mod.rs | 722 ---- packages/kos-sdk/src/chains/tron/requests.rs | 124 - packages/kos-sdk/src/lib.rs | 7 - packages/kos-sdk/src/models.rs | 276 -- packages/kos-sdk/src/utils.rs | 88 - packages/kos-sdk/src/wallet.rs | 674 ---- packages/kos-sdk/src/wm.rs | 650 ---- packages/kos-types/Cargo.toml | 30 - packages/kos-types/src/array_types.rs | 298 -- packages/kos-types/src/bytes.rs | 35 - packages/kos-types/src/error.rs | 157 - packages/kos-types/src/hash.rs | 74 - packages/kos-types/src/lib.rs | 44 - packages/kos-types/src/number.rs | 251 -- packages/kos-types/src/vectorize.rs | 26 - packages/kos-utils/Cargo.toml | 21 - packages/kos-utils/src/lib.rs | 28 - packages/kos-utils/src/logger.rs | 179 - packages/kos-web/Cargo.toml | 12 + packages/kos-web/src/lib.rs | 14 + packages/kos/Cargo.toml | 99 +- packages/kos/src/api.rs | 121 - packages/kos/src/chains/ada/address.rs | 122 + packages/kos/src/chains/ada/mod.rs | 152 + packages/kos/src/chains/apt/mod.rs | 96 + packages/kos/src/chains/atom/mod.rs | 134 + packages/kos/src/chains/bch/mod.rs | 175 + packages/kos/src/chains/bnb/mod.rs | 107 + packages/kos/src/chains/btc/mod.rs | 197 ++ packages/kos/src/chains/constants.rs | 57 + packages/kos/src/chains/default/mod.rs | 51 + packages/kos/src/chains/egld/mod.rs | 97 + packages/kos/src/chains/eth/mod.rs | 242 ++ packages/kos/src/chains/eth/models.rs | 182 + packages/kos/src/chains/icp/mod.rs | 158 + packages/kos/src/chains/klv/mod.rs | 244 ++ packages/kos/src/chains/klv/models.rs | 241 ++ packages/kos/src/chains/mod.rs | 348 ++ packages/kos/src/chains/movr/mod.rs | 118 + packages/kos/src/chains/sol/mod.rs | 85 + packages/kos/src/chains/substrate/mod.rs | 182 + packages/kos/src/chains/substrate/models.rs | 140 + packages/kos/src/chains/sui/mod.rs | 121 + packages/kos/src/chains/trx/mod.rs | 328 ++ packages/kos/src/chains/util.rs | 17 + packages/kos/src/chains/xrp/mod.rs | 119 + packages/kos/src/crypto/b58.rs | 51 + packages/kos/src/crypto/base64.rs | 63 + packages/kos/src/crypto/bignum.rs | 152 + packages/kos/src/crypto/bip32.rs | 360 ++ packages/kos/src/crypto/ed25519.rs | 64 + packages/kos/src/crypto/ed25519_bip32.rs | 37 + packages/kos/src/crypto/hash.rs | 87 + packages/kos/src/crypto/mnemonic.rs | 17 + packages/kos/src/crypto/mod.rs | 41 + packages/kos/src/crypto/pbkdf2.rs | 45 + packages/kos/src/crypto/rng.rs | 50 + packages/kos/src/crypto/secp256k1.rs | 119 + packages/kos/src/crypto/sr25519.rs | 80 + packages/kos/src/lib.rs | 82 +- packages/kos/src/models.rs | 218 ++ .../protos/generated/klv/google.protobuf.rs | 0 packages/kos/src/protos/generated/klv/mod.rs | 1 + .../kos/src/protos/generated/klv/proto.rs | 1645 +++++++++ packages/kos/src/protos/generated/mod.rs | 2 + .../protos/generated/trx/google.protobuf.rs | 0 packages/kos/src/protos/generated/trx/mod.rs | 1 + .../kos/src/protos/generated/trx/protocol.rs | 3109 +++++++++++++++++ .../src/protos}/klever/contracts.proto | 20 +- .../kos/src/protos/klever/transaction.proto | 137 + .../src/protos/klever/userAccountData.proto | 34 + packages/kos/src/protos/mod.rs | 62 + packages/kos/src/protos/tron/.gitignore | 4 + packages/kos/src/protos/tron/.travis.yml | 13 + ...inese version of TRON Protocol document.md | 696 ++++ ...glish version of TRON Protocol document.md | 736 ++++ packages/kos/src/protos/tron/LICENSE | 165 + packages/kos/src/protos/tron/README.md | 13 + packages/kos/src/protos/tron/api/api.proto | 1534 ++++++++ .../kos/src/protos/tron/api/zksnark.proto | 33 + .../kos/src/protos/tron/core/Discover.proto | 44 + packages/kos/src/protos/tron/core/Tron.proto | 891 +++++ .../protos/tron/core/TronInventoryItems.proto | 12 + .../tron/core/contract/account_contract.proto | 50 + .../core/contract/asset_issue_contract.proto | 60 + .../tron/core/contract/balance_contract.proto | 118 + .../protos/tron/core/contract/common.proto | 13 + .../core/contract/exchange_contract.proto | 37 + .../tron/core/contract/market_contract.proto | 19 + .../core/contract/proposal_contract.proto | 23 + .../tron/core/contract/shield_contract.proto | 81 + .../tron/core/contract/smart_contract.proto | 104 + .../tron/core/contract/storage_contract.proto | 27 + .../core/contract/vote_asset_contract.proto | 14 + .../tron/core/contract/witness_contract.proto | 27 + .../src/protos/tron/core/tron/account.proto | 0 .../kos/src/protos/tron/core/tron/block.proto | 0 .../tron/core/tron/delegated_resource.proto | 0 .../kos/src/protos/tron/core/tron/p2p.proto | 0 .../src/protos/tron/core/tron/proposal.proto | 0 .../protos/tron/core/tron/transaction.proto | 0 .../kos/src/protos/tron/core/tron/vote.proto | 0 .../src/protos/tron/core/tron/witness.proto | 0 .../kos/src/protos/tron/install-googleapis.sh | 14 + .../kos/src/protos/tron/install-protobuf.sh | 10 + 151 files changed, 15247 insertions(+), 13172 deletions(-) delete mode 100644 packages/kos-crypto/Cargo.toml delete mode 100644 packages/kos-crypto/src/blake2b.rs delete mode 100644 packages/kos-crypto/src/cipher.rs delete mode 100644 packages/kos-crypto/src/ed25519.rs delete mode 100644 packages/kos-crypto/src/hash.rs delete mode 100644 packages/kos-crypto/src/keypair.rs delete mode 100644 packages/kos-crypto/src/lib.rs delete mode 100644 packages/kos-crypto/src/mnemonic.rs delete mode 100644 packages/kos-crypto/src/secp256k1.rs delete mode 100644 packages/kos-crypto/src/serde_util.rs delete mode 100644 packages/kos-proto/Cargo.toml delete mode 100644 packages/kos-proto/build.rs delete mode 100644 packages/kos-proto/proto/include/google/api/annotations.proto delete mode 100644 packages/kos-proto/proto/include/google/api/http.proto delete mode 100644 packages/kos-proto/proto/klever/transaction.proto delete mode 100644 packages/kos-proto/proto/klever/userAccountData.proto delete mode 160000 packages/kos-proto/proto/tron delete mode 100644 packages/kos-proto/src/lib.rs delete mode 100644 packages/kos-proto/src/options.rs delete mode 100644 packages/kos-sdk/Cargo.toml delete mode 100644 packages/kos-sdk/build.rs delete mode 100644 packages/kos-sdk/env.nodes.example delete mode 100644 packages/kos-sdk/src/chain.rs delete mode 100644 packages/kos-sdk/src/chains/bitcoin/mod.rs delete mode 100644 packages/kos-sdk/src/chains/bitcoin/requests.rs delete mode 100644 packages/kos-sdk/src/chains/bitcoin/transaction.rs delete mode 100644 packages/kos-sdk/src/chains/default/mod.rs delete mode 100644 packages/kos-sdk/src/chains/ethereum/address.rs delete mode 100644 packages/kos-sdk/src/chains/ethereum/mod.rs delete mode 100644 packages/kos-sdk/src/chains/ethereum/request.rs delete mode 100644 packages/kos-sdk/src/chains/ethereum/transaction.rs delete mode 100644 packages/kos-sdk/src/chains/evm20.rs delete mode 100644 packages/kos-sdk/src/chains/klever/address.rs delete mode 100644 packages/kos-sdk/src/chains/klever/klever_test.rs delete mode 100644 packages/kos-sdk/src/chains/klever/mod.rs delete mode 100644 packages/kos-sdk/src/chains/klever/models.rs delete mode 100644 packages/kos-sdk/src/chains/klever/requests.rs delete mode 100644 packages/kos-sdk/src/chains/mod.rs delete mode 100644 packages/kos-sdk/src/chains/polygon/mod.rs delete mode 100644 packages/kos-sdk/src/chains/tron/address.rs delete mode 100644 packages/kos-sdk/src/chains/tron/mod.rs delete mode 100644 packages/kos-sdk/src/chains/tron/requests.rs delete mode 100644 packages/kos-sdk/src/lib.rs delete mode 100644 packages/kos-sdk/src/models.rs delete mode 100644 packages/kos-sdk/src/utils.rs delete mode 100644 packages/kos-sdk/src/wallet.rs delete mode 100644 packages/kos-sdk/src/wm.rs delete mode 100644 packages/kos-types/Cargo.toml delete mode 100644 packages/kos-types/src/array_types.rs delete mode 100644 packages/kos-types/src/bytes.rs delete mode 100644 packages/kos-types/src/error.rs delete mode 100644 packages/kos-types/src/hash.rs delete mode 100644 packages/kos-types/src/lib.rs delete mode 100644 packages/kos-types/src/number.rs delete mode 100644 packages/kos-types/src/vectorize.rs delete mode 100644 packages/kos-utils/Cargo.toml delete mode 100644 packages/kos-utils/src/lib.rs delete mode 100644 packages/kos-utils/src/logger.rs create mode 100644 packages/kos-web/Cargo.toml create mode 100644 packages/kos-web/src/lib.rs delete mode 100644 packages/kos/src/api.rs create mode 100644 packages/kos/src/chains/ada/address.rs create mode 100644 packages/kos/src/chains/ada/mod.rs create mode 100644 packages/kos/src/chains/apt/mod.rs create mode 100644 packages/kos/src/chains/atom/mod.rs create mode 100644 packages/kos/src/chains/bch/mod.rs create mode 100644 packages/kos/src/chains/bnb/mod.rs create mode 100644 packages/kos/src/chains/btc/mod.rs create mode 100644 packages/kos/src/chains/constants.rs create mode 100644 packages/kos/src/chains/default/mod.rs create mode 100644 packages/kos/src/chains/egld/mod.rs create mode 100644 packages/kos/src/chains/eth/mod.rs create mode 100644 packages/kos/src/chains/eth/models.rs create mode 100644 packages/kos/src/chains/icp/mod.rs create mode 100644 packages/kos/src/chains/klv/mod.rs create mode 100644 packages/kos/src/chains/klv/models.rs create mode 100644 packages/kos/src/chains/mod.rs create mode 100644 packages/kos/src/chains/movr/mod.rs create mode 100644 packages/kos/src/chains/sol/mod.rs create mode 100644 packages/kos/src/chains/substrate/mod.rs create mode 100644 packages/kos/src/chains/substrate/models.rs create mode 100644 packages/kos/src/chains/sui/mod.rs create mode 100644 packages/kos/src/chains/trx/mod.rs create mode 100644 packages/kos/src/chains/util.rs create mode 100644 packages/kos/src/chains/xrp/mod.rs create mode 100644 packages/kos/src/crypto/b58.rs create mode 100644 packages/kos/src/crypto/base64.rs create mode 100644 packages/kos/src/crypto/bignum.rs create mode 100644 packages/kos/src/crypto/bip32.rs create mode 100644 packages/kos/src/crypto/ed25519.rs create mode 100644 packages/kos/src/crypto/ed25519_bip32.rs create mode 100644 packages/kos/src/crypto/hash.rs create mode 100644 packages/kos/src/crypto/mnemonic.rs create mode 100644 packages/kos/src/crypto/mod.rs create mode 100644 packages/kos/src/crypto/pbkdf2.rs create mode 100644 packages/kos/src/crypto/rng.rs create mode 100644 packages/kos/src/crypto/secp256k1.rs create mode 100644 packages/kos/src/crypto/sr25519.rs create mode 100644 packages/kos/src/models.rs create mode 100644 packages/kos/src/protos/generated/klv/google.protobuf.rs create mode 100644 packages/kos/src/protos/generated/klv/mod.rs create mode 100644 packages/kos/src/protos/generated/klv/proto.rs create mode 100644 packages/kos/src/protos/generated/mod.rs create mode 100644 packages/kos/src/protos/generated/trx/google.protobuf.rs create mode 100644 packages/kos/src/protos/generated/trx/mod.rs create mode 100644 packages/kos/src/protos/generated/trx/protocol.rs rename packages/{kos-proto/proto => kos/src/protos}/klever/contracts.proto (97%) create mode 100644 packages/kos/src/protos/klever/transaction.proto create mode 100644 packages/kos/src/protos/klever/userAccountData.proto create mode 100644 packages/kos/src/protos/mod.rs create mode 100644 packages/kos/src/protos/tron/.gitignore create mode 100644 packages/kos/src/protos/tron/.travis.yml create mode 100644 packages/kos/src/protos/tron/Chinese version of TRON Protocol document.md create mode 100644 packages/kos/src/protos/tron/English version of TRON Protocol document.md create mode 100644 packages/kos/src/protos/tron/LICENSE create mode 100644 packages/kos/src/protos/tron/README.md create mode 100644 packages/kos/src/protos/tron/api/api.proto create mode 100644 packages/kos/src/protos/tron/api/zksnark.proto create mode 100644 packages/kos/src/protos/tron/core/Discover.proto create mode 100644 packages/kos/src/protos/tron/core/Tron.proto create mode 100644 packages/kos/src/protos/tron/core/TronInventoryItems.proto create mode 100644 packages/kos/src/protos/tron/core/contract/account_contract.proto create mode 100644 packages/kos/src/protos/tron/core/contract/asset_issue_contract.proto create mode 100644 packages/kos/src/protos/tron/core/contract/balance_contract.proto create mode 100644 packages/kos/src/protos/tron/core/contract/common.proto create mode 100644 packages/kos/src/protos/tron/core/contract/exchange_contract.proto create mode 100644 packages/kos/src/protos/tron/core/contract/market_contract.proto create mode 100644 packages/kos/src/protos/tron/core/contract/proposal_contract.proto create mode 100644 packages/kos/src/protos/tron/core/contract/shield_contract.proto create mode 100644 packages/kos/src/protos/tron/core/contract/smart_contract.proto create mode 100644 packages/kos/src/protos/tron/core/contract/storage_contract.proto create mode 100644 packages/kos/src/protos/tron/core/contract/vote_asset_contract.proto create mode 100644 packages/kos/src/protos/tron/core/contract/witness_contract.proto create mode 100644 packages/kos/src/protos/tron/core/tron/account.proto create mode 100644 packages/kos/src/protos/tron/core/tron/block.proto create mode 100644 packages/kos/src/protos/tron/core/tron/delegated_resource.proto create mode 100644 packages/kos/src/protos/tron/core/tron/p2p.proto create mode 100644 packages/kos/src/protos/tron/core/tron/proposal.proto create mode 100644 packages/kos/src/protos/tron/core/tron/transaction.proto create mode 100644 packages/kos/src/protos/tron/core/tron/vote.proto create mode 100644 packages/kos/src/protos/tron/core/tron/witness.proto create mode 100644 packages/kos/src/protos/tron/install-googleapis.sh create mode 100644 packages/kos/src/protos/tron/install-protobuf.sh diff --git a/.gitignore b/.gitignore index a8c2b32..eb75cc1 100644 --- a/.gitignore +++ b/.gitignore @@ -21,4 +21,8 @@ dist .DS_Store demo/.DS_Store packages/.DS_Store -.idea/* \ No newline at end of file +.idea/* + +packages/kos/target +packages/kos/Cargo.lock +packages/kos/.idea \ No newline at end of file diff --git a/.gitmodules b/.gitmodules index 2a7d142..13bf6f8 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ -[submodule "packages/kos-proto/proto/tron"] - path = packages/kos-proto/proto/tron +[submodule "packages/kos/protos/tron"] + path = packages/kos/protos/tron url = https://github.com/tronprotocol/protocol diff --git a/Cargo.lock b/Cargo.lock index 74406d6..3a244f7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,56 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "addr2line" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - -[[package]] -name = "aead" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" -dependencies = [ - "crypto-common", - "generic-array", -] - -[[package]] -name = "aes" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" -dependencies = [ - "cfg-if", - "cipher", - "cpufeatures", -] - -[[package]] -name = "aes-gcm" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" -dependencies = [ - "aead", - "aes", - "cipher", - "ctr", - "ghash", - "subtle", -] - [[package]] name = "aho-corasick" version = "1.1.3" @@ -97,7 +47,7 @@ version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" dependencies = [ - "windows-sys 0.52.0", + "windows-sys", ] [[package]] @@ -107,7 +57,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" dependencies = [ "anstyle", - "windows-sys 0.52.0", + "windows-sys", ] [[package]] @@ -116,6 +66,12 @@ version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + [[package]] name = "arrayvec" version = "0.7.4" @@ -163,70 +119,18 @@ dependencies = [ "nom", ] -[[package]] -name = "async-stream" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" -dependencies = [ - "async-stream-impl", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-stream-impl" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", -] - -[[package]] -name = "atomic-polyfill" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" -dependencies = [ - "critical-section", -] - [[package]] name = "autocfg" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" -[[package]] -name = "backtrace" -version = "0.3.72" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17c6a35df3749d2e8bb1b7b21a976d82b15548788d2735b9d82f329268f71a11" -dependencies = [ - "addr2line", - "cc", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", -] - [[package]] name = "base16ct" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" -[[package]] -name = "base58" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6107fe1be6682a68940da878d9e9f5e90ca5745b3dec9fd1bb393c8777d4f581" - [[package]] name = "base64" version = "0.13.1" @@ -239,12 +143,6 @@ version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" -[[package]] -name = "base64" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" - [[package]] name = "base64ct" version = "1.6.0" @@ -276,41 +174,14 @@ dependencies = [ ] [[package]] -name = "bitcoin" -version = "0.30.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1945a5048598e4189e239d3f809b19bdad4845c4b2ba400d304d2dcf26d2c462" -dependencies = [ - "bech32", - "bitcoin-private", - "bitcoin_hashes", - "hex_lit", - "secp256k1", - "serde", -] - -[[package]] -name = "bitcoin-private" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73290177011694f38ec25e165d0387ab7ea749a4b81cd4c80dae5988229f7a57" - -[[package]] -name = "bitcoin_hashes" -version = "0.12.0" +name = "bip39-dict" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d7066118b13d4b20b23645932dfb3a81ce7e29f95726c2036fa33cd7b092501" +checksum = "29f1d227703899f704884cb6dfe1dc6a1bd447ea9f91418539989618ebf01685" dependencies = [ - "bitcoin-private", - "serde", + "cryptoxide", ] -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - [[package]] name = "bitflags" version = "2.5.0" @@ -329,20 +200,26 @@ dependencies = [ "wyz", ] +[[package]] +name = "blake2b-ref" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "294d17c72e0ba59fad763caa112368d0672083779cdebbb97164f4bb4c1e339a" + [[package]] name = "block-buffer" -version = "0.10.4" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ "generic-array", ] [[package]] -name = "block-padding" -version = "0.3.3" +name = "block-buffer" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ "generic-array", ] @@ -353,28 +230,16 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" dependencies = [ - "sha2", + "sha2 0.10.8", "tinyvec", ] -[[package]] -name = "bumpalo" -version = "3.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" - [[package]] name = "byte-slice-cast" version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" -[[package]] -name = "bytemuck" -version = "1.17.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773d90827bc3feecfb67fab12e24de0749aad83c74b9504ecde46237b5cd24e2" - [[package]] name = "byteorder" version = "1.5.0" @@ -419,30 +284,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "cbc" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" -dependencies = [ - "cipher", -] - -[[package]] -name = "cc" -version = "1.0.98" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f" - -[[package]] -name = "cfb-mode" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "738b8d467867f80a71351933f70461f5b56f24d5c93e0cf216e59229c968d330" -dependencies = [ - "cipher", -] - [[package]] name = "cfg-if" version = "1.0.0" @@ -459,16 +300,6 @@ dependencies = [ "serde", ] -[[package]] -name = "cipher" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" -dependencies = [ - "crypto-common", - "inout", -] - [[package]] name = "clap" version = "4.5.16" @@ -509,12 +340,6 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" -[[package]] -name = "cobs" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" - [[package]] name = "coins-bip32" version = "0.8.7" @@ -523,11 +348,11 @@ checksum = "3b6be4a5df2098cd811f3194f64ddb96c267606bffd9689ac7b0160097b01ad3" dependencies = [ "bs58", "coins-core", - "digest", - "hmac", + "digest 0.10.7", + "hmac 0.12.1", "k256", "serde", - "sha2", + "sha2 0.10.8", "thiserror", ] @@ -539,11 +364,11 @@ checksum = "3db8fba409ce3dc04f7d804074039eb68b960b0829161f8e06c95fea3f122528" dependencies = [ "bitvec", "coins-bip32", - "hmac", + "hmac 0.12.1", "once_cell", "pbkdf2", "rand", - "sha2", + "sha2 0.10.8", "thiserror", ] @@ -556,67 +381,29 @@ dependencies = [ "base64 0.21.7", "bech32", "bs58", - "digest", + "digest 0.10.7", "generic-array", "hex", "ripemd", "serde", "serde_derive", - "sha2", + "sha2 0.10.8", "sha3", "thiserror", ] -[[package]] -name = "color_quant" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" - [[package]] name = "colorchoice" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" -[[package]] -name = "console_error_panic_hook" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" -dependencies = [ - "cfg-if", - "wasm-bindgen", -] - [[package]] name = "const-oid" version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" - -[[package]] -name = "core-foundation" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" - [[package]] name = "cpufeatures" version = "0.2.12" @@ -626,21 +413,6 @@ dependencies = [ "libc", ] -[[package]] -name = "crc32fast" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "critical-section" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216" - [[package]] name = "crunchy" version = "0.2.2" @@ -666,19 +438,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", - "rand_core", "typenum", ] [[package]] -name = "ctr" -version = "0.9.2" +name = "crypto-mac" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" dependencies = [ - "cipher", + "generic-array", + "subtle", ] +[[package]] +name = "cryptoxide" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "382ce8820a5bb815055d3553a610e8cb542b2d767bbacea99038afda96cd760d" + [[package]] name = "curve25519-dalek" version = "4.1.3" @@ -688,7 +466,7 @@ dependencies = [ "cfg-if", "cpufeatures", "curve25519-dalek-derive", - "digest", + "digest 0.10.7", "fiat-crypto", "rustc_version", "subtle", @@ -717,16 +495,12 @@ dependencies = [ ] [[package]] -name = "derive_more" -version = "0.99.17" +name = "digest" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "convert_case", - "proc-macro2", - "quote", - "rustc_version", - "syn 1.0.109", + "generic-array", ] [[package]] @@ -735,24 +509,12 @@ version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer", + "block-buffer 0.10.4", "const-oid", "crypto-common", "subtle", ] -[[package]] -name = "dotenv-build" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4547f16c17f6051a12cdb8c62b803f94bee6807c74aa7c530b30b737df981fc" - -[[package]] -name = "dotenvy" -version = "0.15.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" - [[package]] name = "ecdsa" version = "0.16.9" @@ -760,7 +522,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ "der", - "digest", + "digest 0.10.7", "elliptic-curve", "rfc6979", "signature", @@ -773,8 +535,6 @@ version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" dependencies = [ - "pkcs8", - "serde", "signature", ] @@ -786,10 +546,8 @@ checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" dependencies = [ "curve25519-dalek", "ed25519", - "serde", - "sha2", + "sha2 0.10.8", "subtle", - "zeroize", ] [[package]] @@ -806,7 +564,7 @@ checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ "base16ct", "crypto-bigint", - "digest", + "digest 0.10.7", "ff", "generic-array", "group", @@ -817,57 +575,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "embedded-io" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" - -[[package]] -name = "encoding_rs" -version = "0.8.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "enum_delegate" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8ea75f31022cba043afe037940d73684327e915f88f62478e778c3de914cd0a" -dependencies = [ - "enum_delegate_lib", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "enum_delegate_lib" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e1f6c3800b304a6be0012039e2a45a322a093539c45ab818d9e6895a39c90fe" -dependencies = [ - "proc-macro2", - "quote", - "rand", - "syn 1.0.109", -] - -[[package]] -name = "enum_dispatch" -version = "0.3.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa18ce2bc66555b3218614519ac839ddb759a7d6720732f979ef8d13be147ecd" -dependencies = [ - "once_cell", - "proc-macro2", - "quote", - "syn 2.0.66", -] - [[package]] name = "equivalent" version = "1.0.1" @@ -891,51 +598,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "ethabi" -version = "18.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7413c5f74cc903ea37386a8965a936cbeb334bd270862fdece542c1b2dcbc898" -dependencies = [ - "ethereum-types", - "hex", - "once_cell", - "regex", - "serde", - "serde_json", - "sha3", - "thiserror", - "uint", -] - -[[package]] -name = "ethbloom" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c22d4b5885b6aa2fe5e8b9329fb8d232bf739e434e6b87347c63bdd00c120f60" -dependencies = [ - "crunchy", - "fixed-hash", - "impl-rlp", - "impl-serde", - "tiny-keccak", -] - -[[package]] -name = "ethereum-types" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02d215cbf040552efcbe99a38372fe80ab9d00268e20012b79fcd0f073edd8ee" -dependencies = [ - "ethbloom", - "fixed-hash", - "impl-rlp", - "impl-serde", - "primitive-types", - "uint", + "windows-sys", ] [[package]] @@ -944,15 +607,6 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" -[[package]] -name = "fdeflate" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f9bfee30e4dedf0ab8b422f03af778d9612b63f502710fc500a334ebe2de645" -dependencies = [ - "simd-adler32", -] - [[package]] name = "ff" version = "0.13.0" @@ -969,64 +623,12 @@ version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" -[[package]] -name = "fixed-hash" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" -dependencies = [ - "byteorder", - "rand", - "rustc-hex", - "static_assertions", -] - [[package]] name = "fixedbitset" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" -[[package]] -name = "flate2" -version = "1.0.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - -[[package]] -name = "form_urlencoded" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" -dependencies = [ - "percent-encoding", -] - [[package]] name = "fs-err" version = "2.11.0" @@ -1042,105 +644,6 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" -[[package]] -name = "futures" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" - -[[package]] -name = "futures-executor" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" - -[[package]] -name = "futures-macro" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", -] - -[[package]] -name = "futures-sink" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" - -[[package]] -name = "futures-task" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" - -[[package]] -name = "futures-timer" -version = "3.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" -dependencies = [ - "gloo-timers", - "send_wrapper", -] - -[[package]] -name = "futures-util" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - [[package]] name = "generic-array" version = "0.14.7" @@ -1159,46 +662,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", - "js-sys", "libc", "wasi", - "wasm-bindgen", ] [[package]] -name = "ghash" -version = "0.5.1" +name = "getrandom_or_panic" +version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" +checksum = "6ea1015b5a70616b688dc230cfe50c8af89d972cb132d5a622814d29773b10b9" dependencies = [ - "opaque-debug", - "polyval", + "rand_core", ] -[[package]] -name = "gimli" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" - [[package]] name = "glob" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" -[[package]] -name = "gloo-timers" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" -dependencies = [ - "futures-channel", - "futures-core", - "js-sys", - "wasm-bindgen", -] - [[package]] name = "goblin" version = "0.8.2" @@ -1221,78 +703,12 @@ dependencies = [ "subtle", ] -[[package]] -name = "h2" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http 0.2.12", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "hash32" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" -dependencies = [ - "byteorder", -] - [[package]] name = "hashbrown" version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" -[[package]] -name = "headers" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" -dependencies = [ - "base64 0.21.7", - "bytes", - "headers-core", - "http 0.2.12", - "httpdate", - "mime", - "sha1", -] - -[[package]] -name = "headers-core" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" -dependencies = [ - "http 0.2.12", -] - -[[package]] -name = "heapless" -version = "0.7.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" -dependencies = [ - "atomic-polyfill", - "hash32", - "rustc_version", - "serde", - "spin", - "stable_deref_trait", -] - [[package]] name = "heck" version = "0.4.1" @@ -1305,270 +721,40 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" -[[package]] -name = "hermit-abi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - [[package]] name = "hex" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -[[package]] -name = "hex_lit" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3011d1213f159867b13cfd6ac92d2cd5f1345762c63be3554e84092d85a50bbd" - [[package]] name = "hmac" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" -dependencies = [ - "digest", -] - -[[package]] -name = "home" -version = "0.5.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" -dependencies = [ - "windows-sys 0.52.0", -] - -[[package]] -name = "html-escape" -version = "0.2.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d1ad449764d627e22bfd7cd5e8868264fc9236e07c752972b4080cd351cb476" -dependencies = [ - "utf8-width", -] - -[[package]] -name = "http" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" -dependencies = [ - "bytes", - "http 0.2.12", - "pin-project-lite", -] - -[[package]] -name = "http-body" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" -dependencies = [ - "bytes", - "http 1.1.0", -] - -[[package]] -name = "http-body-util" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" -dependencies = [ - "bytes", - "futures-core", - "http 1.1.0", - "http-body 1.0.0", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" - -[[package]] -name = "httpdate" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" - -[[package]] -name = "hyper" -version = "0.14.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f361cde2f109281a220d4307746cdfd5ee3f410da58a70377762396775634b33" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http 0.2.12", - "http-body 0.4.6", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", - "want", -] - -[[package]] -name = "hyper" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d" -dependencies = [ - "bytes", - "futures-channel", - "futures-util", - "http 1.1.0", - "http-body 1.0.0", - "httparse", - "itoa", - "pin-project-lite", - "smallvec", - "tokio", - "want", -] - -[[package]] -name = "hyper-rustls" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0bea761b46ae2b24eb4aef630d8d1c398157b6fc29e6350ecf090a0b70c952c" -dependencies = [ - "futures-util", - "http 1.1.0", - "hyper 1.3.1", - "hyper-util", - "rustls", - "rustls-pki-types", - "tokio", - "tokio-rustls", - "tower-service", -] - -[[package]] -name = "hyper-tls" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" -dependencies = [ - "bytes", - "hyper 0.14.29", - "native-tls", - "tokio", - "tokio-native-tls", -] - -[[package]] -name = "hyper-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b875924a60b96e5d7b9ae7b066540b1dd1cbd90d1828f54c92e02a283351c56" -dependencies = [ - "bytes", - "futures-channel", - "futures-util", - "http 1.1.0", - "http-body 1.0.0", - "hyper 1.3.1", - "pin-project-lite", - "socket2", - "tokio", - "tower", - "tower-service", - "tracing", -] - -[[package]] -name = "idna" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "idna" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "image" -version = "0.24.9" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d" +checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" dependencies = [ - "bytemuck", - "byteorder", - "color_quant", - "num-traits", - "png", + "crypto-mac", + "digest 0.9.0", ] [[package]] -name = "impl-codec" -version = "0.6.0" +name = "hmac" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "parity-scale-codec", + "digest 0.10.7", ] [[package]] -name = "impl-rlp" +name = "hmac-drbg" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28220f89297a075ddc7245cd538076ee98b01f2a9c23a53a4f1105d5a322808" -dependencies = [ - "rlp", -] - -[[package]] -name = "impl-serde" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc88fc67028ae3db0c853baa36269d398d5f45b6982f95549ff5def78c935cd" +checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1" dependencies = [ - "serde", + "digest 0.9.0", + "generic-array", + "hmac 0.8.1", ] [[package]] @@ -1592,43 +778,18 @@ dependencies = [ "hashbrown", ] -[[package]] -name = "inout" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" -dependencies = [ - "block-padding", - "generic-array", -] - [[package]] name = "inventory" version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f958d3d68f4167080a18141e10381e7634563984a537f2a49a30fd8e53ac5767" -[[package]] -name = "ipnet" -version = "2.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" - [[package]] name = "is_terminal_polyfill" version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - [[package]] name = "itertools" version = "0.12.1" @@ -1644,41 +805,17 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" -[[package]] -name = "js-sys" -version = "0.3.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "jsonrpc-core" -version = "18.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14f7f76aef2d054868398427f6c54943cf3d1caa9a7ec7d0c38d69df97a965eb" -dependencies = [ - "futures", - "futures-executor", - "futures-util", - "log", - "serde", - "serde_derive", - "serde_json", -] - [[package]] name = "k256" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" +checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" dependencies = [ "cfg-if", "ecdsa", "elliptic-curve", "once_cell", - "sha2", + "sha2 0.10.8", "signature", ] @@ -1695,154 +832,50 @@ dependencies = [ name = "kos" version = "0.1.2" dependencies = [ - "console_error_panic_hook", - "futures", - "hex", - "js-sys", - "kos-crypto", - "kos-sdk", - "kos-types", - "kos-utils", - "log", - "qrcode-generator", - "wasm-bindgen", - "wasm-bindgen-test", - "web-sys", -] - -[[package]] -name = "kos-crypto" -version = "0.1.2" -dependencies = [ - "aes", - "aes-gcm", - "base64 0.21.7", - "cbc", - "cfb-mode", - "coins-bip32", + "bech32", + "bip39-dict", + "blake2b-ref", "coins-bip39", "ed25519-dalek", + "heck 0.4.1", "hex", - "hmac", - "kos-types", - "log", + "hmac 0.12.1", + "libsecp256k1", + "parity-scale-codec", "pbkdf2", - "pem", - "rand", - "secp256k1", - "serde", - "sha1", - "sha2", - "sha3", - "wasm-bindgen", - "zeroize", -] - -[[package]] -name = "kos-mobile" -version = "0.1.2" -dependencies = [ - "hex", - "kos-crypto", - "kos-proto", - "kos-sdk", - "kos-types", - "kos-utils", - "lazy_static", - "thiserror", - "uniffi", -] - -[[package]] -name = "kos-proto" -version = "0.1.2" -dependencies = [ - "bytes", - "glob", - "heck 0.4.1", - "kos-types", - "pbjson", - "pbjson-build", - "pbjson-types", - "prost 0.11.9", - "prost-build 0.12.6", - "prost-types 0.11.9", + "prost", + "prost-build", + "prost-types", "prost-wkt", "prost-wkt-build", "prost-wkt-types", "quote", - "serde", - "serde_json", - "wasm-bindgen", -] - -[[package]] -name = "kos-sdk" -version = "0.1.2" -dependencies = [ - "base58", - "bech32", - "bitcoin", - "coins-bip39", - "dotenv-build", - "dotenvy", - "enum_delegate", - "enum_dispatch", - "hex", - "hmac", - "kos-crypto", - "kos-proto", - "kos-types", - "kos-utils", - "lazy_static", - "log", - "pbjson", - "pbjson-types", - "pem", - "prost 0.11.9", "rand", - "reqwest 0.12.4", + "rand_core", + "ripemd", "rlp", - "secp256k1", - "serde", - "serde-wasm-bindgen", - "serde_json", - "strum", - "tokio-test", - "wasm-bindgen", - "wasm-bindgen-futures", - "web3", + "schnorrkel", + "sha2 0.10.8", + "sha3", + "tiny-json-rs", ] [[package]] -name = "kos-types" +name = "kos-mobile" version = "0.1.2" dependencies = [ - "coins-bip32", - "coins-bip39", - "ed25519-dalek", "hex", - "log", - "num-bigint", - "num-traits", - "rand", - "reqwest 0.12.4", - "secp256k1", - "serde", - "serde_json", - "wasm-bindgen", + "kos", + "lazy_static", + "thiserror", + "uniffi", ] [[package]] -name = "kos-utils" +name = "kos-web" version = "0.1.2" dependencies = [ - "kos-types", - "log", - "postcard", - "serde", - "wasm-bindgen", - "web-sys", + "kos", ] [[package]] @@ -1858,21 +891,59 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] -name = "linux-raw-sys" -version = "0.4.14" +name = "libsecp256k1" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +checksum = "95b09eff1b35ed3b33b877ced3a691fc7a481919c7e29c53c906226fcf55e2a1" +dependencies = [ + "arrayref", + "base64 0.13.1", + "digest 0.9.0", + "hmac-drbg", + "libsecp256k1-core", + "libsecp256k1-gen-ecmult", + "libsecp256k1-gen-genmult", + "rand", + "serde", + "sha2 0.9.9", + "typenum", +] [[package]] -name = "lock_api" -version = "0.4.12" +name = "libsecp256k1-core" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +checksum = "5be9b9bb642d8522a44d533eab56c16c738301965504753b03ad1de3425d5451" dependencies = [ - "autocfg", - "scopeguard", + "crunchy", + "digest 0.9.0", + "subtle", ] +[[package]] +name = "libsecp256k1-gen-ecmult" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3038c808c55c87e8a172643a7d87187fc6c4174468159cb3090659d55bcb4809" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "libsecp256k1-gen-genmult" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3db8d6ba2cec9eacc40e6e8ccc98931840301f1006e95647ceb2dd5c3aa06f7c" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + [[package]] name = "log" version = "0.4.21" @@ -1885,6 +956,18 @@ version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" +[[package]] +name = "merlin" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58c38e2799fc0978b65dfff8023ec7843e2330bb462f19198840b34b6582397d" +dependencies = [ + "byteorder", + "keccak", + "rand_core", + "zeroize", +] + [[package]] name = "mime" version = "0.3.17" @@ -1907,56 +990,12 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" -[[package]] -name = "miniz_oxide" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" -dependencies = [ - "adler", - "simd-adler32", -] - -[[package]] -name = "mio" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" -dependencies = [ - "libc", - "wasi", - "windows-sys 0.48.0", -] - -[[package]] -name = "multimap" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" - [[package]] name = "multimap" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03" -[[package]] -name = "native-tls" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" -dependencies = [ - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - [[package]] name = "nom" version = "7.1.3" @@ -1967,25 +1006,6 @@ dependencies = [ "minimal-lexical", ] -[[package]] -name = "num-bigint" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" -dependencies = [ - "num-integer", - "num-traits", -] - -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits", -] - [[package]] name = "num-traits" version = "0.2.19" @@ -1995,25 +1015,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "object" -version = "0.35.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8ec7ab813848ba4522158d5517a6093db1ded27575b070f4177b8d12b41db5e" -dependencies = [ - "memchr", -] - [[package]] name = "once_cell" version = "1.19.0" @@ -2026,50 +1027,6 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" -[[package]] -name = "openssl" -version = "0.10.66" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" -dependencies = [ - "bitflags 2.5.0", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", -] - -[[package]] -name = "openssl-probe" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" - -[[package]] -name = "openssl-sys" -version = "0.9.103" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - [[package]] name = "parity-scale-codec" version = "3.6.12" @@ -2077,11 +1034,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" dependencies = [ "arrayvec", - "bitvec", "byte-slice-cast", "impl-trait-for-tuples", "parity-scale-codec-derive", - "serde", ] [[package]] @@ -2096,29 +1051,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "parking_lot" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-targets 0.52.5", -] - [[package]] name = "password-hash" version = "0.5.0" @@ -2136,69 +1068,18 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" -[[package]] -name = "pbjson" -version = "0.5.1" -source = "git+https://github.com/klever-io/pbjson#e0e9f4e558c53ef6611ddcabce28d49c1b47629d" -dependencies = [ - "base64 0.13.1", - "hex", - "serde", -] - -[[package]] -name = "pbjson-build" -version = "0.5.1" -source = "git+https://github.com/klever-io/pbjson#e0e9f4e558c53ef6611ddcabce28d49c1b47629d" -dependencies = [ - "heck 0.4.1", - "itertools 0.10.5", - "prost 0.11.9", - "prost-types 0.11.9", -] - -[[package]] -name = "pbjson-types" -version = "0.5.1" -source = "git+https://github.com/klever-io/pbjson#e0e9f4e558c53ef6611ddcabce28d49c1b47629d" -dependencies = [ - "bytes", - "chrono", - "pbjson", - "pbjson-build", - "prost 0.11.9", - "prost-build 0.11.9", - "serde", -] - [[package]] name = "pbkdf2" version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" dependencies = [ - "digest", - "hmac", + "digest 0.10.7", + "hmac 0.12.1", "password-hash", - "sha2", -] - -[[package]] -name = "pem" -version = "3.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658fae" -dependencies = [ - "base64 0.22.1", - "serde", + "sha2 0.10.8", ] -[[package]] -name = "percent-encoding" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" - [[package]] name = "petgraph" version = "0.6.5" @@ -2209,38 +1090,6 @@ dependencies = [ "indexmap", ] -[[package]] -name = "pin-project" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - [[package]] name = "pkcs8" version = "0.10.2" @@ -2251,69 +1100,19 @@ dependencies = [ "spki", ] -[[package]] -name = "pkg-config" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" - [[package]] name = "plain" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" -[[package]] -name = "png" -version = "0.17.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06e4b0d3d1312775e782c86c91a111aa1f910cbb65e1337f9975b5f9a554b5e1" -dependencies = [ - "bitflags 1.3.2", - "crc32fast", - "fdeflate", - "flate2", - "miniz_oxide", -] - -[[package]] -name = "polyval" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" -dependencies = [ - "cfg-if", - "cpufeatures", - "opaque-debug", - "universal-hash", -] - -[[package]] -name = "postcard" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a55c51ee6c0db07e68448e336cf8ea4131a620edefebf9893e759b2d793420f8" -dependencies = [ - "cobs", - "embedded-io", - "heapless", - "serde", -] - [[package]] name = "ppv-lite86" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" - -[[package]] -name = "prettyplease" -version = "0.1.25" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" dependencies = [ - "proc-macro2", - "syn 1.0.109", + "zerocopy", ] [[package]] @@ -2326,19 +1125,6 @@ dependencies = [ "syn 2.0.66", ] -[[package]] -name = "primitive-types" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" -dependencies = [ - "fixed-hash", - "impl-codec", - "impl-rlp", - "impl-serde", - "uint", -] - [[package]] name = "proc-macro-crate" version = "3.1.0" @@ -2357,16 +1143,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "prost" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" -dependencies = [ - "bytes", - "prost-derive 0.11.9", -] - [[package]] name = "prost" version = "0.12.6" @@ -2374,29 +1150,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29" dependencies = [ "bytes", - "prost-derive 0.12.6", -] - -[[package]] -name = "prost-build" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270" -dependencies = [ - "bytes", - "heck 0.4.1", - "itertools 0.10.5", - "lazy_static", - "log", - "multimap 0.8.3", - "petgraph", - "prettyplease 0.1.25", - "prost 0.11.9", - "prost-types 0.11.9", - "regex", - "syn 1.0.109", - "tempfile", - "which", + "prost-derive", ] [[package]] @@ -2407,30 +1161,17 @@ checksum = "22505a5c94da8e3b7c2996394d1c933236c4d743e81a410bcca4e6989fc066a4" dependencies = [ "bytes", "heck 0.5.0", - "itertools 0.12.1", + "itertools", "log", - "multimap 0.10.0", + "multimap", "once_cell", "petgraph", - "prettyplease 0.2.20", - "prost 0.12.6", - "prost-types 0.12.6", + "prettyplease", + "prost", + "prost-types", "regex", - "syn 2.0.66", - "tempfile", -] - -[[package]] -name = "prost-derive" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" -dependencies = [ - "anyhow", - "itertools 0.10.5", - "proc-macro2", - "quote", - "syn 1.0.109", + "syn 2.0.66", + "tempfile", ] [[package]] @@ -2440,39 +1181,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1" dependencies = [ "anyhow", - "itertools 0.12.1", + "itertools", "proc-macro2", "quote", "syn 2.0.66", ] -[[package]] -name = "prost-types" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" -dependencies = [ - "prost 0.11.9", -] - [[package]] name = "prost-types" version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9091c90b0a32608e984ff2fa4091273cbdd755d54935c51d520887f4a1dbd5b0" dependencies = [ - "prost 0.12.6", + "prost", ] [[package]] name = "prost-wkt" -version = "0.4.2" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "562788060bcf2bfabe055194bd991ed2442457661744c88e0a0828ff9a08c08b" +checksum = "5fb7ec2850c138ebaa7ab682503b5d08c3cb330343e9c94776612928b6ddb53f" dependencies = [ "chrono", "inventory", - "prost 0.11.9", + "prost", "serde", "serde_derive", "serde_json", @@ -2481,27 +1213,27 @@ dependencies = [ [[package]] name = "prost-wkt-build" -version = "0.4.2" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4dca8bcead3b728a6a7da017cc95e7f4cb2320ec4f6896bc593a1c4700f7328" +checksum = "598b7365952c2ed4e32902de0533653aafbe5ae3da436e8e2335c7d375a1cef3" dependencies = [ - "heck 0.4.1", - "prost 0.11.9", - "prost-build 0.11.9", - "prost-types 0.11.9", + "heck 0.5.0", + "prost", + "prost-build", + "prost-types", "quote", ] [[package]] name = "prost-wkt-types" -version = "0.4.2" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2377c5680f2342871823045052e791b4487f7c90aae17e0feaee24cf59578a34" +checksum = "1a8eadc2381640a49c1fbfb9f4a857794b4e5bf5a2cbc2d858cfdb74f64dcd22" dependencies = [ "chrono", - "prost 0.11.9", - "prost-build 0.11.9", - "prost-types 0.11.9", + "prost", + "prost-build", + "prost-types", "prost-wkt", "prost-wkt-build", "regex", @@ -2510,23 +1242,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "qrcode-generator" -version = "4.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d06cb9646c7a14096231a2474d7f21e5e8c13de090c68d13bde6157cfe7f159" -dependencies = [ - "html-escape", - "image", - "qrcodegen", -] - -[[package]] -name = "qrcodegen" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4339fc7a1021c9c1621d87f5e3505f2805c8c105420ba2f2a4df86814590c142" - [[package]] name = "quote" version = "1.0.36" @@ -2572,15 +1287,6 @@ dependencies = [ "getrandom", ] -[[package]] -name = "redox_syscall" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" -dependencies = [ - "bitflags 2.5.0", -] - [[package]] name = "regex" version = "1.10.4" @@ -2610,120 +1316,23 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" -[[package]] -name = "reqwest" -version = "0.11.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" -dependencies = [ - "base64 0.21.7", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", - "h2", - "http 0.2.12", - "http-body 0.4.6", - "hyper 0.14.29", - "hyper-tls", - "ipnet", - "js-sys", - "log", - "mime", - "native-tls", - "once_cell", - "percent-encoding", - "pin-project-lite", - "rustls-pemfile 1.0.4", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper", - "system-configuration", - "tokio", - "tokio-native-tls", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "winreg 0.50.0", -] - -[[package]] -name = "reqwest" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10" -dependencies = [ - "base64 0.22.1", - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "http 1.1.0", - "http-body 1.0.0", - "http-body-util", - "hyper 1.3.1", - "hyper-rustls", - "hyper-util", - "ipnet", - "js-sys", - "log", - "mime", - "once_cell", - "percent-encoding", - "pin-project-lite", - "rustls", - "rustls-pemfile 2.1.2", - "rustls-pki-types", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper", - "tokio", - "tokio-rustls", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "webpki-roots", - "winreg 0.52.0", -] - [[package]] name = "rfc6979" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ - "hmac", + "hmac 0.12.1", "subtle", ] -[[package]] -name = "ring" -version = "0.17.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" -dependencies = [ - "cc", - "cfg-if", - "getrandom", - "libc", - "spin", - "untrusted", - "windows-sys 0.52.0", -] - [[package]] name = "ripemd" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" dependencies = [ - "digest", + "digest 0.10.7", ] [[package]] @@ -2736,12 +1345,6 @@ dependencies = [ "rustc-hex", ] -[[package]] -name = "rustc-demangle" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" - [[package]] name = "rustc-hex" version = "2.1.0" @@ -2763,69 +1366,13 @@ version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags 2.5.0", + "bitflags", "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", -] - -[[package]] -name = "rustls" -version = "0.22.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" -dependencies = [ - "log", - "ring", - "rustls-pki-types", - "rustls-webpki", - "subtle", - "zeroize", -] - -[[package]] -name = "rustls-pemfile" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" -dependencies = [ - "base64 0.21.7", -] - -[[package]] -name = "rustls-pemfile" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" -dependencies = [ - "base64 0.22.1", - "rustls-pki-types", -] - -[[package]] -name = "rustls-pki-types" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" - -[[package]] -name = "rustls-webpki" -version = "0.102.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e" -dependencies = [ - "ring", - "rustls-pki-types", - "untrusted", + "windows-sys", ] -[[package]] -name = "rustversion" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" - [[package]] name = "ryu" version = "1.0.18" @@ -2833,26 +1380,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] -name = "schannel" -version = "0.1.23" +name = "schnorrkel" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +checksum = "8de18f6d8ba0aad7045f5feae07ec29899c1112584a38509a84ad7b04451eaa0" dependencies = [ - "windows-sys 0.52.0", + "arrayref", + "arrayvec", + "curve25519-dalek", + "getrandom_or_panic", + "merlin", + "rand_core", + "sha2 0.10.8", + "subtle", + "zeroize", ] -[[package]] -name = "scoped-tls" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - [[package]] name = "scroll" version = "0.12.0" @@ -2887,50 +1430,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "secp256k1" -version = "0.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25996b82292a7a57ed3508f052cfff8640d38d32018784acd714758b43da9c8f" -dependencies = [ - "bitcoin_hashes", - "rand", - "secp256k1-sys", - "serde", -] - -[[package]] -name = "secp256k1-sys" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70a129b9e9efbfb223753b9163c4ab3b13cff7fd9c7f010fbac25ab4099fa07e" -dependencies = [ - "cc", -] - -[[package]] -name = "security-framework" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" -dependencies = [ - "bitflags 2.5.0", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "semver" version = "1.0.23" @@ -2940,12 +1439,6 @@ dependencies = [ "serde", ] -[[package]] -name = "send_wrapper" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" - [[package]] name = "serde" version = "1.0.203" @@ -2955,17 +1448,6 @@ dependencies = [ "serde_derive", ] -[[package]] -name = "serde-wasm-bindgen" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3b143e2833c57ab9ad3ea280d21fd34e285a42837aeb0ee301f4f41890fa00e" -dependencies = [ - "js-sys", - "serde", - "wasm-bindgen", -] - [[package]] name = "serde_derive" version = "1.0.203" @@ -2989,26 +1471,16 @@ dependencies = [ ] [[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "sha1" -version = "0.10.6" +name = "sha2" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" dependencies = [ + "block-buffer 0.9.0", "cfg-if", "cpufeatures", - "digest", + "digest 0.9.0", + "opaque-debug", ] [[package]] @@ -3019,7 +1491,7 @@ checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", - "digest", + "digest 0.10.7", ] [[package]] @@ -3028,7 +1500,7 @@ version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" dependencies = [ - "digest", + "digest 0.10.7", "keccak", ] @@ -3038,62 +1510,22 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ - "digest", + "digest 0.10.7", "rand_core", ] -[[package]] -name = "simd-adler32" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" - [[package]] name = "siphasher" version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" -[[package]] -name = "slab" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] - -[[package]] -name = "smallvec" -version = "1.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" - [[package]] name = "smawk" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" -[[package]] -name = "socket2" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" -dependencies = [ - "lock_api", -] - [[package]] name = "spki" version = "0.7.3" @@ -3104,12 +1536,6 @@ dependencies = [ "der", ] -[[package]] -name = "stable_deref_trait" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" - [[package]] name = "static_assertions" version = "1.1.0" @@ -3122,28 +1548,6 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" -[[package]] -name = "strum" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" -dependencies = [ - "strum_macros", -] - -[[package]] -name = "strum_macros" -version = "0.25.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" -dependencies = [ - "heck 0.4.1", - "proc-macro2", - "quote", - "rustversion", - "syn 2.0.66", -] - [[package]] name = "subtle" version = "2.5.0" @@ -3172,33 +1576,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "sync_wrapper" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" - -[[package]] -name = "system-configuration" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "system-configuration-sys", -] - -[[package]] -name = "system-configuration-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "tap" version = "1.0.1" @@ -3214,135 +1591,72 @@ dependencies = [ "cfg-if", "fastrand", "rustix", - "windows-sys 0.52.0", -] - -[[package]] -name = "textwrap" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" -dependencies = [ - "smawk", -] - -[[package]] -name = "thiserror" -version = "1.0.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", -] - -[[package]] -name = "tiny-keccak" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" -dependencies = [ - "crunchy", -] - -[[package]] -name = "tinyvec" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" -dependencies = [ - "tinyvec_macros", + "windows-sys", ] [[package]] -name = "tinyvec_macros" -version = "0.1.1" +name = "textwrap" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" +dependencies = [ + "smawk", +] [[package]] -name = "tokio" -version = "1.38.0" +name = "thiserror" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" dependencies = [ - "backtrace", - "bytes", - "libc", - "mio", - "num_cpus", - "pin-project-lite", - "socket2", - "windows-sys 0.48.0", + "thiserror-impl", ] [[package]] -name = "tokio-native-tls" -version = "0.3.1" +name = "thiserror-impl" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ - "native-tls", - "tokio", + "proc-macro2", + "quote", + "syn 2.0.66", ] [[package]] -name = "tokio-rustls" -version = "0.25.0" +name = "tiny-json-rs" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" +checksum = "922df6879c950dd96850b09e28fa4e7006c28770844eec77a8ee56a759b41f31" dependencies = [ - "rustls", - "rustls-pki-types", - "tokio", + "tiny_json_derive", ] [[package]] -name = "tokio-stream" -version = "0.1.15" +name = "tiny_json_derive" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" +checksum = "2356490d7043f9ddf974a16550e75868d900f2382d83088db0ec9b917dbaca9e" dependencies = [ - "futures-core", - "pin-project-lite", - "tokio", + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] -name = "tokio-test" -version = "0.4.4" +name = "tinyvec" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2468baabc3311435b55dd935f702f42cd1b8abb7e754fb7dfb16bd36aa88f9f7" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ - "async-stream", - "bytes", - "futures-core", - "tokio", - "tokio-stream", + "tinyvec_macros", ] [[package]] -name = "tokio-util" -version = "0.7.11" +name = "tinyvec_macros" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", -] +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "toml" @@ -3370,58 +1684,6 @@ dependencies = [ "winnow", ] -[[package]] -name = "tower" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" -dependencies = [ - "futures-core", - "futures-util", - "pin-project", - "pin-project-lite", - "tokio", - "tower-layer", - "tower-service", -] - -[[package]] -name = "tower-layer" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" - -[[package]] -name = "tower-service" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" - -[[package]] -name = "tracing" -version = "0.1.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" -dependencies = [ - "pin-project-lite", - "tracing-core", -] - -[[package]] -name = "tracing-core" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" -dependencies = [ - "once_cell", -] - -[[package]] -name = "try-lock" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" - [[package]] name = "typeid" version = "1.0.0" @@ -3458,18 +1720,6 @@ dependencies = [ "syn 2.0.66", ] -[[package]] -name = "uint" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" -dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", -] - [[package]] name = "unicase" version = "2.7.0" @@ -3479,27 +1729,12 @@ dependencies = [ "version_check", ] -[[package]] -name = "unicode-bidi" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" - [[package]] name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" -[[package]] -name = "unicode-normalization" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" -dependencies = [ - "tinyvec", -] - [[package]] name = "uniffi" version = "0.28.1" @@ -3631,217 +1866,24 @@ dependencies = [ "weedle2", ] -[[package]] -name = "universal-hash" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" -dependencies = [ - "crypto-common", - "subtle", -] - -[[package]] -name = "untrusted" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - -[[package]] -name = "url" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" -dependencies = [ - "form_urlencoded", - "idna 0.5.0", - "percent-encoding", -] - -[[package]] -name = "utf8-width" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3" - [[package]] name = "utf8parse" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - [[package]] name = "version_check" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" -[[package]] -name = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" -[[package]] -name = "wasm-bindgen" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn 2.0.66", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" - -[[package]] -name = "wasm-bindgen-test" -version = "0.3.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9bf62a58e0780af3e852044583deee40983e5886da43a271dd772379987667b" -dependencies = [ - "console_error_panic_hook", - "js-sys", - "scoped-tls", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-bindgen-test-macro", -] - -[[package]] -name = "wasm-bindgen-test-macro" -version = "0.3.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7f89739351a2e03cb94beb799d47fb2cac01759b40ec441f7de39b00cbf7ef0" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", -] - -[[package]] -name = "web-sys" -version = "0.3.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "web3" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5388522c899d1e1c96a4c307e3797e0f697ba7c77dd8e0e625ecba9dd0342937" -dependencies = [ - "arrayvec", - "base64 0.21.7", - "bytes", - "derive_more", - "ethabi", - "ethereum-types", - "futures", - "futures-timer", - "getrandom", - "headers", - "hex", - "idna 0.4.0", - "js-sys", - "jsonrpc-core", - "log", - "parking_lot", - "pin-project", - "rand", - "reqwest 0.11.27", - "rlp", - "serde", - "serde-wasm-bindgen", - "serde_json", - "tiny-keccak", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", -] - -[[package]] -name = "webpki-roots" -version = "0.26.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3de34ae270483955a94f4b21bdaaeb83d508bb84a01435f393818edb0012009" -dependencies = [ - "rustls-pki-types", -] - [[package]] name = "weedle2" version = "5.0.0" @@ -3851,49 +1893,13 @@ dependencies = [ "nom", ] -[[package]] -name = "which" -version = "4.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" -dependencies = [ - "either", - "home", - "once_cell", - "rustix", -] - -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - [[package]] name = "windows-sys" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.5", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", + "windows-targets", ] [[package]] @@ -3902,46 +1908,28 @@ version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" dependencies = [ - "windows_aarch64_gnullvm 0.52.5", - "windows_aarch64_msvc 0.52.5", - "windows_i686_gnu 0.52.5", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.5", - "windows_x86_64_gnu 0.52.5", - "windows_x86_64_gnullvm 0.52.5", - "windows_x86_64_msvc 0.52.5", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - [[package]] name = "windows_aarch64_msvc" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - [[package]] name = "windows_i686_gnu" version = "0.52.5" @@ -3954,48 +1942,24 @@ version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - [[package]] name = "windows_i686_msvc" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - [[package]] name = "windows_x86_64_gnu" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - [[package]] name = "windows_x86_64_msvc" version = "0.52.5" @@ -4012,32 +1976,33 @@ dependencies = [ ] [[package]] -name = "winreg" -version = "0.50.0" +name = "wyz" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" dependencies = [ - "cfg-if", - "windows-sys 0.48.0", + "tap", ] [[package]] -name = "winreg" -version = "0.52.0" +name = "zerocopy" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ - "cfg-if", - "windows-sys 0.48.0", + "byteorder", + "zerocopy-derive", ] [[package]] -name = "wyz" -version = "0.5.1" +name = "zerocopy-derive" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ - "tap", + "proc-macro2", + "quote", + "syn 2.0.66", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 7f44c83..49fc44a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,11 +2,8 @@ # https://doc.rust-lang.org/edition-guide/rust-2021/default-cargo-resolver.html#details resolver = "2" members = [ - "packages/kos-types", "packages/kos", - "packages/kos-crypto", - "packages/kos-sdk", - "packages/kos-mobile", + "packages/kos-mobile", "packages/kos-web", ] # This makes the compiled code faster and smaller, but it makes compiling slower, # so it's only enabled in release mode. @@ -42,7 +39,7 @@ pbjson = { version = "0.5", git = "https://github.com/klever-io/pbjson" } pbjson-types = { version = "0.5", git = "https://github.com/klever-io/pbjson" } pbjson-build = { version = "0.5", git = "https://github.com/klever-io/pbjson" } -uniffi = { version = "0.28.1"} +uniffi = { version = "0.28.1" } reqwest = { version = "0.12", default-features = false, feature = ["rustls-tls", "blocking", "json"] } wasm-bindgen = "0.2" @@ -54,8 +51,4 @@ log = "0.4" lazy_static = "1.4.0" thiserror = "1.0" -kos-types = { version = "0.1.0", path = "./packages/kos-types", default-features = false } -kos-crypto = { version = "0.1.0", path = "./packages/kos-crypto", default-features = false } -kos-sdk = { version = "0.1.0", path = "./packages/kos-sdk", default-features = false } -kos-utils = { version = "0.1.0", path = "./packages/kos-utils", default-features = false } -kos-proto = { version = "0.1.0", path = "./packages/kos-proto", default-features = false } \ No newline at end of file +kos = { version = "0.1.0", path = "./packages/kos", default-features = false } diff --git a/packages/kos-crypto/Cargo.toml b/packages/kos-crypto/Cargo.toml deleted file mode 100644 index 5ab1a3a..0000000 --- a/packages/kos-crypto/Cargo.toml +++ /dev/null @@ -1,33 +0,0 @@ -[package] -name = "kos-crypto" -version = { workspace = true } -authors = { workspace = true } -edition = { workspace = true } -homepage = { workspace = true } -license = { workspace = true } -repository = { workspace = true } -rust-version = { workspace = true } - -[dependencies] -kos-types = { workspace = true, features = ["serde"] } -serde = { workspace = true, features = ["derive"] } -log = { workspace = true } -wasm-bindgen = { workspace = true } -rand = { workspace = true } -zeroize = { workspace = true } -coins-bip32 = { workspace = true } -coins-bip39 = { workspace = true } -hex = { workspace = true } -sha1 = "0.10" -sha2 = { workspace = true } -sha3 = { workspace = true } -hmac = { workspace = true } -secp256k1 = { workspace = true, features = ["rand", "serde", "bitcoin_hashes"] } -ed25519-dalek = { workspace = true, features = ["serde"] } -aes-gcm = "0.10" -aes = { version = "0.8" } -cfb-mode = "0.8" -cbc = { version = "0.1", features = ["block-padding", "std"] } -pem = "3" -pbkdf2 = { version = "0.12", features = ["simple"] } -base64 = "0.21" diff --git a/packages/kos-crypto/src/blake2b.rs b/packages/kos-crypto/src/blake2b.rs deleted file mode 100644 index 2bdbbe8..0000000 --- a/packages/kos-crypto/src/blake2b.rs +++ /dev/null @@ -1,218 +0,0 @@ -pub const BLOCK_BYTES: usize = 128; -pub const KEY_BYTES: usize = 64; -pub const OUT_BYTES: usize = 64; - -#[rustfmt::skip] -static IV : [u64; 8] = [ - 0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1, - 0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179, -]; - -#[rustfmt::skip] -static SIGMA : [[u8; 16]; 12] = [ - [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ], - [ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 ], - [ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 ], - [ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 ], - [ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 ], - [ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 ], - [ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 ], - [ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 ], - [ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 ], - [ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 ], - [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ], - [ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 ], -]; - -pub struct Blake2b { - h: [u64; 8], - t: [u64; 2], - f: [u64; 2], - buf: [u8; 2 * BLOCK_BYTES], - buf_len: usize, - output_len: usize, -} - -impl Copy for Blake2b {} -impl Clone for Blake2b { - fn clone(&self) -> Blake2b { - *self - } -} - -impl Blake2b { - pub fn new(size: usize) -> Blake2b { - assert!(size > 0 && size <= OUT_BYTES); - - let param = encode_params(size as u8, 0); - let mut state = IV; - - for i in 0..state.len() { - state[i] ^= load64(¶m[i * 8..]); - } - - Blake2b { - h: state, - t: [0, 0], - f: [0, 0], - buf: [0u8; 2 * BLOCK_BYTES], - buf_len: 0, - output_len: size, - } - } - - pub fn new_with_key(size: usize, key: &[u8]) -> Blake2b { - assert!(size > 0 && size <= OUT_BYTES); - assert!(!key.is_empty() && key.len() <= KEY_BYTES); - - let param = encode_params(size as u8, key.len() as u8); - let mut state = IV; - - for i in 0..state.len() { - println!("i2: {} ", i); - state[i] ^= load64(¶m[i * 8..]); - } - - let mut b = Blake2b { - h: state, - t: [0, 0], - f: [0, 0], - buf: [0u8; 2 * BLOCK_BYTES], - buf_len: 0, - output_len: size, - }; - - let mut block = [0u8; BLOCK_BYTES]; - block[..key.len()].copy_from_slice(key); - b.update(block.as_ref()); - b - } - - pub fn update(&mut self, m: &[u8]) { - let mut m = m; - - while !m.is_empty() { - let left = self.buf_len; - let fill = 2 * BLOCK_BYTES - left; - - if m.len() > fill { - self.buf[left..(fill + left)].copy_from_slice(&m[..fill]); - self.buf_len += fill; - m = &m[fill..]; - self.increment_counter(BLOCK_BYTES as u64); - self.compress(); - for i in 0..BLOCK_BYTES { - self.buf[i] = self.buf[i + BLOCK_BYTES]; - } - self.buf_len -= BLOCK_BYTES; - } else { - self.buf[left..(m.len() + left)].copy_from_slice(m); - self.buf_len += m.len(); - m = &m[m.len()..]; - } - } - } - - pub fn finalize(&mut self) -> Vec { - let mut buf = [0u8; OUT_BYTES]; - if self.buf_len > BLOCK_BYTES { - self.increment_counter(BLOCK_BYTES as u64); - self.compress(); - for i in 0..BLOCK_BYTES { - self.buf[i] = self.buf[i + BLOCK_BYTES]; - } - self.buf_len -= BLOCK_BYTES; - } - let n = self.buf_len as u64; - self.increment_counter(n); - self.f[0] = !0; - for i in self.buf_len..self.buf.len() { - self.buf[i] = 0; - } - self.compress(); - for i in 0..self.h.len() { - store64(&mut buf[i * 8..], self.h[i]); - } - - buf[..self.output_len].to_vec() - } - - fn increment_counter(&mut self, inc: u64) { - self.t[0] += inc; - self.t[1] += if self.t[0] < inc { 1 } else { 0 }; - } - - fn compress(&mut self) { - let mut m = [0u64; 16]; - let mut v = [0u64; 16]; - let block = self.buf.as_ref(); - - assert!(block.len() >= BLOCK_BYTES); - - for i in 0..m.len() { - m[i] = load64(&block[i * 8..]); - } - - v[..8].copy_from_slice(&self.h[..8]); - - v[8] = IV[0]; - v[9] = IV[1]; - v[10] = IV[2]; - v[11] = IV[3]; - v[12] = self.t[0] ^ IV[4]; - v[13] = self.t[1] ^ IV[5]; - v[14] = self.f[0] ^ IV[6]; - v[15] = self.f[1] ^ IV[7]; - - macro_rules! g( - ($r: expr, $i: expr, $a: expr, $b: expr, $c: expr, $d: expr) => ({ - $a = $a.wrapping_add($b).wrapping_add(m[SIGMA[$r][2*$i+0] as usize]); - $d = ($d ^ $a).rotate_right(32); - $c = $c.wrapping_add($d); - $b = ($b ^ $c).rotate_right(24); - $a = $a.wrapping_add($b).wrapping_add(m[SIGMA[$r][2*$i+1] as usize]); - $d = ($d ^ $a).rotate_right(16); - $c = $c.wrapping_add($d); - $b = ($b ^ $c).rotate_right(63); - }); - ); - - macro_rules! round( - ($r: expr) => ({ - g!($r, 0, v[ 0], v[ 4], v[ 8], v[12]); - g!($r, 1, v[ 1], v[ 5], v[ 9], v[13]); - g!($r, 2, v[ 2], v[ 6], v[10], v[14]); - g!($r, 3, v[ 3], v[ 7], v[11], v[15]); - g!($r, 4, v[ 0], v[ 5], v[10], v[15]); - g!($r, 5, v[ 1], v[ 6], v[11], v[12]); - g!($r, 6, v[ 2], v[ 7], v[ 8], v[13]); - g!($r, 7, v[ 3], v[ 4], v[ 9], v[14]); - }); - ); - - for i in 0..12 { - round!(i); - } - - for i in 0..8 { - self.h[i] = self.h[i] ^ v[i] ^ v[i + 8] - } - } -} - -fn encode_params(size: u8, key_len: u8) -> [u8; 64] { - let mut param = [0u8; 64]; - param[0] = size; - param[1] = key_len; - param[2] = 1; // fanout - param[3] = 1; // depth - param -} - -fn load64(b: &[u8]) -> u64 { - u64::from_le_bytes(b[..8].try_into().expect("slice with incorrect length")) -} - -fn store64(b: &mut [u8], v: u64) { - b[..8].copy_from_slice(&v.to_le_bytes()); -} diff --git a/packages/kos-crypto/src/cipher.rs b/packages/kos-crypto/src/cipher.rs deleted file mode 100644 index b40f44e..0000000 --- a/packages/kos-crypto/src/cipher.rs +++ /dev/null @@ -1,355 +0,0 @@ -use base64::{engine::general_purpose as b64_engine, Engine}; -use kos_types::error::Error; - -use aes::cipher::{ - block_padding::Pkcs7, generic_array::GenericArray, AsyncStreamCipher, BlockDecryptMut, - BlockEncryptMut, KeyIvInit, -}; -use aes_gcm::{ - aead::{Aead, AeadCore, KeyInit as GCMKeyInit, OsRng}, - Aes256Gcm, - Key, // Or `Aes128Gcm` - Nonce, -}; - -use hmac::Hmac; -use pbkdf2::pbkdf2; -use pbkdf2::{ - password_hash::{PasswordHash, PasswordHasher, SaltString}, - Pbkdf2, -}; -use pem::{parse as parse_pem, Pem}; -use rand::Rng; -use sha2::Sha256; - -use wasm_bindgen::prelude::*; - -const KEY_SIZE: usize = 32; // SALTSIZE -const NONCE_SIZE: usize = 12; // NONCESIZE -const IV_SIZE: usize = 16; // IVSIZE -const BLOCK_SIZE: usize = 16; // BLOCKSIZE - -const ITERATIONS: u32 = 10000; - -#[derive(Debug, Clone)] -#[wasm_bindgen] -pub enum CipherAlgo { - GMC = 0, - CBC = 1, - CFB = 2, -} -// todo!("build with macro") -impl CipherAlgo { - pub fn to_vec(&self) -> Vec { - match self { - CipherAlgo::GMC => vec![0], - CipherAlgo::CBC => vec![1], - CipherAlgo::CFB => vec![2], - } - } - - pub fn from_u8(value: u8) -> Result { - match value { - 0 => Ok(CipherAlgo::GMC), - 1 => Ok(CipherAlgo::CBC), - 2 => Ok(CipherAlgo::CFB), - _ => Err(Error::CipherError("Invalid cipher algorithm".to_owned())), - } - } - - pub fn encrypt(&self, data: &[u8], password: &str) -> Result, Error> { - match self { - CipherAlgo::GMC => gcm_encrypt(data, password), - CipherAlgo::CBC => cbc_encrypt(data, password), - CipherAlgo::CFB => cfb_encrypt(data, password), - } - } - - pub fn decrypt(&self, data: &[u8], password: &str) -> Result, Error> { - match self { - CipherAlgo::GMC => gcm_decrypt(data, password), - CipherAlgo::CBC => cbc_decrypt(data, password), - CipherAlgo::CFB => cfb_decrypt(data, password), - } - } -} - -pub fn to_pem(tag: String, data: &[u8]) -> Result { - Ok(Pem::new(tag, data)) -} - -pub fn from_pem(pem: Pem) -> Vec { - pem.contents().to_vec() -} - -pub fn string_to_pem(data: &str) -> Result { - parse_pem(data.as_bytes()).map_err(|e| Error::CipherError(format!("{}", e))) -} - -pub fn create_checksum(password: &str) -> String { - let rng = rand::thread_rng(); - let salt = SaltString::generate(rng); - let password_hash = pbkdf2::Pbkdf2 - .hash_password(password.as_bytes(), &salt) - .unwrap(); - - password_hash.to_string() -} - -pub fn check_checksum(password: &str, checksum: String) -> bool { - let parsed_hash = PasswordHash::new(&checksum).unwrap(); - let result = parsed_hash.verify_password(&[&Pbkdf2], password); - - result.is_ok() -} - -pub fn derive_key(salt: &[u8], password: &str) -> Vec { - let mut key = vec![0u8; KEY_SIZE]; - pbkdf2::>(password.as_bytes(), salt, ITERATIONS, &mut key) - .expect("Error deriving key"); - key -} - -pub fn encrypt(algo: CipherAlgo, data: &[u8], password: &str) -> Result, Error> { - algo.encrypt(data, password) -} - -pub fn decrypt(data: &[u8], password: &str) -> Result, Error> { - if data.is_empty() { - return Err(Error::CipherError("Invalid PEM data".to_owned())); - } - - // get algo - let algo = CipherAlgo::from_u8(data[0])?; - algo.decrypt(&data[1..], password) -} - -pub fn gcm_encrypt(data: &[u8], password: &str) -> Result, Error> { - // Derive key from password - let salt: [u8; 32] = rand::thread_rng().gen(); - let derived_key = derive_key(&salt, password); - let key = Key::::from_slice(&derived_key); - let cipher = Aes256Gcm::new(key); - - // Generate a unique nonce - let nonce = Aes256Gcm::generate_nonce(&mut OsRng); - - // Encrypt data - let ciphertext = cipher - .encrypt(&nonce, data) - .map_err(|e| Error::CipherError(format!("encryption failed: {}", e)))?; - - // Create PEM - let mut result = CipherAlgo::GMC.to_vec(); - result.extend_from_slice(&salt); - result.extend_from_slice(&nonce); - result.extend_from_slice(&ciphertext); - - Ok(result) -} - -pub fn gcm_decrypt(encrypted: &[u8], password: &str) -> Result, Error> { - if encrypted.len() < KEY_SIZE + NONCE_SIZE { - return Err(Error::CipherError("Invalid PEM data".to_owned())); - } - let salt = &encrypted[..KEY_SIZE]; - let nonce = &encrypted[KEY_SIZE..KEY_SIZE + NONCE_SIZE]; - let encrypted_data = &encrypted[KEY_SIZE + NONCE_SIZE..]; - let derived_key = derive_key(salt, password); - let key = Key::::from_slice(&derived_key); - let cipher = Aes256Gcm::new(key); - cipher - .decrypt(Nonce::from_slice(nonce), encrypted_data) - .map_err(|e| Error::CipherError(format!("decryption failed: {}", e))) -} - -type Aes256CbcEnc = cbc::Encryptor; -type Aes256CbcDec = cbc::Decryptor; -pub fn cbc_encrypt(data: &[u8], password: &str) -> Result, Error> { - let iv: [u8; IV_SIZE] = rand::thread_rng().gen(); - let derived_key = derive_key(&iv, password); // KeySize [u8; 32] - let key = GenericArray::from_slice(&derived_key); - - let padding_size = BLOCK_SIZE - data.len() % BLOCK_SIZE; - let buf_len = data.len() + padding_size; - - let mut buf = vec![0; buf_len]; - - buf[..data.len()].copy_from_slice(data); - - let ct = Aes256CbcEnc::new(key, &iv.into()) - .encrypt_padded_mut::(&mut buf, data.len()) - .map_err(|e| Error::CipherError(format!("encryption failed: {}", e)))?; - - // Create PEM - let mut result = CipherAlgo::CBC.to_vec(); - result.extend_from_slice(&iv); - result.extend_from_slice(ct); - - Ok(result) -} - -pub fn cbc_decrypt(encrypted: &[u8], password: &str) -> Result, Error> { - if encrypted.len() < IV_SIZE { - return Err(Error::CipherError("Invalid PEM data".to_owned())); - } - - let iv = GenericArray::from_slice(&encrypted[..IV_SIZE]); - let encrypted_data = &encrypted[IV_SIZE..]; - let derived_key = derive_key(iv, password); - let key = GenericArray::from_slice(&derived_key); - - let mut buf = encrypted_data.to_vec(); - let pt: &[u8] = Aes256CbcDec::new(key, iv) - .decrypt_padded_mut::(&mut buf) - .map_err(|e| Error::CipherError(format!("decryption failed: {}", e)))?; - - Ok(pt.to_vec()) -} - -type Aes256CfbEnc = cfb_mode::Encryptor; -type Aes256CfbDec = cfb_mode::Decryptor; -pub fn cfb_encrypt(data: &[u8], password: &str) -> Result, Error> { - let iv: [u8; IV_SIZE] = rand::thread_rng().gen(); - let derived_key = derive_key(&iv, password); // KeySize [u8; 32] - let key = GenericArray::from_slice(&derived_key); - - let mut buf = data.to_vec(); - Aes256CfbEnc::new(key, &iv.into()).encrypt(&mut buf); - - // Create PEM - let mut result = CipherAlgo::CFB.to_vec(); - result.extend_from_slice(&iv); - result.extend_from_slice(&buf); - - Ok(result) -} - -pub fn cfb_decrypt(encrypted: &[u8], password: &str) -> Result, Error> { - if encrypted.len() < IV_SIZE { - return Err(Error::CipherError("Invalid PEM data".to_owned())); - } - - let iv = GenericArray::from_slice(&encrypted[..IV_SIZE]); - let encrypted_data = &encrypted[IV_SIZE..]; - let derived_key = derive_key(iv, password); - let key = GenericArray::from_slice(&derived_key); - - let mut buf = encrypted_data.to_vec(); - Aes256CfbDec::new(key, iv).decrypt(&mut buf); - - Ok(buf) -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_encrypt_decrypt() { - for algo in vec![CipherAlgo::GMC, CipherAlgo::CBC, CipherAlgo::CFB] { - let data = b"hello world"; - let password = "password"; - - let encrypted = encrypt(algo.to_owned(), data, password).unwrap(); - let decrypted = decrypt(&encrypted, password).unwrap(); - assert_eq!(data, decrypted.as_slice()); - } - } - - #[test] - fn test_encrypt_decrypt_invalid_password() { - for algo in vec![CipherAlgo::GMC, CipherAlgo::CBC, CipherAlgo::CFB] { - let data = b"hello world"; - let password = "password"; - - let encrypted = encrypt(algo, data, password).unwrap(); - let decrypted = decrypt(&encrypted, "invalid password"); - match decrypted { - Ok(decrypted) => { - assert_ne!(data, decrypted.as_slice()); - } - _ => {} - } - } - } - - #[test] - fn test_encrypt_decrypt_invalid_data() { - for algo in vec![CipherAlgo::GMC, CipherAlgo::CBC, CipherAlgo::CFB] { - let data = b"hello world"; - let password = "password"; - - let encrypted = encrypt(algo.clone(), data, password).unwrap(); - let decrypted = decrypt(&encrypted[..encrypted.len() - 1], password); - match decrypted { - Ok(decrypted) => { - assert_ne!(data, decrypted.as_slice()); - } - _ => {} - } - } - } - - #[test] - fn test_to_pem() { - let data = b"hello world"; - let tag = "TEST"; - let pem = to_pem(tag.to_owned(), data).unwrap(); - assert_eq!(pem.tag(), tag); - assert_eq!(pem.contents(), data); - } - - #[test] - fn test_from_pem() { - let data = b"hello world"; - let tag = "TEST"; - let pem = to_pem(tag.to_owned(), data).unwrap(); - let pem_data = from_pem(pem); - assert_eq!(pem_data, data); - } - - #[test] - fn test_create_checksum() { - let password = "password"; - let checksum = create_checksum(password); - assert!(check_checksum(password, checksum)); - } -} - -/* - LEGACY GCM DECRYPT SHA1 KEY no SALT -*/ -use sha1::Sha1; -#[wasm_bindgen(js_name = gcmDecryptByKey)] -pub fn gcm_decrypt_by_key(encrypted: &str, key: &str) -> Result, Error> { - if encrypted.len() < NONCE_SIZE { - return Err(Error::CipherError("invalid data len".to_owned())); - } - - // convert hex to bytes - let encrypted = hex::decode(encrypted) - .map_err(|e| Error::CipherError(format!("decryption failed: {}", e)))?; - - let b64 = b64_engine::STANDARD; - // convert base64 to bytes - let key = b64 - .decode(key) - .map_err(|e| Error::CipherError(format!("decryption failed: {}", e)))?; - - // compute encrypt key - let salt = crate::hash::sha256("".as_bytes()); - let key_hash = crate::hash::sha256(&key[..]); - let mut key = vec![0u8; KEY_SIZE]; - pbkdf2::>(&key_hash, &salt, 4096, &mut key).expect("Error deriving key"); - - // retrieve nonce and encrypted data - let nonce = &encrypted[..NONCE_SIZE]; - let encrypted_data = &encrypted[NONCE_SIZE..]; - - let key = Key::::from_slice(&key); - let cipher = Aes256Gcm::new(key); - cipher - .decrypt(Nonce::from_slice(nonce), encrypted_data) - .map_err(|e| Error::CipherError(format!("decryption failed: {}", e))) -} diff --git a/packages/kos-crypto/src/ed25519.rs b/packages/kos-crypto/src/ed25519.rs deleted file mode 100644 index 980440e..0000000 --- a/packages/kos-crypto/src/ed25519.rs +++ /dev/null @@ -1,154 +0,0 @@ -use kos_types::{error::Error, Bytes32}; - -use coins_bip32::path::DerivationPath; -use coins_bip39::{English, Mnemonic}; -use ed25519_dalek::{Signer, SigningKey, VerifyingKey, PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH}; -use hmac::{Hmac, Mac}; -use sha2::Sha512; -use std::{fmt, str::FromStr}; - -use wasm_bindgen::prelude::wasm_bindgen; - -type HmacSha521 = Hmac; - -#[derive(serde::Serialize, serde::Deserialize)] -#[wasm_bindgen] -pub struct Ed25519KeyPair { - secret_key: SigningKey, - public_key: VerifyingKey, -} - -impl Default for Ed25519KeyPair { - fn default() -> Self { - Self { - secret_key: SigningKey::from_bytes(&[0u8; SECRET_KEY_LENGTH]), - public_key: VerifyingKey::from_bytes(&[0u8; PUBLIC_KEY_LENGTH]).unwrap(), - } - } -} - -impl Clone for Ed25519KeyPair { - fn clone(&self) -> Ed25519KeyPair { - Ed25519KeyPair { - secret_key: self.secret_key.clone(), - public_key: self.public_key, - } - } -} - -impl Ed25519KeyPair { - pub fn random(rng: &mut R) -> Self - where - R: rand::Rng + ?Sized, - { - let mut secret = Bytes32::zeroed(); - rng.fill(secret.as_mut()); - - Ed25519KeyPair::new(secret.into()) - } - - pub fn new(secret: [u8; 32]) -> Self { - let secret_key: SigningKey = SigningKey::from_bytes(&secret); - let public_key: VerifyingKey = (&secret_key).into(); - - Self { - secret_key, - public_key, - } - } - - pub fn new_from_mnemonic_phrase_with_path( - phrase: &str, - path: &str, - password: Option<&str>, - ) -> Result { - let mnemonic = Mnemonic::::new_from_phrase(phrase)?; - let path = DerivationPath::from_str(path)?; - Self::new_from_mnemonic(path, mnemonic, password) - } - - /// Generate a new secret key from a `DerivationPath` and `Mnemonic`. - pub fn new_from_mnemonic( - d: DerivationPath, - m: Mnemonic, - password: Option<&str>, - ) -> Result { - let seed = m.to_seed(password)?; - - let hardened_child_padding: u8 = 0; - let mut digest = - HmacSha521::new_from_slice(b"ed25519 seed").expect("HMAC can take key of any size"); - digest.update(&seed); - let intermediary: Vec = digest.finalize().into_bytes().into_iter().collect(); - let mut key = intermediary[..SECRET_KEY_LENGTH].to_vec(); - let mut chain_code = intermediary[SECRET_KEY_LENGTH..].to_vec(); - - for child_idx in d.iter() { - let mut buff = [vec![hardened_child_padding], key.clone()].concat(); - buff.push((child_idx >> 24) as u8); - buff.push((child_idx >> 16) as u8); - buff.push((child_idx >> 8) as u8); - buff.push((child_idx & 0xff) as u8); - - digest = - HmacSha521::new_from_slice(&chain_code).expect("HMAC can take key of any size"); - digest.update(&buff); - let intermediary: Vec = digest.finalize().into_bytes().into_iter().collect(); - key = intermediary[..SECRET_KEY_LENGTH].to_vec(); - chain_code = intermediary[SECRET_KEY_LENGTH..].to_vec(); - } - - Ok(Self::new(key.try_into().map_err(|_e| { - Error::InvalidMnemonic("Error convert vec into slice") - })?)) - } -} - -impl Ed25519KeyPair { - pub fn public_key(&self) -> Vec { - self.public_key.to_bytes().to_vec() - } - - pub fn secret_key(&self) -> Vec { - self.secret_key.to_bytes().to_vec() - } -} - -impl Ed25519KeyPair { - pub fn sign_digest(&self, message: &[u8]) -> Vec { - let sig = self.secret_key.sign(message); - sig.to_bytes().to_vec() - } - - pub fn verify_digest(&self, message: &[u8], signature: &[u8], public_key: &[u8]) -> bool { - if signature.len() != 64 { - return false; - } - let mut sig_bytes = [0u8; 64]; - sig_bytes.copy_from_slice(signature); - - let mut pub_bytes = [0u8; 32]; - if public_key.len() != 32 { - pub_bytes = self.public_key.to_bytes(); - } else { - pub_bytes.copy_from_slice(public_key); - } - - VerifyingKey::from_bytes(&pub_bytes) - .map(|public_key| { - public_key - .verify_strict(message, &ed25519_dalek::Signature::from_bytes(&sig_bytes)) - .is_ok() - }) - .unwrap_or(false) - } -} - -impl fmt::Debug for Ed25519KeyPair { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("") - .field(&self.secret_key) - .field(&self.public_key) - .finish() - } -} diff --git a/packages/kos-crypto/src/hash.rs b/packages/kos-crypto/src/hash.rs deleted file mode 100644 index 4f513fa..0000000 --- a/packages/kos-crypto/src/hash.rs +++ /dev/null @@ -1,31 +0,0 @@ -use crate::blake2b::Blake2b; -use sha2::{Digest, Sha256, Sha512}; -use sha3::Keccak256; - -#[inline] -pub fn sha256(input: &[u8]) -> [u8; 32] { - let mut hasher = Sha256::new(); - hasher.update(input); - hasher.finalize().into() -} - -#[inline] -pub fn keccak256(input: &[u8]) -> [u8; 32] { - let mut hasher = Keccak256::new(); - hasher.update(input); - hasher.finalize().into() -} - -#[inline] -pub fn blake2b256(input: &[u8]) -> [u8; 32] { - let mut hasher = Blake2b::new(32); - hasher.update(input); - hasher.finalize().try_into().unwrap() -} - -#[inline] -pub fn sha512(input: &[u8]) -> [u8; 64] { - let mut hasher = Sha512::new(); - hasher.update(input); - hasher.finalize().into() -} diff --git a/packages/kos-crypto/src/keypair.rs b/packages/kos-crypto/src/keypair.rs deleted file mode 100644 index 4323134..0000000 --- a/packages/kos-crypto/src/keypair.rs +++ /dev/null @@ -1,139 +0,0 @@ -use crate::ed25519; -use crate::secp256k1; - -use std::fmt; - -use wasm_bindgen::prelude::wasm_bindgen; - -#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] -enum KeyType { - Default, - Ed25519, - Secp256k1, - Secp256k1Compressed, -} - -#[derive(Clone, serde::Serialize, serde::Deserialize)] -#[wasm_bindgen] -pub struct KeyPair { - key_type: KeyType, - ed25519: Option, - secp256k1: Option, -} - -#[wasm_bindgen] -impl KeyPair { - pub fn new_default() -> Self { - Self { - key_type: KeyType::Default, - ed25519: None, - secp256k1: None, - } - } - - pub fn new_ed25519(kp: ed25519::Ed25519KeyPair) -> Self { - Self { - key_type: KeyType::Ed25519, - ed25519: Some(kp), - secp256k1: None, - } - } - - pub fn new_secp256k1(kp: secp256k1::Secp256k1KeyPair) -> Self { - Self { - key_type: if kp.is_compressed() { - KeyType::Secp256k1Compressed - } else { - KeyType::Secp256k1 - }, - ed25519: None, - secp256k1: Some(kp), - } - } -} - -impl KeyPair { - pub fn sign_digest(&self, digest: &[u8]) -> Vec { - match self.key_type { - KeyType::Default => Vec::new(), - KeyType::Ed25519 => self.ed25519.as_ref().unwrap().sign_digest(digest), - KeyType::Secp256k1 => self.secp256k1.as_ref().unwrap().sign_digest(digest), - KeyType::Secp256k1Compressed => self.secp256k1.as_ref().unwrap().sign_digest(digest), - } - } - - pub fn verify_digest(&self, digest: &[u8], signature: &[u8], public_key: &[u8]) -> bool { - match self.key_type { - KeyType::Default => false, - KeyType::Ed25519 => self - .ed25519 - .as_ref() - .unwrap() - .verify_digest(digest, signature, public_key), - KeyType::Secp256k1 => self - .secp256k1 - .as_ref() - .unwrap() - .verify_digest(digest, signature, public_key), - KeyType::Secp256k1Compressed => self - .secp256k1 - .as_ref() - .unwrap() - .verify_digest(digest, signature, public_key), - } - } -} - -impl From for KeyPair { - fn from(kp: ed25519::Ed25519KeyPair) -> Self { - Self::new_ed25519(kp) - } -} - -impl From for KeyPair { - fn from(kp: secp256k1::Secp256k1KeyPair) -> Self { - Self::new_secp256k1(kp) - } -} - -impl KeyPair { - pub fn public_key(&self) -> Vec { - match self.key_type { - KeyType::Default => Vec::new(), - KeyType::Ed25519 => self.ed25519.as_ref().unwrap().public_key(), - KeyType::Secp256k1 | KeyType::Secp256k1Compressed => { - self.secp256k1.as_ref().unwrap().public_key() - } - } - } - - pub fn public_key_hex(&self) -> String { - let bytes = self.public_key(); - hex::encode(bytes) - } - - pub fn secret_key(&self) -> Vec { - match self.key_type { - KeyType::Default => Vec::new(), - KeyType::Ed25519 => self.ed25519.as_ref().unwrap().secret_key(), - KeyType::Secp256k1 | KeyType::Secp256k1Compressed => { - self.secp256k1.as_ref().unwrap().secret_key() - } - } - } - - pub fn secret_key_hex(&self) -> String { - let bytes = self.secret_key(); - hex::encode(bytes) - } -} - -impl fmt::Debug for KeyPair { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("") - .field(&self.key_type) - .field(&self.ed25519) - .field(&self.secp256k1) - .finish() - } -} diff --git a/packages/kos-crypto/src/lib.rs b/packages/kos-crypto/src/lib.rs deleted file mode 100644 index d2d5a19..0000000 --- a/packages/kos-crypto/src/lib.rs +++ /dev/null @@ -1,7 +0,0 @@ -pub mod blake2b; -pub mod cipher; -pub mod ed25519; -pub mod hash; -pub mod keypair; -pub mod mnemonic; -pub mod secp256k1; diff --git a/packages/kos-crypto/src/mnemonic.rs b/packages/kos-crypto/src/mnemonic.rs deleted file mode 100644 index 9c1cd2c..0000000 --- a/packages/kos-crypto/src/mnemonic.rs +++ /dev/null @@ -1,16 +0,0 @@ -use kos_types::error::Error; - -use coins_bip39::{English, Mnemonic}; - -pub fn generate_mnemonic(count: usize) -> Result, Error> { - // create rng - let mut rng = rand::thread_rng(); - // generate mnemonic phrase - Ok(Mnemonic::::new_with_count(&mut rng, count)?) -} - -pub fn validate_mnemonic(phrase: &str) -> Result<(), Error> { - // validate mnemonic phrase - let _mnemonic: Mnemonic = phrase.parse()?; - Ok(()) -} diff --git a/packages/kos-crypto/src/secp256k1.rs b/packages/kos-crypto/src/secp256k1.rs deleted file mode 100644 index 20491d7..0000000 --- a/packages/kos-crypto/src/secp256k1.rs +++ /dev/null @@ -1,141 +0,0 @@ -use kos_types::error::Error; - -use coins_bip32::path::DerivationPath; -use coins_bip39::{English, Mnemonic}; -use secp256k1::{ - ecdsa::{RecoverableSignature, RecoveryId}, - Error as Secp256k1Error, Message, PublicKey, Secp256k1, SecretKey, -}; -use std::{fmt, str::FromStr}; - -use wasm_bindgen::prelude::wasm_bindgen; - -#[derive(Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)] -#[wasm_bindgen] -pub struct Secp256k1KeyPair { - secret_key: SecretKey, - public_key: PublicKey, - compressed: bool, -} - -impl Secp256k1KeyPair { - pub fn random(rng: &mut R) -> Self - where - R: rand::Rng + ?Sized, - { - let secp = Secp256k1::new(); - let (secret_key, public_key) = secp.generate_keypair(rng); - Self { - secret_key, - public_key, - compressed: false, - } - } - - pub fn new(secret: [u8; 32]) -> Self { - let secp = Secp256k1::new(); - - let secret_key: SecretKey = SecretKey::from_slice(secret.as_ref()).unwrap(); - let public_key = PublicKey::from_secret_key(&secp, &secret_key); - - Self { - secret_key, - public_key, - compressed: false, - } - } - - pub fn new_from_mnemonic_phrase_with_path( - phrase: &str, - path: &str, - password: Option<&str>, - ) -> Result { - let mnemonic = Mnemonic::::new_from_phrase(phrase)?; - let path = DerivationPath::from_str(path)?; - Self::new_from_mnemonic(path, mnemonic, password) - } - - /// Generate a new secret key from a `DerivationPath` and `Mnemonic`. - pub fn new_from_mnemonic( - d: DerivationPath, - m: Mnemonic, - password: Option<&str>, - ) -> Result { - let derived_priv_key = m.derive_key(d, password)?; - let key: &coins_bip32::prelude::SigningKey = derived_priv_key.as_ref(); - - let secp = Secp256k1::new(); - let secret_key = SecretKey::from_slice(key.to_bytes().as_mut())?; - let public_key = PublicKey::from_secret_key(&secp, &secret_key); - - Ok(Self { - secret_key, - public_key, - compressed: false, - }) - } -} - -impl Secp256k1KeyPair { - pub fn public_key(&self) -> Vec { - if self.compressed { - self.public_key.serialize().to_vec() - } else { - self.public_key.serialize_uncompressed()[1..].to_vec() - } - } - - pub fn secret_key(&self) -> Vec { - self.secret_key[..].to_vec() - } - - pub fn is_compressed(&self) -> bool { - self.compressed - } - - pub fn set_compressed(mut self, compressed: bool) -> Self { - self.compressed = compressed; - self - } -} - -impl Secp256k1KeyPair { - pub fn sign_digest(&self, digest: &[u8]) -> Vec { - let secp = secp256k1::Secp256k1::new(); - let message = Message::from_slice(digest).unwrap(); - let sig = secp.sign_ecdsa_recoverable(&message, &self.secret_key); - - let (rec_id, compact) = sig.serialize_compact(); - let mut raw = vec![0; 65]; - raw[0..64].copy_from_slice(&compact); - raw[64] = (rec_id.to_i32() & 0xff) as u8; - raw - } - - pub fn verify_digest(&self, digest: &[u8], signature: &[u8], public_key: &[u8]) -> bool { - Self::recover(digest, signature).map_or(false, |recovered| recovered == public_key) - } - - pub fn recover(digest: &[u8], sig: &[u8]) -> Result, Error> { - // check signature length - if sig.len() != 65 { - return Err(Secp256k1Error::InvalidSignature.into()); - } - - let secp = secp256k1::Secp256k1::new(); - let recid = RecoveryId::from_i32(sig[64] as i32)?; - let rec_sig = RecoverableSignature::from_compact(&sig[0..64], recid)?; - let message = Message::from_slice(digest)?; - let public_key = secp.recover_ecdsa(&message, &rec_sig)?; - Ok(public_key.serialize_uncompressed()[1..].to_vec()) - } -} - -impl fmt::Debug for Secp256k1KeyPair { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("") - .field(&self.secret_key) - .field(&self.public_key) - .finish() - } -} diff --git a/packages/kos-crypto/src/serde_util.rs b/packages/kos-crypto/src/serde_util.rs deleted file mode 100644 index 3b851b2..0000000 --- a/packages/kos-crypto/src/serde_util.rs +++ /dev/null @@ -1,116 +0,0 @@ -// SPDX-License-Identifier: CC0-1.0 - -use core::fmt; -use core::marker::PhantomData; -use core::str::{self, FromStr}; - -use serde::de; - -/// A serde visitor that works for `T`s implementing `FromStr`. -pub struct FromStrVisitor { - expectation: &'static str, - _pd: PhantomData, -} - -impl FromStrVisitor { - pub fn new(expectation: &'static str) -> Self { - FromStrVisitor { expectation, _pd: PhantomData } - } -} - -impl<'de, T> de::Visitor<'de> for FromStrVisitor -where - T: FromStr, - ::Err: fmt::Display, -{ - type Value = T; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str(self.expectation) - } - - fn visit_str(self, v: &str) -> Result { - FromStr::from_str(v).map_err(E::custom) - } -} - -pub struct BytesVisitor { - expectation: &'static str, - parse_fn: F, -} - -impl BytesVisitor -where - F: FnOnce(&[u8]) -> Result, - Err: fmt::Display, -{ - pub fn new(expectation: &'static str, parse_fn: F) -> Self { - BytesVisitor { expectation, parse_fn } - } -} - -impl<'de, F, T, Err> de::Visitor<'de> for BytesVisitor -where - F: FnOnce(&[u8]) -> Result, - Err: fmt::Display, -{ - type Value = T; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str(self.expectation) - } - - fn visit_bytes(self, v: &[u8]) -> Result { - (self.parse_fn)(v).map_err(E::custom) - } -} - -macro_rules! impl_tuple_visitor { - ($thing:ident, $len:expr) => { - pub(crate) struct $thing { - expectation: &'static str, - parse_fn: F, - } - - impl $thing - where - F: FnOnce(&[u8]) -> Result, - E: fmt::Display, - { - pub fn new(expectation: &'static str, parse_fn: F) -> Self { - $thing { expectation, parse_fn } - } - } - - impl<'de, F, T, E> de::Visitor<'de> for $thing - where - F: FnOnce(&[u8]) -> Result, - E: fmt::Display, - { - type Value = T; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str(self.expectation) - } - - fn visit_seq(self, mut seq: V) -> Result - where - V: de::SeqAccess<'de>, - { - let mut bytes = [0u8; $len]; - - for (i, byte) in bytes.iter_mut().enumerate() { - if let Some(value) = seq.next_element()? { - *byte = value; - } else { - return Err(de::Error::invalid_length(i, &self)); - } - } - (self.parse_fn)(&bytes).map_err(de::Error::custom) - } - } - }; -} - -impl_tuple_visitor!(Tuple32Visitor, 32); -impl_tuple_visitor!(Tuple33Visitor, 33); diff --git a/packages/kos-mobile/Cargo.toml b/packages/kos-mobile/Cargo.toml index 6331fd1..1c38d67 100644 --- a/packages/kos-mobile/Cargo.toml +++ b/packages/kos-mobile/Cargo.toml @@ -16,11 +16,7 @@ name = "uniffi-bindgen" path = "src/bin/uniffi-bindgen.rs" [dependencies] -kos-types = { workspace = true, features = ["serde"] } -kos-crypto = { workspace = true } -kos-proto = { workspace = true } -kos-utils = { workspace = true } -kos-sdk = { workspace = true, features = ["serde"] } +kos = { workspace = true } hex = { workspace = true } lazy_static = { workspace = true } diff --git a/packages/kos-mobile/src/lib.rs b/packages/kos-mobile/src/lib.rs index 84c4547..2c26d92 100644 --- a/packages/kos-mobile/src/lib.rs +++ b/packages/kos-mobile/src/lib.rs @@ -1,11 +1,6 @@ use hex::FromHexError; use hex::ToHex; -use kos_crypto::cipher; -use kos_crypto::cipher::CipherAlgo; -use kos_sdk::chain::Chain; -use kos_sdk::models::{PathOptions, Transaction}; -use kos_sdk::wallet::Wallet; -use kos_types::error::Error as KosError; +use kos::chains::{get_chain_by_id, Chain, ChainError, Transaction}; uniffi::setup_scaffolding!(); @@ -19,8 +14,8 @@ enum KOSError { HexDecode(String), } -impl From for KOSError { - fn from(err: KosError) -> Self { +impl From for KOSError { + fn from(err: ChainError) -> Self { KOSError::KOSDelegate(err.to_string()) } } @@ -48,32 +43,14 @@ struct KOSTransaction { pub signature: String, } -#[uniffi::export] -fn sign_transaction(account: KOSAccount, raw: String) -> Result { - let chain = get_chain_by(account.chain_id)?; - let wallet = Wallet::from_private_key(chain, account.private_key.to_string())?; - let transaction = Transaction::from_raw(chain, &raw)?; - let signed_transaction = wallet.sign(transaction)?; - let signature = signed_transaction - .get_signature() - .ok_or(KOSError::KOSDelegate("Signature not found".to_string()))?; - - Ok(KOSTransaction { - chain_id: account.chain_id, - raw: signed_transaction.get_raw()?, - sender: signed_transaction.sender, - signature, - }) -} - #[uniffi::export] fn generate_mnemonic(size: i32) -> Result { - Ok(kos_crypto::mnemonic::generate_mnemonic(size as usize)?.to_phrase()) + Ok(kos::crypto::mnemonic::generate_mnemonic(size as usize)?.to_phrase()) } #[uniffi::export] fn validate_mnemonic(mnemonic: String) -> bool { - kos_crypto::mnemonic::validate_mnemonic(mnemonic.as_str()).is_ok() + kos::crypto::mnemonic::validate_mnemonic(mnemonic.as_str()).is_ok() } #[uniffi::export] @@ -87,16 +64,17 @@ fn generate_wallet_from_mnemonic( return Err(KOSError::KOSDelegate("Invalid mnemonic".to_string())); } let chain = get_chain_by(chain_id)?; - let mut path_options = PathOptions::new(index as u32); - path_options.set_legacy(use_legacy_path); - let path = chain.get_path(&path_options)?; - let wallet = Wallet::from_mnemonic(chain, mnemonic, path, None)?; + let seed = chain.mnemonic_to_seed(mnemonic, String::from("")).unwrap(); + let private_key = chain.derive(seed, String::new()).unwrap(); + + let public_key = chain.get_pbk(private_key.clone()).unwrap(); + Ok(KOSAccount { chain_id, - private_key: wallet.get_private_key(), - public_key: wallet.get_public_key(), - address: wallet.get_address(), - path: wallet.get_path(), + private_key: hex::encode(private_key), + public_key: hex::encode(public_key.clone()), + address: chain.get_address(public_key)?, + path: String::new(), // TODO: implement path }) } @@ -106,48 +84,68 @@ fn generate_wallet_from_private_key( private_key: String, ) -> Result { let chain = get_chain_by(chain_id)?; - let wallet = Wallet::from_private_key(chain, private_key)?; + + let public_key = chain.get_pbk(hex::decode(private_key.clone())?)?; + let address = chain.get_address(public_key.clone())?; Ok(KOSAccount { chain_id, - private_key: wallet.get_private_key(), - public_key: wallet.get_public_key(), - address: wallet.get_address(), - path: wallet.get_path(), + private_key: private_key.clone(), + public_key: hex::encode(public_key.clone()), + address, + path: String::new(), // TODO: implement path }) } #[uniffi::export] fn encrypt_with_gmc(data: String, password: String) -> Result { - let encrypted_data = CipherAlgo::GMC.encrypt(data.as_bytes(), password.as_str())?; - Ok(encrypted_data.encode_hex()) + todo!() } #[uniffi::export] fn encrypt_with_cbc(data: String, password: String) -> Result { - let encrypted_data = CipherAlgo::CBC.encrypt(data.as_bytes(), password.as_str())?; - Ok(encrypted_data.encode_hex()) + todo!() } #[uniffi::export] fn encrypt_with_cfb(data: String, password: String) -> Result { - let encrypted_data = CipherAlgo::CFB.encrypt(data.as_bytes(), password.as_str())?; - Ok(encrypted_data.encode_hex()) + todo!() } #[uniffi::export] fn decrypt(data: String, password: String) -> Result { - let data_in_byte = hex::decode(data)?; - let decrypted_data = cipher::decrypt(&data_in_byte, password.as_str())?; - Ok(String::from_utf8_lossy(&decrypted_data).to_string()) + todo!() } -fn get_chain_by(id: i32) -> Result { - let id_u8 = u8::try_from(id).map_err(|_| KOSError::UnsupportedChain { id: id.to_string() })?; - let chain = Chain::get_by_code(id_u8) - .ok_or_else(|| KOSError::UnsupportedChain { id: id.to_string() })?; +fn get_chain_by(id: i32) -> Result, KOSError> { + let id_u8 = u32::try_from(id).map_err(|_| KOSError::UnsupportedChain { id: id.to_string() })?; + let chain = + get_chain_by_id(id_u8).ok_or_else(|| KOSError::UnsupportedChain { id: id.to_string() })?; + Ok(chain) } +#[uniffi::export] +fn sign_transaction(account: KOSAccount, raw: String) -> Result { + let chain = get_chain_by(account.chain_id)?; + let raw_tx_bytes = hex::decode(raw.clone())?; + let transaction = Transaction { + raw_data: raw_tx_bytes, + signature: Vec::new(), + tx_hash: Vec::new(), + }; + let pk = hex::decode(account.private_key.clone())?; + + let signed_transaction = chain.sign_tx(pk, transaction)?; + let signature = signed_transaction.signature; + + Ok(KOSTransaction { + chain_id: account.chain_id, + raw: hex::encode(signed_transaction.raw_data), + sender: account.address, + signature: hex::encode(signature), + }) +} + #[cfg(test)] mod tests { use crate::*; diff --git a/packages/kos-proto/Cargo.toml b/packages/kos-proto/Cargo.toml deleted file mode 100644 index 8e95e47..0000000 --- a/packages/kos-proto/Cargo.toml +++ /dev/null @@ -1,38 +0,0 @@ -[package] -name = "kos-proto" -version = { workspace = true } -authors = { workspace = true } -edition = { workspace = true } -homepage = { workspace = true } -license = { workspace = true } -repository = { workspace = true } -rust-version = { workspace = true } - -[features] - -[dependencies] -kos-types = { workspace = true, features = ["serde"]} - -bytes = { workspace = true } -prost = { workspace = true } -prost-types = { workspace = true } -prost-wkt = "0.4" -prost-wkt-types = "0.4" -pbjson = { workspace = true } -pbjson-types = { workspace = true } - -serde = { workspace = true, features = ["derive"] } -serde_json = { workspace = true } -wasm-bindgen = { workspace = true } - -[lib] -test = false -doctest = false - -[build-dependencies] -glob = "0.3" -prost-build = "0.12" -prost-wkt-build = "0.4" -quote = "1.0" -heck = " 0.4" -pbjson-build = { workspace = true } diff --git a/packages/kos-proto/build.rs b/packages/kos-proto/build.rs deleted file mode 100644 index a11091f..0000000 --- a/packages/kos-proto/build.rs +++ /dev/null @@ -1,182 +0,0 @@ -use glob::glob; -use heck::ToUpperCamelCase; -use prost_wkt_build::*; -use quote::{format_ident, quote}; -use std::fs::{self, File, OpenOptions}; -use std::io::Error; -use std::io::Write; -use std::path::Path; -use std::{env, path::PathBuf}; - -fn build_pbjson( - package_name: &str, - proto_serde: &[impl AsRef], - protos: &[impl AsRef], - includes: &[impl AsRef], - use_number_for_ui64: bool, - use_hex_for_bytes: bool, - btree_map: bool, -) -> Result<(), Error> { - let full_path = format!("{}/{}", env::var("OUT_DIR").unwrap().as_str(), package_name); - fs::create_dir_all(&full_path).unwrap(); - - let out_dir = PathBuf::from(&full_path); - let descriptor_file = out_dir.join(format!("{}.descriptors.bin", package_name)); - let mut prost_build = prost_build::Config::new(); - prost_build - .extern_path(".google.protobuf", "::pbjson_types") - .file_descriptor_set_path(&descriptor_file) - .protoc_arg("--experimental_allow_proto3_optional") - // Override prost-types with pbjson-types - .compile_well_known_types(); - - if btree_map { - prost_build.btree_map(["."]); - } - - prost_build - .out_dir(&full_path) - .compile_protos(protos, includes) - .unwrap(); - - let descriptor_bytes = std::fs::read(descriptor_file).unwrap(); - - let descriptor = FileDescriptorSet::decode(&descriptor_bytes[..]).unwrap(); - - let mut binding = pbjson_build::Builder::new(); - binding - .preserve_proto_field_names() - .register_descriptors(&descriptor_bytes)? - .use_number_for_ui64(use_number_for_ui64) - .use_hex_for_bytes(use_hex_for_bytes); - - if btree_map { - binding.btree_map(["."]); - } - - binding.out_dir(&full_path).build(proto_serde)?; - - generate_extras(&out_dir, &descriptor); - - println!("cargo:warning={}", full_path); - - Ok(()) -} - -fn get_files(dir: &str) -> Vec { - let mut list: Vec = vec![]; - for entry in glob(dir).expect("Failed to read glob pattern") { - let Ok(st) = entry else { - continue; - }; - list.push(format!("./{:}", st.display())); - } - list -} - -#[allow(dead_code)] -fn build_prost_serde( - package_name: &str, - protos: &[impl AsRef], - includes: &[impl AsRef], -) -> Result<(), Error> { - let full_path = format!("{}/{}", env::var("OUT_DIR").unwrap().as_str(), package_name); - fs::create_dir_all(&full_path).unwrap(); - - let out_dir = PathBuf::from(&full_path); - let descriptor_file = out_dir.join(format!("{}.descriptors.bin", package_name)); - let mut prost_build = prost_build::Config::new(); - prost_build - .type_attribute(".", "#[derive(serde::Serialize,serde::Deserialize)]") - .compile_well_known_types() - .extern_path(".google.protobuf.Any", "::prost_wkt_types::Any") - .extern_path(".google.protobuf.Timestamp", "::prost_wkt_types::Timestamp") - .extern_path(".google.protobuf.Value", "::prost_wkt_types::Value") - .out_dir(&out_dir) - .file_descriptor_set_path(&descriptor_file) - .compile_protos(protos, includes)?; - - let descriptor_bytes = std::fs::read(descriptor_file)?; - - let descriptor = FileDescriptorSet::decode(&descriptor_bytes[..])?; - - prost_wkt_build::add_serde(out_dir, descriptor); - - println!("cargo:warning={}", full_path); - - Ok(()) -} - -fn main() -> Result<(), Error> { - // kleverchain - build_pbjson( - "klever", - &[".proto"], - get_files("proto/klever/*.proto").as_slice(), - &["proto/klever"], - true, - false, - false, - )?; - - // Tron protocol - let mut list = get_files("proto/tron/core/contract/*.proto"); - list.push("proto/tron/core/Tron.proto".to_string()); - list.push("proto/tron/core/Discover.proto".to_string()); - list.push("proto/tron/api/api.proto".to_string()); - - build_pbjson( - "tron", - &[".protocol"], - list.as_slice(), - &["proto/include", "proto/tron"], - true, - true, - false, - )?; - - Ok(()) -} - -fn generate_extras(out_dir: &Path, file_descriptor_set: &FileDescriptorSet) { - for fd in &file_descriptor_set.file { - let package = match fd.package { - Some(ref pkg) => pkg, - None => continue, - }; - - if package.starts_with("google.") { - continue; - } - - let gen_path = out_dir.join(format!("{}.rs", package)); - let mut gen_file = OpenOptions::new().append(true).open(gen_path).unwrap(); - - for msg in &fd.message_type { - let name = match msg.name { - Some(ref name) => name, - None => continue, - }; - - let type_url = format!("type.googleapis.com/{}.{}", package, name); - let type_name = name.to_upper_camel_case(); - - gen_type_url(&mut gen_file, &type_url, &type_name); - } - } -} - -fn gen_type_url(gen_file: &mut File, type_url: &str, type_name: &str) { - let type_name = format_ident!("{}", type_name); - - let tokens = quote! { - impl crate::TypeUrl for #type_name { - fn type_url() -> &'static str { - #type_url - } - } - }; - - writeln!(gen_file).unwrap(); - writeln!(gen_file, "{}", &tokens).unwrap(); -} diff --git a/packages/kos-proto/proto/include/google/api/annotations.proto b/packages/kos-proto/proto/include/google/api/annotations.proto deleted file mode 100644 index 00741c8..0000000 --- a/packages/kos-proto/proto/include/google/api/annotations.proto +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) 2015, Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.api; - -import "google/api/http.proto"; -import "google/protobuf/descriptor.proto"; - -option java_multiple_files = true; -option java_outer_classname = "AnnotationsProto"; -option java_package = "com.google.api"; - -extend google.protobuf.MethodOptions { - // See `HttpRule`. - HttpRule http = 72295728; -} \ No newline at end of file diff --git a/packages/kos-proto/proto/include/google/api/http.proto b/packages/kos-proto/proto/include/google/api/http.proto deleted file mode 100644 index e04173e..0000000 --- a/packages/kos-proto/proto/include/google/api/http.proto +++ /dev/null @@ -1,281 +0,0 @@ -// Copyright 2016 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.api; - -option cc_enable_arenas = true; -option java_multiple_files = true; -option java_outer_classname = "HttpProto"; -option java_package = "com.google.api"; - - -// Defines the HTTP configuration for a service. It contains a list of -// [HttpRule][google.api.HttpRule], each specifying the mapping of an RPC method -// to one or more HTTP REST API methods. -message Http { - // A list of HTTP rules for configuring the HTTP REST API methods. - repeated HttpRule rules = 1; -} - -// `HttpRule` defines the mapping of an RPC method to one or more HTTP -// REST APIs. The mapping determines what portions of the request -// message are populated from the path, query parameters, or body of -// the HTTP request. The mapping is typically specified as an -// `google.api.http` annotation, see "google/api/annotations.proto" -// for details. -// -// The mapping consists of a field specifying the path template and -// method kind. The path template can refer to fields in the request -// message, as in the example below which describes a REST GET -// operation on a resource collection of messages: -// -// ```proto -// service Messaging { -// rpc GetMessage(GetMessageRequest) returns (Message) { -// option (google.api.http).get = "/v1/messages/{message_id}/{sub.subfield}"; -// } -// } -// message GetMessageRequest { -// message SubMessage { -// string subfield = 1; -// } -// string message_id = 1; // mapped to the URL -// SubMessage sub = 2; // `sub.subfield` is url-mapped -// } -// message Message { -// string text = 1; // content of the resource -// } -// ``` -// -// This definition enables an automatic, bidrectional mapping of HTTP -// JSON to RPC. Example: -// -// HTTP | RPC -// -----|----- -// `GET /v1/messages/123456/foo` | `GetMessage(message_id: "123456" sub: SubMessage(subfield: "foo"))` -// -// In general, not only fields but also field paths can be referenced -// from a path pattern. Fields mapped to the path pattern cannot be -// repeated and must have a primitive (non-message) type. -// -// Any fields in the request message which are not bound by the path -// pattern automatically become (optional) HTTP query -// parameters. Assume the following definition of the request message: -// -// ```proto -// message GetMessageRequest { -// message SubMessage { -// string subfield = 1; -// } -// string message_id = 1; // mapped to the URL -// int64 revision = 2; // becomes a parameter -// SubMessage sub = 3; // `sub.subfield` becomes a parameter -// } -// ``` -// -// This enables a HTTP JSON to RPC mapping as below: -// -// HTTP | RPC -// -----|----- -// `GET /v1/messages/123456?revision=2&sub.subfield=foo` | `GetMessage(message_id: "123456" revision: 2 sub: SubMessage(subfield: "foo"))` -// -// Note that fields which are mapped to HTTP parameters must have a -// primitive type or a repeated primitive type. Message types are not -// allowed. In the case of a repeated type, the parameter can be -// repeated in the URL, as in `...?param=A¶m=B`. -// -// For HTTP method kinds which allow a request body, the `body` field -// specifies the mapping. Consider a REST update method on the -// message resource collection: -// -// ```proto -// service Messaging { -// rpc UpdateMessage(UpdateMessageRequest) returns (Message) { -// option (google.api.http) = { -// put: "/v1/messages/{message_id}" -// body: "message" -// }; -// } -// } -// message UpdateMessageRequest { -// string message_id = 1; // mapped to the URL -// Message message = 2; // mapped to the body -// } -// ``` -// -// The following HTTP JSON to RPC mapping is enabled, where the -// representation of the JSON in the request body is determined by -// protos JSON encoding: -// -// HTTP | RPC -// -----|----- -// `PUT /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: "123456" message { text: "Hi!" })` -// -// The special name `*` can be used in the body mapping to define that -// every field not bound by the path template should be mapped to the -// request body. This enables the following alternative definition of -// the update method: -// -// ```proto -// service Messaging { -// rpc UpdateMessage(Message) returns (Message) { -// option (google.api.http) = { -// put: "/v1/messages/{message_id}" -// body: "*" -// }; -// } -// } -// message Message { -// string message_id = 1; -// string text = 2; -// } -// ``` -// -// The following HTTP JSON to RPC mapping is enabled: -// -// HTTP | RPC -// -----|----- -// `PUT /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: "123456" text: "Hi!")` -// -// Note that when using `*` in the body mapping, it is not possible to -// have HTTP parameters, as all fields not bound by the path end in -// the body. This makes this option more rarely used in practice of -// defining REST APIs. The common usage of `*` is in custom methods -// which don't use the URL at all for transferring data. -// -// It is possible to define multiple HTTP methods for one RPC by using -// the `additional_bindings` option. Example: -// -// ```proto -// service Messaging { -// rpc GetMessage(GetMessageRequest) returns (Message) { -// option (google.api.http) = { -// get: "/v1/messages/{message_id}" -// additional_bindings { -// get: "/v1/users/{user_id}/messages/{message_id}" -// } -// }; -// } -// } -// message GetMessageRequest { -// string message_id = 1; -// string user_id = 2; -// } -// ``` -// -// This enables the following two alternative HTTP JSON to RPC -// mappings: -// -// HTTP | RPC -// -----|----- -// `GET /v1/messages/123456` | `GetMessage(message_id: "123456")` -// `GET /v1/users/me/messages/123456` | `GetMessage(user_id: "me" message_id: "123456")` -// -// # Rules for HTTP mapping -// -// The rules for mapping HTTP path, query parameters, and body fields -// to the request message are as follows: -// -// 1. The `body` field specifies either `*` or a field path, or is -// omitted. If omitted, it assumes there is no HTTP body. -// 2. Leaf fields (recursive expansion of nested messages in the -// request) can be classified into three types: -// (a) Matched in the URL template. -// (b) Covered by body (if body is `*`, everything except (a) fields; -// else everything under the body field) -// (c) All other fields. -// 3. URL query parameters found in the HTTP request are mapped to (c) fields. -// 4. Any body sent with an HTTP request can contain only (b) fields. -// -// The syntax of the path template is as follows: -// -// Template = "/" Segments [ Verb ] ; -// Segments = Segment { "/" Segment } ; -// Segment = "*" | "**" | LITERAL | Variable ; -// Variable = "{" FieldPath [ "=" Segments ] "}" ; -// FieldPath = IDENT { "." IDENT } ; -// Verb = ":" LITERAL ; -// -// The syntax `*` matches a single path segment. It follows the semantics of -// [RFC 6570](https://tools.ietf.org/html/rfc6570) Section 3.2.2 Simple String -// Expansion. -// -// The syntax `**` matches zero or more path segments. It follows the semantics -// of [RFC 6570](https://tools.ietf.org/html/rfc6570) Section 3.2.3 Reserved -// Expansion. -// -// The syntax `LITERAL` matches literal text in the URL path. -// -// The syntax `Variable` matches the entire path as specified by its template; -// this nested template must not contain further variables. If a variable -// matches a single path segment, its template may be omitted, e.g. `{var}` -// is equivalent to `{var=*}`. -// -// NOTE: the field paths in variables and in the `body` must not refer to -// repeated fields or map fields. -// -// Use CustomHttpPattern to specify any HTTP method that is not included in the -// `pattern` field, such as HEAD, or "*" to leave the HTTP method unspecified for -// a given URL path rule. The wild-card rule is useful for services that provide -// content to Web (HTML) clients. -message HttpRule { - // Selects methods to which this rule applies. - // - // Refer to [selector][google.api.DocumentationRule.selector] for syntax details. - string selector = 1; - - // Determines the URL pattern is matched by this rules. This pattern can be - // used with any of the {get|put|post|delete|patch} methods. A custom method - // can be defined using the 'custom' field. - oneof pattern { - // Used for listing and getting information about resources. - string get = 2; - - // Used for updating a resource. - string put = 3; - - // Used for creating a resource. - string post = 4; - - // Used for deleting a resource. - string delete = 5; - - // Used for updating a resource. - string patch = 6; - - // Custom pattern is used for defining custom verbs. - CustomHttpPattern custom = 8; - } - - // The name of the request field whose value is mapped to the HTTP body, or - // `*` for mapping all fields not captured by the path pattern to the HTTP - // body. NOTE: the referred field must not be a repeated field. - string body = 7; - - // Additional HTTP bindings for the selector. Nested bindings must - // not contain an `additional_bindings` field themselves (that is, - // the nesting may only be one level deep). - repeated HttpRule additional_bindings = 11; -} - -// A custom pattern is used for defining custom HTTP verb. -message CustomHttpPattern { - // The name of this custom HTTP verb. - string kind = 1; - - // The path matched by this custom verb. - string path = 2; -} \ No newline at end of file diff --git a/packages/kos-proto/proto/klever/transaction.proto b/packages/kos-proto/proto/klever/transaction.proto deleted file mode 100644 index 989ab2d..0000000 --- a/packages/kos-proto/proto/klever/transaction.proto +++ /dev/null @@ -1,161 +0,0 @@ -syntax = "proto3"; - -package proto; - -option go_package = "./;transaction"; - -import "google/protobuf/any.proto"; - -// TXContract available -message TXContract { - enum ContractType { - TransferContractType = 0; - CreateAssetContractType = 1; - CreateValidatorContractType = 2; - ValidatorConfigContractType = 3; - FreezeContractType = 4; - UnfreezeContractType = 5; - DelegateContractType = 6; - UndelegateContractType = 7; - WithdrawContractType = 8; - ClaimContractType = 9; - UnjailContractType = 10; - AssetTriggerContractType = 11; - SetAccountNameContractType = 12; - ProposalContractType = 13; - VoteContractType = 14; - ConfigITOContractType = 15; - SetITOPricesContractType = 16; - BuyContractType = 17; - SellContractType = 18; - CancelMarketOrderContractType = 19; - CreateMarketplaceContractType = 20; - ConfigMarketplaceContractType = 21; - UpdateAccountPermissionContractType = 22; - DepositContractType = 23; - ITOTriggerContractType = 24; - SmartContractType = 99; - } - ContractType Type = 1 [json_name = "Type"]; - google.protobuf.Any Parameter = 2 [json_name = "Parameter"]; -} - -// Transaction holds all the data needed for a value transfer -message Transaction { - enum TXResult { - SUCCESS = 0; - FAILED = 1; - } - - enum TXResultCode { - Ok = 0; - OutOfFunds = 1; - AccountError = 2; - AssetError = 3; - ContractInvalid = 4; - ContractNotFound = 5; - FeeInvalid = 6; - ParameterInvalid = 7; - APRInvalid = 8; - AssetIDInvalid = 9; - AssetTypeInvalid = 10; - AssetCantBeMinted = 11; - AssetCantBeBurned = 12; - AssetCantBePaused = 13; - AssetCantBeDelegated = 14; - AssetOwnerCantBeChanged = 15; - AccountNotOwner = 16; - CommissionTooHigh = 17; - DelegationAmountInvalid = 18; - ProposalNotActive = 19; - ValueInvalid = 20; - AmountInvalid = 21; - BucketIDInvalid = 22; - KeyConflict = 23; - MaxDelegationAmount = 24; - InvalidPeerKey = 25; - MinKFIStakedUnreached = 26; - MaxSupplyExeeced = 27; - SaveAccountError = 28; - LoadAccountError = 29; - SameAccountError = 30; - AssetPaused = 31; - DeletegateError = 32; - WithdrawNotAvailable = 33; - ErrOverflow = 34; - SetStakingErr = 35; - SetMarketOrderErr = 36; - BalanceError = 37; - KAPPError = 38; - UnfreezeError = 39; - UndeletegateError = 40; - WithdrawError = 41; - ClaimError = 42; - BucketsExceded = 43; - AssetCantBeWiped = 44; - AssetCantAddRoles = 45; - FreezeError = 46; - ITONotActive = 47; - NFTMintStopped = 48; - RoyaltiesChangeStopped = 49; - ITOKAPPError = 50; - ITOWhiteListError = 51; - NFTMetadataChangeStopped = 52; - AlreadyExists = 53; - IteratorLimitReached = 54; - // FunctionNotFound is returned when the input specifies a function name that does not exist or is not public. - VMFunctionNotFound = 55; - // FunctionWrongSignature is returned when the wrong number of arguments is provided. - VMFunctionWrongSignature = 56; - // UserError is returned for various execution errors. - VMUserError = 57; - // OutOfGas is returned when VM execution runs out of gas. - VMOutOfGas = 58; - // AccountCollision is returned when created account already exists. - VMAccountCollision = 59; - // CallStackOverFlow is returned when stack overflow occurs. - VMCallStackOverFlow = 60; - // Execution Panicked - VMExecutionPanicked = 61; - // ExecutionFailed is returned when the execution of the specified function has failed. - VMExecutionFailed = 62; - // UpgradeFailed is returned when the upgrade of the contract has failed - VMUpgradeFailed = 63; - // SimulateFailed is returned when tx simulation fails execution - VMSimulateFailed = 64; - - Fail = 99; - } - - message KDAFee { - bytes KDA = 1 [json_name = "KDA"]; - int64 Amount = 2 [json_name = "Amount"]; - // TODO: allow spread - } - - message Raw { - uint64 Nonce = 1 [json_name = "Nonce"]; - bytes Sender = 2 [json_name = "Sender"]; - repeated TXContract Contract = 6 [json_name = "Contract"]; - int32 PermissionID = 7 [json_name = "PermissionID"]; - repeated bytes Data = 10 [json_name = "Data"]; - int64 KAppFee = 13 [json_name = "KAppFee"]; - int64 BandwidthFee = 14 [json_name = "BandwidthFee"]; - uint32 Version = 15 [json_name = "Version"]; - bytes ChainID = 16 [json_name = "ChainID"]; - KDAFee KDAFee = 17 [json_name = "KDAFee"]; - } - - message Receipt { - repeated bytes Data = 1 [json_name = "data"]; - } - - Raw RawData = 1 [json_name = "RawData"]; - repeated bytes Signature = 2 [json_name = "Signature"]; - TXResult Result = 3 [json_name = "Result"]; - TXResultCode ResultCode = 4 [json_name = "ResultCode"]; - repeated Receipt Receipts = 5 [json_name = "Receipts"]; - uint64 Block = 6 [json_name = "Block"]; - uint64 GasLimit = 7 [json_name = "GasLimit"]; - uint64 GasMultiplier = 8 [json_name = "GasMultiplier"]; -} diff --git a/packages/kos-proto/proto/klever/userAccountData.proto b/packages/kos-proto/proto/klever/userAccountData.proto deleted file mode 100644 index 1a94d4e..0000000 --- a/packages/kos-proto/proto/klever/userAccountData.proto +++ /dev/null @@ -1,43 +0,0 @@ -syntax = "proto3"; - -package proto; - -option go_package = "./;state"; - -message Key { - bytes address = 1; - int64 weight = 2; -} - -message Permission { - enum PermissionType { - Owner = 0; - User = 1; - } - int32 ID = 1; - PermissionType Type = 2; - string PermissionName = 3; - int64 Threshold = 4; - bytes Operations = 5; - repeated Key Signers = 6; -} - -message UserAccountData { - bytes Address = 1; - bytes Name = 2; - bytes RootHash = 3; - int64 Balance = 5; - int64 Allowance = 6; - uint64 Nonce = 7; - - repeated Permission Permissions = 8; - - bytes OwnerAddress = 9; - bytes CodeHash = 10; - bytes CodeMetadata = 11; -} - -message CodeEntry { - bytes Code = 1; - uint32 NumReferences = 2; -} diff --git a/packages/kos-proto/proto/tron b/packages/kos-proto/proto/tron deleted file mode 160000 index 244c835..0000000 --- a/packages/kos-proto/proto/tron +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 244c8353b9c1368049f83110c33325ace5c55bdf diff --git a/packages/kos-proto/src/lib.rs b/packages/kos-proto/src/lib.rs deleted file mode 100644 index 922f027..0000000 --- a/packages/kos-proto/src/lib.rs +++ /dev/null @@ -1,71 +0,0 @@ -pub mod options; -pub mod klever { - include!(concat!(env!("OUT_DIR"), "/klever/proto.rs")); - include!(concat!(env!("OUT_DIR"), "/klever/proto.serde.rs")); -} - -pub mod tron { - include!(concat!(env!("OUT_DIR"), "/tron/protocol.rs")); - include!(concat!(env!("OUT_DIR"), "/tron/protocol.serde.rs")); -} - -pub fn write_message(message: &M) -> Vec { - let mut buf: Vec = Vec::with_capacity(message.encoded_len()); - message.encode(&mut buf).unwrap(); - buf -} - -pub fn from_bytes(buffer: Vec) -> Result { - let mut r = M::default(); - r.merge(buffer.as_slice())?; - Ok(r) -} - -pub fn clone(msg: &M) -> Result -where - M: prost::Message + Default, -{ - let mut buf = Vec::with_capacity(msg.encoded_len()); - msg.encode(&mut buf) - .map_err(|_| prost::DecodeError::new("encode error"))?; - - let mut new_msg = M::default(); - new_msg.merge(buf.as_slice())?; - - Ok(new_msg) -} - -pub trait TypeUrl { - fn type_url() -> &'static str; -} - -pub fn pack_to_any(msg: M) -> pbjson_types::Any -where - M: prost::Message + TypeUrl, -{ - pbjson_types::Any { - type_url: M::type_url().to_owned(), - value: msg.encode_to_vec().into(), - } -} - -pub fn unpack_from_option_any(msg: &Option) -> Option -where - M: prost::Message + TypeUrl + Default, -{ - match msg { - Some(any) => unpack_from_any(any), - _ => None, - } -} - -pub fn unpack_from_any(msg: &pbjson_types::Any) -> Option -where - M: prost::Message + TypeUrl + Default, -{ - if msg.type_url == M::type_url() { - Some(M::decode(&msg.value[..]).ok()?) - } else { - None - } -} diff --git a/packages/kos-proto/src/options.rs b/packages/kos-proto/src/options.rs deleted file mode 100644 index 1b33be6..0000000 --- a/packages/kos-proto/src/options.rs +++ /dev/null @@ -1,436 +0,0 @@ -use kos_types::{error::Error, number::BigNumber}; -use serde::{Deserialize, Serialize}; - -use wasm_bindgen::prelude::*; - -#[derive(Default, Deserialize, Serialize, Clone, Debug)] -#[wasm_bindgen] -pub struct KLVOptions { - #[wasm_bindgen(skip)] - pub nonce: Option, - #[wasm_bindgen(skip)] - pub kda: Option, - #[wasm_bindgen(skip)] - pub kda_royalties: Option, - #[wasm_bindgen(skip)] - pub kda_fee: Option, - #[wasm_bindgen(skip)] - pub memo: Option>, -} - -#[wasm_bindgen] -impl KLVOptions { - #[wasm_bindgen(constructor)] - pub fn new() -> Self { - Self::default() - } - - #[wasm_bindgen(js_name = setNonce)] - pub fn set_nonce(&mut self, nonce: i64) { - self.nonce = Some(nonce as u64); - } - - #[wasm_bindgen(js_name = getNonce)] - pub fn get_nonce(&self) -> u64 { - self.nonce.unwrap_or_default() - } - - #[wasm_bindgen(js_name = addMemo)] - pub fn add_memo(&mut self, data: &str) { - let mut memo = self.memo.clone().unwrap_or_default(); - memo.push(data.to_owned()); - - self.memo = Some(memo); - } - - #[wasm_bindgen(js_name = getMemo)] - pub fn get_memo(&self) -> Vec { - self.memo - .clone() - .unwrap_or_default() - .into_iter() - .map(|m| JsValue::from_str(&m)) - .collect() - } - - #[wasm_bindgen(js_name = setKDA)] - pub fn set_kda(&mut self, kda: &str) { - self.kda = Some(kda.to_owned()); - } - - #[wasm_bindgen(js_name = getKDA)] - pub fn get_kda(&self) -> String { - self.kda.clone().unwrap_or_default() - } - - #[wasm_bindgen(js_name = setKDARoyalties)] - pub fn set_kda_royalties(&mut self, royalties: i64) { - self.kda_royalties = Some(royalties); - } - - #[wasm_bindgen(js_name = getKDARoyalties)] - pub fn get_kda_royalties(&self) -> i64 { - self.kda_royalties.unwrap_or_default() - } - - #[wasm_bindgen(js_name = setKDAFee)] - pub fn set_kda_fee(&mut self, kda: &str) { - self.kda_fee = Some(kda.to_owned()); - } - - #[wasm_bindgen(js_name = getKDAFee)] - pub fn get_kda_fee(&self) -> String { - self.kda_fee.clone().unwrap_or_default() - } -} - -#[derive(Deserialize, Serialize, Clone, Debug)] -#[wasm_bindgen] -pub struct TRXOptions { - #[wasm_bindgen(skip)] - pub token: Option, - #[wasm_bindgen(js_name = feeLimit)] - pub fee_limit: Option, - #[wasm_bindgen(skip)] - pub memo: Option, -} - -#[wasm_bindgen] -impl TRXOptions { - #[wasm_bindgen(constructor)] - pub fn new() -> Self { - Self::default() - } - - #[wasm_bindgen(js_name = setToken)] - pub fn set_token(&mut self, token: &str) { - self.token = Some(token.to_owned()); - } - - #[wasm_bindgen(js_name = getToken)] - pub fn get_token(&self) -> String { - self.token.clone().unwrap_or_default() - } - - #[wasm_bindgen(js_name = setFeeLimit)] - pub fn set_fee_limit(&mut self, fee_limit: u64) { - self.fee_limit = Some(fee_limit as i64); - } - - #[wasm_bindgen(js_name = getFeeLimit)] - pub fn get_fee_limit(&self) -> u64 { - self.fee_limit.unwrap_or_default() as u64 - } - - #[wasm_bindgen(js_name = setMemo)] - pub fn set_memo(&mut self, memo: &str) { - self.memo = Some(memo.to_owned()); - } - - #[wasm_bindgen(js_name = getMemo)] - pub fn get_memo(&self) -> String { - self.memo.clone().unwrap_or_default() - } -} - -impl Default for TRXOptions { - fn default() -> Self { - Self { - token: None, - fee_limit: Some(10_000_000), - memo: None, - } - } -} - -#[derive(Deserialize, Serialize, Default, Clone, Debug)] -#[wasm_bindgen] -pub struct ETHOptions { - #[wasm_bindgen(skip)] - pub legacy_type: Option, - #[wasm_bindgen(skip)] - pub nonce: Option, - #[wasm_bindgen(skip)] - pub chain_id: Option, - #[wasm_bindgen(skip)] - pub token: Option, - #[wasm_bindgen(skip)] - pub gas_limit: Option, - #[wasm_bindgen(skip)] - pub gas_price: Option, - #[wasm_bindgen(skip)] - pub contract_data: Option>, - #[wasm_bindgen(skip)] - pub max_fee_per_gas: Option, - #[wasm_bindgen(skip)] - pub max_priority_fee_per_gas: Option, -} - -#[wasm_bindgen] -impl ETHOptions { - #[wasm_bindgen(constructor)] - pub fn new() -> Self { - Self::default() - } - - #[wasm_bindgen(js_name = setLegacyType)] - pub fn set_legacy_type(&mut self, legacy_type: bool) { - self.legacy_type = Some(legacy_type); - } - - #[wasm_bindgen(js_name = getLegacyType)] - pub fn get_legacy_type(&self) -> bool { - self.legacy_type.unwrap_or_default() - } - - #[wasm_bindgen(js_name = setNonce)] - pub fn set_nonce(&mut self, nonce: u64) { - self.nonce = Some(nonce); - } - - #[wasm_bindgen(js_name = getNonce)] - pub fn get_nonce(&self) -> u64 { - self.nonce.unwrap_or_default() - } - - #[wasm_bindgen(js_name = setChainId)] - pub fn set_chain_id(&mut self, chain_id: u64) { - self.chain_id = Some(chain_id); - } - - #[wasm_bindgen(js_name = getChainId)] - pub fn get_chain_id(&self) -> u64 { - self.chain_id.unwrap_or_default() - } - - #[wasm_bindgen(js_name = setToken)] - pub fn set_token(&mut self, token: &str) { - self.token = Some(token.to_owned()); - } - - #[wasm_bindgen(js_name = getToken)] - pub fn get_token(&self) -> String { - self.token.clone().unwrap_or_default() - } - - #[wasm_bindgen(js_name = setGasLimit)] - pub fn set_gas_limit(&mut self, gas_limit: &str) -> Result<(), Error> { - self.gas_limit = Some(BigNumber::from_string(gas_limit)?); - Ok(()) - } - - #[wasm_bindgen(js_name = getGasLimit)] - pub fn get_gas_limit(&self) -> String { - self.gas_limit.clone().unwrap_or_default().to_string() - } - - #[wasm_bindgen(js_name = setGasPrice)] - pub fn set_gas_price(&mut self, gas_price: &str) -> Result<(), Error> { - self.gas_price = Some(BigNumber::from_string(gas_price)?); - Ok(()) - } - - #[wasm_bindgen(js_name = getGasPrice)] - pub fn get_gas_price(&self) -> String { - self.gas_price.clone().unwrap_or_default().to_string() - } - - #[wasm_bindgen(js_name = setContractData)] - pub fn set_contract_data(&mut self, contract_data: &[u8]) { - self.contract_data = Some(contract_data.to_owned()); - } - - #[wasm_bindgen(js_name = getContractData)] - pub fn get_contract_data(&self) -> Vec { - self.contract_data.clone().unwrap_or_default() - } - - #[wasm_bindgen(js_name = setMaxFeePerGas)] - pub fn set_max_fee_per_gas(&mut self, max_fee_per_gas: &str) -> Result<(), Error> { - self.max_fee_per_gas = Some(BigNumber::from_string(max_fee_per_gas)?); - Ok(()) - } - - #[wasm_bindgen(js_name = getMaxFeePerGas)] - pub fn get_max_fee_per_gas(&self) -> String { - self.max_fee_per_gas.clone().unwrap_or_default().to_string() - } - - #[wasm_bindgen(js_name = setMaxPriorityFeePerGas)] - pub fn set_max_priority_fee_per_gas( - &mut self, - max_priority_fee_per_gas: &str, - ) -> Result<(), Error> { - self.max_priority_fee_per_gas = Some(BigNumber::from_string(max_priority_fee_per_gas)?); - Ok(()) - } - - #[wasm_bindgen(js_name = getMaxPriorityFeePerGas)] - pub fn get_max_priority_fee_per_gas(&self) -> String { - self.max_priority_fee_per_gas - .clone() - .unwrap_or_default() - .to_string() - } -} - -#[derive(Deserialize, Serialize, Default, Clone, Debug)] -#[wasm_bindgen] -pub struct MATICOptions { - #[wasm_bindgen(skip)] - pub eth: ETHOptions, -} - -#[wasm_bindgen] -impl MATICOptions { - #[wasm_bindgen(constructor)] - pub fn new() -> Self { - Self::default() - } - - #[wasm_bindgen(js_name = setETHOptions)] - pub fn set_eth_options(&mut self, options: ÐOptions) { - self.eth = options.clone(); - } - - #[wasm_bindgen(js_name = getETHOptions)] - pub fn get_eth_options(&self) -> ETHOptions { - self.eth.clone() - } -} - -#[derive(Deserialize, Serialize, Default, Clone, Debug)] -#[wasm_bindgen] -pub struct BTCOptions { - /// hex magic from network (default is bitcoin mainnet) - #[wasm_bindgen(skip)] - pub network: Option, - #[wasm_bindgen(skip)] - pub sats_per_bytes: Option, - #[wasm_bindgen(skip)] - pub dust_value: Option, - #[wasm_bindgen(skip)] - pub send_all: Option, - #[wasm_bindgen(skip)] - pub change_address: Option, - #[wasm_bindgen(skip)] - pub receivers: Option>, - #[wasm_bindgen(skip)] - pub rbf: Option, -} - -#[wasm_bindgen] -impl BTCOptions { - #[wasm_bindgen(constructor)] - pub fn new() -> Self { - Self::default() - } - - #[wasm_bindgen(js_name = setNetwork)] - pub fn set_network(&mut self, network: &str) { - self.network = Some(network.to_owned()); - } - - #[wasm_bindgen(js_name = getNetwork)] - pub fn get_network(&self) -> String { - self.network.clone().unwrap_or_default() - } - - #[wasm_bindgen(js_name = setSatsPerBytes)] - pub fn set_sats_per_bytes(&mut self, sats_per_bytes: u64) { - self.sats_per_bytes = Some(sats_per_bytes); - } - - #[wasm_bindgen(js_name = getSatsPerBytes)] - pub fn get_sats_per_bytes(&self) -> u64 { - self.sats_per_bytes.unwrap_or_default() - } - - #[wasm_bindgen(js_name = setDustValue)] - pub fn set_dust_value(&mut self, dust_value: &str) -> Result<(), Error> { - self.dust_value = Some(BigNumber::from_string(dust_value)?); - Ok(()) - } - - #[wasm_bindgen(js_name = getDustValue)] - pub fn get_dust_value(&self) -> String { - self.dust_value.clone().unwrap_or_default().to_string() - } - - #[wasm_bindgen(js_name = setSendAll)] - pub fn set_send_all(&mut self, send_all: bool) { - self.send_all = Some(send_all); - } - - #[wasm_bindgen(js_name = getSendAll)] - pub fn get_send_all(&self) -> bool { - self.send_all.unwrap_or_default() - } - - #[wasm_bindgen(js_name = setChangeAddress)] - pub fn set_change_address(&mut self, change_address: &str) { - self.change_address = Some(change_address.to_owned()); - } - - #[wasm_bindgen(js_name = getChangeAddress)] - pub fn get_change_address(&self) -> String { - self.change_address.clone().unwrap_or_default() - } - - #[wasm_bindgen(js_name = addReceiver)] - pub fn addr_receiver(&mut self, addr: &str, amount: &str) -> Result<(), Error> { - let amount = BigNumber::from_string(amount)?; - let receiver = (addr.to_owned(), amount); - - let mut receivers = self.receivers.clone().unwrap_or_default(); - receivers.push(receiver); - - self.receivers = Some(receivers); - - Ok(()) - } - - #[wasm_bindgen(js_name = getReceivers)] - pub fn get_receivers(&self) -> Vec { - self.receivers - .clone() - .unwrap_or_default() - .into_iter() - .map(|(addr, amount)| { - let obj = serde_json::json!({ - "address": addr, - "amount": amount.to_string(), - }); - obj.to_string().into() - }) - .collect() - } - - #[wasm_bindgen(js_name = setRBF)] - pub fn set_rbf(&mut self, rbf: bool) { - self.rbf = Some(rbf); - } - - #[wasm_bindgen(js_name = getRBF)] - pub fn get_rbf(&self) -> bool { - self.rbf.unwrap_or_default() - } -} - -impl BTCOptions { - pub fn dust_value(&self) -> BigNumber { - self.dust_value.clone().unwrap_or(BigNumber::from(546)) - } - - pub fn sats_per_bytes(&self) -> u64 { - self.sats_per_bytes.unwrap_or(1) - } - - pub fn receivers(&self) -> Vec<(String, BigNumber)> { - self.receivers.clone().unwrap_or_default() - } - - pub fn rbf(&self) -> bool { - self.rbf.unwrap_or(false) - } -} diff --git a/packages/kos-sdk/Cargo.toml b/packages/kos-sdk/Cargo.toml deleted file mode 100644 index 32004f1..0000000 --- a/packages/kos-sdk/Cargo.toml +++ /dev/null @@ -1,58 +0,0 @@ -[package] -name = "kos-sdk" -version = { workspace = true } -authors = { workspace = true } -edition = { workspace = true } -homepage = { workspace = true } -license = { workspace = true } -repository = { workspace = true } -rust-version = { workspace = true } - -[lib] -crate-type = ["cdylib", "rlib"] - -[features] -default = ["serde"] -serde = ["bitcoin/serde"] - -[dependencies] -strum = { version = "0.25", features = ["derive"] } -serde = { workspace = true, features = ["derive"] } -serde_json = { workspace = true } -serde-wasm-bindgen = "0.5" -enum_delegate = { workspace = true } -enum_dispatch = "0.3" - -log = { workspace = true } -wasm-bindgen = { workspace = true } -base58 = { workspace = true } -bech32 = { workspace = true } -hmac = { workspace = true } -hex = { workspace = true } -rand = { workspace = true } -coins-bip39 = { workspace = true } -pem = "3" -web3 = { version = "0.19", default-features = false, features = ["http-tls", "wasm"] } -bitcoin = { version = "0.30" } -secp256k1 = { workspace = true, features = ["serde", "bitcoin_hashes"] } -rlp = "0.5" - -reqwest = { workspace = true, default-features = false, features = ["rustls-tls", "blocking", "json"] } -wasm-bindgen-futures = "0.4" - -lazy_static = { workspace = true } - -kos-types = { workspace = true, features = ["serde"] } -kos-crypto = { workspace = true } -kos-proto = { workspace = true } -kos-utils = { workspace = true } -pbjson = { workspace = true } -pbjson-types = { workspace = true } -prost = { workspace = true } - -[dev-dependencies] -tokio-test = "*" -dotenvy = "0.15.7" - -[build-dependencies] -dotenv-build = "0.1" diff --git a/packages/kos-sdk/build.rs b/packages/kos-sdk/build.rs deleted file mode 100644 index a819e0c..0000000 --- a/packages/kos-sdk/build.rs +++ /dev/null @@ -1,9 +0,0 @@ -fn main() { - let config = dotenv_build::Config { - filename: std::path::Path::new(".env.nodes"), - recursive_search: false, - fail_if_missing_dotenv: false, - }; - - dotenv_build::output(config).unwrap(); -} diff --git a/packages/kos-sdk/env.nodes.example b/packages/kos-sdk/env.nodes.example deleted file mode 100644 index 8374279..0000000 --- a/packages/kos-sdk/env.nodes.example +++ /dev/null @@ -1,7 +0,0 @@ - -# NODES -NODE_KLV= -NODE_TRX= -NODE_BTC= -NODE_ETH= -NODE_MATIC= diff --git a/packages/kos-sdk/src/chain.rs b/packages/kos-sdk/src/chain.rs deleted file mode 100644 index 1a7087b..0000000 --- a/packages/kos-sdk/src/chain.rs +++ /dev/null @@ -1,248 +0,0 @@ -use crate::chains::*; -use crate::models::{self, BroadcastResult, PathOptions, Transaction}; -use kos_crypto::keypair::KeyPair; -use kos_types::error::Error; -use kos_types::number::BigNumber; - -use lazy_static::lazy_static; -use serde::{Deserialize, Serialize}; -use std::collections::HashMap; -use strum::{EnumCount, IntoStaticStr}; - -use wasm_bindgen::prelude::*; - -macro_rules! createChains { - ($($name:ident),*) => { - #[wasm_bindgen] - #[derive(Serialize, Deserialize, PartialEq, Debug, Copy, Clone, EnumCount, IntoStaticStr)] - pub enum Chain { - $($name,)* - } - - lazy_static! { - static ref CHAIN_MAP: HashMap = { - let mut map = HashMap::new(); - $(map.insert($name::base_chain().chain_code, Chain::$name);)* - // remove the NONE chain - map.remove(&0); - map - }; - } - - impl Chain { - pub fn base_chain(&self) -> BaseChain { - match self { - $(Chain::$name => $name::base_chain(),)* - } - } - - pub fn new_keypair(&self) -> Result { - match self { - $(Chain::$name => $name::random(),)* - } - } - - pub fn keypair_from_bytes(&self, private_key: &[u8]) -> Result { - match self { - $(Chain::$name => $name::keypair_from_bytes(private_key),)* - } - } - - pub fn keypair_from_mnemonic(&self, mnemonic: &str, path: &str, password: Option) -> Result { - match self { - $(Chain::$name => $name::keypair_from_mnemonic(mnemonic, path, password),)* - } - } - - pub fn get_address_from_keypair(&self, privatekey: &KeyPair) -> Result { - match self { - $(Chain::$name => $name::get_address_from_keypair(privatekey),)* - } - } - - pub fn get_path(&self, options: &PathOptions) -> Result { - match self { - $(Chain::$name => $name::get_path(options),)* - } - } - - pub fn get_by_code(code: u8) -> Option { - CHAIN_MAP.get(&code).cloned() - } - - pub fn get_chains() -> HashMap { - CHAIN_MAP.clone() - } - - /// Sign digest data with the private key. - pub fn sign_digest(&self, digest: &[u8], keypair: &KeyPair) -> Result, Error> { - match self { - $(Chain::$name => $name::sign_digest(digest, keypair),)* - } - } - - /// Verify Message signature - pub fn verify_digest(&self, digest: &[u8], signature: &[u8], address: &str) -> Result { - match self { - $(Chain::$name => $name::verify_digest(digest, signature, address),)* - } - } - - /// Hash and Sign data with the private key. - pub fn sign(&self, data: Transaction, keypair: &KeyPair) -> Result { - match self { - $(Chain::$name => $name::sign(data, keypair),)* - } - } - - /// Append prefix and hash the message - pub fn message_hash(&self, message: &[u8]) -> Result, Error> { - match self { - $(Chain::$name => $name::message_hash(message),)* - } - } - - /// Sign Message with the private key. - pub fn sign_message(&self, message: &[u8], keypair: &KeyPair) -> Result, Error> { - match self { - $(Chain::$name => $name::sign_message(message, keypair),)* - } - } - - /// Verify Message signature - pub fn verify_message_signature(&self, message: &[u8], signature: &[u8], address: &str) -> Result { - match self { - $(Chain::$name => $name::verify_message_signature(message, signature, address),)* - } - } - - /// Get balance of address and token - /// If token is None, it will return balance of native token - /// If token is Some, it will return balance of token - /// If node_url is None, it will use default node url - pub async fn get_balance(&self, address: &str, token: Option, node_url: Option) -> Result { - match self { - $(Chain::$name => $name::get_balance(address, token, node_url).await,)* - } - } - - pub async fn send( - &self, - sender: String, - receiver: String, - amount: BigNumber, - options: Option, - node_url: Option, - ) -> Result { - match self { - $(Chain::$name => $name::send(sender, receiver, amount, options, node_url).await,)* - } - } - - pub async fn broadcast(&self, data: Transaction, node_url: Option) -> Result { - match self { - $(Chain::$name => $name::broadcast(data, node_url).await,)* - } - } - - /// validate chain address format with options - pub fn validate_address(&self, address: &str, option: Option) -> Result { - match self { - $(Chain::$name => $name::validate_address(address, option),)* - } - } - } - } -} - -createChains!(NONE, KLV, TRX, BTC, ETH, MATIC); - -// pub enum Chain { -// NONE, // 0 -// TRX, -// BTC, -// ETH, -// XRP, -// LTC, // 5 -// XLM, -// COSMOS, -// EOS, -// ONT, -// KLAY, // 10 -// DASH, -// DOGE, -// IOTX, -// ONE, -// SYS, // 15 -// DGB, -// BNB, -// BCH, -// VET, -// ADA, // 20 -// DOT, -// XMR, -// XTZ, -// EGLD, -// NEO, // 25 -// BSC, -// KSM, -// MATIC, -// REEF, -// HT, // 30 -// ICP, -// MOVR, -// TKLV, // 33 -// GLMR, -// SDN, // 35 -// ASTR, -// SYSNEVM, -// KLV, -// AVAX, -// SOL, // 40 -// KAR, -// AIR, -// FLOW, -// KILT, -// CUDOS, //45 -// ACA, -// CFG, -// TIA, -// AURA, -// APT, //50 -// } - -#[wasm_bindgen] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub struct BaseChain { - #[wasm_bindgen(skip)] - pub name: &'static str, - #[wasm_bindgen(skip)] - pub symbol: &'static str, - #[wasm_bindgen(skip)] - pub precision: u8, - #[wasm_bindgen(skip)] - pub chain_code: u8, -} - -#[wasm_bindgen] -impl BaseChain { - #[wasm_bindgen(js_name = getName)] - pub fn get_name(&self) -> String { - self.name.to_string() - } - - #[wasm_bindgen(js_name = getSymbol)] - pub fn get_symbol(&self) -> String { - self.symbol.to_string() - } - - #[wasm_bindgen(js_name = getPrecision)] - pub fn get_precision(&self) -> u8 { - self.precision - } - - #[wasm_bindgen(js_name = getChainCode)] - pub fn get_chain_code(&self) -> u8 { - self.chain_code - } -} diff --git a/packages/kos-sdk/src/chains/bitcoin/mod.rs b/packages/kos-sdk/src/chains/bitcoin/mod.rs deleted file mode 100644 index a32bac6..0000000 --- a/packages/kos-sdk/src/chains/bitcoin/mod.rs +++ /dev/null @@ -1,551 +0,0 @@ -mod requests; -pub mod transaction; - -use crate::chain::{BaseChain, Chain}; -use crate::models::{self, BroadcastResult, PathOptions, Transaction, TransactionRaw}; - -use kos_crypto::{keypair::KeyPair, secp256k1::Secp256k1KeyPair}; -use kos_proto::options::BTCOptions; -use kos_types::{error::Error, hash::Hash, number::BigNumber}; - -use bitcoin::{network::constants::Magic, Address, Network}; - -use std::{ops::Add, str::FromStr}; -use wasm_bindgen::prelude::*; - -#[derive(Debug, Copy, Clone)] -#[wasm_bindgen] -pub struct BTC {} - -pub const SIGN_PREFIX: &[u8; 25] = b"\x18Bitcoin Signed Message:\n"; -pub const BIP44_PATH: u32 = 0; - -pub const BASE_CHAIN: BaseChain = BaseChain { - name: "Bitcoin", - symbol: "BTC", - precision: 8, - chain_code: 2, -}; - -const DEFAULT_NETWORK: Network = Network::Bitcoin; - -pub fn get_network(option: &BTCOptions) -> Result { - match option.network.clone() { - Some(hex_magic) => { - let magic_bytes = hex::decode(hex_magic)?; - if magic_bytes.len() != 4 { - return Err(Error::UnsupportedChain("invalid magic for network length")); - } - - let array: [u8; 4] = [ - magic_bytes[0], - magic_bytes[1], - magic_bytes[2], - magic_bytes[3], - ]; - let magic = Magic::from_bytes(array); - - Network::from_magic(magic).ok_or(Error::UnsupportedChain("invalid magic for network")) - } - _ => Ok(DEFAULT_NETWORK), - } -} - -fn get_options(options: Option) -> BTCOptions { - match options.and_then(|opt| opt.data) { - Some(crate::models::Options::Bitcoin(op)) => op, - _ => BTCOptions::default(), - } -} - -#[wasm_bindgen] -impl BTC { - #[wasm_bindgen(js_name = "baseChain")] - pub fn base_chain() -> BaseChain { - BASE_CHAIN - } - - #[wasm_bindgen(js_name = "random")] - pub fn random() -> Result { - let mut rng = rand::thread_rng(); - let kp = Secp256k1KeyPair::random(&mut rng).set_compressed(true); - Ok(KeyPair::new_secp256k1(kp)) - } - - #[wasm_bindgen(js_name = "keypairFromBytes")] - pub fn keypair_from_bytes(private_key: &[u8]) -> Result { - // copy to fixed length array - let mut pk_slice = [0u8; 32]; - pk_slice.copy_from_slice(private_key); - - let kp = Secp256k1KeyPair::new(pk_slice).set_compressed(true); - Ok(KeyPair::new_secp256k1(kp)) - } - - #[wasm_bindgen(js_name = "keypairFromMnemonic")] - pub fn keypair_from_mnemonic( - mnemonic: &str, - path: &str, - password: Option, - ) -> Result { - let kp = Secp256k1KeyPair::new_from_mnemonic_phrase_with_path( - mnemonic, - path, - password.as_deref(), - )? - .set_compressed(true); - - Ok(KeyPair::new_secp256k1(kp)) - } - - #[wasm_bindgen(js_name = "getAddressFromKeyPair")] - pub fn get_address_from_keypair(kp: &KeyPair) -> Result { - let address = BTC::get_address(kp, DEFAULT_NETWORK)?; - Ok(address.to_string()) - } - - #[wasm_bindgen(js_name = "getPath")] - pub fn get_path(options: &PathOptions) -> Result { - Ok(format!("m/84'/{}'/0'/0/{}", BIP44_PATH, options.index)) - } - - #[wasm_bindgen(js_name = "signDigest")] - /// Sign digest data with the private key. - pub fn sign_digest(digest: &[u8], keypair: &KeyPair) -> Result, Error> { - let raw = keypair.sign_digest(digest); - Ok(raw) - } - - #[wasm_bindgen(js_name = "verifyDigest")] - /// Verify Message signature - pub fn verify_digest(_digest: &[u8], _signature: &[u8], _address: &str) -> Result { - todo!() - } - - #[wasm_bindgen(js_name = "sign")] - /// Hash and Sign data with the private key. - /// P2WPKH address is used as the signature address. - pub fn sign(tx: Transaction, keypair: &KeyPair) -> Result { - match tx.data { - // get bitcoin transaction from raw - Some(TransactionRaw::Bitcoin(btc_tx)) => { - let mut btc_tx = btc_tx; - - // sign tx - btc_tx.sign(keypair)?; - - // redeem script - btc_tx.finalize()?; - - let signature = btc_tx.get_signature().unwrap_or("".to_string()); - - Ok(Transaction { - hash: btc_tx.txid_hash()?, - data: Some(TransactionRaw::Bitcoin(btc_tx)), - signature: Some(signature), - ..tx - }) - } - _ => Err(Error::InvalidMessage( - "not a bitcoin transaction".to_string(), - )), - } - } - - #[wasm_bindgen(js_name = "hash")] - /// hash digest - pub fn hash(message: &[u8]) -> Result, Error> { - let digest = kos_crypto::hash::keccak256(message); - Ok(digest.to_vec()) - } - - #[wasm_bindgen(js_name = "messageHash")] - /// Append prefix and hash the message - pub fn message_hash(message: &[u8]) -> Result, Error> { - let to_sign = [SIGN_PREFIX, message.len().to_string().as_bytes(), message].concat(); - - BTC::hash(&to_sign) - } - - #[wasm_bindgen(js_name = "signMessage")] - /// Sign Message with the private key. - pub fn sign_message(message: &[u8], keypair: &KeyPair) -> Result, Error> { - let m = BTC::message_hash(message)?; - BTC::sign_digest(&m, keypair) - } - - #[wasm_bindgen(js_name = "verifyMessageSignature")] - /// Verify Message signature - pub fn verify_message_signature( - message: &[u8], - signature: &[u8], - address: &str, - ) -> Result { - let m = BTC::message_hash(message)?; - BTC::verify_digest(&m, signature, address) - } - - #[wasm_bindgen(js_name = "getBalance")] - pub async fn get_balance( - address: &str, - _token: Option, - node_url: Option, - ) -> Result { - let node = node_url.unwrap_or_else(|| crate::utils::get_node_url("BTC")); - requests::balance(&node, address, 0).await - } - - fn get_receiver( - receiver: String, - amount: &BigNumber, - network: Network, - ) -> Result<(Address, BigNumber), Error> { - let addr = - Address::from_str(&receiver).map_err(|e| Error::InvalidAddress(e.to_string()))?; - Ok(( - addr.require_network(network) - .map_err(|e| Error::InvalidAddress(e.to_string()))?, - amount.clone(), - )) - } - - pub async fn send( - sender: String, - receiver: String, - amount: BigNumber, - options: Option, - node_url: Option, - ) -> Result { - let node = node_url.unwrap_or_else(|| crate::utils::get_node_url("BTC")); - let options = get_options(options); - - let network = get_network(&options)?; - - let mut total_amount = amount.clone(); - - let mut receivers: Vec<(Address, BigNumber)> = Vec::new(); - if !receiver.is_empty() { - receivers.push(Self::get_receiver(receiver, &amount, network)?); - } else { - // check if amount is provided without receiver - if !amount.is_zero() { - return Err(Error::InvalidTransaction(format!( - "receiver is required for amount {}", - amount.to_string() - ))); - } - } - // add outputs from options - for output in options.receivers() { - receivers.push(Self::get_receiver(output.0, &output.1, network)?); - total_amount = total_amount.add(output.1); - } - - let sender_address = Address::from_str(&sender.clone()) - .map_err(|e| Error::InvalidAddress(e.to_string()))? - .require_network(network) - .map_err(|e| Error::InvalidAddress(e.to_string()))?; - - let change_address = - Address::from_str(&options.change_address.clone().unwrap_or(sender.clone())) - .map_err(|e| Error::InvalidAddress(e.to_string()))? - .require_network(network) - .map_err(|e| Error::InvalidAddress(e.to_string()))?; - - // get utoxs - let sender_utxos = - requests::select_utxos(&node, &sender, &total_amount, 1, 1, 10, false, false).await?; - - // create transaction - let tx = transaction::create_transaction( - sender_address, - sender_utxos, - receivers, - change_address, - &options, - )?; - - Ok(crate::models::Transaction { - chain: Chain::BTC, - sender, - hash: Hash::new(&tx.txid().to_string())?, - data: Some(TransactionRaw::Bitcoin(tx)), - signature: None, - }) - } - - #[wasm_bindgen(js_name = "broadcast")] - pub async fn broadcast( - tx: crate::models::Transaction, - node_url: Option, - ) -> Result { - let node = node_url.unwrap_or_else(|| crate::utils::get_node_url("BTC")); - - match &tx.data { - Some(TransactionRaw::Bitcoin(btc_tx)) => { - let txid = requests::broadcast(&node, &btc_tx.btc_serialize_hex()).await?; - // check if tx hash is same as txid - if btc_tx.txid() != txid { - return Err(Error::InvalidTransaction(format!( - "invalid transaction hash: {}/{}", - txid, - btc_tx.txid() - ))); - } - Ok(BroadcastResult { tx }) - } - _ => Err(Error::InvalidTransaction( - "not a bitcoin transaction".to_string(), - )), - } - } - - #[wasm_bindgen(js_name = "serializeTx")] - pub fn serialize_tx(tx: Transaction) -> Result { - match tx.data { - Some(TransactionRaw::Bitcoin(btc_tx)) => Ok(btc_tx.btc_serialize_hex()), - _ => Err(Error::InvalidTransaction( - "not a bitcoin transaction".to_string(), - )), - } - } - - fn decode_magic(hex_magic: String) -> Result { - let magic_bytes = hex::decode(hex_magic)?; - if magic_bytes.len() != 4 { - return Err(Error::UnsupportedChain("invalid magic for network length")); - } - - let array: [u8; 4] = [ - magic_bytes[0], - magic_bytes[1], - magic_bytes[2], - magic_bytes[3], - ]; - let magic = Magic::from_bytes(array); - - let network = Network::from_magic(magic) - .ok_or(Error::UnsupportedChain("invalid magic for network"))?; - - Ok(network) - } - - #[wasm_bindgen(js_name = "validateAddress")] - pub fn validate_address( - address: &str, - options: Option, - ) -> Result { - let addr = Address::from_str(address); - if addr.is_err() { - return Ok(false); - } - - let addr = addr.unwrap(); - - // get network from options - let network = match options { - Some(opt) => match opt.network { - Some(hex_magic) => BTC::decode_magic(hex_magic)?, - _ => DEFAULT_NETWORK, - }, - _ => DEFAULT_NETWORK, - }; - - Ok(addr.is_valid_for_network(network)) - } -} - -impl BTC { - #[inline] - pub fn get_address(kp: &KeyPair, network: Network) -> Result { - let pubkey = BTC::get_pubkey(&kp.public_key())?; - - Address::p2wpkh(&pubkey, network).map_err(|e| Error::InvalidAddress(e.to_string())) - } - - #[inline] - pub fn get_pubkey(data: &[u8]) -> Result { - bitcoin::PublicKey::from_slice(data) - .map_err(|e| Error::InvalidPublicKey(format!("Invalid public key: {}", e))) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use dotenvy; - use hex::{FromHex, ToHex}; - use kos_types::Bytes32; - use std::sync::Once; - - const DEFAULT_PRIVATE_KEY: &str = - "4604b4b710fe91f584fff084e1a9159fe4f8408fff380596a604948474ce4fa3"; - const DEFAULT_ADDRESS: &str = "bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu"; - const DEFAULT_MNEMONIC: &str = - "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"; - - static _INIT: Once = Once::new(); - - fn _init() { - _INIT.call_once(|| { - dotenvy::from_filename(".env.nodes").ok(); - }); - } - - fn get_default_secret() -> KeyPair { - let b = Bytes32::from_hex(DEFAULT_PRIVATE_KEY).unwrap(); - let kp = Secp256k1KeyPair::new(b.into()).set_compressed(true); - KeyPair::new_secp256k1(kp) - } - - #[test] - fn test_address_from_private_key() { - let address = BTC::get_address_from_keypair(&get_default_secret()).unwrap(); - - assert_eq!(DEFAULT_ADDRESS, address); - } - - #[test] - fn test_address_from_private_key_bytes() { - // convert hex to [u8] - let pk_bytes = Bytes32::from_hex(DEFAULT_PRIVATE_KEY).unwrap(); - let kp = BTC::keypair_from_bytes(pk_bytes.as_ref()).unwrap(); - let address = BTC::get_address_from_keypair(&kp).unwrap(); - - assert_eq!(DEFAULT_ADDRESS, address); - } - - #[test] - fn test_validate_bip44() { - let v = vec![ - (0, "bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu"), - (1, "bc1qnjg0jd8228aq7egyzacy8cys3knf9xvrerkf9g"), - (2, "bc1qp59yckz4ae5c4efgw2s5wfyvrz0ala7rgvuz8z"), - (3, "bc1qgl5vlg0zdl7yvprgxj9fevsc6q6x5dmcyk3cn3"), - (4, "bc1qm97vqzgj934vnaq9s53ynkyf9dgr05rargr04n"), - ]; - - for (index, expected_addr) in v { - let path = BTC::get_path(&PathOptions::new(index)).unwrap(); - let kp = BTC::keypair_from_mnemonic(DEFAULT_MNEMONIC, &path, None).unwrap(); - let addr = BTC::get_address_from_keypair(&kp).unwrap(); - - assert_eq!(expected_addr, addr); - } - } - - #[test] - fn test_get_balance() { - let balance = tokio_test::block_on(BTC::get_balance( - "12cbQLTFMXRnSzktFkuoG3eHoMeFtpTu3S", - None, - None, - )) - .unwrap(); - - assert!(balance.to_i64() > 100); - } - - #[test] - fn test_send_and_sign() { - let btc_address_sender = "tb1q09hyefvam4x5hrnnavx6sphv797f0l5xcqt7cl"; - let btc_address_receiver = "tb1qgg29y2z8xsvav65j5kx2pztqff4g2ctn6a4x0u"; - - let testnet_magic = "0b110907"; - - let option = models::SendOptions { - data: Some(models::Options::Bitcoin(BTCOptions { - sats_per_bytes: Some(1), - network: Some(testnet_magic.to_string()), - ..Default::default() - })), - }; - - let send_tx = tokio_test::block_on(BTC::send( - btc_address_sender.to_string(), - btc_address_receiver.to_string(), - BigNumber::from(1000), - Some(option), - None, - )) - .unwrap(); - - let sign_tx = BTC::sign(send_tx, &get_default_secret()).unwrap(); - - let tx = match sign_tx.data.unwrap() { - TransactionRaw::Bitcoin(tx) => tx, - _ => panic!("invalid transaction"), - }; - - assert!(tx.total_send.to_u64() == 1000); - assert!(tx.fee.to_u64() == 226); - // let _ = tokio_test::block_on(BTC::broadcast(sign_tx, Some(node.to_string()))).unwrap(); - } - - #[test] - fn test_validate_address_ok() { - let list = [ - "bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu", - "bc1qnjg0jd8228aq7egyzacy8cys3knf9xvrerkf9g", - "1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2", - "3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy", - "bc1qgl5vlg0zdl7yvprgxj9fevsc6q6x5dmcyk3cn3", - ]; - - for addr in list.iter() { - let valid = BTC::validate_address(addr, None).unwrap(); - assert_eq!(valid, true, "address {} should be valid", addr); - } - - // network mainnet - for addr in list.iter() { - let valid = BTC::validate_address( - addr, - Some(models::AddressOptions::new( - Some(Network::Bitcoin.magic().encode_hex()), - None, - None, - )), - ) - .unwrap(); - assert_eq!(valid, true, "address {} should be valid", addr); - } - } - - #[test] - fn test_validate_address_fail() { - let list = [ - "bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu", - "bc1qnjg0jd8228aq7egyzacy8cys3knf9xvrerkf9g", - "1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2", - "3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy", - "bc1qgl5vlg0zdl7yvprgxj9fevsc6q6x5dmcyk3cn3", - ]; - - // wrong network - for addr in list.iter() { - let valid = BTC::validate_address( - addr, - Some(models::AddressOptions::new( - Some(Network::Testnet.magic().encode_hex()), - None, - None, - )), - ) - .unwrap(); - assert_eq!(valid, false, "address {} should be invalid", addr); - } - - let list = [ - "qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu", // no prefix - "ltc1qz9vvmr3q2s6m4drd9y9plzs0l38u9z4p96wwxz", // wrong prefix - "BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2", - "1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN", - ]; - - for addr in list.iter() { - let valid = BTC::validate_address(addr, None).unwrap(); - assert_eq!(valid, false, "address {} should be invalid", addr); - } - } -} diff --git a/packages/kos-sdk/src/chains/bitcoin/requests.rs b/packages/kos-sdk/src/chains/bitcoin/requests.rs deleted file mode 100644 index 82cb3d1..0000000 --- a/packages/kos-sdk/src/chains/bitcoin/requests.rs +++ /dev/null @@ -1,193 +0,0 @@ -use super::transaction::{estimate_fee, UTXO}; -use crate::utils; - -use kos_types::{error::Error, number::BigNumber}; -use std::ops::Add; - -pub async fn fetch_utxos( - node_url: &str, - address: &str, - confirmations: u64, -) -> Result, Error> { - let url = format!("{}/api/v2/utxo/{}", node_url, address); - let mut list: Vec = utils::http_get_auth::>(url) - .await? - .into_iter() - .filter(|utxo| utxo.confirmations >= confirmations) - .collect(); - - list.sort_by_key(|a| a.amount()); - - Ok(list) -} - -// Fetch UTXOs and sum up the total amount. -pub async fn balance( - node_url: &str, - address: &str, - confirmations: u64, -) -> Result { - let unspent = fetch_utxos(node_url, address, confirmations) - .await? - .into_iter() - .map(|utxo| BigNumber::from_string(&utxo.value).unwrap_or_default()) - .reduce(|a, b| a.add(b)); - - Ok(unspent.unwrap_or_default()) -} - -// Fetch UTXOs from Bitcoin node and select UTXOs to cover the desired amount. -#[allow(clippy::too_many_arguments)] -pub async fn select_utxos( - node_url: &str, - address: &str, - desired_amount: &BigNumber, - outputs: u64, - confirmations: u64, - sats_per_bytes: u64, - spend_biggest_first: bool, - spend_all: bool, -) -> Result, Error> { - let mut unspent: Vec = fetch_utxos(node_url, address, confirmations).await?; - - if spend_all { - return Ok(unspent); - } - - // min TX Value defined by dust - let min_value = BigNumber::from(148 * sats_per_bytes); - - let tx_fee_min = estimate_fee(1, outputs, sats_per_bytes).add(desired_amount.clone()); - let tx_fee_max = estimate_fee(1, outputs + 1, sats_per_bytes).add(desired_amount.clone()); - - // check if there is a UTXO that better match the desired amount - for utxo in &unspent { - let value = utxo.amount(); - - // if utxo match the desired amount, stop selecting UTXOs. - // todo!("revisit this logic") - if value.ge(&tx_fee_min) && value.le(&tx_fee_max) { - return Ok(vec![utxo.clone()]); - } - } - - // accumulate UTXOs until we have enough value - // reverse order to reduce the number of UTXOs - if spend_biggest_first { - unspent.sort_by_key(|b| std::cmp::Reverse(b.amount())) - } - - // Vector to hold selected UTXOs. - let mut selected_utxos = Vec::new(); - // Variable to keep track of the total amount in the selected UTXOs. - let mut total_amount = BigNumber::from(0); - - for utxo in unspent { - let value = BigNumber::from_string(&utxo.value)?; - - // Ignore dust values - if value.lt(&min_value) { - continue; - } - - // Add the value of the UTXO to the total amount. - total_amount = total_amount.add(value); - - // Add the UTXO to the selected UTXOs. - selected_utxos.push(utxo); - - // if we have select utxos with enough value, stop looping (but keep processing utxos for a better match) - if total_amount.ge(&tx_fee_min) { - break; - } - } - - Ok(selected_utxos) -} - -// Broadcast raw hex transaction to Bitcoin node. -pub async fn broadcast(node_url: &str, hex_tx: &str) -> Result { - let url = format!("{}/api/v2/sendtx/", node_url); - let data = hex_tx.as_bytes().to_vec(); - - let result = utils::http_post_auth::(url, &data).await; - - let result = result?; - - if let Some(err) = result.get("error") { - if let Some(err) = err.as_str() { - return Err(Error::ReqwestError(err.to_string())); - } - } - - if let Some(txid_value) = result.get("result") { - if let Some(txid) = txid_value.as_str() { - return Ok(txid.to_string()); - } else { - return Err(Error::ReqwestError("txid is not a string".to_string())); - } - } - - Err(Error::ReqwestError("missing txid".to_string())) -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_select_utxos() { - let node = "https://bitcoin.explorer.klever.io"; - - let amount = BigNumber::from_string("20000000").unwrap(); - let list = tokio_test::block_on(select_utxos( - node, - "12cbQLTFMXRnSzktFkuoG3eHoMeFtpTu3S", - &amount, - 0, - 0, - 10, - false, - false, - )) - .unwrap(); - - // computer total - let total = list - .iter() - .map(|utxo| BigNumber::from_string(&utxo.value).unwrap_or_default()) - .reduce(|a, b| a.add(b)) - .unwrap_or_default(); - - println!("total: {:?}", total); - - assert!(total.ge(&amount)); - } - - #[test] - fn test_spend_all() { - let node = "https://bitcoin.explorer.klever.io"; - - let selected = tokio_test::block_on(select_utxos( - node, - "12cbQLTFMXRnSzktFkuoG3eHoMeFtpTu3S", - &BigNumber::from(0), - 0, - 0, - 10, - false, - true, - )) - .unwrap(); - - // get all utxos - let list = tokio_test::block_on(fetch_utxos( - "https://bitcoin.explorer.klever.io", - "12cbQLTFMXRnSzktFkuoG3eHoMeFtpTu3S", - 0, - )) - .unwrap(); - - assert_eq!(selected.len(), list.len()); - } -} diff --git a/packages/kos-sdk/src/chains/bitcoin/transaction.rs b/packages/kos-sdk/src/chains/bitcoin/transaction.rs deleted file mode 100644 index 5024ca4..0000000 --- a/packages/kos-sdk/src/chains/bitcoin/transaction.rs +++ /dev/null @@ -1,265 +0,0 @@ -use super::BTC; - -use kos_crypto::keypair::KeyPair; -use kos_proto::options; -use kos_types::{error::Error, hash::Hash, number::BigNumber}; - -use bitcoin::{ - absolute::LockTime, - blockdata::transaction::{Transaction, TxIn, TxOut}, - ecdsa, - psbt::{self, PartiallySignedTransaction}, - sighash, Address, OutPoint, Sequence, -}; - -use serde::{Deserialize, Serialize}; -use std::{ - ops::{Add, Div, Sub}, - str::FromStr, -}; - -// Structure to hold Transaction data. -#[derive(Serialize, Debug, Clone)] -pub struct BTCTransaction { - pub sender_address: Address, - pub tx: PartiallySignedTransaction, - pub total_inputs: BigNumber, - pub total_outputs: BigNumber, - pub total_send: BigNumber, - pub change_amount: BigNumber, - pub change_address: Address, - pub fee: BigNumber, - pub sats_per_bytes: BigNumber, -} - -impl BTCTransaction { - pub fn txid(&self) -> String { - let btc_tx = self.tx.clone().extract_tx(); - btc_tx.txid().to_string() - } - - pub fn txid_hash(&self) -> Result { - Hash::new(&self.txid()) - } - - pub fn btc_serialize_hex(&self) -> String { - bitcoin::consensus::encode::serialize_hex(&self.tx.clone().extract_tx()) - } - - pub fn get_signature(&self) -> Result { - let sig = self.tx.clone().extract_tx().wtxid(); - Ok(sig.to_string()) - } - - pub fn finalize(&mut self) -> Result<(), Error> { - for inp_idx in 0..self.tx.inputs.len() { - // todo!("multi sig and redeem type"); - let script_witness = { - match self.tx.inputs[inp_idx].partial_sigs.first_key_value() { - Some((pubkey, sig)) => { - let mut script_witness = bitcoin::Witness::new(); - script_witness.push(sig.to_vec()); - script_witness.push(pubkey.to_bytes()); - script_witness - } - _ => return Err(Error::TransportError("No signature found".to_string())), - } - }; - self.tx.inputs[inp_idx].final_script_witness = Some(script_witness); - } - - Ok(()) - } - - pub fn sign(&mut self, keypair: &KeyPair) -> Result<(), Error> { - // get BIP143 hasher - let mut cache = sighash::SighashCache::new(&self.tx.unsigned_tx); - let secp = &secp256k1::Secp256k1::new(); - let sk = bitcoin::secp256k1::SecretKey::from_slice(&keypair.secret_key()) - .map_err(|_| Error::InvalidSignature("private key error"))?; - let pk = BTC::get_pubkey(&keypair.public_key())?; - - // sign inputs - for inp_idx in 0..self.tx.inputs.len() { - // compute sighash - let msg_sighash_ty_res = self.tx.sighash_ecdsa(inp_idx, &mut cache); - - // Only return the error if we have a secret key to sign this input. - let (msg, sighash_ty) = match msg_sighash_ty_res { - Err(e) => return Err(Error::InvalidTransaction(format!("{:?}", e))), - Ok((msg, sighash_ty)) => (msg, sighash_ty), - }; - - // sign - let sig = ecdsa::Signature { - sig: secp.sign_ecdsa(&msg, &sk), - hash_ty: sighash_ty, - }; - - // insert signature - self.tx.inputs[inp_idx].partial_sigs.insert(pk, sig); - } - - Ok(()) - } -} - -pub fn create_transaction( - sender_address: Address, - sender_utxos: Vec, - receivers: Vec<(Address, BigNumber)>, - change_address: Address, - options: &options::BTCOptions, -) -> Result { - let total_send = receivers - .iter() - .fold(BigNumber::from(0), |acc, (_, amount)| { - acc.add(amount.clone()) - }); - - let mut total_inputs = BigNumber::from(0); - let mut total_outputs = BigNumber::from(0); - - let mut tx_inputs: Vec = Vec::new(); - let sequence = if options.rbf() { - Sequence::ENABLE_RBF_NO_LOCKTIME - } else { - Sequence::MAX - }; - - let spk = sender_address.script_pubkey(); - let mut psbt_input = Vec::new(); - for utxo in sender_utxos { - // check for RBF flag - tx_inputs.push(TxIn { - previous_output: utxo.to_outpoint()?, - sequence, - ..Default::default() - }); - - let amount = BigNumber::from_str(&utxo.value)?; - total_inputs = total_inputs.add(amount.clone()); - - // todo!("allow non segwit inputs") - psbt_input.push(psbt::Input { - witness_utxo: Some(TxOut { - script_pubkey: spk.clone(), - value: amount.to_u64(), - }), - non_witness_utxo: None, - ..Default::default() - }); - } - - let sats_per_bytes = options.sats_per_bytes(); - - let mut tx_outputs: Vec = Vec::new(); - - // Output to receiver - for (receiver, amount) in receivers { - tx_outputs.push(TxOut { - script_pubkey: receiver.script_pubkey(), - value: amount.to_u64(), - }); - - total_outputs = total_outputs.add(amount); - } - - let change_output = if total_inputs.gt(&total_send) { 1 } else { 0 }; - - // estimate fee - let fee = estimate_fee( - tx_inputs.len() as u64, - tx_outputs.len() as u64 + change_output, - sats_per_bytes, - ); - - let send_plus_estimated_fee = total_send.clone().add(fee.clone()); - - // error if not enough funds to cover fee and amount send - if total_inputs.lt(&send_plus_estimated_fee) { - return Err(Error::TransportError( - format!( - "Not enough funds to cover fee and amount send. Total inputs: {}, Total send: {}, Fee: {}", - total_inputs.to_string(), - total_send.to_string(), - fee.to_string(), - ))); - } - - // Output to self (change) if applicable - // todo add fee calculation - let change_amount = total_inputs.clone().sub(send_plus_estimated_fee); - // compute dust value if not provided - let dust_value = options.dust_value(); - if change_amount.gt(&dust_value) { - tx_outputs.push(TxOut { - script_pubkey: change_address.script_pubkey(), - value: change_amount.clone().to_u64(), - }); - - total_outputs = total_outputs.add(change_amount.clone()); - } - - let fee = total_inputs.clone().sub(total_outputs.clone()); - let size = estimate_size(tx_inputs.len() as u64, tx_outputs.len() as u64); - let sats_per_bytes = fee.clone().div(BigNumber::from(size)); - - // Build Transaction - let mut tx = PartiallySignedTransaction::from_unsigned_tx(Transaction { - version: 2, - lock_time: LockTime::ZERO, - input: tx_inputs, - output: tx_outputs, - }) - .map_err(|e| Error::InvalidTransaction(format!("creating psbt: {}", e)))?; - - // update inputs - tx.inputs = psbt_input; - - Ok(BTCTransaction { - sender_address, - tx, - total_inputs, - total_outputs, - total_send, - fee, - change_amount, - change_address, - sats_per_bytes, - }) -} - -// Structure to hold UTXO data. -#[allow(clippy::upper_case_acronyms)] -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct UTXO { - pub txid: String, - pub vout: u32, - pub value: String, - #[serde(default)] - pub height: u64, - pub confirmations: u64, -} - -impl UTXO { - pub fn to_outpoint(&self) -> Result { - let txid = bitcoin::Txid::from_str(&self.txid) - .map_err(|e| Error::InvalidTransaction(e.to_string()))?; - let outpoint = OutPoint::new(txid, self.vout); - Ok(outpoint) - } - - pub fn amount(&self) -> BigNumber { - BigNumber::from_string(&self.value).unwrap_or_default() - } -} - -pub fn estimate_size(tx_in: u64, tx_out: u64) -> u64 { - (148 * tx_in) + (34 * tx_out + 10) -} - -// EstimateFee based on Transaction size -pub fn estimate_fee(tx_in: u64, tx_out: u64, sats_per_bytes: u64) -> BigNumber { - BigNumber::from(estimate_size(tx_in, tx_out) * sats_per_bytes) -} diff --git a/packages/kos-sdk/src/chains/default/mod.rs b/packages/kos-sdk/src/chains/default/mod.rs deleted file mode 100644 index 42cc590..0000000 --- a/packages/kos-sdk/src/chains/default/mod.rs +++ /dev/null @@ -1,133 +0,0 @@ -use crate::chain::BaseChain; -use crate::models::{self, BroadcastResult, PathOptions, Transaction}; -use kos_crypto::keypair::KeyPair; -use kos_types::error::Error; -use kos_types::number::BigNumber; - -use wasm_bindgen::prelude::*; - -#[derive(Debug, Copy, Clone)] -#[wasm_bindgen] -pub struct NONE; -pub const BASE_CHAIN: BaseChain = BaseChain { - name: "None", - symbol: "NONE", - precision: 0, - chain_code: 0, -}; - -#[wasm_bindgen] -impl NONE { - #[wasm_bindgen(js_name = "baseChain")] - pub fn base_chain() -> BaseChain { - BASE_CHAIN - } - - #[wasm_bindgen(js_name = "random")] - pub fn random() -> Result { - Err(Error::UnsupportedChain("NONE")) - } - - #[wasm_bindgen(js_name = "keypairFromBytes")] - pub fn keypair_from_bytes(_private_key: &[u8]) -> Result { - Err(Error::UnsupportedChain("NONE")) - } - - #[wasm_bindgen(js_name = "keypairFromMnemonic")] - pub fn keypair_from_mnemonic( - _mnemonic: &str, - _path: &str, - _password: Option, - ) -> Result { - Ok(KeyPair::new_default()) - } - - #[wasm_bindgen(js_name = "getAddressFromKeyPair")] - pub fn get_address_from_keypair(_private_key: &KeyPair) -> Result { - Ok("NONE".into()) - } - - #[wasm_bindgen(js_name = "getPath")] - pub fn get_path(_options: &PathOptions) -> Result { - Err(Error::UnsupportedChain("NONE")) - } - - #[wasm_bindgen(js_name = "signDigest")] - /// Sign digest data with the private key. - pub fn sign_digest(_digest: &[u8], _keypair: &KeyPair) -> Result, Error> { - Err(Error::UnsupportedChain("NONE")) - } - - #[wasm_bindgen(js_name = "verifyDigest")] - /// Verify Message signature - pub fn verify_digest(_digest: &[u8], _signature: &[u8], _address: &str) -> Result { - Err(Error::UnsupportedChain("NONE")) - } - - #[wasm_bindgen(js_name = "sign")] - /// Hash and Sign data with the private key. - pub fn sign(_data: Transaction, _keypair: &KeyPair) -> Result { - Err(Error::UnsupportedChain("NONE")) - } - - #[wasm_bindgen(js_name = "messageHash")] - /// Append prefix and hash the message - pub fn message_hash(_message: &[u8]) -> Result, Error> { - Err(Error::UnsupportedChain("NONE")) - } - - #[wasm_bindgen(js_name = "signMessage")] - /// Sign Message with the private key. - pub fn sign_message(_message: &[u8], _keypair: &KeyPair) -> Result, Error> { - Err(Error::UnsupportedChain("NONE")) - } - - #[wasm_bindgen(js_name = "verifyMessageSignature")] - /// Verify Message signature - pub fn verify_message_signature( - _message: &[u8], - _signature: &[u8], - _address: &str, - ) -> Result { - Err(Error::UnsupportedChain("NONE")) - } - - #[wasm_bindgen(js_name = "getBalance")] - /// Get balance of address and token - /// If token is None, it will return balance of native token - /// If token is Some, it will return balance of token - /// If node_url is None, it will use default node url - pub async fn get_balance( - _address: &str, - _token: Option, - _node_url: Option, - ) -> Result { - Err(Error::UnsupportedChain("NONE")) - } - - pub async fn send( - _sender: String, - _receiver: String, - _amount: BigNumber, - _options: Option, - _node_url: Option, - ) -> Result { - Err(Error::UnsupportedChain("NONE")) - } - - #[wasm_bindgen(js_name = "broadcast")] - pub async fn broadcast( - _data: crate::models::Transaction, - _node_url: Option, - ) -> Result { - Err(Error::UnsupportedChain("NONE")) - } - - #[wasm_bindgen(js_name = "validateAddress")] - pub fn validate_address( - _address: &str, - _option: Option, - ) -> Result { - Err(Error::UnsupportedChain("NONE")) - } -} diff --git a/packages/kos-sdk/src/chains/ethereum/address.rs b/packages/kos-sdk/src/chains/ethereum/address.rs deleted file mode 100644 index d7ec3cc..0000000 --- a/packages/kos-sdk/src/chains/ethereum/address.rs +++ /dev/null @@ -1,193 +0,0 @@ -use kos_crypto::keypair::KeyPair; -use kos_types::error::Error; - -use hex::FromHex; -use rlp::{DecoderError, Rlp}; -use std::{fmt, str::FromStr}; -use web3::types::Address as Web3Address; - -use wasm_bindgen::prelude::*; - -const ADDRESS_LEN: usize = 20; - -#[derive(PartialEq, Eq, Clone, Copy, Hash, PartialOrd, Ord)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[repr(transparent)] -#[wasm_bindgen(js_name = "ETHAddress")] -pub struct Address([u8; ADDRESS_LEN]); - -impl Address { - /// Address of a public key. - pub fn from_public(public: [u8; 64]) -> Address { - let digest = kos_crypto::hash::keccak256(&public); - - let mut raw = [0u8; ADDRESS_LEN]; - raw.copy_from_slice(&digest[digest.len() - ADDRESS_LEN..]); - - Address(raw) - } - - /// Address of a private key. - pub fn from_keypair(kp: &KeyPair) -> Address { - Address::from_public(kp.public_key().try_into().unwrap()) - } - - pub fn as_bytes(&self) -> &[u8] { - &self.0 - } - - pub fn from_bytes(raw: &[u8]) -> &Address { - assert!(raw.len() == ADDRESS_LEN); - - unsafe { std::mem::transmute(&raw[0]) } - } - - /// To hex address - pub fn to_hex_address(self) -> String { - Address::to_hex_checksum(&hex::encode(self.0)) - } - - pub fn to_hex_checksum(address: &str) -> String { - let address = address.trim_start_matches("0x").to_lowercase(); - - let address_hash = hex::encode(kos_crypto::hash::keccak256(address.as_bytes())); - - address - .char_indices() - .fold(String::from("0x"), |mut acc, (index, address_char)| { - // this cannot fail since it's Keccak256 hashed - let n = u16::from_str_radix(&address_hash[index..index + 1], 16).unwrap(); - - if n > 7 { - // make char uppercase if ith character is 9..f - acc.push_str(&address_char.to_uppercase().to_string()) - } else { - // already lowercased - acc.push(address_char) - } - - acc - }) - } -} - -impl fmt::Display for Address { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.to_hex_address().fmt(f) - } -} - -impl ::std::fmt::Debug for Address { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - f.debug_tuple("Address").field(&self.to_string()).finish() - } -} - -impl TryFrom<&[u8]> for Address { - type Error = Error; - - fn try_from(value: &[u8]) -> Result { - if value.len() != ADDRESS_LEN { - Err(Error::InvalidAddress(format!( - "invalid length, {}", - value.len() - ))) - } else { - let mut raw = [0u8; ADDRESS_LEN]; - raw[..ADDRESS_LEN].copy_from_slice(value); - Ok(Address(raw)) - } - } -} - -impl TryFrom> for Address { - type Error = Error; - - fn try_from(value: Vec) -> Result { - Self::try_from(&value[..]) - } -} - -impl TryFrom<&Vec> for Address { - type Error = Error; - - fn try_from(value: &Vec) -> Result { - Self::try_from(&value[..]) - } -} - -impl TryFrom<&str> for Address { - type Error = Error; - - fn try_from(value: &str) -> Result { - Address::from_str(value) - } -} - -impl FromHex for Address { - type Error = Error; - - fn from_hex>(hex: T) -> Result { - Address::try_from(hex.as_ref()) - } -} - -impl FromStr for Address { - type Err = Error; - - fn from_str(s: &str) -> Result - where - Self: Sized, - { - // remove "0x"|"0X" if exists - let s = if s.len() > 2 && (s.starts_with("0x") || s.starts_with("0X")) { - &s[2..] - } else { - s - }; - - if s.len() == 40 { - return Vec::from_hex(s) - .map_err(|e| Error::InvalidAddress(e.to_string())) - .and_then(Address::try_from); - } - - eprintln!("len={} prefix={:x}", s.len(), s.as_bytes()[0]); - Err(Error::InvalidAddress( - "invalid ethereum address".to_string(), - )) - } -} - -// NOTE: AsRef<[u8]> implies ToHex -impl AsRef<[u8]> for Address { - fn as_ref(&self) -> &[u8] { - &self.0 - } -} - -impl rlp::Decodable for Address { - fn decode(rlp: &Rlp) -> Result { - let mut data: Vec = rlp.as_val()?; - let mut bytes: [u8; ADDRESS_LEN] = [0; ADDRESS_LEN]; - while data.len() < ADDRESS_LEN { - data.push(0); - } - bytes.copy_from_slice(&data[..]); - Ok(Address(bytes)) - } -} - -impl TryFrom<&Web3Address> for Address { - type Error = Error; - - fn try_from(value: &Web3Address) -> Result { - Address::try_from(value.as_bytes()) - } -} - -impl From
for Web3Address { - fn from(value: Address) -> Self { - Web3Address::from(value.0) - } -} diff --git a/packages/kos-sdk/src/chains/ethereum/mod.rs b/packages/kos-sdk/src/chains/ethereum/mod.rs deleted file mode 100644 index 502eed3..0000000 --- a/packages/kos-sdk/src/chains/ethereum/mod.rs +++ /dev/null @@ -1,749 +0,0 @@ -pub mod address; -pub mod request; -pub mod transaction; - -use crate::chain::{self, BaseChain}; -use crate::chains::evm20; -use crate::models::{self, BroadcastResult, PathOptions, Transaction, TransactionRaw}; - -use kos_crypto::keypair::KeyPair; -use kos_crypto::secp256k1::Secp256k1KeyPair; -use kos_proto::options::ETHOptions; -use kos_types::error::Error; -use kos_types::hash::Hash; -use kos_types::number::BigNumber; - -use rlp::Rlp; -use secp256k1::ecdsa::{RecoverableSignature, RecoveryId}; -use std::{ops::Div, str::FromStr}; -use wasm_bindgen::prelude::*; -use web3::ethabi; -use web3::types::U256; - -#[derive(Debug, Copy, Clone)] -#[wasm_bindgen] -pub struct ETH {} - -pub const SIGN_PREFIX: &[u8; 26] = b"\x19Ethereum Signed Message:\n"; -pub const BIP44_PATH: u32 = 60; -pub const CHAIN_ID: u64 = 1; -pub const DEFAULT_GAS_TRANSFER: u64 = 21000; - -/// hash digest -pub fn hash_transaction(eth_tx: &transaction::Transaction) -> Result, Error> { - let bytes = eth_tx.encode()?; - let digest = ETH::hash(&bytes)?; - Ok(digest) -} - -pub const BASE_CHAIN: BaseChain = BaseChain { - name: "Ethereum", - symbol: "ETH", - precision: 18, - chain_code: 3, -}; - -#[wasm_bindgen] -impl ETH { - #[wasm_bindgen(js_name = "baseChain")] - pub fn base_chain() -> BaseChain { - BASE_CHAIN - } - - #[wasm_bindgen(js_name = "random")] - pub fn random() -> Result { - let mut rng = rand::thread_rng(); - let kp = Secp256k1KeyPair::random(&mut rng); - Ok(KeyPair::new_secp256k1(kp)) - } - - #[wasm_bindgen(js_name = "keypairFromBytes")] - pub fn keypair_from_bytes(private_key: &[u8]) -> Result { - // copy to fixed length array - let mut pk_slice = [0u8; 32]; - pk_slice.copy_from_slice(private_key); - - let kp = Secp256k1KeyPair::new(pk_slice); - Ok(KeyPair::new_secp256k1(kp)) - } - - #[wasm_bindgen(js_name = "keypairFromMnemonic")] - pub fn keypair_from_mnemonic( - mnemonic: &str, - path: &str, - password: Option, - ) -> Result { - let kp = Secp256k1KeyPair::new_from_mnemonic_phrase_with_path( - mnemonic, - path, - password.as_deref(), - )?; - - Ok(KeyPair::new_secp256k1(kp)) - } - - #[wasm_bindgen(js_name = "getAddressFromKeyPair")] - pub fn get_address_from_keypair(kp: &KeyPair) -> Result { - Ok(address::Address::from_keypair(kp).to_string()) - } - - #[wasm_bindgen(js_name = "getPath")] - pub fn get_path(options: &PathOptions) -> Result { - Ok(format!("m/44'/{}'/0'/0/{}", BIP44_PATH, options.index)) - } - - #[wasm_bindgen(js_name = "signDigest")] - /// Sign digest data with the private key. - pub fn sign_digest(digest: &[u8], keypair: &KeyPair) -> Result, Error> { - let raw = keypair.sign_digest(digest); - Ok(raw) - } - - #[wasm_bindgen(js_name = "verifyDigest")] - /// Verify Message signature - pub fn verify_digest(_digest: &[u8], _signature: &[u8], _address: &str) -> Result { - // let message = Message::from_slice(message).map_err(|_| RecoveryError::InvalidMessage)?; - // let recovery_id = RecoveryId::from_i32(recovery_id).map_err(|_| RecoveryError::InvalidSignature)?; - // let signature = - // RecoverableSignature::from_compact(signature, recovery_id).map_err(|_| RecoveryError::InvalidSignature)?; - // let public_key = CONTEXT - // .recover_ecdsa(&message, &signature) - // .map_err(|_| RecoveryError::InvalidSignature)?; - - // Ok(public_key_address(&public_key)) - todo!() - } - - #[wasm_bindgen(js_name = "sign")] - /// Hash and Sign data with the private key. - pub fn sign(tx: Transaction, keypair: &KeyPair) -> Result { - match tx.data { - Some(TransactionRaw::Ethereum(eth_tx)) => { - let mut new_tx = eth_tx.clone(); - - // remove signature if any - let mut eth_tx = eth_tx.clone(); - eth_tx.signature = None; - - let digest = hash_transaction(ð_tx)?; - let sig = ETH::sign_digest(digest.as_slice(), keypair)?; - - new_tx.signature = Some(RecoverableSignature::from_compact( - &sig[..64], - RecoveryId::from_i32(sig[64] as i32)?, - )?); - - let new_hash = hash_transaction(&new_tx)?; - let result = Transaction { - chain: tx.chain, - sender: tx.sender, - hash: Hash::from_vec(new_hash)?, - data: Some(TransactionRaw::Ethereum(new_tx)), - signature: Some(hex::encode(sig)), - }; - - Ok(result) - } - _ => Err(Error::InvalidMessage( - "not a ethereum transaction".to_string(), - )), - } - } - - #[wasm_bindgen(js_name = "hash")] - /// hash digest - pub fn hash(message: &[u8]) -> Result, Error> { - let digest = kos_crypto::hash::keccak256(message); - Ok(digest.to_vec()) - } - - #[wasm_bindgen(js_name = "messageHash")] - /// Append prefix and hash the message - pub fn message_hash(message: &[u8]) -> Result, Error> { - let to_sign = [SIGN_PREFIX, message.len().to_string().as_bytes(), message].concat(); - - ETH::hash(&to_sign) - } - - #[wasm_bindgen(js_name = "signMessage")] - /// Sign Message with the private key. - pub fn sign_message(message: &[u8], keypair: &KeyPair) -> Result, Error> { - let m = ETH::message_hash(message)?; - ETH::sign_digest(&m, keypair) - } - - #[wasm_bindgen(js_name = "verifyMessageSignature")] - /// Verify Message signature - pub fn verify_message_signature( - message: &[u8], - signature: &[u8], - address: &str, - ) -> Result { - let m = ETH::message_hash(message)?; - ETH::verify_digest(&m, signature, address) - } - - #[wasm_bindgen(js_name = "getBalance")] - pub async fn get_balance( - address: &str, - token: Option, - node_url: Option, - ) -> Result { - let node = node_url.unwrap_or_else(|| crate::utils::get_node_url("ETH")); - - let from: address::Address = address.try_into()?; - - match token { - Some(key) if key != "ETH" => { - let contract_address: address::Address = key.as_str().try_into()?; - let contract = evm20::get_contract_evm20(); - let func = contract.function("balanceOf").map_err(|e| { - Error::InvalidMessage(format!("failed to get balanceOf function: {}", e)) - })?; - - let data = func - .encode_input(&[ethabi::Token::Address(from.into())]) - .map_err(|e| Error::InvalidMessage(format!("failed to encode input: {}", e)))?; - - let result = request::call(&node, from, contract_address, data).await?; - - // Decode the output (the balance). - let balance = match func.decode_output(&result).unwrap()[0].clone().into_uint() { - Some(b) => b, - _ => return Err(Error::ReqwestError("failed to decode output".to_string())), - }; - - Ok(balance.to_string().try_into()?) - } - _ => request::get_balance(&node, from).await, - } - } - - #[wasm_bindgen(js_name = "getGasPrice")] - pub async fn gas_price(node_url: Option) -> Result { - let node = node_url.unwrap_or_else(|| crate::utils::get_node_url("ETH")); - let gas_price = request::gas_price(&node).await?; - BigNumber::from_string(&gas_price.to_string()) - } - - fn get_options(options: Option) -> kos_proto::options::ETHOptions { - match options.and_then(|opt| opt.data) { - Some(crate::models::Options::Ethereum(op)) => op, - _ => kos_proto::options::ETHOptions::default(), - } - } - - pub async fn send( - sender: String, - receiver: String, - amount: BigNumber, - options: Option, - node_url: Option, - ) -> Result { - let node = node_url.unwrap_or_else(|| crate::utils::get_node_url("ETH")); - - // validate sender address - let addr_sender = address::Address::from_str(&sender)?; - let mut addr_receiver = address::Address::from_str(&receiver)?; - let mut options = ETH::get_options(options); - - let token = options.token.as_deref().unwrap_or("ETH"); - let is_eth_token = token == "ETH"; - - let mut amount_eth = amount.clone(); - // Update addr_receiver for non-ETH token. - if !is_eth_token { - // update contract data for token transfer - let contract = evm20::get_contract_evm20(); - let func = contract.function("transfer").map_err(|e| { - Error::InvalidMessage(format!("failed to get transfer function: {}", e)) - })?; - - let encoded = func - .encode_input(&[ - ethabi::Token::Address(addr_receiver.into()), - ethabi::Token::Uint( - U256::from_dec_str(&amount.to_string()) - .map_err(|e| Error::InvalidNumberParse(e.to_string()))?, - ), - ]) - .map_err(|e| Error::InvalidTransaction(e.to_string()))?; - - addr_receiver = address::Address::from_str(token)?; - options.contract_data = Some(encoded); - amount_eth = 0.into(); - } else if options.gas_limit.is_none() { - options.gas_limit = Some(BigNumber::from(DEFAULT_GAS_TRANSFER)); - } - - let tx = ETH::build_tx(&node, addr_sender, addr_receiver, amount_eth, options).await?; - - let digest = hash_transaction(&tx)?; - - Ok(crate::models::Transaction { - chain: chain::Chain::ETH, - sender, - hash: Hash::from_vec(digest)?, - data: Some(TransactionRaw::Ethereum(tx)), - signature: None, - }) - } - - async fn build_tx( - node: &str, - sender: address::Address, - receiver: address::Address, - amount: BigNumber, - options: ETHOptions, - ) -> Result { - // update chain id if none - let chain_id = options.chain_id.unwrap_or(CHAIN_ID); - - // compute nonce if none - let nonce = match options.nonce { - Some(value) if value != 0 => U256::from_dec_str(&value.to_string()) - .map_err(|e| Error::InvalidNumberParse(e.to_string()))?, - _ => { - let nonce = request::get_nonce(node, sender).await?; - U256::from(nonce) - } - }; - - let gas_price: Option = match options.gas_price { - Some(value) => Some( - U256::from_dec_str(&value.to_string()) - .map_err(|e| Error::InvalidNumberParse(e.to_string()))?, - ), - None => { - if options.legacy_type.unwrap_or(false) { - Some(request::gas_price(node).await?) - } else { - None - } - } - }; - - let value = U256::from_dec_str(&amount.to_string()) - .map_err(|e| Error::InvalidNumberParse(e.to_string()))?; - - let gas_limit: U256 = match options.gas_limit { - Some(value) => U256::from_dec_str(&value.to_string()) - .map_err(|e| Error::InvalidNumberParse(e.to_string()))?, - None => { - request::estimate_gas( - node, - sender, - receiver, - gas_price, - Some(value), - options.contract_data.to_owned(), - ) - .await? - } - }; - - let max_fee_per_gas: Option = match options.max_fee_per_gas { - Some(value) => Some( - U256::from_dec_str(&value.to_string()) - .map_err(|e| Error::InvalidNumberParse(e.to_string()))?, - ), - None => { - if !options.legacy_type.unwrap_or(false) { - Some(request::base_fee(node).await?) - } else { - None - } - } - }; - - let max_priority_fee_per_gas: Option = match options.max_priority_fee_per_gas { - Some(value) => Some( - U256::from_dec_str(&value.to_string()) - .map_err(|e| Error::InvalidNumberParse(e.to_string()))?, - ), - None => { - if !options.legacy_type.unwrap_or(false) { - // use 10% of max_fee_per_gas for max_priority_fee_per_gas as default - Some(max_fee_per_gas.unwrap_or_default().div(U256::from(10))) - } else { - None - } - } - }; - - Ok(transaction::Transaction { - transaction_type: Some(if options.legacy_type.unwrap_or(false) { - transaction::TransactionType::Legacy - } else { - transaction::TransactionType::EIP1559 - }), - chain_id: Some(chain_id), - nonce, - from: Some(sender), - to: Some(receiver), - value, - data: options.contract_data.unwrap_or_default(), - gas: gas_limit, - gas_price, - max_fee_per_gas, - max_priority_fee_per_gas, - signature: None, - }) - } - - #[wasm_bindgen(js_name = "broadcast")] - pub async fn broadcast( - tx: crate::models::Transaction, - node_url: Option, - ) -> Result { - let node = node_url.unwrap_or_else(|| crate::utils::get_node_url("ETH")); - - let eth_tx = match tx.data.to_owned() { - Some(TransactionRaw::Ethereum(tx)) => tx, - _ => return Err(Error::InvalidTransaction("Invalid transaction type".into())), - }; - - _ = request::broadcast(node.as_str(), eth_tx.encode()?).await?; - - Ok(BroadcastResult::new(tx)) - } - - #[wasm_bindgen(js_name = "validateAddress")] - pub fn validate_address( - address: &str, - option: Option, - ) -> Result { - let addr = address::Address::from_str(address); - let addr = match addr { - Ok(addr) => addr.to_string().trim_start_matches("0x").to_string(), - Err(_) => return Ok(false), - }; - - let option = option.unwrap_or_default(); - - // Check if address checksum is required and if the address matches the expected format - if option.check_summed.unwrap_or(false) - && addr != address.to_string().trim_start_matches("0x") - { - return Ok(false); - } - - Ok(true) - } - - #[wasm_bindgen(js_name = "txFromRaw")] - pub fn tx_from_raw(raw: &str) -> Result { - let hex_tx = hex::decode(raw)?; - let rlp = Rlp::new(&hex_tx); - - let tx = match transaction::Transaction::decode_legacy(&rlp) { - Ok(tx) => tx, - Err(_) => { - let rlp = Rlp::new(&hex_tx[2..]); - self::transaction::Transaction::decode_eip155(rlp).map_err(|e| { - Error::InvalidTransaction(format!("failed to decode transaction: {}", e)) - })? - } - }; - - let signature = tx.signature.map(|sig| sig.to_standard().to_string()); - - let digest = hash_transaction(&tx)?; - - Ok(crate::models::Transaction { - chain: chain::Chain::ETH, - sender: "".to_string(), //TODO: implement sender on eth decode - hash: Hash::from_vec(digest)?, - data: Some(TransactionRaw::Ethereum(tx)), - signature, - }) - } - - #[wasm_bindgen(js_name = "txFromJson")] - pub fn tx_from_json(raw: &str) -> Result { - // build expected send result - let tx: transaction::Transaction = serde_json::from_str(raw)?; - - let digest = hash_transaction(&tx)?; - - let sender = match tx.from { - Some(addr) => addr.to_string(), - None => "".to_string(), - }; - - let signature = tx.signature.map(|sig| sig.to_standard().to_string()); - - Ok(crate::models::Transaction { - chain: chain::Chain::ETH, - sender, - hash: Hash::from_vec(digest)?, - data: Some(TransactionRaw::Ethereum(tx)), - signature, - }) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use dotenvy; - use hex::FromHex; - use kos_types::Bytes32; - use std::sync::Once; - - const DEFAULT_PRIVATE_KEY: &str = - "1ab42cc412b618bdea3a599e3c9bae199ebf030895b039e9db1e30dafb12b727"; - const DEFAULT_ADDRESS: &str = "0x9858EfFD232B4033E47d90003D41EC34EcaEda94"; - const DEFAULT_MNEMONIC: &str = - "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"; - - static _INIT: Once = Once::new(); - - fn _init() { - _INIT.call_once(|| { - dotenvy::from_filename(".env.nodes").ok(); - }); - } - - fn get_default_secret() -> KeyPair { - let b = Bytes32::from_hex(DEFAULT_PRIVATE_KEY).unwrap(); - let kp = Secp256k1KeyPair::new(b.into()); - KeyPair::new_secp256k1(kp) - } - - #[test] - fn test_address_from_private_key() { - let address = ETH::get_address_from_keypair(&get_default_secret()).unwrap(); - - assert_eq!(DEFAULT_ADDRESS, address); - } - - #[test] - fn test_validate_bip44() { - let v = vec![ - (0, "0x9858EfFD232B4033E47d90003D41EC34EcaEda94"), - (1, "0x6Fac4D18c912343BF86fa7049364Dd4E424Ab9C0"), - (2, "0xb6716976A3ebe8D39aCEB04372f22Ff8e6802D7A"), - (3, "0xF3f50213C1d2e255e4B2bAD430F8A38EEF8D718E"), - (4, "0x51cA8ff9f1C0a99f88E86B8112eA3237F55374cA"), - ]; - - for (index, expected_addr) in v { - let path = ETH::get_path(&PathOptions::new(index)).unwrap(); - let kp = ETH::keypair_from_mnemonic(DEFAULT_MNEMONIC, &path, None).unwrap(); - let addr = ETH::get_address_from_keypair(&kp).unwrap(); - - assert_eq!(expected_addr, addr); - } - } - - #[test] - fn test_send_and_sign() { - let options = models::SendOptions { - data: Some(models::Options::Ethereum(kos_proto::options::ETHOptions { - chain_id: Some(1), - nonce: Some(100), - max_fee_per_gas: Some("1000000000".try_into().unwrap()), - max_priority_fee_per_gas: Some("1000000000".try_into().unwrap()), - ..Default::default() - })), - }; - - let tx = tokio_test::block_on(ETH::send( - DEFAULT_ADDRESS.to_string(), - "0x6Fac4D18c912343BF86fa7049364Dd4E424Ab9C0".to_string(), - "1000".try_into().unwrap(), - Some(options), - None, - )) - .unwrap(); - - assert_eq!( - tx.hash.to_string(), - "c2c9b955cf8394fa9434ba812e69f2297c23c16a261a915fa3f1a18adf3fae63" - ); - - let signed = ETH::sign(tx, &get_default_secret()); - assert!(signed.is_ok()); - assert_eq!( - signed.unwrap().hash.to_string(), - "87eab8c8201462ac4872200dfebe841aa77bdc0cc0e5310542c7f319dd304fdf" - ); - } - - #[test] - fn test_send_erc20() { - let options = models::SendOptions { - data: Some(models::Options::Ethereum(kos_proto::options::ETHOptions { - chain_id: Some(1), - nonce: Some(100), - token: Some("0xc12d1c73ee7dc3615ba4e37e4abfdbddfa38907e".to_string()), - gas_limit: Some(1000000.into()), - gas_price: Some(0.into()), - max_fee_per_gas: Some(0.into()), - max_priority_fee_per_gas: Some(0.into()), - ..Default::default() - })), - }; - - let tx = tokio_test::block_on(ETH::send( - DEFAULT_ADDRESS.to_string(), - "0x6Fac4D18c912343BF86fa7049364Dd4E424Ab9C0".to_string(), - "1000".try_into().unwrap(), - Some(options), - None, - )) - .unwrap(); - - assert_eq!( - tx.hash.to_string(), - "fa2b84b45d28888c43c0bda80000e4a4d2040017f3b6e4a31e7d8a4ace27db29" - ); - - let eth_tx = match tx.data.clone() { - Some(models::TransactionRaw::Ethereum(tx)) => tx, - _ => panic!("invalid tx"), - }; - - assert_eq!(eth_tx.value.to_string(), "0"); - assert_eq!(hex::encode(eth_tx.data), "a9059cbb0000000000000000000000006fac4d18c912343bf86fa7049364dd4e424ab9c000000000000000000000000000000000000000000000000000000000000003e8"); - - let signed = ETH::sign(tx, &get_default_secret()); - assert!(signed.is_ok()); - assert_eq!( - signed.unwrap().hash.to_string(), - "f4c27caf4a9e3718d217f315e8fed3f9b739fa61c78e5ab43a7ca7d4fd1c010f" - ); - } - - #[test] - fn test_get_balance() { - let balance = tokio_test::block_on(ETH::get_balance(DEFAULT_ADDRESS, None, None)).unwrap(); - - assert!(balance.to_i64() > 0); - } - - #[test] - fn test_get_balance_erc20() { - let balance = tokio_test::block_on(ETH::get_balance( - DEFAULT_ADDRESS, - Some("0xC12D1c73eE7DC3615BA4e37E4ABFdbDDFA38907E".to_string()), - None, - )); - assert!(balance.is_ok()); - - assert!(balance.unwrap().to_i64() > 100); - } - - #[test] - fn test_validate_address_ok() { - let list = [ - "0x9858EfFD232B4033E47d90003D41EC34EcaEda94", - "0x6Fac4D18c912343BF86fa7049364Dd4E424Ab9C0", - "9858EfFD232B4033E47d90003D41EC34EcaEda94", // no 0x prefix as valid - ]; - - for addr in list { - let valid = ETH::validate_address(addr, None).unwrap(); - assert!(valid); - } - - // check summed - for addr in list { - let valid = ETH::validate_address( - addr, - Some(models::AddressOptions::new(None, None, Some(true))), - ) - .unwrap(); - assert_eq!(valid, true, "address: {}", addr); - } - } - - #[test] - fn test_validate_address_fail() { - let list = [ - "0x9858EfFD232B4033E47d90003D41EC34EcaEda95", // wrong check sum - &"0x6Fac4D18c912343BF86fa7049364Dd4E424Ab9C0".to_lowercase(), // all lower case - ]; - - // check summed - for addr in list { - let valid = ETH::validate_address( - addr, - Some(models::AddressOptions::new(None, None, Some(true))), - ) - .unwrap(); - assert_eq!(valid, false, "address: {}", addr); - } - - // wrong size - let list = [ - "0x9858EfFD232B4033E47d90003D41EC34EcaEda9", // hex convert wrong parity - "0x9858EfFD232B4033E47d90003D41EC34EcaEda941", // hex convert wrong parity - "0x9858EfFD232B4033E47d90003D41EC34EcaEda94Ab", // hex convert ok, wrong length - ]; - - // check summed - for addr in list { - let valid = ETH::validate_address(&addr, None).unwrap(); - assert_eq!(valid, false, "address: {}", addr); - } - } - - #[test] - fn test_decode_rlp_tx() { - let raw_tx = "af02ed0182012884019716f7850e60f86055827530944cbeee256240c92a9ad920ea6f4d7df6466d2cdc0180c0808080"; - let tx = ETH::tx_from_raw(raw_tx).unwrap(); - - assert_eq!(tx.chain, chain::Chain::ETH); - - let eth_tx = match tx.data { - Some(TransactionRaw::Ethereum(tx)) => tx, - _ => panic!("invalid tx"), - }; - - assert_eq!(eth_tx.chain_id, Some(1)); - assert_eq!(eth_tx.nonce, U256::from_dec_str("296").unwrap()); - assert_eq!( - eth_tx.to.unwrap().to_string(), - "0x4cBeee256240c92A9ad920ea6f4d7Df6466D2Cdc" - ); - assert_eq!(eth_tx.gas, U256::from(30000)); - assert_eq!(eth_tx.value, U256::from_dec_str("1").unwrap()); - assert_eq!(eth_tx.signature, None); - } - - #[test] - fn test_decode_json() { - let json = r#"{ - "from":"0x4cbeee256240c92a9ad920ea6f4d7df6466d2cdc", - "maxPriorityFeePerGas":null,"maxFeePerGas":null, - "gas": "0x00", - "value": "0x00", - "data":"0xa9059cbb000000000000000000000000ac4145fef6c828e8ae017207ad944c988ccb2cf700000000000000000000000000000000000000000000000000000000000f4240", - "to":"0xdac17f958d2ee523a2206206994597c13d831ec7", - "nonce":"0x00"}"#; - let tx = ETH::tx_from_json(json).unwrap(); - - assert_eq!(tx.chain, chain::Chain::ETH); - - let eth_tx = match tx.data { - Some(TransactionRaw::Ethereum(tx)) => tx, - _ => panic!("invalid tx"), - }; - - assert_eq!(eth_tx.chain_id, None); - assert_eq!(eth_tx.nonce, U256::from_dec_str("0").unwrap()); - assert_eq!( - eth_tx.from.unwrap().to_string(), - "0x4cBeee256240c92A9ad920ea6f4d7Df6466D2Cdc" - ); - assert_eq!( - eth_tx.to.unwrap().to_string(), - "0xdAC17F958D2ee523a2206206994597C13D831ec7" - ); - assert_eq!(eth_tx.gas, U256::from(0)); - assert_eq!(eth_tx.value, U256::from(0)); - assert_eq!(eth_tx.signature, None); - } -} diff --git a/packages/kos-sdk/src/chains/ethereum/request.rs b/packages/kos-sdk/src/chains/ethereum/request.rs deleted file mode 100644 index 70fe080..0000000 --- a/packages/kos-sdk/src/chains/ethereum/request.rs +++ /dev/null @@ -1,121 +0,0 @@ -use super::address::Address; - -use kos_types::{error::Error, number::BigNumber}; - -use web3::{transports::Http, types::U256, Web3}; - -pub fn new_transport(url: &str) -> Result { - let transport = - web3::transports::Http::new(url).map_err(|e| Error::TransportError(e.to_string()))?; - Ok(transport) -} - -pub fn get_web3(url: &str) -> Result, Error> { - let transport = new_transport(url)?; - let web3 = Web3::new(transport); - Ok(web3) -} - -pub async fn call(url: &str, from: Address, to: Address, data: Vec) -> Result, Error> { - let call = web3::types::CallRequest { - from: Some(from.into()), - to: Some(to.into()), - gas: None, - gas_price: None, - value: None, - data: Some(data.into()), - ..Default::default() - }; - - let web3 = get_web3(url)?; - let result = web3 - .eth() - .call(call, None) - .await - .map_err(|e| Error::TransportError(e.to_string()))?; - - Ok(result.0) -} - -pub async fn get_balance(url: &str, address: Address) -> Result { - let web3 = get_web3(url)?; - let balance = web3 - .eth() - .balance(address.into(), None) - .await - .map_err(|e| Error::TransportError(e.to_string()))?; - balance.to_string().try_into() -} - -pub async fn get_nonce(url: &str, address: Address) -> Result { - let web3 = get_web3(url)?; - let nonce = web3 - .eth() - .transaction_count(address.into(), None) - .await - .map_err(|e| Error::TransportError(e.to_string()))?; - Ok(nonce.as_u64()) -} - -/// Call a contract without changing the state of the blockchain to estimate gas usage. -pub async fn estimate_gas( - url: &str, - from: Address, - to: Address, - gas_price: Option, - value: Option, - data: Option>, -) -> Result { - let req = web3::types::CallRequest { - from: Some(from.into()), - to: Some(to.into()), - gas: None, - gas_price, - value, - data: data.map(|data| data.into()), - ..Default::default() - }; - - let web3 = get_web3(url)?; - web3.eth() - .estimate_gas(req, None) - .await - .map_err(|e| Error::TransportError(e.to_string())) -} - -/// Get current recommended gas price -pub async fn gas_price(url: &str) -> Result { - let web3 = get_web3(url)?; - web3.eth() - .gas_price() - .await - .map_err(|e| Error::TransportError(e.to_string())) -} - -pub async fn base_fee(url: &str) -> Result { - let web3 = get_web3(url)?; - let block = web3 - .eth() - .block(web3::types::BlockId::Number( - web3::types::BlockNumber::Pending, - )) - .await - .map_err(|e| Error::TransportError(e.to_string()))? - .unwrap(); - - // get block base fee - let base_fee = block.base_fee_per_gas.unwrap_or(U256::zero()); - - Ok(base_fee) -} - -/// Broadcast ETH transaction -pub async fn broadcast(url: &str, tx_raw: Vec) -> Result { - let web3 = get_web3(url)?; - Ok(web3 - .eth() - .send_raw_transaction(tx_raw.into()) - .await - .map_err(|e| Error::TransportError(e.to_string()))? - .to_string()) -} diff --git a/packages/kos-sdk/src/chains/ethereum/transaction.rs b/packages/kos-sdk/src/chains/ethereum/transaction.rs deleted file mode 100644 index 20ac348..0000000 --- a/packages/kos-sdk/src/chains/ethereum/transaction.rs +++ /dev/null @@ -1,281 +0,0 @@ -use super::address::Address; -use std::str::FromStr; - -use kos_types::error::Error; - -use rlp::{DecoderError, Rlp, RlpStream}; -use secp256k1::ecdsa::RecoverableSignature; -use serde::{Deserialize, Deserializer, Serialize}; -use web3::types::U256; - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] -pub enum TransactionType { - Legacy, - EIP1559, -} - -fn signature_serialize(x: &Option, s: S) -> Result -where - S: serde::Serializer, -{ - if let Some(signature) = x { - let serialized = format!("{:?}", signature); - s.serialize_str(&serialized) - } else { - s.serialize_none() - } -} - -pub fn deserialize_addr<'de, D>(deserializer: D) -> Result, D::Error> -where - D: Deserializer<'de>, -{ - let s = String::deserialize(deserializer)?; - if s.is_empty() { - Ok(None) - } else { - Ok(Some( - Address::from_str(&s).map_err(serde::de::Error::custom)?, - )) - } -} - -pub fn deserialize_data<'de, D>(deserializer: D) -> Result, D::Error> -where - D: Deserializer<'de>, -{ - let s = String::deserialize(deserializer)?; - if s.is_empty() { - Ok(Vec::new()) - } else { - let s = if s.len() > 2 && (s.starts_with("0x") || s.starts_with("0X")) { - &s[2..] - } else { - &s - }; - - Ok(hex::decode(s).map_err(serde::de::Error::custom)?) - } -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] -pub struct Transaction { - pub transaction_type: Option, - pub nonce: U256, - #[serde(deserialize_with = "deserialize_addr")] - pub from: Option
, - #[serde(deserialize_with = "deserialize_addr")] - pub to: Option
, - pub gas: U256, - pub gas_price: Option, - pub value: U256, - #[serde(deserialize_with = "deserialize_data")] - pub data: Vec, - pub chain_id: Option, - pub max_fee_per_gas: Option, - pub max_priority_fee_per_gas: Option, - #[serde(serialize_with = "signature_serialize", skip_deserializing)] - pub signature: Option, -} - -impl Transaction { - fn rlp_append_legacy(&self, stream: &mut RlpStream) { - stream.append(&self.nonce); - stream.append(&self.gas_price.unwrap_or_default()); - stream.append(&self.gas); - if let Some(to) = self.to { - stream.append(&to.as_bytes()); - } else { - stream.append(&""); - } - stream.append(&self.value); - stream.append(&self.data); - } - - fn encode_legacy(&self) -> RlpStream { - let mut stream = RlpStream::new(); - stream.begin_list(9); - - self.rlp_append_legacy(&mut stream); - - if let Some(signature) = self.signature { - self.rlp_append_signature(&mut stream, signature); - } else { - stream.append(&self.chain_id.unwrap_or(0)); - stream.append(&0u8); - stream.append(&0u8); - }; - - stream - } - - fn encode_eip1559_payload(&self) -> RlpStream { - let mut stream = RlpStream::new(); - - let list_size = if self.signature.is_some() { 12 } else { 9 }; - stream.begin_list(list_size); - - // append chain_id. from EIP-2930: chainId is defined to be an integer of arbitrary size. - stream.append(&self.chain_id.unwrap_or(0)); - - stream.append(&self.nonce); - stream.append(&self.max_priority_fee_per_gas.unwrap_or_default()); - - let gas_price = self.max_fee_per_gas.or(self.gas_price).unwrap_or_default(); - stream.append(&gas_price); - - stream.append(&self.gas); - if let Some(to) = self.to { - stream.append(&to.as_bytes()); - } else { - stream.append(&""); - } - stream.append(&self.value); - stream.append(&self.data); - - self.rlp_append_access_list(&mut stream); - - if let Some(signature) = self.signature { - self.rlp_append_signature(&mut stream, signature); - } - - stream - } - - fn rlp_append_access_list(&self, stream: &mut RlpStream) { - stream.begin_list(0); - // todo!(access_list) - } - - fn rlp_append_signature(&self, stream: &mut RlpStream, signature: RecoverableSignature) { - // Deconstruct the signature into r, s, and v - let (rec_id, raw_sig) = signature.serialize_compact(); - let v = self.rlp_adjust_v_value(rec_id.to_i32()); - let r = &raw_sig[0..32]; - let s = &raw_sig[32..64]; - stream.append(&v); - stream.append(&U256::from_big_endian(r)); - stream.append(&U256::from_big_endian(s)); - } - - fn rlp_adjust_v_value(&self, v: i32) -> u64 { - match self.transaction_type { - Some(TransactionType::Legacy) | None => { - let chain_id = self.chain_id.unwrap_or(0); - chain_id * 2 + 35 + (v as u64) - } - _ => v as u64, - } - } - - pub fn encode(&self) -> Result, Error> { - match self.transaction_type { - Some(TransactionType::Legacy) | None => { - let stream = self.encode_legacy(); - Ok(stream.out().to_vec()) - } - - Some(TransactionType::EIP1559) => { - let stream = self.encode_eip1559_payload(); - Ok([&[2], stream.as_raw()].concat()) - } - } - } - - pub fn decode_legacy(rlp: &Rlp) -> Result { - Ok(Transaction { - transaction_type: Some(TransactionType::Legacy), - nonce: rlp.val_at(0)?, - gas_price: Some(rlp.val_at(1)?), - gas: rlp.val_at(2)?, - from: None, - to: Some(rlp.val_at(3)?), - value: rlp.val_at(4)?, - data: rlp.val_at(5)?, - chain_id: None, - max_fee_per_gas: None, - max_priority_fee_per_gas: None, - signature: None, - }) - } - - pub fn decode_eip155(rlp: Rlp) -> Result { - Ok(Transaction { - transaction_type: Some(TransactionType::EIP1559), - chain_id: Some(rlp.val_at(0)?), - nonce: rlp.val_at(1)?, - max_priority_fee_per_gas: Some(rlp.val_at(2)?), - max_fee_per_gas: Some(rlp.val_at(3)?), - gas: rlp.val_at(4)?, - from: None, - to: Some(rlp.val_at(5)?), // Convert to Option - value: rlp.val_at(6)?, - data: rlp.val_at(7)?, - signature: None, - gas_price: None, - }) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::chains::ethereum::address::Address; - use secp256k1::ecdsa::{RecoverableSignature, RecoveryId}; - - #[test] - fn test_encode_legacy() { - let tx = Transaction { - transaction_type: Some(TransactionType::Legacy), - nonce: U256::from_dec_str("691").unwrap(), - from: None, - to: Some(Address::try_from("0x4592D8f8D7B001e72Cb26A73e4Fa1806a51aC79d").unwrap()), - gas: U256::from(21000), - gas_price: Some(U256::from_dec_str("2000000000").unwrap()), - value: U256::from_dec_str("1000000000000000000").unwrap(), - data: Vec::new(), - chain_id: Some(4), - max_fee_per_gas: None, - max_priority_fee_per_gas: None, - signature: Some( - RecoverableSignature::from_compact( - &hex::decode("699ff162205967ccbabae13e07cdd4284258d46ec1051a70a51be51ec2bc69f34e6944d508244ea54a62ebf9a72683eeadacb73ad7c373ee542f1998147b220e").unwrap(), - RecoveryId::from_i32(0).unwrap(), - ).unwrap(), - ) - }; - - let raw = tx.encode().unwrap(); - let expected = hex::decode("f86d8202b38477359400825208944592d8f8d7b001e72cb26a73e4fa1806a51ac79d880de0b6b3a7640000802ba0699ff162205967ccbabae13e07cdd4284258d46ec1051a70a51be51ec2bc69f3a04e6944d508244ea54a62ebf9a72683eeadacb73ad7c373ee542f1998147b220e"); - - assert_eq!(raw, expected.unwrap()); - } - - #[test] - fn test_encode_eip1559() { - let tx = Transaction { - transaction_type: Some(TransactionType::EIP1559), - nonce: U256::from_dec_str("241").unwrap(), - from: None, - to: Some(Address::try_from("0xe0e5d2B4EDcC473b988b44b4d13c3972cb6694cb").unwrap()), - gas: U256::from(21000), - gas_price: None, - value: U256::from_dec_str("138078072511761950").unwrap(), - data: Vec::new(), - chain_id: Some(1), - max_fee_per_gas: Some(U256::from_dec_str("91097072255").unwrap()), - max_priority_fee_per_gas: Some(U256::from_dec_str("1000000000").unwrap()), - signature: Some( - RecoverableSignature::from_compact( - &hex::decode("7eb3335f4fd4de25ec3452c08882f28fb098b2eaa37a332941f918d869f5c2ad59b9d4aa997c7fa34f1b167f98a12432bb1a4a35660d723a9c19bb76b4cd025d").unwrap(), - RecoveryId::from_i32(1).unwrap(), - ).unwrap(), - ) - }; - - let raw = tx.encode().unwrap(); - let expected = hex::decode("02f8740181f1843b9aca00851535cf027f82520894e0e5d2b4edcc473b988b44b4d13c3972cb6694cb8801ea8d467f558e1e80c001a07eb3335f4fd4de25ec3452c08882f28fb098b2eaa37a332941f918d869f5c2ada059b9d4aa997c7fa34f1b167f98a12432bb1a4a35660d723a9c19bb76b4cd025d"); - - assert_eq!(raw, expected.unwrap()); - } -} diff --git a/packages/kos-sdk/src/chains/evm20.rs b/packages/kos-sdk/src/chains/evm20.rs deleted file mode 100644 index d3a10b0..0000000 --- a/packages/kos-sdk/src/chains/evm20.rs +++ /dev/null @@ -1,82 +0,0 @@ -use web3::ethabi::Contract; - -// ERC20 contract ABI. This is a simplified ABI with only the `balanceOf` function. -const EVM20_CONTRACT_ABI: &str = r#" -[ - { - "constant": true, - "inputs": [ - { - "name": "_owner", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "name": "balance", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_from", - "type": "address" - }, - { - "name": "_to", - "type": "address" - }, - { - "name": "_value", - "type": "uint256" - } - - ], - "name": "transferFrom", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant":false, - "inputs":[ - { - "name":"_to", - "type":"address" - }, - { - "name":"_value", - "type":"uint256" - } - ], - "name":"transfer", - "outputs":[ - { - "name":"", - "type":"bool" - } - ], - "payable":false, - "stateMutability":"nonpayable", - "type":"function" - } -] -"#; - -pub fn get_contract_evm20() -> Contract { - // Parse the ABI. - Contract::load(EVM20_CONTRACT_ABI.as_bytes()).unwrap() -} diff --git a/packages/kos-sdk/src/chains/klever/address.rs b/packages/kos-sdk/src/chains/klever/address.rs deleted file mode 100644 index a3dfecb..0000000 --- a/packages/kos-sdk/src/chains/klever/address.rs +++ /dev/null @@ -1,157 +0,0 @@ -use kos_crypto::keypair::KeyPair; -use kos_types::error::Error; - -use bech32::{FromBase32, ToBase32}; -use hex::FromHex; -use std::{fmt, str::FromStr}; - -use wasm_bindgen::prelude::*; - -const ADDRESS_LEN: usize = 32; -const ADDRESS_HRP: &str = "klv"; - -#[derive(PartialEq, Eq, Clone, Copy, Hash, PartialOrd, Ord)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[repr(transparent)] -#[wasm_bindgen(js_name = "KLVAddress")] -pub struct Address([u8; ADDRESS_LEN]); - -impl Address { - /// Address of a public key. - pub fn from_public(public: [u8; 32]) -> Address { - // pubkey to address use first 32 bytes - Address(public) - } - - pub fn public_key(&self) -> [u8; 32] { - self.0 - } - - /// Address of a keypair. - pub fn from_keypair(kp: &KeyPair) -> Address { - Address::from_public(kp.public_key().try_into().unwrap()) - } - - /// As raw 32-byte address. - pub fn as_bytes(&self) -> &[u8] { - &self.0 - } - - /// Address from raw 32-byte. - pub fn from_bytes(raw: &[u8]) -> &Address { - assert!(raw.len() == ADDRESS_LEN); - - unsafe { std::mem::transmute(&raw[0]) } - } - - /// To hex address - pub fn to_hex_address(self) -> String { - hex::encode(self.0) - } -} -impl fmt::Display for Address { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let st = bech32::encode(ADDRESS_HRP, self.0.to_base32(), bech32::Variant::Bech32).unwrap(); - st.fmt(f) - } -} - -impl ::std::fmt::Debug for Address { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - f.debug_tuple("Address").field(&self.to_string()).finish() - } -} - -impl TryFrom<&[u8]> for Address { - type Error = Error; - - fn try_from(value: &[u8]) -> Result { - if value.len() != ADDRESS_LEN { - Err(Error::InvalidAddress(format!( - "invalid length: {}", - value.len() - ))) - } else { - let mut raw = [0u8; ADDRESS_LEN]; - raw[..ADDRESS_LEN].copy_from_slice(value); - Ok(Address(raw)) - } - } -} - -impl TryFrom> for Address { - type Error = Error; - - fn try_from(value: Vec) -> Result { - Self::try_from(&value[..]) - } -} - -impl TryFrom<&Vec> for Address { - type Error = Error; - - fn try_from(value: &Vec) -> Result { - Self::try_from(&value[..]) - } -} - -impl TryFrom<&str> for Address { - type Error = Error; - - fn try_from(value: &str) -> Result { - Address::from_str(value) - } -} - -impl FromHex for Address { - type Error = Error; - - fn from_hex>(hex: T) -> Result { - Address::try_from(hex.as_ref()) - } -} - -impl FromStr for Address { - type Err = Error; - - fn from_str(s: &str) -> Result - where - Self: Sized, - { - if s.starts_with(ADDRESS_HRP) { - return bech32::decode(s) - .map_err(|e| Error::InvalidAddress(e.to_string())) - .and_then(|(_, data, _)| { - Vec::from_base32(&data) - .map_err(|e| Error::InvalidAddress(e.to_string())) - .and_then(Address::try_from) - }); - } - - if s.len() == 64 { - return Vec::from_hex(s) - .map_err(|e| Error::InvalidAddress(e.to_string())) - .and_then(Address::try_from); - } - - if s.len() == 66 && (s.starts_with("0x") || s.starts_with("0X")) { - return Vec::from_hex(&s.as_bytes()[2..]) - .map_err(|e| Error::InvalidAddress(e.to_string())) - .and_then(Address::try_from); - } - - if s == "_" || s == "0x0" || s == "/0" { - return Ok(Address([0u8; ADDRESS_LEN])); - } - - eprintln!("len={} prefix={:x}", s.len(), s.as_bytes()[0]); - Err(Error::InvalidAddress("invalid klever address".to_string())) - } -} - -// NOTE: AsRef<[u8]> implies ToHex -impl AsRef<[u8]> for Address { - fn as_ref(&self) -> &[u8] { - &self.0 - } -} diff --git a/packages/kos-sdk/src/chains/klever/klever_test.rs b/packages/kos-sdk/src/chains/klever/klever_test.rs deleted file mode 100644 index 3ab6849..0000000 --- a/packages/kos-sdk/src/chains/klever/klever_test.rs +++ /dev/null @@ -1,250 +0,0 @@ -#[cfg(test)] -mod klever_test { - use dotenvy; - use std::assert_eq; - use std::str; - - use crate::chains::klever::*; - use crate::models::PathOptions; - use crate::models::SendOptions; - use hex::FromHex; - use kos_types::Bytes32; - use std::sync::Once; - - const DEFAULT_KAPP_FEE: i64 = 1000000; - const DEFAULT_BANDWIDTH_FEE: i64 = 2000000; - - const DEFAULT_PRIVATE_KEY: &str = - "8734062c1158f26a3ca8a4a0da87b527a7c168653f7f4c77045e5cf571497d9d"; - const DEFAULT_ADDRESS: &str = "klv1usdnywjhrlv4tcyu6stxpl6yvhplg35nepljlt4y5r7yppe8er4qujlazy"; - - static _INIT: Once = Once::new(); - - fn _init() { - _INIT.call_once(|| { - dotenvy::from_filename(".env.nodes").ok(); - }); - } - - fn get_default_secret() -> KeyPair { - let b = Bytes32::from_hex(DEFAULT_PRIVATE_KEY).unwrap(); - let kp = Ed25519KeyPair::new(b.into()); - KeyPair::from(kp) - } - - #[test] - fn test_get_balance() { - let balance = tokio_test::block_on(KLV::get_balance( - "klv1usdnywjhrlv4tcyu6stxpl6yvhplg35nepljlt4y5r7yppe8er4qujlazy", - Some("KLV".to_string()), - None, - )) - .unwrap(); - println!("balance: {}", balance.to_string()); - println!("balance: {}", balance.with_precision(6)); - - assert!(balance > BigNumber::from(0)); - } - - #[test] - fn test_broadcast() { - let klv_tx: kos_proto::klever::Transaction = serde_json::from_str( - "{\"RawData\":{\"Nonce\":13,\"Sender\":\"5BsyOlcf2VXgnNQWYP9EZcP0RpPIfy+upKD8QIcnyOo=\",\"Contract\":[{\"Parameter\":{\"type_url\":\"type.googleapis.com/proto.TransferContract\",\"value\":\"CiAysyg0Aj8xj/rr5XGU6iJ+ATI29mnRHS0W0BrC1vz0CBIDS0xWGAo=\"}}],\"KAppFee\":500000,\"BandwidthFee\":1000000,\"Version\":1,\"ChainID\":\"MTAwNDIw\"},\"Signature\":[\"O7C2MjTUMauWl8kfeJjgwDnFLkiDqY2U23s6AWzTstut63FnZeKC3EcxY0DiAgzf5PQ1+jeC2dIx3+pP7BHlBQ==\"]}", - ).unwrap(); - - let to_broadcast = crate::models::Transaction { - chain: crate::chain::Chain::KLV, - sender: "klv1usdnywjhrlv4tcyu6stxpl6yvhplg35nepljlt4y5r7yppe8er4qujlazy".to_string(), - hash: Hash::new("0x0000000000000000000000000000000000000000000000000000000000000000") - .unwrap(), - data: Some(TransactionRaw::Klever(klv_tx)), - signature: None, - }; - - let result = tokio_test::block_on(KLV::broadcast(to_broadcast, None)); - - assert!(result.is_err()); - assert!(result - .unwrap_err() - .to_string() - .contains("invalid transaction fees")) - } - - #[test] - fn test_send() { - let result = tokio_test::block_on(KLV::send( - "klv1usdnywjhrlv4tcyu6stxpl6yvhplg35nepljlt4y5r7yppe8er4qujlazy".to_string(), - "klv1x2ejsdqz8uccl7htu4cef63z0cqnydhkd8g36tgk6qdv94hu7syqms3spm".to_string(), - BigNumber::from(10), - None, - None, - )); - - assert!(result.is_ok()); - match result.unwrap().data { - Some(TransactionRaw::Klever(tx)) => { - let raw = &tx.raw_data.unwrap(); - assert!(raw.nonce > 0); - assert_eq!(raw.k_app_fee, DEFAULT_KAPP_FEE); - assert_eq!(raw.bandwidth_fee, DEFAULT_BANDWIDTH_FEE); - assert!(raw.kda_fee.is_none()); - - assert_eq!(raw.contract.len(), 1); - let c: kos_proto::klever::TransferContract = - kos_proto::unpack_from_option_any(&raw.contract.get(0).unwrap().parameter) - .unwrap(); - - assert_eq!(c.amount, 10); - assert_eq!(c.asset_id.len(), 0); - } - _ => assert!(false), - } - } - - #[test] - fn test_send_kda() { - let kda = "TAS-1I86".to_string(); - // create KLV send options - let klv_options = kos_proto::options::KLVOptions { - kda: Some(kda.clone()), - ..Default::default() - }; - - let options = SendOptions::new_klever_send_options(klv_options); - - let result = tokio_test::block_on(KLV::send( - "klv1usdnywjhrlv4tcyu6stxpl6yvhplg35nepljlt4y5r7yppe8er4qujlazy".to_string(), - "klv1x2ejsdqz8uccl7htu4cef63z0cqnydhkd8g36tgk6qdv94hu7syqms3spm".to_string(), - BigNumber::from(10), - Some(options), - None, - )); - - assert!(result.is_ok()); - match result.unwrap().data { - Some(TransactionRaw::Klever(tx)) => { - let raw = &tx.raw_data.unwrap(); - assert!(raw.nonce > 0); - assert_eq!(raw.k_app_fee, DEFAULT_KAPP_FEE); - assert_eq!(raw.bandwidth_fee, DEFAULT_BANDWIDTH_FEE); - assert!(raw.kda_fee.is_none()); - - assert_eq!(raw.contract.len(), 1); - let c: kos_proto::klever::TransferContract = - kos_proto::unpack_from_option_any(&raw.contract.get(0).unwrap().parameter) - .unwrap(); - - assert_eq!(c.amount, 10); - assert_eq!(str::from_utf8(&c.asset_id).unwrap(), kda); - } - _ => assert!(false), - } - } - - #[test] - fn test_address_from_mnemonic() { - let path = KLV::get_path(&PathOptions::new(0)).unwrap(); - let kp = KLV::keypair_from_mnemonic("abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about", &path, None).unwrap(); - let address = KLV::get_address_from_keypair(&kp).unwrap(); - - assert_eq!(DEFAULT_ADDRESS, address); - } - - #[test] - fn test_address_from_private_key() { - let address = KLV::get_address_from_keypair(&get_default_secret()).unwrap(); - - assert_eq!(DEFAULT_ADDRESS, address.to_string()); - } - - #[test] - fn test_sign_message() { - let message = "Hello World"; - let kp = get_default_secret(); - let signature = KLV::sign_message(message.as_bytes(), &kp).unwrap(); - assert_eq!( - "38b3fd1e4d5a34291dddb2c6ca66e857c1696f3160981ca6abb8a78087f86b6163314cadd16179239d38201ba91c97aa201b7f38ecfff50c7f0448da67bf5a05", - hex::encode(signature) - ); - } - - #[test] - fn test_verify_message() { - let message = "Hello World"; - let kp = get_default_secret(); - let signature = hex::decode("38b3fd1e4d5a34291dddb2c6ca66e857c1696f3160981ca6abb8a78087f86b6163314cadd16179239d38201ba91c97aa201b7f38ecfff50c7f0448da67bf5a05").unwrap() ; - let address = KLV::get_address_from_keypair(&kp).unwrap(); - let result = KLV::verify_message_signature(message.as_bytes(), &signature, &address); - - assert!(result.is_ok()); - assert_eq!(result.unwrap(), true); - } - - #[test] - fn test_tx_from_raw() { - let raw = "{\"RawData\":{\"BandwidthFee\":1000000,\"ChainID\":\"MTAwNDIw\",\"Contract\":[{\"Parameter\":{\"type_url\":\"type.googleapis.com/proto.TransferContract\",\"value\":\"CiAysyg0Aj8xj/rr5XGU6iJ+ATI29mnRHS0W0BrC1vz0CBgK\"}}],\"KAppFee\":500000,\"Nonce\":39,\"Sender\":\"5BsyOlcf2VXgnNQWYP9EZcP0RpPIfy+upKD8QIcnyOo=\",\"Version\":1}}"; - - let tx = KLV::tx_from_raw(raw); - assert!(tx.is_ok()); - let tx = tx.unwrap(); - assert_eq!(tx.chain, crate::chain::Chain::KLV); - assert_eq!( - tx.sender, - "klv1usdnywjhrlv4tcyu6stxpl6yvhplg35nepljlt4y5r7yppe8er4qujlazy" - ); - assert_eq!( - tx.hash.to_string(), - "1e61c51f0d230f4855dc9b8935b47b9019887baf02be75d364a4068083833c15" - ); - match tx.data.unwrap() { - TransactionRaw::Klever(klv_tx) => { - let raw = &klv_tx.raw_data.unwrap(); - assert_eq!(raw.nonce, 39); - assert_eq!(raw.contract.len(), 1); - assert_eq!(raw.k_app_fee, 500000); - assert_eq!(raw.bandwidth_fee, 1000000); - - let c: kos_proto::klever::TransferContract = - kos_proto::unpack_from_option_any(&raw.contract.get(0).unwrap().parameter) - .unwrap(); - - assert_eq!(c.amount, 10); - } - _ => assert!(false), - } - } - - #[test] - fn test_validate_address_ok() { - let list = [ - "klv1usdnywjhrlv4tcyu6stxpl6yvhplg35nepljlt4y5r7yppe8er4qujlazy", - "klv1x2ejsdqz8uccl7htu4cef63z0cqnydhkd8g36tgk6qdv94hu7syqms3spm", - ]; - - for addr in list.iter() { - let result = KLV::validate_address(addr, None); - assert!(result.is_ok()); - assert_eq!(result.unwrap(), true, "address: {}", addr); - } - } - - #[test] - fn test_validate_address_fail() { - let list = [ - "klv1usdnywjhrlv4tcyu6stxpl6yvhplg35nepljlt4y5r7yppe8er4qujlaz", - "klv1usdnywjhrlv4tcyu6stxpl6yvhplg35nepljlt4y5r7yppe8er4qujlazy1", - "klv2usdnywjhrlv4tcyu6stxpl6yvhplg35nepljlt4y5r7yppe8er4qujlazy", - "klvusdnywjhrlv4tcyu6stxpl6yvhplg35nepljlt4y5r7yppe8er4qujlazy", - "1usdnywjhrlv4tcyu6stxpl6yvhplg35nepljlt4y5r7yppe8er4qujlazy", - "usdnywjhrlv4tcyu6stxpl6yvhplg35nepljlt4y5r7yppe8er4qujlazy", - "bnb1ztx5rf7jx28k3xnemftcq3kfgm3yhfvfmhm456", - "0x9858EfFD232B4033E47d90003D41EC34EcaEda94", - ]; - - for addr in list.iter() { - let result = KLV::validate_address(addr, None); - assert!(result.is_ok()); - assert_eq!(result.unwrap(), false, "address: {}", addr); - } - } -} diff --git a/packages/kos-sdk/src/chains/klever/mod.rs b/packages/kos-sdk/src/chains/klever/mod.rs deleted file mode 100644 index 00e9229..0000000 --- a/packages/kos-sdk/src/chains/klever/mod.rs +++ /dev/null @@ -1,303 +0,0 @@ -pub mod address; -pub mod models; -pub mod requests; -use crate::{ - chain::BaseChain, - models::{AddressOptions, BroadcastResult, PathOptions, Transaction, TransactionRaw}, -}; -use kos_crypto::{ed25519::Ed25519KeyPair, keypair::KeyPair}; -use kos_types::{error::Error, hash::Hash, number::BigNumber}; - -use pbjson::private::base64; -use std::str::FromStr; -use wasm_bindgen::prelude::*; - -#[derive(Debug, Copy, Clone)] -#[wasm_bindgen()] -pub struct KLV {} - -pub const SIGN_PREFIX: &[u8; 24] = b"\x17Klever Signed Message:\n"; -pub const BIP44_PATH: u32 = 690; -pub const BASE_CHAIN: BaseChain = BaseChain { - name: "Klever", - symbol: "KLV", - precision: 6, - chain_code: 38, -}; - -#[wasm_bindgen] -impl KLV { - #[wasm_bindgen(js_name = "baseChain")] - pub fn base_chain() -> BaseChain { - BASE_CHAIN - } - - #[wasm_bindgen(js_name = "random")] - pub fn random() -> Result { - let mut rng = rand::thread_rng(); - let kp = Ed25519KeyPair::random(&mut rng); - Ok(KeyPair::new_ed25519(kp)) - } - - #[wasm_bindgen(js_name = "keypairFromBytes")] - pub fn keypair_from_bytes(private_key: &[u8]) -> Result { - // copy to fixed length array - let mut pk_slice = [0u8; 32]; - pk_slice.copy_from_slice(private_key); - - let kp = Ed25519KeyPair::new(pk_slice); - Ok(KeyPair::new_ed25519(kp)) - } - - #[wasm_bindgen(js_name = "keypairFromMnemonic")] - pub fn keypair_from_mnemonic( - mnemonic: &str, - path: &str, - password: Option, - ) -> Result { - let kp = Ed25519KeyPair::new_from_mnemonic_phrase_with_path( - mnemonic, - path, - password.as_deref(), - )?; - - Ok(KeyPair::new_ed25519(kp)) - } - - #[wasm_bindgen(js_name = "getAddressFromKeyPair")] - pub fn get_address_from_keypair(keypair: &KeyPair) -> Result { - Ok(address::Address::from_keypair(keypair).to_string()) - } - - #[wasm_bindgen(js_name = "getPath")] - pub fn get_path(options: &PathOptions) -> Result { - Ok(format!("m/44'/{}'/0'/0'/{}'", BIP44_PATH, options.index)) - } - - #[wasm_bindgen(js_name = "signDigest")] - /// Sign digest data with the private key. - pub fn sign_digest(digest: &[u8], keypair: &KeyPair) -> Result, Error> { - let sig = keypair.sign_digest(digest); - Ok(sig) - } - - #[wasm_bindgen(js_name = "verifyDigest")] - /// Verify Message signature - pub fn verify_digest(digest: &[u8], signature: &[u8], address: &str) -> Result { - let addr = address::Address::from_str(address)?; - let kp = Ed25519KeyPair::default(); - - if kp.verify_digest(digest, signature, &addr.public_key()) { - Ok(true) - } else { - Err(Error::InvalidSignature("message verification fail")) - } - } - - #[wasm_bindgen(js_name = "sign")] - /// Hash and Sign data with the private key. - pub fn sign(tx: Transaction, keypair: &KeyPair) -> Result { - match tx.data { - Some(TransactionRaw::Klever(klv_tx)) => { - let mut new_tx = klv_tx.clone(); - let digest = KLV::hash_transaction(&klv_tx)?; - let sig = KLV::sign_digest(digest.as_slice(), keypair)?; - - let signature = base64::encode(sig.clone()); - - new_tx.signature.push(sig); - let result = Transaction { - chain: tx.chain, - sender: tx.sender, - hash: Hash::from_vec(digest)?, - data: Some(TransactionRaw::Klever(new_tx)), - signature: Some(signature), - }; - - Ok(result) - } - _ => Err(Error::InvalidMessage( - "not a klever transaction".to_string(), - )), - } - } - - fn hash_transaction(tx: &kos_proto::klever::Transaction) -> Result, Error> { - if let Some(raw_data) = &tx.raw_data { - let bytes = kos_proto::write_message(raw_data); - KLV::hash(&bytes) - } else { - Err(Error::InvalidTransaction("klv raw".to_string())) - } - } - - #[wasm_bindgen(js_name = "hash")] - /// hash digest - pub fn hash(message: &[u8]) -> Result, Error> { - let digest = kos_crypto::hash::blake2b256(message); - Ok(digest.to_vec()) - } - - #[wasm_bindgen(js_name = "messageHash")] - /// Append prefix and hash the message - pub fn message_hash(message: &[u8]) -> Result, Error> { - let to_sign = [SIGN_PREFIX, message.len().to_string().as_bytes(), message].concat(); - - let digest = kos_crypto::hash::keccak256(&to_sign); - Ok(digest.to_vec()) - } - - #[wasm_bindgen(js_name = "signMessage")] - /// Sign Message with the private key. - pub fn sign_message(message: &[u8], keypair: &KeyPair) -> Result, Error> { - let m = KLV::message_hash(message)?; - KLV::sign_digest(&m, keypair) - } - - #[wasm_bindgen(js_name = "verifyMessageSignature")] - /// Verify Message signature - pub fn verify_message_signature( - message: &[u8], - signature: &[u8], - address: &str, - ) -> Result { - let m = KLV::message_hash(message)?; - KLV::verify_digest(&m, signature, address) - } - - #[wasm_bindgen(js_name = "getBalance")] - /// Get balance of address and token - /// If token is None, it will return balance of native token - /// If token is Some, it will return balance of token - /// If node_url is None, it will use default node url - pub async fn get_balance( - address: &str, - token: Option, - node_url: Option, - ) -> Result { - let node = node_url.unwrap_or_else(|| crate::utils::get_node_url("KLV")); - let acc = requests::get_account(node.as_str(), address).await?; - - Ok(match token { - Some(key) if key != "KLV" => match acc.assets.unwrap().get(&key) { - Some(asset) => BigNumber::from(asset.balance), - None => BigNumber::from(0), - }, - _ => BigNumber::from(acc.balance.unwrap_or(0)), - }) - } - - #[wasm_bindgen(js_name = "broadcast")] - pub async fn broadcast( - tx: crate::models::Transaction, - node_url: Option, - ) -> Result { - let node = node_url.unwrap_or_else(|| crate::utils::get_node_url("KLV")); - let raw = tx - .data - .clone() - .ok_or_else(|| Error::ReqwestError("Missing transaction data".into()))?; - - let result = requests::broadcast(node.as_str(), raw.try_into()?).await?; - - match result.get("data").and_then(|v| v.as_object()) { - Some(v) => { - let tx_hash_str = v - .get("txHash") - .and_then(|v| v.as_str()) - .ok_or_else(|| Error::ReqwestError("Missing transaction hash".into()))?; - - let tx_hash = Hash::new(tx_hash_str)?; - - Ok(BroadcastResult::new(crate::models::Transaction { - chain: tx.chain, - sender: tx.sender, - hash: tx_hash, - data: tx.data, - signature: None, - })) - } - None => match result.get("error") { - Some(err) => Err(Error::ReqwestError(err.to_string())), - None => Err(Error::ReqwestError("Unknown error".into())), - }, - } - } - - fn get_options(options: Option) -> kos_proto::options::KLVOptions { - match options.and_then(|opt| opt.data) { - Some(crate::models::Options::Klever(op)) => op, - _ => kos_proto::options::KLVOptions::default(), - } - } - - /// create a send transaction network - #[wasm_bindgen(js_name = "send")] - pub async fn send( - sender: String, - receiver: String, - amount: BigNumber, - options: Option, - node_url: Option, - ) -> Result { - let node = node_url.unwrap_or_else(|| crate::utils::get_node_url("KLV")); - let options = KLV::get_options(options); - - let contract = models::TransferTXRequest { - receiver, - amount: amount.to_i64(), - kda: options.kda.clone(), - kda_royalties: options.kda_royalties, - }; - - requests::make_request(sender, contract, &options, node.as_str()).await - } - - #[wasm_bindgen(js_name = "validateAddress")] - pub fn validate_address( - address: &str, - _options: Option, - ) -> Result { - let addr = address::Address::from_str(address); - if addr.is_err() { - return Ok(false); - } - - if addr.unwrap().to_string() == address { - return Ok(true); - } - - Ok(false) - } -} - -#[wasm_bindgen] -impl KLV { - /// import raw TX rom JSValue to Transaction model - #[wasm_bindgen(js_name = "txFromRaw")] - pub fn tx_from_raw(raw: &str) -> Result { - // build expected send result - let tx: kos_proto::klever::Transaction = serde_json::from_str(raw)?; - - // unwrap raw_data - let data = tx - .raw_data - .clone() - .ok_or_else(|| Error::InvalidTransaction("no raw TX found".to_string()))?; - - let sender = address::Address::from_bytes(&data.sender); - let digest = KLV::hash_transaction(&tx)?; - let signature = tx.signature.first().map(|sig| base64::encode(sig.clone())); - - Ok(crate::models::Transaction { - chain: crate::chain::Chain::KLV, - sender: sender.to_string(), - hash: Hash::from_slice(&digest)?, - data: Some(TransactionRaw::Klever(tx)), - signature, - }) - } -} - -#[cfg(test)] -mod klever_test; diff --git a/packages/kos-sdk/src/chains/klever/models.rs b/packages/kos-sdk/src/chains/klever/models.rs deleted file mode 100644 index 826f06c..0000000 --- a/packages/kos-sdk/src/chains/klever/models.rs +++ /dev/null @@ -1,148 +0,0 @@ -use kos_types::error::Error; - -use serde::{Deserialize, Serialize}; -use serde_json; -use std::{ - collections, - fmt::{self, Display, Formatter}, -}; -use wasm_bindgen::prelude::*; - -#[derive(Deserialize, Serialize, Clone, Debug)] -pub struct ResultAccount { - pub data: DataAccount, -} - -#[derive(Deserialize, Serialize, Clone, Debug)] -pub struct DataAccount { - pub account: Account, -} - -impl std::fmt::Display for ResultAccount { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match serde_json::to_string(&self) { - Ok(json_str) => write!(f, "({})", json_str), - Err(e) => write!(f, "{}", e), - } - } -} - -#[derive(Deserialize, Serialize, Clone, Debug)] -#[serde(rename_all = "camelCase")] -#[wasm_bindgen(getter_with_clone)] -pub struct Asset { - pub asset_id: String, - pub collection: String, - pub asset_name: String, - pub asset_type: u8, - pub balance: u64, - pub precision: u8, - pub frozen_balance: u64, - pub unfrozen_balance: u64, -} - -#[derive(Deserialize, Serialize, Clone, Debug)] -#[serde(rename_all = "camelCase")] -#[wasm_bindgen(getter_with_clone)] -pub struct Account { - // pub address: String, - #[serde(rename = "Nonce")] - pub nonce: Option, - #[serde(rename = "Balance")] - pub balance: Option, - // pub frozen_balance: u64, - #[serde(rename = "Allowance")] - pub allowance: Option, - #[wasm_bindgen(skip)] - pub assets: Option>, -} - -pub struct TransactionResult { - pub tx_hash: String, - pub tx: kos_proto::klever::Transaction, -} - -impl TryFrom for TransactionResult { - type Error = kos_types::error::Error; - - fn try_from(value: serde_json::value::Value) -> Result { - if let Some(v) = value.get("data") { - if let Some(obj) = v.as_object() { - let hash = obj.get("txHash").unwrap().as_str().unwrap(); - let result = obj.get("result").unwrap().to_string(); - let tx: kos_proto::klever::Transaction = serde_json::from_str(&result)?; - return Ok(Self { - tx_hash: hash.to_string(), - tx, - }); - } - } - - match value.get("error") { - Some(err) => Err(Error::ReqwestError(err.to_string())), - None => Err(Error::ReqwestError("Unknown error".to_string())), - } - } -} - -// SendTXRequest - -#[derive(Deserialize, Serialize, Clone, Debug)] -pub struct SendTXRequest { - #[serde(rename = "type")] - pub tx_type: u32, - #[serde(rename = "sender")] - pub sender: String, - #[serde(rename = "nonce")] - pub nonce: Option, - #[serde(rename = "permID")] - pub perm_id: Option, - #[serde(rename = "data")] - pub data: Option>>, - #[serde(rename = "contract")] - pub contract: Option, - #[serde(rename = "contracts")] - pub contracts: Option>, - #[serde(rename = "kdaFee")] - pub kda_fee: Option, -} - -impl SendTXRequest { - pub fn set_contract(&mut self, contract: impl Serialize) -> Result<(), Error> { - let data = serde_json::to_value(&contract)?; - self.contract = Some(data); - Ok(()) - } - - pub fn to_vec(&self) -> Result, Error> { - let data = serde_json::to_vec(&self).map_err(Error::from)?; - Ok(data) - } -} - -impl Display for SendTXRequest { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - write!(f, "{}", serde_json::to_string(&self).unwrap()) - } -} - -#[derive(Deserialize, Serialize, Clone, Debug)] -// TransferTXRequest - -pub struct TransferTXRequest { - #[serde(rename = "receiver")] - pub receiver: String, - #[serde(rename = "amount")] - pub amount: i64, - #[serde(rename = "kda")] - pub kda: Option, - #[serde(rename = "kdaRoyalties")] - pub kda_royalties: Option, -} - -impl std::fmt::Display for TransferTXRequest { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match serde_json::to_string(&self) { - Ok(json_str) => write!(f, "({})", json_str), - Err(e) => write!(f, "{}", e), - } - } -} diff --git a/packages/kos-sdk/src/chains/klever/requests.rs b/packages/kos-sdk/src/chains/klever/requests.rs deleted file mode 100644 index 318625f..0000000 --- a/packages/kos-sdk/src/chains/klever/requests.rs +++ /dev/null @@ -1,89 +0,0 @@ -use super::models; -use crate::{chain, models::TransactionRaw, utils}; -use kos_types::{error::Error, hash::Hash}; -use serde::Serialize; - -pub async fn get_account(node_url: &str, address: &str) -> Result { - let url = format!("{}/address/{}", node_url, address); - - utils::http_get::(url) - .await - .map(|r| r.data.account) -} - -pub async fn broadcast( - node_url: &str, - tx: kos_proto::klever::Transaction, -) -> Result { - let url = format!("{}/transaction/broadcast", node_url); - log::debug!( - "Broadcasting to {}\nData: {} ", - url, - serde_json::to_string(&tx)?, - ); - - // adjust to kleverchain format - let data = format!( - "{{\"tx\": {}}}", - serde_json::to_string(&tx)?.replace("typeUrl", "type_url"), - ) - .as_bytes() - .to_vec(); - - utils::http_post::(url, &data).await -} - -pub async fn send_request( - node_url: &str, - request: &mut models::SendTXRequest, -) -> Result { - let url = format!("{}/transaction/send", node_url); - - if request.nonce.unwrap_or(0) == 0 { - let account = get_account(node_url, &request.sender).await?; - request.nonce = account.nonce; - } - - log::debug!("Send request: {}", request.to_string()); - - // to json - let data = request.to_vec().unwrap(); - - utils::http_post::(url, &data).await -} - -pub async fn make_request( - sender: String, - contract: impl Serialize, - options: &kos_proto::options::KLVOptions, - node: &str, -) -> Result { - let data = options.memo.clone().map(|memo| { - memo.into_iter() - .map(|m| m.into_bytes()) - .collect::>>() - }); - - let mut tx_request = models::SendTXRequest { - tx_type: 0, - sender: sender.to_owned(), - nonce: options.nonce, - perm_id: None, - data, - contract: None, - contracts: None, - kda_fee: options.kda_fee.clone(), - }; - - tx_request.set_contract(contract)?; - let result = send_request(node, &mut tx_request).await?; - let tx = models::TransactionResult::try_from(result)?; - - Ok(crate::models::Transaction { - chain: chain::Chain::KLV, - sender, - hash: Hash::new(&tx.tx_hash)?, - data: Some(TransactionRaw::Klever(tx.tx)), - signature: None, - }) -} diff --git a/packages/kos-sdk/src/chains/mod.rs b/packages/kos-sdk/src/chains/mod.rs deleted file mode 100644 index f6bc78f..0000000 --- a/packages/kos-sdk/src/chains/mod.rs +++ /dev/null @@ -1,19 +0,0 @@ -mod bitcoin; -mod default; -mod ethereum; -mod evm20; -mod klever; -mod polygon; -mod tron; - -pub use self::bitcoin::BTC; -pub use default::NONE; -pub use ethereum::ETH; -pub use klever::KLV; -pub use polygon::MATIC; -pub use tron::TRX; - -pub use ethereum::transaction::Transaction as ETHTransaction; -pub use polygon::Transaction as MATICTransaction; - -pub use self::bitcoin::transaction::BTCTransaction; diff --git a/packages/kos-sdk/src/chains/polygon/mod.rs b/packages/kos-sdk/src/chains/polygon/mod.rs deleted file mode 100644 index a7fac20..0000000 --- a/packages/kos-sdk/src/chains/polygon/mod.rs +++ /dev/null @@ -1,357 +0,0 @@ -use super::ETHTransaction; -use super::ETH; - -use crate::chain::{BaseChain, Chain}; -use crate::models::PathOptions; -use crate::models::{self, BroadcastResult, TransactionRaw}; - -use kos_crypto::keypair::KeyPair; -use kos_types::error::Error; -use kos_types::number::BigNumber; - -use serde::Serialize; -use wasm_bindgen::prelude::*; - -#[derive(Debug, Copy, Clone)] -#[wasm_bindgen] -pub struct MATIC {} - -pub const CHAIN_ID: u64 = 137; - -pub const BASE_CHAIN: BaseChain = BaseChain { - name: "Polygon", - symbol: "MATIC", - precision: 18, - chain_code: 28, -}; - -#[derive(Serialize, Clone, Debug, PartialEq)] -pub struct Transaction { - pub eth: ETHTransaction, -} - -fn convert_options( - options: Option, -) -> Option { - let mut data = match options.and_then(|opt| opt.data) { - Some(crate::models::Options::Polygon(op)) => op.eth, - _ => kos_proto::options::ETHOptions::default(), - }; - - if data.chain_id.is_none() { - data.chain_id = Some(CHAIN_ID) - }; - - Some(crate::models::SendOptions::new( - crate::models::Options::Ethereum(data), - )) -} - -fn convert_transaction(tx: models::Transaction) -> Result { - match tx.data.clone() { - Some(TransactionRaw::Polygon(tx_polygon)) => { - Ok(tx.new_data(Chain::MATIC, TransactionRaw::Ethereum(tx_polygon.eth))) - } - Some(TransactionRaw::Ethereum(tx_eth)) => Ok(tx.new_data( - Chain::MATIC, - TransactionRaw::Polygon(Transaction { eth: tx_eth }), - )), - _ => Err(Error::InvalidTransaction( - "Invalid Transaction Type".to_string(), - )), - } -} - -#[wasm_bindgen] -impl MATIC { - #[wasm_bindgen(js_name = "baseChain")] - pub fn base_chain() -> BaseChain { - BASE_CHAIN - } - - #[wasm_bindgen(js_name = "random")] - pub fn random() -> Result { - ETH::random() - } - - #[wasm_bindgen(js_name = "keypairFromBytes")] - pub fn keypair_from_bytes(private_key: &[u8]) -> Result { - ETH::keypair_from_bytes(private_key) - } - - #[wasm_bindgen(js_name = "keypairFromMnemonic")] - pub fn keypair_from_mnemonic( - mnemonic: &str, - path: &str, - password: Option, - ) -> Result { - ETH::keypair_from_mnemonic(mnemonic, path, password) - } - - #[wasm_bindgen(js_name = "getAddressFromKeyPair")] - pub fn get_address_from_keypair(kp: &KeyPair) -> Result { - ETH::get_address_from_keypair(kp) - } - - #[wasm_bindgen(js_name = "getPath")] - pub fn get_path(options: &PathOptions) -> Result { - ETH::get_path(options) - } - - #[wasm_bindgen(js_name = "signDigest")] - /// Sign digest data with the private key. - pub fn sign_digest(digest: &[u8], keypair: &KeyPair) -> Result, Error> { - ETH::sign_digest(digest, keypair) - } - - #[wasm_bindgen(js_name = "verifyDigest")] - /// Verify Message signature - pub fn verify_digest(digest: &[u8], signature: &[u8], address: &str) -> Result { - ETH::verify_digest(digest, signature, address) - } - - #[wasm_bindgen(js_name = "sign")] - /// Hash and Sign data with the private key. - pub fn sign(tx: models::Transaction, keypair: &KeyPair) -> Result { - let result = ETH::sign(convert_transaction(tx)?, keypair); - - // convert back to polygon tx enum - convert_transaction(result?) - } - - #[wasm_bindgen(js_name = "hash")] - /// hash digest - pub fn hash(message: &[u8]) -> Result, Error> { - ETH::hash(message) - } - - #[wasm_bindgen(js_name = "messageHash")] - /// Append prefix and hash the message - pub fn message_hash(message: &[u8]) -> Result, Error> { - ETH::message_hash(message) - } - - #[wasm_bindgen(js_name = "signMessage")] - /// Sign Message with the private key. - pub fn sign_message(message: &[u8], keypair: &KeyPair) -> Result, Error> { - ETH::sign_message(message, keypair) - } - - #[wasm_bindgen(js_name = "verifyMessageSignature")] - /// Verify Message signature - pub fn verify_message_signature( - message: &[u8], - signature: &[u8], - address: &str, - ) -> Result { - ETH::verify_message_signature(message, signature, address) - } - - #[wasm_bindgen(js_name = "getBalance")] - pub async fn get_balance( - address: &str, - token: Option, - node_url: Option, - ) -> Result { - let node = node_url.unwrap_or_else(|| crate::utils::get_node_url("MATIC")); - ETH::get_balance(address, token, Some(node)).await - } - - #[wasm_bindgen(js_name = "getGasPrice")] - pub async fn gas_price(node_url: Option) -> Result { - let node = node_url.unwrap_or_else(|| crate::utils::get_node_url("MATIC")); - ETH::gas_price(Some(node)).await - } - - pub async fn send( - sender: String, - receiver: String, - amount: BigNumber, - options: Option, - node_url: Option, - ) -> Result { - let node = node_url.unwrap_or_else(|| crate::utils::get_node_url("MATIC")); - let result = ETH::send( - sender, - receiver, - amount, - convert_options(options), - Some(node), - ) - .await?; - convert_transaction(result) - } - - #[wasm_bindgen(js_name = "broadcast")] - pub async fn broadcast( - tx: models::Transaction, - node_url: Option, - ) -> Result { - let node = node_url.unwrap_or_else(|| crate::utils::get_node_url("MATIC")); - let result = ETH::broadcast(tx, Some(node)).await?; - Ok(BroadcastResult::new(convert_transaction(result.tx)?)) - } - - #[wasm_bindgen(js_name = "validateAddress")] - pub fn validate_address( - address: &str, - option: Option, - ) -> Result { - ETH::validate_address(address, option) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use hex::FromHex; - use kos_crypto::secp256k1::Secp256k1KeyPair; - use kos_types::Bytes32; - - const DEFAULT_PRIVATE_KEY: &str = - "1ab42cc412b618bdea3a599e3c9bae199ebf030895b039e9db1e30dafb12b727"; - const DEFAULT_ADDRESS: &str = "0x9858EfFD232B4033E47d90003D41EC34EcaEda94"; - const DEFAULT_MNEMONIC: &str = - "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"; - - fn init() { - std::env::set_var("NODE_MATIC", "https://matic.node.klever.io"); - } - - fn get_default_secret() -> KeyPair { - let b = Bytes32::from_hex(DEFAULT_PRIVATE_KEY).unwrap(); - let kp = Secp256k1KeyPair::new(b.into()); - KeyPair::new_secp256k1(kp) - } - - #[test] - fn test_address_from_private_key() { - let address = MATIC::get_address_from_keypair(&get_default_secret()).unwrap(); - - assert_eq!(DEFAULT_ADDRESS, address); - } - - #[test] - fn test_validate_bip44() { - let v = vec![ - (0, "0x9858EfFD232B4033E47d90003D41EC34EcaEda94"), - (1, "0x6Fac4D18c912343BF86fa7049364Dd4E424Ab9C0"), - (2, "0xb6716976A3ebe8D39aCEB04372f22Ff8e6802D7A"), - (3, "0xF3f50213C1d2e255e4B2bAD430F8A38EEF8D718E"), - (4, "0x51cA8ff9f1C0a99f88E86B8112eA3237F55374cA"), - ]; - - for (index, expected_addr) in v { - let path = MATIC::get_path(&PathOptions::new(index)).unwrap(); - let kp = MATIC::keypair_from_mnemonic(DEFAULT_MNEMONIC, &path, None).unwrap(); - let addr = MATIC::get_address_from_keypair(&kp).unwrap(); - - assert_eq!(expected_addr, addr); - } - } - - #[test] - fn test_send_and_sign() { - let options = models::SendOptions { - data: Some(models::Options::Polygon(kos_proto::options::MATICOptions { - eth: kos_proto::options::ETHOptions { - chain_id: Some(CHAIN_ID), - nonce: Some(100), - max_fee_per_gas: Some("1000000000".try_into().unwrap()), - max_priority_fee_per_gas: Some("1000000000".try_into().unwrap()), - ..Default::default() - }, - })), - }; - - let tx = tokio_test::block_on(MATIC::send( - DEFAULT_ADDRESS.to_string(), - "0x6Fac4D18c912343BF86fa7049364Dd4E424Ab9C0".to_string(), - "1000".try_into().unwrap(), - Some(options), - None, - )) - .unwrap(); - - assert_eq!( - tx.hash.to_string(), - "ce4fdd2a2d7767a4d4df8533bd1218a51755e6d15f814a20d3fa834e27c8602c" - ); - - let signed = MATIC::sign(tx, &get_default_secret()); - assert!(signed.is_ok()); - assert_eq!( - signed.unwrap().hash.to_string(), - "df531bd12423bc8c2a047c01a30b1513a41b47e81d75904a703bdb1d8962bd22" - ); - } - - #[test] - fn test_send_erc20() { - std::env::set_var("NODE_MATIC", "https://matic.node.klever.io"); - let options = models::SendOptions { - data: Some(models::Options::Polygon(kos_proto::options::MATICOptions { - eth: kos_proto::options::ETHOptions { - chain_id: Some(CHAIN_ID), - nonce: Some(100), - token: Some("0xc12d1c73ee7dc3615ba4e37e4abfdbddfa38907e".to_string()), - gas_limit: Some(1000000.into()), - gas_price: Some(0.into()), - max_fee_per_gas: Some(0.into()), - max_priority_fee_per_gas: Some(0.into()), - ..Default::default() - }, - })), - }; - - let tx = tokio_test::block_on(MATIC::send( - DEFAULT_ADDRESS.to_string(), - "0x6Fac4D18c912343BF86fa7049364Dd4E424Ab9C0".to_string(), - "1000".try_into().unwrap(), - Some(options), - None, - )) - .unwrap(); - assert_eq!( - tx.hash.to_string(), - "531d345f8aa0a5ff3625d758e53ff601fa8e2a060bc7a3a1b83e50e927fbb5f5" - ); - - let polygon_tx = match tx.data.clone() { - Some(models::TransactionRaw::Polygon(tx)) => tx, - _ => panic!("invalid tx"), - }; - - assert_eq!(polygon_tx.eth.value.to_string(), "0"); - assert_eq!(hex::encode(polygon_tx.eth.data), "a9059cbb0000000000000000000000006fac4d18c912343bf86fa7049364dd4e424ab9c000000000000000000000000000000000000000000000000000000000000003e8"); - - let signed = MATIC::sign(tx, &get_default_secret()); - assert!(signed.is_ok()); - assert_eq!( - signed.unwrap().hash.to_string(), - "1b570ed15ef11db9860618fce69ac0a6b50cef5403cefa94c86483103ae2bde3" - ); - } - - #[test] - fn test_get_balance() { - init(); - let balance = - tokio_test::block_on(MATIC::get_balance(DEFAULT_ADDRESS, None, None)).unwrap(); - - assert!(balance.to_i64() >= 0); - } - - #[test] - fn test_get_balance_erc20() { - init(); - let balance = tokio_test::block_on(MATIC::get_balance( - DEFAULT_ADDRESS, - Some("0x19a935cbaaa4099072479d521962588d7857d717".to_string()), - None, - )); - assert!(balance.is_ok()); - - assert_eq!(balance.unwrap().to_string(), "1000000000000000000000"); - } -} diff --git a/packages/kos-sdk/src/chains/tron/address.rs b/packages/kos-sdk/src/chains/tron/address.rs deleted file mode 100644 index 7d06e2b..0000000 --- a/packages/kos-sdk/src/chains/tron/address.rs +++ /dev/null @@ -1,196 +0,0 @@ -use kos_crypto::keypair::KeyPair; -use kos_types::error::Error; - -use base58::{FromBase58, ToBase58}; -use hex::FromHex; -use std::{fmt, str::FromStr}; - -use wasm_bindgen::prelude::*; - -/// The mainnet uses 0x41('A') as address type prefix. -pub const ADDRESS_TYPE_PREFIX: u8 = 0x41; -pub const ADDRESS_LEN: usize = 21; -pub const ADDRESS_LEN_STR: usize = 34; -pub const ADDRESS_TYPE_PREFIX_STR: &str = "T"; - -/// Address of Tron, saved in 21-byte format. -#[derive(PartialEq, Eq, Clone, Copy, Hash, PartialOrd, Ord)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[repr(transparent)] -#[wasm_bindgen(js_name = "TRXAddress")] -pub struct Address([u8; ADDRESS_LEN]); - -impl Address { - /// Address of a public key. - pub fn from_public(public: [u8; 64]) -> Address { - let digest = kos_crypto::hash::keccak256(&public); - - let mut raw = [ADDRESS_TYPE_PREFIX; ADDRESS_LEN]; - raw[1..ADDRESS_LEN].copy_from_slice(&digest[digest.len() - 20..]); - - Address(raw) - } - - /// Address of a private key. - pub fn from_keypair(kp: &KeyPair) -> Address { - Address::from_public(kp.public_key().try_into().unwrap()) - } - - /// As raw 21-byte address. - pub fn as_bytes(&self) -> &[u8] { - &self.0 - } - - /// As 20-byte address that compatiable with Ethereum. - pub fn as_tvm_bytes(&self) -> &[u8] { - &self.0[1..] - } - - /// Address from 20-byte address that compatiable with Ethereum. - pub fn from_tvm_bytes(raw: &[u8]) -> Self { - assert!(raw.len() == 20); - - let mut inner = [ADDRESS_TYPE_PREFIX; ADDRESS_LEN]; - inner[1..ADDRESS_LEN].copy_from_slice(raw); - Address(inner) - } - - /// Address from raw 21-byte. - pub fn from_bytes(raw: &[u8]) -> &Address { - assert!(raw.len() == ADDRESS_LEN); - - unsafe { std::mem::transmute(&raw[0]) } - } - - /// To hex address, i.e. 41-address. - pub fn to_hex_address(self) -> String { - hex::encode(self.0) - } -} - -impl fmt::Display for Address { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - b58encode_check(self.0).fmt(f) - } -} - -impl ::std::fmt::Debug for Address { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - f.debug_tuple("Address").field(&self.to_string()).finish() - } -} - -impl TryFrom<&[u8]> for Address { - type Error = Error; - - fn try_from(value: &[u8]) -> Result { - if value.len() != ADDRESS_LEN { - Err(Error::InvalidAddress(format!( - "invalid length: {}", - value.len() - ))) - } else { - let mut raw = [0u8; ADDRESS_LEN]; - raw[..ADDRESS_LEN].copy_from_slice(value); - Ok(Address(raw)) - } - } -} - -impl TryFrom> for Address { - type Error = Error; - - fn try_from(value: Vec) -> Result { - Self::try_from(&value[..]) - } -} - -impl TryFrom<&Vec> for Address { - type Error = Error; - - fn try_from(value: &Vec) -> Result { - Self::try_from(&value[..]) - } -} - -impl TryFrom<&str> for Address { - type Error = Error; - - fn try_from(value: &str) -> Result { - Address::from_str(value) - } -} - -impl FromHex for Address { - type Error = Error; - - fn from_hex>(hex: T) -> Result { - Address::try_from(hex.as_ref()) - } -} - -impl FromStr for Address { - type Err = Error; - - fn from_str(s: &str) -> Result - where - Self: Sized, - { - if s.len() == ADDRESS_LEN_STR && s.starts_with(ADDRESS_TYPE_PREFIX_STR) { - return b58decode_check(s).and_then(Address::try_from); - } - - if s.len() == 42 && s[..2] == hex::encode([ADDRESS_TYPE_PREFIX]) { - return Vec::from_hex(s) - .map_err(|e| Error::InvalidAddress(e.to_string())) - .and_then(Address::try_from); - } - - if s.len() == 44 && (s.starts_with("0x") || s.starts_with("0X")) { - return Vec::from_hex(&s.as_bytes()[2..]) - .map_err(|e| Error::InvalidAddress(e.to_string())) - .and_then(Address::try_from); - } - - if s == "_" || s == "0x0" || s == "/0" { - return "410000000000000000000000000000000000000000".parse(); - } - - eprintln!("len={} prefix={:x}", s.len(), s.as_bytes()[0]); - Err(Error::InvalidAddress("invalid tron address".to_string())) - } -} - -// NOTE: AsRef<[u8]> implies ToHex -impl AsRef<[u8]> for Address { - fn as_ref(&self) -> &[u8] { - &self.0 - } -} - -/// Base58check encode. -pub fn b58encode_check>(raw: T) -> String { - let digest1 = kos_crypto::hash::sha256(raw.as_ref()); - let digest2 = kos_crypto::hash::sha256(&digest1); - - let mut raw = raw.as_ref().to_owned(); - raw.extend(&digest2[..4]); - raw.to_base58() -} - -/// Base58check decode. -pub fn b58decode_check(s: &str) -> Result, Error> { - let mut result = s - .from_base58() - .map_err(|e| Error::InvalidAddress(format!("base58: {:?}", e)))?; - - let check = result.split_off(result.len() - 4); - let digest1 = kos_crypto::hash::sha256(&result); - let digest2 = kos_crypto::hash::sha256(&digest1); - - if check != digest2[..4] { - Err(Error::InvalidChecksum("base58check")) - } else { - Ok(result) - } -} diff --git a/packages/kos-sdk/src/chains/tron/mod.rs b/packages/kos-sdk/src/chains/tron/mod.rs deleted file mode 100644 index 6cddd0d..0000000 --- a/packages/kos-sdk/src/chains/tron/mod.rs +++ /dev/null @@ -1,722 +0,0 @@ -pub mod address; -pub mod requests; - -use std::str::FromStr; - -use crate::{ - chain::{self, BaseChain}, - chains::ethereum::address::Address as ETHAddress, - chains::evm20, - models::{BroadcastResult, PathOptions, Transaction, TransactionRaw}, -}; -use kos_crypto::{keypair::KeyPair, secp256k1::Secp256k1KeyPair}; -use kos_types::error::Error; -use kos_types::hash::Hash; -use kos_types::number::BigNumber; - -use kos_proto::tron::transaction::contract::ContractType; -use wasm_bindgen::prelude::*; -use web3::{ethabi, types::U256}; - -#[derive(Debug, Copy, Clone)] -#[wasm_bindgen] -pub struct TRX {} - -pub const SIGN_PREFIX: &[u8; 22] = b"\x19TRON Signed Message:\n"; -pub const BIP44_PATH: u32 = 195; -pub const BASE_CHAIN: BaseChain = BaseChain { - name: "Tron", - symbol: "TRX", - precision: 6, - chain_code: 1, -}; - -#[wasm_bindgen] -impl TRX { - #[wasm_bindgen(js_name = "baseChain")] - pub fn base_chain() -> BaseChain { - BASE_CHAIN - } - - fn get_options(options: Option) -> kos_proto::options::TRXOptions { - match options.and_then(|opt| opt.data) { - Some(crate::models::Options::Tron(op)) => op, - _ => kos_proto::options::TRXOptions::default(), - } - } - - #[wasm_bindgen(js_name = "random")] - pub fn random() -> Result { - let mut rng = rand::thread_rng(); - let kp = Secp256k1KeyPair::random(&mut rng); - Ok(KeyPair::new_secp256k1(kp)) - } - - #[wasm_bindgen(js_name = "keypairFromBytes")] - pub fn keypair_from_bytes(private_key: &[u8]) -> Result { - // copy to fixed length array - let mut pk_slice = [0u8; 32]; - pk_slice.copy_from_slice(private_key); - - let kp = Secp256k1KeyPair::new(pk_slice); - Ok(KeyPair::new_secp256k1(kp)) - } - - #[wasm_bindgen(js_name = "keypairFromMnemonic")] - pub fn keypair_from_mnemonic( - mnemonic: &str, - path: &str, - password: Option, - ) -> Result { - let kp = Secp256k1KeyPair::new_from_mnemonic_phrase_with_path( - mnemonic, - path, - password.as_deref(), - )?; - - Ok(KeyPair::new_secp256k1(kp)) - } - - #[wasm_bindgen(js_name = "getAddressFromKeyPair")] - pub fn get_address_from_keypair(kp: &KeyPair) -> Result { - Ok(address::Address::from_keypair(kp).to_string()) - } - - #[wasm_bindgen(js_name = "getPath")] - pub fn get_path(options: &PathOptions) -> Result { - let index = options.index; - - let is_legacy = options.is_legacy.unwrap_or(false); - - if is_legacy { - Ok(format!("m/44'/{}'/{}'", BIP44_PATH, index)) - } else { - // use account 0 index X - Ok(format!("m/44'/{}'/0'/0/{}", BIP44_PATH, index)) - } - } - - #[wasm_bindgen(js_name = "signDigest")] - /// Sign digest data with the private key. - pub fn sign_digest(digest: &[u8], keypair: &KeyPair) -> Result, Error> { - let raw = keypair.sign_digest(digest); - Ok(raw) - } - - #[wasm_bindgen(js_name = "verifyDigest")] - /// Verify Message signature - pub fn verify_digest(_digest: &[u8], _signature: &[u8], _address: &str) -> Result { - todo!() - } - - #[wasm_bindgen(js_name = "sign")] - /// Hash and Sign data with the private key. - pub fn sign(tx: Transaction, keypair: &KeyPair) -> Result { - match tx.data { - Some(TransactionRaw::Tron(trx_tx)) => { - let mut new_tx = trx_tx.clone(); - let digest = TRX::hash_transaction(&trx_tx)?; - let sig = TRX::sign_digest(digest.as_slice(), keypair)?; - let hex_sig = hex::encode(sig.clone()); - - new_tx.signature.push(sig); - let result = Transaction { - chain: tx.chain, - sender: tx.sender, - hash: Hash::from_vec(digest)?, - data: Some(TransactionRaw::Tron(new_tx)), - signature: Some(hex_sig), - }; - - Ok(result) - } - _ => Err(Error::InvalidMessage("not a tron transaction".to_string())), - } - } - - fn hash_transaction(tx: &kos_proto::tron::Transaction) -> Result, Error> { - if let Some(raw_data) = &tx.raw_data { - let bytes = kos_proto::write_message(raw_data); - TRX::hash(&bytes) - } else { - Err(Error::InvalidTransaction("trx raw_data".to_string())) - } - } - - #[wasm_bindgen(js_name = "hash")] - /// hash digest - pub fn hash(message: &[u8]) -> Result, Error> { - let digest = kos_crypto::hash::sha256(message); - Ok(digest.to_vec()) - } - - #[wasm_bindgen(js_name = "messageHash")] - /// Append prefix and hash the message - pub fn message_hash(message: &[u8]) -> Result, Error> { - let to_sign = [SIGN_PREFIX, message.len().to_string().as_bytes(), message].concat(); - - TRX::hash(&to_sign) - } - - #[wasm_bindgen(js_name = "signMessage")] - /// Sign Message with the private key. - pub fn sign_message(message: &[u8], keypair: &KeyPair) -> Result, Error> { - let m = TRX::message_hash(message)?; - TRX::sign_digest(&m, keypair) - } - - #[wasm_bindgen(js_name = "verifyMessageSignature")] - /// Verify Message signature - pub fn verify_message_signature( - message: &[u8], - signature: &[u8], - address: &str, - ) -> Result { - let m = TRX::message_hash(message)?; - TRX::verify_digest(&m, signature, address) - } - - #[wasm_bindgen(js_name = "getBalance")] - /// Get balance of address and token - /// If token is None, it will return balance of native token - /// If token is Some, it will return balance of token - /// If node_url is None, it will use default node url - pub async fn get_balance( - addr: &str, - token: Option, - node_url: Option, - ) -> Result { - let node = node_url.unwrap_or_else(|| crate::utils::get_node_url("TRX")); - - let acc_address = address::Address::from_str(addr)?; - - // check if TRC20 -> trigger contract instead todo!() - let acc = requests::get_account(&node, &acc_address.to_hex_address()).await?; - - Ok(match token { - Some(key) if key != "TRX" => match acc.asset_v2.get(&key) { - Some(value) => BigNumber::from(*value), - None => BigNumber::from(0), - }, - _ => BigNumber::from(acc.balance), - }) - } - - async fn trigger_asset_transfer( - addr_sender: &address::Address, - addr_receiver: &address::Address, - amount: &BigNumber, - token: &str, - node: &str, - ) -> Result { - let contract = kos_proto::tron::TransferAssetContract { - owner_address: addr_sender.as_bytes().to_vec(), - to_address: addr_receiver.as_bytes().to_vec(), - amount: amount.to_i64(), - asset_name: token.as_bytes().to_vec(), - }; - let transaction = requests::create_asset_transfer(node, contract).await?; - Ok(transaction) - } - - async fn trigger_trc20_transfer( - addr_sender: &address::Address, - addr_receiver: &address::Address, - amount: &BigNumber, - token: &str, - node: &str, - fee_limit: &i64, - ) -> Result { - let contract = evm20::get_contract_evm20(); - let func = contract.function("transfer").map_err(|e| { - Error::InvalidMessage(format!("failed to get transfer function: {}", e)) - })?; - - let to_address = *ETHAddress::from_bytes(addr_receiver.as_tvm_bytes()); - let encoded = func - .encode_input(&[ - ethabi::Token::Address(to_address.into()), - ethabi::Token::Uint( - U256::from_dec_str(&amount.to_string()) - .map_err(|e| Error::InvalidNumberParse(e.to_string()))?, - ), - ]) - .map_err(|e| Error::InvalidTransaction(e.to_string()))?; - let contract_address = address::Address::from_str(token)?; - - let contract = kos_proto::tron::TriggerSmartContract { - owner_address: addr_sender.as_bytes().to_vec(), - contract_address: contract_address.as_bytes().to_vec(), - data: encoded, - call_token_value: 0, - call_value: 0, - token_id: 0, - }; - - let extended = requests::ContractOptions { - contract, - // TODO: estimate fee limit, for now use 100 TRX - fee_limit: fee_limit | 100000000, - }; - let transaction = requests::trigger_smartcontract(node, extended).await?; - Ok(transaction) - } - - /// create a send transaction network - #[wasm_bindgen(js_name = "send")] - pub async fn send( - sender: String, - receiver: String, - amount: BigNumber, - options: Option, - node_url: Option, - ) -> Result { - let node = node_url.unwrap_or_else(|| crate::utils::get_node_url("TRX")); - let addr_sender = address::Address::from_str(&sender)?; - let addr_receiver = address::Address::from_str(&receiver)?; - - let options = TRX::get_options(options); - - let fee_limit = options.fee_limit.unwrap_or(0); - - let tx: kos_proto::tron::Transaction = match options.token { - Some(token) if token != "TRX" => { - // Check if TRC20 transfer - let valid_address = TRX::validate_address(&token, None)?; - if valid_address { - TRX::trigger_trc20_transfer( - &addr_sender, - &addr_receiver, - &amount, - &token, - &node, - &fee_limit, - ) - .await? - } else { - TRX::trigger_asset_transfer( - &addr_sender, - &addr_receiver, - &amount, - &token, - &node, - ) - .await? - } - } - _ => { - let contract = kos_proto::tron::TransferContract { - owner_address: addr_sender.as_bytes().to_vec(), - to_address: addr_receiver.as_bytes().to_vec(), - amount: amount.to_i64(), - }; - - requests::create_transfer(&node, contract).await? - } - }; - // update memo field - let tx = match options.memo { - Some(memo) => { - let mut tx = tx.clone(); - tx.raw_data.as_mut().unwrap().data = memo.as_bytes().to_vec(); - tx - } - None => tx, - }; - - let digest = TRX::hash_transaction(&tx)?; - - Ok(crate::models::Transaction { - chain: chain::Chain::TRX, - sender, - hash: Hash::from_vec(digest)?, - data: Some(TransactionRaw::Tron(tx)), - signature: None, - }) - } - - #[wasm_bindgen(js_name = "broadcast")] - pub async fn broadcast( - tx: crate::models::Transaction, - node_url: Option, - ) -> Result { - let node = node_url.unwrap_or_else(|| crate::utils::get_node_url("TRX")); - - let raw = tx - .data - .clone() - .ok_or_else(|| Error::ReqwestError("Missing transaction data".into()))?; - - let result = requests::broadcast(node.as_str(), raw.try_into()?).await?; - - if let Some(false) = result.get("result").and_then(|v| v.as_bool()) { - let error_message = result - .get("message") - .and_then(|m| m.as_str()) - .unwrap_or("no message"); - return Err(Error::InvalidTransaction(format!( - "Expected successful broadcast, got: {:?}", - error_message - ))); - } - - Ok(BroadcastResult::new(crate::models::Transaction { - chain: tx.chain, - sender: tx.sender, - hash: tx.hash, - data: tx.data, - signature: tx.signature, - })) - } - - #[wasm_bindgen(js_name = "validateAddress")] - pub fn validate_address( - addr: &str, - _option: Option, - ) -> Result { - if addr.len() == address::ADDRESS_LEN_STR - && addr.starts_with(address::ADDRESS_TYPE_PREFIX_STR) - { - let check = address::b58decode_check(addr); - if check.is_err() { - return Ok(false); - } - - let check = check.unwrap(); - - // check mainnet prefix - if check[0] == address::ADDRESS_TYPE_PREFIX { - return Ok(true); - } - } - - Ok(false) - } - - #[wasm_bindgen(js_name = "serializeTxIntoRawHex")] - pub fn serialize_tx_into_raw_hex(raw: &str) -> Result { - let raw: kos_proto::tron::Transaction = serde_json::from_str(raw)?; - - let bytes = kos_proto::write_message(&raw); - Ok(hex::encode(bytes)) - } - - #[wasm_bindgen(js_name = "serializeRawDataIntoHexString")] - pub fn serialize_raw_data_into_hex_string(tx: &str) -> Result { - let t: kos_proto::tron::Transaction = serde_json::from_str(tx)?; - let raw_data = t.raw_data.ok_or(Error::InvalidTransaction( - "Transaction raw data is missing.".to_string(), - ))?; - let bytes = kos_proto::write_message(&raw_data); - Ok(hex::encode(bytes)) - } - - pub fn tx_from_raw(data: &str) -> Result { - let raw_data_bytes = hex::decode(data)?; - let raw_data: kos_proto::tron::transaction::Raw = - kos_proto::from_bytes(raw_data_bytes).unwrap(); - - let contract = raw_data - .contract - .first() - .ok_or_else(|| Error::InvalidTransaction("Missing contract".to_string()))?; - - let sender: String = TRX::extract_address_from_contract(contract)?; - - let tx = kos_proto::tron::Transaction { - raw_data: Some(raw_data), - signature: Vec::new(), - ret: Vec::new(), - }; - - let hash = Hash::from_vec(TRX::hash_transaction(&tx)?)?; - - let signature = tx.signature.first().map(hex::encode); - - Ok(Transaction { - chain: chain::Chain::TRX, - sender, - hash, - data: Some(TransactionRaw::Tron(tx)), - signature, - }) - } - - fn extract_address_from_contract( - contract: &kos_proto::tron::transaction::Contract, - ) -> Result { - let contract_type = ContractType::from_i32(contract.r#type) - .ok_or_else(|| Error::InvalidTransaction("Invalid contract type".to_string()))?; - - let address = match contract_type { - ContractType::TransferContract => { - let parameter: kos_proto::tron::TransferContract = - kos_proto::unpack_from_option_any(&contract.parameter).unwrap(); - address::Address::from_bytes(parameter.owner_address.as_slice()).to_string() - } - ContractType::TransferAssetContract => { - let parameter: kos_proto::tron::TransferAssetContract = - kos_proto::unpack_from_option_any(&contract.parameter).unwrap(); - address::Address::from_bytes(parameter.owner_address.as_slice()).to_string() - } - ContractType::TriggerSmartContract => { - let parameter: kos_proto::tron::TriggerSmartContract = - kos_proto::unpack_from_option_any(&contract.parameter).unwrap(); - address::Address::from_bytes(parameter.owner_address.as_slice()).to_string() - } - _ => "".to_string(), - }; - - Ok(address) - } -} - -#[cfg(test)] -mod tests { - use std::assert_eq; - use std::str; - - use hex::FromHex; - - use kos_types::Bytes32; - - use crate::models::SendOptions; - - use super::*; - - const DEFAULT_PRIVATE_KEY: &str = - "b5a4cea271ff424d7c31dc12a3e43e401df7a40d7412a15750f3f0b6b5449a28"; - const DEFAULT_ADDRESS: &str = "TUEZSdKsoDHQMeZwihtdoBiN46zxhGWYdH"; - - fn get_default_secret() -> KeyPair { - let b = Bytes32::from_hex(DEFAULT_PRIVATE_KEY).unwrap(); - let kp = Secp256k1KeyPair::new(b.into()); - KeyPair::new_secp256k1(kp) - } - - #[test] - fn test_address_from_mnemonic() { - let path = TRX::get_path(&PathOptions::new(0)).unwrap(); - let kp = TRX::keypair_from_mnemonic("abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about", &path, None).unwrap(); - let address = TRX::get_address_from_keypair(&kp).unwrap(); - - assert_eq!(DEFAULT_ADDRESS, address); - } - - #[test] - fn test_address_from_private_key() { - let address = TRX::get_address_from_keypair(&get_default_secret()).unwrap(); - - assert_eq!(DEFAULT_ADDRESS, address); - } - - #[test] - fn test_get_balance() { - let balance = tokio_test::block_on(TRX::get_balance( - "TWd4WrZ9wn84f5x1hZhL4DHvk738ns5jwb", - Some("TRX".to_string()), - None, - )) - .unwrap(); - println!("balance: {}", balance.to_string()); - - assert!(balance.to_number() > 0 as f64); - } - - #[test] - fn test_send() { - let result = tokio_test::block_on(TRX::send( - "TAUN6FwrnwwmaEqYcckffC7wYmbaS6cBiX".to_string(), - DEFAULT_ADDRESS.to_string(), - BigNumber::from(10), - None, - Some("https://tron.node.klever.io".to_string()), - )); - - assert!(result.is_ok()); - let t = result.unwrap().clone(); - match t.clone().data { - Some(TransactionRaw::Tron(tx)) => { - let raw = &tx.raw_data.unwrap(); - assert_eq!(raw.contract.len(), 1); - let c: kos_proto::tron::TransferContract = - kos_proto::unpack_from_option_any(&raw.contract.get(0).unwrap().parameter) - .unwrap(); - - assert_eq!(c.amount, 10); - } - _ => assert!(false), - } - } - - #[test] - fn test_send_trc20() { - // create TRX send options - let trx_options = kos_proto::options::TRXOptions { - token: Some("TKk6DLX1xWRKHjDhHfdyQKefnP1WUppEXB".to_string()), - ..Default::default() - }; - - let options = SendOptions::new_tron_send_options(trx_options); - - let result = tokio_test::block_on(TRX::send( - "TCwwZeH6so1X4R5kcdbKqa4GWuzF53xPqG".to_string(), - DEFAULT_ADDRESS.to_string(), - BigNumber::from(1000000), - Some(options), - None, - )); - - assert!(result.is_ok()); - let t = result.unwrap().clone(); - match t.clone().data { - Some(TransactionRaw::Tron(tx)) => { - let raw = &tx.raw_data.unwrap(); - assert_eq!(raw.contract.len(), 1); - let c: kos_proto::tron::TriggerSmartContract = - kos_proto::unpack_from_option_any(&raw.contract.get(0).unwrap().parameter) - .unwrap(); - let data: String = c.data.iter().map(|b| format!("{:02X}", b)).collect(); - let owner_address = address::Address::from_bytes(&c.owner_address); - let contract_address = address::Address::from_bytes(&c.contract_address); - assert!(data.starts_with("A9059CBB")); - assert_eq!( - owner_address.to_string(), - "TCwwZeH6so1X4R5kcdbKqa4GWuzF53xPqG".to_string() - ); - assert_eq!( - contract_address.to_string(), - "TKk6DLX1xWRKHjDhHfdyQKefnP1WUppEXB".to_string() - ); - } - _ => assert!(false), - } - } - - #[test] - fn test_validate_bip44() { - let default_mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"; - let v = vec![ - (0, "TUEZSdKsoDHQMeZwihtdoBiN46zxhGWYdH"), - (1, "TSeJkUh4Qv67VNFwY8LaAxERygNdy6NQZK"), - (2, "TYJPRrdB5APNeRs4R7fYZSwW3TcrTKw2gx"), - (3, "TRhVWK5XEDkQBDevcdCWW7RW51aRncty4W"), - (4, "TT2X2yyubp7qpAWYYNE5JQWBtoZ7ikQFsY"), - ]; - - for (index, expected_addr) in v { - let path = TRX::get_path(&PathOptions::new(index)).unwrap(); - let kp = TRX::keypair_from_mnemonic(default_mnemonic, &path, None).unwrap(); - let addr = TRX::get_address_from_keypair(&kp).unwrap(); - - assert_eq!(expected_addr, addr); - } - } - - #[test] - fn test_validate_address_ok() { - // valid addresses - let list = [ - "TUEZSdKsoDHQMeZwihtdoBiN46zxhGWYdH", - "TSeJkUh4Qv67VNFwY8LaAxERygNdy6NQZK", - "TYJPRrdB5APNeRs4R7fYZSwW3TcrTKw2gx", - "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", - ]; - - for addr in list { - let result = TRX::validate_address(addr, None); - assert!(result.is_ok()); - - let result = result.unwrap(); - assert_eq!(result, true, "address: {}", addr); - } - } - - #[test] - fn test_validate_address_invalid() { - // invalid addresses - let list = [ - "TuEZSdKsoDHQMeZwihtdoBiN46zxhGWYdH", - "TronEnergyioE1Z3ukeRv38sYkv5Jn55bL", - "TronEnergyioNijNo8g3LF2ABKUAae6D2Z", - "TUEZSdKsoDHQMeZwihtdoBiN46zxhGWYdH1", - "0x9858EfFD232B4033E47d90003D41EC34EcaEda94", - ]; - - for addr in list { - let result = TRX::validate_address(addr, None); - assert!(result.is_ok()); - - let result = result.unwrap(); - assert_eq!(result, false, "address: {}", addr); - } - } - - #[test] - fn test_serialize_raw_data_into_hex_string() { - let result = tokio_test::block_on(TRX::send( - "TAUN6FwrnwwmaEqYcckffC7wYmbaS6cBiX".to_string(), - DEFAULT_ADDRESS.to_string(), - BigNumber::from(10), - None, - Some("https://tron.node.klever.io".to_string()), - )); - - let t = result.unwrap().clone(); - match t.clone().data { - Some(TransactionRaw::Tron(tx)) => { - let raw = tx.clone().raw_data.unwrap(); - assert_eq!(raw.contract.len(), 1); - let c: kos_proto::tron::TransferContract = - kos_proto::unpack_from_option_any(&raw.contract.get(0).unwrap().parameter) - .unwrap(); - - assert_eq!(c.amount, 10); - let raw_data_string = t.get_raw().unwrap(); - let hex_string_tx = - TRX::serialize_raw_data_into_hex_string(&raw_data_string).unwrap(); - println!("tx: {:?}", hex_string_tx); - assert!(hex_string_tx.len() > 0); - } - _ => assert!(false), - } - } - - #[test] - fn test_serialize_raw_data_empty_input() { - let result = TRX::serialize_raw_data_into_hex_string(""); - assert!(result.is_err()); - } - - #[test] - fn test_serialize_raw_data_invalid_format() { - let invalid_tx = "invalid_json_format"; - let result = TRX::serialize_raw_data_into_hex_string(invalid_tx); - assert!(result.is_err()); - } - - #[test] - fn test_tx_from_raw() { - let tx = "0a02d8372208e9c73b516bcd78844088c6e8ad9a325a67080112630a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412320a1541e825d52582eec346c839b4875376117904a76cbc12154120ab1300cf70c048e4cf5d5b1b33f59653ed662618c0843d70fdfee4ad9a32"; - let result = TRX::tx_from_raw(tx); - assert!(result.is_ok()); - let t = result.unwrap(); - assert_eq!(t.chain, chain::Chain::TRX); - assert_eq!(t.sender, "TX8h6Df74VpJsXF6sTDz1QJsq3Ec8dABc3"); - assert_eq!( - t.hash.to_string(), - "3e6c463b2e88d78e912dee3aa31a14aa71c0e56bbdfbdbba012c8af4e45b8834" - ); - - let trigger_smart_contract_tx = "0a029af222085e42eee56c43056140d0c8aeec9d325ad402081f12cf020a31747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e54726967676572536d617274436f6e74726163741299020a15415ad61eb25c69f75711f059e106bc1ca1b338a814121541ff7155b5df8008fbf3834922b2d52430b27874f518c0843d22e4017ff36ab500000000000000000000000000000000000000000000099d6ced5f1867f3579900000000000000000000000000000000000000000000000000000000000000800000000000000000000000005ad61eb25c69f75711f059e106bc1ca1b338a8140000000000000000000000000000000000000000000000000000000066e0a6d40000000000000000000000000000000000000000000000000000000000000002000000000000000000000000891cdb91d149f23b1a45d9c5ca78a88d0cb44c18000000000000000000000000691a8e6e5b03bf79e133be5ac6cdc0986142e684708afdaaec9d3290018094ebdc03"; - let result = TRX::tx_from_raw(trigger_smart_contract_tx); - assert!(result.is_ok()); - let t = result.unwrap(); - assert_eq!(t.chain, chain::Chain::TRX); - assert_eq!(t.sender, "TJFWKdqCxgqu4LngZrC6mRvrpT4fGAsznp"); - assert_eq!( - t.hash.to_string(), - "066b49fab01944699516efc5c3d636f150c12d7e157e4867c155b29d94edb018" - ); - } -} diff --git a/packages/kos-sdk/src/chains/tron/requests.rs b/packages/kos-sdk/src/chains/tron/requests.rs deleted file mode 100644 index abea6f8..0000000 --- a/packages/kos-sdk/src/chains/tron/requests.rs +++ /dev/null @@ -1,124 +0,0 @@ -use crate::utils; -use kos_types::error::Error; -use serde::Serialize; -use serde_json::json; - -#[derive(Serialize)] -pub struct ContractOptions { - #[serde(flatten)] - pub contract: kos_proto::tron::TriggerSmartContract, - pub fee_limit: i64, -} - -pub async fn get_account(node_url: &str, address: &str) -> Result { - let url = format!("{}/wallet/getaccount", node_url); - - let data = json!({ "address": address }).to_string().into_bytes(); - - let mut r: serde_json::Value = utils::http_post::(url, &data).await?; - - // remove hash map for now todo!(): fix this - let v = r.as_object_mut().unwrap(); - for key in [ - "assetV2", - "asset", - "free_asset_net_usage", - "free_asset_net_usageV2", - ] - .into_iter() - { - v.remove(key); - } - - let acc: kos_proto::tron::Account = serde_json::from_str(&r.to_string())?; - - Ok(acc) -} - -pub async fn broadcast( - node_url: &str, - tx: kos_proto::tron::Transaction, -) -> Result { - let url = format!("{}/wallet/broadcasthex", node_url); - - log::debug!( - "Broadcasting to {}\nData: {} ", - url, - serde_json::to_string(&tx)?, - ); - - // hex encode tx data - let tx_raw = kos_proto::write_message(&tx); - - // adjust to tron format - let data = format!("{{\"transaction\": \"{}\"}}", hex::encode(tx_raw),); - - utils::http_post::(url, data.as_bytes()).await -} - -pub async fn create_transfer( - node_url: &str, - contract: kos_proto::tron::TransferContract, -) -> Result { - let url = format!("{}/wallet/createtransaction", node_url); - - create_transaction(url, contract).await -} - -pub async fn create_asset_transfer( - node_url: &str, - contract: kos_proto::tron::TransferAssetContract, -) -> Result { - let url = format!("{}/wallet/transferasset", node_url); - - create_transaction(url, contract).await -} - -pub async fn trigger_smartcontract( - node_url: &str, - contract: ContractOptions, -) -> Result { - let url = format!("{}/wallet/triggersmartcontract", node_url); - - create_transaction(url, contract).await -} - -async fn create_transaction( - url: String, - contract: impl serde::Serialize, -) -> Result { - let data = serde_json::to_string(&contract)?.as_bytes().to_vec(); - let result = utils::http_post::(url, &data).await?; - let raw_hex = unpack_result(result)?; - pack_tx(&raw_hex) -} - -fn pack_tx(raw_hex: &str) -> Result { - // encode raw data - let raw_data_bytes = hex::decode(raw_hex)?; - let raw_data: kos_proto::tron::transaction::Raw = kos_proto::from_bytes(raw_data_bytes) - .map_err(|e| Error::InvalidTransaction(e.to_string()))?; - - Ok(kos_proto::tron::Transaction { - raw_data: Some(raw_data), - signature: Vec::new(), - ret: Vec::new(), - }) -} - -fn unpack_result(value: serde_json::Value) -> Result { - if let Some(v) = value.get("raw_data_hex").and_then(|v| v.as_str()) { - return Ok(v.to_string()); - } - - if let Some(transaction) = value.get("transaction") { - if let Some(v) = transaction.get("raw_data_hex").and_then(|v| v.as_str()) { - return Ok(v.to_string()); - } - } - - match value.get("Error") { - Some(err) => Err(Error::ReqwestError(err.to_string())), - None => Err(Error::ReqwestError("Unknown error".to_string())), - } -} diff --git a/packages/kos-sdk/src/lib.rs b/packages/kos-sdk/src/lib.rs deleted file mode 100644 index e5adaff..0000000 --- a/packages/kos-sdk/src/lib.rs +++ /dev/null @@ -1,7 +0,0 @@ -pub mod chain; -pub mod chains; -pub mod models; -pub mod wallet; -pub mod wm; - -mod utils; diff --git a/packages/kos-sdk/src/models.rs b/packages/kos-sdk/src/models.rs deleted file mode 100644 index 70fdd51..0000000 --- a/packages/kos-sdk/src/models.rs +++ /dev/null @@ -1,276 +0,0 @@ -use crate::chain::Chain; -use crate::chains::{ETH, KLV, TRX}; -use kos_types::{error::Error, hash::Hash}; -use serde::{Deserialize, Serialize}; -use wasm_bindgen::prelude::*; - -#[derive(Debug, Clone, Serialize)] -#[wasm_bindgen] -pub struct BroadcastResult { - #[wasm_bindgen(skip)] - pub tx: Transaction, -} - -#[wasm_bindgen] -impl BroadcastResult { - #[wasm_bindgen(constructor)] - pub fn new(tx: Transaction) -> Self { - Self { tx } - } - - #[wasm_bindgen(js_name = hash)] - pub fn hash(&self) -> Hash { - self.tx.hash - } - - #[allow(clippy::inherent_to_string)] - #[wasm_bindgen(js_name = toString)] - pub fn to_string(&self) -> String { - serde_json::to_string(&self).unwrap() - } -} -#[derive(Default, Deserialize, Serialize, Clone, Debug)] -#[wasm_bindgen] -pub struct PathOptions { - #[wasm_bindgen(skip)] - pub index: u32, - #[wasm_bindgen(skip)] - pub is_legacy: Option, -} - -#[wasm_bindgen] -impl PathOptions { - #[wasm_bindgen(constructor)] - pub fn constructor() -> Self { - Self::default() - } - - pub fn new(index: u32) -> Self { - Self { - index, - is_legacy: Some(false), - } - } - #[wasm_bindgen(js_name = setIndex)] - pub fn set_index(&mut self, index: u32) { - self.index = index; - } - #[wasm_bindgen(js_name = setLegacy)] - pub fn set_legacy(&mut self, is_legacy: bool) { - self.is_legacy = Some(is_legacy); - } -} - -// create enum variant list of transaction types supported -kos_types::enum_thing! { - enum TransactionRaw { - Klever(kos_proto::klever::Transaction), - Tron(kos_proto::tron::Transaction), - Ethereum(super::chains::ETHTransaction), - Polygon(super::chains::MATICTransaction), - Bitcoin(super::chains::BTCTransaction), - } -} - -// create enum variant list of transaction types supported -kos_types::enum_thing! { - enum Options { - Klever(kos_proto::options::KLVOptions), - Tron(kos_proto::options::TRXOptions), - Ethereum(kos_proto::options::ETHOptions), - Polygon(kos_proto::options::MATICOptions), - Bitcoin(kos_proto::options::BTCOptions), - } -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -#[wasm_bindgen] -/// Transaction Handler -pub struct SendOptions { - #[wasm_bindgen(skip)] - #[serde(skip)] - pub data: Option, -} - -impl SendOptions { - pub fn new(data: Options) -> Self { - Self { data: Some(data) } - } -} - -#[wasm_bindgen] -impl SendOptions { - #[wasm_bindgen(js_name = newKleverSendOptions)] - pub fn new_klever_send_options(option: kos_proto::options::KLVOptions) -> Self { - Self { - data: Some(Options::Klever(option)), - } - } - - #[wasm_bindgen(js_name = newTronSendOptions)] - pub fn new_tron_send_options(option: kos_proto::options::TRXOptions) -> Self { - Self { - data: Some(Options::Tron(option)), - } - } - - #[wasm_bindgen(js_name = newEthereumSendOptions)] - pub fn new_ethereum_send_options(option: &kos_proto::options::ETHOptions) -> Self { - Self { - data: Some(Options::Ethereum(option.clone())), - } - } - - #[wasm_bindgen(js_name = newPolygonSendOptions)] - pub fn new_polygon_send_options(option: &kos_proto::options::MATICOptions) -> Self { - Self { - data: Some(Options::Polygon(option.clone())), - } - } - - #[wasm_bindgen(js_name = newBitcoinSendOptions)] - pub fn new_bitcoin_send_options(option: &kos_proto::options::BTCOptions) -> Self { - Self { - data: Some(Options::Bitcoin(option.clone())), - } - } -} - -#[derive(Debug, Clone, Serialize)] -#[wasm_bindgen] -/// Transaction Handler -pub struct Transaction { - #[wasm_bindgen(skip)] - pub chain: Chain, - #[wasm_bindgen(skip)] - pub sender: String, - #[wasm_bindgen(js_name = hash)] - pub hash: Hash, - #[wasm_bindgen(skip)] - pub data: Option, - #[wasm_bindgen(skip)] - pub signature: Option, -} - -#[wasm_bindgen] -impl Transaction { - #[wasm_bindgen(js_name = chain)] - pub fn chain(&self) -> Chain { - self.chain - } - - #[wasm_bindgen(js_name = toString)] - pub fn to_string(&self) -> Result { - serde_json::to_string(&self).map_err(|e| e.into()) - } - - #[wasm_bindgen(js_name = getRaw)] - pub fn get_raw(&self) -> Result { - match &self.data { - Some(data) => match data { - TransactionRaw::Klever(data) => serde_json::to_string(&data).map_err(|e| e.into()), - TransactionRaw::Tron(data) => serde_json::to_string(&data).map_err(|e| e.into()), - TransactionRaw::Ethereum(data) => { - let encoded = data.encode()?; - Ok(hex::encode(encoded)) - } - TransactionRaw::Polygon(data) => { - let encoded = data.eth.encode()?; - Ok(hex::encode(encoded)) - } - TransactionRaw::Bitcoin(data) => { - serde_json::to_string(&data.tx).map_err(|e| e.into()) - } - }, - None => Err(Error::InvalidTransaction("no data found".to_string())), - } - } - - #[wasm_bindgen(js_name = getSignature)] - pub fn get_signature(&self) -> Option { - self.signature.clone() - } -} -impl Transaction { - pub fn new_data(&self, chain: Chain, data: TransactionRaw) -> Transaction { - let mut tx = self.clone(); - tx.chain = chain; - tx.data = Some(data); - tx - } -} - -#[wasm_bindgen] -impl Transaction { - #[wasm_bindgen(js_name = fromRaw)] - pub fn from_raw(chain: Chain, data: &str) -> Result { - match chain { - Chain::KLV => KLV::tx_from_raw(data), - Chain::TRX => TRX::tx_from_raw(data), - Chain::ETH => ETH::tx_from_json(data), - Chain::MATIC => Err(Error::InvalidTransaction( - "MATIC chain not implemented".to_string(), - )), - Chain::BTC => Err(Error::InvalidTransaction( - "BTC chain not implemented".to_string(), - )), - Chain::NONE => Err(Error::InvalidTransaction("Invalid chain".to_string())), - } - } -} - -#[derive(Default, Debug, Clone, Serialize, Deserialize)] -#[wasm_bindgen] -pub struct AddressOptions { - #[wasm_bindgen(skip)] - pub network: Option, - #[wasm_bindgen(skip)] - pub prefix: Option, - #[wasm_bindgen(skip)] - pub check_summed: Option, -} - -#[wasm_bindgen] -impl AddressOptions { - pub fn new( - network: Option, - prefix: Option, - check_summed: Option, - ) -> Self { - Self { - network, - prefix, - check_summed, - } - } - - #[wasm_bindgen(js_name = setNetwork)] - pub fn set_network(&mut self, network: Option) { - self.network = network; - } - - #[wasm_bindgen(js_name = setPrefix)] - pub fn set_prefix(&mut self, prefix: Option) { - self.prefix = prefix; - } - - #[wasm_bindgen(js_name = setCheckSummed)] - pub fn set_check_summed(&mut self, check_summed: Option) { - self.check_summed = check_summed; - } - - #[wasm_bindgen(js_name = getNetwork)] - pub fn get_network(&self) -> Option { - self.network.clone() - } - - #[wasm_bindgen(js_name = getPrefix)] - pub fn get_prefix(&self) -> Option { - self.prefix.clone() - } - - #[wasm_bindgen(js_name = getCheckSummed)] - pub fn get_check_summed(&self) -> Option { - self.check_summed - } -} diff --git a/packages/kos-sdk/src/utils.rs b/packages/kos-sdk/src/utils.rs deleted file mode 100644 index b3f4ab4..0000000 --- a/packages/kos-sdk/src/utils.rs +++ /dev/null @@ -1,88 +0,0 @@ -use kos_types::error::Error; - -use serde::de::DeserializeOwned; - -static APP_USER_AGENT: &str = concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION")); - -#[allow(dead_code)] -#[cfg(not(target_arch = "wasm32"))] -pub fn http_get_block(url: String) -> Result { - let body = reqwest::blocking::get(url).unwrap(); - body.json::().map_err(Error::from) -} - -pub fn get_client() -> Result { - let mut client = reqwest::Client::builder(); - - #[cfg(not(target_arch = "wasm32"))] - { - client = client - .user_agent(APP_USER_AGENT) - .connect_timeout(std::time::Duration::from_secs(20)) - .timeout(std::time::Duration::from_secs(100)); - } - - client - .build() - .map_err(|e| Error::ReqwestError(e.to_string())) -} - -/// HTTP GET request -pub async fn http_get(url: String) -> Result { - let client = get_client()?; - - let body = client.get(url).send().await?; - body.json::().await.map_err(Error::from) -} - -/// HTTP GET request with basic auth -pub async fn http_get_auth(url: String) -> Result { - let client = get_client()?; - - let body = basic_auth(client.get(url)).send().await?; - body.json::().await.map_err(Error::from) -} - -/// HTTP POST request -pub async fn http_post(url: String, data: &[u8]) -> Result { - let client = get_client()?; - - client - .post(url) - .header("Content-Type", "application/json") - .body(data.to_vec()) - .send() - .await - .map_err(Error::from)? - .json::() - .await - .map_err(Error::from) -} - -/// HTTP POST request with basic auth -pub async fn http_post_auth(url: String, data: &[u8]) -> Result { - let client = get_client()?; - - basic_auth(client.post(url)) - .header("Content-Type", "application/json") - .body(data.to_vec()) - .send() - .await - .map_err(Error::from)? - .json::() - .await - .map_err(Error::from) -} - -pub fn get_node_url(name: &str) -> String { - std::env::var(format!("NODE_{}", name)).unwrap_or("".to_string()) -} - -pub fn basic_auth(client: reqwest::RequestBuilder) -> reqwest::RequestBuilder { - if let Ok(user) = std::env::var("KOS_API_USER") { - let pass: Option = std::env::var("KOS_API_PASS").ok(); - return client.basic_auth(user, pass); - } - - client -} diff --git a/packages/kos-sdk/src/wallet.rs b/packages/kos-sdk/src/wallet.rs deleted file mode 100644 index aac57f0..0000000 --- a/packages/kos-sdk/src/wallet.rs +++ /dev/null @@ -1,674 +0,0 @@ -use crate::{ - chain::{BaseChain, Chain}, - models::{self, BroadcastResult, PathOptions, Transaction}, -}; - -use kos_crypto::keypair::KeyPair; -use kos_types::{error::Error, number::BigNumber}; -use kos_utils::{pack, unpack}; - -use pem::{encode as encode_pem, parse as parse_pem, Pem}; -use serde::{Deserialize, Serialize}; -use strum::{EnumCount, IntoStaticStr}; - -use kos_crypto::cipher::CipherAlgo; -use wasm_bindgen::prelude::*; - -// todo!("allow change of default algo") -const DEFAULT_ALGO: CipherAlgo = kos_crypto::cipher::CipherAlgo::GMC; -// todo!("implement wallet auto lock") - -#[wasm_bindgen] -#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Copy, EnumCount, IntoStaticStr)] -pub enum AccountType { - Mnemonic, - PrivateKey, - KleverSafe, - ReadOnly, -} - -#[wasm_bindgen] -#[derive(Debug, Clone)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub struct Wallet { - chain: Chain, - account_type: AccountType, - public_address: String, - is_locked: bool, - node_url: Option, - index: Option, - - encrypted_data: Option>, - mnemonic: Option, - path: Option, - keypair: Option, -} - -#[wasm_bindgen] -impl Wallet { - pub fn wallet_key(chain: crate::chain::Chain, address: &str) -> String { - format!("{}-{}", chain.base_chain().symbol, address) - } - - pub fn get_key(&self) -> String { - Wallet::wallet_key(self.chain, &self.public_address) - } - - /// lock wallet privatekey with password - pub fn lock(&mut self, password: String) -> Result<(), Error> { - // return if is locked - if self.is_locked { - return Ok(()); - } - - // Verify password if encrypted_data is present, else serialize and encrypt wallet - match self.encrypted_data { - Some(_) => self.verify_password(password.clone())?, - None => { - let serialized = pack(self)?; - - let encrypted_data = - kos_crypto::cipher::encrypt(DEFAULT_ALGO, &serialized, &password)?; - self.encrypted_data = Some(encrypted_data); - } - } - - // reset secrets - self.keypair = None; - self.mnemonic = None; - self.path = None; - self.is_locked = true; - - Ok(()) - } - - /// unlock wallet privatekey with password - pub fn unlock(&mut self, password: String) -> Result<(), Error> { - // return if is unlocked - if !self.is_locked { - return Ok(()); - } - - let encrypted_data = match self.encrypted_data { - Some(ref data) => data, - None => return Err(Error::WalletManagerError("No encrypted data".to_string())), - }; - // decrypt encrypted_data - let data = kos_crypto::cipher::decrypt(encrypted_data, &password)?; - // restore values - let wallet: Wallet = - unpack(&data[..]).map_err(|e| Error::CipherError(format!("deserialize: {}", e)))?; - - // restore secrets - self.keypair = wallet.keypair; - self.mnemonic = wallet.mnemonic; - self.path = wallet.path; - self.is_locked = false; - - Ok(()) - } - - #[wasm_bindgen(js_name = "isLocked")] - /// check if wallet is locked - pub fn is_locked(&self) -> bool { - self.is_locked - } - - #[wasm_bindgen(js_name = "verifyPassword")] - pub fn verify_password(&self, password: String) -> Result<(), Error> { - match self.encrypted_data { - Some(ref encrypted_data) => { - // verify password - // decrypt encrypted_data - _ = kos_crypto::cipher::decrypt(encrypted_data, &password)?; - - Ok(()) - } - None => Err(Error::WalletManagerError("No encrypted data".to_string())), - } - } - - #[wasm_bindgen(constructor)] - /// create a random private key wallet - pub fn new(chain: Chain) -> Result { - let kp = chain.new_keypair()?; - - Wallet::from_keypair(chain, kp) - } - - #[wasm_bindgen(js_name = "fromKeyPair")] - /// restore wallet from keypair - pub fn from_keypair(chain: Chain, kp: KeyPair) -> Result { - let address = chain.get_address_from_keypair(&kp)?; - - Ok(Wallet { - chain, - account_type: AccountType::PrivateKey, - public_address: address, - is_locked: false, - node_url: None, - index: None, - - encrypted_data: None, - mnemonic: Some(String::new()), - path: Some(String::new()), - keypair: Some(kp), - }) - } - - #[wasm_bindgen(js_name = "fromMnemonic")] - /// restore wallet from mnemonic - pub fn from_mnemonic( - chain: Chain, - mnemonic: String, - path: String, - password: Option, - ) -> Result { - // validate mnemonic entropy - kos_crypto::mnemonic::validate_mnemonic(&mnemonic)?; - - let kp = chain.keypair_from_mnemonic(&mnemonic, &path, password)?; - let address = chain.get_address_from_keypair(&kp)?; - - Ok(Wallet { - chain, - account_type: AccountType::Mnemonic, - public_address: address, - is_locked: false, - node_url: None, - index: None, - - encrypted_data: None, - mnemonic: Some(mnemonic), - path: Some(path), - keypair: Some(kp), - }) - } - - #[wasm_bindgen(js_name = "fromPrivateKey")] - /// restore wallet from mnemonic - pub fn from_private_key(chain: Chain, private_key: String) -> Result { - // convert hex to bytes - let private_key = hex::decode(private_key)?; - - // check size of private key - if private_key.len() != 32 { - return Err(Error::WalletManagerError("Invalid private key".to_string())); - } - - // crete keypair from private key - let kp = chain.keypair_from_bytes(&private_key)?; - - // create wallet from keypair - Wallet::from_keypair(chain, kp) - } - - #[wasm_bindgen(js_name = "fromKCPem")] - /// restore wallet from mnemonic - pub fn from_kc_pem(chain: Chain, data: &[u8]) -> Result { - // decode pem file - let pem = parse_pem(data) - .map_err(|_| Error::WalletManagerError("Invalid PEM data".to_string()))?; - - let content = String::from_utf8(pem.contents().to_vec()) - .map_err(|_| Error::WalletManagerError("Invalid PEM data".to_string()))?; - - let pk_hex = content.chars().take(64).collect::(); - - // import from private key - Wallet::from_private_key(chain, pk_hex) - } - - #[wasm_bindgen(js_name = "fromMnemonicIndex")] - /// restore wallet from mnemonic - pub fn from_mnemonic_index( - chain: Chain, - mnemonic: String, - path_options: &PathOptions, - password: Option, - ) -> Result { - let path = chain.get_path(path_options)?; - let mut wallet = Wallet::from_mnemonic(chain, mnemonic, path, password)?; - wallet.index = Some(path_options.index); - - Ok(wallet) - } - - #[wasm_bindgen(js_name = "fromPem")] - pub fn from_pem(data: &[u8]) -> Result { - // parse pem - let pem = parse_pem(data) - .map_err(|_| Error::WalletManagerError("Invalid PEM data".to_string()))?; - - Wallet::import(pem) - } - - #[wasm_bindgen(js_name = "toPem")] - pub fn to_pem(&self, password: String) -> Result, Error> { - let pem = self.export(password)?; - - Ok(encode_pem(&pem).as_bytes().to_vec()) - } -} - -// wallet properties -impl Wallet { - pub fn import(pem: Pem) -> Result { - // Deserialize decrypted bytes to WalletManager - let wallet: Wallet = unpack(pem.contents()) - .map_err(|e| Error::CipherError(format!("deserialize data: {}", e)))?; - - Ok(wallet) - } - - pub fn export(&self, password: String) -> Result { - // validate password and lock wallet - if !self.is_locked() { - return Err(Error::WalletManagerError( - "Wallet is not locked".to_string(), - )); - } - - self.verify_password(password)?; - - // serialize wallet manager - let serialized = pack(self)?; - - let pem = kos_crypto::cipher::to_pem(self.get_key(), &serialized)?; - - Ok(pem) - } -} - -#[wasm_bindgen] -// wallet properties -impl Wallet { - #[wasm_bindgen(js_name = "getChain")] - /// get wallet chain type - pub fn get_chain(&self) -> Chain { - self.chain - } - - #[wasm_bindgen(js_name = "getAccountType")] - /// get wallet account type - pub fn get_account_type(&self) -> AccountType { - self.account_type - } - - #[wasm_bindgen(js_name = "getAddress")] - /// get wallet address - pub fn get_address(&self) -> String { - self.public_address.clone() - } - - #[wasm_bindgen(js_name = "getPublicKey")] - /// get wallet public key - pub fn get_public_key(&self) -> String { - match self.keypair { - Some(ref kp) => kp.public_key_hex(), - None => String::new(), - } - } - - #[wasm_bindgen(js_name = "getPath")] - /// get wallet path if wallet is created from mnemonic - pub fn get_path(&self) -> String { - match self.path { - Some(ref path) => path.clone(), - None => String::new(), - } - } - - #[wasm_bindgen(js_name = "getIndex")] - /// get wallet index if wallet is created from mnemonic index - pub fn get_index(&self) -> Result { - self.index.ok_or(Error::WalletManagerError( - "Wallet is not created from mnemonic index".to_string(), - )) - } - - #[wasm_bindgen(js_name = "getPrivateKey")] - /// get wallet private key - pub fn get_private_key(&self) -> String { - match self.keypair { - Some(ref kp) => kp.secret_key_hex(), - None => String::new(), - } - } - - #[wasm_bindgen(js_name = "getMnemonic")] - /// get wallet mnemonic if wallet is created from mnemonic - pub fn get_mnemonic(&self) -> String { - match self.mnemonic { - Some(ref mnemonic) => mnemonic.clone(), - None => String::new(), - } - } - - #[wasm_bindgen(js_name = "getNodeUrl")] - /// get node url setting for wallet - pub fn get_node_url(&self) -> String { - match self.node_url { - Some(ref node_url) => node_url.clone(), - None => crate::utils::get_node_url(self.chain.base_chain().symbol), - } - } - - #[wasm_bindgen(js_name = "setNodeUrl")] - /// set node url setting for wallet - pub fn set_node_url(&mut self, node_url: String) { - self.node_url = Some(node_url.clone()); - } -} - -#[wasm_bindgen] -// wallet methods -impl Wallet { - #[wasm_bindgen(js_name = "getBaseChain")] - /// sign message with private key - pub fn base_chain(&self) -> Result { - Ok(self.chain.base_chain()) - } - - #[wasm_bindgen(js_name = "signMessage")] - /// sign message with keypair - pub fn sign_message(&self, message: &[u8]) -> Result, Error> { - if self.is_locked { - return Err(Error::WalletManagerError("Wallet is locked".to_string())); - } - - match self.keypair { - Some(ref kp) => self.chain.sign_message(message, kp), - None => Err(Error::WalletManagerError("no keypair".to_string())), - } - } - - #[wasm_bindgen(js_name = "signDigest")] - /// sign digest with raw keypair - pub fn sign_digest(&self, hash: &[u8]) -> Result, Error> { - if self.is_locked { - return Err(Error::WalletManagerError("Wallet is locked".to_string())); - } - - match self.keypair { - Some(ref kp) => self.chain.sign_digest(hash, kp), - None => Err(Error::WalletManagerError("no keypair".to_string())), - } - } - - #[wasm_bindgen(js_name = "sign")] - pub fn sign(&self, tx: Transaction) -> Result { - if self.is_locked { - return Err(Error::WalletManagerError("Wallet is locked".to_string())); - } - - match self.keypair { - Some(ref kp) => self.chain.sign(tx, kp), - None => Err(Error::WalletManagerError("no keypair".to_string())), - } - } -} - -#[wasm_bindgen] -impl Wallet { - #[wasm_bindgen(js_name = "getBalance")] - pub async fn get_balance( - &self, - address: &str, - token: Option, - node_url: Option, - ) -> Result { - self.chain - .get_balance(address, token, node_url.or(self.node_url.clone())) - .await - } - - #[wasm_bindgen(js_name = "send")] - /// create a send transaction network - pub async fn send( - &self, - receiver: String, - amount: BigNumber, - options: Option, - node_url: Option, - ) -> Result { - self.chain - .send( - self.get_address(), - receiver, - amount, - options, - node_url.or(self.node_url.clone()), - ) - .await - } - - #[wasm_bindgen(js_name = "broadcast")] - /// broadcast transaction to network - pub async fn broadcast( - &self, - data: Transaction, - node_url: Option, - ) -> Result { - self.chain - .broadcast(data, node_url.or(self.node_url.clone())) - .await - } - - #[wasm_bindgen(js_name = "validateAddress")] - pub fn validate_address( - &self, - address: &str, - option: Option, - ) -> Result { - self.chain.validate_address(address, option) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_sign_broadcast() { - let mut w1 = Wallet::from_mnemonic( - Chain::KLV, - "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(), - Chain::KLV.get_path(&PathOptions::new(0)).unwrap(), - None, - ).unwrap(); - - w1.set_node_url("https://node.testnet.klever.finance".to_string()); - - let tx = tokio_test::block_on(w1.send( - "klv1x2ejsdqz8uccl7htu4cef63z0cqnydhkd8g36tgk6qdv94hu7syqms3spm".to_string(), - BigNumber::from(10), - None, - None, - )) - .unwrap(); - - let to_broadcast = w1.sign(tx).unwrap(); - let result = tokio_test::block_on(w1.broadcast(to_broadcast, None)); - - assert!(result.is_ok()) - } - - #[test] - fn test_export_import() { - let default_password = "password"; - // create wallet - let mut w1 = Wallet::from_mnemonic( - Chain::KLV, - "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(), - Chain::KLV.get_path(&PathOptions::new(0)).unwrap(), - None, - ).unwrap(); - - // check if wallet is unlocked (nearly created wallet) - assert!(!w1.is_locked()); - // lock wallet - let result = w1.lock(default_password.to_string()); - assert!(result.is_ok()); - assert!(w1.is_locked()); - // check if secret keys are removed - assert!(w1.get_private_key().is_empty()); - assert!(w1.get_mnemonic().is_empty()); - assert!(w1.get_path().is_empty()); - - // export wallet - let result = w1.to_pem(default_password.to_string()); - assert!(result.is_ok()); - let pem = result.unwrap(); - println!("{}", String::from_utf8(pem.clone()).unwrap()); - - // export wrong password - let result = w1.to_pem("wrong password".to_string()); - assert!(result.is_err()); - - // unlock wallet - let result = w1.unlock(default_password.to_string()); - println!("{:?}", result); - assert!(result.is_ok()); - assert!(!w1.is_locked()); - // check if secret keys restored - assert_eq!( - w1.get_private_key(), - "8734062c1158f26a3ca8a4a0da87b527a7c168653f7f4c77045e5cf571497d9d" - ); - assert_eq!(w1.get_mnemonic(), "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"); - assert_eq!(w1.get_path(), "m/44'/690'/0'/0'/0'"); - - // try to export wallet unlocked - let result = w1.export(default_password.to_string()); - assert!(result.is_err()); - - // try to lock with wrong password - let result = w1.lock("wrong password".to_string()); - assert!(result.is_err()); - } - - #[test] - fn test_import_pem() { - let pem_str = - "-----BEGIN KLV-klv1usdnywjhrlv4tcyu6stxpl6yvhplg35nepljlt4y5r7yppe8er4qujlazy----- -AQA+a2x2MXVzZG55d2pocmx2NHRjeXU2c3R4cGw2eXZocGxnMzVuZXBsamx0NHk1 -cjd5cHBlOGVyNHF1amxhenkBAAABvAIAOJCsBrwdU4FmaoxoUm790L+QMK4zTixR -pX8Nich/FhH53iI1cgoAyySPnzUVpvdSrsYZgpALJHO1Iv5FYBMYOqIIOJfLgMYp -N4C8Qw2LCgx4L/VIFoU+nbxJhvnx8Xd9mmkyWhbcoBSAHxzQ/teEfTRAMu9l8H33 -tN5xf3N7KRFsjZ3vDSW9w/xoiOCsi1QbTpE7SHB0KGLPaW1kgJ57J0gPC1QHI8Nk -csPM/08jVmOb1OIIs51qmo/FOsewPwb5aPEji6panHN3aJiYYv5XZCAxbWQqu2oY -Q4mznxvSHZLyGLsTGDmrticCzCL2i+3nXh7a07PsTMguY8IqUNRZpF68TqcYw/Bf -56tx4+0OgQ2ujSMWWeR3uN95K6o7rzIMpRbLxrcGfTkfozbGMe/H0Ur+5YI0hVY/ -qeVTAAAA ------END KLV-klv1usdnywjhrlv4tcyu6stxpl6yvhplg35nepljlt4y5r7yppe8er4qujlazy-----"; - - let wallet = Wallet::from_pem(pem_str.as_bytes()).unwrap(); - assert!(wallet.is_locked()); - assert_eq!( - wallet.get_address(), - "klv1usdnywjhrlv4tcyu6stxpl6yvhplg35nepljlt4y5r7yppe8er4qujlazy" - ) - } - - #[test] - fn test_wallet_mnemonic_without_index() { - let w1 = Wallet::from_mnemonic( - Chain::KLV, - "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(), - Chain::KLV.get_path(&PathOptions::new(0)).unwrap(), - None, - ).unwrap(); - - let result = w1.get_index(); - assert!(result.is_err()); - } - - #[test] - fn test_wallet_mnemonic_with_index() { - let w1 = Wallet::from_mnemonic_index( - Chain::KLV, - "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(), - &PathOptions::new(10), - None, - ).unwrap(); - let result = w1.get_index(); - assert!(result.is_ok()); - assert_eq!(result.unwrap(), 10); - } - - #[test] - fn test_validate_address_ok() { - let list_klv = [ - "klv1usdnywjhrlv4tcyu6stxpl6yvhplg35nepljlt4y5r7yppe8er4qujlazy", - "klv1x2ejsdqz8uccl7htu4cef63z0cqnydhkd8g36tgk6qdv94hu7syqms3spm", - ]; - - let list_btc = [ - "bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu", - "bc1qnjg0jd8228aq7egyzacy8cys3knf9xvrerkf9g", - "1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2", - "3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy", - "bc1qgl5vlg0zdl7yvprgxj9fevsc6q6x5dmcyk3cn3", - ]; - - let w1 = Wallet::new(Chain::KLV).unwrap(); - - for address in list_klv.iter() { - let result = w1.validate_address(address, None); - assert!(result.is_ok()); - assert!(result.unwrap()); - } - - let w2 = Wallet::new(Chain::BTC).unwrap(); - for address in list_btc.iter() { - let result = w2.validate_address(address, None); - assert!(result.is_ok()); - assert!(result.unwrap()); - } - } - - #[test] - fn test_validate_address_fail() { - let list_klv = [ - "klv1usdnywjhrlv4tcyu6stxpl6yvhplg35nepljlt4y5r7yppe8er4qujlaz", - "klv1usdnywjhrlv4tcyu6stxpl6yvhplg35nepljlt4y5r7yppe8er4qujlazy1", - "klv2usdnywjhrlv4tcyu6stxpl6yvhplg35nepljlt4y5r7yppe8er4qujlazy", - "klvusdnywjhrlv4tcyu6stxpl6yvhplg35nepljlt4y5r7yppe8er4qujlazy", - "1usdnywjhrlv4tcyu6stxpl6yvhplg35nepljlt4y5r7yppe8er4qujlazy", - "usdnywjhrlv4tcyu6stxpl6yvhplg35nepljlt4y5r7yppe8er4qujlazy", - "bnb1ztx5rf7jx28k3xnemftcq3kfgm3yhfvfmhm456", - "0x9858EfFD232B4033E47d90003D41EC34EcaEda94", - ]; - - let list_btc = [ - "bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu", - "bc1qnjg0jd8228aq7egyzacy8cys3knf9xvrerkf9g", - "1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2", - "3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy", - "bc1qgl5vlg0zdl7yvprgxj9fevsc6q6x5dmcyk3cn3", - ]; - - let w1 = Wallet::new(Chain::KLV).unwrap(); - - for address in list_klv.iter() { - let result = w1.validate_address(address, None); - assert!(result.is_ok()); - assert!(!result.unwrap()); - } - - let w2 = Wallet::new(Chain::BTC).unwrap(); - for address in list_btc.iter() { - let result = w2.validate_address( - address, - Some(models::AddressOptions::new( - Some("0B110907".to_string()), - None, - None, - )), - ); - assert!(result.is_ok()); - assert!(!result.unwrap()); - } - } -} diff --git a/packages/kos-sdk/src/wm.rs b/packages/kos-sdk/src/wm.rs deleted file mode 100644 index 25d72e4..0000000 --- a/packages/kos-sdk/src/wm.rs +++ /dev/null @@ -1,650 +0,0 @@ -use crate::{models::PathOptions, wallet::Wallet}; -use kos_types::error::Error; -use kos_utils::{pack, unpack}; - -use pem::{ - encode as encode_pem, encode_many as encode_many_pem, parse as parse_pem, - parse_many as parse_many_pem, Pem, -}; -use serde::{Deserialize, Serialize}; -use std::collections::HashMap; - -use wasm_bindgen::prelude::*; - -const KOS_WM_TAG: &str = "KOS WALLET MANAGER"; -const KOS_WM_TAG_DEFAULT: &str = "KOS WM DEFAULT"; - -#[wasm_bindgen] -#[derive(Debug, Clone, Deserialize, Serialize)] -pub struct WalletManager { - is_locked: bool, - encrypted_data: Option>, - checksum: Option>, - // skip serializing wallets, all data must be encrypted into encrypted_data - #[serde(skip)] - wallets: HashMap, -} - -#[wasm_bindgen] -impl WalletManager { - #[wasm_bindgen(constructor)] - pub fn new() -> WalletManager { - WalletManager { - is_locked: false, - encrypted_data: None, - checksum: None, - wallets: HashMap::new(), - } - } - - #[wasm_bindgen(js_name = "verifyPassword")] - pub fn verify_password(&self, password: String) -> Result<(), Error> { - _ = self - .encrypted_data - .as_ref() - .ok_or_else(|| Error::WalletManagerError("No encrypted data".to_string()))?; - let checksum = self - .checksum - .as_ref() - .ok_or_else(|| Error::WalletManagerError("No checksum".to_string()))?; - - let checksum_str = String::from_utf8(checksum.clone()) - .map_err(|_| Error::WalletManagerError("Invalid checksum".to_string()))?; - - if !kos_crypto::cipher::check_checksum(&password, checksum_str) { - return Err(Error::WalletManagerError("Invalid password".to_string())); - } - - Ok(()) - } - - #[wasm_bindgen(js_name = "fromPem")] - pub fn from_pem(data: &[u8]) -> Result { - // parse pem - let pem = parse_pem(data) - .map_err(|_| Error::WalletManagerError("Invalid PEM data".to_string()))?; - - WalletManager::import(pem) - } - - #[wasm_bindgen(js_name = "toPem")] - pub fn to_pem(&self, password: String) -> Result, Error> { - let pem = self.export(password)?; - - Ok(encode_pem(&pem).as_bytes().to_vec()) - } - - #[wasm_bindgen(js_name = "isLocked")] - pub fn is_locked(&self) -> bool { - self.is_locked - } - - #[wasm_bindgen(js_name = "unlock")] - pub fn unlock(&mut self, password: String) -> Result<(), Error> { - // return if already unlocked - if !self.is_locked() { - return Ok(()); - } - - // verify password - self.verify_password(password.clone())?; - - // reload encrypted wallets from encrypted_data - let wallets = parse_many_pem(self.encrypted_data.as_ref().unwrap()) - .map_err(|_| Error::WalletManagerError("Invalid encrypted data".to_string()))?; - - // deserialize all wallets and save to encrypted_data - for pem in wallets.iter() { - let wallet = Wallet::import(pem.clone())?; - self.wallets - .insert(pem.tag().to_string(), wallet.to_owned()); - } - - // unlock status - self.is_locked = false; - - Ok(()) - } - - #[wasm_bindgen(js_name = "lock")] - pub fn lock(&mut self, password: String) -> Result<(), Error> { - // return if is locked - if self.is_locked() { - return Ok(()); - } - - // verify password if encrypted data is present - if self.encrypted_data.is_some() { - self.verify_password(password.clone())?; - } - - let wallets: Result, Error> = self - .wallets - .iter_mut() - .map(|(tag, wallet)| { - wallet.lock(password.clone())?; - let w = wallet.export(password.clone())?; - - // replace default tag with KOS_WM_TAG_DEFAULT - Ok(if tag == KOS_WM_TAG_DEFAULT { - Pem::new(KOS_WM_TAG_DEFAULT, w.contents()) - } else { - w - }) - }) - .collect(); - - let wallets = wallets?; - - self.encrypted_data = Some(encode_many_pem(&wallets).as_bytes().to_vec()); - self.checksum = Some( - kos_crypto::cipher::create_checksum(&password) - .as_bytes() - .to_vec(), - ); - - // reset secrets - self.wallets.clear(); - self.is_locked = true; - - Ok(()) - } -} - -impl WalletManager { - pub fn import(pem: Pem) -> Result { - // check tag - if pem.tag() != KOS_WM_TAG { - return Err(Error::WalletManagerError("Invalid PEM tag".to_string())); - } - - // Deserialize decrypted bytes to WalletManager - let wm: WalletManager = unpack(pem.contents()) - .map_err(|e| Error::CipherError(format!("deserialize wm: {}", e)))?; - - Ok(wm) - } - - pub fn export(&self, password: String) -> Result { - // validate password and lock wallet - if !self.is_locked() { - return Err(Error::WalletManagerError( - "WalletManager is not locked".to_string(), - )); - } - - self.verify_password(password.clone())?; - - let data = pack(self).map_err(|e| Error::CipherError(format!("serialize wm: {}", e)))?; - - let pem = kos_crypto::cipher::to_pem(KOS_WM_TAG.to_owned(), &data)?; - - Ok(pem) - } -} - -impl Default for WalletManager { - fn default() -> Self { - Self::new() - } -} - -#[wasm_bindgen] -impl WalletManager { - fn ensure_unlocked(&mut self, password: String) -> Result<(), Error> { - if !self.is_locked() { - self.unlock(password) - } else { - self.verify_password(password) - } - } - - #[wasm_bindgen(js_name = "addWallet")] - pub fn add_wallet(&mut self, wallet: Wallet, password: String) -> Result { - self.ensure_unlocked(password.clone())?; - - let mut wallet = wallet.clone(); - - // check if wallet is locked - if !wallet.is_locked() { - wallet.lock(password.clone())?; - } else { - wallet.verify_password(password.clone())?; - } - - let wallet_name = wallet.get_key(); - - // error if exists - if self.wallets.contains_key(&wallet_name) { - return Err(Error::WalletManagerError( - "Wallet already exists".to_string(), - )); - } - - self.wallets.insert(wallet_name, wallet.clone()); - - Ok(wallet) - } - - #[wasm_bindgen(js_name = "newWallet")] - pub fn new_wallet( - &mut self, - chain: crate::chain::Chain, - password: String, - ) -> Result { - self.ensure_unlocked(password.clone())?; - - let index = self - .wallets - .values() - .filter(|wallet| { - wallet.get_chain() == chain - && wallet.get_account_type() == crate::wallet::AccountType::Mnemonic - }) - .filter_map(|wallet| wallet.get_index().ok()) - .max() - .map(|x| x + 1) - .unwrap_or(0); - - let mut wallet = Wallet::from_mnemonic_index( - chain, - self.get_mnemonic(password.to_owned())?, - &PathOptions::new(index), - None, - )?; - - wallet.lock(password.clone())?; - - self.add_wallet(wallet, password) - } - - #[wasm_bindgen(js_name = "removeWallet")] - pub fn remove_wallet( - &mut self, - chain: crate::chain::Chain, - address: String, - ) -> Result<(), Error> { - let wallet_name = Wallet::wallet_key(chain, &address); - match self.wallets.remove(&wallet_name) { - Some(_) => Ok(()), - None => Err(Error::WalletManagerError(format!( - "Wallet with address {} not found", - address - ))), - } - } - - #[wasm_bindgen(js_name = "getWallet")] - pub fn get_wallet(&self, chain: crate::chain::Chain, address: String) -> Result { - let wallet_name = Wallet::wallet_key(chain, &address); - match self.wallets.get(&wallet_name) { - Some(wallet) => Ok(wallet.clone()), - None => Err(Error::WalletManagerError(format!( - "Wallet with address {} not found", - address - ))), - } - } - - #[wasm_bindgen(js_name = "getMnemonic")] - pub fn get_mnemonic(&self, password: String) -> Result { - // error if unlocked - if self.is_locked() { - return Err(Error::WalletManagerError( - "WalletManager is locked".to_string(), - )); - } - - // reload encrypted wallets from encrypted_data - let mut w_mnemonic = self - .wallets - .get(KOS_WM_TAG_DEFAULT) - .ok_or(Error::WalletManagerError( - "Default mnemonic not found".to_string(), - ))? - .to_owned(); - - // decrypt mnemonic - w_mnemonic.unlock(password.clone())?; - let mnemonic_str = w_mnemonic.get_mnemonic(); - if mnemonic_str.is_empty() { - return Err(Error::WalletManagerError( - "Default mnemonic not found".to_string(), - )); - } - - Ok(mnemonic_str) - } - - #[wasm_bindgen(js_name = "setMnemonic")] - pub fn set_mnemonic(&mut self, mnemonic: String, password: String) -> Result<(), Error> { - // error if unlocked - if self.is_locked() { - return Err(Error::WalletManagerError( - "WalletManager is locked".to_string(), - )); - } - - // error if default mnemonic exists - if self.wallets.contains_key(KOS_WM_TAG_DEFAULT) { - return Err(Error::WalletManagerError( - "Default mnemonic already exists".to_string(), - )); - } - - // create wallet - let mut wallet = Wallet::from_mnemonic( - crate::chain::Chain::NONE, - mnemonic.clone(), - "".to_string(), - None, - )?; - - wallet.lock(password.clone())?; - self.wallets.insert(KOS_WM_TAG_DEFAULT.to_owned(), wallet); - - Ok(()) - } - - #[wasm_bindgen(js_name = "viewWallets")] - pub fn view_wallets(&self) -> Result { - let wallets = self.list_wallets(); - serde_wasm_bindgen::to_value(&wallets).map_err(|e| Error::JSONSerde(e.to_string())) - } -} - -impl WalletManager { - pub fn list_wallets(&self) -> Vec { - let mut wallets = Vec::new(); - for w in self.wallets.values() { - // skip default mnemonic wallet - if w.get_chain() == crate::chain::Chain::NONE { - continue; - } - - wallets.push(WalletView { - chain: w.get_chain(), - address: w.get_address(), - // todo!("add name to wallet struct") - name: w.get_key(), - }); - } - wallets - } -} - -#[derive(Deserialize, Serialize)] -pub struct WalletView { - pub chain: crate::chain::Chain, - pub address: String, - pub name: String, -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::chain::Chain; - const DEFAULT_MNEMONIC: &str = - "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"; - - #[test] - fn test_wallet_manager_export_import() { - let default_password = "password".to_string(); - - let mut wm = WalletManager::new(); - let wallet = Wallet::new(Chain::KLV).unwrap(); - let result = wm.add_wallet(wallet.to_owned(), default_password.to_owned()); - assert!(result.is_ok()); - - // set default mnemonic - wm.set_mnemonic(DEFAULT_MNEMONIC.to_string(), default_password.to_string()) - .unwrap(); - - let result = wm.export(default_password.to_owned()); - assert_eq!( - result.err(), - Some(Error::WalletManagerError( - "WalletManager is not locked".to_string() - )) - ); - - let result = wm.lock(default_password.to_owned()); - assert!(result.is_ok()); - let pem = wm.export(default_password.to_owned()); - assert!(pem.is_ok()); - - let mut wm2 = WalletManager::import(pem.unwrap()).unwrap(); - // unlock wallet manager - let result = wm2.unlock(default_password.to_owned()); - assert!(result.is_ok()); - // count should be 2 dues to default mnemonic wallet - assert_eq!(wm2.wallets.len(), 2); - - // check if wallet address matches - let wallet2 = wm2 - .get_wallet(wallet.get_chain(), wallet.get_address()) - .unwrap(); - assert_eq!(wallet2.get_address(), wallet.get_address()); - - // check default mnemonic matchs - let mnemonic = wm2.get_mnemonic(default_password.to_owned()).unwrap(); - assert_eq!(mnemonic, DEFAULT_MNEMONIC); - } - - #[test] - fn test_wallet_manager_lock_unlock() { - let default_password = "password".to_string(); - - let mut wm = WalletManager::new(); - let wallet = Wallet::new(Chain::KLV).unwrap(); - let test_privete_key = wallet.get_private_key(); - - let resul = wm.add_wallet(wallet.clone(), default_password.to_owned()); - assert!(resul.is_ok()); - let result = wm.lock(default_password.to_owned()); - assert!(result.is_ok()); - assert!(wm.is_locked()); - assert_eq!(wm.wallets.len(), 0); - // try unlock with wrong password - let result = wm.unlock("wrong_password".to_owned()); - assert_eq!( - result.err(), - Some(Error::WalletManagerError("Invalid password".to_string())) - ); - // unlock with correct password - let result = wm.unlock(default_password.to_owned()); - assert!(result.is_ok()); - assert!(!wm.is_locked()); - assert_eq!(wm.wallets.len(), 1); - - // check if wallet is locked - let mut wallet = wm - .get_wallet(wallet.get_chain(), wallet.get_address()) - .unwrap(); - assert!(wallet.is_locked()); - assert!(wallet.get_private_key().is_empty()); - - // unlock wallet - let result = wallet.unlock("password".to_owned()); - assert!(result.is_ok()); - assert_eq!(wallet.get_private_key(), test_privete_key); - } - - #[test] - fn test_wallet_manager_wallet_timing() { - let default_password = "password".to_string(); - const WALLET_COUNT: usize = 10; - - let start_time = std::time::Instant::now(); - let mut wm = WalletManager::new(); - println!("New Manger: {:?}", start_time.elapsed()); - - let start_time = std::time::Instant::now(); - for _ in 0..WALLET_COUNT { - let wallet = Wallet::new(Chain::KLV).unwrap(); - _ = wm.add_wallet(wallet.to_owned(), default_password.to_owned()); - } - println!("{} New Wallets: {:?}", WALLET_COUNT, start_time.elapsed()); - - // lock wallet manager with WALLET_COUNT wallets - let start_time = std::time::Instant::now(); - let result = wm.lock(default_password.to_owned()); - assert!(result.is_ok()); - println!( - "Lock {} New Wallets: {:?}", - WALLET_COUNT, - start_time.elapsed() - ); - - // unlock wallet manager - let start_time = std::time::Instant::now(); - let result = wm.unlock(default_password.to_owned()); - assert!(result.is_ok()); - println!( - "Unlock Wallet Manager with {} wallets: {:?}", - WALLET_COUNT, - start_time.elapsed() - ); - - // lock wallet manager with WALLET_COUNT wallets all locked - let start_time = std::time::Instant::now(); - let result = wm.lock(default_password.to_owned()); - assert!(result.is_ok()); - println!( - "Lock {} New Wallets all locked: {:?}", - WALLET_COUNT, - start_time.elapsed() - ); - - // export wallet manager - let start_time = std::time::Instant::now(); - let pem = wm.export(default_password.to_owned()).unwrap(); - println!( - "Export Wallet Manager with {} wallets: {:?}", - WALLET_COUNT, - start_time.elapsed() - ); - println!("Pem size: {:?} bytes", pem.contents().len()); - - // import wallet manager - let start_time = std::time::Instant::now(); - let mut wm2 = WalletManager::import(pem).unwrap(); - println!( - "Import Wallet Manager with {} wallets: {:?}", - WALLET_COUNT, - start_time.elapsed() - ); - assert!(wm2.is_locked()); - assert_eq!(wm2.wallets.len(), 0); - wm2.unlock(default_password.to_owned()).unwrap(); - assert_eq!(wm2.wallets.len(), WALLET_COUNT); - } - - #[test] - fn test_add_existent_wallet_should_fail() { - let default_password = "password"; - - let mut wm = WalletManager::new(); - let wallet = Wallet::new(Chain::KLV).unwrap(); - - let result = wm.add_wallet(wallet.clone(), default_password.to_owned()); - assert!(result.is_ok()); - let result = wm.add_wallet(wallet.clone(), default_password.to_owned()); - assert_eq!( - result.err(), - Some(Error::WalletManagerError( - "Wallet already exists".to_string() - )) - ); - } - - #[test] - fn test_set_mnemonic_should_work() { - let default_password = "password".to_string(); - - let mut wm = WalletManager::new(); - - let result = wm.set_mnemonic(DEFAULT_MNEMONIC.to_string(), default_password); - assert!(result.is_ok()); - } - - #[test] - fn test_set_mnemonic_should_fail() { - let default_password = "password".to_string(); - - let mut wm = WalletManager::new(); - - let result = wm.set_mnemonic("invalid mnemonic".to_string(), default_password); - assert_eq!( - result.err(), - Some(Error::InvalidMnemonic("Invalid mnemonic")) - ); - } - - #[test] - fn test_set_mnemonic_already_set_should_fail() { - let default_password = "password".to_string(); - - let mut wm = WalletManager::new(); - - let result = wm.set_mnemonic(DEFAULT_MNEMONIC.to_string(), default_password.clone()); - assert!(result.is_ok()); - - let result = wm.set_mnemonic(DEFAULT_MNEMONIC.to_string(), default_password); - assert_eq!( - result.err(), - Some(Error::WalletManagerError( - "Default mnemonic already exists".to_string() - )) - ); - } - - #[test] - fn test_get_mnemonic_not_set_should_fail() { - let default_password = "password".to_string(); - - let wm = WalletManager::new(); - let result = wm.get_mnemonic(default_password); - assert_eq!( - result.err(), - Some(Error::WalletManagerError( - "Default mnemonic not found".to_string() - )) - ); - } - - #[test] - fn test_get_mnemonic_should_work() { - let default_password = "password".to_string(); - - let mut wm = WalletManager::new(); - - let result = wm.set_mnemonic(DEFAULT_MNEMONIC.to_string(), default_password.clone()); - assert!(result.is_ok()); - - let result = wm.get_mnemonic(default_password); - assert!(result.is_ok()); - assert_eq!(result.unwrap(), DEFAULT_MNEMONIC); - } - - #[test] - fn test_get_mnemonic_wallet() { - let default_password = "password".to_string(); - - let mut wm = WalletManager::new(); - - let result = wm.set_mnemonic(DEFAULT_MNEMONIC.to_string(), default_password.clone()); - assert!(result.is_ok()); - - let mut w_default = wm.wallets.get(KOS_WM_TAG_DEFAULT).unwrap().to_owned(); - assert!(w_default.is_locked()); - // get mnemonic shoudl be empty - let result = w_default.get_mnemonic(); - assert_eq!(result, ""); - - // unlock wallet and retrive mnemonic - let _ = w_default.unlock(default_password); - let result = w_default.get_mnemonic(); - assert_eq!(result, DEFAULT_MNEMONIC); - } -} diff --git a/packages/kos-types/Cargo.toml b/packages/kos-types/Cargo.toml deleted file mode 100644 index 1dac0bb..0000000 --- a/packages/kos-types/Cargo.toml +++ /dev/null @@ -1,30 +0,0 @@ -[package] -name = "kos-types" -version = { workspace = true } -authors = { workspace = true } -edition = { workspace = true } -homepage = { workspace = true } -license = { workspace = true } -repository = { workspace = true } -rust-version = { workspace = true } - -[features] -alloc = ["hex/alloc"] -serde = ["dep:serde", "alloc"] -std = ["alloc", "serde?/std"] -random = ["rand"] - -[dependencies] -rand = { workspace = true, optional = true } -coins-bip32 = { workspace = true } -coins-bip39 = { workspace = true } -secp256k1 = { workspace = true, features = ["recovery", "rand"] } -ed25519-dalek = { workspace = true } -log = { workspace = true } -serde = { workspace = true, features = ["derive", "alloc"], optional = true } -serde_json = { workspace = true } -hex = { workspace = true } -reqwest = { workspace = true, default-features = false } -wasm-bindgen = { workspace = true } -num-bigint = "0.4" -num-traits = "0.2" diff --git a/packages/kos-types/src/array_types.rs b/packages/kos-types/src/array_types.rs deleted file mode 100644 index 175ccfc..0000000 --- a/packages/kos-types/src/array_types.rs +++ /dev/null @@ -1,298 +0,0 @@ -// serde-big-array doesn't allow documentation of its generated structure -#![allow(missing_docs)] -use core::array::TryFromSliceError; -use core::borrow::Borrow; -use core::borrow::BorrowMut; -use core::convert::TryFrom; -use core::ops::{Deref, DerefMut}; -use core::{fmt, str}; -use hex::{FromHex, FromHexError}; - -#[cfg(feature = "alloc")] -extern crate alloc; - -#[cfg(feature = "random")] -use rand::{ - distributions::{Distribution, Standard}, - Rng, -}; - -use crate::hex_val; - -macro_rules! key { - ($i:ident, $s:expr) => { - #[derive(Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] - /// atomic array type. - #[repr(transparent)] - pub struct $i([u8; $s]); - - key_methods!($i, $s); - - #[cfg(feature = "random")] - impl Distribution<$i> for Standard { - fn sample(&self, rng: &mut R) -> $i { - $i(rng.gen()) - } - } - }; -} - -macro_rules! key_with_big_array { - ($i:ident, $s:expr) => { - #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] - /// atomic type. - #[repr(transparent)] - pub struct $i([u8; $s]); - - key_methods!($i, $s); - - impl Default for $i { - fn default() -> $i { - $i([0u8; $s]) - } - } - - #[cfg(feature = "random")] - impl Distribution<$i> for Standard { - fn sample(&self, rng: &mut R) -> $i { - let mut bytes = $i::default(); - - rng.fill_bytes(bytes.as_mut()); - - bytes - } - } - }; -} - -macro_rules! key_methods { - ($i:ident, $s:expr) => { - impl $i { - /// Memory length of the type - pub const LEN: usize = $s; - - /// Bytes constructor. - pub const fn new(bytes: [u8; $s]) -> Self { - Self(bytes) - } - - /// Zeroes bytes constructor. - pub const fn zeroed() -> $i { - $i([0; $s]) - } - - #[allow(unsafe_code)] - /// Add a conversion from arbitrary slices into owned - /// - /// # Safety - /// - /// This function will not panic if the length of the slice is smaller than - /// `Self::LEN`. Instead, it will cause undefined behavior and read random disowned - /// bytes - pub unsafe fn from_slice_unchecked(bytes: &[u8]) -> Self { - $i($crate::bytes::from_slice_unchecked(bytes)) - } - - /// Copy-free reference cast - /// # Safety - /// Assumes the type is `repr[transparent]`. - pub fn from_bytes_ref_checked(bytes: &[u8]) -> Option<&Self> { - let bytes: &[u8; $s] = bytes.get(..$s)?.try_into().ok()?; - Some(Self::from_bytes_ref(bytes)) - } - - /// Copy-free reference cast - /// # Safety - /// Assumes the type is `repr[transparent]`. - pub fn from_bytes_ref(bytes: &[u8; $s]) -> &Self { - // The interpreter will frequently make references to keys and values using - // logically checked slices. - // - // This function will save unnecessary copy to owned slices for the interpreter - // access - #[allow(unsafe_code)] - unsafe { - &*(bytes.as_ptr() as *const Self) - } - } - - /// The memory size of the type by the method. - pub const fn size(&self) -> usize { - Self::LEN - } - } - - #[cfg(feature = "random")] - impl rand::Fill for $i { - fn try_fill(&mut self, rng: &mut R) -> Result<(), rand::Error> { - rng.fill_bytes(self.as_mut()); - - Ok(()) - } - } - - impl Deref for $i { - type Target = [u8; $s]; - - fn deref(&self) -> &[u8; $s] { - &self.0 - } - } - - impl Borrow<[u8; $s]> for $i { - fn borrow(&self) -> &[u8; $s] { - &self.0 - } - } - - impl BorrowMut<[u8; $s]> for $i { - fn borrow_mut(&mut self) -> &mut [u8; $s] { - &mut self.0 - } - } - - impl DerefMut for $i { - fn deref_mut(&mut self) -> &mut [u8; $s] { - &mut self.0 - } - } - - impl AsRef<[u8]> for $i { - fn as_ref(&self) -> &[u8] { - &self.0 - } - } - - impl AsMut<[u8]> for $i { - fn as_mut(&mut self) -> &mut [u8] { - &mut self.0 - } - } - - impl From<[u8; $s]> for $i { - fn from(bytes: [u8; $s]) -> Self { - Self(bytes) - } - } - - impl From<$i> for [u8; $s] { - fn from(salt: $i) -> [u8; $s] { - salt.0 - } - } - - impl TryFrom<&[u8]> for $i { - type Error = TryFromSliceError; - - fn try_from(bytes: &[u8]) -> Result<$i, TryFromSliceError> { - <[u8; $s]>::try_from(bytes).map(|b| b.into()) - } - } - - impl FromHex for $i { - type Error = FromHexError; - - fn from_hex>(hex: T) -> Result { - let b: [u8; Self::LEN] = FromHex::from_hex(hex)?; - b.try_into().map_err(|_| FromHexError::InvalidStringLength) - } - } - - impl fmt::LowerHex for $i { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - if f.alternate() { - write!(f, "0x")? - } - - match f.width() { - Some(w) if w > 0 => self.0.chunks(2 * Self::LEN / w).try_for_each(|c| { - write!(f, "{:02x}", c.iter().fold(0u8, |acc, x| acc ^ x)) - }), - - _ => self.0.iter().try_for_each(|b| write!(f, "{:02x}", &b)), - } - } - } - - impl fmt::UpperHex for $i { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - if f.alternate() { - write!(f, "0x")? - } - - match f.width() { - Some(w) if w > 0 => self.0.chunks(2 * Self::LEN / w).try_for_each(|c| { - write!(f, "{:02X}", c.iter().fold(0u8, |acc, x| acc ^ x)) - }), - - _ => self.0.iter().try_for_each(|b| write!(f, "{:02X}", &b)), - } - } - } - - impl fmt::Debug for $i { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - ::fmt(&self, f) - } - } - - impl fmt::Display for $i { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - ::fmt(&self, f) - } - } - - impl str::FromStr for $i { - type Err = &'static str; - - fn from_str(s: &str) -> Result { - const ERR: &str = "Invalid encoded byte"; - - let alternate = s.starts_with("0x"); - - let mut b = s.bytes(); - let mut ret = $i::zeroed(); - - if alternate { - b.next(); - b.next(); - } - - for r in ret.as_mut() { - let h = b.next().and_then(hex_val).ok_or(ERR)?; - let l = b.next().and_then(hex_val).ok_or(ERR)?; - - *r = h << 4 | l; - } - - Ok(ret) - } - } - - #[cfg(feature = "serde")] - impl serde::Serialize for $i { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - use alloc::format; - serializer.serialize_str(&format!("{:x}", &self)) - } - } - - #[cfg(feature = "serde")] - impl<'de> serde::Deserialize<'de> for $i { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - use serde::de::Error; - let s: &str = serde::Deserialize::deserialize(deserializer)?; - s.parse().map_err(D::Error::custom) - } - } - }; -} - -key!(Bytes32, 32); -key_with_big_array!(Bytes64, 64); diff --git a/packages/kos-types/src/bytes.rs b/packages/kos-types/src/bytes.rs deleted file mode 100644 index fe13b76..0000000 --- a/packages/kos-types/src/bytes.rs +++ /dev/null @@ -1,35 +0,0 @@ -#[derive(Debug, PartialEq, Clone, Eq)] -pub struct Bytes(pub Vec); - -impl From for Vec { - fn from(raw_slice: Bytes) -> Vec { - raw_slice.0 - } -} - -impl PartialEq> for Bytes { - fn eq(&self, other: &Vec) -> bool { - self.0 == *other - } -} - -impl PartialEq for Vec { - fn eq(&self, other: &Bytes) -> bool { - *self == other.0 - } -} - -#[allow(unsafe_code)] -/// Add a conversion from arbitrary slices into arrays -/// -/// # Safety -/// -/// This function will not panic if the length of the slice is smaller than `N`. Instead, it will -/// cause undefined behavior and read random disowned bytes. -pub unsafe fn from_slice_unchecked(buf: &[u8]) -> [u8; N] { - let ptr = buf.as_ptr() as *const [u8; N]; - - // Static assertions are not applicable to runtime length check (e.g. slices). - // This is safe if the size of `bytes` is consistent to `N` - *ptr -} diff --git a/packages/kos-types/src/error.rs b/packages/kos-types/src/error.rs deleted file mode 100644 index a73cb16..0000000 --- a/packages/kos-types/src/error.rs +++ /dev/null @@ -1,157 +0,0 @@ -use core::convert::Infallible; -use ed25519_dalek::SignatureError; -use reqwest::Error as ReqwestError; -use secp256k1::Error as Secp256k1Error; -use std::{error, fmt, str}; -use wasm_bindgen::JsValue; - -/// Crypto error variants -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub enum Error { - // Invalid string - InvalidString(String), - // JSON serialization error - JSONSerde(String), - // UnsupportedChain, - UnsupportedChain(&'static str), - // InvalidMnemonic, - InvalidMnemonic(&'static str), - // InvalidPath, - InvalidPath(&'static str), - // InvalidPrivateKey, - InvalidPrivateKey(&'static str), - // InvalidPublicKey, - InvalidPublicKey(String), - // InvalidAddress, - InvalidAddress(String), - // InvalidChecksum, - InvalidChecksum(&'static str), - /// Invalid secp256k1 signature - InvalidSignature(&'static str), - /// Invalid secp256k1 signature message - InvalidMessage(String), - /// Out of preallocated memory - NotEnoughMemory(String), - /// Reqwest error - ReqwestError(String), - /// Invalid Enum Variant - InvalidEnumVariant(String), - /// Invalid Len - InvalidLen(String), - /// InvalidNumberParse - InvalidNumberParse(String), - /// InvalidTransaction - InvalidTransaction(String), - /// WalletManagerError - WalletManagerError(String), - /// CipherError - CipherError(String), - /// TransportError - TransportError(String), -} - -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Error::InvalidString(e) => write!(f, "Invalid string: {}", e), - Error::JSONSerde(e) => write!(f, "JSON serialization: {}", e), - Error::UnsupportedChain(e) => write!(f, "Unsupported chain: {}", e), - Error::InvalidMnemonic(e) => write!(f, "Invalid mnemonic: {}", e), - Error::InvalidPath(e) => write!(f, "Invalid path: {}", e), - Error::InvalidPrivateKey(e) => write!(f, "Invalid private key: {}", e), - Error::InvalidPublicKey(e) => write!(f, "Invalid public key: {}", e), - Error::InvalidAddress(e) => write!(f, "Invalid address: {}", e), - Error::InvalidChecksum(e) => write!(f, "Invalid checksum: {}", e), - Error::InvalidSignature(e) => write!(f, "Invalid signature: {}", e), - Error::InvalidMessage(e) => write!(f, "Invalid message: {}", e), - Error::NotEnoughMemory(e) => write!(f, "Not enough memory: {}", e), - Error::ReqwestError(e) => write!(f, "Reqwest error: {}", e), - Error::InvalidEnumVariant(e) => write!(f, "Invalid Enum Variant error: {}", e), - Error::InvalidLen(e) => write!(f, "Invalid Len: {}", e), - Error::InvalidNumberParse(e) => write!(f, "Invalid number parse: {}", e), - Error::InvalidTransaction(e) => write!(f, "Invalid transaction: {}", e), - Error::WalletManagerError(e) => write!(f, "WalletManager error: {}", e), - Error::CipherError(e) => write!(f, "Cipher error: {}", e), - Error::TransportError(e) => write!(f, "Transport error: {}", e), - } - } -} - -impl From for Error { - fn from(secp: Secp256k1Error) -> Self { - match secp { - Secp256k1Error::IncorrectSignature - | Secp256k1Error::InvalidSignature - | Secp256k1Error::InvalidTweak - | Secp256k1Error::InvalidSharedSecret - | Secp256k1Error::InvalidPublicKeySum - | Secp256k1Error::InvalidParityValue(_) - | Secp256k1Error::InvalidRecoveryId => Self::InvalidSignature("Secp256k1Error"), - Secp256k1Error::InvalidMessage => Self::InvalidMessage(secp.to_string()), - Secp256k1Error::InvalidPublicKey => Self::InvalidPublicKey(secp.to_string()), - Secp256k1Error::InvalidSecretKey => Self::InvalidPrivateKey("Secp256k1Error"), - Secp256k1Error::NotEnoughMemory => Self::NotEnoughMemory(secp.to_string()), - } - } -} - -impl From for Error { - fn from(_: SignatureError) -> Self { - Self::InvalidSignature("Invalid signature") - } -} - -impl From for Error { - fn from(_: coins_bip39::MnemonicError) -> Self { - Self::InvalidMnemonic("Invalid mnemonic") - } -} - -impl From for Error { - fn from(_: coins_bip32::Bip32Error) -> Self { - Self::InvalidPath("Invalid path") - } -} - -impl From for Error { - fn from(e: serde_json::Error) -> Self { - Self::JSONSerde(e.to_string()) - } -} - -impl error::Error for Error { - fn source(&self) -> Option<&(dyn error::Error + 'static)> { - None - } -} - -impl From for JsValue { - fn from(e: Error) -> Self { - JsValue::from_str(&format!("{}", e)) - } -} - -impl From for Error { - fn from(e: ReqwestError) -> Self { - Self::ReqwestError(e.to_string()) - } -} - -impl From for Error { - fn from(e: hex::FromHexError) -> Self { - Self::InvalidString(e.to_string()) - } -} - -impl From for Infallible { - fn from(_: Error) -> Infallible { - unreachable!() - } -} - -impl From for Error { - fn from(_: Infallible) -> Error { - unreachable!() - } -} diff --git a/packages/kos-types/src/hash.rs b/packages/kos-types/src/hash.rs deleted file mode 100644 index bb4628d..0000000 --- a/packages/kos-types/src/hash.rs +++ /dev/null @@ -1,74 +0,0 @@ -use crate::error::Error; -use crate::Bytes32; - -use std::fmt::{Display, Formatter}; -use std::str::FromStr; -use wasm_bindgen::prelude::*; - -#[derive(Debug, Default, Copy, Clone)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[wasm_bindgen] -pub struct Hash { - data: Bytes32, -} - -#[wasm_bindgen] -impl Hash { - #[wasm_bindgen(constructor)] - pub fn new(data: &str) -> Result { - log::debug!("Hash::new({})", data); - - let value = Bytes32::from_str(data).map_err(|e| Error::InvalidString(e.to_string()))?; - - Ok(Self { data: value }) - } - - #[allow(clippy::inherent_to_string_shadow_display)] - #[wasm_bindgen(js_name = toString)] - pub fn to_string(&self) -> String { - self.data.to_string() - } - - #[wasm_bindgen(js_name = bytes)] - pub fn bytes(&self) -> Vec { - self.data.to_vec() - } - - #[wasm_bindgen(js_name = fromSlice)] - pub fn from_slice(data: &[u8]) -> Result { - // check length - if data.len() != Bytes32::LEN { - return Err(Error::InvalidLen(format!( - "expected {}, found {}", - Bytes32::LEN, - data.len() - ))); - } - let value = unsafe { Bytes32::from_slice_unchecked(data) }; - - Ok(Self { data: value }) - } - - #[wasm_bindgen(js_name = fromVec)] - pub fn from_vec(data: Vec) -> Result { - Hash::from_slice(data.as_slice()) - } -} - -impl From for Hash { - fn from(data: Bytes32) -> Self { - Self { data } - } -} - -impl From for Bytes32 { - fn from(hash: Hash) -> Self { - hash.data - } -} - -impl Display for Hash { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.data) - } -} diff --git a/packages/kos-types/src/lib.rs b/packages/kos-types/src/lib.rs deleted file mode 100644 index 818fb92..0000000 --- a/packages/kos-types/src/lib.rs +++ /dev/null @@ -1,44 +0,0 @@ -pub mod bytes; -pub mod error; -pub mod hash; -pub mod number; -pub mod vectorize; - -mod array_types; -pub use array_types::*; - -pub(crate) const fn hex_val(c: u8) -> Option { - match c { - b'A'..=b'F' => Some(c - b'A' + 10), - b'a'..=b'f' => Some(c - b'a' + 10), - b'0'..=b'9' => Some(c - b'0'), - _ => None, - } -} - -#[macro_export] -macro_rules! enum_thing { - ( - enum $EnumName:ident { - $($EnumVariant:ident($EnumType:ty)),* $(,)? - } - ) => { - #[derive(serde::Serialize, Clone, Debug)] - pub enum $EnumName { - $($EnumVariant($EnumType),)* - } - - $( - impl TryFrom<$EnumName> for $EnumType { - type Error = kos_types::error::Error; - - fn try_from(other: $EnumName) -> Result { - match other { - $EnumName::$EnumVariant(v) => Ok(v), - _ => Err(kos_types::error::Error::InvalidEnumVariant(stringify!($EnumName).to_string())), - } - } - } - )* - }; -} diff --git a/packages/kos-types/src/number.rs b/packages/kos-types/src/number.rs deleted file mode 100644 index ac82c90..0000000 --- a/packages/kos-types/src/number.rs +++ /dev/null @@ -1,251 +0,0 @@ -use crate::error::Error; - -use core::cmp::Ordering; -use std::{ - fmt::{Display, Formatter}, - ops::{Add, Deref, Div, Mul, Sub}, - str::FromStr, -}; - -use num_bigint::BigInt; -use num_traits::{ToPrimitive, Zero}; -use serde::{Deserialize, Serialize, Serializer}; - -use wasm_bindgen::prelude::*; - -#[derive(Default, Debug, Clone)] -#[wasm_bindgen] -pub struct BigNumber { - v: BigInt, -} - -impl Deref for BigNumber { - type Target = BigInt; - - fn deref(&self) -> &Self::Target { - &self.v - } -} - -impl Serialize for BigNumber { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - serializer.serialize_str(&self.v.to_string()) - } -} - -impl<'de> Deserialize<'de> for BigNumber { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - String::deserialize(deserializer)? - .parse() - .map_err(serde::de::Error::custom) - .map(|v| BigNumber { v }) - } -} - -impl FromStr for BigNumber { - type Err = Error; - - fn from_str(s: &str) -> Result { - BigNumber::from_string(s) - } -} - -impl TryInto for &str { - type Error = Error; - - fn try_into(self) -> Result { - BigNumber::from_str(self) - } -} - -impl TryFrom for BigNumber { - type Error = Error; - - fn try_from(s: String) -> Result { - BigNumber::from_str(&s) - } -} - -#[wasm_bindgen] -impl BigNumber { - #[wasm_bindgen(js_name = "fromString")] - pub fn from_string(value: &str) -> Result { - let value = value.trim().replace('_', ""); - - Ok(BigNumber { - v: BigInt::from_str(value.as_str()) - .map_err(|e| Error::InvalidNumberParse(e.to_string()))?, - }) - } - - #[allow(clippy::inherent_to_string_shadow_display)] - #[wasm_bindgen(js_name = "toString")] - pub fn to_string(&self) -> String { - self.v.to_string() - } - - #[wasm_bindgen(js_name = "toHex")] - pub fn to_hex(&self) -> String { - format!("{:#x}", self.v) - } - - #[wasm_bindgen(js_name = "toNumber")] - pub fn to_number(&self) -> f64 { - self.v.to_f64().unwrap_or(0.0) - } - - #[wasm_bindgen(js_name = "toI64")] - pub fn to_i64(&self) -> i64 { - self.v.to_i64().unwrap_or(0) - } - - #[wasm_bindgen(js_name = "toU64")] - pub fn to_u64(&self) -> u64 { - self.v.to_u64().unwrap_or(0) - } - - #[wasm_bindgen(js_name = "withPrecision")] - pub fn with_precision(&self, precision: u32) -> String { - let mut s = self.v.to_string(); - let len = s.len(); - if len < precision as usize { - s.insert_str(0, &"0".repeat(precision as usize - len)); - } - let len = s.len(); - let index = len - precision as usize; - s.insert(index, '.'); - s - } - - pub fn is_zero(&self) -> bool { - self.v.is_zero() - } - - pub fn self_add(mut self, other: &BigNumber) -> Self { - self.v += &other.v; - self - } - - pub fn self_sub(mut self, other: &BigNumber) -> Self { - self.v -= &other.v; - self - } - - pub fn self_mul(mut self, other: &BigNumber) -> Self { - self.v *= &other.v; - self - } - - pub fn self_div(mut self, other: &BigNumber) -> Self { - self.v /= &other.v; - self - } - - pub fn gt(&self, other: &BigNumber) -> bool { - self.v > other.v - } - - pub fn gte(&self, other: &BigNumber) -> bool { - self.v >= other.v - } - - pub fn lt(&self, other: &BigNumber) -> bool { - self.v < other.v - } - - pub fn lte(&self, other: &BigNumber) -> bool { - self.v <= other.v - } -} - -impl Add for BigNumber { - type Output = Self; - - fn add(self, other: Self) -> Self::Output { - BigNumber { - v: self.v + &other.v, - } - } -} - -impl Sub for BigNumber { - type Output = Self; - - fn sub(self, other: Self) -> Self::Output { - BigNumber { - v: self.v - &other.v, - } - } -} - -impl Mul for BigNumber { - type Output = Self; - - fn mul(self, other: Self) -> Self::Output { - BigNumber { - v: self.v * &other.v, - } - } -} - -impl Div for BigNumber { - type Output = Self; - - fn div(self, other: Self) -> Self::Output { - BigNumber { - v: self.v / &other.v, - } - } -} - -impl PartialEq for BigNumber { - #[inline] - fn eq(&self, other: &BigNumber) -> bool { - self.v.eq(&other.v) - } -} - -impl Eq for BigNumber {} - -impl PartialOrd for BigNumber { - #[inline] - fn partial_cmp(&self, other: &BigNumber) -> Option { - Some(self.cmp(other)) - } -} - -impl Ord for BigNumber { - #[inline] - fn cmp(&self, other: &BigNumber) -> Ordering { - self.v.cmp(&other.v) - } -} - -macro_rules! impl_from { - ($($uint_type: ty),*) => { - $( - impl From<$uint_type> for BigNumber { - fn from(s: $uint_type) -> BigNumber { - BigNumber { - v: BigInt::from(s), - } - } - } - )* - } -} - -impl_from!(u8, u16, u32, u64, u128); -impl_from!(i8, i16, i32, i64, i128); - -impl Display for BigNumber { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.v) - } -} diff --git a/packages/kos-types/src/vectorize.rs b/packages/kos-types/src/vectorize.rs deleted file mode 100644 index 50c82f7..0000000 --- a/packages/kos-types/src/vectorize.rs +++ /dev/null @@ -1,26 +0,0 @@ -use serde::{Deserialize, Deserializer, Serialize, Serializer}; -use std::iter::FromIterator; - -#[cfg(feature = "serde")] -pub fn serialize<'a, T, K, V, S>(target: T, ser: S) -> Result -where - S: Serializer, - T: IntoIterator, - K: Serialize + 'a, - V: Serialize + 'a, -{ - let container: Vec<_> = target.into_iter().collect(); - serde::Serialize::serialize(&container, ser) -} - -#[cfg(feature = "serde")] -pub fn deserialize<'de, T, K, V, D>(des: D) -> Result -where - D: Deserializer<'de>, - T: FromIterator<(K, V)>, - K: Deserialize<'de>, - V: Deserialize<'de>, -{ - let container: Vec<_> = serde::Deserialize::deserialize(des)?; - Ok(T::from_iter(container)) -} diff --git a/packages/kos-utils/Cargo.toml b/packages/kos-utils/Cargo.toml deleted file mode 100644 index 01e45a1..0000000 --- a/packages/kos-utils/Cargo.toml +++ /dev/null @@ -1,21 +0,0 @@ -[package] -name = "kos-utils" -version = { workspace = true } -authors = { workspace = true } -edition = { workspace = true } -homepage = { workspace = true } -license = { workspace = true } -repository = { workspace = true } -rust-version = { workspace = true } - -[lib] -crate-type = ["cdylib", "rlib"] - -[dependencies] -kos-types = { workspace = true } - -log = { workspace = true, features=["std"] } -wasm-bindgen = { workspace = true } -web-sys = { version="0.3", features=["console"] } -postcard = { version = "1.0.6", features=["use-std"] } -serde = { version="1.0", features=["derive"] } diff --git a/packages/kos-utils/src/lib.rs b/packages/kos-utils/src/lib.rs deleted file mode 100644 index 4c5f9bd..0000000 --- a/packages/kos-utils/src/lib.rs +++ /dev/null @@ -1,28 +0,0 @@ -pub mod logger; -use kos_types::error::Error; - -use serde::{Deserialize, Serialize}; - -pub fn pack(t: &T) -> Result, Error> -where - T: Serialize + ?Sized, -{ - postcard::to_stdvec(t).map_err(|e| Error::InvalidString(e.to_string())) -} - -pub fn unpack<'a, T: Deserialize<'a>>(bytes: &'a [u8]) -> Result { - postcard::from_bytes(bytes).map_err(|e| Error::InvalidString(e.to_string())) -} - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn test_pack_unpack() { - let to_serialize = "data to serialize"; - let serialized = pack(&to_serialize).unwrap(); - let deserialized: String = unpack(&serialized).unwrap(); - assert_eq!(to_serialize, deserialized); - } -} diff --git a/packages/kos-utils/src/logger.rs b/packages/kos-utils/src/logger.rs deleted file mode 100644 index bd86bde..0000000 --- a/packages/kos-utils/src/logger.rs +++ /dev/null @@ -1,179 +0,0 @@ -use log::{Level, Log, Metadata, Record}; -use wasm_bindgen::prelude::*; -use web_sys::console; - -/// Specify what to be logged -pub struct Config { - level: Level, - module_prefix: Option, - message_location: MessageLocation, -} - -/// Specify where the message will be logged. -pub enum MessageLocation { - /// The message will be on the same line as other info (level, path...) - SameLine, - /// The message will be on its own line, a new after other info. - NewLine, -} - -impl Default for Config { - fn default() -> Self { - Self { - level: Level::Debug, - module_prefix: None, - message_location: MessageLocation::SameLine, - } - } -} - -impl Config { - /// Specify the maximum level you want to log - pub fn new(level: Level) -> Self { - Self { - level, - module_prefix: None, - message_location: MessageLocation::SameLine, - } - } - - /// Initialize the logger with the given config - pub fn with_prefix(level: Level, prefix: &str) -> Self { - Config::new(level).module_prefix(prefix) - } - - /// Configure the `target` of the logger. If specified, the logger - /// only output for `log`s in module that its path starts with - /// `module_prefix`. logger only supports single prefix. Only - /// the last call to `module_prefix` has effect if you call it multiple times. - pub fn module_prefix(mut self, module_prefix: &str) -> Self { - self.module_prefix = Some(module_prefix.to_string()); - self - } - - /// Put the message on a new line, separated from other information - /// such as level, file path, line number. - pub fn message_on_new_line(mut self) -> Self { - self.message_location = MessageLocation::NewLine; - self - } -} - -/// The log styles -struct Style { - lvl_trace: String, - lvl_debug: String, - lvl_info: String, - lvl_warn: String, - lvl_error: String, - tgt: String, - args: String, -} - -impl Style { - fn new() -> Style { - let base = String::from("color: white; padding: 0 3px; background:"); - Style { - lvl_trace: format!("{} gray;", base), - lvl_debug: format!("{} blue;", base), - lvl_info: format!("{} green;", base), - lvl_warn: format!("{} orange;", base), - lvl_error: format!("{} darkred;", base), - tgt: String::from("font-weight: bold; color: inherit"), - args: String::from("background: inherit; color: inherit"), - } - } -} - -/// The logger -struct Logger { - config: Config, - style: Style, -} - -impl Log for Logger { - fn enabled(&self, metadata: &Metadata<'_>) -> bool { - if let Some(ref prefix) = self.config.module_prefix { - metadata.target().starts_with(prefix) - } else { - true - } - } - - fn log(&self, record: &Record<'_>) { - if self.enabled(record.metadata()) { - let style = &self.style; - let message_separator = match self.config.message_location { - MessageLocation::NewLine => "\n", - MessageLocation::SameLine => " ", - }; - let s = format!( - "%c{}%c {}:{}%c{}{}", - record.level(), - record.file().unwrap_or_else(|| record.target()), - record - .line() - .map_or_else(|| "[Unknown]".to_string(), |line| line.to_string()), - message_separator, - record.args(), - ); - let s = JsValue::from_str(&s); - let tgt_style = JsValue::from_str(&style.tgt); - let args_style = JsValue::from_str(&style.args); - - match record.level() { - Level::Trace => console::debug_4( - &s, - &JsValue::from(&style.lvl_trace), - &tgt_style, - &args_style, - ), - Level::Debug => console::log_4( - &s, - &JsValue::from(&style.lvl_debug), - &tgt_style, - &args_style, - ), - Level::Info => { - console::info_4(&s, &JsValue::from(&style.lvl_info), &tgt_style, &args_style) - } - Level::Warn => { - console::warn_4(&s, &JsValue::from(&style.lvl_warn), &tgt_style, &args_style) - } - Level::Error => console::error_4( - &s, - &JsValue::from(&style.lvl_error), - &tgt_style, - &args_style, - ), - } - } - } - - fn flush(&self) {} -} - -/// Initialize the logger which the given config. If failed, it will log a message to the the browser console. -/// -/// ## Examples -/// ```rust -/// use kos_utils::logger::*; -/// init(Config::new(log::Level::Debug)); -/// ``` -/// or -/// ```rust -/// use kos_utils::logger::*; -/// init(Config::with_prefix(log::Level::Debug, "some::module")); -/// ``` -pub fn init(config: Config) { - let max_level = config.level; - let wl = Logger { - config, - style: Style::new(), - }; - - match log::set_boxed_logger(Box::new(wl)) { - Ok(_) => log::set_max_level(max_level.to_level_filter()), - Err(e) => console::error_1(&JsValue::from(e.to_string())), - } -} diff --git a/packages/kos-web/Cargo.toml b/packages/kos-web/Cargo.toml new file mode 100644 index 0000000..0923ed7 --- /dev/null +++ b/packages/kos-web/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "kos-web" +authors.workspace = true +edition.workspace = true +homepage.workspace = true +license.workspace = true +repository.workspace = true +rust-version.workspace = true +version.workspace = true + +[dependencies] +kos = { workspace = true } diff --git a/packages/kos-web/src/lib.rs b/packages/kos-web/src/lib.rs new file mode 100644 index 0000000..b93cf3f --- /dev/null +++ b/packages/kos-web/src/lib.rs @@ -0,0 +1,14 @@ +pub fn add(left: u64, right: u64) -> u64 { + left + right +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add(2, 2); + assert_eq!(result, 4); + } +} diff --git a/packages/kos/Cargo.toml b/packages/kos/Cargo.toml index a842941..17ef695 100644 --- a/packages/kos/Cargo.toml +++ b/packages/kos/Cargo.toml @@ -1,47 +1,62 @@ [package] name = "kos" -version = { workspace = true } -authors = { workspace = true } -edition = { workspace = true } -homepage = { workspace = true } -license = { workspace = true } -publish = false -repository = { workspace = true } -rust-version = { workspace = true } - -[lib] -crate-type = ["cdylib", "rlib"] - -[features] -# If you uncomment this line, it will enable `wee_alloc`: -#default = ["wee_alloc"] - +authors.workspace = true +edition.workspace = true +homepage.workspace = true +license.workspace = true +repository.workspace = true +rust-version.workspace = true +version.workspace = true + +## Only necessary if using Protobuf well-known types: +#[lib] +#name = "kos" +#crate-type = ["staticlib", "cdylib"] +# +# +## See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +#[profile.release] +#opt-level = 'z' # Optimize for size +#lto = true # Enable Link Time Optimization +#panic = 'abort' # Generally reduces size for embedded systems +#codegen-units = 1 # more aggressive code merging +#strip = true # Strip symbols from the final binary + +[profile.dev] +panic = 'abort' [dependencies] -log = { workspace = true } -wasm-bindgen = { workspace = true } -console_error_panic_hook = "0.1" -qrcode-generator = "4.1" -hex = { workspace = true } - -# `wee_alloc` is a tiny allocator for wasm that is only ~1K in code size -# compared to the default allocator's ~10K. However, it is slower than the default -# allocator, so it's not enabled by default. - -kos-types = { workspace = true } -kos-crypto = { workspace = true } -kos-sdk = { workspace = true, features = ["serde"] } -kos-utils = { workspace = true } - - -# The `web-sys` crate allows you to interact with the various browser APIs, -# like the DOM. -[dependencies.web-sys] -version = "0.3.66" -features = ["console"] - -[dev-dependencies] -wasm-bindgen-test = "0.3" -futures = "0.3" -js-sys = "0.3.66" +hmac = { version = "0.12", default-features = false } +sha2 = { version = "0.10", default-features = false } +sha3 = { version = "0.10", default-features = false } +prost = { version = "0.12.1", default-features = false, features = ["prost-derive"] } +prost-types = { version = "0.12.1", default-features = false } +bech32 = { version = "0.9.1", default-features = false } +blake2b-ref = { version = "0.3.1", default-features = false } +rlp = { version = "0.5.0", default-features = false } +hex = { version = "0.4.3", features = ["alloc"], default-features = false } +tiny-json-rs = "0.2.5" +ripemd = { version = "0.1.3", default-features = false } +schnorrkel = { version = "0.11.4", default-features = false } +ed25519-dalek = { version = "2.1.0", features = ["hazmat"], default-features = false } +pbkdf2 = { version = "0.12.2 ", features = ["sha2", "hmac", "password-hash"], default-features = false } +bip39-dict = { version = "0.1.0", features = ["english"], default-features = false } +libsecp256k1 = { version = "0.7.1", features = ["hmac", "static-context"], default-features = false } +rand_core = { version = "0.6.4", default-features = false } +rand = "0.8" +coins-bip39 = { version = "0.8", default-features = false, features = ["english"] } +parity-scale-codec = { version = "3.6.9", default-features = false, features = ["derive"] } + +[target.'cfg(target_arch = "x86_64")'.dependencies] +rand_core = { version = "0.6.4", features = ["getrandom"], default-features = false } + + +[build-dependencies] +prost-build = "0.12.1" +quote = "1.0.33" +prost-wkt-build = "0.5.0" +prost-wkt = { version = "0.5.0", default-features = false } +prost-wkt-types = { version = "0.5.0", default-features = false } +heck = "0.4.1" + diff --git a/packages/kos/src/api.rs b/packages/kos/src/api.rs deleted file mode 100644 index 37482c0..0000000 --- a/packages/kos/src/api.rs +++ /dev/null @@ -1,121 +0,0 @@ -use kos_sdk::chains; -use kos_types::error::Error; - -use wasm_bindgen::prelude::*; - -/// API Signature model -#[wasm_bindgen] -#[derive(Clone, Debug)] -pub struct APISignature { - #[wasm_bindgen(skip)] - pub user: String, - #[wasm_bindgen(skip)] - pub nonce: u64, - #[wasm_bindgen(skip)] - pub message_hash: String, - #[wasm_bindgen(skip)] - pub signature: String, -} - -#[wasm_bindgen] -impl APISignature { - #[wasm_bindgen(js_name = "getUser")] - pub fn get_user(&self) -> String { - self.user.clone() - } - - #[wasm_bindgen(js_name = "getNonce")] - pub fn get_nonce(&self) -> u64 { - self.nonce - } - - #[wasm_bindgen(js_name = "getMessageHash")] - pub fn get_message_hash(&self) -> String { - self.message_hash.clone() - } - - #[wasm_bindgen(js_name = "getSignature")] - pub fn get_signature(&self) -> String { - self.signature.clone() - } -} - -/// Create QRCode based on data -#[wasm_bindgen(js_name = "apiSignature")] -pub fn api_signature( - private_key: String, - client_id: String, - nonce: u64, -) -> Result { - let nonce = if nonce == 0 { - // current timestamp in ms - std::time::SystemTime::now() - .duration_since(std::time::UNIX_EPOCH) - .unwrap() - .as_millis() as u64 - } else { - nonce - }; - - println!("nonce: {}", nonce); - - // message prefix - let prefix = "\x17KLEVER Signed Message:\n".as_bytes(); - - // create token nonce - let token_nonce = format!("{}/{}", nonce, client_id); - // sha256 token nonce - let token_nonce_hash = kos_crypto::hash::sha256(token_nonce.as_bytes()); - let token_hash_len: [u8; 4] = [0, 0, 0, 32]; - // append prefix. message length and message - let to_sign = [prefix, &token_hash_len, &token_nonce_hash].concat(); - // keccak256 hash - let hash = kos_crypto::hash::keccak256(&to_sign); - - // convert hex prive key to bytes - let pk = hex::decode(private_key).unwrap(); - // KLV KeyPair - let mut pk_array: [u8; 32] = [0; 32]; - pk_array.copy_from_slice(&pk); - - let kp = kos_crypto::keypair::KeyPair::new_ed25519(kos_crypto::ed25519::Ed25519KeyPair::new( - pk_array, - )); - - // sign message - let signature = kp.sign_digest(&hash); - - let addr = chains::KLV::get_address_from_keypair(&kp)?; - - Ok(APISignature { - user: addr, - nonce, - message_hash: hex::encode(hash), - signature: hex::encode(signature), - }) -} - -#[cfg(test)] -mod test { - use super::api_signature; - - #[test] - fn test_api_signature() { - const DEFAULT_PRIVATE_KEY: &str = - "8734062c1158f26a3ca8a4a0da87b527a7c168653f7f4c77045e5cf571497d9d"; - const CLIENT_ID: &str = "web-extension"; - - let nonce = 1692031458346; - - let v = api_signature( - DEFAULT_PRIVATE_KEY.to_string(), - CLIENT_ID.to_string(), - nonce, - ) - .unwrap(); - - println!("{:?}", v); - - assert_eq!(v.signature, "c24b408e710ca3be41fc6814e48857c226f869b13bc269a2a3c84cbd7ad89bc0433674fb816c92b656c1ea3fd18d1895d4fe56ab5427f8a50536060d5c400809") - } -} diff --git a/packages/kos/src/chains/ada/address.rs b/packages/kos/src/chains/ada/address.rs new file mode 100644 index 0000000..40fac7e --- /dev/null +++ b/packages/kos/src/chains/ada/address.rs @@ -0,0 +1,122 @@ +use crate::chains::ChainError; +use crate::crypto::hash::blake244_digest; +use alloc::string::String; +use alloc::vec; +use alloc::vec::Vec; +use bech32::{u5, Variant}; + +pub enum AddressType { + Base, + Pointer, + Enterprise, +} + +impl AddressType { + pub fn from_u8(val: u8) -> Self { + match val { + 0..=3 => AddressType::Base, + 4..=5 => AddressType::Pointer, + _ => AddressType::Enterprise, + } + } + + pub fn to_u8(&self) -> u8 { + match self { + AddressType::Base => 0, + AddressType::Pointer => 4, + AddressType::Enterprise => 6, + } + } +} + +#[derive(Clone)] +#[allow(dead_code)] +pub enum CredentialType { + Key, + Script, +} + +#[derive(Clone)] +pub struct StakeCredential { + _type: CredentialType, + key_hash: Option<[u8; 28]>, + script_hash: Option<[u8; 28]>, +} + +impl StakeCredential { + pub fn new(pbk: &[u8]) -> Self { + let key_hash = blake244_digest(&pbk); + StakeCredential::from_key_hash(key_hash) + } + + pub fn from_key_hash(key_hash: [u8; 28]) -> Self { + StakeCredential { + _type: CredentialType::Key, + key_hash: Some(key_hash), + script_hash: None, + } + } + + pub fn get_hash(&self) -> Result<[u8; 28], ChainError> { + match self._type { + CredentialType::Key => match self.key_hash { + Some(hash) => Ok(hash), + None => Err(ChainError::InvalidCredential), + }, + CredentialType::Script => match self.script_hash { + Some(hash) => Ok(hash), + None => Err(ChainError::InvalidCredential), + }, + } + } +} + +pub struct Address { + pub network: u8, + pub _type: u8, + pub payment_cred: Option, + pub stake_cred: Option, + //TODO: Pointer attrs +} + +impl Address { + pub fn serialize(&self) -> Result, ChainError> { + let mut addr_bytes = vec![self._type << 4 | self.network]; + let addr_type = AddressType::from_u8(self._type); + match addr_type { + AddressType::Base => { + let payment_cred = self + .payment_cred + .as_ref() + .ok_or(ChainError::InvalidCredential)?; + let stake_cred = self + .stake_cred + .as_ref() + .ok_or(ChainError::InvalidCredential)?; + addr_bytes.append(&mut payment_cred.get_hash()?.to_vec()); + addr_bytes.append(&mut stake_cred.get_hash()?.to_vec()); + Ok(addr_bytes) + } + AddressType::Enterprise => { + let payment_cred = self + .payment_cred + .as_ref() + .ok_or(ChainError::InvalidCredential)?; + addr_bytes.append(&mut payment_cred.get_hash()?.to_vec()); + Ok(addr_bytes) + } + AddressType::Pointer => return Err(ChainError::NotSupported), + } + } + + pub fn encode_bech32(&self) -> Result { + let addr_bytes = self.serialize()?; + let addr_encoded = bech32::convert_bits(addr_bytes.as_ref(), 8, 5, true)?; + let mut addr_u5: Vec = Vec::new(); + for i in addr_encoded { + addr_u5.push(u5::try_from_u8(i)?); + } + let res = bech32::encode("addr", addr_u5, Variant::Bech32)?; + Ok(res) + } +} diff --git a/packages/kos/src/chains/ada/mod.rs b/packages/kos/src/chains/ada/mod.rs new file mode 100644 index 0000000..0feaa0e --- /dev/null +++ b/packages/kos/src/chains/ada/mod.rs @@ -0,0 +1,152 @@ +mod address; + +use crate::chains::ada::address::{Address, AddressType, StakeCredential}; +use crate::chains::util::private_key_from_vec; +use crate::chains::{util, Chain, ChainError, Transaction, TxInfo}; +use crate::crypto::bip32::{derive_ed25519_bip32, mnemonic_to_seed_ed25519_bip32}; +use crate::crypto::ed25519; +use crate::crypto::ed25519::Ed25519Trait; +use alloc::string::{String, ToString}; +use alloc::vec::Vec; + +pub struct ADA {} + +impl Chain for ADA { + fn get_name(&self) -> &str { + "Cardano" + } + + fn get_symbol(&self) -> &str { + "ADA" + } + + fn get_decimals(&self) -> u32 { + todo!() + } + + fn mnemonic_to_seed(&self, mnemonic: String, _password: String) -> Result, ChainError> { + Ok(mnemonic_to_seed_ed25519_bip32(mnemonic)?) + } + + fn derive(&self, seed: Vec, path: String) -> Result, ChainError> { + if seed.len() != 96 { + return Err(ChainError::InvalidSeed); + } + + let mut seed_arr = [0u8; 96]; + seed_arr.copy_from_slice(&seed[..]); + + Ok(derive_ed25519_bip32(seed_arr, path)?.to_vec()) + } + + fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { + match private_key.len() { + 64 => { + let mut pvk = private_key_from_vec(&private_key)?; + let pbk = ed25519::Ed25519::public_from_extended(&pvk)?; + pvk.fill(0); + if pbk.len() < 32 { + return Err(ChainError::InvalidPrivateKey); + } + + Ok(pbk[0..32].to_vec()) + } + 96 => { + let mut pvk = [0u8; 64]; + let mut cc = [0u8; 32]; + pvk.copy_from_slice(&private_key[..64]); + cc.copy_from_slice(&private_key[64..]); + let vk = self.get_pbk(pvk.to_vec())?; + let mut xvk = Vec::new(); + xvk.append(&mut vk.to_vec()); + xvk.append(&mut cc.to_vec()); + + pvk.fill(0); + cc.fill(0); + + Ok(xvk) + } + _ => Err(ChainError::InvalidPrivateKey), + } + } + + fn get_address(&self, public_key: Vec) -> Result { + match public_key.len() { + 128 => { + let pbk = &public_key[..32]; + let pbk_stake = &public_key[32..64]; + + let payment = StakeCredential::new(&pbk); + let stake = StakeCredential::new(&pbk_stake); + let address = Address { + network: 1, + _type: AddressType::Base.to_u8(), + payment_cred: Some(payment), + stake_cred: Some(stake), + }; + + Ok(address.encode_bech32()?.to_string()) + } + 64 => { + let payment = StakeCredential::new(&public_key[0..32]); + let address = Address { + network: 1, + _type: AddressType::Enterprise.to_u8(), + payment_cred: Some(payment), + stake_cred: None, + }; + + Ok(address.encode_bech32()?.to_string()) + } + _ => Err(ChainError::InvalidPublicKey), + } + } + + fn sign_tx(&self, _private_key: Vec, _tx: Transaction) -> Result { + Err(ChainError::NotSupported) + } + + fn sign_message( + &self, + _private_key: Vec, + _message: Vec, + ) -> Result, ChainError> { + Err(ChainError::NotSupported) + } + + fn sign_raw(&self, private_key: Vec, payload: Vec) -> Result, ChainError> { + let mut private_key_bytes = util::private_key_from_vec(&private_key)?; + let sig = ed25519::Ed25519::sign_extended(&private_key_bytes, &payload)?; + private_key_bytes.fill(0); + Ok(sig) + } + + fn get_tx_info(&self, _raw_tx: Vec) -> Result { + Err(ChainError::NotSupported) + } +} + +#[cfg(test)] +mod test { + use crate::chains::Chain; + use alloc::string::ToString; + + #[test] + fn test_address() { + let mnemonic = + "permit best kiwi blast purchase cook grab present have hurdle quarter steak" + .to_string(); + let ada = super::ADA {}; + + let seed = ada.mnemonic_to_seed(mnemonic, "".to_string()).unwrap(); + let pvk = ada + .derive(seed, "m/1852'/1815'/0'/0/0".to_string()) + .unwrap(); + let pbk = ada.get_pbk(pvk).unwrap(); + let addr = ada.get_address(pbk).unwrap(); + assert_eq!( + addr, + "addr1vywpa9tjxu68p0tll20gdcc2mlg2xwncn4jrzps4eup7jks08gtf2" + ); + } +} diff --git a/packages/kos/src/chains/apt/mod.rs b/packages/kos/src/chains/apt/mod.rs new file mode 100644 index 0000000..7fd0a86 --- /dev/null +++ b/packages/kos/src/chains/apt/mod.rs @@ -0,0 +1,96 @@ +use crate::chains::util::private_key_from_vec; +use crate::chains::{Chain, ChainError, Transaction, TxInfo}; +use crate::crypto::bip32; +use crate::crypto::ed25519::{Ed25519, Ed25519Trait}; +use crate::crypto::hash::sha3_digest; +use alloc::string::{String, ToString}; +use alloc::vec::Vec; + +pub struct APT {} + +impl Chain for APT { + fn get_name(&self) -> &str { + "Aptos" + } + + fn get_symbol(&self) -> &str { + "APT" + } + + fn get_decimals(&self) -> u32 { + 8 + } + + fn mnemonic_to_seed(&self, mnemonic: String, password: String) -> Result, ChainError> { + Ok(bip32::mnemonic_to_seed(mnemonic, password)?) + } + + fn derive(&self, seed: Vec, path: String) -> Result, ChainError> { + let result = bip32::derive_ed25519(&seed, path)?; + Ok(Vec::from(result)) + } + + fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { + let mut pvk_bytes = private_key_from_vec(&private_key)?; + let pbk = Ed25519::public_from_private(&pvk_bytes)?; + + pvk_bytes.fill(0); + Ok(pbk) + } + + fn get_address(&self, mut public_key: Vec) -> Result { + if public_key.len() != 32 { + return Err(ChainError::InvalidPublicKey); + } + + public_key.push(0); + let checksum = sha3_digest(&public_key[..]); + let hex_encode = hex::encode(checksum); + let mut addr = "0x".to_string(); + addr.push_str(&hex_encode[..64]); + Ok(addr) + } + + fn sign_tx(&self, _private_key: Vec, _tx: Transaction) -> Result { + Err(ChainError::NotSupported) + } + + fn sign_message(&self, _private_key: Vec, _message: Vec) -> Result, ChainError> { + Err(ChainError::NotSupported) + } + + fn sign_raw(&self, private_key: Vec, payload: Vec) -> Result, ChainError> { + let mut pvk_bytes = private_key_from_vec(&private_key)?; + let signature = Ed25519::sign(&pvk_bytes, &payload)?; + + pvk_bytes.fill(0); + Ok(signature) + } + + fn get_tx_info(&self, _raw_tx: Vec) -> Result { + Err(ChainError::NotSupported) + } +} + +#[cfg(test)] +mod test { + use crate::chains::Chain; + use alloc::string::{String, ToString}; + + #[test] + fn test_derive() { + let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); + + let apt = super::APT {}; + let seed = apt.mnemonic_to_seed(mnemonic, String::new()).unwrap(); + let pvk = apt + .derive(seed.clone(), "m/44'/637'/0'/0'/0'".to_string()) + .unwrap(); + let pbk = apt.get_pbk(pvk.clone()).unwrap(); + let addr = apt.get_address(pbk.clone()).unwrap(); + assert_eq!( + addr, + "0xeb663b681209e7087d681c5d3eed12aaa8e1915e7c87794542c3f96e94b3d3bf" + ); + } +} diff --git a/packages/kos/src/chains/atom/mod.rs b/packages/kos/src/chains/atom/mod.rs new file mode 100644 index 0000000..4f71255 --- /dev/null +++ b/packages/kos/src/chains/atom/mod.rs @@ -0,0 +1,134 @@ +use crate::chains::util::{private_key_from_vec, slice_from_vec}; +use crate::chains::{Chain, ChainError, Transaction, TxInfo}; +use crate::crypto::hash::ripemd160_digest; +use crate::crypto::secp256k1::{Secp256K1, Secp256k1Trait}; +use crate::crypto::{bip32, secp256k1}; +use alloc::string::{String, ToString}; +use alloc::vec::Vec; +use bech32::{u5, Variant}; + +pub(crate) struct ATOM { + pub addr_prefix: String, + #[allow(dead_code)] + pub network_str: String, + pub name: String, + pub symbol: String, +} + +impl ATOM { + pub fn new() -> Self { + Self { + addr_prefix: "cosmos".to_string(), + network_str: "cosmoshub-4".to_string(), + name: "Cosmos".to_string(), + symbol: "ATOM".to_string(), + } + } + + pub fn new_cosmos_based( + addr_prefix: &str, + network_str: &str, + name: &str, + symbol: &str, + ) -> Self { + Self { + addr_prefix: addr_prefix.to_string(), + network_str: network_str.to_string(), + name: name.to_string(), + symbol: symbol.to_string(), + } + } +} + +impl Chain for ATOM { + fn get_name(&self) -> &str { + self.name.as_str() + } + + fn get_symbol(&self) -> &str { + self.symbol.as_str() + } + + fn get_decimals(&self) -> u32 { + 6 + } + + fn mnemonic_to_seed(&self, mnemonic: String, password: String) -> Result, ChainError> { + Ok(bip32::mnemonic_to_seed(mnemonic, password)?) + } + + fn derive(&self, seed: Vec, path: String) -> Result, ChainError> { + let pvk = bip32::derive(&seed, path)?; + Ok(Vec::from(pvk)) + } + + fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { + let mut pvk = private_key_from_vec(&private_key)?; + let pbk = Secp256K1::private_to_public_compressed(&pvk)?; + pvk.fill(0); + Ok(Vec::from(pbk)) + } + + fn get_address(&self, public_key: Vec) -> Result { + if public_key.len() != 33 { + return Err(ChainError::InvalidPublicKey); + } + + let mut pubkey_bytes = [0; 33]; + pubkey_bytes.copy_from_slice(&public_key[..33]); + + let hash = ripemd160_digest(&pubkey_bytes); + let addr_bytes = hash.to_vec(); + let add_encoded = bech32::convert_bits(addr_bytes.as_ref(), 8, 5, true)?; + let mut addr_u5: Vec = Vec::new(); + for i in add_encoded { + addr_u5.push(u5::try_from_u8(i)?); + } + let res = bech32::encode(self.addr_prefix.as_str(), addr_u5, Variant::Bech32)?; + Ok(res) + } + + fn sign_tx(&self, _private_key: Vec, _tx: Transaction) -> Result { + Err(ChainError::NotSupported) + } + + fn sign_message( + &self, + _private_key: Vec, + _message: Vec, + ) -> Result, ChainError> { + Err(ChainError::NotSupported) + } + + fn sign_raw(&self, private_key: Vec, payload: Vec) -> Result, ChainError> { + let mut pvk_bytes = private_key_from_vec(&private_key)?; + let payload_bytes = slice_from_vec(&payload)?; + + let sig = secp256k1::Secp256K1::sign(&payload_bytes, &pvk_bytes)?; + + pvk_bytes.fill(0); + Ok(sig.to_vec()) + } + + fn get_tx_info(&self, _raw_tx: Vec) -> Result { + Err(ChainError::NotSupported) + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_get_addr() { + let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); + let path = "m/44'/118'/0'/0/0".to_string(); + + let atom = ATOM::new(); + let seed = atom.mnemonic_to_seed(mnemonic, "".to_string()).unwrap(); + let pvk = atom.derive(seed, path).unwrap(); + let pbk = atom.get_pbk(pvk).unwrap(); + let addr = atom.get_address(pbk).unwrap(); + assert_eq!(addr, "cosmos19rl4cm2hmr8afy4kldpxz3fka4jguq0auqdal4"); + } +} diff --git a/packages/kos/src/chains/bch/mod.rs b/packages/kos/src/chains/bch/mod.rs new file mode 100644 index 0000000..01ba93e --- /dev/null +++ b/packages/kos/src/chains/bch/mod.rs @@ -0,0 +1,175 @@ +use crate::chains::util::{private_key_from_vec, slice_from_vec}; +use crate::chains::{Chain, ChainError, Transaction, TxInfo}; +use crate::crypto::bip32; +use crate::crypto::hash::ripemd160_digest; +use crate::crypto::secp256k1::{Secp256K1, Secp256k1Trait}; +use alloc::string::String; +use alloc::vec; +use alloc::vec::Vec; + +const BCH_CHARSET: &str = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"; +const BCH_PREFIX: &str = "bitcoincash"; +const BCH_MASK: u8 = 0x1f; + +pub struct BCH {} + +impl BCH { + fn expand_prefix(prefix: &str) -> Result, ChainError> { + let mut prefix_bytes = prefix.as_bytes().to_vec(); + for i in 0..prefix_bytes.len() { + prefix_bytes[i] = prefix_bytes[i] & BCH_MASK; + } + + prefix_bytes.push(0u8); + Ok(prefix_bytes) + } + + fn create_checksum(prefix: &str, payload: &[u8]) -> Result, ChainError> { + let expanded_prefix = BCH::expand_prefix(prefix)?; + let to_encode = [expanded_prefix, payload.to_vec(), vec![0u8; 8]].concat(); + let check = BCH::poly_mod(&to_encode); + let mut ret = [0u8; 8]; + for i in 0..ret.len() { + ret[i] = ((check >> (5 * (7 - i))) & (BCH_MASK as u64)) as u8; + } + + Ok(ret.to_vec()) + } + + fn poly_mod(p_input: &[u8]) -> u64 { + const POLY_TABLE: [u64; 5] = [ + 0x98f2bc8e61, + 0x79b76d99e2, + 0xf33e5fb3c4, + 0xae2eabe2a8, + 0x1e4f43e470, + ]; + let mut check: u64 = 1; + + for &item in p_input.iter() { + let check0 = (check >> 35) as u8; // Assuming C0_SHIFT_COUNT is 35, as it's not defined in the original code + + check = ((check & 0x07ffffffff) << 5) ^ (item as u64); + + if (check0 & 0x01) > 0 { + check ^= POLY_TABLE[0]; + } + if (check0 & 0x02) > 0 { + check ^= POLY_TABLE[1]; + } + if (check0 & 0x04) > 0 { + check ^= POLY_TABLE[2]; + } + if (check0 & 0x08) > 0 { + check ^= POLY_TABLE[3]; + } + if (check0 & 0x10) > 0 { + check ^= POLY_TABLE[4]; + } + } + + check ^ 1 + } +} + +impl Chain for BCH { + fn get_name(&self) -> &str { + "Bitcoin Cash" + } + + fn get_symbol(&self) -> &str { + "BCH" + } + + fn get_decimals(&self) -> u32 { + 8 + } + + fn mnemonic_to_seed(&self, mnemonic: String, password: String) -> Result, ChainError> { + Ok(bip32::mnemonic_to_seed(mnemonic, password)?) + } + + fn derive(&self, seed: Vec, path: String) -> Result, ChainError> { + let pvk = bip32::derive(&seed, path)?; + Ok(pvk.to_vec()) + } + + fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { + let mut pvk_bytes = private_key_from_vec(&private_key)?; + let pbk = Secp256K1::private_to_public_compressed(&pvk_bytes)?; + pvk_bytes.fill(0); + Ok(pbk.to_vec()) + } + + fn get_address(&self, public_key: Vec) -> Result { + if public_key.len() != 33 { + return Err(ChainError::InvalidPublicKey); + } + + let mut pubkey_bytes = [0; 33]; + pubkey_bytes.copy_from_slice(&public_key[..33]); + + let hash = ripemd160_digest(&pubkey_bytes); + let to_base_58 = [vec![0x00], hash[..].to_vec()].concat(); + let addr_converted = bech32::convert_bits(&to_base_58, 8, 5, true)?; + let checksum = BCH::create_checksum(BCH_PREFIX, &addr_converted)?; + + let mut final_address = Vec::new(); + for i in 0..addr_converted.len() { + final_address.push(BCH_CHARSET.as_bytes()[addr_converted[i] as usize]); + } + + for i in 0..checksum.len() { + final_address.push(BCH_CHARSET.as_bytes()[checksum[i] as usize]); + } + + Ok(String::from_utf8(final_address)?) + } + + fn sign_tx(&self, _private_key: Vec, _tx: Transaction) -> Result { + Err(ChainError::NotSupported) + } + + fn sign_message( + &self, + _private_key: Vec, + _message: Vec, + ) -> Result, ChainError> { + Err(ChainError::NotSupported) + } + + fn sign_raw(&self, private_key: Vec, payload: Vec) -> Result, ChainError> { + let mut pvk_bytes = private_key_from_vec(&private_key)?; + let payload_bytes = slice_from_vec(&payload)?; + + let sig = Secp256K1::sign(&payload_bytes, &pvk_bytes)?; + + pvk_bytes.fill(0); + Ok(sig.to_vec()) + } + + fn get_tx_info(&self, _raw_tx: Vec) -> Result { + Err(ChainError::NotSupported) + } +} + +#[cfg(test)] +mod test { + use crate::chains::Chain; + use alloc::string::ToString; + + #[test] + fn test_bch_address() { + let bch = super::BCH{}; + let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); + + let seed = bch.mnemonic_to_seed(mnemonic, "".to_string()).unwrap(); + let pvk = bch.derive(seed, "m/44'/145'/0'/0/0".to_string()).unwrap(); + let pbk = bch.get_pbk(pvk).unwrap(); + let addr = bch.get_address(pbk).unwrap(); + + assert_eq!(addr, "qqyx49mu0kkn9ftfj6hje6g2wfer34yfnq5tahq3q6"); + } +} + + diff --git a/packages/kos/src/chains/bnb/mod.rs b/packages/kos/src/chains/bnb/mod.rs new file mode 100644 index 0000000..28b24c2 --- /dev/null +++ b/packages/kos/src/chains/bnb/mod.rs @@ -0,0 +1,107 @@ +use crate::chains::util::{private_key_from_vec, slice_from_vec}; +use crate::chains::{Chain, ChainError, Transaction, TxInfo}; +use crate::crypto::bip32; +use crate::crypto::hash::ripemd160_digest; +use crate::crypto::secp256k1::{Secp256K1, Secp256k1Trait}; +use alloc::string::String; +use alloc::vec::Vec; +use bech32::{u5, Variant}; + +const BNB_PREFIX: &str = "bnb"; + +pub struct BNB {} + +impl Chain for BNB { + fn get_name(&self) -> &str { + "Binance" + } + + fn get_symbol(&self) -> &str { + "BNB" + } + + fn get_decimals(&self) -> u32 { + todo!() + } + + fn mnemonic_to_seed(&self, mnemonic: String, password: String) -> Result, ChainError> { + Ok(bip32::mnemonic_to_seed(mnemonic, password)?) + } + + fn derive(&self, seed: Vec, path: String) -> Result, ChainError> { + let pvk = bip32::derive(&seed, path)?; + Ok(pvk.to_vec()) + } + + fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { + let mut pvk_bytes = private_key_from_vec(&private_key)?; + + let pbk = Secp256K1::private_to_public_compressed(&pvk_bytes)?; + pvk_bytes.fill(0); + Ok(pbk.to_vec()) + } + + fn get_address(&self, public_key: Vec) -> Result { + if public_key.len() != 33 { + return Err(ChainError::InvalidPublicKey); + } + + let mut pubkey_bytes = [0; 33]; + pubkey_bytes.copy_from_slice(&public_key[..33]); + + let hash = ripemd160_digest(&pubkey_bytes); + let add_encoded = bech32::convert_bits(&hash, 8, 5, true)?; + let mut addr_u5: Vec = Vec::new(); + for i in add_encoded { + addr_u5.push(u5::try_from_u8(i)?); + } + let res = bech32::encode(BNB_PREFIX, addr_u5, Variant::Bech32)?; + Ok(res) + } + + fn sign_tx(&self, _private_key: Vec, _tx: Transaction) -> Result { + Err(ChainError::NotSupported) + } + + fn sign_message( + &self, + _private_key: Vec, + _message: Vec, + ) -> Result, ChainError> { + Err(ChainError::NotSupported) + } + + fn sign_raw(&self, private_key: Vec, payload: Vec) -> Result, ChainError> { + let mut pvk_bytes = private_key_from_vec(&private_key)?; + let payload_bytes = slice_from_vec(&payload)?; + + let sig = Secp256K1::sign(&payload_bytes, &pvk_bytes)?; + + pvk_bytes.fill(0); + Ok(sig.to_vec()) + } + + fn get_tx_info(&self, _raw_tx: Vec) -> Result { + Err(ChainError::NotSupported) + } +} + +#[cfg(test)] +mod test { + use super::*; + use alloc::string::ToString; + + #[test] + fn test_mnemonic_to_seed() { + let bnb = BNB {}; + let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); + + let seed = bnb.mnemonic_to_seed(mnemonic, "".to_string()).unwrap(); + let pvk = bnb.derive(seed, "m/44'/714'/0'/0/0".to_string()).unwrap(); + let pbk = bnb.get_pbk(pvk.clone()).unwrap(); + + let addr = bnb.get_address(pbk.clone()).unwrap(); + + assert_eq!(addr, "bnb1rxhz5vdv4fvdjye8gxqvfv0yvg20jtlwf4f38d"); + } +} diff --git a/packages/kos/src/chains/btc/mod.rs b/packages/kos/src/chains/btc/mod.rs new file mode 100644 index 0000000..8759c62 --- /dev/null +++ b/packages/kos/src/chains/btc/mod.rs @@ -0,0 +1,197 @@ +use crate::chains::util::{private_key_from_vec, slice_from_vec}; +use crate::chains::{Chain, ChainError, Transaction, TxInfo}; +use crate::crypto::b58::b58enc; +use crate::crypto::bip32; +use crate::crypto::hash::{ripemd160_digest, sha256_digest}; +use crate::crypto::secp256k1::{Secp256K1, Secp256k1Trait}; +use alloc::string::{String, ToString}; +use alloc::vec; +use alloc::vec::Vec; +use bech32::{u5, Variant}; + +pub struct BTC { + pub addr_prefix: String, + pub symbol: String, + pub name: String, + pub use_legacy_address: bool, + pub legacy_version: u8, +} + +impl BTC { + pub fn new() -> Self { + BTC::new_btc_based("bc", "BTC", "Bitcoin") + } + + pub fn new_btc_based(addr_prefix: &str, symbol: &str, name: &str) -> Self { + BTC { + addr_prefix: addr_prefix.to_string(), + symbol: symbol.to_string(), + name: name.to_string(), + use_legacy_address: false, + legacy_version: 0, + } + } + + pub fn new_legacy_btc_based(legacy_version: u8, symbol: &str, name: &str) -> Self { + BTC { + addr_prefix: "".to_string(), + symbol: symbol.to_string(), + name: name.to_string(), + use_legacy_address: true, + legacy_version, + } + } +} + +impl BTC { + fn get_addr_new(&self, public_key: Vec) -> Result { + if public_key.len() != 33 { + return Err(ChainError::InvalidPublicKey); + } + + let mut pubkey_bytes = [0; 33]; + pubkey_bytes.copy_from_slice(&public_key[..33]); + + let hash = ripemd160_digest(&pubkey_bytes); + let addr_bytes = hash.to_vec(); + let addr_converted = bech32::convert_bits(&addr_bytes, 8, 5, true)?; + let mut addr_u5: Vec = Vec::from([u5::try_from_u8(0).unwrap(); 1]); + for i in addr_converted { + addr_u5.push(u5::try_from_u8(i)?); + } + + let res = bech32::encode(self.addr_prefix.as_str(), addr_u5, Variant::Bech32)?; + Ok(res) + } + + pub fn get_addr_legacy(&self, public_key: Vec) -> Result { + if public_key.len() != 33 { + return Err(ChainError::InvalidPublicKey); + } + + let mut pubkey_bytes = [0; 33]; + pubkey_bytes.copy_from_slice(&public_key[..33]); + + let hash = ripemd160_digest(&pubkey_bytes); + + let to_base_58 = [vec![self.legacy_version], hash[..].to_vec()].concat(); + let checksum = sha256_digest(&sha256_digest(&to_base_58)); + let checksum_bytes = checksum[..4].to_vec(); + let to_base_58 = [&to_base_58[..], &checksum_bytes[..]].concat(); + + let res = b58enc(&to_base_58); + let addr = String::from_utf8(res)?; + Ok(addr) + } +} + +impl Chain for BTC { + fn get_name(&self) -> &str { + self.name.as_str() + } + + fn get_symbol(&self) -> &str { + self.symbol.as_str() + } + + fn get_decimals(&self) -> u32 { + 8 + } + + fn mnemonic_to_seed(&self, mnemonic: String, password: String) -> Result, ChainError> { + Ok(bip32::mnemonic_to_seed(mnemonic, password)?) + } + + fn derive(&self, seed: Vec, path: String) -> Result, ChainError> { + let pvk = bip32::derive(&seed, path)?; + Ok(pvk.to_vec()) + } + + fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { + if private_key.len() != 32 { + return Err(ChainError::InvalidPrivateKey); + } + + let mut pk_bytes: [u8; 32] = [0; 32]; + pk_bytes.copy_from_slice(&private_key[..32]); + + let pbk = Secp256K1::private_to_public_compressed(&pk_bytes)?; + Ok(pbk.to_vec()) + } + + fn get_address(&self, public_key: Vec) -> Result { + if self.use_legacy_address { + return Ok(self.get_addr_legacy(public_key)?); + } + + Ok(self.get_addr_new(public_key)?) + } + + fn sign_tx(&self, _private_key: Vec, _tx: Transaction) -> Result { + Err(ChainError::NotSupported) + } + + fn sign_message( + &self, + _private_key: Vec, + _message: Vec, + ) -> Result, ChainError> { + Err(ChainError::NotSupported) + } + + fn sign_raw(&self, private_key: Vec, payload: Vec) -> Result, ChainError> { + let mut pvk_bytes = private_key_from_vec(&private_key)?; + let payload_bytes = slice_from_vec(&payload)?; + let sig = Secp256K1::sign(&payload_bytes, &pvk_bytes)?; + + pvk_bytes.fill(0); + Ok(sig.to_vec()) + } + + fn get_tx_info(&self, _raw_tx: Vec) -> Result { + Err(ChainError::NotSupported) + } +} + +#[cfg(test)] +mod test { + use super::*; + use alloc::string::ToString; + + #[test] + fn test_derive() { + let menmonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); + let path = "m/84'/0'/0'/0/0".to_string(); + let expected = + hex::decode("4604b4b710fe91f584fff084e1a9159fe4f8408fff380596a604948474ce4fa3") + .unwrap(); + let btc = BTC::new(); + let seed = btc.mnemonic_to_seed(menmonic, "".to_string()).unwrap(); + let res = btc.derive(seed, path).unwrap(); + assert_eq!(res, expected); + } + + #[test] + fn test_get_addr() { + let pvk = hex::decode("4604b4b710fe91f584fff084e1a9159fe4f8408fff380596a604948474ce4fa3") + .unwrap(); + + let btc = BTC::new(); + let pbk = btc.get_pbk(pvk).unwrap(); + let addr = btc.get_address(pbk).unwrap(); + assert_eq!(addr, "bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu"); + } + + #[test] + fn test_get_addr_legacy() { + let menmonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); + let path = "m/44'/3'/0'/0/0".to_string(); + + let btc = BTC::new_legacy_btc_based(0x1e, "DOGE", "Dogecoin"); + let seed = btc.mnemonic_to_seed(menmonic, "".to_string()).unwrap(); + let pvk = btc.derive(seed, path).unwrap(); + let pbk = btc.get_pbk(pvk).unwrap(); + let addr = btc.get_address(pbk).unwrap(); + assert_eq!(addr, "DBus3bamQjgJULBJtYXpEzDWQRwF5iwxgC"); + } +} diff --git a/packages/kos/src/chains/constants.rs b/packages/kos/src/chains/constants.rs new file mode 100644 index 0000000..25736b4 --- /dev/null +++ b/packages/kos/src/chains/constants.rs @@ -0,0 +1,57 @@ +#![allow(dead_code)] +#![allow(unused_variables)] +#![allow(unused)] + +pub const RESERVED: u32 = 0; +pub const TRX: u32 = 1; +pub const BTC: u32 = 2; +pub const ETH: u32 = 3; +pub const BSC: u32 = 4; +pub const EGLD: u32 = 5; +pub const DOT: u32 = 6; +pub const KSM: u32 = 7; +pub const KLV: u32 = 8; +pub const LTC: u32 = 9; +pub const DOGE: u32 = 10; +pub const DASH: u32 = 11; +pub const POLYGON: u32 = 12; +pub const BNB: u32 = 13; +pub const REEF: u32 = 14; +pub const ICP: u32 = 15; +pub const DGB: u32 = 16; +pub const XRP: u32 = 17; +pub const MOVR: u32 = 18; +pub const GLMR: u32 = 19; +pub const SYS: u32 = 20; +pub const HT: u32 = 21; +pub const BCH: u32 = 22; +pub const SDN: u32 = 23; +pub const ASTR: u32 = 24; +pub const ONE: u32 = 25; +pub const SYS_NEVM: u32 = 26; +pub const KILT: u32 = 27; +pub const ALTAIR: u32 = 28; +pub const SOL: u32 = 29; +pub const XLM: u32 = 30; +pub const SUBSTRATE: u32 = 31; +pub const COSMOS: u32 = 32; +pub const CELESTIA: u32 = 33; +pub const SUI: u32 = 34; +pub const CUDOS: u32 = 35; +pub const AURA: u32 = 36; +pub const APT: u32 = 37; +pub const ADA: u32 = 38; +pub const AVAIL: u32 = 39; +pub const ROLLUX: u32 = 40; +pub const AVAX: u32 = 41; +pub const CFG: u32 = 42; +pub const ARB: u32 = 43; +pub const BASE: u32 = 44; +pub const NEAR: u32 = 45; +pub const FTM: u32 = 46; +pub const CHZ: u32 = 47; +pub const OP: u32 = 48; +pub const HBAR: u32 = 49; +pub const FLOW: u32 = 50; +pub const POLYGON_ZKEVM: u32 = 51; +pub const STOLZ: u32 = 52; \ No newline at end of file diff --git a/packages/kos/src/chains/default/mod.rs b/packages/kos/src/chains/default/mod.rs new file mode 100644 index 0000000..fbaeab2 --- /dev/null +++ b/packages/kos/src/chains/default/mod.rs @@ -0,0 +1,51 @@ +pub struct NONE; + +impl Chain for NONE { + fn get_name(&self) -> &str { + return "NONE"; + } + + fn get_symbol(&self) -> &str { + return "NONE"; + } + + fn get_decimals(&self) -> u32 { + return 0; + } + + fn mnemonic_to_seed(&self, mnemonic: String, password: String) -> Result, ChainError> { + Err(ChainError::NotSupported) + } + + fn derive(&self, seed: Vec, path: String) -> Result, ChainError> { + Err(ChainError::NotSupported) + } + + fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { + Err(ChainError::NotSupported) + } + + fn get_address(&self, public_key: Vec) -> Result { + Err(ChainError::NotSupported) + } + + fn sign_tx( + &self, + private_key: Vec, + mut tx: Transaction, + ) -> Result { + Err(ChainError::NotSupported) + } + + fn sign_message(&self, private_key: Vec, message: Vec) -> Result, ChainError> { + Err(ChainError::NotSupported) + } + + fn sign_raw(&self, private_key: Vec, payload: Vec) -> Result, ChainError> { + Err(ChainError::NotSupported) + } + + fn get_tx_info(&self, raw_tx: Vec) -> Result { + Err(ChainError::NotSupported) + } +} diff --git a/packages/kos/src/chains/egld/mod.rs b/packages/kos/src/chains/egld/mod.rs new file mode 100644 index 0000000..aee5841 --- /dev/null +++ b/packages/kos/src/chains/egld/mod.rs @@ -0,0 +1,97 @@ +use crate::chains::util::private_key_from_vec; +use crate::chains::{Chain, ChainError, Transaction, TxInfo}; +use crate::crypto::bip32; +use crate::crypto::ed25519::{Ed25519, Ed25519Trait}; +use crate::crypto::hash::keccak256_digest; +use alloc::string::String; +use alloc::vec::Vec; +use bech32::{u5, Variant}; + +pub struct EGLD {} + +impl Chain for EGLD { + fn get_name(&self) -> &str { + "Elrond" + } + + fn get_symbol(&self) -> &str { + "EGLD" + } + + fn get_decimals(&self) -> u32 { + 18 + } + + fn mnemonic_to_seed(&self, mnemonic: String, password: String) -> Result, ChainError> { + Ok(bip32::mnemonic_to_seed(mnemonic, password)?) + } + + fn derive(&self, seed: Vec, path: String) -> Result, ChainError> { + let result = bip32::derive_ed25519(&seed, path)?; + Ok(Vec::from(result)) + } + + fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { + let pvk_bytes = private_key_from_vec(&private_key)?; + let pbk = Ed25519::public_from_private(&pvk_bytes)?; + Ok(pbk) + } + + fn get_address(&self, public_key: Vec) -> Result { + let pbk_hash = keccak256_digest(&public_key[..]); + let add_encoded = bech32::convert_bits(pbk_hash.as_ref(), 8, 5, true)?; + let mut addr_u5: Vec = Vec::new(); + for i in add_encoded { + addr_u5.push(u5::try_from_u8(i)?); + } + let res = bech32::encode("erd", addr_u5, Variant::Bech32)?; + Ok(res) + } + + fn sign_tx(&self, _private_key: Vec, _tx: Transaction) -> Result { + Err(ChainError::NotSupported) + } + + fn sign_message( + &self, + _private_key: Vec, + _message: Vec, + ) -> Result, ChainError> { + Err(ChainError::NotSupported) + } + + fn sign_raw(&self, private_key: Vec, payload: Vec) -> Result, ChainError> { + let mut pvk_bytes = private_key_from_vec(&private_key)?; + + let signature = Ed25519::sign(&pvk_bytes, &payload)?; + pvk_bytes.fill(0); + Ok(signature) + } + + fn get_tx_info(&self, _raw_tx: Vec) -> Result { + Err(ChainError::NotSupported) + } +} + +#[cfg(test)] +mod test { + use crate::chains::Chain; + use alloc::string::{String, ToString}; + + #[test] + fn test_derive() { + let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); + + let egld = super::EGLD {}; + let seed = egld.mnemonic_to_seed(mnemonic, String::new()).unwrap(); + let pvk = egld + .derive(seed.clone(), "m/44'/508'/0'/0'/0'".to_string()) + .unwrap(); + let pbk = egld.get_pbk(pvk.clone()).unwrap(); + let addr = egld.get_address(pbk.clone()).unwrap(); + assert_eq!( + addr, + "erd19a76e058k023kss9zhg5zfwtc9m8qwnq0tq8v3cp9e0632q9437sxrxrec" + ); + } +} diff --git a/packages/kos/src/chains/eth/mod.rs b/packages/kos/src/chains/eth/mod.rs new file mode 100644 index 0000000..1da00be --- /dev/null +++ b/packages/kos/src/chains/eth/mod.rs @@ -0,0 +1,242 @@ +mod models; + +use crate::chains::eth::models::EthereumTransaction; +use crate::chains::util::{private_key_from_vec, slice_from_vec}; +use crate::chains::{Chain, ChainError, Transaction, TxInfo, TxType}; +use crate::crypto::hash::keccak256_digest; +use crate::crypto::secp256k1::{Secp256K1, Secp256k1Trait}; +use crate::crypto::{bip32, secp256k1}; +use alloc::string::{String, ToString}; +use alloc::vec::Vec; + +pub(crate) const ETH_ADDR_SIZE: usize = 20; +const ETH_MESSAGE_PREFIX: &[u8; 26] = b"\x19Ethereum Signed Message:\n"; +pub struct ETH { + pub chaincode: u32, + pub symbol: String, + pub name: String, +} + +impl ETH { + pub fn new() -> Self { + ETH::new_eth_based(1, "ETH", "Ethereum") + } + + pub fn new_eth_based(chaincode: u32, symbol: &str, name: &str) -> Self { + ETH { + chaincode, + symbol: symbol.to_string(), + name: name.to_string(), + } + } + + pub(crate) fn addr_bytes_to_string( + address_bytes: [u8; ETH_ADDR_SIZE], + ) -> Result { + let addr_str = hex::encode(address_bytes); + + let address_hash = hex::encode(keccak256_digest(addr_str.as_bytes())); + + let address = addr_str.as_str(); + let address = + address + .char_indices() + .fold(String::from("0x"), |mut acc, (index, address_char)| { + // this cannot fail since it's Keccak256 hashed + let n = u16::from_str_radix(&address_hash[index..index + 1], 16).unwrap(); + + if n > 7 { + // make char uppercase if ith character is 9..f + acc.push_str(&address_char.to_uppercase().to_string()) + } else { + // already lowercased + acc.push(address_char) + } + + acc + }); + Ok(address.to_string()) + } +} + +impl Chain for ETH { + fn get_name(&self) -> &str { + return self.name.as_str(); + } + + fn get_symbol(&self) -> &str { + return self.symbol.as_str(); + } + + fn get_decimals(&self) -> u32 { + return 18; + } + + fn mnemonic_to_seed(&self, mnemonic: String, password: String) -> Result, ChainError> { + Ok(bip32::mnemonic_to_seed(mnemonic, password)?) + } + + fn derive(&self, seed: Vec, path: String) -> Result, ChainError> { + let pvk = bip32::derive(&seed, path)?; + Ok(Vec::from(pvk)) + } + + fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { + let mut pvk = private_key_from_vec(&private_key)?; + let pbk = Secp256K1::private_to_public_uncompressed(&pvk)?; + pvk.fill(0); + Ok(Vec::from(pbk)) + } + + fn get_address(&self, public_key: Vec) -> Result { + let pbk_hash = keccak256_digest(&public_key[1..]); + let mut address_bytes: [u8; ETH_ADDR_SIZE] = [0; ETH_ADDR_SIZE]; + address_bytes.copy_from_slice(&pbk_hash[12..]); + + return ETH::addr_bytes_to_string(address_bytes); + } + + fn sign_tx( + &self, + private_key: Vec, + mut tx: Transaction, + ) -> Result { + let mut eth_tx = EthereumTransaction::decode(&tx.raw_data)?; + + //Ensure empty signature + eth_tx.signature = None; + if eth_tx.transaction_type == models::TransactionType::Legacy { + eth_tx.chain_id = Some(self.chaincode as u64); + } + + let new_rlp = eth_tx.encode()?; + let to_sign = keccak256_digest(&new_rlp[..]); + let signature = self.sign_raw(private_key, to_sign.to_vec())?; + if signature.len() != 65 { + return Err(ChainError::InvalidSignature); + } + + let _sig_hex = hex::encode(&signature[..]); + + let mut signature_bytes: [u8; 65] = [0; 65]; + signature_bytes.copy_from_slice(&signature[..]); + eth_tx.signature = Some(signature_bytes); + let signed_rlp = eth_tx.encode()?; + tx.raw_data = signed_rlp.clone(); + tx.tx_hash = Vec::from(keccak256_digest(&signed_rlp[..])); + tx.signature = signature.to_vec(); + Ok(tx) + } + + fn sign_message(&self, private_key: Vec, message: Vec) -> Result, ChainError> { + let to_sign = [ + ETH_MESSAGE_PREFIX, + message.len().to_string().as_bytes(), + &message[..], + ] + .concat(); + let hashed = keccak256_digest(&to_sign[..]); + let signature = self.sign_raw(private_key, hashed.to_vec())?; + Ok(signature) + } + + fn sign_raw(&self, private_key: Vec, payload: Vec) -> Result, ChainError> { + let mut pvk_bytes = private_key_from_vec(&private_key)?; + let payload_bytes = slice_from_vec(&payload)?; + let sig = secp256k1::Secp256K1::sign(&payload_bytes, &pvk_bytes)?; + + pvk_bytes.fill(0); + Ok(sig.to_vec()) + } + + fn get_tx_info(&self, raw_tx: Vec) -> Result { + let eth_tx = EthereumTransaction::decode(raw_tx.as_slice())?; + let mut tx_info = TxInfo { + sender: String::new(), + receiver: String::new(), + value: 0.0, + tx_type: TxType::Transfer, + }; + + if eth_tx.to.is_some() { + tx_info.tx_type = TxType::TriggerContract; + let addr_vec = eth_tx.to.unwrap_or([0; ETH_ADDR_SIZE].to_vec()); + let mut address_bytes: [u8; ETH_ADDR_SIZE] = [0; ETH_ADDR_SIZE]; + address_bytes.copy_from_slice(&addr_vec[..]); + tx_info.receiver = ETH::addr_bytes_to_string(address_bytes)?; + } + + tx_info.value = eth_tx.value.to_f64(self.get_decimals()); + + Ok(tx_info) + } +} + +#[cfg(test)] +mod test { + use crate::chains::Chain; + use alloc::string::ToString; + use alloc::vec::Vec; + + #[test] + fn test_derive() { + let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); + + let eth = super::ETH::new(); + let seed = eth.mnemonic_to_seed(mnemonic, "".to_string()).unwrap(); + let pvk = eth.derive(seed, "m/44'/60'/0'/0/0".to_string()).unwrap(); + let pbk = eth.get_pbk(pvk).unwrap(); + let addr = eth.get_address(pbk).unwrap(); + assert_eq!(addr, "0x9858EfFD232B4033E47d90003D41EC34EcaEda94"); + } + + #[test] + fn test_sign_tx() { + let raw_tx = hex::decode( + "b302f101819e84ae7937b285035f6cccc58252089498de4c83810b87f0e2cd92d80c9fac28c4ded4818568c696991f80c0808080", + ) + .unwrap(); + let pvk = hex::decode("1ab42cc412b618bdea3a599e3c9bae199ebf030895b039e9db1e30dafb12b727") + .unwrap(); + let eth = super::ETH::new(); + + let tx = crate::chains::Transaction { + raw_data: raw_tx, + tx_hash: Vec::new(), + signature: Vec::new(), + }; + + let _ = eth.sign_tx(pvk, tx).unwrap(); + } + + #[test] + fn test_sign_london_tx() { + let raw_tx = hex::decode("b87602f8730182014f84147b7eeb85084ec9f83f8301450994dac17f958d2ee523a2206206994597c13d831ec780b844a9059cbb0000000000000000000000004cbeee256240c92a9ad920ea6f4d7df6466d2cdc000000000000000000000000000000000000000000000000000000000000000ac0808080").unwrap(); + let pvk = hex::decode("1ab42cc412b618bdea3a599e3c9bae199ebf030895b039e9db1e30dafb12b727") + .unwrap(); + let eth = super::ETH::new_eth_based(56, "ETH", "Ethereum"); + + let tx = crate::chains::Transaction { + raw_data: raw_tx, + tx_hash: Vec::new(), + signature: Vec::new(), + }; + + let _ = eth.sign_tx(pvk, tx).unwrap(); + } + + #[test] + fn test_decode_tx() { + let raw_tx = hex::decode( + "ad02eb01038493a7d5d085068da15595825208944cbeee256240c92a9ad920ea6f4d7df6466d2cdc0a80c0808080", + ) + .unwrap(); + let eth = super::ETH::new(); + let tx_info = eth.get_tx_info(raw_tx).unwrap(); + assert_eq!( + tx_info.receiver, + "0x84ae7937b285035f6cccc58252089498de4c8381" + ); + assert_eq!(tx_info.value, 0.1); + } +} diff --git a/packages/kos/src/chains/eth/models.rs b/packages/kos/src/chains/eth/models.rs new file mode 100644 index 0000000..fe6e15d --- /dev/null +++ b/packages/kos/src/chains/eth/models.rs @@ -0,0 +1,182 @@ +use crate::crypto::bignum::U256; +use alloc::string::{String, ToString}; +use alloc::vec::Vec; +use rlp::{DecoderError, Rlp, RlpStream}; + +extern crate rlp; + +#[derive(Debug, PartialEq)] +pub enum TransactionType { + Legacy, + Eip155, +} + +pub struct EthereumTransaction { + pub transaction_type: TransactionType, + pub nonce: U256, + pub to: Option>, // Ethereum address (Option for contract creation) + pub gas: U256, + pub gas_price: Option, + pub value: U256, + pub data: Vec, + pub chain_id: Option, + pub max_fee_per_gas: Option, + pub max_priority_fee_per_gas: Option, + pub signature: Option<[u8; 65]>, +} + +impl EthereumTransaction { + pub fn decode(rlp_data: &[u8]) -> Result { + let rlp = Rlp::new(rlp_data); + + let tx_result = self::EthereumTransaction::decode_legacy(&rlp); + if tx_result.is_ok() { + return Ok(tx_result.unwrap()); + } + + let tx_result = self::EthereumTransaction::decode_eip_envelope(rlp); + if tx_result.is_ok() { + return Ok(tx_result.unwrap()); + } + + let rlp = Rlp::new(&rlp_data[2..]); + self::EthereumTransaction::decode_eip155(rlp) + } + + pub fn encode_eip25519(&self) -> Result { + let mut rlp = RlpStream::new(); + let list_size = if self.signature.is_some() { 12 } else { 9 }; + rlp.begin_list(list_size); + rlp.append(&self.chain_id.unwrap_or(0)); + rlp.append(&self.nonce); + rlp.append( + &self + .max_priority_fee_per_gas + .clone() + .unwrap_or(U256([0; 32])), + ); + let gas_price = self.max_fee_per_gas.clone().unwrap_or(U256([0; 32])); + + rlp.append(&gas_price); + rlp.append(&self.gas); + if let Some(to) = &self.to { + rlp.append(to); + } else { + rlp.append(&""); + } + rlp.append(&self.value); + rlp.append(&self.data); + + rlp.begin_list(0); + + if self.signature.is_some() { + let sig = self.signature.unwrap_or([0; 65]); + let mut r = U256([0; 32]); + r.0.copy_from_slice(&sig[..32]); + let mut s = U256([0; 32]); + s.0.copy_from_slice(&sig[32..64]); + let v = sig[64] as u64; + rlp.append(&v); + rlp.append(&r); + rlp.append(&s); + } + Ok(rlp) + } + + pub fn encode_legacy(&self) -> Result { + let mut rlp = RlpStream::new(); + rlp.begin_list(9); + rlp.append(&self.nonce); + rlp.append(&self.gas_price.clone().unwrap_or(U256([0; 32]))); + rlp.append(&self.gas); + if self.to.is_some() { + rlp.append(&self.to.clone().unwrap().as_slice()); + } else { + rlp.append(&""); + } + rlp.append(&self.value); + rlp.append(&self.data); + if self.chain_id.is_some() { + let cid = self.chain_id.unwrap_or(0); + if self.signature.is_some() { + let sig = self.signature.unwrap_or([0; 65]); + let mut r = U256([0; 32]); + r.0.copy_from_slice(&sig[..32]); + let mut s = U256([0; 32]); + s.0.copy_from_slice(&sig[32..64]); + let v = cid * 2 + 35 + (sig[64] as u64); + rlp.append(&v); + rlp.append(&r); + rlp.append(&s); + } else { + rlp.append(&cid); + rlp.append(&0u8); + rlp.append(&0u8); + } + } + + Ok(rlp) + } + + pub fn encode(&self) -> Result, DecoderError> { + match self.transaction_type { + TransactionType::Legacy => { + let stream = self.encode_legacy()?; + Ok(stream.out().to_vec()) + } + + TransactionType::Eip155 => { + let stream = self.encode_eip25519()?; + Ok([&[2], stream.as_raw()].concat()) + } + } + } + + pub fn decode_legacy(rlp: &Rlp) -> Result { + Ok(EthereumTransaction { + transaction_type: TransactionType::Legacy, + nonce: rlp.val_at(0)?, + gas_price: Some(rlp.val_at(1)?), + gas: rlp.val_at(2)?, + to: Some(rlp.val_at(3)?), + value: rlp.val_at(4)?, + data: rlp.val_at(5)?, + chain_id: None, + max_fee_per_gas: None, + max_priority_fee_per_gas: None, + signature: None, + }) + } + + pub fn decode_eip155(rlp: Rlp) -> Result { + Ok(EthereumTransaction { + transaction_type: TransactionType::Eip155, + chain_id: Some(rlp.val_at(0)?), + nonce: rlp.val_at(1)?, + max_priority_fee_per_gas: Some(rlp.val_at(2)?), + max_fee_per_gas: Some(rlp.val_at(3)?), + gas: rlp.val_at(4)?, + to: Some(rlp.val_at(5)?), // Convert to Option + value: rlp.val_at(6)?, + data: rlp.val_at(7)?, + signature: None, + gas_price: None, + }) + } + + pub fn decode_eip_envelope(rlp: Rlp) -> Result { + let mut string_tx: String = rlp.to_string(); + string_tx = string_tx[1..string_tx.len() - 1].to_string(); + if string_tx.starts_with("0x") { + string_tx = string_tx[2..].to_string(); + } + + let mut byte_tx = hex::decode(string_tx).map_err(|_| DecoderError::RlpExpectedToBeData)?; + if byte_tx[0] == 2 { + byte_tx.remove(0); + } + + let rlp = Rlp::new(&byte_tx); + return EthereumTransaction::decode_eip155(rlp); + } +} diff --git a/packages/kos/src/chains/icp/mod.rs b/packages/kos/src/chains/icp/mod.rs new file mode 100644 index 0000000..934e49f --- /dev/null +++ b/packages/kos/src/chains/icp/mod.rs @@ -0,0 +1,158 @@ +use crate::chains::util::private_key_from_vec; +use crate::chains::{Chain, ChainError, Transaction, TxInfo}; +use crate::crypto::bip32; +use crate::crypto::ed25519::{Ed25519, Ed25519Trait}; +use crate::crypto::hash::sha224_digest; +use alloc::string::{String, ToString}; +use alloc::vec; +use alloc::vec::Vec; + +const ASN1_ED25519_HEADER: [u8; 12] = [48u8, 42, 48, 5, 6, 3, 43, 101, 112, 3, 33, 0]; +const ICP_TAIL: u8 = 2; +const ACCOUNT_ID_STR: &str = "account-id"; +const ACCOUNT_ID_BYTE: u8 = 0x0A; +pub struct ICP {} + +impl Chain for ICP { + fn get_name(&self) -> &str { + "Internet Computer" + } + + fn get_symbol(&self) -> &str { + "ICP" + } + + fn get_decimals(&self) -> u32 { + 8 + } + + fn mnemonic_to_seed(&self, mnemonic: String, password: String) -> Result, ChainError> { + Ok(bip32::mnemonic_to_seed(mnemonic, password)?) + } + + fn derive(&self, seed: Vec, path: String) -> Result, ChainError> { + let result = bip32::derive_ed25519(&seed, path)?; + Ok(Vec::from(result)) + } + + fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { + let mut pvk_bytes = private_key_from_vec(&private_key)?; + let pbk = Ed25519::public_from_private(&pvk_bytes)?; + pvk_bytes.fill(0); + Ok(pbk) + } + + fn get_address(&self, public_key: Vec) -> Result { + let mut der = Vec::new(); + der.extend_from_slice(&ASN1_ED25519_HEADER); + der.extend_from_slice(&public_key); + + let mut der_digest = sha224_digest(&der).to_vec(); + + let mut new_digest = vec![ACCOUNT_ID_BYTE]; + new_digest.append(&mut ACCOUNT_ID_STR.as_bytes().to_vec()); + new_digest.append(der_digest.as_mut()); + new_digest.push(ICP_TAIL); + new_digest.append(&mut vec![0u8; 32]); + + let out_digest = sha224_digest(&new_digest); + let crc_calc = crc_calc_singletable(&out_digest); + + let mut addr_bytes: Vec = Vec::new(); + addr_bytes.append(&mut crc_calc.to_be_bytes().to_vec()); + addr_bytes.append(&mut out_digest.to_vec()); + + let addr = hex::encode(addr_bytes).to_string(); + Ok(addr) + } + + fn sign_tx(&self, _private_key: Vec, _tx: Transaction) -> Result { + todo!() + } + + fn sign_message( + &self, + _private_key: Vec, + _message: Vec, + ) -> Result, ChainError> { + todo!() + } + + fn sign_raw(&self, private_key: Vec, payload: Vec) -> Result, ChainError> { + let mut pvk_bytes = private_key_from_vec(&private_key)?; + + let signature = Ed25519::sign(&pvk_bytes, &payload)?; + pvk_bytes.fill(0); + Ok(signature) + } + + fn get_tx_info(&self, _raw_tx: Vec) -> Result { + todo!() + } +} + +const TABLE_0: [u32; 256] = [ + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, + 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, + 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, + 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, + 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, + 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, + 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, + 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, + 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, + 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, + 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, + 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, + 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, + 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, +]; + +pub fn crc_calc_singletable(buffer: &[u8]) -> u32 { + let mut crc: u32 = 0xFFFFFFFF; + + for &byte in buffer.iter() { + crc = TABLE_0[((crc as u8) ^ byte) as usize] ^ (crc >> 8); + } + + !crc +} + +#[cfg(test)] +mod test { + + use super::*; + #[test] + fn test_icp_get_address() { + let icp = ICP {}; + + let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); + let seed = icp.mnemonic_to_seed(mnemonic, "".to_string()).unwrap(); + let pvk = icp.derive(seed, "m/44'/223'/0'/0'/0".to_string()).unwrap(); + let pbk = icp.get_pbk(pvk).unwrap(); + + let addr = icp.get_address(pbk).unwrap(); + assert_eq!( + addr, + "11d238129427ef0e44d86bd27cb6d9da4d7e8934cb0306a93a540e657082d885" + ); + } +} diff --git a/packages/kos/src/chains/klv/mod.rs b/packages/kos/src/chains/klv/mod.rs new file mode 100644 index 0000000..b2470f8 --- /dev/null +++ b/packages/kos/src/chains/klv/mod.rs @@ -0,0 +1,244 @@ +mod models; + +use crate::chains::{Chain, ChainError, Transaction, TxInfo, TxType}; +use crate::crypto::bip32; +use crate::crypto::ed25519::{Ed25519, Ed25519Trait}; +use crate::crypto::hash::{blake2b_digest, keccak256_digest}; +use crate::protos::generated::klv::proto; +use alloc::string::{String, ToString}; +use alloc::vec::Vec; +use bech32::{u5, Variant}; + +use crate::chains::util::private_key_from_vec; +use crate::crypto::base64::simple_base64_encode; +use crate::crypto::bignum::U256; +use prost::Message; + +const KLEVER_MESSAGE_PREFIX: &str = "\x17Klever Signed Message:\n"; + +pub struct KLV {} + +impl KLV { + pub fn prepare_message(message: Vec) -> [u8; 32] { + let mut msg = Vec::new(); + msg.extend_from_slice(KLEVER_MESSAGE_PREFIX.as_bytes()); + msg.extend_from_slice(message.len().to_string().as_bytes()); + msg.extend_from_slice(&message); + + let hash_result = keccak256_digest(&msg[..]); + hash_result + } +} + +impl Chain for KLV { + fn get_name(&self) -> &str { + "Klever" + } + + fn get_symbol(&self) -> &str { + "KLV" + } + + fn get_decimals(&self) -> u32 { + 6 + } + + fn mnemonic_to_seed(&self, mnemonic: String, password: String) -> Result, ChainError> { + Ok(bip32::mnemonic_to_seed(mnemonic, password)?) + } + + fn derive(&self, seed: Vec, path: String) -> Result, ChainError> { + let result = bip32::derive_ed25519(&seed, path)?; + Ok(Vec::from(result)) + } + + fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { + let mut pvk_bytes = private_key_from_vec(&private_key)?; + let pbk = Ed25519::public_from_private(&pvk_bytes)?; + pvk_bytes.fill(0); + Ok(pbk) + } + + fn get_address(&self, public_key: Vec) -> Result { + let add_encoded = bech32::convert_bits(public_key.as_ref(), 8, 5, true)?; + let mut addr_u5: Vec = Vec::new(); + for i in add_encoded { + addr_u5.push(u5::try_from_u8(i)?); + } + let res = bech32::encode("klv", addr_u5, Variant::Bech32)?; + Ok(res) + } + + fn sign_tx( + &self, + private_key: Vec, + mut tx: Transaction, + ) -> Result { + let raw_tx = tx.raw_data; + let mut js_tx: models::Transaction = + tiny_json_rs::decode(String::from_utf8(raw_tx.clone())?)?; + let klv_tx = proto::Transaction::try_from(js_tx.clone()) + .map_err(|_| ChainError::ProtoDecodeError)?; + + let raw_data = klv_tx + .raw_data + .clone() + .ok_or(ChainError::ProtoDecodeError)?; + let mut tx_raw = Vec::with_capacity(raw_data.encoded_len()); + raw_data.encode(&mut tx_raw)?; + let result_buffer = blake2b_digest(&tx_raw); + + let sig = self.sign_raw(private_key, result_buffer.to_vec())?; + + js_tx.signature = Some(Vec::from([simple_base64_encode(&sig)])); + + tx.raw_data = tiny_json_rs::encode(js_tx).into_bytes(); + tx.tx_hash = result_buffer.to_vec(); + tx.signature = sig.as_slice().to_vec(); + Ok(tx) + } + + fn sign_message(&self, private_key: Vec, message: Vec) -> Result, ChainError> { + let prepared_messafe = KLV::prepare_message(message); + let signature = self.sign_raw(private_key, prepared_messafe.to_vec())?; + Ok(signature) + } + + fn sign_raw(&self, private_key: Vec, payload: Vec) -> Result, ChainError> { + let mut pvk_bytes = private_key_from_vec(&private_key)?; + let signature = Ed25519::sign(&pvk_bytes, &payload)?; + pvk_bytes.fill(0); + Ok(signature) + } + + fn get_tx_info(&self, raw_tx: Vec) -> Result { + let js_tx: models::Transaction = tiny_json_rs::decode(String::from_utf8(raw_tx)?)?; + let tx = proto::Transaction::try_from(js_tx).map_err(|_| ChainError::ProtoDecodeError)?; + let raw = tx.raw_data.ok_or(ChainError::ProtoDecodeError)?; + + if raw.contract.len() != 1 { + return Err(ChainError::ProtoDecodeError); + } + + let c_type: proto::tx_contract::ContractType = + proto::tx_contract::ContractType::try_from(raw.contract[0].r#type) + .map_err(|_| ChainError::ProtoDecodeError)?; + match c_type { + proto::tx_contract::ContractType::TransferContractType => { + let value = raw.contract[0].clone().parameter.unwrap().value; + let tc = proto::TransferContract::decode(value.as_slice()) + .map_err(|_| ChainError::ProtoDecodeError)?; + let sender = self.get_address(raw.sender)?; + let receiver = self.get_address(tc.to_address)?; + let value = U256::from_i64(tc.amount).to_f64(self.get_decimals()); + + Ok(TxInfo { + sender, + receiver, + value, + tx_type: TxType::Transfer, + }) + } + _ => Ok(TxInfo { + sender: String::new(), + receiver: String::new(), + value: 0.0, + tx_type: TxType::Unknown, + }), + } + } +} + +#[cfg(test)] +mod test { + use crate::chains::Chain; + use alloc::string::{String, ToString}; + use alloc::vec::Vec; + + #[test] + fn test_derive() { + let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); + let path = String::from("m/44'/690'/0'/0'/0'"); + + let seed = crate::chains::klv::KLV {} + .mnemonic_to_seed(mnemonic, String::new()) + .unwrap(); + let pvk = crate::chains::klv::KLV {}.derive(seed, path).unwrap(); + assert_eq!(pvk.len(), 32); + let pbk = crate::chains::klv::KLV {}.get_pbk(pvk).unwrap(); + assert_eq!(pbk.len(), 32); + let addr = crate::chains::klv::KLV {}.get_address(pbk).unwrap(); + assert_eq!( + addr, + "klv1usdnywjhrlv4tcyu6stxpl6yvhplg35nepljlt4y5r7yppe8er4qujlazy" + ); + } + + #[test] + fn test_sign_raw() { + let mnemonic = + "permit best kiwi blast purchase cook grab present have hurdle quarter steak" + .to_string(); + let path = String::from("m/44'/690'/0'/0'/0'"); + + let seed = crate::chains::klv::KLV {} + .mnemonic_to_seed(mnemonic, String::new()) + .unwrap(); + let pvk = crate::chains::klv::KLV {}.derive(seed, path).unwrap(); + + let digest = + hex::decode("0f47f28830f7aa9607a7a462b267003f94b4ef2c5c28ac8763cfc68e8fe10915"); + let signature = crate::chains::klv::KLV {} + .sign_raw(pvk, digest.unwrap()) + .unwrap(); + assert_eq!(signature.len(), 64) + } + + #[test] + fn test_sign_tx() { + let pvk = hex::decode("1ab42cc412b618bdea3a599e3c9bae199ebf030895b039e9db1e30dafb12b727") + .unwrap(); + + let raw_tx = hex::decode( + "7b2252617744617461223a7b224e6f6e6365223a3837312c2253656e646572223a226e506832763367457a636d41684b4c783630764d41734e65384a5871716f5a47695a30504e51434c2b55303d222c22436f6e7472616374223a5b7b22506172616d65746572223a7b22747970655f75726c223a22747970652e676f6f676c65617069732e636f6d2f70726f746f2e5472616e73666572436f6e7472616374222c2276616c7565223a224369417633486c46453731646170613948454e704a454b4671656e7468417a32306b67436c76776e46753076635249714d48686b59574d784e3259354e54686b4d6d566c4e54497a595449794d4459794d4459354f5451314f54646a4d544e6b4f444d785a574d3347416f3d227d7d5d2c224b417070466565223a313030303030302c2242616e647769647468466565223a323030303030302c2256657273696f6e223a312c22436861696e4944223a224d544134227d7d", + ) + .unwrap(); + + let tx = crate::chains::Transaction { + raw_data: raw_tx, + tx_hash: Vec::new(), + signature: Vec::new(), + }; + + let result_tx = crate::chains::klv::KLV {}.sign_tx(pvk, tx).unwrap(); + assert_eq!( + result_tx.tx_hash, + hex::decode("318d85981adc675bf7accae68d4627dca8b59f13d16e5cd23fa1a011181b8479") + .unwrap() + ) + } + + #[test] + fn test_decode_klv_tx() { + let raw_tx = hex::decode( + "7b225261774\ + 4617461223a7b224e6f6e6365223a322c2253656e646572223a2231427\ + 673447457583848784162506664437742686b6956767378446637354e7a\ + 4d4f6c44727357377034633d222c22436f6e7472616374223a5b7b22506\ + 172616d65746572223a7b22747970655f75726c223a22747970652e676f\ + 6f676c65617069732e636f6d2f70726f746f2e5472616e73666572436f6\ + e7472616374222c2276616c7565223a224369446653574f374e61687538\ + 74717056506b4d547645324a6a4649385752702f4d62452f326c702b385\ + 06f37786742227d7d5d2c224b417070466565223a3530303030302c2242\ + 616e647769647468466565223a313030303030302c2256657273696f6e2\ + 23a312c22436861696e4944223a224d544134227d7d", + ) + .unwrap(); + + let tx_info = crate::chains::klv::KLV {}.get_tx_info(raw_tx).unwrap(); + assert_eq!( + tx_info.sender, + "klv16sd7crk4jlc8csrv7lwskqrpjgjklvcsmlhexuesa9p6a3dm57rs5vh0hq" + ); + } +} diff --git a/packages/kos/src/chains/klv/models.rs b/packages/kos/src/chains/klv/models.rs new file mode 100644 index 0000000..a72b748 --- /dev/null +++ b/packages/kos/src/chains/klv/models.rs @@ -0,0 +1,241 @@ +use crate::alloc::borrow::ToOwned; +use crate::alloc::string::ToString; +use crate::crypto::base64::simple_base64_decode; +use crate::protos::generated::klv::proto; +use crate::protos::generated::klv::proto::tx_contract::ContractType; +use crate::{chains, protos}; +use alloc::format; +use alloc::string::String; +use alloc::vec::Vec; +use tiny_json_rs::mapper; +use tiny_json_rs::serializer; +use tiny_json_rs::Deserialize; +use tiny_json_rs::Serialize; + +#[derive(Serialize, Deserialize)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq)] +pub struct Transaction { + #[Rename = "RawData"] + pub raw_data: ::core::option::Option, + #[Rename = "Signature"] + pub signature: Option>, //Base64 encoded + #[Rename = "Result"] + pub result: Option, + #[Rename = "ResultCode"] + pub result_code: Option, + #[Rename = "Receipts"] + pub receipts: Option>, + #[Rename = "Block"] + pub block: Option, +} + +#[derive(Clone, PartialEq, Serialize, Deserialize)] +pub struct Raw { + #[Rename = "Nonce"] + pub nonce: u64, + #[Rename = "Sender"] + pub sender: String, + #[Rename = "Contract"] + pub contract: ::prost::alloc::vec::Vec, + #[Rename = "PermissionID"] + pub permission_id: Option, + #[Rename = "Data"] + pub data: Option>, + #[Rename = "KAppFee"] // Use this to match the exact JSON field name for this field + pub k_app_fee: Option, + #[Rename = "BandwidthFee"] // Use this to match the exact JSON field name for this field + pub bandwidth_fee: Option, + #[Rename = "Version"] + pub version: Option, + #[Rename = "ChainID"] + pub chain_id: String, + #[Rename = "KdaFee"] // Use this to match the exact JSON field name for this field + pub kda_fee: ::core::option::Option, +} + +#[derive(Serialize, Deserialize, Clone, PartialEq)] +pub struct TxContract { + #[Rename = "Parameter"] + pub parameter: Parameter, + // ... other fields +} + +#[derive(Serialize, Deserialize, Clone, PartialEq)] +pub struct Parameter { + pub type_url: String, + pub value: String, + // ... other fields +} + +#[derive(Clone, PartialEq, Serialize, Deserialize)] +pub struct KdaFee { + #[Rename = "Kda"] + pub kda: String, + #[Rename = "Amount"] + pub amount: i64, +} + +#[derive(Clone, PartialEq, Serialize, Deserialize)] +pub struct Receipt { + #[Rename = "Data"] + pub data: ::prost::alloc::vec::Vec, +} + +#[derive(Debug)] +pub enum ConversionError { + InvalidData(&'static str), + Base64Error, + // You can add more error types as needed for detailed error handling +} + +impl TryFrom for proto::Transaction { + type Error = ConversionError; + + fn try_from(value: chains::klv::models::Transaction) -> Result { + let raw_data = match value.raw_data { + Some(raw) => Some(proto::transaction::Raw::try_from(raw)?), + None => None, + }; + + let receipts = value + .receipts + .unwrap_or(Vec::new()) + .into_iter() + .map(proto::transaction::Receipt::try_from) + .collect::>()?; + + let signatures = value + .signature + .unwrap_or(Vec::new()) + .into_iter() + .map(|s| simple_base64_decode(&s).map_err(|_| ConversionError::Base64Error)) + .collect::, _>>()?; + + let proto_tx = proto::Transaction { + raw_data, + signature: signatures, + result: value.result.unwrap_or(0), + result_code: value.result_code.unwrap_or(0), + receipts, + block: value.block.unwrap_or(0), + ..Default::default() // Include other fields as necessary + }; + + Ok(proto_tx) + } +} + +impl TryFrom for proto::transaction::Raw { + type Error = ConversionError; + + fn try_from(value: chains::klv::models::Raw) -> Result { + let contracts = value + .contract + .into_iter() + .map(proto::TxContract::try_from) + .collect::>()?; + + let chain_id_bytes = + simple_base64_decode(&value.chain_id).map_err(|_| ConversionError::Base64Error)?; + + let datas = value + .data + .unwrap_or(Vec::new()) + .into_iter() + .map(|d| simple_base64_decode(&d).map_err(|_| ConversionError::Base64Error)) + .collect::, _>>()?; + + let proto_raw = proto::transaction::Raw { + nonce: value.nonce, + sender: simple_base64_decode(&value.sender) + .map_err(|_| ConversionError::Base64Error)?, + contract: contracts, + permission_id: value.permission_id.unwrap_or(0), + data: datas, + k_app_fee: value.k_app_fee.unwrap_or(0), + bandwidth_fee: value.bandwidth_fee.unwrap_or(0), + version: value.version.unwrap_or(0), + chain_id: chain_id_bytes, + kda_fee: value + .kda_fee + .map(proto::transaction::KdaFee::try_from) + .transpose()?, + ..Default::default() + }; + + Ok(proto_raw) + } +} + +impl TryFrom for proto::TxContract { + type Error = ConversionError; + + fn try_from(value: chains::klv::models::TxContract) -> Result { + let contract_name = value.parameter.type_url.clone(); + //Remove the "type.googleapis.com/" prefix + let contract_name = contract_name + .strip_prefix("type.googleapis.com/proto.") + .ok_or(ConversionError::InvalidData("Invalid contract name"))?; + //Add Type at the end of str + let contract_name = format!("{}Type", contract_name); + let contract_type = ContractType::from_str_name(&contract_name) + .ok_or(ConversionError::InvalidData("Invalid contract type"))?; + let proto_contract = proto::TxContract { + r#type: contract_type as i32, + parameter: Option::from(protos::Any::try_from(value.parameter)?), + }; + + Ok(proto_contract) + } +} + +impl TryFrom for protos::Any { + type Error = ConversionError; + + fn try_from(value: chains::klv::models::Parameter) -> Result { + let proto_parameter = protos::Any { + type_url: value.type_url, + value: simple_base64_decode(&value.value).map_err(|_| ConversionError::Base64Error)?, + ..Default::default() + }; + + Ok(proto_parameter) + } +} + +impl TryFrom for proto::transaction::KdaFee { + type Error = ConversionError; + + fn try_from(value: chains::klv::models::KdaFee) -> Result { + let kda_bytes = + simple_base64_decode(&value.kda).map_err(|_| ConversionError::Base64Error)?; + + let proto_kda_fee = proto::transaction::KdaFee { + kda: kda_bytes, + amount: value.amount, + ..Default::default() + }; + + Ok(proto_kda_fee) + } +} + +impl TryFrom for proto::transaction::Receipt { + type Error = ConversionError; + + fn try_from(value: chains::klv::models::Receipt) -> Result { + let data = value + .data + .into_iter() + .map(|d| simple_base64_decode(&d).map_err(|_| ConversionError::Base64Error)) + .collect::>()?; + + let proto_receipt = proto::transaction::Receipt { + data, + ..Default::default() + }; + + Ok(proto_receipt) + } +} diff --git a/packages/kos/src/chains/mod.rs b/packages/kos/src/chains/mod.rs new file mode 100644 index 0000000..57a1cb1 --- /dev/null +++ b/packages/kos/src/chains/mod.rs @@ -0,0 +1,348 @@ +use crate::alloc::borrow::ToOwned; +use crate::crypto::bip32::Bip32Err; +use crate::crypto::ed25519::Ed25519Err; +use crate::crypto::secp256k1::Secp256Err; +use crate::crypto::sr25519::Sr25519Error; +use alloc::boxed::Box; +use alloc::format; +use alloc::string::{FromUtf8Error, String, ToString}; +use alloc::vec::Vec; +use core::fmt::Display; +use prost::{DecodeError, EncodeError}; +use rlp::DecoderError; +use tiny_json_rs::lexer::StringType; +use tiny_json_rs::mapper; +use tiny_json_rs::serializer; +use tiny_json_rs::serializer::Token; +use tiny_json_rs::Serialize; + +pub mod ada; +mod apt; +mod atom; +mod bch; +mod bnb; +mod btc; +pub mod constants; +pub mod egld; +mod eth; +mod icp; +pub mod klv; +mod movr; +mod sol; +mod substrate; +mod sui; +pub mod trx; +mod util; +mod xrp; + +#[derive(Debug)] +pub enum ChainError { + ErrDerive, + InvalidPrivateKey, + ProtoDecodeError, + CurveError(Secp256Err), + CurveErrorSr(Sr25519Error), + EncodeError(EncodeError), + DecodeError(DecodeError), + Ed25519Error, + Bech32EncodeError, + RlpError, + InvalidMessageSize, + InvalidSignature, + NotSupported, + InvalidPublicKey, + InvalidSeed, + InvalidCredential, +} + +impl Display for ChainError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + ChainError::ErrDerive => write!(f, "Derive error"), + ChainError::InvalidPrivateKey => write!(f, "Invalid private key"), + ChainError::CurveError(e) => write!(f, "Curve error: {}", e), + ChainError::ProtoDecodeError => { + write!(f, "Proto decode error") + } + ChainError::EncodeError(e) => { + write!(f, "encode error: {}", e) + } + ChainError::DecodeError(e) => { + write!(f, "decode error: {}", e) + } + ChainError::Ed25519Error => { + write!(f, "ed25519 error") + } + ChainError::Bech32EncodeError => { + write!(f, "bech32 encode error") + } + ChainError::RlpError => { + write!(f, "rlp error") + } + ChainError::InvalidMessageSize => { + write!(f, "invalid message size") + } + ChainError::InvalidSignature => { + write!(f, "invalid signature") + } + ChainError::NotSupported => { + write!(f, "not supported") + } + ChainError::InvalidPublicKey => { + write!(f, "invalid public key") + } + ChainError::CurveErrorSr(e) => { + write!(f, "curve error sr: {}", e) + } + ChainError::InvalidSeed => { + write!(f, "invalid seed") + } + ChainError::InvalidCredential => { + write!(f, "invalid credential") + } + } + } +} + +impl From for ChainError { + fn from(value: Secp256Err) -> Self { + ChainError::CurveError(value) + } +} + +impl From for ChainError { + fn from(_: Ed25519Err) -> Self { + ChainError::Ed25519Error + } +} + +impl From for ChainError { + fn from(_: Bip32Err) -> Self { + ChainError::ErrDerive + } +} + +impl From for ChainError { + fn from(_: FromUtf8Error) -> Self { + ChainError::InvalidPrivateKey + } +} + +impl From for ChainError { + fn from(v: DecodeError) -> Self { + ChainError::DecodeError(v) + } +} + +impl From for ChainError { + fn from(v: EncodeError) -> Self { + ChainError::EncodeError(v) + } +} + +impl From for ChainError { + fn from(_: bech32::Error) -> Self { + ChainError::Bech32EncodeError + } +} + +impl From for ChainError { + fn from(_: DecoderError) -> Self { + ChainError::RlpError + } +} + +impl From for ChainError { + fn from(_: tiny_json_rs::serializer::DecodeError) -> Self { + ChainError::ProtoDecodeError + } +} + +impl From for ChainError { + fn from(value: Sr25519Error) -> Self { + ChainError::CurveErrorSr(value) + } +} + +#[allow(dead_code)] +impl ChainError { + pub fn to_u32(&self) -> u32 { + match self { + ChainError::ErrDerive => 1, + ChainError::InvalidPrivateKey => 2, + ChainError::ProtoDecodeError => 3, + ChainError::CurveError(_) => 4, + ChainError::EncodeError(_) => 5, + ChainError::DecodeError(_) => 6, + ChainError::Ed25519Error => 7, + ChainError::Bech32EncodeError => 8, + ChainError::RlpError => 9, + ChainError::InvalidMessageSize => 10, + ChainError::InvalidSignature => 11, + ChainError::NotSupported => 12, + ChainError::InvalidPublicKey => 13, + ChainError::CurveErrorSr(_) => 14, + ChainError::InvalidSeed => 15, + ChainError::InvalidCredential => 16, + } + } +} + +pub enum TxType { + Unknown, + Transfer, + TriggerContract, +} + +impl tiny_json_rs::serializer::Serialize for TxType { + fn serialize(&self) -> tiny_json_rs::mapper::Value { + let str = match self { + TxType::Unknown => "Unknown", + TxType::Transfer => "Transfer", + TxType::TriggerContract => "TriggerContract", + }; + let token = Token { + token_type: tiny_json_rs::lexer::TokenType::String(StringType::SimpleString), + literal: str.to_string(), + }; + + tiny_json_rs::mapper::Value::Token(token) + } +} + +#[derive(Serialize)] +pub struct TxInfo { + pub sender: String, + pub receiver: String, + pub value: f64, + pub tx_type: TxType, +} + +pub struct Transaction { + pub raw_data: Vec, + pub tx_hash: Vec, + pub signature: Vec, +} + +#[allow(dead_code)] +impl Transaction { + pub fn default() -> Self { + Self { + raw_data: Vec::new(), + tx_hash: Vec::new(), + signature: Vec::new(), + } + } +} + +pub trait Chain { + fn get_name(&self) -> &str; + fn get_symbol(&self) -> &str; + fn get_decimals(&self) -> u32; + fn mnemonic_to_seed(&self, mnemonic: String, password: String) -> Result, ChainError>; + fn derive(&self, seed: Vec, path: String) -> Result, ChainError>; + fn get_pbk(&self, private_key: Vec) -> Result, ChainError>; + fn get_address(&self, public_key: Vec) -> Result; + fn sign_tx(&self, private_key: Vec, tx: Transaction) -> Result; + fn sign_message(&self, private_key: Vec, message: Vec) -> Result, ChainError>; + fn sign_raw(&self, private_key: Vec, payload: Vec) -> Result, ChainError>; + fn get_tx_info(&self, raw_tx: Vec) -> Result; +} + +pub fn get_chain_by_id(id: u32) -> Option> { + match id { + constants::ETH => Some(Box::new(eth::ETH::new())), + constants::BSC => Some(Box::new(eth::ETH::new_eth_based( + 56, + "BSC", + "BnbSmartChain", + ))), + constants::POLYGON => Some(Box::new(eth::ETH::new_eth_based(137, "MATIC", "Polygon"))), + constants::HT => Some(Box::new(eth::ETH::new_eth_based(128, "HT", "Huobi"))), + constants::SYS_NEVM => Some(Box::new(eth::ETH::new_eth_based( + 57, + "SYS_NEVM", + "Syscoin Nevm", + ))), + constants::TRX => Some(Box::new(trx::TRX {})), + constants::KLV => Some(Box::new(klv::KLV {})), + constants::BTC => Some(Box::new(btc::BTC::new())), + constants::DOT => Some(Box::new(substrate::Substrate::new(0, "DOT", "Polkadot"))), + constants::KSM => Some(Box::new(substrate::Substrate::new(2, "KSM", "Kusama"))), + constants::LTC => Some(Box::new(btc::BTC::new_btc_based("ltc", "LTC", "Litecoin"))), + constants::REEF => Some(Box::new(substrate::Substrate::new(42, "REEF", "Reef"))), + constants::SDN => Some(Box::new(substrate::Substrate::new(5, "SDN", "Shiden"))), + constants::ASTR => Some(Box::new(substrate::Substrate::new(5, "ASTR", "Astar"))), + constants::CFG => Some(Box::new(substrate::Substrate::new(36, "CFG", "Centrifuge"))), + constants::SYS => Some(Box::new(btc::BTC::new_btc_based("sys", "SYS", "Syscoin"))), + constants::KILT => Some(Box::new(substrate::Substrate::new(38, "KILT", "KILT"))), + constants::ALTAIR => Some(Box::new(substrate::Substrate::new(136, "ALTAIR", "Altair"))), + constants::DOGE => Some(Box::new(btc::BTC::new_legacy_btc_based( + 0x1E, "DOGE", "Dogecoin", + ))), + constants::DASH => Some(Box::new(btc::BTC::new_legacy_btc_based( + 0x4C, "DASH", "Dash", + ))), + constants::XRP => Some(Box::new(xrp::XRP::new())), + constants::DGB => Some(Box::new(btc::BTC::new_btc_based("dgb", "DGB", "Digibyte"))), + constants::COSMOS => Some(Box::new(atom::ATOM::new())), + constants::CELESTIA => Some(Box::new(atom::ATOM::new_cosmos_based( + "celestia", "celestia", "Celestia", "TIA", + ))), + constants::CUDOS => Some(Box::new(atom::ATOM::new_cosmos_based( + "cudos", "cudos-1", "Cudos", "CUDOS", + ))), + constants::AURA => Some(Box::new(atom::ATOM::new_cosmos_based( + "aura", "xstaxy-1", "Aura", "AURA", + ))), + constants::ICP => Some(Box::new(icp::ICP {})), + constants::SOL => Some(Box::new(sol::SOL {})), + constants::MOVR => Some(Box::new(movr::MOVR::new())), + constants::GLMR => Some(Box::new(movr::MOVR::new_glmr())), + constants::BNB => Some(Box::new(bnb::BNB {})), + constants::BCH => Some(Box::new(bch::BCH {})), + constants::ADA => Some(Box::new(ada::ADA {})), + constants::SUI => Some(Box::new(sui::SUI {})), + constants::APT => Some(Box::new(apt::APT {})), + constants::AVAIL => Some(Box::new(substrate::Substrate::new(42, "AVAIL", "Avail"))), + constants::ROLLUX => Some(Box::new(eth::ETH::new_eth_based(570, "ROLLUX", "Rollux"))), + constants::AVAX => Some(Box::new(eth::ETH::new_eth_based( + 43114, + "AVAX", + "Avalanche", + ))), + constants::ARB => Some(Box::new(eth::ETH::new_eth_based(42161, "ARB", "Arbitrum"))), + constants::BASE => Some(Box::new(eth::ETH::new_eth_based(8453, "BASE", "Base"))), + constants::NEAR => Some(Box::new(eth::ETH::new_eth_based(397, "NEAR", "Near"))), + constants::FTM => Some(Box::new(eth::ETH::new_eth_based(250, "FTM", "Fantom"))), + constants::CHZ => Some(Box::new(eth::ETH::new_eth_based(88888, "CHZ", "Chiliz"))), + constants::OP => Some(Box::new(eth::ETH::new_eth_based(10, "OP", "Optimism"))), + constants::POLYGON_ZKEVM => Some(Box::new(eth::ETH::new_eth_based( + 1101, + "ZKEVM", + "Polygon zkEVM", + ))), + constants::STOLZ => Some(Box::new(eth::ETH::new_eth_based(2344, "STOLZ", "Stolz"))), + _ => None, + } +} + +pub enum CustomChainType { + NotCustom(u32), + CustomEth(u32), + CustomSubstrate(u32), + CustomCosmos(String), +} + +pub fn get_chain_by_params(params: CustomChainType) -> Option> { + return match params { + CustomChainType::NotCustom(c) => get_chain_by_id(c), + CustomChainType::CustomEth(chaincode) => Some(Box::new(eth::ETH::new_eth_based( + chaincode, + format!("ETH {}", chaincode).as_str(), + format!("Eth Based {}", chaincode).as_str(), + ))), + CustomChainType::CustomSubstrate(_) => None, + CustomChainType::CustomCosmos(_) => None, + }; +} diff --git a/packages/kos/src/chains/movr/mod.rs b/packages/kos/src/chains/movr/mod.rs new file mode 100644 index 0000000..6788bb4 --- /dev/null +++ b/packages/kos/src/chains/movr/mod.rs @@ -0,0 +1,118 @@ +use crate::chains::eth::ETH; +use crate::chains::util::{private_key_from_vec, slice_from_vec}; +use crate::chains::{Chain, ChainError, Transaction}; +use crate::crypto::hash::keccak256_digest; +use crate::crypto::secp256k1::{Secp256K1, Secp256k1Trait}; +use crate::crypto::{bip32, secp256k1}; +use alloc::string::{String, ToString}; +use alloc::vec::Vec; + +pub struct MOVR { + name: String, + symbol: String, + decimals: u32, +} + +impl MOVR { + pub fn new() -> Self { + MOVR { + name: "Moonriver".to_string(), + symbol: "MOVR".to_string(), + decimals: 18, + } + } + + pub fn new_glmr() -> Self { + MOVR { + name: "Moonbeam".to_string(), + symbol: "GLMR".to_string(), + decimals: 18, + } + } +} + +impl Chain for MOVR { + fn get_name(&self) -> &str { + &self.name + } + + fn get_symbol(&self) -> &str { + &self.symbol + } + + fn get_decimals(&self) -> u32 { + self.decimals + } + + fn mnemonic_to_seed(&self, mnemonic: String, password: String) -> Result, ChainError> { + Ok(bip32::mnemonic_to_seed(mnemonic, password)?) + } + + fn derive(&self, seed: Vec, path: String) -> Result, ChainError> { + let result = bip32::derive(&seed, path)?; + Ok(Vec::from(result)) + } + + fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { + let pvk = private_key_from_vec(&private_key)?; + + let pbk = Secp256K1::private_to_public_uncompressed(&pvk)?; + Ok(Vec::from(pbk)) + } + + fn get_address(&self, public_key: Vec) -> Result { + let pbk_hash = keccak256_digest(&public_key[1..]); + let mut address_bytes: [u8; crate::chains::eth::ETH_ADDR_SIZE] = + [0; crate::chains::eth::ETH_ADDR_SIZE]; + address_bytes.copy_from_slice(&pbk_hash[12..]); + + return ETH::addr_bytes_to_string(address_bytes); + } + + fn sign_tx( + &self, + private_key: Vec, + mut tx: Transaction, + ) -> Result { + let tx_bytes = tx.raw_data.clone(); + let tx_hash = keccak256_digest(&tx_bytes); + + let sig = self.sign_raw(private_key, tx_hash.clone().to_vec())?; + tx.signature = sig; + tx.tx_hash = tx_hash.to_vec(); + + Ok(tx) + } + + fn sign_raw(&self, private_key: Vec, payload: Vec) -> Result, ChainError> { + let mut pvk_bytes = private_key_from_vec(&private_key)?; + let payload_bytes = slice_from_vec(&payload)?; + + let sig = secp256k1::Secp256K1::sign(&payload_bytes, &pvk_bytes)?; + + pvk_bytes.fill(0); + Ok(sig.to_vec()) + } + + fn sign_message(&self, private_key: Vec, message: Vec) -> Result, ChainError> { + if private_key.len() != 32 { + return Err(ChainError::InvalidPrivateKey); + } + + let mut pvk_bytes: [u8; 32] = [0; 32]; + pvk_bytes.copy_from_slice(&private_key[..32]); + + let mut payload_bytes: [u8; 32] = [0; 32]; + payload_bytes.copy_from_slice(&message[..32]); + + let sig = secp256k1::Secp256K1::sign(&payload_bytes, &pvk_bytes)?; + Ok(sig.to_vec()) + } + + fn get_tx_info( + &self, + _raw_tx: Vec, + ) -> Result { + Err(ChainError::NotSupported) + } +} diff --git a/packages/kos/src/chains/sol/mod.rs b/packages/kos/src/chains/sol/mod.rs new file mode 100644 index 0000000..1967ef1 --- /dev/null +++ b/packages/kos/src/chains/sol/mod.rs @@ -0,0 +1,85 @@ +use crate::chains::util::private_key_from_vec; +use crate::chains::{Chain, ChainError, Transaction, TxInfo}; +use crate::crypto::b58::b58enc; +use crate::crypto::bip32; +use crate::crypto::ed25519::{Ed25519, Ed25519Trait}; +use alloc::string::String; +use alloc::vec::Vec; + +pub struct SOL {} + +impl Chain for SOL { + fn get_name(&self) -> &str { + "Solana" + } + + fn get_symbol(&self) -> &str { + "SOL" + } + + fn get_decimals(&self) -> u32 { + todo!() + } + + fn mnemonic_to_seed(&self, mnemonic: String, password: String) -> Result, ChainError> { + Ok(bip32::mnemonic_to_seed(mnemonic, password)?) + } + + fn derive(&self, seed: Vec, path: String) -> Result, ChainError> { + let result = bip32::derive_ed25519(&seed, path)?; + Ok(Vec::from(result)) + } + + fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { + let mut pvk_bytes = private_key_from_vec(&private_key)?; + let pbk = Ed25519::public_from_private(&pvk_bytes)?; + pvk_bytes.fill(0); + Ok(pbk) + } + + fn get_address(&self, public_key: Vec) -> Result { + let addr = b58enc(&public_key); + Ok(String::from_utf8(addr)?) + } + + fn sign_tx(&self, _private_key: Vec, _tx: Transaction) -> Result { + Err(ChainError::NotSupported) + } + + fn sign_message( + &self, + _private_key: Vec, + _message: Vec, + ) -> Result, ChainError> { + Err(ChainError::NotSupported) + } + + fn sign_raw(&self, private_key: Vec, payload: Vec) -> Result, ChainError> { + let mut pvk_bytes = private_key_from_vec(&private_key)?; + let signature = Ed25519::sign(&pvk_bytes, &payload)?; + pvk_bytes.fill(0); + Ok(signature) + } + + fn get_tx_info(&self, _raw_tx: Vec) -> Result { + Err(ChainError::NotSupported) + } +} + +#[cfg(test)] +mod test { + use super::*; + use alloc::string::ToString; + + #[test] + fn test_derive() { + let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); + + let sol = super::SOL {}; + let seed = sol.mnemonic_to_seed(mnemonic, "".to_string()).unwrap(); + let pvk = sol.derive(seed, "m/44'/501'/0'/0'/0'".to_string()).unwrap(); + let pbk = sol.get_pbk(pvk).unwrap(); + let addr = sol.get_address(pbk).unwrap(); + assert_eq!(addr, "B9sVeu4rJU12oUrUtzjc6BSNuEXdfvurZkdcaTVkP2LY"); + } +} diff --git a/packages/kos/src/chains/substrate/mod.rs b/packages/kos/src/chains/substrate/mod.rs new file mode 100644 index 0000000..88a66e5 --- /dev/null +++ b/packages/kos/src/chains/substrate/mod.rs @@ -0,0 +1,182 @@ +mod models; + +use crate::chains::util::private_key_from_vec; +use crate::chains::{Chain, ChainError, Transaction, TxInfo}; +use crate::crypto::hash::blake2b_64_digest; +use crate::crypto::sr25519::Sr25519Trait; +use crate::crypto::{b58, bip32, sr25519}; +use alloc::string::{String, ToString}; +use alloc::vec::Vec; +use models::{Call, CallArgs}; +use parity_scale_codec::Decode; + +const LOWER_MASK: u16 = 0x3FFF; +const TYPE1_ACCOUNT_ID: u16 = 63; +const IDENTIFIER_LOWER_MASK: u16 = 0x00FC; +const IDENTIFIER_UPPER_MASK: u16 = 0x0003; +const IDENTIFIER_LOWER_PREFIX: u8 = 0x40; +const SUBSTRATE_NETWORK_PREFIX: &str = "SS58PRE"; + +pub struct Substrate { + network_id: u16, + name: String, + symbol: String, +} + +impl Substrate { + pub fn new(network_id: u16, name: &str, symbol: &str) -> Self { + Self { + network_id, + name: name.to_string(), + symbol: symbol.to_string(), + } + } +} + +impl Chain for Substrate { + fn get_name(&self) -> &str { + self.name.as_str() + } + + fn get_symbol(&self) -> &str { + self.symbol.as_str() + } + + fn get_decimals(&self) -> u32 { + 12 + } + + fn mnemonic_to_seed(&self, mnemonic: String, password: String) -> Result, ChainError> { + Ok(bip32::mnemonic_to_seed_substrate(mnemonic, password)?) + } + + fn derive(&self, seed: Vec, path: String) -> Result, ChainError> { + let pvk = bip32::derive_sr25519(&seed, path)?; + Ok(pvk.to_vec()) + } + + fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { + let mut pvk = private_key_from_vec(&private_key)?; + let pbk = sr25519::Sr25519::public_from_private(&pvk)?; + pvk.fill(0); + Ok(pbk) + } + + fn get_address(&self, public_key: Vec) -> Result { + let identifier = self.network_id & LOWER_MASK; + let mut prefix = Vec::new(); + if identifier < TYPE1_ACCOUNT_ID { + prefix.push(identifier as u8); + } else { + let lower_byte = ((identifier & IDENTIFIER_LOWER_MASK) >> 2) as u8; + let upper_byte = + ((identifier >> 8) | ((identifier & IDENTIFIER_UPPER_MASK) << 6)) as u8; + prefix.push(lower_byte | IDENTIFIER_LOWER_PREFIX); + prefix.push(upper_byte); + } + + let data_to_hash = [ + SUBSTRATE_NETWORK_PREFIX.as_bytes(), + &prefix[..], + &public_key[..], + ] + .concat(); + let digest = blake2b_64_digest(&data_to_hash); + + let to_base_58 = [&prefix[..], &public_key[..], &digest[..2].to_vec()].concat(); + let encoded = b58::b58enc(&to_base_58); + let addr = String::from_utf8(encoded).unwrap(); + Ok(addr) + } + + fn sign_tx( + &self, + private_key: Vec, + mut tx: Transaction, + ) -> Result { + let sig = self.sign_raw(private_key, tx.raw_data.clone())?; + tx.signature = [[1u8].to_vec(), sig].concat(); + Ok(tx) + } + + fn sign_message(&self, private_key: Vec, message: Vec) -> Result, ChainError> { + self.sign_raw(private_key, message) + } + + fn sign_raw(&self, private_key: Vec, payload: Vec) -> Result, ChainError> { + let mut private_key_bytes = private_key_from_vec(&private_key)?; + let sig = sr25519::Sr25519::sign(&payload, &private_key_bytes)?; + private_key_bytes.fill(0); + Ok(sig) + } + + fn get_tx_info(&self, _raw_tx: Vec) -> Result { + let info = Call::decode(&mut &_raw_tx[..]).map_err(|_| ChainError::InvalidPrivateKey)?; + let args = info.args.to_vec(); + let tx_info = + CallArgs::decode(&mut &args[..]).map_err(|_| ChainError::InvalidPrivateKey)?; + let address_to = self.get_address(tx_info.addr_to.to_vec())?; + let new_tx_info = TxInfo { + receiver: address_to, + sender: "".to_string(), + tx_type: super::TxType::Unknown, + value: tx_info.amount.to_f64(self.get_decimals()), + }; + Ok(new_tx_info) + } +} + +#[cfg(test)] +mod test { + + use crate::chains::Chain; + use alloc::string::{String, ToString}; + + #[test] + fn test_get_addr() { + let dot = super::Substrate::new(0, "Polkadot", "DOT"); + + let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); + let path = String::from(""); + + let seed = dot.mnemonic_to_seed(mnemonic, String::from("")).unwrap(); + let pvk = dot.derive(seed, path).unwrap(); + let pbk = dot.get_pbk(pvk).unwrap(); + let addr = dot.get_address(pbk).unwrap(); + assert_eq!(addr, "13KVd4f2a4S5pLp4gTTFezyXdPWx27vQ9vS6xBXJ9yWVd7xo"); + } + + #[test] + fn test_sign_raw() { + let dot = super::Substrate::new(0, "Polkadot", "DOT"); + + let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); + let path = String::from(""); + + let seed = dot.mnemonic_to_seed(mnemonic, String::from("")).unwrap(); + let pvk = dot.derive(seed, path).unwrap(); + let payload = [0; 32].to_vec(); + let _tx = dot.sign_raw(pvk, payload).unwrap(); + } + + #[test] + fn sign_tx() { + let dot = super::Substrate::new(0, "Polkadot", "DOT"); + + let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); + let path = String::from(""); + + let seed = dot.mnemonic_to_seed(mnemonic, String::from("")).unwrap(); + let _pvk = dot.derive(seed, path).unwrap(); + } + + #[test] + fn test_get_tx_info() { + let dot = super::Substrate::new(0, "Polkadot", "DOT"); + let raw_data = "05030092fb4dc4e0790663aa4be18e6c49d62e8db091a6e1c4d0727c14906cf79f0f7a280000002b460f001900000091b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c391b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3".to_string(); + + let raw_data_hex = hex::decode(raw_data).unwrap(); + let tx_info = dot.get_tx_info(raw_data_hex); + assert!(tx_info.is_ok()); + } +} \ No newline at end of file diff --git a/packages/kos/src/chains/substrate/models.rs b/packages/kos/src/chains/substrate/models.rs new file mode 100644 index 0000000..fe4f9e6 --- /dev/null +++ b/packages/kos/src/chains/substrate/models.rs @@ -0,0 +1,140 @@ +use alloc::vec; +use alloc::vec::Vec; +use parity_scale_codec::{Decode, Input}; + +use crate::crypto::bignum::U256; + +#[derive(Decode)] +pub struct Call { + pub call_index: CallIndex, + pub args: [u8; 100], +} + +#[derive(Decode)] +pub struct CallIndex { + _section_index: u8, + _method_index: u8, +} + +#[derive(Decode)] +pub struct CallArgs { + pub addr_to: MultiAddress, + pub amount: UIntCompact, +} + +pub struct MultiAddress { + pub is_id: bool, + pub as_id: [u8; 32], + pub is_index: bool, + pub as_index: u32, + pub is_raw: bool, + pub as_raw: [u8; 32], + pub is_address32: bool, + pub as_address32: [u8; 32], + pub is_address20: bool, + pub as_address20: [u8; 20], +} + +impl MultiAddress { + pub fn to_vec(&self) -> Vec { + if self.is_id { + return self.as_id.to_vec(); + } + if self.is_index { + return self.as_index.to_le_bytes().to_vec(); + } + if self.is_raw { + return self.as_raw.to_vec(); + } + if self.is_address32 { + return self.as_address32.to_vec(); + } + return self.as_address20.to_vec(); + } +} + +impl Decode for MultiAddress { + fn decode(input: &mut I) -> Result { + let mut address = MultiAddress { + is_id: false, + as_id: [0; 32], + is_index: false, + as_index: 0, + is_raw: false, + as_raw: [0; 32], + is_address32: false, + as_address32: [0; 32], + is_address20: false, + as_address20: [0; 20], + }; + let t = input.read_byte()?; + + match t { + 1 => { + address.is_index = true; + let mut as_index = [0u8; 4]; + let _ = input.read(&mut as_index); + address.as_index = u32::from_le_bytes(as_index); + return Ok(address); + } + 2 => { + address.is_raw = true; + let _ = input.read(&mut address.as_raw); + return Ok(address); + } + 3 => { + address.is_address32 = true; + let _ = input.read(&mut address.as_address32); + return Ok(address); + } + 4 => { + address.is_address20 = true; + let _ = input.read(&mut address.as_address20); + return Ok(address); + } + _ => { + address.is_id = true; + let _ = input.read(&mut address.as_id); + return Ok(address); + } + } + } +} + +pub type UIntCompact = U256; + +impl Decode for UIntCompact { + fn decode(input: &mut I) -> Result { + let b = input.read_byte()?; + let mode = b & 3; + + match mode { + 1 => { + let bb = input.read_byte()?; + let mut r = bb as u64; + r <<= 6; + r += (b >> 2) as u64; + return Ok(U256::from_u64((r) as u64)); + } + 2 => { + let mut buf = [0u8; 4]; + let _ = input.read(&mut buf); + let mut r = u32::from_le_bytes(buf); + r >>= 2; + return Ok(U256::from_u64((r) as u64)); + } + 3 => { + let l = b >> 2; + if l > 63 { + todo!() + } + let mut buf = vec![0u8; (l + 4) as usize]; + input.read(&mut buf)?; + return Ok(U256::read_data_as_le(buf)); + } + _ => { + return Ok(U256::from_u64((b >> 2) as u64)); + } + } + } +} \ No newline at end of file diff --git a/packages/kos/src/chains/sui/mod.rs b/packages/kos/src/chains/sui/mod.rs new file mode 100644 index 0000000..69b8400 --- /dev/null +++ b/packages/kos/src/chains/sui/mod.rs @@ -0,0 +1,121 @@ +use crate::chains::util::private_key_from_vec; +use crate::chains::{Chain, ChainError, Transaction, TxInfo}; +use crate::crypto::bip32; +use crate::crypto::ed25519::{Ed25519, Ed25519Trait}; +use crate::crypto::hash::blake2b_digest; +use alloc::string::{String, ToString}; +use alloc::vec::Vec; + +pub struct SUI {} + +impl Chain for SUI { + fn get_name(&self) -> &str { + "Sui" + } + + fn get_symbol(&self) -> &str { + "SUI" + } + + fn get_decimals(&self) -> u32 { + todo!() + } + + fn mnemonic_to_seed(&self, mnemonic: String, password: String) -> Result, ChainError> { + Ok(bip32::mnemonic_to_seed(mnemonic, password)?) + } + + fn derive(&self, seed: Vec, path: String) -> Result, ChainError> { + let result = bip32::derive_ed25519(&seed, path)?; + Ok(Vec::from(result)) + } + + fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { + let mut pvk_bytes = private_key_from_vec(&private_key)?; + let pbk = Ed25519::public_from_private(&pvk_bytes)?; + pvk_bytes.fill(0); + Ok(pbk) + } + + fn get_address(&self, public_key: Vec) -> Result { + if public_key.len() != 32 { + return Err(ChainError::InvalidPublicKey); + } + + let mut signed_pbk = [0u8; 33]; + signed_pbk[1..].copy_from_slice(&public_key[..]); + + let checksum = blake2b_digest(&signed_pbk); + let hex_encode = hex::encode(checksum); + let mut addr = "0x".to_string(); + addr.push_str(&hex_encode[..64]); + Ok(addr) + } + + fn sign_tx( + &self, + private_key: Vec, + mut tx: Transaction, + ) -> Result { + let raw = tx.raw_data.clone(); + let signature = self.sign_message(private_key, raw)?; + tx.signature = signature; + Ok(tx) + } + + fn sign_message(&self, private_key: Vec, message: Vec) -> Result, ChainError> { + let mut intent_message = Vec::new(); + intent_message.append(&mut [0; 3].to_vec()); + intent_message.append(&mut message.clone()); + + let check_sum = blake2b_digest(&intent_message); + let mut pvk_bytes = private_key_from_vec(&private_key)?; + + let mut response = Vec::new(); + response.push(0x00); + + let signature = Ed25519::sign(&pvk_bytes, &check_sum)?; + response.append(&mut signature.clone()); + + let pbk = Ed25519::public_from_private(&pvk_bytes)?; + response.append(&mut pbk.clone()); + + pvk_bytes.fill(0); + Ok(response) + } + + fn sign_raw(&self, private_key: Vec, payload: Vec) -> Result, ChainError> { + let mut pvk_bytes = private_key_from_vec(&private_key)?; + let signature = Ed25519::sign(&pvk_bytes, &payload)?; + + pvk_bytes.fill(0); + Ok(signature) + } + + fn get_tx_info(&self, _raw_tx: Vec) -> Result { + Err(ChainError::NotSupported) + } +} + +#[cfg(test)] +mod test { + use crate::chains::Chain; + use alloc::string::{String, ToString}; + + #[test] + fn test_derive() { + let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); + + let sui = super::SUI {}; + let seed = sui.mnemonic_to_seed(mnemonic, String::new()).unwrap(); + let pvk = sui + .derive(seed.clone(), "m/44'/784'/0'/0'/0'".to_string()) + .unwrap(); + let pbk = sui.get_pbk(pvk.clone()).unwrap(); + let addr = sui.get_address(pbk.clone()).unwrap(); + assert_eq!( + addr, + "0x5e93a736d04fbb25737aa40bee40171ef79f65fae833749e3c089fe7cc2161f1" + ); + } +} diff --git a/packages/kos/src/chains/trx/mod.rs b/packages/kos/src/chains/trx/mod.rs new file mode 100644 index 0000000..544c4c2 --- /dev/null +++ b/packages/kos/src/chains/trx/mod.rs @@ -0,0 +1,328 @@ +use crate::chains::util::{private_key_from_vec, slice_from_vec}; +use crate::chains::{Chain, ChainError, Transaction, TxInfo, TxType}; +use crate::crypto::b58::b58enc; +use crate::crypto::bignum::U256; +use crate::crypto::hash::{keccak256_digest, sha256_digest}; +use crate::crypto::secp256k1::Secp256k1Trait; +use crate::crypto::{bip32, secp256k1}; +use crate::protos::generated::trx::protocol; +use crate::protos::generated::trx::protocol::transaction::contract::ContractType; +use alloc::string::{String, ToString}; +use alloc::vec; +use alloc::vec::Vec; +use prost::Message; + +const TRX_ADDR_PREFIX: u8 = 0x41; +const TRX_ADD_RAW_LEN: usize = 21; +const TRX_ADD_SIZE: usize = 25; + +const TRON_MESSAGE_PREFIX: &str = "\x19TRON Signed Message:\n"; +pub struct TRX {} + +impl TRX { + pub fn prepare_message(message: Vec) -> [u8; 32] { + let mut msg = Vec::new(); + msg.extend_from_slice(TRON_MESSAGE_PREFIX.as_bytes()); + msg.extend_from_slice(message.len().to_string().as_bytes()); + msg.extend_from_slice(&message); + + let hash_result = keccak256_digest(&msg[..]); + hash_result + } + + pub fn expand_address_with_checksum(address: &[u8; 21]) -> String { + let mut address_with_checksum: [u8; TRX_ADD_SIZE] = [0; TRX_ADD_SIZE]; + address_with_checksum[..TRX_ADD_RAW_LEN].copy_from_slice(&address[..]); + let hash = sha256_digest(&address_with_checksum[..TRX_ADD_RAW_LEN]); + let hash = sha256_digest(&hash[..]); + address_with_checksum[21..].copy_from_slice(&hash[0..4]); + let bytes_addr = b58enc(&address_with_checksum[..]); + let addr = String::from_utf8(bytes_addr).unwrap(); + addr + } + + pub fn decode_transaction(raw_tx: Vec) -> Result { + let tx = protocol::Transaction::decode(raw_tx.as_slice()); + match tx { + Ok(t) => return Ok(t), + Err(_) => {} + } + + let raw_tx = protocol::transaction::Raw::decode(raw_tx.as_slice())?; + let tx = protocol::Transaction { + raw_data: Some(raw_tx), + signature: vec![], + ret: vec![], + }; + + Ok(tx) + } +} + +impl Chain for TRX { + fn get_name(&self) -> &str { + return "TRON"; + } + + fn get_symbol(&self) -> &str { + return "TRX"; + } + + fn get_decimals(&self) -> u32 { + return 6; + } + + fn mnemonic_to_seed(&self, mnemonic: String, password: String) -> Result, ChainError> { + Ok(bip32::mnemonic_to_seed(mnemonic, password)?) + } + + fn derive(&self, seed: Vec, path: String) -> Result, ChainError> { + let pvk = bip32::derive(&seed, path)?; + Ok(Vec::from(pvk)) + } + + fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { + let mut pvk = private_key_from_vec(&private_key)?; + let pbk = secp256k1::Secp256K1::private_to_public_uncompressed(&pvk)?; + pvk.fill(0); + Ok(Vec::from(pbk)) + } + + fn get_address(&self, public_key: Vec) -> Result { + let hash = keccak256_digest(&public_key[1..]); + + let mut address: [u8; TRX_ADD_RAW_LEN] = [0; TRX_ADD_RAW_LEN]; + address[0] = TRX_ADDR_PREFIX; + address[1..TRX_ADD_RAW_LEN].copy_from_slice(&hash[12..]); + Ok(TRX::expand_address_with_checksum(&address)) + } + + fn sign_tx( + &self, + private_key: Vec, + mut tx: Transaction, + ) -> Result { + let raw_tx = tx.raw_data; + + if private_key.len() != 32 { + return Err(ChainError::InvalidPrivateKey); + } + + let mut pvk_bytes: [u8; 32] = [0; 32]; + pvk_bytes.copy_from_slice(&private_key[..32]); + let mut tron_tx = TRX::decode_transaction(raw_tx)?; + + let raw_data_clone = tron_tx + .raw_data + .clone() + .ok_or(ChainError::ProtoDecodeError)?; + let mut tx_raw = Vec::new(); + raw_data_clone.encode(&mut tx_raw)?; + + let tx_id = sha256_digest(&tx_raw[..]); + let sig = secp256k1::Secp256K1::sign(&tx_id, &pvk_bytes)?; + + tron_tx.signature.push(sig.to_vec()); + + let mut tx_data = Vec::new(); + tron_tx.encode(&mut tx_data)?; + + tx.raw_data = tx_data; + tx.tx_hash = tx_id.to_vec(); + tx.signature = sig.as_slice().to_vec(); + Ok(tx) + } + + fn sign_message(&self, private_key: Vec, message: Vec) -> Result, ChainError> { + if private_key.len() != 32 { + return Err(ChainError::InvalidPrivateKey); + } + + let mut pvk_bytes: [u8; 32] = [0; 32]; + pvk_bytes.copy_from_slice(&private_key[..32]); + + let parsed_message = TRX::prepare_message(message); + let sig = self.sign_raw(private_key, parsed_message.to_vec())?; + Ok(sig.as_slice().to_vec()) + } + + fn sign_raw(&self, private_key: Vec, payload: Vec) -> Result, ChainError> { + let mut pvk_bytes = private_key_from_vec(&private_key)?; + let payload_bytes = slice_from_vec(&payload)?; + + let sig = secp256k1::Secp256K1::sign(&payload_bytes, &pvk_bytes)?; + + pvk_bytes.fill(0); + Ok(sig.to_vec()) + } + + fn get_tx_info(&self, raw_tx: Vec) -> Result { + let tx = TRX::decode_transaction(raw_tx)?; + let raw = tx.raw_data.ok_or(ChainError::ProtoDecodeError)?; + if raw.contract.len() == 0 { + return Err(ChainError::ProtoDecodeError); + } + + let contract = raw.contract[0].clone(); + + let contract_type = + ContractType::try_from(contract.r#type).map_err(|_| ChainError::ProtoDecodeError)?; + let parameter = contract.parameter.ok_or(ChainError::ProtoDecodeError)?; + + match contract_type { + ContractType::TransferContract => { + let transfer_contract = + protocol::TransferContract::decode(parameter.value.as_slice())?; + let mut owner_u8_addr: [u8; 21] = [0; 21]; + let mut owner_address = String::from(""); + + if transfer_contract.owner_address.len() >= TRX_ADD_RAW_LEN { + owner_u8_addr.copy_from_slice(&transfer_contract.owner_address[..]); + owner_address = TRX::expand_address_with_checksum(&owner_u8_addr); + } + + let mut to_u8_addr: [u8; 21] = [0; 21]; + let mut to_address = String::from(""); + + if transfer_contract.to_address.len() >= TRX_ADD_RAW_LEN { + to_u8_addr.copy_from_slice(&transfer_contract.to_address[..]); + to_address = TRX::expand_address_with_checksum(&to_u8_addr); + } + + let value = U256::from_i64(transfer_contract.amount).to_f64(self.get_decimals()); + return Ok(TxInfo { + sender: owner_address, + receiver: to_address, + value, + tx_type: TxType::Transfer, + }); + } + + ContractType::TransferAssetContract => { + let transfer_contract: protocol::TransferAssetContract = + protocol::TransferAssetContract::decode(parameter.value.as_slice())?; + let mut owner_u8_addr: [u8; 21] = [0; 21]; + let mut owner_address = String::from(""); + + if transfer_contract.owner_address.len() >= TRX_ADD_RAW_LEN { + owner_u8_addr.copy_from_slice(&transfer_contract.owner_address[..]); + owner_address = TRX::expand_address_with_checksum(&owner_u8_addr); + } + + let mut to_u8_addr: [u8; 21] = [0; 21]; + let mut to_address = String::from(""); + + if transfer_contract.to_address.len() >= TRX_ADD_RAW_LEN { + to_u8_addr.copy_from_slice(&transfer_contract.to_address[..]); + to_address = TRX::expand_address_with_checksum(&to_u8_addr); + } + + let value = U256::from_i64(transfer_contract.amount).to_f64(self.get_decimals()); + return Ok(TxInfo { + sender: owner_address, + receiver: to_address, + value, + tx_type: TxType::Transfer, + }); + } + + ContractType::TriggerSmartContract => { + let trigger_contract = + protocol::TriggerSmartContract::decode(parameter.value.as_slice())?; + let mut owner_u8_addr: [u8; 21] = [0; 21]; + let mut owner_address = String::from(""); + + if trigger_contract.owner_address.len() >= TRX_ADD_RAW_LEN { + owner_u8_addr.copy_from_slice(&trigger_contract.owner_address[..]); + owner_address = TRX::expand_address_with_checksum(&owner_u8_addr); + } + + let mut to_u8_addr: [u8; 21] = [0; 21]; + let mut to_address = String::from(""); + + if trigger_contract.contract_address.len() >= TRX_ADD_RAW_LEN { + to_u8_addr.copy_from_slice(&trigger_contract.contract_address[..]); + to_address = TRX::expand_address_with_checksum(&to_u8_addr); + } + + return Ok(TxInfo { + sender: owner_address, + receiver: to_address, + value: 0.0, + tx_type: TxType::TriggerContract, + }); + } + _ => {} + }; + + Ok(TxInfo { + sender: "".to_string(), + receiver: "".to_string(), + value: 0.0, + tx_type: TxType::Unknown, + }) + } +} + +#[cfg(test)] +mod test { + use crate::chains::{Chain, Transaction}; + use alloc::string::{String, ToString}; + use alloc::vec; + + #[test] + fn test_trx_derive() { + let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); + let path = String::from("m/44'/195'/0'/0/0"); + + let seed = crate::chains::trx::TRX {} + .mnemonic_to_seed(mnemonic, String::from("")) + .unwrap(); + let pvk = crate::chains::trx::TRX {}.derive(seed, path).unwrap(); + assert_eq!(pvk.len(), 32); + let pbk = crate::chains::trx::TRX {}.get_pbk(pvk).unwrap(); + assert_eq!(pbk.len(), 65); + let addr = crate::chains::trx::TRX {}.get_address(pbk).unwrap(); + assert_eq!(addr, "TUEZSdKsoDHQMeZwihtdoBiN46zxhGWYdH"); + } + + #[test] + fn test_sign_tx() { + let hex_tx = hex::decode( + "0a02487c22080608af18\ + f6ec6c8340d8f8fae2e0315a65080112610a2d747970652e676f6f676c65\ + 617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e74\ + 7261637412300a1541e825d52582eec346c839b4875376117904a76cbc121\ + 54120ab1300cf70c048e4cf5d5b1b33f59653ed6626180a708fb1f7e2e031", + ) + .unwrap(); + + let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); + let path = String::from("m/44'/195'/0'/0/0"); + + let seed = crate::chains::trx::TRX {} + .mnemonic_to_seed(mnemonic, String::from("")) + .unwrap(); + let pvk = crate::chains::trx::TRX {}.derive(seed, path).unwrap(); + assert_eq!(pvk.len(), 32); + + let tx = Transaction { + raw_data: hex_tx, + tx_hash: vec![], + signature: vec![], + }; + let _tx = crate::chains::trx::TRX {}.sign_tx(pvk, tx).unwrap(); + } + + #[test] + fn test_decode_tx() { + let hex_tx = hex::decode("0a022986220894d3a7d6c869ebc840c0e1b2b5e1315a65080112610a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412300a1541e825d52582eec346c839b4875376117904a76cbc12154120ab1300cf70c048e4cf5d5b1b33f59653ed6626180a70ae9cafb5e131").unwrap(); + + let info = crate::chains::trx::TRX {}.get_tx_info(hex_tx).unwrap(); + let res = tiny_json_rs::encode(info); + assert_eq!( + res, + r#"{"receiver":"TCwwZeH6so1X4R5kcdbKqa4GWuzF53xPqG","sender":"TX8h6Df74VpJsXF6sTDz1QJsq3Ec8dABc3","tx_type":"Transfer","value":0.00001}"# + ); + } +} diff --git a/packages/kos/src/chains/util.rs b/packages/kos/src/chains/util.rs new file mode 100644 index 0000000..5400088 --- /dev/null +++ b/packages/kos/src/chains/util.rs @@ -0,0 +1,17 @@ +use crate::chains::ChainError; +use alloc::vec::Vec; + +pub fn slice_from_vec(vec: &Vec) -> Result<[u8; N], ChainError> { + if vec.len() < N { + return Err(ChainError::InvalidMessageSize); + } + + let mut arr: [u8; N] = [0; N]; + arr.copy_from_slice(&vec[..]); + Ok(arr) +} + +pub fn private_key_from_vec(vec: &Vec) -> Result<[u8; N], ChainError> { + return slice_from_vec::(vec).map_err(|_| ChainError::InvalidPrivateKey); +} + diff --git a/packages/kos/src/chains/xrp/mod.rs b/packages/kos/src/chains/xrp/mod.rs new file mode 100644 index 0000000..4f4e710 --- /dev/null +++ b/packages/kos/src/chains/xrp/mod.rs @@ -0,0 +1,119 @@ +use crate::chains::util::{private_key_from_vec, slice_from_vec}; +use crate::chains::{Chain, ChainError, Transaction, TxInfo}; +use crate::crypto::b58::custom_b58enc; +use crate::crypto::bip32; +use crate::crypto::hash::{ripemd160_digest, sha256_digest}; +use crate::crypto::secp256k1::{Secp256K1, Secp256k1Trait}; +use alloc::string::String; +use alloc::vec; +use alloc::vec::Vec; + +const XRP_ALPHA: &[u8; 58] = b"rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz"; + +pub(crate) struct XRP {} + +impl XRP { + pub fn new() -> Self { + XRP {} + } +} + +impl Chain for XRP { + fn get_name(&self) -> &str { + "Ripple" + } + + fn get_symbol(&self) -> &str { + "XRP" + } + + fn get_decimals(&self) -> u32 { + todo!() + } + + fn mnemonic_to_seed(&self, mnemonic: String, password: String) -> Result, ChainError> { + Ok(bip32::mnemonic_to_seed(mnemonic, password)?) + } + + fn derive(&self, seed: Vec, path: String) -> Result, ChainError> { + let pvk = bip32::derive(&seed, path)?; + Ok(pvk.to_vec()) + } + + fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { + if private_key.len() != 32 { + return Err(ChainError::InvalidPrivateKey); + } + + let mut pk_bytes: [u8; 32] = [0; 32]; + pk_bytes.copy_from_slice(&private_key[..32]); + + let pbk = Secp256K1::private_to_public_compressed(&pk_bytes)?; + Ok(pbk.to_vec()) + } + + fn get_address(&self, public_key: Vec) -> Result { + if public_key.len() != 33 { + return Err(ChainError::InvalidPublicKey); + } + + let mut pubkey_bytes = [0; 33]; + pubkey_bytes.copy_from_slice(&public_key[..33]); + + let hash = ripemd160_digest(&pubkey_bytes); + + let to_base_58 = [vec![0], hash[..].to_vec()].concat(); + let checksum = sha256_digest(&sha256_digest(&to_base_58)); + let checksum_bytes = checksum[..4].to_vec(); + let to_base_58 = [&to_base_58[..], &checksum_bytes[..]].concat(); + + let res = custom_b58enc(&to_base_58, XRP_ALPHA); + let addr = String::from_utf8(res)?; + Ok(addr) + } + + fn sign_tx(&self, _private_key: Vec, _tx: Transaction) -> Result { + Err(ChainError::NotSupported) + } + + fn sign_message( + &self, + _private_key: Vec, + _message: Vec, + ) -> Result, ChainError> { + Err(ChainError::NotSupported) + } + + fn sign_raw(&self, private_key: Vec, payload: Vec) -> Result, ChainError> { + let pvk_bytes = private_key_from_vec(&private_key)?; + let payload_bytes = slice_from_vec(&payload)?; + + let sig = Secp256K1::sign(&payload_bytes, &pvk_bytes)?; + Ok(sig.to_vec()) + } + + fn get_tx_info(&self, _raw_tx: Vec) -> Result { + Err(ChainError::NotSupported) + } +} + +#[cfg(test)] +mod test { + use crate::chains::Chain; + use alloc::string::{String, ToString}; + + #[test] + fn test_get_addr() { + let xrp = super::XRP::new(); + + let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); + let path = String::from("m/44'/144'/0'/0/0"); + + let seed = xrp.mnemonic_to_seed(mnemonic, String::from("")).unwrap(); + let pvk = xrp.derive(seed, path).unwrap(); + let pbk = xrp.get_pbk(pvk).unwrap(); + let addr = xrp.get_address(pbk).unwrap(); + + assert_eq!(addr, "rHsMGQEkVNJmpGWs8XUBoTBiAAbwxZN5v3"); + } +} diff --git a/packages/kos/src/crypto/b58.rs b/packages/kos/src/crypto/b58.rs new file mode 100644 index 0000000..a39c2a5 --- /dev/null +++ b/packages/kos/src/crypto/b58.rs @@ -0,0 +1,51 @@ +use alloc::vec; +use alloc::vec::Vec; + +const B58DIGITS_ORDERED: &[u8; 58] = b"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; + +pub fn custom_b58enc(data: &[u8], alpha: &[u8; 58]) -> Vec { + let mut zcount = 0; + + while zcount < data.len() && data[zcount] == 0 { + zcount += 1; + } + + let size = (data.len() - zcount) * 138 / 100 + 1; + let mut buf = vec![0u8; size]; + + let mut high = size - 1; + for (_, &val) in data.iter().enumerate().skip(zcount) { + let mut carry = val as usize; + let mut j = size - 1; + + while j > high || carry != 0 { + carry += 256 * buf[j] as usize; + buf[j] = (carry % 58) as u8; + carry /= 58; + + if j == 0 { + break; + } + j -= 1; + } + high = j; + } + + let mut j = 0; + while j < size && buf[j] == 0 { + j += 1; + } + + let mut result = Vec::with_capacity(zcount + size - j); + result.extend(vec![alpha[0]; zcount]); + + for &val in &buf[j..] { + result.push(alpha[val as usize]); + } + + result +} + +pub fn b58enc(data: &[u8]) -> Vec { + custom_b58enc(data, B58DIGITS_ORDERED) +} diff --git a/packages/kos/src/crypto/base64.rs b/packages/kos/src/crypto/base64.rs new file mode 100644 index 0000000..27edd2f --- /dev/null +++ b/packages/kos/src/crypto/base64.rs @@ -0,0 +1,63 @@ +// A very simple base64 encoder for demonstration purposes +pub fn simple_base64_encode(input: &[u8]) -> alloc::string::String { + const CHARSET: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + let mut output = alloc::string::String::new(); + + let mut temp = 0u32; + let mut temp_bits = 0; + + for byte in input { + temp <<= 8; + temp |= *byte as u32; + temp_bits += 8; + + while temp_bits >= 6 { + temp_bits -= 6; + output.push(CHARSET[((temp >> temp_bits) & 0x3F) as usize] as char); + } + } + + if temp_bits > 0 { + temp <<= 6 - temp_bits; + output.push(CHARSET[(temp & 0x3F) as usize] as char); + } + + while output.len() % 4 != 0 { + output.push('='); + } + + output +} + +// A very simple base64 decoder for demonstration purposes +pub fn simple_base64_decode(input: &str) -> Result, &'static str> { + let input = input.trim_end_matches('='); + let mut buffer = alloc::vec::Vec::new(); + + let mut temp = 0u32; + let mut temp_bits = 0; + for c in input.chars() { + let value = match c as u8 { + b'A'..=b'Z' => c as u8 - b'A', + b'a'..=b'z' => c as u8 - b'a' + 26, + b'0'..=b'9' => c as u8 - b'0' + 52, + b'+' => 62, + b'/' => 63, + _ => return Err("Invalid base64 character"), + }; + temp <<= 6; + temp |= value as u32; + temp_bits += 6; + + if temp_bits >= 8 { + temp_bits -= 8; + buffer.push((temp >> temp_bits) as u8); + } + } + + if temp_bits >= 6 || (temp & ((1 << temp_bits) - 1)) != 0 { + return Err("Invalid base64 padding"); + } + + Ok(buffer) +} diff --git a/packages/kos/src/crypto/bignum.rs b/packages/kos/src/crypto/bignum.rs new file mode 100644 index 0000000..303984c --- /dev/null +++ b/packages/kos/src/crypto/bignum.rs @@ -0,0 +1,152 @@ +use alloc::vec::Vec; +use core::f64; +use rlp::{DecoderError, Rlp, RlpStream}; + +pub struct U256(pub [u8; 32]); + +impl Clone for U256 { + fn clone(&self) -> Self { + let mut bytes: [u8; 32] = [0; 32]; + bytes.copy_from_slice(&self.0[..]); + U256(bytes) + } +} + +impl rlp::Decodable for U256 { + fn decode(rlp: &Rlp) -> Result { + let data: Vec = rlp.as_val()?; + + let val = U256::read_data_as_le(data.clone()); + + Ok(val) + } +} + +impl rlp::Encodable for U256 { + fn rlp_append(&self, s: &mut RlpStream) { + //Copy data as the reverse of the bytes removing the leading zeroes + let to_put = self.put_data_as_le(); + + s.encoder().encode_value(&to_put); + } +} + +impl U256 { + pub fn to_f64(&self, precision: u32) -> f64 { + let bytes = self.0; + let mut value: f64 = 0.0; + + for i in 0..32 { + value *= 256.0; + value += bytes[i] as f64; + } + + value = value / (powi(10.0, precision as i32) as f64); + value + } + + pub fn from_i64(value: i64) -> U256 { + let value = value as u64; + U256::from_u64(value) + } + + pub fn from_u64(value: u64) -> U256 { + let mut bytes: [u8; 32] = [0; 32]; + bytes[24..32].copy_from_slice(&value.to_be_bytes()); + U256(bytes) + } + + #[allow(dead_code)] + pub fn to_u64_be(&self) -> u64 { + let bytes = self.0; + let mut significant_part = [0u8; 8]; + significant_part.copy_from_slice(&bytes[24..32]); + u64::from_be_bytes(significant_part) + } + + #[allow(dead_code)] + pub fn read_data_as_be(data: Vec) -> Self { + let mut bytes: [u8; 32] = [0; 32]; + let len = data.len().min(32); + for i in 0..len { + bytes[i] = data[i]; + } + + U256(bytes) + } + + pub fn read_data_as_le(data: Vec) -> Self { + let mut bytes: [u8; 32] = [0; 32]; + let len = data.len(); + for i in 0..len { + bytes[i] = data[len - 1 - i]; + } + + U256(bytes) + } + + #[allow(dead_code)] + pub fn put_data_as_be(&self) -> Vec { + let mut data: Vec = Vec::new(); + for i in 0..32 { + data.push(self.0[i]); + } + + data + } + + pub fn put_data_as_le(&self) -> Vec { + let mut data: Vec = Vec::new(); + //find the end of the data + for i in 0..32 { + data.push(self.0[31 - i]); + } + + //Trim the leading zeroes + let mut start = data.len(); + for i in 0..32 { + if data[i] != 0 { + start = i; + break; + } + } + + data = data[start..].to_vec(); + data + } +} + +fn powi(f: f64, exp: i32) -> f64 { + let mut result = 1.0; + let mut base = f; + let mut exponent = exp; + + if exponent < 0 { + base = 1.0 / base; + exponent = -exponent; + } + + while exponent > 0 { + if exponent % 2 == 1 { + result *= base; + } + base *= base; + exponent /= 2; + } + + result +} + +#[cfg(test)] +mod test { + use crate::crypto::bignum::U256; + + #[test] + fn test_f64_conversion() { + let mut value = U256([0x0; 32]); + value.0[31] = 0x01; + let precision = 6; + let float_value = value.to_f64(precision); + assert_eq!(float_value, 1e-6); + } +} diff --git a/packages/kos/src/crypto/bip32.rs b/packages/kos/src/crypto/bip32.rs new file mode 100644 index 0000000..56dcb14 --- /dev/null +++ b/packages/kos/src/crypto/bip32.rs @@ -0,0 +1,360 @@ +use crate::crypto::ed25519::{Ed25519Err, Ed25519Trait}; +use crate::crypto::ed25519_bip32::{add28_mul8, add_mod256}; +use crate::crypto::pbkdf2::{Pbkdf2, Pbkdf2Trait}; +use crate::crypto::secp256k1::{Secp256Err, Secp256K1, Secp256k1Trait}; +use crate::crypto::sr25519::{Sr25519, Sr25519Error, Sr25519Trait}; +use alloc::string::{String, ToString}; +use alloc::vec; +use alloc::vec::Vec; +use bip39_dict::{Entropy, ENGLISH}; +use core::fmt::{Display, Formatter}; +use core::num::ParseIntError; +use core::str::FromStr; +use hmac::digest::InvalidLength; +use hmac::{Hmac, Mac}; +use pbkdf2::pbkdf2_hmac; +use sha2::Sha512; + +const BTC_SEED_NAME: &[u8] = b"Bitcoin seed"; +const ED25519_NAME: &[u8] = b"ed25519 seed"; + +const BIP39_PBKDF2_ROUNDS: u32 = 2048; + +#[derive(Debug)] +pub enum Bip32Err { + ConversionErr, + Secp256Err(Secp256Err), + Sr25519Error(Sr25519Error), + HmacError, + DeriveError, + PathError, + InvalidMnemonic, +} + +impl Display for Bip32Err { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + match self { + Bip32Err::ConversionErr => write!(f, "Conversion error"), + Bip32Err::Secp256Err(v) => write!(f, "Curve error: {}", v), + Bip32Err::PathError => write!(f, "Path error"), + Bip32Err::DeriveError => write!(f, "Derive error"), + Bip32Err::InvalidMnemonic => write!(f, "Invalid mnemonic"), + Bip32Err::Sr25519Error(v) => write!(f, "Sr25519 error: {}", v), + Bip32Err::HmacError => write!(f, "Hmac error"), + } + } +} + +impl From for Bip32Err { + fn from(_: ParseIntError) -> Self { + Bip32Err::ConversionErr + } +} + +impl From for Bip32Err { + fn from(value: Secp256Err) -> Self { + Bip32Err::Secp256Err(value) + } +} + +impl From for Bip32Err { + fn from(_: Ed25519Err) -> Self { + Bip32Err::DeriveError + } +} + +impl From for Bip32Err { + fn from(value: Sr25519Error) -> Self { + Bip32Err::Sr25519Error(value) + } +} + +impl From for Bip32Err { + fn from(_: InvalidLength) -> Self { + Bip32Err::HmacError + } +} + +type Hmac512 = Hmac; +pub fn compute_hmac(message: &[u8], key: &[u8]) -> Result<(Vec, Vec), Bip32Err> { + let mut mac = Hmac512::new_from_slice(key)?; + mac.update(message); + let result = mac.finalize().into_bytes(); + let vec_result = result.to_vec(); + let mut left = vec![0u8; 32]; + let mut right = vec![0u8; 32]; + left.copy_from_slice(&vec_result[..32]); + right.copy_from_slice(&vec_result[32..]); + + Ok((left, right)) +} + +pub fn compute_master_from_seed(seed: &[u8]) -> Result<(Vec, Vec), Bip32Err> { + let (left, right) = compute_hmac(seed, BTC_SEED_NAME)?; + Ok((left, right)) +} + +pub struct PathComponent { + pub is_hardened: bool, + pub index: u32, +} + +pub fn handle_path(path: String) -> Result, Bip32Err> { + let mut components: Vec<&str> = path.split('/').collect(); + Vec::remove(&mut components, 0); + let mut path_components: Vec = Vec::new(); + + for component in components { + let mut is_hardened = false; + let index: u32; + if component.contains("'") { + is_hardened = true; + index = component.replace("'", "").parse::().unwrap(); + } else { + index = component.parse::()? + } + + path_components.push(PathComponent { is_hardened, index }); + } + + return Ok(path_components); +} + +pub fn derive_private_key( + pvk: &[u8; 32], + ch: &[u8; 32], + mut pc: PathComponent, +) -> Result<([u8; 32], [u8; 32]), Bip32Err> { + let mut data: Vec = Vec::new(); + if pc.is_hardened { + pc.index |= 0x80000000; + data.push(0); + data.extend_from_slice(pvk); + } else { + let pbk = Secp256K1::private_to_public_compressed(pvk)?; + data = Vec::from(pbk); + } + + data.extend_from_slice(&pc.index.to_be_bytes()); + let (hmac_master, hmac_ch) = compute_hmac(&data, ch)?; + let mut new_data: [u8; 32] = [0; 32]; + let mut new_ch: [u8; 32] = [0; 32]; + new_data.copy_from_slice(&hmac_master[..32]); + new_ch.copy_from_slice(&hmac_ch[..32]); + + let x = Secp256K1::add_scalars(pvk, &new_data)?; + + return Ok((x, new_ch)); +} + +pub fn derive_pk_from_path( + pvk: &[u8], + ch: &[u8], + path_c: Vec, +) -> Result<[u8; 32], Bip32Err> { + let mut data: [u8; 32] = [0; 32]; + data.copy_from_slice(pvk); + + let mut chaincode: [u8; 32] = [0; 32]; + chaincode.copy_from_slice(ch); + + for component in path_c { + let (new_data, new_ch) = derive_private_key(&data, &chaincode, component)?; + data.copy_from_slice(&new_data); + chaincode.copy_from_slice(&new_ch); + } + + Ok(data) +} +pub fn derive(input_key: &[u8], path: String) -> Result<[u8; 32], Bip32Err> { + let path_components = handle_path(path)?; + let (master_key, chain_code) = compute_master_from_seed(input_key)?; + let pk = derive_pk_from_path(&master_key, &chain_code, path_components)?; + Ok(pk) +} + +pub fn derive_ed25519(input_key: &[u8], path: String) -> Result<[u8; 32], Bip32Err> { + let path_components = handle_path(path)?; + + let (mut key, mut chaincode) = compute_hmac(input_key, ED25519_NAME)?; + + for mut component in path_components { + let mut data = Vec::new(); + data.push(0); + data.extend_from_slice(&key[..32]); + if component.is_hardened { + component.index |= 0x80000000; + } + + data.extend_from_slice(&component.index.to_be_bytes()); + let (hmac_master, hmac_ch) = compute_hmac(&data, &chaincode)?; + key = hmac_master; + chaincode = hmac_ch; + } + + let mut result_key: [u8; 32] = [0; 32]; + result_key.copy_from_slice(&key[..32]); + Ok(result_key) +} + +pub fn derive_sr25519(input_key: &[u8], mut path: String) -> Result<[u8; 64], Bip32Err> { + let mut chaincode = [0u8; 32]; + let mut is_hardned = false; + if path != "" { + path = path + .strip_prefix("//") + .ok_or(Bip32Err::PathError)? + .to_string(); + path = path + .strip_suffix("///") + .ok_or(Bip32Err::PathError)? + .to_string(); + + let chaincode_value = u8::from_str(path.as_str()).map_err(|_| Bip32Err::PathError)?; + + chaincode[0] = chaincode_value; + is_hardned = true; + } + + let mut mini_sk = [0; 32]; + mini_sk.copy_from_slice(&input_key[..32]); + + let (mut sk, mut nonce) = Sr25519::expand_secret_key(&mini_sk)?; + if is_hardned { + let mini_sk = Sr25519::hard_derive_mini_sk(&mini_sk, &chaincode)?; + (sk, nonce) = Sr25519::expand_secret_key(&mini_sk)? + } + + let mut result_key: [u8; 64] = [0; 64]; + result_key[..32].copy_from_slice(&sk); + result_key[32..].copy_from_slice(&nonce); + + Ok(result_key) +} + +pub fn mnemonic_to_seed(mnemonic: String, password: String) -> Result, Bip32Err> { + let mut salt = String::from("mnemonic"); + salt.push_str(password.as_str()); + let mut seed = [0u8; 64]; + pbkdf2_hmac::( + mnemonic.as_bytes(), + salt.as_bytes(), + BIP39_PBKDF2_ROUNDS, + &mut seed, + ); + Ok(Vec::from(seed)) +} + +pub fn mnemonic_to_seed_substrate(mnemonic: String, password: String) -> Result, Bip32Err> { + let entropy = mnemonic_to_entropy(mnemonic)?; + let mut salt = String::from("mnemonic"); + salt.push_str(password.as_str()); + let mut seed = [0u8; 64]; + pbkdf2_hmac::( + entropy.as_slice(), + salt.as_bytes(), + BIP39_PBKDF2_ROUNDS, + &mut seed, + ); + Ok(Vec::from(seed)) +} + +pub fn mnemonic_to_entropy(mnemonic: String) -> Result, Bip32Err> { + let words_count = mnemonic.split(" ").count(); + match words_count { + 12 => mnemonic_to_entropy_12(mnemonic), + 24 => mnemonic_to_entropy_24(mnemonic), + _ => Err(Bip32Err::InvalidMnemonic), + } +} + +pub fn mnemonic_to_entropy_12(mnemonic: String) -> Result, Bip32Err> { + let mnemonic = + bip39_dict::Mnemonics::<12>::from_string(&bip39_dict::ENGLISH, mnemonic.as_str()) + .map_err(|_| Bip32Err::InvalidMnemonic)?; + + let entropy = + Entropy::<16>::from_mnemonics::<12, 4>(&mnemonic).map_err(|_| Bip32Err::InvalidMnemonic)?; + + Ok(entropy.0.to_vec()) +} + +pub fn mnemonic_to_entropy_24(mnemonic: String) -> Result, Bip32Err> { + let mnemonic = + bip39_dict::Mnemonics::<24>::from_string(&bip39_dict::ENGLISH, mnemonic.as_str()) + .map_err(|_| Bip32Err::InvalidMnemonic)?; + + let entropy = + Entropy::<32>::from_mnemonics::<24, 8>(&mnemonic).map_err(|_| Bip32Err::InvalidMnemonic)?; + + Ok(entropy.0.to_vec()) +} + +pub fn mnemonic_to_seed_ed25519_bip32(mnemonic: String) -> Result, Bip32Err> { + let entropy = mnemonic_to_entropy(mnemonic)?; + let icarus_key = Pbkdf2::pbkdf2_hmac_512::<96>(&[], &entropy, 4096); + + let mut pvk = icarus_key.to_vec(); + pvk[0] &= 0xf8; + pvk[31] &= 0x1f; + pvk[31] |= 0x40; + + return Ok(pvk); +} + +pub fn derive_ed25519_bip32(input_key: [u8; 96], path: String) -> Result<[u8; 96], Bip32Err> { + let path_components = handle_path(path)?; + let mut pvk = [0u8; 64]; + let mut chaincode = [0u8; 32]; + + pvk.copy_from_slice(&input_key[..64]); + chaincode.copy_from_slice(&input_key[64..]); + + for mut component in path_components { + if component.is_hardened { + component.index |= 0x80000000; + } + + let mut zmac = Hmac512::new_from_slice(&chaincode)?; + let mut ccmac = Hmac512::new_from_slice(&chaincode)?; + + let sindex = component.index.to_le_bytes().to_vec(); + + if component.is_hardened { + zmac.update(&[0]); + zmac.update(&pvk); + zmac.update(&sindex); + ccmac.update(&[0x01]); + ccmac.update(&pvk); + ccmac.update(&sindex); + } else { + let pub_key = crate::crypto::ed25519::Ed25519::public_from_extended(&pvk)?; + zmac.update(&[0x02]); + zmac.update(&pub_key); + zmac.update(&sindex); + ccmac.update(&[0x03]); + ccmac.update(&pub_key); + ccmac.update(&sindex); + } + + let z = zmac.finalize().into_bytes(); + let zl = z[..32].to_vec(); + let zr = z[32..].to_vec(); + + let kl = add28_mul8(&pvk[0..32], &zl); + let kr = add_mod256(&pvk[32..64], &zr); + + let cc = ccmac.finalize().into_bytes(); + let cc = cc[32..].to_vec(); + + pvk[0..32].copy_from_slice(&kl); + pvk[32..64].copy_from_slice(&kr); + chaincode.copy_from_slice(&cc); + } + + let mut result_key: [u8; 96] = [0; 96]; + result_key[..64].copy_from_slice(&pvk); + result_key[64..].copy_from_slice(&chaincode); + + Ok(result_key) +} diff --git a/packages/kos/src/crypto/ed25519.rs b/packages/kos/src/crypto/ed25519.rs new file mode 100644 index 0000000..3633ad8 --- /dev/null +++ b/packages/kos/src/crypto/ed25519.rs @@ -0,0 +1,64 @@ +use alloc::vec::Vec; +use core::fmt::Display; +use ed25519_dalek::hazmat::ExpandedSecretKey; +use ed25519_dalek::Signer; +use sha2::Sha512; + +#[derive(Debug)] +#[allow(dead_code)] +pub enum Ed25519Err { + ErrDerive, +} + +impl Display for Ed25519Err { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Ed25519Err::ErrDerive => write!(f, "Derive error"), + } + } +} + +pub struct Ed25519 {} + +pub trait Ed25519Trait { + fn public_from_private(pvk: &[u8; 32]) -> Result, Ed25519Err>; + fn sign(pvk: &[u8; 32], msg: &[u8]) -> Result, Ed25519Err>; + fn public_from_extended(pvk: &[u8; 64]) -> Result, Ed25519Err>; + fn sign_extended(pvk: &[u8; 64], msg: &[u8]) -> Result, Ed25519Err>; +} + +impl Ed25519Trait for Ed25519 { + fn public_from_private(pvk: &[u8; 32]) -> Result, Ed25519Err> { + let mut sk = ed25519_dalek::SecretKey::default(); + sk.copy_from_slice(pvk); + let pb = ed25519_dalek::SigningKey::from(&sk) + .verifying_key() + .to_bytes() + .to_vec(); + if pb.len() != 32 { + return Err(Ed25519Err::ErrDerive); + } + + Ok(pb) + } + + fn public_from_extended(pvk: &[u8; 64]) -> Result, Ed25519Err> { + let vk = ed25519_dalek::VerifyingKey::from(&ExpandedSecretKey::from_bytes(pvk)); + Ok(vk.to_bytes().to_vec()) + } + + fn sign_extended(pvk: &[u8; 64], msg: &[u8]) -> Result, Ed25519Err> { + let expanded = ExpandedSecretKey::from_bytes(pvk); + let vk = ed25519_dalek::VerifyingKey::from(&ExpandedSecretKey::from_bytes(pvk)); + let sig = ed25519_dalek::hazmat::raw_sign::(&expanded, msg, &vk); + Ok(sig.to_bytes().as_slice().to_vec()) + } + + fn sign(pvk: &[u8; 32], msg: &[u8]) -> Result, Ed25519Err> { + let mut sk = ed25519_dalek::SecretKey::default(); + sk.copy_from_slice(pvk); + let sig_key = ed25519_dalek::SigningKey::from(&sk); + let sig = sig_key.sign(msg); + Ok(sig.to_bytes().as_slice().to_vec()) + } +} diff --git a/packages/kos/src/crypto/ed25519_bip32.rs b/packages/kos/src/crypto/ed25519_bip32.rs new file mode 100644 index 0000000..7bf59ae --- /dev/null +++ b/packages/kos/src/crypto/ed25519_bip32.rs @@ -0,0 +1,37 @@ +use alloc::vec; +use alloc::vec::Vec; + +pub fn add28_mul8(x: &[u8], y: &[u8]) -> Vec { + let mut out = vec![0u8; 32]; + let mut carry = 0u16; + + // Process the first 28 bytes with multiplication by 8 + for i in 0..28 { + let r = x[i] as u16 + ((y[i] as u16) << 3) + carry; + out[i] = (r & 0xff) as u8; + carry = r >> 8; + } + + // Process the remaining bytes with only carry + for i in 28..32 { + let r = x[i] as u16 + carry; + out[i] = (r & 0xff) as u8; + carry = r >> 8; + } + + out +} + +pub fn add_mod256(x: &[u8], y: &[u8]) -> Vec { + let mut out = vec![0u8; 32]; // Initialize output vector with 32 zeros + let mut carry = 0u16; // Initialize carry as a 16-bit integer to hold overflow + + for i in 0..32 { + // Perform the addition with carry for each byte + let r = x[i] as u16 + y[i] as u16 + carry; + out[i] = (r & 0xFF) as u8; // Assign the lower 8 bits to the output + carry = r >> 8; // Update carry with the overflow bit + } + + out +} diff --git a/packages/kos/src/crypto/hash.rs b/packages/kos/src/crypto/hash.rs new file mode 100644 index 0000000..333311b --- /dev/null +++ b/packages/kos/src/crypto/hash.rs @@ -0,0 +1,87 @@ +use blake2b_ref::Blake2bBuilder; +use sha2::digest::FixedOutput; +use sha2::Digest; + +pub fn sha256_digest(data: &[u8]) -> [u8; 32] { + let mut hasher = sha2::Sha256::default(); + hasher.update(data); + let mut hash: [u8; 32] = [0; 32]; + let out = hasher.finalize_fixed(); + hash.copy_from_slice(&out[..]); + hash +} + +#[allow(dead_code)] +pub fn sha512_digest(data: &[u8]) -> [u8; 64] { + let mut hasher = sha2::Sha512::default(); + hasher.update(data); + let mut hash: [u8; 64] = [0; 64]; + let out = hasher.finalize_fixed(); + hash.copy_from_slice(&out[..]); + hash +} + +#[allow(dead_code)] +pub fn sha3_digest(data: &[u8]) -> [u8; 32] { + let mut hasher = sha3::Sha3_256::default(); + hasher.update(data); + let mut hash: [u8; 32] = [0; 32]; + let out = hasher.finalize_fixed(); + hash.copy_from_slice(&out[..]); + hash +} + +pub fn keccak256_digest(data: &[u8]) -> [u8; 32] { + let mut hasher = sha3::Keccak256::default(); + hasher.update(data); + let mut hash: [u8; 32] = [0; 32]; + let out = hasher.finalize_fixed(); + hash.copy_from_slice(&out[..]); + hash +} + +pub fn blake2b_digest(data: &[u8]) -> [u8; 32] { + let mut hasher = Blake2bBuilder::new(32).build(); + hasher.update(&data); + + let mut result_buffer: [u8; 32] = [0; 32]; + hasher.finalize(result_buffer.as_mut_slice()); + result_buffer +} + +pub fn blake244_digest(data: &[u8]) -> [u8; 28] { + let mut hasher = Blake2bBuilder::new(28).build(); + hasher.update(&data); + + let mut result_buffer: [u8; 28] = [0; 28]; + hasher.finalize(result_buffer.as_mut_slice()); + result_buffer +} + +pub fn blake2b_64_digest(data: &[u8]) -> [u8; 64] { + let mut hasher = Blake2bBuilder::new(64).build(); + hasher.update(&data); + + let mut result_buffer: [u8; 64] = [0; 64]; + hasher.finalize(result_buffer.as_mut_slice()); + result_buffer +} + +pub fn ripemd160_digest(data: &[u8]) -> [u8; 20] { + let input_md = sha256_digest(data); + let mut hasher = ripemd::Ripemd160::default(); + hasher.update(input_md); + let mut hash: [u8; 20] = [0; 20]; + let out = hasher.finalize_fixed(); + hash.copy_from_slice(&out[..]); + hash +} + +pub fn sha224_digest(data: &[u8]) -> [u8; 28] { + let mut hasher = sha2::Sha224::default(); + hasher.update(data); + let mut hash: [u8; 28] = [0; 28]; + let out = hasher.finalize_fixed(); + hash.copy_from_slice(&out[..]); + hash +} diff --git a/packages/kos/src/crypto/mnemonic.rs b/packages/kos/src/crypto/mnemonic.rs new file mode 100644 index 0000000..e11f42c --- /dev/null +++ b/packages/kos/src/crypto/mnemonic.rs @@ -0,0 +1,17 @@ +use crate::chains::ChainError; +use crate::crypto::bip32::Bip32Err; +use coins_bip39::{English, Mnemonic}; + +pub fn generate_mnemonic(count: usize) -> Result, ChainError> { + // create rng + let mut rng = rand::thread_rng(); + // generate mnemonic phrase + Ok(Mnemonic::::new_with_count(&mut rng, count) + .map_err(|_| Bip32Err::InvalidMnemonic)?) +} + +pub fn validate_mnemonic(phrase: &str) -> Result<(), ChainError> { + // validate mnemonic phrase + let _mnemonic: Mnemonic = phrase.parse().map_err(|_| Bip32Err::InvalidMnemonic)?; + Ok(()) +} diff --git a/packages/kos/src/crypto/mod.rs b/packages/kos/src/crypto/mod.rs new file mode 100644 index 0000000..eee419a --- /dev/null +++ b/packages/kos/src/crypto/mod.rs @@ -0,0 +1,41 @@ +pub mod b58; +pub mod base64; +pub mod bignum; +pub mod bip32; +pub mod ed25519; +mod ed25519_bip32; +pub mod hash; +pub mod mnemonic; +mod pbkdf2; +mod rng; +pub mod secp256k1; +pub mod sr25519; + +mod crypto {} + +#[cfg(test)] +mod tests { + use crate::crypto; + use alloc::string::String; + + #[test] + fn test_path() { + let path = String::from("m/44'/0'/0'/0/0"); + let path_components = crypto::bip32::handle_path(path).unwrap(); + assert_eq!(path_components.len(), 5); + } + + #[test] + fn test_derive() { + let seed = hex::decode( + "5eb00bbddc\ + f069084889a8ab9155568165f5c453ccb85e70811aaed6f6da5fc19\ + a5ac40b389cd370d086206dec8aa6c43daea6690f20ad3d8d48b2d2\ + ce9e38e4", + ) + .unwrap(); + let path = String::from("m/44'/195'/0'/0/0"); + let pvk = crypto::bip32::derive(&seed, path).unwrap(); + assert_eq!(pvk.len(), 32); + } +} diff --git a/packages/kos/src/crypto/pbkdf2.rs b/packages/kos/src/crypto/pbkdf2.rs new file mode 100644 index 0000000..e7ed815 --- /dev/null +++ b/packages/kos/src/crypto/pbkdf2.rs @@ -0,0 +1,45 @@ +#[cfg(not(target_arch = "x86_64"))] +extern "C" { + fn c_pbkdf2_hmac_sha512( + pass: *const u8, + pass_len: u32, + salt: *const u8, + salt_len: u32, + rounds: u32, + out: *mut u8, + out_len: u32, + ); +} + +pub trait Pbkdf2Trait { + fn pbkdf2_hmac_512(password: &[u8], salt: &[u8], rounds: u32) -> [u8; N]; +} + +pub struct Pbkdf2 {} + +#[cfg(target_arch = "x86_64")] +impl Pbkdf2Trait for Pbkdf2 { + fn pbkdf2_hmac_512(password: &[u8], salt: &[u8], rounds: u32) -> [u8; N] { + let icarus_key = pbkdf2::pbkdf2_hmac_array::(password, &salt, rounds); + icarus_key + } +} + +#[cfg(not(target_arch = "x86_64"))] +impl Pbkdf2Trait for Pbkdf2 { + fn pbkdf2_hmac_512(password: &[u8], salt: &[u8], rounds: u32) -> [u8; N] { + let mut out = [0u8; N]; + unsafe { + c_pbkdf2_hmac_sha512( + password.as_ptr(), + password.len() as u32, + salt.as_ptr(), + salt.len() as u32, + rounds, + out.as_mut_ptr(), + N as u32, + ); + } + out + } +} diff --git a/packages/kos/src/crypto/rng.rs b/packages/kos/src/crypto/rng.rs new file mode 100644 index 0000000..e7f871b --- /dev/null +++ b/packages/kos/src/crypto/rng.rs @@ -0,0 +1,50 @@ +use rand_core::{CryptoRng, Error, RngCore}; + +extern "C" { + #[allow(dead_code)] + fn random_buffer(p_buffer: *mut u8, size: u32); +} + +#[allow(dead_code)] +struct MyRng; + +impl RngCore for MyRng { + fn next_u32(&mut self) -> u32 { + let mut buf = [0u8; 4]; + unsafe { + random_buffer(buf.as_mut_ptr(), buf.len() as u32); + } + u32::from_ne_bytes(buf) + } + + fn next_u64(&mut self) -> u64 { + let mut buf = [0u8; 8]; + unsafe { + random_buffer(buf.as_mut_ptr(), buf.len() as u32); + } + u64::from_ne_bytes(buf) + } + + fn fill_bytes(&mut self, dest: &mut [u8]) { + unsafe { + random_buffer(dest.as_mut_ptr(), dest.len() as u32); + } + } + + fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { + self.fill_bytes(dest); + Ok(()) + } +} + +impl CryptoRng for MyRng {} + +#[cfg(target_arch = "x86_64")] +pub fn getrandom_or_panic() -> impl RngCore + CryptoRng { + rand_core::OsRng +} + +#[cfg(not(target_arch = "x86_64"))] +pub fn getrandom_or_panic() -> impl RngCore + CryptoRng { + MyRng +} diff --git a/packages/kos/src/crypto/secp256k1.rs b/packages/kos/src/crypto/secp256k1.rs new file mode 100644 index 0000000..4429fa3 --- /dev/null +++ b/packages/kos/src/crypto/secp256k1.rs @@ -0,0 +1,119 @@ +use core::fmt::{Display, Formatter}; + +#[derive(Debug)] +#[allow(dead_code)] +pub enum Secp256Err { + ErrDerive, +} + +impl Display for Secp256Err { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + match self { + Secp256Err::ErrDerive => write!(f, "Derive error"), + } + } +} + +#[cfg(target_arch = "x86_64")] +impl From for Secp256Err { + fn from(_: libsecp256k1::Error) -> Self { + Secp256Err::ErrDerive + } +} + +pub struct Secp256K1 {} + +#[cfg(not(target_arch = "x86_64"))] +extern "C" { + fn c_ecdsa_secp256k1_sign(msg: *const u8, msg_len: u32, pvk: *const u8, sig: *mut u8); + + fn c_ecdsa_scalar_add(a: *const u8, b: *const u8, c: *mut u8) -> u8; // Assuming that C's `bool` is equivalent to Rust's `u8` here + + fn c_ecdsa_get_pub_key65(pvk: *const u8, pbk: *mut u8); + + fn c_ecdsa_get_pub_key33(pvk: *const u8, pbk: *mut u8); +} + +pub trait Secp256k1Trait { + fn add_scalars(a: &[u8; 32], b: &[u8; 32]) -> Result<[u8; 32], Secp256Err>; + fn private_to_public_compressed(pvk: &[u8; 32]) -> Result<[u8; 33], Secp256Err>; + fn private_to_public_uncompressed(pvk: &[u8; 32]) -> Result<[u8; 65], Secp256Err>; + fn sign(msg: &[u8; 32], pvk: &[u8; 32]) -> Result<[u8; 65], Secp256Err>; +} + +#[cfg(not(target_arch = "x86_64"))] +impl Secp256k1Trait for Secp256K1 { + fn add_scalars(a: &[u8; 32], b: &[u8; 32]) -> Result<[u8; 32], Secp256Err> { + let mut c = [0; 32]; + unsafe { + c_ecdsa_scalar_add(a.as_ptr(), b.as_ptr(), c.as_mut_ptr()); + } + + Ok(c) + } + + fn private_to_public_compressed(pvk: &[u8; 32]) -> Result<[u8; 33], Secp256Err> { + let mut pbk = [0; 33]; + unsafe { + c_ecdsa_get_pub_key33(pvk.as_ptr(), pbk.as_mut_ptr()); + } + + Ok(pbk) + } + + fn private_to_public_uncompressed(pvk: &[u8; 32]) -> Result<[u8; 65], Secp256Err> { + let mut pbk = [0; 65]; + unsafe { + c_ecdsa_get_pub_key65(pvk.as_ptr(), pbk.as_mut_ptr()); + } + + Ok(pbk) + } + + fn sign(msg: &[u8; 32], pvk: &[u8; 32]) -> Result<[u8; 65], Secp256Err> { + let mut sig = [0; 65]; + unsafe { + c_ecdsa_secp256k1_sign( + msg.as_ptr(), + msg.len() as u32, + pvk.as_ptr(), + sig.as_mut_ptr(), + ); + } + + Ok(sig) + } +} + +#[cfg(target_arch = "x86_64")] +impl Secp256k1Trait for Secp256K1 { + fn add_scalars(a: &[u8; 32], b: &[u8; 32]) -> Result<[u8; 32], Secp256Err> { + let mut a = libsecp256k1::SecretKey::parse(a)?; + let b = libsecp256k1::SecretKey::parse(b)?; + a.tweak_add_assign(&b)?; + Ok(a.serialize()) + } + + fn private_to_public_compressed(pvk: &[u8; 32]) -> Result<[u8; 33], Secp256Err> { + let sk = libsecp256k1::SecretKey::parse(pvk)?; + let pbk = libsecp256k1::PublicKey::from_secret_key(&sk); + Ok(pbk.serialize_compressed()) + } + + fn private_to_public_uncompressed(pvk: &[u8; 32]) -> Result<[u8; 65], Secp256Err> { + let sk = libsecp256k1::SecretKey::parse(pvk)?; + let pbk = libsecp256k1::PublicKey::from_secret_key(&sk); + Ok(pbk.serialize()) + } + + fn sign(msg: &[u8; 32], pvk: &[u8; 32]) -> Result<[u8; 65], Secp256Err> { + let sk = libsecp256k1::SecretKey::parse(pvk)?; + let msg = libsecp256k1::Message::parse(msg); + let (sig, rec) = libsecp256k1::sign(&msg, &sk); + + let mut sig_vec: [u8; 65] = [0; 65]; + sig_vec[..64].copy_from_slice(&sig.serialize()[..]); + sig_vec[64] = rec.serialize(); + Ok(sig_vec) + } +} diff --git a/packages/kos/src/crypto/sr25519.rs b/packages/kos/src/crypto/sr25519.rs new file mode 100644 index 0000000..955f4a2 --- /dev/null +++ b/packages/kos/src/crypto/sr25519.rs @@ -0,0 +1,80 @@ +use alloc::vec::Vec; +use core::fmt::{Display, Formatter}; +use schnorrkel::context::SigningContext; +use schnorrkel::derive::ChainCode; + +const SUBSTRATE_CTX: &[u8; 9] = b"substrate"; + +#[derive(Debug)] +pub enum Sr25519Error { + ErrDerive, +} + +impl Display for Sr25519Error { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + match self { + Sr25519Error::ErrDerive => write!(f, "Derive error"), + } + } +} + +pub trait Sr25519Trait { + fn public_from_private(pvk: &[u8; 64]) -> Result, Sr25519Error>; + fn sign(msg: &[u8], pvk: &[u8; 64]) -> Result, Sr25519Error>; + + fn hard_derive_mini_sk(seed: &[u8; 32], chaincode: &[u8; 32]) + -> Result<[u8; 32], Sr25519Error>; + + fn expand_secret_key(mini_secret: &[u8; 32]) -> Result<([u8; 32], [u8; 32]), Sr25519Error>; +} + +pub struct Sr25519 {} + +impl Sr25519Trait for Sr25519 { + fn public_from_private(pvk: &[u8; 64]) -> Result, Sr25519Error> { + let pvk = schnorrkel::SecretKey::from_bytes(pvk).unwrap(); + + let pbk = pvk.to_public().to_bytes().to_vec(); + Ok(pbk) + } + + fn sign(msg: &[u8], pvk: &[u8; 64]) -> Result, Sr25519Error> { + let pvk = schnorrkel::SecretKey::from_bytes(pvk).map_err(|_| Sr25519Error::ErrDerive)?; + + let pbk = pvk.to_public(); + let ctx = SigningContext::new(SUBSTRATE_CTX).bytes(msg); + let ctx = schnorrkel::context::attach_rng(ctx, crate::crypto::rng::getrandom_or_panic()); + let sig = pvk.sign(ctx, &pbk); + Ok(sig.to_bytes().as_slice().to_vec()) + } + + fn hard_derive_mini_sk( + seed: &[u8; 32], + chaincode: &[u8; 32], + ) -> Result<[u8; 32], Sr25519Error> { + let seed = + schnorrkel::MiniSecretKey::from_bytes(seed).map_err(|_| Sr25519Error::ErrDerive)?; + + let chaincode = ChainCode(chaincode.clone()); + let (new_seed, _) = seed.hard_derive_mini_secret_key( + Some(chaincode), + [], + schnorrkel::ExpansionMode::Ed25519, + ); + Ok(new_seed.to_bytes()) + } + + fn expand_secret_key(mini_secret: &[u8; 32]) -> Result<([u8; 32], [u8; 32]), Sr25519Error> { + let mini_secret = schnorrkel::MiniSecretKey::from_bytes(mini_secret) + .map_err(|_| Sr25519Error::ErrDerive)?; + let secret = mini_secret.expand(schnorrkel::ExpansionMode::Ed25519); + let mut sk = [0; 32]; + let mut nonce = [0; 32]; + + let secret = secret.to_bytes(); + sk.copy_from_slice(&secret[0..32]); + nonce.copy_from_slice(&secret[32..64]); + + Ok((sk, nonce)) + } +} diff --git a/packages/kos/src/lib.rs b/packages/kos/src/lib.rs index 5cfb913..ec08339 100644 --- a/packages/kos/src/lib.rs +++ b/packages/kos/src/lib.rs @@ -1,77 +1,7 @@ -pub mod api; +#![no_std] +pub mod chains; +pub mod crypto; +pub mod models; +pub mod protos; -use kos_crypto::cipher; -pub use kos_crypto::cipher::*; -use kos_crypto::mnemonic::generate_mnemonic; -pub use kos_sdk::*; -use kos_types::error::Error; -use kos_utils::logger; - -use qrcode_generator::QrCodeEcc; - -use wasm_bindgen::prelude::*; - -// Called when the wasm module is instantiated -#[wasm_bindgen(start)] -pub fn main() -> Result<(), JsValue> { - console_error_panic_hook::set_once(); - - logger::init(logger::Config::default()); - - log::info!("KOS Module initialized"); - - Ok(()) -} - -/// Generates a random mnemonic phrase given the number of words to generate, `count`. -#[wasm_bindgen(js_name = "generateMnemonicPhrase")] -pub fn generate_mnemonic_phrase(count: usize) -> Result { - Ok(generate_mnemonic(count)?.to_phrase()) -} - -/// Converts the given string to bytes. -#[wasm_bindgen(js_name = "toBytes")] -pub fn to_bytes(data: &str) -> Result, Error> { - Ok(data.as_bytes().to_vec()) -} - -/// Converts the given bytes to a string. -#[wasm_bindgen(js_name = "toString")] -pub fn to_string(data: &[u8]) -> Result { - String::from_utf8(data.to_vec()) - .map_err(|e| Error::InvalidString(format!("Invalid UTF-8 string: {}", e))) -} - -/// Encrypts the given data with the given password. -#[wasm_bindgen(js_name = "encrypt")] -pub fn encrypt(algo: CipherAlgo, data: &[u8], password: &str) -> Result, Error> { - algo.encrypt(data, password) -} - -/// Decrypts the given data with the given password. -/// Data will have the algorithm tag prepended to it (1 byte). -#[wasm_bindgen(js_name = "decrypt")] -pub fn decrypt(data: &[u8], password: &str) -> Result, Error> { - cipher::decrypt(data, password) -} - -/// Create pem file from tag and data -#[wasm_bindgen(js_name = "toPem")] -pub fn to_pem(tag: String, data: &[u8]) -> Result { - let result = cipher::to_pem(tag, data)?; - Ok(result.to_string()) -} - -/// Decrypt pem file to bytes -#[wasm_bindgen(js_name = "fromPem")] -pub fn from_pem(data: &str, password: &str) -> Result, Error> { - let pem = cipher::string_to_pem(data)?; - decrypt(pem.contents(), password) -} - -/// Create QRCode based on data -#[wasm_bindgen(js_name = "generateQR")] -pub fn generate_qr(data: &str) -> Result, Error> { - qrcode_generator::to_png_to_vec(data, QrCodeEcc::Low, 1024) - .map_err(|e| Error::InvalidString(format!("Invalid QRCode data: {}", e))) -} +extern crate alloc; diff --git a/packages/kos/src/models.rs b/packages/kos/src/models.rs new file mode 100644 index 0000000..f154393 --- /dev/null +++ b/packages/kos/src/models.rs @@ -0,0 +1,218 @@ +use crate::chains::TxInfo; +use alloc::string::String; +use alloc::vec::Vec; + +#[repr(C)] +pub struct CNodeStruct { + seed: *mut u8, + seed_len: u32, + pvk: *mut u8, + pvk_len: u32, + pbk: *mut u8, + pbk_len: u32, + path: *mut u8, + path_len: u32, +} + +fn read_to_vec(src: *const u8, src_len: u32) -> Vec { + let mut result = Vec::with_capacity(src_len as usize); + if src.is_null() { + return result; + } + unsafe { + for i in 0..src_len as usize { + result.push(*src.add(i)); + } + } + result +} + +fn write_to_memory(dst: *mut u8, dst_len: u32, src: *const u8, src_len: u32) { + if dst.is_null() || src.is_null() || dst_len < src_len { + return; + } + unsafe { + for i in 0..src_len as usize { + *dst.add(i) = *src.add(i); + } + } +} + +impl CNodeStruct { + pub fn write_seed(&mut self, data: *const u8, data_len: u32) { + write_to_memory(self.seed, self.seed_len, data, data_len); + self.seed_len = data_len; + } + + pub fn write_pvk(&mut self, data: *const u8, data_len: u32) { + write_to_memory(self.pvk, self.pvk_len, data, data_len); + self.pvk_len = data_len; + } + + pub fn write_pbk(&mut self, data: *const u8, data_len: u32) { + write_to_memory(self.pbk, self.pbk_len, data, data_len); + self.pbk_len = data_len; + } + + pub fn write_path(&mut self, data: *const u8, data_len: u32) { + write_to_memory(self.path, self.path_len, data, data_len); + self.path_len = data_len; + } + + pub fn read_seed(&self) -> Vec { + read_to_vec(self.seed, self.seed_len) + } + + pub fn read_pvk(&self) -> Vec { + read_to_vec(self.pvk, self.pvk_len) + } + + pub fn read_pbk(&self) -> Vec { + read_to_vec(self.pbk, self.pbk_len) + } + + pub fn read_path(&self) -> Vec { + read_to_vec(self.path, self.path_len) + } +} + +#[repr(C)] +pub struct CBuffer { + data: *mut u8, + len: u32, +} + +impl CBuffer { + pub fn write(&mut self, data: *const u8, data_len: u32) { + write_to_memory(self.data, self.len, data, data_len); + self.len = data_len; + } + + pub fn read(&self) -> Vec { + read_to_vec(self.data, self.len) + } +} + +#[repr(C)] +pub struct CTransaction { + raw_data: *mut u8, + raw_data_len: u32, + tx_hash: *mut u8, + tx_hash_len: u32, + signature: *mut u8, + signature_len: u32, +} + +impl CTransaction { + // Implement CTransaction similar to the other structs + pub fn write_raw_data(&mut self, data: *const u8, data_len: u32) { + write_to_memory(self.raw_data, self.raw_data_len, data, data_len); + self.raw_data_len = data_len; + } + + pub fn write_tx_hash(&mut self, data: *const u8, data_len: u32) { + write_to_memory(self.tx_hash, self.tx_hash_len, data, data_len); + self.tx_hash_len = data_len; + } + + pub fn write_signature(&mut self, data: *const u8, data_len: u32) { + write_to_memory(self.signature, self.signature_len, data, data_len); + self.signature_len = data_len; + } + + pub fn read_raw_data(&self) -> Vec { + read_to_vec(self.raw_data, self.raw_data_len) + } + + pub fn read_tx_hash(&self) -> Vec { + read_to_vec(self.tx_hash, self.tx_hash_len) + } + + pub fn read_signature(&self) -> Vec { + read_to_vec(self.signature, self.signature_len) + } +} + +#[repr(C)] +pub struct CTxInfo { + pub sender: *mut u8, + pub sender_len: u32, + pub receiver: *mut u8, + pub receiver_len: u32, + pub value: f64, + pub tx_type: u32, +} + +impl CTxInfo { + pub fn write_sender(&mut self, data: *const u8, data_len: u32) { + write_to_memory(self.sender, self.sender_len, data, data_len); + self.sender_len = data_len; + } + + pub fn write_receiver(&mut self, data: *const u8, data_len: u32) { + write_to_memory(self.receiver, self.receiver_len, data, data_len); + self.receiver_len = data_len; + } + + pub fn read_sender(&self) -> Vec { + read_to_vec(self.sender, self.sender_len) + } + + pub fn read_receiver(&self) -> Vec { + read_to_vec(self.receiver, self.receiver_len) + } + + pub fn write(&mut self, tx_info: TxInfo) { + self.write_sender(tx_info.sender.as_ptr(), tx_info.sender.len() as u32); + self.write_receiver(tx_info.receiver.as_ptr(), tx_info.receiver.len() as u32); + self.value = tx_info.value; + self.tx_type = match tx_info.tx_type { + crate::chains::TxType::Unknown => 1, + crate::chains::TxType::Transfer => 2, + crate::chains::TxType::TriggerContract => 3, + }; + } + + pub fn to_tx_info(&self) -> TxInfo { + TxInfo { + sender: String::from_utf8(self.read_sender()).unwrap_or_else(|_| String::new()), + receiver: String::from_utf8(self.read_receiver()).unwrap_or_else(|_| String::new()), + value: self.value, + tx_type: match self.tx_type { + 1 => crate::chains::TxType::Unknown, + 2 => crate::chains::TxType::Transfer, + 3 => crate::chains::TxType::TriggerContract, + _ => crate::chains::TxType::Unknown, + }, + } + } +} + +#[repr(C)] +pub struct RequestChainParams { + pub chain: u32, + pub is_custom: bool, + pub chaincode: u32, + pub chaincode_str: [u8; 64], +} + +impl RequestChainParams { + pub fn to_chain_type(&self) -> crate::chains::CustomChainType { + if !self.is_custom { + return crate::chains::CustomChainType::NotCustom(self.chain); + } + + match self.chain { + crate::chains::constants::ETH => { + crate::chains::CustomChainType::CustomEth(self.chaincode) + } + crate::chains::constants::SUBSTRATE => { + crate::chains::CustomChainType::CustomSubstrate(self.chaincode) + } + crate::chains::constants::COSMOS => crate::chains::CustomChainType::CustomCosmos( + String::from_utf8(self.chaincode_str.to_vec()).unwrap_or_else(|_| String::new()), + ), + _ => crate::chains::CustomChainType::NotCustom(self.chain), + } + } +} diff --git a/packages/kos/src/protos/generated/klv/google.protobuf.rs b/packages/kos/src/protos/generated/klv/google.protobuf.rs new file mode 100644 index 0000000..e69de29 diff --git a/packages/kos/src/protos/generated/klv/mod.rs b/packages/kos/src/protos/generated/klv/mod.rs new file mode 100644 index 0000000..febacec --- /dev/null +++ b/packages/kos/src/protos/generated/klv/mod.rs @@ -0,0 +1 @@ +pub mod proto; diff --git a/packages/kos/src/protos/generated/klv/proto.rs b/packages/kos/src/protos/generated/klv/proto.rs new file mode 100644 index 0000000..d480efe --- /dev/null +++ b/packages/kos/src/protos/generated/klv/proto.rs @@ -0,0 +1,1645 @@ +// This file is @generated by prost-build. +/// TXContract available +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct TransferContract { + #[prost(bytes = "vec", tag = "1")] + pub to_address: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "2")] + pub asset_id: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "3")] + pub amount: i64, + #[prost(int64, tag = "4")] + pub kda_royalties: i64, +} +/// CreateAssetContract holds the data for a Klever digital asset +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct CreateAssetContract { + #[prost(enumeration = "create_asset_contract::EnumAssetType", tag = "1")] + pub r#type: i32, + #[prost(bytes = "vec", tag = "2")] + pub name: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "3")] + pub ticker: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "4")] + pub owner_address: ::prost::alloc::vec::Vec, + #[prost(string, tag = "5")] + pub logo: ::prost::alloc::string::String, + #[prost(btree_map = "string, string", tag = "6")] + pub ur_is: ::prost::alloc::collections::BTreeMap< + ::prost::alloc::string::String, + ::prost::alloc::string::String, + >, + #[prost(uint32, tag = "7")] + pub precision: u32, + #[prost(int64, tag = "8")] + pub initial_supply: i64, + #[prost(int64, tag = "9")] + pub max_supply: i64, + #[prost(message, optional, tag = "10")] + pub royalties: ::core::option::Option, + #[prost(message, optional, tag = "11")] + pub properties: ::core::option::Option, + #[prost(message, optional, tag = "12")] + pub attributes: ::core::option::Option, + #[prost(message, optional, tag = "13")] + pub staking: ::core::option::Option, + #[prost(message, repeated, tag = "14")] + pub roles: ::prost::alloc::vec::Vec, +} +/// Nested message and enum types in `CreateAssetContract`. +pub mod create_asset_contract { + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] + #[repr(i32)] + pub enum EnumAssetType { + Fungible = 0, + NonFungible = 1, + } + impl EnumAssetType { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + EnumAssetType::Fungible => "Fungible", + EnumAssetType::NonFungible => "NonFungible", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "Fungible" => Some(Self::Fungible), + "NonFungible" => Some(Self::NonFungible), + _ => None, + } + } + } +} +/// PropertiesInfo hold the properties structure for the KDA asset +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct PropertiesInfo { + #[prost(bool, tag = "1")] + pub can_freeze: bool, + #[prost(bool, tag = "2")] + pub can_wipe: bool, + #[prost(bool, tag = "3")] + pub can_pause: bool, + #[prost(bool, tag = "4")] + pub can_mint: bool, + #[prost(bool, tag = "5")] + pub can_burn: bool, + #[prost(bool, tag = "6")] + pub can_change_owner: bool, + #[prost(bool, tag = "7")] + pub can_add_roles: bool, +} +/// AttributesInfo hold the attributes structure for the KDA asset +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct AttributesInfo { + #[prost(bool, tag = "1")] + pub is_paused: bool, + #[prost(bool, tag = "2")] + pub is_nft_mint_stopped: bool, + #[prost(bool, tag = "3")] + pub is_royalties_change_stopped: bool, + #[prost(bool, tag = "4")] + pub is_nft_metadata_change_stopped: bool, +} +/// StakingInfo hold the staking structure for the KDA asset +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct StakingInfo { + #[prost(enumeration = "staking_info::InterestType", tag = "1")] + pub r#type: i32, + #[prost(uint32, tag = "2")] + pub apr: u32, + #[prost(uint32, tag = "3")] + pub min_epochs_to_claim: u32, + #[prost(uint32, tag = "4")] + pub min_epochs_to_unstake: u32, + #[prost(uint32, tag = "5")] + pub min_epochs_to_withdraw: u32, +} +/// Nested message and enum types in `StakingInfo`. +pub mod staking_info { + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] + #[repr(i32)] + pub enum InterestType { + Apri = 0, + Fpri = 1, + } + impl InterestType { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + InterestType::Apri => "APRI", + InterestType::Fpri => "FPRI", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "APRI" => Some(Self::Apri), + "FPRI" => Some(Self::Fpri), + _ => None, + } + } + } +} +/// RolesInfo holds the roles for a given asset and the given address +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct RolesInfo { + #[prost(bytes = "vec", tag = "1")] + pub address: ::prost::alloc::vec::Vec, + #[prost(bool, tag = "2")] + pub has_role_mint: bool, + #[prost(bool, tag = "3")] + pub has_role_set_ito_prices: bool, + #[prost(bool, tag = "4")] + pub has_role_deposit: bool, +} +/// RoyaltiesInfo holds the royalties for a given asset +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct RoyaltiesInfo { + #[prost(bytes = "vec", tag = "1")] + pub address: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "2")] + pub transfer_percentage: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "3")] + pub transfer_fixed: i64, + #[prost(uint32, tag = "4")] + pub market_percentage: u32, + #[prost(int64, tag = "5")] + pub market_fixed: i64, + #[prost(btree_map = "string, message", tag = "6")] + pub split_royalties: ::prost::alloc::collections::BTreeMap< + ::prost::alloc::string::String, + RoyaltySplitInfo, + >, + #[prost(int64, tag = "7")] + pub ito_fixed: i64, + #[prost(uint32, tag = "8")] + pub ito_percentage: u32, +} +/// RoyaltySplitInfo holds the royalty split +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct RoyaltySplitInfo { + #[prost(uint32, tag = "1")] + pub percent_transfer_percentage: u32, + #[prost(uint32, tag = "2")] + pub percent_transfer_fixed: u32, + #[prost(uint32, tag = "3")] + pub percent_market_percentage: u32, + #[prost(uint32, tag = "4")] + pub percent_market_fixed: u32, + #[prost(uint32, tag = "5")] + pub percent_ito_percentage: u32, + #[prost(uint32, tag = "6")] + pub percent_ito_fixed: u32, +} +/// RoyaltyInfo holds the royalty threshold +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct RoyaltyInfo { + #[prost(int64, tag = "1")] + pub amount: i64, + #[prost(uint32, tag = "2")] + pub percentage: u32, +} +/// KDAPoolInfo holds the KDA Fee pool info +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct KdaPoolInfo { + #[prost(bool, tag = "1")] + pub active: bool, + #[prost(bytes = "vec", tag = "2")] + pub admin_address: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "3")] + pub f_ratio_kda: i64, + #[prost(int64, tag = "4")] + pub f_ratio_klv: i64, +} +/// AssetTriggerContract triggers assets functions +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct AssetTriggerContract { + #[prost(enumeration = "asset_trigger_contract::EnumTriggerType", tag = "1")] + pub trigger_type: i32, + #[prost(bytes = "vec", tag = "2")] + pub asset_id: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "3")] + pub to_address: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "4")] + pub amount: i64, + #[prost(bytes = "vec", tag = "5")] + pub mime: ::prost::alloc::vec::Vec, + #[prost(string, tag = "6")] + pub logo: ::prost::alloc::string::String, + #[prost(btree_map = "string, string", tag = "7")] + pub ur_is: ::prost::alloc::collections::BTreeMap< + ::prost::alloc::string::String, + ::prost::alloc::string::String, + >, + #[prost(message, optional, tag = "8")] + pub role: ::core::option::Option, + #[prost(message, optional, tag = "9")] + pub staking: ::core::option::Option, + #[prost(message, optional, tag = "10")] + pub royalties: ::core::option::Option, + #[prost(message, optional, tag = "11")] + pub kda_pool: ::core::option::Option, +} +/// Nested message and enum types in `AssetTriggerContract`. +pub mod asset_trigger_contract { + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] + #[repr(i32)] + pub enum EnumTriggerType { + Mint = 0, + Burn = 1, + Wipe = 2, + Pause = 3, + Resume = 4, + ChangeOwner = 5, + AddRole = 6, + RemoveRole = 7, + UpdateMetadata = 8, + StopNftMint = 9, + UpdateLogo = 10, + UpdateUrIs = 11, + ChangeRoyaltiesReceiver = 12, + UpdateStaking = 13, + UpdateRoyalties = 14, + UpdateKdaFeePool = 15, + StopRoyaltiesChange = 16, + StopNftMetadataChange = 17, + } + impl EnumTriggerType { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + EnumTriggerType::Mint => "Mint", + EnumTriggerType::Burn => "Burn", + EnumTriggerType::Wipe => "Wipe", + EnumTriggerType::Pause => "Pause", + EnumTriggerType::Resume => "Resume", + EnumTriggerType::ChangeOwner => "ChangeOwner", + EnumTriggerType::AddRole => "AddRole", + EnumTriggerType::RemoveRole => "RemoveRole", + EnumTriggerType::UpdateMetadata => "UpdateMetadata", + EnumTriggerType::StopNftMint => "StopNFTMint", + EnumTriggerType::UpdateLogo => "UpdateLogo", + EnumTriggerType::UpdateUrIs => "UpdateURIs", + EnumTriggerType::ChangeRoyaltiesReceiver => "ChangeRoyaltiesReceiver", + EnumTriggerType::UpdateStaking => "UpdateStaking", + EnumTriggerType::UpdateRoyalties => "UpdateRoyalties", + EnumTriggerType::UpdateKdaFeePool => "UpdateKDAFeePool", + EnumTriggerType::StopRoyaltiesChange => "StopRoyaltiesChange", + EnumTriggerType::StopNftMetadataChange => "StopNFTMetadataChange", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "Mint" => Some(Self::Mint), + "Burn" => Some(Self::Burn), + "Wipe" => Some(Self::Wipe), + "Pause" => Some(Self::Pause), + "Resume" => Some(Self::Resume), + "ChangeOwner" => Some(Self::ChangeOwner), + "AddRole" => Some(Self::AddRole), + "RemoveRole" => Some(Self::RemoveRole), + "UpdateMetadata" => Some(Self::UpdateMetadata), + "StopNFTMint" => Some(Self::StopNftMint), + "UpdateLogo" => Some(Self::UpdateLogo), + "UpdateURIs" => Some(Self::UpdateUrIs), + "ChangeRoyaltiesReceiver" => Some(Self::ChangeRoyaltiesReceiver), + "UpdateStaking" => Some(Self::UpdateStaking), + "UpdateRoyalties" => Some(Self::UpdateRoyalties), + "UpdateKDAFeePool" => Some(Self::UpdateKdaFeePool), + "StopRoyaltiesChange" => Some(Self::StopRoyaltiesChange), + "StopNFTMetadataChange" => Some(Self::StopNftMetadataChange), + _ => None, + } + } + } +} +/// ValidatorConfig holds the data for a validator configuration +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ValidatorConfig { + #[prost(bytes = "vec", tag = "1")] + pub bls_public_key: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "2")] + pub reward_address: ::prost::alloc::vec::Vec, + #[prost(bool, tag = "3")] + pub can_delegate: bool, + #[prost(uint32, tag = "4")] + pub commission: u32, + #[prost(int64, tag = "5")] + pub max_delegation_amount: i64, + #[prost(string, tag = "6")] + pub logo: ::prost::alloc::string::String, + #[prost(btree_map = "string, string", tag = "7")] + pub ur_is: ::prost::alloc::collections::BTreeMap< + ::prost::alloc::string::String, + ::prost::alloc::string::String, + >, + #[prost(string, tag = "8")] + pub name: ::prost::alloc::string::String, +} +/// CreateValidatorContract holds the data for create a validator +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct CreateValidatorContract { + #[prost(bytes = "vec", tag = "1")] + pub owner_address: ::prost::alloc::vec::Vec, + #[prost(message, optional, tag = "2")] + pub config: ::core::option::Option, +} +/// ValidatorConfigContract holds the data for a validator configuration transaction +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ValidatorConfigContract { + #[prost(message, optional, tag = "1")] + pub config: ::core::option::Option, +} +/// FreezeContract holds the data for a freeze transaction +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct FreezeContract { + #[prost(bytes = "vec", tag = "1")] + pub asset_id: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "2")] + pub amount: i64, +} +/// UnfreezeContract holds the data for a unfreeze transaction +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct UnfreezeContract { + #[prost(bytes = "vec", tag = "1")] + pub asset_id: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "2")] + pub bucket_id: ::prost::alloc::vec::Vec, +} +/// DelegateContract holds the data for a delegate transaction +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct DelegateContract { + #[prost(bytes = "vec", tag = "1")] + pub to_address: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "2")] + pub bucket_id: ::prost::alloc::vec::Vec, +} +/// UndelegateContract holds the data for a undelegate transaction +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct UndelegateContract { + #[prost(bytes = "vec", tag = "1")] + pub bucket_id: ::prost::alloc::vec::Vec, +} +/// WithdrawContract holds the data for a withdraw transaction +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct WithdrawContract { + #[prost(bytes = "vec", tag = "1")] + pub asset_id: ::prost::alloc::vec::Vec, + #[prost(enumeration = "withdraw_contract::EnumWithdrawType", tag = "2")] + pub withdraw_type: i32, + #[prost(int64, tag = "3")] + pub amount: i64, + #[prost(bytes = "vec", tag = "4")] + pub currency_id: ::prost::alloc::vec::Vec, +} +/// Nested message and enum types in `WithdrawContract`. +pub mod withdraw_contract { + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] + #[repr(i32)] + pub enum EnumWithdrawType { + Staking = 0, + KdaPool = 1, + } + impl EnumWithdrawType { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + EnumWithdrawType::Staking => "Staking", + EnumWithdrawType::KdaPool => "KDAPool", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "Staking" => Some(Self::Staking), + "KDAPool" => Some(Self::KdaPool), + _ => None, + } + } + } +} +/// ClaimContract holds the data for a claim transaction +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ClaimContract { + #[prost(enumeration = "claim_contract::EnumClaimType", tag = "1")] + pub claim_type: i32, + #[prost(bytes = "vec", tag = "2")] + pub id: ::prost::alloc::vec::Vec, +} +/// Nested message and enum types in `ClaimContract`. +pub mod claim_contract { + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] + #[repr(i32)] + pub enum EnumClaimType { + StakingClaim = 0, + AllowanceClaim = 1, + MarketClaim = 2, + } + impl EnumClaimType { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + EnumClaimType::StakingClaim => "StakingClaim", + EnumClaimType::AllowanceClaim => "AllowanceClaim", + EnumClaimType::MarketClaim => "MarketClaim", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "StakingClaim" => Some(Self::StakingClaim), + "AllowanceClaim" => Some(Self::AllowanceClaim), + "MarketClaim" => Some(Self::MarketClaim), + _ => None, + } + } + } +} +/// UnjailContract holds the data for a unjail transaction +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct UnjailContract {} +/// SetAccountNameContract holds the data for a setAccountName transaction +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SetAccountNameContract { + #[prost(bytes = "vec", tag = "1")] + pub name: ::prost::alloc::vec::Vec, +} +/// ProposalContract holds the data for a proposal transaction +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ProposalContract { + #[prost(btree_map = "int32, bytes", tag = "1")] + pub parameters: ::prost::alloc::collections::BTreeMap< + i32, + ::prost::alloc::vec::Vec, + >, + #[prost(bytes = "vec", tag = "2")] + pub description: ::prost::alloc::vec::Vec, + #[prost(uint32, tag = "3")] + pub epochs_duration: u32, +} +/// VoteContract holds the data for a vote transaction +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct VoteContract { + #[prost(uint64, tag = "1")] + pub proposal_id: u64, + #[prost(int64, tag = "2")] + pub amount: i64, + #[prost(enumeration = "vote_contract::EnumVoteType", tag = "3")] + pub r#type: i32, +} +/// Nested message and enum types in `VoteContract`. +pub mod vote_contract { + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] + #[repr(i32)] + pub enum EnumVoteType { + Yes = 0, + No = 1, + } + impl EnumVoteType { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + EnumVoteType::Yes => "Yes", + EnumVoteType::No => "No", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "Yes" => Some(Self::Yes), + "No" => Some(Self::No), + _ => None, + } + } + } +} +/// ConfigITOContract holds the data for a ConfigITO transaction +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ConfigItoContract { + #[prost(bytes = "vec", tag = "1")] + pub asset_id: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "2")] + pub receiver_address: ::prost::alloc::vec::Vec, + #[prost(enumeration = "config_ito_contract::EnumItoStatus", tag = "3")] + pub status: i32, + #[prost(int64, tag = "4")] + pub max_amount: i64, + #[prost(btree_map = "string, message", tag = "5")] + pub pack_info: ::prost::alloc::collections::BTreeMap< + ::prost::alloc::string::String, + PackInfo, + >, + #[prost(int64, tag = "6")] + pub default_limit_per_address: i64, + #[prost(enumeration = "config_ito_contract::EnumItoStatus", tag = "7")] + pub whitelist_status: i32, + #[prost(btree_map = "string, message", tag = "8")] + pub whitelist_info: ::prost::alloc::collections::BTreeMap< + ::prost::alloc::string::String, + WhitelistInfo, + >, + #[prost(int64, tag = "9")] + pub whitelist_start_time: i64, + #[prost(int64, tag = "10")] + pub whitelist_end_time: i64, + #[prost(int64, tag = "11")] + pub start_time: i64, + #[prost(int64, tag = "12")] + pub end_time: i64, +} +/// Nested message and enum types in `ConfigITOContract`. +pub mod config_ito_contract { + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] + #[repr(i32)] + pub enum EnumItoStatus { + DefaultIto = 0, + ActiveIto = 1, + PausedIto = 2, + } + impl EnumItoStatus { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + EnumItoStatus::DefaultIto => "DefaultITO", + EnumItoStatus::ActiveIto => "ActiveITO", + EnumItoStatus::PausedIto => "PausedITO", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "DefaultITO" => Some(Self::DefaultIto), + "ActiveITO" => Some(Self::ActiveIto), + "PausedITO" => Some(Self::PausedIto), + _ => None, + } + } + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct WhitelistInfo { + #[prost(int64, tag = "1")] + pub limit: i64, +} +/// SetITOPrices holds the data for a ConfigITO transaction +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SetItoPricesContract { + #[prost(bytes = "vec", tag = "1")] + pub asset_id: ::prost::alloc::vec::Vec, + #[prost(btree_map = "string, message", tag = "2")] + pub pack_info: ::prost::alloc::collections::BTreeMap< + ::prost::alloc::string::String, + PackInfo, + >, +} +/// ITOTriggerContract triggers assets functions +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ItoTriggerContract { + #[prost(enumeration = "ito_trigger_contract::EnumItoTriggerType", tag = "1")] + pub trigger_type: i32, + #[prost(bytes = "vec", tag = "2")] + pub asset_id: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "3")] + pub receiver_address: ::prost::alloc::vec::Vec, + #[prost(enumeration = "ito_trigger_contract::EnumItoStatus", tag = "4")] + pub status: i32, + #[prost(int64, tag = "5")] + pub max_amount: i64, + #[prost(btree_map = "string, message", tag = "6")] + pub pack_info: ::prost::alloc::collections::BTreeMap< + ::prost::alloc::string::String, + PackInfo, + >, + #[prost(int64, tag = "7")] + pub default_limit_per_address: i64, + #[prost(enumeration = "ito_trigger_contract::EnumItoStatus", tag = "8")] + pub whitelist_status: i32, + #[prost(btree_map = "string, message", tag = "9")] + pub whitelist_info: ::prost::alloc::collections::BTreeMap< + ::prost::alloc::string::String, + WhitelistInfo, + >, + #[prost(int64, tag = "10")] + pub whitelist_start_time: i64, + #[prost(int64, tag = "11")] + pub whitelist_end_time: i64, + #[prost(int64, tag = "12")] + pub start_time: i64, + #[prost(int64, tag = "13")] + pub end_time: i64, +} +/// Nested message and enum types in `ITOTriggerContract`. +pub mod ito_trigger_contract { + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] + #[repr(i32)] + pub enum EnumItoTriggerType { + SetItoPrices = 0, + UpdateStatus = 1, + UpdateReceiverAddress = 2, + UpdateMaxAmount = 3, + UpdateDefaultLimitPerAddress = 4, + UpdateTimes = 5, + UpdateWhitelistStatus = 6, + AddToWhitelist = 7, + RemoveFromWhitelist = 8, + UpdateWhitelistTimes = 9, + } + impl EnumItoTriggerType { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + EnumItoTriggerType::SetItoPrices => "SetITOPrices", + EnumItoTriggerType::UpdateStatus => "UpdateStatus", + EnumItoTriggerType::UpdateReceiverAddress => "UpdateReceiverAddress", + EnumItoTriggerType::UpdateMaxAmount => "UpdateMaxAmount", + EnumItoTriggerType::UpdateDefaultLimitPerAddress => { + "UpdateDefaultLimitPerAddress" + } + EnumItoTriggerType::UpdateTimes => "UpdateTimes", + EnumItoTriggerType::UpdateWhitelistStatus => "UpdateWhitelistStatus", + EnumItoTriggerType::AddToWhitelist => "AddToWhitelist", + EnumItoTriggerType::RemoveFromWhitelist => "RemoveFromWhitelist", + EnumItoTriggerType::UpdateWhitelistTimes => "UpdateWhitelistTimes", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "SetITOPrices" => Some(Self::SetItoPrices), + "UpdateStatus" => Some(Self::UpdateStatus), + "UpdateReceiverAddress" => Some(Self::UpdateReceiverAddress), + "UpdateMaxAmount" => Some(Self::UpdateMaxAmount), + "UpdateDefaultLimitPerAddress" => { + Some(Self::UpdateDefaultLimitPerAddress) + } + "UpdateTimes" => Some(Self::UpdateTimes), + "UpdateWhitelistStatus" => Some(Self::UpdateWhitelistStatus), + "AddToWhitelist" => Some(Self::AddToWhitelist), + "RemoveFromWhitelist" => Some(Self::RemoveFromWhitelist), + "UpdateWhitelistTimes" => Some(Self::UpdateWhitelistTimes), + _ => None, + } + } + } + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] + #[repr(i32)] + pub enum EnumItoStatus { + DefaultIto = 0, + ActiveIto = 1, + PausedIto = 2, + } + impl EnumItoStatus { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + EnumItoStatus::DefaultIto => "DefaultITO", + EnumItoStatus::ActiveIto => "ActiveITO", + EnumItoStatus::PausedIto => "PausedITO", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "DefaultITO" => Some(Self::DefaultIto), + "ActiveITO" => Some(Self::ActiveIto), + "PausedITO" => Some(Self::PausedIto), + _ => None, + } + } + } +} +/// PackInfo holds the pack list structure for the ITO contract +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct PackInfo { + #[prost(message, repeated, tag = "1")] + pub packs: ::prost::alloc::vec::Vec, +} +/// PackItem hold the pack structure for the ITO contract +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct PackItem { + #[prost(int64, tag = "1")] + pub amount: i64, + #[prost(int64, tag = "2")] + pub price: i64, +} +/// BuyContract holds the data for a buy transaction +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BuyContract { + #[prost(enumeration = "buy_contract::EnumBuyType", tag = "1")] + pub buy_type: i32, + #[prost(bytes = "vec", tag = "2")] + pub id: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "3")] + pub currency_id: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "4")] + pub amount: i64, +} +/// Nested message and enum types in `BuyContract`. +pub mod buy_contract { + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] + #[repr(i32)] + pub enum EnumBuyType { + ItoBuy = 0, + MarketBuy = 1, + } + impl EnumBuyType { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + EnumBuyType::ItoBuy => "ITOBuy", + EnumBuyType::MarketBuy => "MarketBuy", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "ITOBuy" => Some(Self::ItoBuy), + "MarketBuy" => Some(Self::MarketBuy), + _ => None, + } + } + } +} +/// SellContract holds the data for a sell transaction +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SellContract { + #[prost(enumeration = "sell_contract::EnumMarketType", tag = "1")] + pub market_type: i32, + #[prost(bytes = "vec", tag = "2")] + pub marketplace_id: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "3")] + pub asset_id: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "4")] + pub currency_id: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "5")] + pub price: i64, + #[prost(int64, tag = "6")] + pub reserve_price: i64, + #[prost(int64, tag = "7")] + pub end_time: i64, +} +/// Nested message and enum types in `SellContract`. +pub mod sell_contract { + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] + #[repr(i32)] + pub enum EnumMarketType { + BuyItNowMarket = 0, + AuctionMarket = 1, + } + impl EnumMarketType { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + EnumMarketType::BuyItNowMarket => "BuyItNowMarket", + EnumMarketType::AuctionMarket => "AuctionMarket", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "BuyItNowMarket" => Some(Self::BuyItNowMarket), + "AuctionMarket" => Some(Self::AuctionMarket), + _ => None, + } + } + } +} +/// CancelMarketOrderContract holds the data for a cancel market transaction +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct CancelMarketOrderContract { + #[prost(bytes = "vec", tag = "1")] + pub order_id: ::prost::alloc::vec::Vec, +} +/// CreateMarketplaceContract holds the data for a create marketplace transaction +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct CreateMarketplaceContract { + #[prost(bytes = "vec", tag = "1")] + pub name: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "2")] + pub referral_address: ::prost::alloc::vec::Vec, + #[prost(uint32, tag = "3")] + pub referral_percentage: u32, +} +/// ConfigMarketplaceContract holds the data for a config marketplace transaction +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ConfigMarketplaceContract { + #[prost(bytes = "vec", tag = "1")] + pub marketplace_id: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "2")] + pub name: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "3")] + pub referral_address: ::prost::alloc::vec::Vec, + #[prost(uint32, tag = "4")] + pub referral_percentage: u32, +} +/// TODO: Reuse from account +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct AccKey { + #[prost(bytes = "vec", tag = "1")] + pub address: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "2")] + pub weight: i64, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct AccPermission { + #[prost(enumeration = "acc_permission::AccPermissionType", tag = "2")] + pub r#type: i32, + #[prost(string, tag = "3")] + pub permission_name: ::prost::alloc::string::String, + #[prost(int64, tag = "4")] + pub threshold: i64, + /// 1 bit 1 contract + #[prost(bytes = "vec", tag = "5")] + pub operations: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "6")] + pub signers: ::prost::alloc::vec::Vec, +} +/// Nested message and enum types in `AccPermission`. +pub mod acc_permission { + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] + #[repr(i32)] + pub enum AccPermissionType { + Owner = 0, + User = 1, + } + impl AccPermissionType { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + AccPermissionType::Owner => "Owner", + AccPermissionType::User => "User", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "Owner" => Some(Self::Owner), + "User" => Some(Self::User), + _ => None, + } + } + } +} +/// UpdateAccountPermissionContract holds the data for update account permission transaction +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct UpdateAccountPermissionContract { + #[prost(message, repeated, tag = "8")] + pub permissions: ::prost::alloc::vec::Vec, +} +/// DepositContract holds the data for a deposit transaction +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct DepositContract { + #[prost(enumeration = "deposit_contract::EnumDepositType", tag = "1")] + pub deposit_type: i32, + #[prost(bytes = "vec", tag = "2")] + pub id: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "3")] + pub currency_id: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "4")] + pub amount: i64, +} +/// Nested message and enum types in `DepositContract`. +pub mod deposit_contract { + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] + #[repr(i32)] + pub enum EnumDepositType { + FprDeposit = 0, + KdaPool = 1, + } + impl EnumDepositType { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + EnumDepositType::FprDeposit => "FPRDeposit", + EnumDepositType::KdaPool => "KDAPool", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "FPRDeposit" => Some(Self::FprDeposit), + "KDAPool" => Some(Self::KdaPool), + _ => None, + } + } + } +} +/// TXContract available +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct TxContract { + #[prost(enumeration = "tx_contract::ContractType", tag = "1")] + pub r#type: i32, + #[prost(message, optional, tag = "2")] + pub parameter: ::core::option::Option, +} +/// Nested message and enum types in `TXContract`. +pub mod tx_contract { + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] + #[repr(i32)] + pub enum ContractType { + TransferContractType = 0, + CreateAssetContractType = 1, + CreateValidatorContractType = 2, + ValidatorConfigContractType = 3, + FreezeContractType = 4, + UnfreezeContractType = 5, + DelegateContractType = 6, + UndelegateContractType = 7, + WithdrawContractType = 8, + ClaimContractType = 9, + UnjailContractType = 10, + AssetTriggerContractType = 11, + SetAccountNameContractType = 12, + ProposalContractType = 13, + VoteContractType = 14, + ConfigItoContractType = 15, + SetItoPricesContractType = 16, + BuyContractType = 17, + SellContractType = 18, + CancelMarketOrderContractType = 19, + CreateMarketplaceContractType = 20, + ConfigMarketplaceContractType = 21, + UpdateAccountPermissionContractType = 22, + DepositContractType = 23, + ItoTriggerContractType = 24, + } + impl ContractType { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + ContractType::TransferContractType => "TransferContractType", + ContractType::CreateAssetContractType => "CreateAssetContractType", + ContractType::CreateValidatorContractType => { + "CreateValidatorContractType" + } + ContractType::ValidatorConfigContractType => { + "ValidatorConfigContractType" + } + ContractType::FreezeContractType => "FreezeContractType", + ContractType::UnfreezeContractType => "UnfreezeContractType", + ContractType::DelegateContractType => "DelegateContractType", + ContractType::UndelegateContractType => "UndelegateContractType", + ContractType::WithdrawContractType => "WithdrawContractType", + ContractType::ClaimContractType => "ClaimContractType", + ContractType::UnjailContractType => "UnjailContractType", + ContractType::AssetTriggerContractType => "AssetTriggerContractType", + ContractType::SetAccountNameContractType => "SetAccountNameContractType", + ContractType::ProposalContractType => "ProposalContractType", + ContractType::VoteContractType => "VoteContractType", + ContractType::ConfigItoContractType => "ConfigITOContractType", + ContractType::SetItoPricesContractType => "SetITOPricesContractType", + ContractType::BuyContractType => "BuyContractType", + ContractType::SellContractType => "SellContractType", + ContractType::CancelMarketOrderContractType => { + "CancelMarketOrderContractType" + } + ContractType::CreateMarketplaceContractType => { + "CreateMarketplaceContractType" + } + ContractType::ConfigMarketplaceContractType => { + "ConfigMarketplaceContractType" + } + ContractType::UpdateAccountPermissionContractType => { + "UpdateAccountPermissionContractType" + } + ContractType::DepositContractType => "DepositContractType", + ContractType::ItoTriggerContractType => "ITOTriggerContractType", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "TransferContractType" => Some(Self::TransferContractType), + "CreateAssetContractType" => Some(Self::CreateAssetContractType), + "CreateValidatorContractType" => Some(Self::CreateValidatorContractType), + "ValidatorConfigContractType" => Some(Self::ValidatorConfigContractType), + "FreezeContractType" => Some(Self::FreezeContractType), + "UnfreezeContractType" => Some(Self::UnfreezeContractType), + "DelegateContractType" => Some(Self::DelegateContractType), + "UndelegateContractType" => Some(Self::UndelegateContractType), + "WithdrawContractType" => Some(Self::WithdrawContractType), + "ClaimContractType" => Some(Self::ClaimContractType), + "UnjailContractType" => Some(Self::UnjailContractType), + "AssetTriggerContractType" => Some(Self::AssetTriggerContractType), + "SetAccountNameContractType" => Some(Self::SetAccountNameContractType), + "ProposalContractType" => Some(Self::ProposalContractType), + "VoteContractType" => Some(Self::VoteContractType), + "ConfigITOContractType" => Some(Self::ConfigItoContractType), + "SetITOPricesContractType" => Some(Self::SetItoPricesContractType), + "BuyContractType" => Some(Self::BuyContractType), + "SellContractType" => Some(Self::SellContractType), + "CancelMarketOrderContractType" => { + Some(Self::CancelMarketOrderContractType) + } + "CreateMarketplaceContractType" => { + Some(Self::CreateMarketplaceContractType) + } + "ConfigMarketplaceContractType" => { + Some(Self::ConfigMarketplaceContractType) + } + "UpdateAccountPermissionContractType" => { + Some(Self::UpdateAccountPermissionContractType) + } + "DepositContractType" => Some(Self::DepositContractType), + "ITOTriggerContractType" => Some(Self::ItoTriggerContractType), + _ => None, + } + } + } +} +/// Transaction holds all the data needed for a value transfer +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Transaction { + #[prost(message, optional, tag = "1")] + pub raw_data: ::core::option::Option, + #[prost(bytes = "vec", repeated, tag = "2")] + pub signature: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec>, + #[prost(enumeration = "transaction::TxResult", tag = "3")] + pub result: i32, + #[prost(enumeration = "transaction::TxResultCode", tag = "4")] + pub result_code: i32, + #[prost(message, repeated, tag = "5")] + pub receipts: ::prost::alloc::vec::Vec, + #[prost(uint64, tag = "6")] + pub block: u64, +} +/// Nested message and enum types in `Transaction`. +pub mod transaction { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct KdaFee { + #[prost(bytes = "vec", tag = "1")] + pub kda: ::prost::alloc::vec::Vec, + /// TODO: allow spread + #[prost(int64, tag = "2")] + pub amount: i64, + } + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct Raw { + #[prost(uint64, tag = "1")] + pub nonce: u64, + #[prost(bytes = "vec", tag = "2")] + pub sender: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "6")] + pub contract: ::prost::alloc::vec::Vec, + #[prost(int32, tag = "7")] + pub permission_id: i32, + #[prost(bytes = "vec", repeated, tag = "10")] + pub data: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec>, + #[prost(int64, tag = "13")] + pub k_app_fee: i64, + #[prost(int64, tag = "14")] + pub bandwidth_fee: i64, + #[prost(uint32, tag = "15")] + pub version: u32, + #[prost(bytes = "vec", tag = "16")] + pub chain_id: ::prost::alloc::vec::Vec, + #[prost(message, optional, tag = "17")] + pub kda_fee: ::core::option::Option, + } + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct Receipt { + #[prost(bytes = "vec", repeated, tag = "1")] + pub data: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec>, + } + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] + #[repr(i32)] + pub enum TxResult { + Success = 0, + Failed = 1, + } + impl TxResult { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + TxResult::Success => "SUCCESS", + TxResult::Failed => "FAILED", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "SUCCESS" => Some(Self::Success), + "FAILED" => Some(Self::Failed), + _ => None, + } + } + } + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] + #[repr(i32)] + pub enum TxResultCode { + Ok = 0, + OutOfFunds = 1, + AccountError = 2, + AssetError = 3, + ContractInvalid = 4, + ContractNotFound = 5, + FeeInvalid = 6, + ParameterInvalid = 7, + AprInvalid = 8, + AssetIdInvalid = 9, + AssetTypeInvalid = 10, + AssetCantBeMinted = 11, + AssetCantBeBurned = 12, + AssetCantBePaused = 13, + AssetCantBeDelegated = 14, + AssetOwnerCantBeChanged = 15, + AccountNotOwner = 16, + CommissionTooHigh = 17, + DelegationAmountInvalid = 18, + ProposalNotActive = 19, + ValueInvalid = 20, + AmountInvalid = 21, + BucketIdInvalid = 22, + KeyConflict = 23, + MaxDelegationAmount = 24, + InvalidPeerKey = 25, + MinKfiStakedUnreached = 26, + MaxSupplyExeeced = 27, + SaveAccountError = 28, + LoadAccountError = 29, + SameAccountError = 30, + AssetPaused = 31, + DeletegateError = 32, + WithdrawNotAvailable = 33, + ErrOverflow = 34, + SetStakingErr = 35, + SetMarketOrderErr = 36, + BalanceError = 37, + KappError = 38, + UnfreezeError = 39, + UndeletegateError = 40, + WithdrawError = 41, + ClaimError = 42, + BucketsExceded = 43, + AssetCantBeWiped = 44, + AssetCantAddRoles = 45, + FreezeError = 46, + ItoNotActive = 47, + NftMintStopped = 48, + RoyaltiesChangeStopped = 49, + ItokappError = 50, + ItoWhiteListError = 51, + NftMetadataChangeStopped = 52, + AlreadyExists = 53, + Fail = 99, + } + impl TxResultCode { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + TxResultCode::Ok => "Ok", + TxResultCode::OutOfFunds => "OutOfFunds", + TxResultCode::AccountError => "AccountError", + TxResultCode::AssetError => "AssetError", + TxResultCode::ContractInvalid => "ContractInvalid", + TxResultCode::ContractNotFound => "ContractNotFound", + TxResultCode::FeeInvalid => "FeeInvalid", + TxResultCode::ParameterInvalid => "ParameterInvalid", + TxResultCode::AprInvalid => "APRInvalid", + TxResultCode::AssetIdInvalid => "AssetIDInvalid", + TxResultCode::AssetTypeInvalid => "AssetTypeInvalid", + TxResultCode::AssetCantBeMinted => "AssetCantBeMinted", + TxResultCode::AssetCantBeBurned => "AssetCantBeBurned", + TxResultCode::AssetCantBePaused => "AssetCantBePaused", + TxResultCode::AssetCantBeDelegated => "AssetCantBeDelegated", + TxResultCode::AssetOwnerCantBeChanged => "AssetOwnerCantBeChanged", + TxResultCode::AccountNotOwner => "AccountNotOwner", + TxResultCode::CommissionTooHigh => "CommissionTooHigh", + TxResultCode::DelegationAmountInvalid => "DelegationAmountInvalid", + TxResultCode::ProposalNotActive => "ProposalNotActive", + TxResultCode::ValueInvalid => "ValueInvalid", + TxResultCode::AmountInvalid => "AmountInvalid", + TxResultCode::BucketIdInvalid => "BucketIDInvalid", + TxResultCode::KeyConflict => "KeyConflict", + TxResultCode::MaxDelegationAmount => "MaxDelegationAmount", + TxResultCode::InvalidPeerKey => "InvalidPeerKey", + TxResultCode::MinKfiStakedUnreached => "MinKFIStakedUnreached", + TxResultCode::MaxSupplyExeeced => "MaxSupplyExeeced", + TxResultCode::SaveAccountError => "SaveAccountError", + TxResultCode::LoadAccountError => "LoadAccountError", + TxResultCode::SameAccountError => "SameAccountError", + TxResultCode::AssetPaused => "AssetPaused", + TxResultCode::DeletegateError => "DeletegateError", + TxResultCode::WithdrawNotAvailable => "WithdrawNotAvailable", + TxResultCode::ErrOverflow => "ErrOverflow", + TxResultCode::SetStakingErr => "SetStakingErr", + TxResultCode::SetMarketOrderErr => "SetMarketOrderErr", + TxResultCode::BalanceError => "BalanceError", + TxResultCode::KappError => "KAPPError", + TxResultCode::UnfreezeError => "UnfreezeError", + TxResultCode::UndeletegateError => "UndeletegateError", + TxResultCode::WithdrawError => "WithdrawError", + TxResultCode::ClaimError => "ClaimError", + TxResultCode::BucketsExceded => "BucketsExceded", + TxResultCode::AssetCantBeWiped => "AssetCantBeWiped", + TxResultCode::AssetCantAddRoles => "AssetCantAddRoles", + TxResultCode::FreezeError => "FreezeError", + TxResultCode::ItoNotActive => "ITONotActive", + TxResultCode::NftMintStopped => "NFTMintStopped", + TxResultCode::RoyaltiesChangeStopped => "RoyaltiesChangeStopped", + TxResultCode::ItokappError => "ITOKAPPError", + TxResultCode::ItoWhiteListError => "ITOWhiteListError", + TxResultCode::NftMetadataChangeStopped => "NFTMetadataChangeStopped", + TxResultCode::AlreadyExists => "AlreadyExists", + TxResultCode::Fail => "Fail", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "Ok" => Some(Self::Ok), + "OutOfFunds" => Some(Self::OutOfFunds), + "AccountError" => Some(Self::AccountError), + "AssetError" => Some(Self::AssetError), + "ContractInvalid" => Some(Self::ContractInvalid), + "ContractNotFound" => Some(Self::ContractNotFound), + "FeeInvalid" => Some(Self::FeeInvalid), + "ParameterInvalid" => Some(Self::ParameterInvalid), + "APRInvalid" => Some(Self::AprInvalid), + "AssetIDInvalid" => Some(Self::AssetIdInvalid), + "AssetTypeInvalid" => Some(Self::AssetTypeInvalid), + "AssetCantBeMinted" => Some(Self::AssetCantBeMinted), + "AssetCantBeBurned" => Some(Self::AssetCantBeBurned), + "AssetCantBePaused" => Some(Self::AssetCantBePaused), + "AssetCantBeDelegated" => Some(Self::AssetCantBeDelegated), + "AssetOwnerCantBeChanged" => Some(Self::AssetOwnerCantBeChanged), + "AccountNotOwner" => Some(Self::AccountNotOwner), + "CommissionTooHigh" => Some(Self::CommissionTooHigh), + "DelegationAmountInvalid" => Some(Self::DelegationAmountInvalid), + "ProposalNotActive" => Some(Self::ProposalNotActive), + "ValueInvalid" => Some(Self::ValueInvalid), + "AmountInvalid" => Some(Self::AmountInvalid), + "BucketIDInvalid" => Some(Self::BucketIdInvalid), + "KeyConflict" => Some(Self::KeyConflict), + "MaxDelegationAmount" => Some(Self::MaxDelegationAmount), + "InvalidPeerKey" => Some(Self::InvalidPeerKey), + "MinKFIStakedUnreached" => Some(Self::MinKfiStakedUnreached), + "MaxSupplyExeeced" => Some(Self::MaxSupplyExeeced), + "SaveAccountError" => Some(Self::SaveAccountError), + "LoadAccountError" => Some(Self::LoadAccountError), + "SameAccountError" => Some(Self::SameAccountError), + "AssetPaused" => Some(Self::AssetPaused), + "DeletegateError" => Some(Self::DeletegateError), + "WithdrawNotAvailable" => Some(Self::WithdrawNotAvailable), + "ErrOverflow" => Some(Self::ErrOverflow), + "SetStakingErr" => Some(Self::SetStakingErr), + "SetMarketOrderErr" => Some(Self::SetMarketOrderErr), + "BalanceError" => Some(Self::BalanceError), + "KAPPError" => Some(Self::KappError), + "UnfreezeError" => Some(Self::UnfreezeError), + "UndeletegateError" => Some(Self::UndeletegateError), + "WithdrawError" => Some(Self::WithdrawError), + "ClaimError" => Some(Self::ClaimError), + "BucketsExceded" => Some(Self::BucketsExceded), + "AssetCantBeWiped" => Some(Self::AssetCantBeWiped), + "AssetCantAddRoles" => Some(Self::AssetCantAddRoles), + "FreezeError" => Some(Self::FreezeError), + "ITONotActive" => Some(Self::ItoNotActive), + "NFTMintStopped" => Some(Self::NftMintStopped), + "RoyaltiesChangeStopped" => Some(Self::RoyaltiesChangeStopped), + "ITOKAPPError" => Some(Self::ItokappError), + "ITOWhiteListError" => Some(Self::ItoWhiteListError), + "NFTMetadataChangeStopped" => Some(Self::NftMetadataChangeStopped), + "AlreadyExists" => Some(Self::AlreadyExists), + "Fail" => Some(Self::Fail), + _ => None, + } + } + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Key { + #[prost(bytes = "vec", tag = "1")] + pub address: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "2")] + pub weight: i64, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Permission { + #[prost(int32, tag = "1")] + pub id: i32, + #[prost(enumeration = "permission::PermissionType", tag = "2")] + pub r#type: i32, + #[prost(string, tag = "3")] + pub permission_name: ::prost::alloc::string::String, + #[prost(int64, tag = "4")] + pub threshold: i64, + #[prost(bytes = "vec", tag = "5")] + pub operations: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "6")] + pub signers: ::prost::alloc::vec::Vec, +} +/// Nested message and enum types in `Permission`. +pub mod permission { + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] + #[repr(i32)] + pub enum PermissionType { + Owner = 0, + User = 1, + } + impl PermissionType { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + PermissionType::Owner => "Owner", + PermissionType::User => "User", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "Owner" => Some(Self::Owner), + "User" => Some(Self::User), + _ => None, + } + } + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct UserAccountData { + #[prost(bytes = "vec", tag = "1")] + pub address: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "2")] + pub name: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "3")] + pub root_hash: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "5")] + pub balance: i64, + #[prost(int64, tag = "6")] + pub allowance: i64, + #[prost(uint64, tag = "7")] + pub nonce: u64, + #[prost(message, repeated, tag = "8")] + pub permissions: ::prost::alloc::vec::Vec, +} diff --git a/packages/kos/src/protos/generated/mod.rs b/packages/kos/src/protos/generated/mod.rs new file mode 100644 index 0000000..ba0c8d6 --- /dev/null +++ b/packages/kos/src/protos/generated/mod.rs @@ -0,0 +1,2 @@ +pub(crate) mod klv; +pub(crate) mod trx; diff --git a/packages/kos/src/protos/generated/trx/google.protobuf.rs b/packages/kos/src/protos/generated/trx/google.protobuf.rs new file mode 100644 index 0000000..e69de29 diff --git a/packages/kos/src/protos/generated/trx/mod.rs b/packages/kos/src/protos/generated/trx/mod.rs new file mode 100644 index 0000000..1b800ec --- /dev/null +++ b/packages/kos/src/protos/generated/trx/mod.rs @@ -0,0 +1 @@ +pub mod protocol; diff --git a/packages/kos/src/protos/generated/trx/protocol.rs b/packages/kos/src/protos/generated/trx/protocol.rs new file mode 100644 index 0000000..dc668a3 --- /dev/null +++ b/packages/kos/src/protos/generated/trx/protocol.rs @@ -0,0 +1,3109 @@ +// This file is @generated by prost-build. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Endpoint { + #[prost(bytes = "vec", tag = "1")] + pub address: ::prost::alloc::vec::Vec, + #[prost(int32, tag = "2")] + pub port: i32, + #[prost(bytes = "vec", tag = "3")] + pub node_id: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct PingMessage { + #[prost(message, optional, tag = "1")] + pub from: ::core::option::Option, + #[prost(message, optional, tag = "2")] + pub to: ::core::option::Option, + #[prost(int32, tag = "3")] + pub version: i32, + #[prost(int64, tag = "4")] + pub timestamp: i64, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct PongMessage { + #[prost(message, optional, tag = "1")] + pub from: ::core::option::Option, + #[prost(int32, tag = "2")] + pub echo: i32, + #[prost(int64, tag = "3")] + pub timestamp: i64, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct FindNeighbours { + #[prost(message, optional, tag = "1")] + pub from: ::core::option::Option, + #[prost(bytes = "vec", tag = "2")] + pub target_id: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "3")] + pub timestamp: i64, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Neighbours { + #[prost(message, optional, tag = "1")] + pub from: ::core::option::Option, + #[prost(message, repeated, tag = "2")] + pub neighbours: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "3")] + pub timestamp: i64, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BackupMessage { + #[prost(bool, tag = "1")] + pub flag: bool, + #[prost(int32, tag = "2")] + pub priority: i32, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum ResourceCode { + Bandwidth = 0, + Energy = 1, + TronPower = 2, +} +impl ResourceCode { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + ResourceCode::Bandwidth => "BANDWIDTH", + ResourceCode::Energy => "ENERGY", + ResourceCode::TronPower => "TRON_POWER", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "BANDWIDTH" => Some(Self::Bandwidth), + "ENERGY" => Some(Self::Energy), + "TRON_POWER" => Some(Self::TronPower), + _ => None, + } + } +} +/// AccountId, (name, address) use name, (null, address) use address, (name, null) use name, +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct AccountId { + #[prost(bytes = "vec", tag = "1")] + pub name: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "2")] + pub address: ::prost::alloc::vec::Vec, +} +/// vote message +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Vote { + /// the super rep address + #[prost(bytes = "vec", tag = "1")] + pub vote_address: ::prost::alloc::vec::Vec, + /// the vote num to this super rep. + #[prost(int64, tag = "2")] + pub vote_count: i64, +} +/// Proposal +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Proposal { + #[prost(int64, tag = "1")] + pub proposal_id: i64, + #[prost(bytes = "vec", tag = "2")] + pub proposer_address: ::prost::alloc::vec::Vec, + #[prost(btree_map = "int64, int64", tag = "3")] + pub parameters: ::prost::alloc::collections::BTreeMap, + #[prost(int64, tag = "4")] + pub expiration_time: i64, + #[prost(int64, tag = "5")] + pub create_time: i64, + #[prost(bytes = "vec", repeated, tag = "6")] + pub approvals: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec>, + #[prost(enumeration = "proposal::State", tag = "7")] + pub state: i32, +} +/// Nested message and enum types in `Proposal`. +pub mod proposal { + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] + #[repr(i32)] + pub enum State { + Pending = 0, + Disapproved = 1, + Approved = 2, + Canceled = 3, + } + impl State { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + State::Pending => "PENDING", + State::Disapproved => "DISAPPROVED", + State::Approved => "APPROVED", + State::Canceled => "CANCELED", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "PENDING" => Some(Self::Pending), + "DISAPPROVED" => Some(Self::Disapproved), + "APPROVED" => Some(Self::Approved), + "CANCELED" => Some(Self::Canceled), + _ => None, + } + } + } +} +/// Exchange +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Exchange { + #[prost(int64, tag = "1")] + pub exchange_id: i64, + #[prost(bytes = "vec", tag = "2")] + pub creator_address: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "3")] + pub create_time: i64, + #[prost(bytes = "vec", tag = "6")] + pub first_token_id: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "7")] + pub first_token_balance: i64, + #[prost(bytes = "vec", tag = "8")] + pub second_token_id: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "9")] + pub second_token_balance: i64, +} +/// market +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MarketOrder { + #[prost(bytes = "vec", tag = "1")] + pub order_id: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "2")] + pub owner_address: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "3")] + pub create_time: i64, + #[prost(bytes = "vec", tag = "4")] + pub sell_token_id: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "5")] + pub sell_token_quantity: i64, + #[prost(bytes = "vec", tag = "6")] + pub buy_token_id: ::prost::alloc::vec::Vec, + /// min to receive + #[prost(int64, tag = "7")] + pub buy_token_quantity: i64, + #[prost(int64, tag = "9")] + pub sell_token_quantity_remain: i64, + /// When state != ACTIVE and sell_token_quantity_return !=0, + /// it means that some sell tokens are returned to the account due to insufficient remaining amount + #[prost(int64, tag = "10")] + pub sell_token_quantity_return: i64, + #[prost(enumeration = "market_order::State", tag = "11")] + pub state: i32, + #[prost(bytes = "vec", tag = "12")] + pub prev: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "13")] + pub next: ::prost::alloc::vec::Vec, +} +/// Nested message and enum types in `MarketOrder`. +pub mod market_order { + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] + #[repr(i32)] + pub enum State { + Active = 0, + Inactive = 1, + Canceled = 2, + } + impl State { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + State::Active => "ACTIVE", + State::Inactive => "INACTIVE", + State::Canceled => "CANCELED", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "ACTIVE" => Some(Self::Active), + "INACTIVE" => Some(Self::Inactive), + "CANCELED" => Some(Self::Canceled), + _ => None, + } + } + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MarketOrderList { + #[prost(message, repeated, tag = "1")] + pub orders: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MarketOrderPairList { + #[prost(message, repeated, tag = "1")] + pub order_pair: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MarketOrderPair { + #[prost(bytes = "vec", tag = "1")] + pub sell_token_id: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "2")] + pub buy_token_id: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MarketAccountOrder { + #[prost(bytes = "vec", tag = "1")] + pub owner_address: ::prost::alloc::vec::Vec, + /// order_id list + #[prost(bytes = "vec", repeated, tag = "2")] + pub orders: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec>, + /// active count + #[prost(int64, tag = "3")] + pub count: i64, + #[prost(int64, tag = "4")] + pub total_count: i64, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MarketPrice { + #[prost(int64, tag = "1")] + pub sell_token_quantity: i64, + #[prost(int64, tag = "2")] + pub buy_token_quantity: i64, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MarketPriceList { + #[prost(bytes = "vec", tag = "1")] + pub sell_token_id: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "2")] + pub buy_token_id: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "3")] + pub prices: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MarketOrderIdList { + #[prost(bytes = "vec", tag = "1")] + pub head: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "2")] + pub tail: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ChainParameters { + #[prost(message, repeated, tag = "1")] + pub chain_parameter: ::prost::alloc::vec::Vec, +} +/// Nested message and enum types in `ChainParameters`. +pub mod chain_parameters { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct ChainParameter { + #[prost(string, tag = "1")] + pub key: ::prost::alloc::string::String, + #[prost(int64, tag = "2")] + pub value: i64, + } +} +/// Account +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Account { + /// account nick name + #[prost(bytes = "vec", tag = "1")] + pub account_name: ::prost::alloc::vec::Vec, + #[prost(enumeration = "AccountType", tag = "2")] + pub r#type: i32, + /// the create address + #[prost(bytes = "vec", tag = "3")] + pub address: ::prost::alloc::vec::Vec, + /// the trx balance + #[prost(int64, tag = "4")] + pub balance: i64, + /// the votes + #[prost(message, repeated, tag = "5")] + pub votes: ::prost::alloc::vec::Vec, + /// the other asset owned by this account + #[prost(btree_map = "string, int64", tag = "6")] + pub asset: ::prost::alloc::collections::BTreeMap< + ::prost::alloc::string::String, + i64, + >, + /// the other asset owned by this account,key is assetId + #[prost(btree_map = "string, int64", tag = "56")] + pub asset_v2: ::prost::alloc::collections::BTreeMap< + ::prost::alloc::string::String, + i64, + >, + /// the frozen balance for bandwidth + #[prost(message, repeated, tag = "7")] + pub frozen: ::prost::alloc::vec::Vec, + /// bandwidth, get from frozen + #[prost(int64, tag = "8")] + pub net_usage: i64, + /// Frozen balance provided by other accounts to this account + #[prost(int64, tag = "41")] + pub acquired_delegated_frozen_balance_for_bandwidth: i64, + /// Freeze and provide balances to other accounts + #[prost(int64, tag = "42")] + pub delegated_frozen_balance_for_bandwidth: i64, + #[prost(int64, tag = "46")] + pub old_tron_power: i64, + #[prost(message, optional, tag = "47")] + pub tron_power: ::core::option::Option, + #[prost(bool, tag = "60")] + pub asset_optimized: bool, + /// this account create time + #[prost(int64, tag = "9")] + pub create_time: i64, + /// this last operation time, including transfer, voting and so on. //FIXME fix grammar + #[prost(int64, tag = "10")] + pub latest_opration_time: i64, + /// witness block producing allowance + #[prost(int64, tag = "11")] + pub allowance: i64, + /// last withdraw time + #[prost(int64, tag = "12")] + pub latest_withdraw_time: i64, + /// not used so far + #[prost(bytes = "vec", tag = "13")] + pub code: ::prost::alloc::vec::Vec, + #[prost(bool, tag = "14")] + pub is_witness: bool, + #[prost(bool, tag = "15")] + pub is_committee: bool, + /// frozen asset(for asset issuer) + #[prost(message, repeated, tag = "16")] + pub frozen_supply: ::prost::alloc::vec::Vec, + /// asset_issued_name + #[prost(bytes = "vec", tag = "17")] + pub asset_issued_name: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "57")] + pub asset_issued_id: ::prost::alloc::vec::Vec, + #[prost(btree_map = "string, int64", tag = "18")] + pub latest_asset_operation_time: ::prost::alloc::collections::BTreeMap< + ::prost::alloc::string::String, + i64, + >, + #[prost(btree_map = "string, int64", tag = "58")] + pub latest_asset_operation_time_v2: ::prost::alloc::collections::BTreeMap< + ::prost::alloc::string::String, + i64, + >, + #[prost(int64, tag = "19")] + pub free_net_usage: i64, + #[prost(btree_map = "string, int64", tag = "20")] + pub free_asset_net_usage: ::prost::alloc::collections::BTreeMap< + ::prost::alloc::string::String, + i64, + >, + #[prost(btree_map = "string, int64", tag = "59")] + pub free_asset_net_usage_v2: ::prost::alloc::collections::BTreeMap< + ::prost::alloc::string::String, + i64, + >, + #[prost(int64, tag = "21")] + pub latest_consume_time: i64, + #[prost(int64, tag = "22")] + pub latest_consume_free_time: i64, + /// the identity of this account, case insensitive + #[prost(bytes = "vec", tag = "23")] + pub account_id: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "24")] + pub net_window_size: i64, + #[prost(bool, tag = "25")] + pub net_window_optimized: bool, + #[prost(message, optional, tag = "26")] + pub account_resource: ::core::option::Option, + #[prost(bytes = "vec", tag = "30")] + pub code_hash: ::prost::alloc::vec::Vec, + #[prost(message, optional, tag = "31")] + pub owner_permission: ::core::option::Option, + #[prost(message, optional, tag = "32")] + pub witness_permission: ::core::option::Option, + #[prost(message, repeated, tag = "33")] + pub active_permission: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "34")] + pub frozen_v2: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "35")] + pub unfrozen_v2: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "36")] + pub delegated_frozen_v2_balance_for_bandwidth: i64, + #[prost(int64, tag = "37")] + pub acquired_delegated_frozen_v2_balance_for_bandwidth: i64, +} +/// Nested message and enum types in `Account`. +pub mod account { + /// frozen balance + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct Frozen { + /// the frozen trx balance + #[prost(int64, tag = "1")] + pub frozen_balance: i64, + /// the expire time + #[prost(int64, tag = "2")] + pub expire_time: i64, + } + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct AccountResource { + /// energy resource, get from frozen + #[prost(int64, tag = "1")] + pub energy_usage: i64, + /// the frozen balance for energy + #[prost(message, optional, tag = "2")] + pub frozen_balance_for_energy: ::core::option::Option, + #[prost(int64, tag = "3")] + pub latest_consume_time_for_energy: i64, + /// Frozen balance provided by other accounts to this account + #[prost(int64, tag = "4")] + pub acquired_delegated_frozen_balance_for_energy: i64, + /// Frozen balances provided to other accounts + #[prost(int64, tag = "5")] + pub delegated_frozen_balance_for_energy: i64, + /// storage resource, get from market + #[prost(int64, tag = "6")] + pub storage_limit: i64, + #[prost(int64, tag = "7")] + pub storage_usage: i64, + #[prost(int64, tag = "8")] + pub latest_exchange_storage_time: i64, + #[prost(int64, tag = "9")] + pub energy_window_size: i64, + #[prost(int64, tag = "10")] + pub delegated_frozen_v2_balance_for_energy: i64, + #[prost(int64, tag = "11")] + pub acquired_delegated_frozen_v2_balance_for_energy: i64, + #[prost(bool, tag = "12")] + pub energy_window_optimized: bool, + } + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct FreezeV2 { + #[prost(enumeration = "super::ResourceCode", tag = "1")] + pub r#type: i32, + #[prost(int64, tag = "2")] + pub amount: i64, + } + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct UnFreezeV2 { + #[prost(enumeration = "super::ResourceCode", tag = "1")] + pub r#type: i32, + #[prost(int64, tag = "3")] + pub unfreeze_amount: i64, + #[prost(int64, tag = "4")] + pub unfreeze_expire_time: i64, + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Key { + #[prost(bytes = "vec", tag = "1")] + pub address: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "2")] + pub weight: i64, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct DelegatedResource { + #[prost(bytes = "vec", tag = "1")] + pub from: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "2")] + pub to: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "3")] + pub frozen_balance_for_bandwidth: i64, + #[prost(int64, tag = "4")] + pub frozen_balance_for_energy: i64, + #[prost(int64, tag = "5")] + pub expire_time_for_bandwidth: i64, + #[prost(int64, tag = "6")] + pub expire_time_for_energy: i64, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Authority { + #[prost(message, optional, tag = "1")] + pub account: ::core::option::Option, + #[prost(bytes = "vec", tag = "2")] + pub permission_name: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Permission { + #[prost(enumeration = "permission::PermissionType", tag = "1")] + pub r#type: i32, + /// Owner id=0, Witness id=1, Active id start by 2 + #[prost(int32, tag = "2")] + pub id: i32, + #[prost(string, tag = "3")] + pub permission_name: ::prost::alloc::string::String, + #[prost(int64, tag = "4")] + pub threshold: i64, + #[prost(int32, tag = "5")] + pub parent_id: i32, + /// 1 bit 1 contract + #[prost(bytes = "vec", tag = "6")] + pub operations: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "7")] + pub keys: ::prost::alloc::vec::Vec, +} +/// Nested message and enum types in `Permission`. +pub mod permission { + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] + #[repr(i32)] + pub enum PermissionType { + Owner = 0, + Witness = 1, + Active = 2, + } + impl PermissionType { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + PermissionType::Owner => "Owner", + PermissionType::Witness => "Witness", + PermissionType::Active => "Active", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "Owner" => Some(Self::Owner), + "Witness" => Some(Self::Witness), + "Active" => Some(Self::Active), + _ => None, + } + } + } +} +/// Witness +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Witness { + #[prost(bytes = "vec", tag = "1")] + pub address: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "2")] + pub vote_count: i64, + #[prost(bytes = "vec", tag = "3")] + pub pub_key: ::prost::alloc::vec::Vec, + #[prost(string, tag = "4")] + pub url: ::prost::alloc::string::String, + #[prost(int64, tag = "5")] + pub total_produced: i64, + #[prost(int64, tag = "6")] + pub total_missed: i64, + #[prost(int64, tag = "7")] + pub latest_block_num: i64, + #[prost(int64, tag = "8")] + pub latest_slot_num: i64, + #[prost(bool, tag = "9")] + pub is_jobs: bool, +} +/// Vote Change +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Votes { + #[prost(bytes = "vec", tag = "1")] + pub address: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "2")] + pub old_votes: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "3")] + pub new_votes: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct TxOutput { + #[prost(int64, tag = "1")] + pub value: i64, + #[prost(bytes = "vec", tag = "2")] + pub pub_key_hash: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct TxInput { + #[prost(message, optional, tag = "1")] + pub raw_data: ::core::option::Option, + #[prost(bytes = "vec", tag = "4")] + pub signature: ::prost::alloc::vec::Vec, +} +/// Nested message and enum types in `TXInput`. +pub mod tx_input { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct Raw { + #[prost(bytes = "vec", tag = "1")] + pub tx_id: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "2")] + pub vout: i64, + #[prost(bytes = "vec", tag = "3")] + pub pub_key: ::prost::alloc::vec::Vec, + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct TxOutputs { + #[prost(message, repeated, tag = "1")] + pub outputs: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ResourceReceipt { + #[prost(int64, tag = "1")] + pub energy_usage: i64, + #[prost(int64, tag = "2")] + pub energy_fee: i64, + #[prost(int64, tag = "3")] + pub origin_energy_usage: i64, + #[prost(int64, tag = "4")] + pub energy_usage_total: i64, + #[prost(int64, tag = "5")] + pub net_usage: i64, + #[prost(int64, tag = "6")] + pub net_fee: i64, + #[prost(enumeration = "transaction::result::ContractResult", tag = "7")] + pub result: i32, + #[prost(int64, tag = "8")] + pub energy_penalty_total: i64, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MarketOrderDetail { + #[prost(bytes = "vec", tag = "1")] + pub maker_order_id: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "2")] + pub taker_order_id: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "3")] + pub fill_sell_quantity: i64, + #[prost(int64, tag = "4")] + pub fill_buy_quantity: i64, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Transaction { + #[prost(message, optional, tag = "1")] + pub raw_data: ::core::option::Option, + /// only support size = 1, repeated list here for muti-sig extension + #[prost(bytes = "vec", repeated, tag = "2")] + pub signature: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec>, + #[prost(message, repeated, tag = "5")] + pub ret: ::prost::alloc::vec::Vec, +} +/// Nested message and enum types in `Transaction`. +pub mod transaction { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct Contract { + #[prost(enumeration = "contract::ContractType", tag = "1")] + pub r#type: i32, + #[prost(message, optional, tag = "2")] + pub parameter: ::core::option::Option<::prost_types::Any>, + #[prost(bytes = "vec", tag = "3")] + pub provider: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "4")] + pub contract_name: ::prost::alloc::vec::Vec, + #[prost(int32, tag = "5")] + pub permission_id: i32, + } + /// Nested message and enum types in `Contract`. + pub mod contract { + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] + #[repr(i32)] + pub enum ContractType { + AccountCreateContract = 0, + TransferContract = 1, + TransferAssetContract = 2, + VoteAssetContract = 3, + VoteWitnessContract = 4, + WitnessCreateContract = 5, + AssetIssueContract = 6, + WitnessUpdateContract = 8, + ParticipateAssetIssueContract = 9, + AccountUpdateContract = 10, + FreezeBalanceContract = 11, + UnfreezeBalanceContract = 12, + WithdrawBalanceContract = 13, + UnfreezeAssetContract = 14, + UpdateAssetContract = 15, + ProposalCreateContract = 16, + ProposalApproveContract = 17, + ProposalDeleteContract = 18, + SetAccountIdContract = 19, + CustomContract = 20, + CreateSmartContract = 30, + TriggerSmartContract = 31, + GetContract = 32, + UpdateSettingContract = 33, + ExchangeCreateContract = 41, + ExchangeInjectContract = 42, + ExchangeWithdrawContract = 43, + ExchangeTransactionContract = 44, + UpdateEnergyLimitContract = 45, + AccountPermissionUpdateContract = 46, + ClearAbiContract = 48, + UpdateBrokerageContract = 49, + ShieldedTransferContract = 51, + MarketSellAssetContract = 52, + MarketCancelOrderContract = 53, + FreezeBalanceV2Contract = 54, + UnfreezeBalanceV2Contract = 55, + WithdrawExpireUnfreezeContract = 56, + DelegateResourceContract = 57, + UnDelegateResourceContract = 58, + CancelAllUnfreezeV2Contract = 59, + } + impl ContractType { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + ContractType::AccountCreateContract => "AccountCreateContract", + ContractType::TransferContract => "TransferContract", + ContractType::TransferAssetContract => "TransferAssetContract", + ContractType::VoteAssetContract => "VoteAssetContract", + ContractType::VoteWitnessContract => "VoteWitnessContract", + ContractType::WitnessCreateContract => "WitnessCreateContract", + ContractType::AssetIssueContract => "AssetIssueContract", + ContractType::WitnessUpdateContract => "WitnessUpdateContract", + ContractType::ParticipateAssetIssueContract => { + "ParticipateAssetIssueContract" + } + ContractType::AccountUpdateContract => "AccountUpdateContract", + ContractType::FreezeBalanceContract => "FreezeBalanceContract", + ContractType::UnfreezeBalanceContract => "UnfreezeBalanceContract", + ContractType::WithdrawBalanceContract => "WithdrawBalanceContract", + ContractType::UnfreezeAssetContract => "UnfreezeAssetContract", + ContractType::UpdateAssetContract => "UpdateAssetContract", + ContractType::ProposalCreateContract => "ProposalCreateContract", + ContractType::ProposalApproveContract => "ProposalApproveContract", + ContractType::ProposalDeleteContract => "ProposalDeleteContract", + ContractType::SetAccountIdContract => "SetAccountIdContract", + ContractType::CustomContract => "CustomContract", + ContractType::CreateSmartContract => "CreateSmartContract", + ContractType::TriggerSmartContract => "TriggerSmartContract", + ContractType::GetContract => "GetContract", + ContractType::UpdateSettingContract => "UpdateSettingContract", + ContractType::ExchangeCreateContract => "ExchangeCreateContract", + ContractType::ExchangeInjectContract => "ExchangeInjectContract", + ContractType::ExchangeWithdrawContract => "ExchangeWithdrawContract", + ContractType::ExchangeTransactionContract => { + "ExchangeTransactionContract" + } + ContractType::UpdateEnergyLimitContract => { + "UpdateEnergyLimitContract" + } + ContractType::AccountPermissionUpdateContract => { + "AccountPermissionUpdateContract" + } + ContractType::ClearAbiContract => "ClearABIContract", + ContractType::UpdateBrokerageContract => "UpdateBrokerageContract", + ContractType::ShieldedTransferContract => "ShieldedTransferContract", + ContractType::MarketSellAssetContract => "MarketSellAssetContract", + ContractType::MarketCancelOrderContract => { + "MarketCancelOrderContract" + } + ContractType::FreezeBalanceV2Contract => "FreezeBalanceV2Contract", + ContractType::UnfreezeBalanceV2Contract => { + "UnfreezeBalanceV2Contract" + } + ContractType::WithdrawExpireUnfreezeContract => { + "WithdrawExpireUnfreezeContract" + } + ContractType::DelegateResourceContract => "DelegateResourceContract", + ContractType::UnDelegateResourceContract => { + "UnDelegateResourceContract" + } + ContractType::CancelAllUnfreezeV2Contract => { + "CancelAllUnfreezeV2Contract" + } + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "AccountCreateContract" => Some(Self::AccountCreateContract), + "TransferContract" => Some(Self::TransferContract), + "TransferAssetContract" => Some(Self::TransferAssetContract), + "VoteAssetContract" => Some(Self::VoteAssetContract), + "VoteWitnessContract" => Some(Self::VoteWitnessContract), + "WitnessCreateContract" => Some(Self::WitnessCreateContract), + "AssetIssueContract" => Some(Self::AssetIssueContract), + "WitnessUpdateContract" => Some(Self::WitnessUpdateContract), + "ParticipateAssetIssueContract" => { + Some(Self::ParticipateAssetIssueContract) + } + "AccountUpdateContract" => Some(Self::AccountUpdateContract), + "FreezeBalanceContract" => Some(Self::FreezeBalanceContract), + "UnfreezeBalanceContract" => Some(Self::UnfreezeBalanceContract), + "WithdrawBalanceContract" => Some(Self::WithdrawBalanceContract), + "UnfreezeAssetContract" => Some(Self::UnfreezeAssetContract), + "UpdateAssetContract" => Some(Self::UpdateAssetContract), + "ProposalCreateContract" => Some(Self::ProposalCreateContract), + "ProposalApproveContract" => Some(Self::ProposalApproveContract), + "ProposalDeleteContract" => Some(Self::ProposalDeleteContract), + "SetAccountIdContract" => Some(Self::SetAccountIdContract), + "CustomContract" => Some(Self::CustomContract), + "CreateSmartContract" => Some(Self::CreateSmartContract), + "TriggerSmartContract" => Some(Self::TriggerSmartContract), + "GetContract" => Some(Self::GetContract), + "UpdateSettingContract" => Some(Self::UpdateSettingContract), + "ExchangeCreateContract" => Some(Self::ExchangeCreateContract), + "ExchangeInjectContract" => Some(Self::ExchangeInjectContract), + "ExchangeWithdrawContract" => Some(Self::ExchangeWithdrawContract), + "ExchangeTransactionContract" => { + Some(Self::ExchangeTransactionContract) + } + "UpdateEnergyLimitContract" => Some(Self::UpdateEnergyLimitContract), + "AccountPermissionUpdateContract" => { + Some(Self::AccountPermissionUpdateContract) + } + "ClearABIContract" => Some(Self::ClearAbiContract), + "UpdateBrokerageContract" => Some(Self::UpdateBrokerageContract), + "ShieldedTransferContract" => Some(Self::ShieldedTransferContract), + "MarketSellAssetContract" => Some(Self::MarketSellAssetContract), + "MarketCancelOrderContract" => Some(Self::MarketCancelOrderContract), + "FreezeBalanceV2Contract" => Some(Self::FreezeBalanceV2Contract), + "UnfreezeBalanceV2Contract" => Some(Self::UnfreezeBalanceV2Contract), + "WithdrawExpireUnfreezeContract" => { + Some(Self::WithdrawExpireUnfreezeContract) + } + "DelegateResourceContract" => Some(Self::DelegateResourceContract), + "UnDelegateResourceContract" => { + Some(Self::UnDelegateResourceContract) + } + "CancelAllUnfreezeV2Contract" => { + Some(Self::CancelAllUnfreezeV2Contract) + } + _ => None, + } + } + } + } + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct Result { + #[prost(int64, tag = "1")] + pub fee: i64, + #[prost(enumeration = "result::Code", tag = "2")] + pub ret: i32, + #[prost(enumeration = "result::ContractResult", tag = "3")] + pub contract_ret: i32, + #[prost(string, tag = "14")] + pub asset_issue_id: ::prost::alloc::string::String, + #[prost(int64, tag = "15")] + pub withdraw_amount: i64, + #[prost(int64, tag = "16")] + pub unfreeze_amount: i64, + #[prost(int64, tag = "18")] + pub exchange_received_amount: i64, + #[prost(int64, tag = "19")] + pub exchange_inject_another_amount: i64, + #[prost(int64, tag = "20")] + pub exchange_withdraw_another_amount: i64, + #[prost(int64, tag = "21")] + pub exchange_id: i64, + #[prost(int64, tag = "22")] + pub shielded_transaction_fee: i64, + #[prost(bytes = "vec", tag = "25")] + pub order_id: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "26")] + pub order_details: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "27")] + pub withdraw_expire_amount: i64, + #[prost(btree_map = "string, int64", tag = "28")] + pub cancel_unfreeze_v2_amount: ::prost::alloc::collections::BTreeMap< + ::prost::alloc::string::String, + i64, + >, + } + /// Nested message and enum types in `Result`. + pub mod result { + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] + #[repr(i32)] + pub enum Code { + Sucess = 0, + Failed = 1, + } + impl Code { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Code::Sucess => "SUCESS", + Code::Failed => "FAILED", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "SUCESS" => Some(Self::Sucess), + "FAILED" => Some(Self::Failed), + _ => None, + } + } + } + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] + #[repr(i32)] + pub enum ContractResult { + Default = 0, + Success = 1, + Revert = 2, + BadJumpDestination = 3, + OutOfMemory = 4, + PrecompiledContract = 5, + StackTooSmall = 6, + StackTooLarge = 7, + IllegalOperation = 8, + StackOverflow = 9, + OutOfEnergy = 10, + OutOfTime = 11, + JvmStackOverFlow = 12, + Unknown = 13, + TransferFailed = 14, + InvalidCode = 15, + } + impl ContractResult { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + ContractResult::Default => "DEFAULT", + ContractResult::Success => "SUCCESS", + ContractResult::Revert => "REVERT", + ContractResult::BadJumpDestination => "BAD_JUMP_DESTINATION", + ContractResult::OutOfMemory => "OUT_OF_MEMORY", + ContractResult::PrecompiledContract => "PRECOMPILED_CONTRACT", + ContractResult::StackTooSmall => "STACK_TOO_SMALL", + ContractResult::StackTooLarge => "STACK_TOO_LARGE", + ContractResult::IllegalOperation => "ILLEGAL_OPERATION", + ContractResult::StackOverflow => "STACK_OVERFLOW", + ContractResult::OutOfEnergy => "OUT_OF_ENERGY", + ContractResult::OutOfTime => "OUT_OF_TIME", + ContractResult::JvmStackOverFlow => "JVM_STACK_OVER_FLOW", + ContractResult::Unknown => "UNKNOWN", + ContractResult::TransferFailed => "TRANSFER_FAILED", + ContractResult::InvalidCode => "INVALID_CODE", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "DEFAULT" => Some(Self::Default), + "SUCCESS" => Some(Self::Success), + "REVERT" => Some(Self::Revert), + "BAD_JUMP_DESTINATION" => Some(Self::BadJumpDestination), + "OUT_OF_MEMORY" => Some(Self::OutOfMemory), + "PRECOMPILED_CONTRACT" => Some(Self::PrecompiledContract), + "STACK_TOO_SMALL" => Some(Self::StackTooSmall), + "STACK_TOO_LARGE" => Some(Self::StackTooLarge), + "ILLEGAL_OPERATION" => Some(Self::IllegalOperation), + "STACK_OVERFLOW" => Some(Self::StackOverflow), + "OUT_OF_ENERGY" => Some(Self::OutOfEnergy), + "OUT_OF_TIME" => Some(Self::OutOfTime), + "JVM_STACK_OVER_FLOW" => Some(Self::JvmStackOverFlow), + "UNKNOWN" => Some(Self::Unknown), + "TRANSFER_FAILED" => Some(Self::TransferFailed), + "INVALID_CODE" => Some(Self::InvalidCode), + _ => None, + } + } + } + } + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct Raw { + #[prost(bytes = "vec", tag = "1")] + pub ref_block_bytes: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "3")] + pub ref_block_num: i64, + #[prost(bytes = "vec", tag = "4")] + pub ref_block_hash: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "8")] + pub expiration: i64, + #[prost(message, repeated, tag = "9")] + pub auths: ::prost::alloc::vec::Vec, + /// data not used + #[prost(bytes = "vec", tag = "10")] + pub data: ::prost::alloc::vec::Vec, + /// only support size = 1, repeated list here for extension + #[prost(message, repeated, tag = "11")] + pub contract: ::prost::alloc::vec::Vec, + /// scripts not used + #[prost(bytes = "vec", tag = "12")] + pub scripts: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "14")] + pub timestamp: i64, + #[prost(int64, tag = "18")] + pub fee_limit: i64, + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct TransactionInfo { + #[prost(bytes = "vec", tag = "1")] + pub id: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "2")] + pub fee: i64, + #[prost(int64, tag = "3")] + pub block_number: i64, + #[prost(int64, tag = "4")] + pub block_time_stamp: i64, + #[prost(bytes = "vec", repeated, tag = "5")] + pub contract_result: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec>, + #[prost(bytes = "vec", tag = "6")] + pub contract_address: ::prost::alloc::vec::Vec, + #[prost(message, optional, tag = "7")] + pub receipt: ::core::option::Option, + #[prost(message, repeated, tag = "8")] + pub log: ::prost::alloc::vec::Vec, + #[prost(enumeration = "transaction_info::Code", tag = "9")] + pub result: i32, + #[prost(bytes = "vec", tag = "10")] + pub res_message: ::prost::alloc::vec::Vec, + #[prost(string, tag = "14")] + pub asset_issue_id: ::prost::alloc::string::String, + #[prost(int64, tag = "15")] + pub withdraw_amount: i64, + #[prost(int64, tag = "16")] + pub unfreeze_amount: i64, + #[prost(message, repeated, tag = "17")] + pub internal_transactions: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "18")] + pub exchange_received_amount: i64, + #[prost(int64, tag = "19")] + pub exchange_inject_another_amount: i64, + #[prost(int64, tag = "20")] + pub exchange_withdraw_another_amount: i64, + #[prost(int64, tag = "21")] + pub exchange_id: i64, + #[prost(int64, tag = "22")] + pub shielded_transaction_fee: i64, + #[prost(bytes = "vec", tag = "25")] + pub order_id: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "26")] + pub order_details: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "27")] + pub packing_fee: i64, + #[prost(int64, tag = "28")] + pub withdraw_expire_amount: i64, + #[prost(btree_map = "string, int64", tag = "29")] + pub cancel_unfreeze_v2_amount: ::prost::alloc::collections::BTreeMap< + ::prost::alloc::string::String, + i64, + >, +} +/// Nested message and enum types in `TransactionInfo`. +pub mod transaction_info { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct Log { + #[prost(bytes = "vec", tag = "1")] + pub address: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", repeated, tag = "2")] + pub topics: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec>, + #[prost(bytes = "vec", tag = "3")] + pub data: ::prost::alloc::vec::Vec, + } + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] + #[repr(i32)] + pub enum Code { + Sucess = 0, + Failed = 1, + } + impl Code { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Code::Sucess => "SUCESS", + Code::Failed => "FAILED", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "SUCESS" => Some(Self::Sucess), + "FAILED" => Some(Self::Failed), + _ => None, + } + } + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct TransactionRet { + #[prost(int64, tag = "1")] + pub block_number: i64, + #[prost(int64, tag = "2")] + pub block_time_stamp: i64, + #[prost(message, repeated, tag = "3")] + pub transactioninfo: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Transactions { + #[prost(message, repeated, tag = "1")] + pub transactions: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BlockHeader { + #[prost(message, optional, tag = "1")] + pub raw_data: ::core::option::Option, + #[prost(bytes = "vec", tag = "2")] + pub witness_signature: ::prost::alloc::vec::Vec, +} +/// Nested message and enum types in `BlockHeader`. +pub mod block_header { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct Raw { + #[prost(int64, tag = "1")] + pub timestamp: i64, + #[prost(bytes = "vec", tag = "2")] + pub tx_trie_root: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "3")] + pub parent_hash: ::prost::alloc::vec::Vec, + /// bytes nonce = 5; + /// bytes difficulty = 6; + #[prost(int64, tag = "7")] + pub number: i64, + #[prost(int64, tag = "8")] + pub witness_id: i64, + #[prost(bytes = "vec", tag = "9")] + pub witness_address: ::prost::alloc::vec::Vec, + #[prost(int32, tag = "10")] + pub version: i32, + #[prost(bytes = "vec", tag = "11")] + pub account_state_root: ::prost::alloc::vec::Vec, + } +} +/// block +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Block { + #[prost(message, repeated, tag = "1")] + pub transactions: ::prost::alloc::vec::Vec, + #[prost(message, optional, tag = "2")] + pub block_header: ::core::option::Option, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ChainInventory { + #[prost(message, repeated, tag = "1")] + pub ids: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "2")] + pub remain_num: i64, +} +/// Nested message and enum types in `ChainInventory`. +pub mod chain_inventory { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct BlockId { + #[prost(bytes = "vec", tag = "1")] + pub hash: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "2")] + pub number: i64, + } +} +/// Inventory +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BlockInventory { + #[prost(message, repeated, tag = "1")] + pub ids: ::prost::alloc::vec::Vec, + #[prost(enumeration = "block_inventory::Type", tag = "2")] + pub r#type: i32, +} +/// Nested message and enum types in `BlockInventory`. +pub mod block_inventory { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct BlockId { + #[prost(bytes = "vec", tag = "1")] + pub hash: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "2")] + pub number: i64, + } + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] + #[repr(i32)] + pub enum Type { + Sync = 0, + Advtise = 1, + Fetch = 2, + } + impl Type { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Type::Sync => "SYNC", + Type::Advtise => "ADVTISE", + Type::Fetch => "FETCH", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "SYNC" => Some(Self::Sync), + "ADVTISE" => Some(Self::Advtise), + "FETCH" => Some(Self::Fetch), + _ => None, + } + } + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Inventory { + #[prost(enumeration = "inventory::InventoryType", tag = "1")] + pub r#type: i32, + #[prost(bytes = "vec", repeated, tag = "2")] + pub ids: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec>, +} +/// Nested message and enum types in `Inventory`. +pub mod inventory { + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] + #[repr(i32)] + pub enum InventoryType { + Trx = 0, + Block = 1, + } + impl InventoryType { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + InventoryType::Trx => "TRX", + InventoryType::Block => "BLOCK", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "TRX" => Some(Self::Trx), + "BLOCK" => Some(Self::Block), + _ => None, + } + } + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Items { + #[prost(enumeration = "items::ItemType", tag = "1")] + pub r#type: i32, + #[prost(message, repeated, tag = "2")] + pub blocks: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "3")] + pub block_headers: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "4")] + pub transactions: ::prost::alloc::vec::Vec, +} +/// Nested message and enum types in `Items`. +pub mod items { + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] + #[repr(i32)] + pub enum ItemType { + Err = 0, + Trx = 1, + Block = 2, + Blockheader = 3, + } + impl ItemType { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + ItemType::Err => "ERR", + ItemType::Trx => "TRX", + ItemType::Block => "BLOCK", + ItemType::Blockheader => "BLOCKHEADER", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "ERR" => Some(Self::Err), + "TRX" => Some(Self::Trx), + "BLOCK" => Some(Self::Block), + "BLOCKHEADER" => Some(Self::Blockheader), + _ => None, + } + } + } +} +/// DynamicProperties +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct DynamicProperties { + #[prost(int64, tag = "1")] + pub last_solidity_block_num: i64, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct DisconnectMessage { + #[prost(enumeration = "ReasonCode", tag = "1")] + pub reason: i32, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct HelloMessage { + #[prost(message, optional, tag = "1")] + pub from: ::core::option::Option, + #[prost(int32, tag = "2")] + pub version: i32, + #[prost(int64, tag = "3")] + pub timestamp: i64, + #[prost(message, optional, tag = "4")] + pub genesis_block_id: ::core::option::Option, + #[prost(message, optional, tag = "5")] + pub solid_block_id: ::core::option::Option, + #[prost(message, optional, tag = "6")] + pub head_block_id: ::core::option::Option, + #[prost(bytes = "vec", tag = "7")] + pub address: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "8")] + pub signature: ::prost::alloc::vec::Vec, + #[prost(int32, tag = "9")] + pub node_type: i32, + #[prost(int64, tag = "10")] + pub lowest_block_num: i64, +} +/// Nested message and enum types in `HelloMessage`. +pub mod hello_message { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct BlockId { + #[prost(bytes = "vec", tag = "1")] + pub hash: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "2")] + pub number: i64, + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct InternalTransaction { + /// internalTransaction identity, the root InternalTransaction hash + /// should equals to root transaction id. + #[prost(bytes = "vec", tag = "1")] + pub hash: ::prost::alloc::vec::Vec, + /// the one send trx (TBD: or token) via function + #[prost(bytes = "vec", tag = "2")] + pub caller_address: ::prost::alloc::vec::Vec, + /// the one recieve trx (TBD: or token) via function + #[prost(bytes = "vec", tag = "3")] + pub transfer_to_address: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "4")] + pub call_value_info: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "5")] + pub note: ::prost::alloc::vec::Vec, + #[prost(bool, tag = "6")] + pub rejected: bool, + #[prost(string, tag = "7")] + pub extra: ::prost::alloc::string::String, +} +/// Nested message and enum types in `InternalTransaction`. +pub mod internal_transaction { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct CallValueInfo { + /// trx (TBD: or token) value + #[prost(int64, tag = "1")] + pub call_value: i64, + /// TBD: tokenName, trx should be empty + #[prost(string, tag = "2")] + pub token_id: ::prost::alloc::string::String, + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct DelegatedResourceAccountIndex { + #[prost(bytes = "vec", tag = "1")] + pub account: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", repeated, tag = "2")] + pub from_accounts: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec>, + #[prost(bytes = "vec", repeated, tag = "3")] + pub to_accounts: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec>, + #[prost(int64, tag = "4")] + pub timestamp: i64, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct NodeInfo { + #[prost(int64, tag = "1")] + pub begin_sync_num: i64, + #[prost(string, tag = "2")] + pub block: ::prost::alloc::string::String, + #[prost(string, tag = "3")] + pub solidity_block: ::prost::alloc::string::String, + /// connect information + #[prost(int32, tag = "4")] + pub current_connect_count: i32, + #[prost(int32, tag = "5")] + pub active_connect_count: i32, + #[prost(int32, tag = "6")] + pub passive_connect_count: i32, + #[prost(int64, tag = "7")] + pub total_flow: i64, + #[prost(message, repeated, tag = "8")] + pub peer_info_list: ::prost::alloc::vec::Vec, + #[prost(message, optional, tag = "9")] + pub config_node_info: ::core::option::Option, + #[prost(message, optional, tag = "10")] + pub machine_info: ::core::option::Option, + #[prost(btree_map = "string, string", tag = "11")] + pub cheat_witness_info_map: ::prost::alloc::collections::BTreeMap< + ::prost::alloc::string::String, + ::prost::alloc::string::String, + >, +} +/// Nested message and enum types in `NodeInfo`. +pub mod node_info { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct PeerInfo { + #[prost(string, tag = "1")] + pub last_sync_block: ::prost::alloc::string::String, + #[prost(int64, tag = "2")] + pub remain_num: i64, + #[prost(int64, tag = "3")] + pub last_block_update_time: i64, + #[prost(bool, tag = "4")] + pub sync_flag: bool, + #[prost(int64, tag = "5")] + pub head_block_time_we_both_have: i64, + #[prost(bool, tag = "6")] + pub need_sync_from_peer: bool, + #[prost(bool, tag = "7")] + pub need_sync_from_us: bool, + #[prost(string, tag = "8")] + pub host: ::prost::alloc::string::String, + #[prost(int32, tag = "9")] + pub port: i32, + #[prost(string, tag = "10")] + pub node_id: ::prost::alloc::string::String, + #[prost(int64, tag = "11")] + pub connect_time: i64, + #[prost(double, tag = "12")] + pub avg_latency: f64, + #[prost(int32, tag = "13")] + pub sync_to_fetch_size: i32, + #[prost(int64, tag = "14")] + pub sync_to_fetch_size_peek_num: i64, + #[prost(int32, tag = "15")] + pub sync_block_requested_size: i32, + #[prost(int64, tag = "16")] + pub un_fetch_syn_num: i64, + #[prost(int32, tag = "17")] + pub block_in_porc_size: i32, + #[prost(string, tag = "18")] + pub head_block_we_both_have: ::prost::alloc::string::String, + #[prost(bool, tag = "19")] + pub is_active: bool, + #[prost(int32, tag = "20")] + pub score: i32, + #[prost(int32, tag = "21")] + pub node_count: i32, + #[prost(int64, tag = "22")] + pub in_flow: i64, + #[prost(int32, tag = "23")] + pub disconnect_times: i32, + #[prost(string, tag = "24")] + pub local_disconnect_reason: ::prost::alloc::string::String, + #[prost(string, tag = "25")] + pub remote_disconnect_reason: ::prost::alloc::string::String, + } + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct ConfigNodeInfo { + #[prost(string, tag = "1")] + pub code_version: ::prost::alloc::string::String, + #[prost(string, tag = "2")] + pub p2p_version: ::prost::alloc::string::String, + #[prost(int32, tag = "3")] + pub listen_port: i32, + #[prost(bool, tag = "4")] + pub discover_enable: bool, + #[prost(int32, tag = "5")] + pub active_node_size: i32, + #[prost(int32, tag = "6")] + pub passive_node_size: i32, + #[prost(int32, tag = "7")] + pub send_node_size: i32, + #[prost(int32, tag = "8")] + pub max_connect_count: i32, + #[prost(int32, tag = "9")] + pub same_ip_max_connect_count: i32, + #[prost(int32, tag = "10")] + pub backup_listen_port: i32, + #[prost(int32, tag = "11")] + pub backup_member_size: i32, + #[prost(int32, tag = "12")] + pub backup_priority: i32, + #[prost(int32, tag = "13")] + pub db_version: i32, + #[prost(int32, tag = "14")] + pub min_participation_rate: i32, + #[prost(bool, tag = "15")] + pub support_constant: bool, + #[prost(double, tag = "16")] + pub min_time_ratio: f64, + #[prost(double, tag = "17")] + pub max_time_ratio: f64, + #[prost(int64, tag = "18")] + pub allow_creation_of_contracts: i64, + #[prost(int64, tag = "19")] + pub allow_adaptive_energy: i64, + } + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct MachineInfo { + #[prost(int32, tag = "1")] + pub thread_count: i32, + #[prost(int32, tag = "2")] + pub dead_lock_thread_count: i32, + #[prost(int32, tag = "3")] + pub cpu_count: i32, + #[prost(int64, tag = "4")] + pub total_memory: i64, + #[prost(int64, tag = "5")] + pub free_memory: i64, + #[prost(double, tag = "6")] + pub cpu_rate: f64, + #[prost(string, tag = "7")] + pub java_version: ::prost::alloc::string::String, + #[prost(string, tag = "8")] + pub os_name: ::prost::alloc::string::String, + #[prost(int64, tag = "9")] + pub jvm_total_memory: i64, + #[prost(int64, tag = "10")] + pub jvm_free_memory: i64, + #[prost(double, tag = "11")] + pub process_cpu_rate: f64, + #[prost(message, repeated, tag = "12")] + pub memory_desc_info_list: ::prost::alloc::vec::Vec< + machine_info::MemoryDescInfo, + >, + #[prost(message, repeated, tag = "13")] + pub dead_lock_thread_info_list: ::prost::alloc::vec::Vec< + machine_info::DeadLockThreadInfo, + >, + } + /// Nested message and enum types in `MachineInfo`. + pub mod machine_info { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct MemoryDescInfo { + #[prost(string, tag = "1")] + pub name: ::prost::alloc::string::String, + #[prost(int64, tag = "2")] + pub init_size: i64, + #[prost(int64, tag = "3")] + pub use_size: i64, + #[prost(int64, tag = "4")] + pub max_size: i64, + #[prost(double, tag = "5")] + pub use_rate: f64, + } + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct DeadLockThreadInfo { + #[prost(string, tag = "1")] + pub name: ::prost::alloc::string::String, + #[prost(string, tag = "2")] + pub lock_name: ::prost::alloc::string::String, + #[prost(string, tag = "3")] + pub lock_owner: ::prost::alloc::string::String, + #[prost(string, tag = "4")] + pub state: ::prost::alloc::string::String, + #[prost(int64, tag = "5")] + pub block_time: i64, + #[prost(int64, tag = "6")] + pub wait_time: i64, + #[prost(string, tag = "7")] + pub stack_trace: ::prost::alloc::string::String, + } + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MetricsInfo { + #[prost(int64, tag = "1")] + pub interval: i64, + #[prost(message, optional, tag = "2")] + pub node: ::core::option::Option, + #[prost(message, optional, tag = "3")] + pub blockchain: ::core::option::Option, + #[prost(message, optional, tag = "4")] + pub net: ::core::option::Option, +} +/// Nested message and enum types in `MetricsInfo`. +pub mod metrics_info { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct NodeInfo { + #[prost(string, tag = "1")] + pub ip: ::prost::alloc::string::String, + #[prost(int32, tag = "2")] + pub node_type: i32, + #[prost(string, tag = "3")] + pub version: ::prost::alloc::string::String, + #[prost(int32, tag = "4")] + pub backup_status: i32, + } + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct BlockChainInfo { + #[prost(int64, tag = "1")] + pub head_block_num: i64, + #[prost(int64, tag = "2")] + pub head_block_timestamp: i64, + #[prost(string, tag = "3")] + pub head_block_hash: ::prost::alloc::string::String, + #[prost(int32, tag = "4")] + pub fork_count: i32, + #[prost(int32, tag = "5")] + pub fail_fork_count: i32, + #[prost(message, optional, tag = "6")] + pub block_process_time: ::core::option::Option, + #[prost(message, optional, tag = "7")] + pub tps: ::core::option::Option, + #[prost(int32, tag = "8")] + pub transaction_cache_size: i32, + #[prost(message, optional, tag = "9")] + pub missed_transaction: ::core::option::Option, + #[prost(message, repeated, tag = "10")] + pub witnesses: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "11")] + pub fail_process_block_num: i64, + #[prost(string, tag = "12")] + pub fail_process_block_reason: ::prost::alloc::string::String, + #[prost(message, repeated, tag = "13")] + pub dup_witness: ::prost::alloc::vec::Vec, + } + /// Nested message and enum types in `BlockChainInfo`. + pub mod block_chain_info { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct Witness { + #[prost(string, tag = "1")] + pub address: ::prost::alloc::string::String, + #[prost(int32, tag = "2")] + pub version: i32, + } + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct DupWitness { + #[prost(string, tag = "1")] + pub address: ::prost::alloc::string::String, + #[prost(int64, tag = "2")] + pub block_num: i64, + #[prost(int32, tag = "3")] + pub count: i32, + } + } + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct RateInfo { + #[prost(int64, tag = "1")] + pub count: i64, + #[prost(double, tag = "2")] + pub mean_rate: f64, + #[prost(double, tag = "3")] + pub one_minute_rate: f64, + #[prost(double, tag = "4")] + pub five_minute_rate: f64, + #[prost(double, tag = "5")] + pub fifteen_minute_rate: f64, + } + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct NetInfo { + #[prost(int32, tag = "1")] + pub error_proto_count: i32, + #[prost(message, optional, tag = "2")] + pub api: ::core::option::Option, + #[prost(int32, tag = "3")] + pub connection_count: i32, + #[prost(int32, tag = "4")] + pub valid_connection_count: i32, + #[prost(message, optional, tag = "5")] + pub tcp_in_traffic: ::core::option::Option, + #[prost(message, optional, tag = "6")] + pub tcp_out_traffic: ::core::option::Option, + #[prost(int32, tag = "7")] + pub disconnection_count: i32, + #[prost(message, repeated, tag = "8")] + pub disconnection_detail: ::prost::alloc::vec::Vec< + net_info::DisconnectionDetailInfo, + >, + #[prost(message, optional, tag = "9")] + pub udp_in_traffic: ::core::option::Option, + #[prost(message, optional, tag = "10")] + pub udp_out_traffic: ::core::option::Option, + #[prost(message, optional, tag = "11")] + pub latency: ::core::option::Option, + } + /// Nested message and enum types in `NetInfo`. + pub mod net_info { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct ApiInfo { + #[prost(message, optional, tag = "1")] + pub qps: ::core::option::Option, + #[prost(message, optional, tag = "2")] + pub fail_qps: ::core::option::Option, + #[prost(message, optional, tag = "3")] + pub out_traffic: ::core::option::Option, + #[prost(message, repeated, tag = "4")] + pub detail: ::prost::alloc::vec::Vec, + } + /// Nested message and enum types in `ApiInfo`. + pub mod api_info { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct ApiDetailInfo { + #[prost(string, tag = "1")] + pub name: ::prost::alloc::string::String, + #[prost(message, optional, tag = "2")] + pub qps: ::core::option::Option, + #[prost(message, optional, tag = "3")] + pub fail_qps: ::core::option::Option, + #[prost(message, optional, tag = "4")] + pub out_traffic: ::core::option::Option, + } + } + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct DisconnectionDetailInfo { + #[prost(string, tag = "1")] + pub reason: ::prost::alloc::string::String, + #[prost(int32, tag = "2")] + pub count: i32, + } + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct LatencyInfo { + #[prost(int32, tag = "1")] + pub top99: i32, + #[prost(int32, tag = "2")] + pub top95: i32, + #[prost(int32, tag = "3")] + pub top75: i32, + #[prost(int32, tag = "4")] + pub total_count: i32, + #[prost(int32, tag = "5")] + pub delay1_s: i32, + #[prost(int32, tag = "6")] + pub delay2_s: i32, + #[prost(int32, tag = "7")] + pub delay3_s: i32, + #[prost(message, repeated, tag = "8")] + pub detail: ::prost::alloc::vec::Vec, + } + /// Nested message and enum types in `LatencyInfo`. + pub mod latency_info { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct LatencyDetailInfo { + #[prost(string, tag = "1")] + pub witness: ::prost::alloc::string::String, + #[prost(int32, tag = "2")] + pub top99: i32, + #[prost(int32, tag = "3")] + pub top95: i32, + #[prost(int32, tag = "4")] + pub top75: i32, + #[prost(int32, tag = "5")] + pub count: i32, + #[prost(int32, tag = "6")] + pub delay1_s: i32, + #[prost(int32, tag = "7")] + pub delay2_s: i32, + #[prost(int32, tag = "8")] + pub delay3_s: i32, + } + } + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct PbftMessage { + #[prost(message, optional, tag = "1")] + pub raw_data: ::core::option::Option, + #[prost(bytes = "vec", tag = "2")] + pub signature: ::prost::alloc::vec::Vec, +} +/// Nested message and enum types in `PBFTMessage`. +pub mod pbft_message { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct Raw { + #[prost(enumeration = "MsgType", tag = "1")] + pub msg_type: i32, + #[prost(enumeration = "DataType", tag = "2")] + pub data_type: i32, + #[prost(int64, tag = "3")] + pub view_n: i64, + #[prost(int64, tag = "4")] + pub epoch: i64, + #[prost(bytes = "vec", tag = "5")] + pub data: ::prost::alloc::vec::Vec, + } + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] + #[repr(i32)] + pub enum MsgType { + ViewChange = 0, + Request = 1, + Preprepare = 2, + Prepare = 3, + Commit = 4, + } + impl MsgType { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + MsgType::ViewChange => "VIEW_CHANGE", + MsgType::Request => "REQUEST", + MsgType::Preprepare => "PREPREPARE", + MsgType::Prepare => "PREPARE", + MsgType::Commit => "COMMIT", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "VIEW_CHANGE" => Some(Self::ViewChange), + "REQUEST" => Some(Self::Request), + "PREPREPARE" => Some(Self::Preprepare), + "PREPARE" => Some(Self::Prepare), + "COMMIT" => Some(Self::Commit), + _ => None, + } + } + } + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] + #[repr(i32)] + pub enum DataType { + Block = 0, + Srl = 1, + } + impl DataType { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + DataType::Block => "BLOCK", + DataType::Srl => "SRL", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "BLOCK" => Some(Self::Block), + "SRL" => Some(Self::Srl), + _ => None, + } + } + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct PbftCommitResult { + #[prost(bytes = "vec", tag = "1")] + pub data: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", repeated, tag = "2")] + pub signature: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec>, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Srl { + #[prost(bytes = "vec", repeated, tag = "1")] + pub sr_address: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec>, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum AccountType { + Normal = 0, + AssetIssue = 1, + Contract = 2, +} +impl AccountType { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + AccountType::Normal => "Normal", + AccountType::AssetIssue => "AssetIssue", + AccountType::Contract => "Contract", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "Normal" => Some(Self::Normal), + "AssetIssue" => Some(Self::AssetIssue), + "Contract" => Some(Self::Contract), + _ => None, + } + } +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum ReasonCode { + Requested = 0, + BadProtocol = 2, + TooManyPeers = 4, + DuplicatePeer = 5, + IncompatibleProtocol = 6, + RandomElimination = 7, + PeerQuiting = 8, + UnexpectedIdentity = 9, + LocalIdentity = 10, + PingTimeout = 11, + UserReason = 16, + Reset = 17, + SyncFail = 18, + FetchFail = 19, + BadTx = 20, + BadBlock = 21, + Forked = 22, + Unlinkable = 23, + IncompatibleVersion = 24, + IncompatibleChain = 25, + TimeOut = 32, + ConnectFail = 33, + TooManyPeersWithSameIp = 34, + LightNodeSyncFail = 35, + BelowThanMe = 36, + NotWitness = 37, + NoSuchMessage = 38, + Unknown = 255, +} +impl ReasonCode { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + ReasonCode::Requested => "REQUESTED", + ReasonCode::BadProtocol => "BAD_PROTOCOL", + ReasonCode::TooManyPeers => "TOO_MANY_PEERS", + ReasonCode::DuplicatePeer => "DUPLICATE_PEER", + ReasonCode::IncompatibleProtocol => "INCOMPATIBLE_PROTOCOL", + ReasonCode::RandomElimination => "RANDOM_ELIMINATION", + ReasonCode::PeerQuiting => "PEER_QUITING", + ReasonCode::UnexpectedIdentity => "UNEXPECTED_IDENTITY", + ReasonCode::LocalIdentity => "LOCAL_IDENTITY", + ReasonCode::PingTimeout => "PING_TIMEOUT", + ReasonCode::UserReason => "USER_REASON", + ReasonCode::Reset => "RESET", + ReasonCode::SyncFail => "SYNC_FAIL", + ReasonCode::FetchFail => "FETCH_FAIL", + ReasonCode::BadTx => "BAD_TX", + ReasonCode::BadBlock => "BAD_BLOCK", + ReasonCode::Forked => "FORKED", + ReasonCode::Unlinkable => "UNLINKABLE", + ReasonCode::IncompatibleVersion => "INCOMPATIBLE_VERSION", + ReasonCode::IncompatibleChain => "INCOMPATIBLE_CHAIN", + ReasonCode::TimeOut => "TIME_OUT", + ReasonCode::ConnectFail => "CONNECT_FAIL", + ReasonCode::TooManyPeersWithSameIp => "TOO_MANY_PEERS_WITH_SAME_IP", + ReasonCode::LightNodeSyncFail => "LIGHT_NODE_SYNC_FAIL", + ReasonCode::BelowThanMe => "BELOW_THAN_ME", + ReasonCode::NotWitness => "NOT_WITNESS", + ReasonCode::NoSuchMessage => "NO_SUCH_MESSAGE", + ReasonCode::Unknown => "UNKNOWN", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "REQUESTED" => Some(Self::Requested), + "BAD_PROTOCOL" => Some(Self::BadProtocol), + "TOO_MANY_PEERS" => Some(Self::TooManyPeers), + "DUPLICATE_PEER" => Some(Self::DuplicatePeer), + "INCOMPATIBLE_PROTOCOL" => Some(Self::IncompatibleProtocol), + "RANDOM_ELIMINATION" => Some(Self::RandomElimination), + "PEER_QUITING" => Some(Self::PeerQuiting), + "UNEXPECTED_IDENTITY" => Some(Self::UnexpectedIdentity), + "LOCAL_IDENTITY" => Some(Self::LocalIdentity), + "PING_TIMEOUT" => Some(Self::PingTimeout), + "USER_REASON" => Some(Self::UserReason), + "RESET" => Some(Self::Reset), + "SYNC_FAIL" => Some(Self::SyncFail), + "FETCH_FAIL" => Some(Self::FetchFail), + "BAD_TX" => Some(Self::BadTx), + "BAD_BLOCK" => Some(Self::BadBlock), + "FORKED" => Some(Self::Forked), + "UNLINKABLE" => Some(Self::Unlinkable), + "INCOMPATIBLE_VERSION" => Some(Self::IncompatibleVersion), + "INCOMPATIBLE_CHAIN" => Some(Self::IncompatibleChain), + "TIME_OUT" => Some(Self::TimeOut), + "CONNECT_FAIL" => Some(Self::ConnectFail), + "TOO_MANY_PEERS_WITH_SAME_IP" => Some(Self::TooManyPeersWithSameIp), + "LIGHT_NODE_SYNC_FAIL" => Some(Self::LightNodeSyncFail), + "BELOW_THAN_ME" => Some(Self::BelowThanMe), + "NOT_WITNESS" => Some(Self::NotWitness), + "NO_SUCH_MESSAGE" => Some(Self::NoSuchMessage), + "UNKNOWN" => Some(Self::Unknown), + _ => None, + } + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct InventoryItems { + #[prost(int32, tag = "1")] + pub r#type: i32, + #[prost(bytes = "vec", repeated, tag = "2")] + pub items: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec>, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct AccountCreateContract { + #[prost(bytes = "vec", tag = "1")] + pub owner_address: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "2")] + pub account_address: ::prost::alloc::vec::Vec, + #[prost(enumeration = "AccountType", tag = "3")] + pub r#type: i32, +} +/// Update account name. Account name is not unique now. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct AccountUpdateContract { + #[prost(bytes = "vec", tag = "1")] + pub account_name: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "2")] + pub owner_address: ::prost::alloc::vec::Vec, +} +/// Set account id if the account has no id. Account id is unique and case insensitive. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SetAccountIdContract { + #[prost(bytes = "vec", tag = "1")] + pub account_id: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "2")] + pub owner_address: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct AccountPermissionUpdateContract { + #[prost(bytes = "vec", tag = "1")] + pub owner_address: ::prost::alloc::vec::Vec, + /// Empty is invalidate + #[prost(message, optional, tag = "2")] + pub owner: ::core::option::Option, + /// Can be empty + #[prost(message, optional, tag = "3")] + pub witness: ::core::option::Option, + /// Empty is invalidate + #[prost(message, repeated, tag = "4")] + pub actives: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct AssetIssueContract { + #[prost(string, tag = "41")] + pub id: ::prost::alloc::string::String, + #[prost(bytes = "vec", tag = "1")] + pub owner_address: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "2")] + pub name: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "3")] + pub abbr: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "4")] + pub total_supply: i64, + #[prost(message, repeated, tag = "5")] + pub frozen_supply: ::prost::alloc::vec::Vec, + #[prost(int32, tag = "6")] + pub trx_num: i32, + #[prost(int32, tag = "7")] + pub precision: i32, + #[prost(int32, tag = "8")] + pub num: i32, + #[prost(int64, tag = "9")] + pub start_time: i64, + #[prost(int64, tag = "10")] + pub end_time: i64, + /// useless + #[prost(int64, tag = "11")] + pub order: i64, + #[prost(int32, tag = "16")] + pub vote_score: i32, + #[prost(bytes = "vec", tag = "20")] + pub description: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "21")] + pub url: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "22")] + pub free_asset_net_limit: i64, + #[prost(int64, tag = "23")] + pub public_free_asset_net_limit: i64, + #[prost(int64, tag = "24")] + pub public_free_asset_net_usage: i64, + #[prost(int64, tag = "25")] + pub public_latest_free_net_time: i64, +} +/// Nested message and enum types in `AssetIssueContract`. +pub mod asset_issue_contract { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct FrozenSupply { + #[prost(int64, tag = "1")] + pub frozen_amount: i64, + #[prost(int64, tag = "2")] + pub frozen_days: i64, + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct TransferAssetContract { + /// this field is token name before the proposal ALLOW_SAME_TOKEN_NAME is active, otherwise it is token id and token is should be in string format. + #[prost(bytes = "vec", tag = "1")] + pub asset_name: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "2")] + pub owner_address: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "3")] + pub to_address: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "4")] + pub amount: i64, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct UnfreezeAssetContract { + #[prost(bytes = "vec", tag = "1")] + pub owner_address: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct UpdateAssetContract { + #[prost(bytes = "vec", tag = "1")] + pub owner_address: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "2")] + pub description: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "3")] + pub url: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "4")] + pub new_limit: i64, + #[prost(int64, tag = "5")] + pub new_public_limit: i64, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ParticipateAssetIssueContract { + #[prost(bytes = "vec", tag = "1")] + pub owner_address: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "2")] + pub to_address: ::prost::alloc::vec::Vec, + /// this field is token name before the proposal ALLOW_SAME_TOKEN_NAME is active, otherwise it is token id and token is should be in string format. + #[prost(bytes = "vec", tag = "3")] + pub asset_name: ::prost::alloc::vec::Vec, + /// the amount of drops + #[prost(int64, tag = "4")] + pub amount: i64, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct FreezeBalanceContract { + #[prost(bytes = "vec", tag = "1")] + pub owner_address: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "2")] + pub frozen_balance: i64, + #[prost(int64, tag = "3")] + pub frozen_duration: i64, + #[prost(enumeration = "ResourceCode", tag = "10")] + pub resource: i32, + #[prost(bytes = "vec", tag = "15")] + pub receiver_address: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct UnfreezeBalanceContract { + #[prost(bytes = "vec", tag = "1")] + pub owner_address: ::prost::alloc::vec::Vec, + #[prost(enumeration = "ResourceCode", tag = "10")] + pub resource: i32, + #[prost(bytes = "vec", tag = "15")] + pub receiver_address: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct WithdrawBalanceContract { + #[prost(bytes = "vec", tag = "1")] + pub owner_address: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct TransferContract { + #[prost(bytes = "vec", tag = "1")] + pub owner_address: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "2")] + pub to_address: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "3")] + pub amount: i64, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct TransactionBalanceTrace { + #[prost(bytes = "vec", tag = "1")] + pub transaction_identifier: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "2")] + pub operation: ::prost::alloc::vec::Vec, + #[prost(string, tag = "3")] + pub r#type: ::prost::alloc::string::String, + #[prost(string, tag = "4")] + pub status: ::prost::alloc::string::String, +} +/// Nested message and enum types in `TransactionBalanceTrace`. +pub mod transaction_balance_trace { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct Operation { + #[prost(int64, tag = "1")] + pub operation_identifier: i64, + #[prost(bytes = "vec", tag = "2")] + pub address: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "3")] + pub amount: i64, + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BlockBalanceTrace { + #[prost(message, optional, tag = "1")] + pub block_identifier: ::core::option::Option, + #[prost(int64, tag = "2")] + pub timestamp: i64, + /// BlockIdentifier parent_block_identifier = 4; + #[prost(message, repeated, tag = "3")] + pub transaction_balance_trace: ::prost::alloc::vec::Vec, +} +/// Nested message and enum types in `BlockBalanceTrace`. +pub mod block_balance_trace { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct BlockIdentifier { + #[prost(bytes = "vec", tag = "1")] + pub hash: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "2")] + pub number: i64, + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct AccountTrace { + #[prost(int64, tag = "1")] + pub balance: i64, + #[prost(int64, tag = "99")] + pub placeholder: i64, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct AccountIdentifier { + #[prost(bytes = "vec", tag = "1")] + pub address: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct AccountBalanceRequest { + #[prost(message, optional, tag = "1")] + pub account_identifier: ::core::option::Option, + #[prost(message, optional, tag = "2")] + pub block_identifier: ::core::option::Option, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct AccountBalanceResponse { + #[prost(int64, tag = "1")] + pub balance: i64, + #[prost(message, optional, tag = "2")] + pub block_identifier: ::core::option::Option, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct FreezeBalanceV2Contract { + #[prost(bytes = "vec", tag = "1")] + pub owner_address: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "2")] + pub frozen_balance: i64, + #[prost(enumeration = "ResourceCode", tag = "3")] + pub resource: i32, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct UnfreezeBalanceV2Contract { + #[prost(bytes = "vec", tag = "1")] + pub owner_address: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "2")] + pub unfreeze_balance: i64, + #[prost(enumeration = "ResourceCode", tag = "3")] + pub resource: i32, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct WithdrawExpireUnfreezeContract { + #[prost(bytes = "vec", tag = "1")] + pub owner_address: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct DelegateResourceContract { + #[prost(bytes = "vec", tag = "1")] + pub owner_address: ::prost::alloc::vec::Vec, + #[prost(enumeration = "ResourceCode", tag = "2")] + pub resource: i32, + #[prost(int64, tag = "3")] + pub balance: i64, + #[prost(bytes = "vec", tag = "4")] + pub receiver_address: ::prost::alloc::vec::Vec, + #[prost(bool, tag = "5")] + pub lock: bool, + #[prost(int64, tag = "6")] + pub lock_period: i64, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct UnDelegateResourceContract { + #[prost(bytes = "vec", tag = "1")] + pub owner_address: ::prost::alloc::vec::Vec, + #[prost(enumeration = "ResourceCode", tag = "2")] + pub resource: i32, + #[prost(int64, tag = "3")] + pub balance: i64, + #[prost(bytes = "vec", tag = "4")] + pub receiver_address: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct CancelAllUnfreezeV2Contract { + #[prost(bytes = "vec", tag = "1")] + pub owner_address: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ExchangeCreateContract { + #[prost(bytes = "vec", tag = "1")] + pub owner_address: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "2")] + pub first_token_id: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "3")] + pub first_token_balance: i64, + #[prost(bytes = "vec", tag = "4")] + pub second_token_id: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "5")] + pub second_token_balance: i64, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ExchangeInjectContract { + #[prost(bytes = "vec", tag = "1")] + pub owner_address: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "2")] + pub exchange_id: i64, + #[prost(bytes = "vec", tag = "3")] + pub token_id: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "4")] + pub quant: i64, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ExchangeWithdrawContract { + #[prost(bytes = "vec", tag = "1")] + pub owner_address: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "2")] + pub exchange_id: i64, + #[prost(bytes = "vec", tag = "3")] + pub token_id: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "4")] + pub quant: i64, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ExchangeTransactionContract { + #[prost(bytes = "vec", tag = "1")] + pub owner_address: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "2")] + pub exchange_id: i64, + #[prost(bytes = "vec", tag = "3")] + pub token_id: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "4")] + pub quant: i64, + #[prost(int64, tag = "5")] + pub expected: i64, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MarketSellAssetContract { + #[prost(bytes = "vec", tag = "1")] + pub owner_address: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "2")] + pub sell_token_id: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "3")] + pub sell_token_quantity: i64, + #[prost(bytes = "vec", tag = "4")] + pub buy_token_id: ::prost::alloc::vec::Vec, + /// min to receive + #[prost(int64, tag = "5")] + pub buy_token_quantity: i64, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MarketCancelOrderContract { + #[prost(bytes = "vec", tag = "1")] + pub owner_address: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "2")] + pub order_id: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ProposalApproveContract { + #[prost(bytes = "vec", tag = "1")] + pub owner_address: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "2")] + pub proposal_id: i64, + /// add or remove approval + #[prost(bool, tag = "3")] + pub is_add_approval: bool, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ProposalCreateContract { + #[prost(bytes = "vec", tag = "1")] + pub owner_address: ::prost::alloc::vec::Vec, + #[prost(btree_map = "int64, int64", tag = "2")] + pub parameters: ::prost::alloc::collections::BTreeMap, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ProposalDeleteContract { + #[prost(bytes = "vec", tag = "1")] + pub owner_address: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "2")] + pub proposal_id: i64, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct AuthenticationPath { + #[prost(bool, repeated, tag = "1")] + pub value: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MerklePath { + #[prost(message, repeated, tag = "1")] + pub authentication_paths: ::prost::alloc::vec::Vec, + #[prost(bool, repeated, tag = "2")] + pub index: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "3")] + pub rt: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct OutputPoint { + #[prost(bytes = "vec", tag = "1")] + pub hash: ::prost::alloc::vec::Vec, + #[prost(int32, tag = "2")] + pub index: i32, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct OutputPointInfo { + #[prost(message, repeated, tag = "1")] + pub out_points: ::prost::alloc::vec::Vec, + #[prost(int32, tag = "2")] + pub block_num: i32, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct PedersenHash { + #[prost(bytes = "vec", tag = "1")] + pub content: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct IncrementalMerkleTree { + #[prost(message, optional, tag = "1")] + pub left: ::core::option::Option, + #[prost(message, optional, tag = "2")] + pub right: ::core::option::Option, + #[prost(message, repeated, tag = "3")] + pub parents: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct IncrementalMerkleVoucher { + #[prost(message, optional, tag = "1")] + pub tree: ::core::option::Option, + #[prost(message, repeated, tag = "2")] + pub filled: ::prost::alloc::vec::Vec, + #[prost(message, optional, tag = "3")] + pub cursor: ::core::option::Option, + #[prost(int64, tag = "4")] + pub cursor_depth: i64, + #[prost(bytes = "vec", tag = "5")] + pub rt: ::prost::alloc::vec::Vec, + #[prost(message, optional, tag = "10")] + pub output_point: ::core::option::Option, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct IncrementalMerkleVoucherInfo { + #[prost(message, repeated, tag = "1")] + pub vouchers: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", repeated, tag = "2")] + pub paths: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec>, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SpendDescription { + #[prost(bytes = "vec", tag = "1")] + pub value_commitment: ::prost::alloc::vec::Vec, + /// merkle root + #[prost(bytes = "vec", tag = "2")] + pub anchor: ::prost::alloc::vec::Vec, + /// used for check double spend + #[prost(bytes = "vec", tag = "3")] + pub nullifier: ::prost::alloc::vec::Vec, + /// used for check spend authority signature + #[prost(bytes = "vec", tag = "4")] + pub rk: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "5")] + pub zkproof: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "6")] + pub spend_authority_signature: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ReceiveDescription { + #[prost(bytes = "vec", tag = "1")] + pub value_commitment: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "2")] + pub note_commitment: ::prost::alloc::vec::Vec, + /// for Encryption + #[prost(bytes = "vec", tag = "3")] + pub epk: ::prost::alloc::vec::Vec, + /// Encryption for incoming, decrypt it with ivk + #[prost(bytes = "vec", tag = "4")] + pub c_enc: ::prost::alloc::vec::Vec, + /// Encryption for audit, decrypt it with ovk + #[prost(bytes = "vec", tag = "5")] + pub c_out: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "6")] + pub zkproof: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ShieldedTransferContract { + /// transparent address + #[prost(bytes = "vec", tag = "1")] + pub transparent_from_address: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "2")] + pub from_amount: i64, + #[prost(message, repeated, tag = "3")] + pub spend_description: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "4")] + pub receive_description: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "5")] + pub binding_signature: ::prost::alloc::vec::Vec, + /// transparent address + #[prost(bytes = "vec", tag = "6")] + pub transparent_to_address: ::prost::alloc::vec::Vec, + /// the amount to transparent to_address + #[prost(int64, tag = "7")] + pub to_amount: i64, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SmartContract { + #[prost(bytes = "vec", tag = "1")] + pub origin_address: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "2")] + pub contract_address: ::prost::alloc::vec::Vec, + #[prost(message, optional, tag = "3")] + pub abi: ::core::option::Option, + #[prost(bytes = "vec", tag = "4")] + pub bytecode: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "5")] + pub call_value: i64, + #[prost(int64, tag = "6")] + pub consume_user_resource_percent: i64, + #[prost(string, tag = "7")] + pub name: ::prost::alloc::string::String, + #[prost(int64, tag = "8")] + pub origin_energy_limit: i64, + #[prost(bytes = "vec", tag = "9")] + pub code_hash: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "10")] + pub trx_hash: ::prost::alloc::vec::Vec, + #[prost(int32, tag = "11")] + pub version: i32, +} +/// Nested message and enum types in `SmartContract`. +pub mod smart_contract { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct Abi { + #[prost(message, repeated, tag = "1")] + pub entrys: ::prost::alloc::vec::Vec, + } + /// Nested message and enum types in `ABI`. + pub mod abi { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct Entry { + #[prost(bool, tag = "1")] + pub anonymous: bool, + #[prost(bool, tag = "2")] + pub constant: bool, + #[prost(string, tag = "3")] + pub name: ::prost::alloc::string::String, + #[prost(message, repeated, tag = "4")] + pub inputs: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "5")] + pub outputs: ::prost::alloc::vec::Vec, + #[prost(enumeration = "entry::EntryType", tag = "6")] + pub r#type: i32, + #[prost(bool, tag = "7")] + pub payable: bool, + #[prost(enumeration = "entry::StateMutabilityType", tag = "8")] + pub state_mutability: i32, + } + /// Nested message and enum types in `Entry`. + pub mod entry { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct Param { + #[prost(bool, tag = "1")] + pub indexed: bool, + #[prost(string, tag = "2")] + pub name: ::prost::alloc::string::String, + /// SolidityType type = 3; + #[prost(string, tag = "3")] + pub r#type: ::prost::alloc::string::String, + } + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] + #[repr(i32)] + pub enum EntryType { + UnknownEntryType = 0, + Constructor = 1, + Function = 2, + Event = 3, + Fallback = 4, + Receive = 5, + Error = 6, + } + impl EntryType { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + EntryType::UnknownEntryType => "UnknownEntryType", + EntryType::Constructor => "Constructor", + EntryType::Function => "Function", + EntryType::Event => "Event", + EntryType::Fallback => "Fallback", + EntryType::Receive => "Receive", + EntryType::Error => "Error", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "UnknownEntryType" => Some(Self::UnknownEntryType), + "Constructor" => Some(Self::Constructor), + "Function" => Some(Self::Function), + "Event" => Some(Self::Event), + "Fallback" => Some(Self::Fallback), + "Receive" => Some(Self::Receive), + "Error" => Some(Self::Error), + _ => None, + } + } + } + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] + #[repr(i32)] + pub enum StateMutabilityType { + UnknownMutabilityType = 0, + Pure = 1, + View = 2, + Nonpayable = 3, + Payable = 4, + } + impl StateMutabilityType { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + StateMutabilityType::UnknownMutabilityType => { + "UnknownMutabilityType" + } + StateMutabilityType::Pure => "Pure", + StateMutabilityType::View => "View", + StateMutabilityType::Nonpayable => "Nonpayable", + StateMutabilityType::Payable => "Payable", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "UnknownMutabilityType" => Some(Self::UnknownMutabilityType), + "Pure" => Some(Self::Pure), + "View" => Some(Self::View), + "Nonpayable" => Some(Self::Nonpayable), + "Payable" => Some(Self::Payable), + _ => None, + } + } + } + } + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ContractState { + #[prost(int64, tag = "1")] + pub energy_usage: i64, + #[prost(int64, tag = "2")] + pub energy_factor: i64, + #[prost(int64, tag = "3")] + pub update_cycle: i64, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct CreateSmartContract { + #[prost(bytes = "vec", tag = "1")] + pub owner_address: ::prost::alloc::vec::Vec, + #[prost(message, optional, tag = "2")] + pub new_contract: ::core::option::Option, + #[prost(int64, tag = "3")] + pub call_token_value: i64, + #[prost(int64, tag = "4")] + pub token_id: i64, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct TriggerSmartContract { + #[prost(bytes = "vec", tag = "1")] + pub owner_address: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "2")] + pub contract_address: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "3")] + pub call_value: i64, + #[prost(bytes = "vec", tag = "4")] + pub data: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "5")] + pub call_token_value: i64, + #[prost(int64, tag = "6")] + pub token_id: i64, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ClearAbiContract { + #[prost(bytes = "vec", tag = "1")] + pub owner_address: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "2")] + pub contract_address: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct UpdateSettingContract { + #[prost(bytes = "vec", tag = "1")] + pub owner_address: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "2")] + pub contract_address: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "3")] + pub consume_user_resource_percent: i64, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct UpdateEnergyLimitContract { + #[prost(bytes = "vec", tag = "1")] + pub owner_address: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "2")] + pub contract_address: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "3")] + pub origin_energy_limit: i64, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SmartContractDataWrapper { + #[prost(message, optional, tag = "1")] + pub smart_contract: ::core::option::Option, + #[prost(bytes = "vec", tag = "2")] + pub runtimecode: ::prost::alloc::vec::Vec, + #[prost(message, optional, tag = "3")] + pub contract_state: ::core::option::Option, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BuyStorageBytesContract { + #[prost(bytes = "vec", tag = "1")] + pub owner_address: ::prost::alloc::vec::Vec, + /// storage bytes for buy + #[prost(int64, tag = "2")] + pub bytes: i64, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BuyStorageContract { + #[prost(bytes = "vec", tag = "1")] + pub owner_address: ::prost::alloc::vec::Vec, + /// trx quantity for buy storage (sun) + #[prost(int64, tag = "2")] + pub quant: i64, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SellStorageContract { + #[prost(bytes = "vec", tag = "1")] + pub owner_address: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "2")] + pub storage_bytes: i64, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct UpdateBrokerageContract { + #[prost(bytes = "vec", tag = "1")] + pub owner_address: ::prost::alloc::vec::Vec, + /// 1 mean 1% + #[prost(int32, tag = "2")] + pub brokerage: i32, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct VoteAssetContract { + #[prost(bytes = "vec", tag = "1")] + pub owner_address: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", repeated, tag = "2")] + pub vote_address: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec>, + #[prost(bool, tag = "3")] + pub support: bool, + #[prost(int32, tag = "5")] + pub count: i32, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct WitnessCreateContract { + #[prost(bytes = "vec", tag = "1")] + pub owner_address: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "2")] + pub url: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct WitnessUpdateContract { + #[prost(bytes = "vec", tag = "1")] + pub owner_address: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "12")] + pub update_url: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct VoteWitnessContract { + #[prost(bytes = "vec", tag = "1")] + pub owner_address: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "2")] + pub votes: ::prost::alloc::vec::Vec, + #[prost(bool, tag = "3")] + pub support: bool, +} +/// Nested message and enum types in `VoteWitnessContract`. +pub mod vote_witness_contract { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct Vote { + #[prost(bytes = "vec", tag = "1")] + pub vote_address: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "2")] + pub vote_count: i64, + } +} diff --git a/packages/kos-proto/proto/klever/contracts.proto b/packages/kos/src/protos/klever/contracts.proto similarity index 97% rename from packages/kos-proto/proto/klever/contracts.proto rename to packages/kos/src/protos/klever/contracts.proto index 72ae07a..595dd83 100644 --- a/packages/kos-proto/proto/klever/contracts.proto +++ b/packages/kos/src/protos/klever/contracts.proto @@ -55,9 +55,9 @@ message AttributesInfo { // StakingInfo hold the staking structure for the KDA asset message StakingInfo { - enum InterestType { - APRI = 0; - FPRI = 1; + enum InterestType { + APRI = 0; + FPRI = 1; } InterestType Type = 1 [json_name = "Type"]; uint32 APR = 2 [json_name = "APR"]; @@ -396,16 +396,4 @@ message DepositContract { bytes ID = 2 [json_name = "ID"]; bytes CurrencyID = 3 [json_name = "CurrencyID"]; int64 Amount = 4 [json_name = "Amount"]; -} - -message SmartContract { - enum SCType { - SCInvoke = 0; - SCDeploy = 1; - } - SCType Type = 1 [json_name = "Type"]; - bytes Address = 2 [json_name = "Address"]; - // SmartContract CallValue is represented by a map of currencyID and amount - // should be limited to 50 currencies - map CallValue = 3 [json_name = "CallValue"]; -} +} \ No newline at end of file diff --git a/packages/kos/src/protos/klever/transaction.proto b/packages/kos/src/protos/klever/transaction.proto new file mode 100644 index 0000000..cb3267d --- /dev/null +++ b/packages/kos/src/protos/klever/transaction.proto @@ -0,0 +1,137 @@ +syntax = "proto3"; + +package proto; + +option go_package = "./;transaction"; + +import "google/protobuf/any.proto"; + +// TXContract available +message TXContract { + enum ContractType { + TransferContractType = 0; + CreateAssetContractType = 1; + CreateValidatorContractType = 2; + ValidatorConfigContractType = 3; + FreezeContractType = 4; + UnfreezeContractType = 5; + DelegateContractType = 6; + UndelegateContractType = 7; + WithdrawContractType = 8; + ClaimContractType = 9; + UnjailContractType = 10; + AssetTriggerContractType = 11; + SetAccountNameContractType = 12; + ProposalContractType = 13; + VoteContractType = 14; + ConfigITOContractType = 15; + SetITOPricesContractType = 16; + BuyContractType = 17; + SellContractType = 18; + CancelMarketOrderContractType = 19; + CreateMarketplaceContractType = 20; + ConfigMarketplaceContractType = 21; + UpdateAccountPermissionContractType = 22; + DepositContractType = 23; + ITOTriggerContractType = 24; + } + ContractType Type = 1 [json_name = "Type"]; + google.protobuf.Any Parameter = 2 [json_name = "Parameter"]; +} + +// Transaction holds all the data needed for a value transfer +message Transaction { + enum TXResult { + SUCCESS = 0; + FAILED = 1; + } + + enum TXResultCode { + Ok = 0; + OutOfFunds = 1; + AccountError = 2; + AssetError = 3; + ContractInvalid = 4; + ContractNotFound = 5; + FeeInvalid = 6; + ParameterInvalid = 7; + APRInvalid = 8; + AssetIDInvalid = 9; + AssetTypeInvalid = 10; + AssetCantBeMinted = 11; + AssetCantBeBurned = 12; + AssetCantBePaused = 13; + AssetCantBeDelegated = 14; + AssetOwnerCantBeChanged = 15; + AccountNotOwner = 16; + CommissionTooHigh = 17; + DelegationAmountInvalid = 18; + ProposalNotActive = 19; + ValueInvalid = 20; + AmountInvalid = 21; + BucketIDInvalid = 22; + KeyConflict = 23; + MaxDelegationAmount = 24; + InvalidPeerKey = 25; + MinKFIStakedUnreached = 26; + MaxSupplyExeeced = 27; + SaveAccountError = 28; + LoadAccountError = 29; + SameAccountError = 30; + AssetPaused = 31; + DeletegateError = 32; + WithdrawNotAvailable = 33; + ErrOverflow = 34; + SetStakingErr = 35; + SetMarketOrderErr = 36; + BalanceError = 37; + KAPPError = 38; + UnfreezeError = 39; + UndeletegateError = 40; + WithdrawError = 41; + ClaimError = 42; + BucketsExceded = 43; + AssetCantBeWiped = 44; + AssetCantAddRoles = 45; + FreezeError = 46; + ITONotActive = 47; + NFTMintStopped = 48; + RoyaltiesChangeStopped = 49; + ITOKAPPError = 50; + ITOWhiteListError = 51; + NFTMetadataChangeStopped = 52; + AlreadyExists = 53; + + Fail = 99; + } + + message KDAFee { + bytes KDA = 1 [json_name = "KDA"]; + int64 Amount = 2 [json_name = "Amount"]; + // TODO: allow spread + } + + message Raw { + uint64 Nonce = 1 [json_name = "Nonce"]; + bytes Sender = 2 [json_name = "Sender"]; + repeated TXContract Contract = 6 [json_name = "Contract"]; + int32 PermissionID = 7 [json_name = "PermissionID"]; + repeated bytes Data = 10 [json_name = "Data"]; + int64 KAppFee = 13 [json_name = "KAppFee"]; + int64 BandwidthFee = 14 [json_name = "BandwidthFee"]; + uint32 Version = 15 [json_name = "Version"]; + bytes ChainID = 16 [json_name = "ChainID"]; + KDAFee KDAFee = 17 [json_name = "KDAFee"]; + } + + message Receipt { + repeated bytes Data = 1 [json_name = "data"]; + } + + Raw RawData = 1 [json_name = "RawData"]; + repeated bytes Signature = 2 [json_name = "Signature"]; + TXResult Result = 3 [json_name = "Result"]; + TXResultCode ResultCode = 4 [json_name = "ResultCode"]; + repeated Receipt Receipts = 5 [json_name = "Receipts"]; + uint64 Block = 6 [json_name = "Block"]; +} \ No newline at end of file diff --git a/packages/kos/src/protos/klever/userAccountData.proto b/packages/kos/src/protos/klever/userAccountData.proto new file mode 100644 index 0000000..5e23dbc --- /dev/null +++ b/packages/kos/src/protos/klever/userAccountData.proto @@ -0,0 +1,34 @@ +syntax = "proto3"; + +package proto; + +option go_package = "./;state"; + +message Key { + bytes address = 1; + int64 weight = 2; +} + +message Permission { + enum PermissionType { + Owner = 0; + User = 1; + } + int32 ID = 1; + PermissionType Type = 2; + string PermissionName = 3; + int64 Threshold = 4; + bytes Operations = 5; + repeated Key Signers = 6; +} + +message UserAccountData { + bytes Address = 1; + bytes Name = 2; + bytes RootHash = 3; + int64 Balance = 5; + int64 Allowance = 6; + uint64 Nonce = 7; + + repeated Permission Permissions = 8; +} \ No newline at end of file diff --git a/packages/kos/src/protos/mod.rs b/packages/kos/src/protos/mod.rs new file mode 100644 index 0000000..6e4a9cc --- /dev/null +++ b/packages/kos/src/protos/mod.rs @@ -0,0 +1,62 @@ +pub mod generated; +use crate::crypto::base64::{simple_base64_decode, simple_base64_encode}; +use alloc::string::{String, ToString}; +use alloc::vec::Vec; +use tiny_json_rs::mapper; +use tiny_json_rs::mapper::Value; +use tiny_json_rs::serializer::DecodeError; +use tiny_json_rs::serializer::{Deserialize, Serialize}; + +#[allow(dead_code)] +pub trait TypeUrl { + fn type_url() -> &'static str; +} + +// Implement serialization for `Any` +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Any { + #[prost(string, tag = "1")] + pub type_url: String, + // This field will hold the actual byte array + #[prost(bytes, tag = "2")] + pub value: Vec, +} + +impl Any { + // Encodes the value field to a base64 string + pub fn encode_to_base64(&self) -> String { + simple_base64_encode(&self.value) + } + + // Decodes a base64 string to the value field +} + +// Implement serde's Serialize for Any +// This is a simplified example and you'll likely need a more comprehensive implementation. +impl Serialize for Any { + fn serialize(&self) -> Value { + let mut object = mapper::Object::new(); + object.insert("type_url".to_string(), self.type_url.serialize()); + object.insert("value".to_string(), self.encode_to_base64().serialize()); + Value::Object(object) + } +} + +impl Deserialize for Any { + fn deserialize(value: Option<&Value>) -> Result { + let value = match value { + None => return Err(DecodeError::UnexpectedType), + Some(v) => v, + }; + + let key = value.get_value::("type_url")?; + let value = value.get_value::("value")?; + + let value = simple_base64_decode(&value) + .map_err(|_| DecodeError::ParseError("Error encoding Any".to_string()))?; + Ok(Any { + type_url: key, + value, + }) + } +} diff --git a/packages/kos/src/protos/tron/.gitignore b/packages/kos/src/protos/tron/.gitignore new file mode 100644 index 0000000..1554c5e --- /dev/null +++ b/packages/kos/src/protos/tron/.gitignore @@ -0,0 +1,4 @@ +# IDEA +.idea +*iml +.DS_Store diff --git a/packages/kos/src/protos/tron/.travis.yml b/packages/kos/src/protos/tron/.travis.yml new file mode 100644 index 0000000..2cc9ce9 --- /dev/null +++ b/packages/kos/src/protos/tron/.travis.yml @@ -0,0 +1,13 @@ +language: ruby +cache: + directories: + - "$HOME/protobuf" +sudo: false +before_install: +before_script: +script: +- ls -l +notifications: + slack: + secure: lCDOgsHefxu0Sd7J4N9wyo6Y/dvAentdf+q+R6R+SpJUym+tI7h4lPVwDFl9iQabFahLC6bV4lgfv/US0aqjL4QE/c3ZsWBDo2dtkfCzGmkCiU6mGd/bPWLFP9e28OHEFBzUT8ukc5O3GDJREnzscIqGk7Knv3QYQGsoZw563grzVG9VVfqKhsVgrAjhzDwiCoUNSiND09ZNifGrHr7JBQ2u0wrZRR+E9yOQ1K3pNnfq5wAJjbJ0LiuxRlLZoajR7z8VeP8ytet+u2XQE1+fd089XEa/thYxtt0ZvhnyOYk1vmEldDdVakqMqVaa9MKiyLBNnLby1xdSosrM55ZB3tFmXQo6EMIaNKyO07xMUJ/hK0gEppQhHMDlbOW31YmOshVutp2yN4tRF8D3ot1OcYPXsVeXFG+kMUR0PYM71YiqZy8UVgoslKgRgEehvxjuAhbMYXMG878bznco9L64TzubFcjOx0+owR8H0kCXDNf5Xwm+tlc2onWlUDerEWIAignVOT1iR8KK0U+EnhTfw2BWfDV+BkSBvaeFbmnsFgz00d7qSvzbtCJ9KdDj3f4FUjUuORNv5ykMGCv1MrvAvttAZPTNIc/wOFJ9yRC2NhoUfbNILYg7bYhmqKiicnflln03Bh7Ml2mzldzPaRMm7eUBUwYTFbgC83YusX4fxBg= + if: branch = master diff --git a/packages/kos/src/protos/tron/Chinese version of TRON Protocol document.md b/packages/kos/src/protos/tron/Chinese version of TRON Protocol document.md new file mode 100644 index 0000000..283bd5f --- /dev/null +++ b/packages/kos/src/protos/tron/Chinese version of TRON Protocol document.md @@ -0,0 +1,696 @@ +# TRON protobuf protocol + +## TRON使用Google protobuf协议,协议内容涉及到账户,区块,传输多个层面。 + ++ 账户有基本账户、资产发布账户和合约账户三种类型。一个账户包含:账户名称,账户类型,地址,余额,投票,其他资产6种属性。 ++ 更进一步的,基本账户可以申请成为验证节点,验证节点具有额外的属性,投票统计数目,公钥,URL,以及历史表现等参数。 + + 3种`Account`类型:`Normal`,`AssetIssue`,`Contract`。 + + enum AccountType {
 + Normal = 0;
 + AssetIssue = 1;
 + Contract = 2;
 + } + + 一个`Account`包含7种参数: + `account_name`:该账户的名称——比如: ”_SicCongsAccount_”。 + `type`:该账户的类型——比如: _0_ 代表的账户类型是`Normal`。 + `balance`:该账户的TRX余额——比如:_4213312_。 + `votes`:账户所得投票数——比如:_{(“0x1b7w…9xj3”,323),(“0x8djq…j12m”,88),…,(“0x82nd…mx6i”,10001)}_。 + `asset`:除TRX以外账户上的其他资产——比如:_{<”WishToken”,66666>,<”Dogie”,233>}_。 + `latest_operation_time`: 该账户的最新活跃时间。 + + // Account
 + message Account {
 + message Vote {
 + bytes vote_address = 1;
 + int64 vote_count = 2;
 + }
 + bytes accout_name = 1;
 + AccountType type = 2;
 + bytes address = 3;
 + int64 balance = 4;
 + repeated Vote votes = 5;
 + map asset = 6;
 + int64 latest_operation_time = 10; + } + + 一个`Witness`包含8种参数: + `address`:验证节点的地址——比如:_“0xu82h…7237”_。 + `voteCount`:验证节点所得投票数——比如:_234234_。 + `pubKey`:验证节点的公钥——比如:_“0xu82h…7237”_。 + `url`:验证节点的url链接。 + `totalProduce`:验证节点产生的区块数——比如:_2434_。 + `totalMissed`:验证节点丢失的区块数——比如:_7_。 + `latestBlockNum`:最新的区块高度——比如:_4522_。 + `isJobs`:布尔表类型标志位。 + + // Witness
 + message Witness {
 + bytes address = 1;
 + int64 voteCount = 2;
 + bytes pubKey = 3;
 + string url = 4;
 + int64 totalProduced = 5;
 + int64 totalMissed = 6;
 + int64 latestBlockNum = 7; + bool isJobs = 9; + 
} + ++ 一个区块由区块头和多笔交易构成。区块头包含时间戳,交易字典树的根,父哈希,签名等区块基本信息。 + + 一个`block`包含`transactions`和`block_header`。 + `transactions`:区块里的交易信息。 + `block_header`:区块的组成部分之一。 + + // block
 + message Block {
 + repeated Transaction transactions = 1;
 + BlockHeader block_header = 2; + 
} + + `BlockHeader` 包括`raw_data`和`witness_signature`。 + `raw_data`:`raw`信息。 + `witness_signature`:区块头到验证节点的签名。 + + message `raw`包含6种参数: + `timestamp`:该消息体的时间戳——比如:_14356325_。 + `txTrieRoot`:Merkle Tree的根——比如:_“7dacsa…3ed”_。 + `parentHash`:上一个区块的哈希值——比如:_“7dacsa…3ed”_。 + `number`:区块高度——比如:_13534657_。 + `witness_id`:验证节点的id——比如:_“0xu82h…7237”_。 + `witness_address`:验证节点的地址——比如:_“0xu82h…7237”_。 + + message BlockHeader {
 + message raw {
 + int64 timestamp = 1;
 + bytes txTrieRoot = 2;
 + bytes parentHash = 3;
 + //bytes nonce = 5;
 + //bytes difficulty = 6;
 + uint64 number = 7;
 + uint64 witness_id = 8;
 + bytes witness_address = 9;
 + }
 + raw raw_data = 1;
 + bytes witness_signature = 2; + 
} + + 消息体 `ChainInventory` 包括 `BlockId` 和 `remain_num`。 + `BlockId`: block的身份信息。 + `remain_num`:在同步过程中,剩余的区块数量。 + + A `BlockId` contains 2 parameters: + `hash`: 该区块的哈希值。 + `number`: 哈希值和高度即为当前区块块号。 + + message ChainInventory { + message BlockId { + bytes hash = 1; + int64 number = 2; + } + repeated BlockId ids = 1; + int64 remain_num = 2; + } + ++ 交易合约有多种类型,包括账户创建合约、账户更新合约、转账合约、转账断言合约、资产投票合约、见证节点投票合约、见证节点创建合约、见证节点更新合约、资产发布合约、参与资产发布和与部署合约11种类型。 + + `AccountCreatContract`包含3种参数: + `type`:账户类型——比如:_0_ 代表的账户类型是`Normal`。 + `account_name`: 账户名称——比如: _"SiCongsaccount”_。 + `owner_address`:合约持有人地址——比如: _“0xu82h…7237”_。 + + message AccountCreateContract {
 + AccountType type = 1;
 + bytes account_name = 2;
 + bytes owner_address = 3;
 + } + `AccountUpdateContract`包含2种参数: + `account_name`: 账户名称——比如: _"SiCongsaccount”_。 + `owner_address`:合约持有人地址——比如: _“0xu82h…7237”_。 + + message AccountUpdateContract { + bytes account_name = 1; + bytes owner_address = 2; + } + + `TransferContract`包含3种参数: + `amount`:TRX数量——比如:_12534_。 + `to_address`: 接收方地址——比如:_“0xu82h…7237”_。 + `owner_address`:合约持有人地址——比如:_“0xu82h…7237”_。 + + message TransferContract {
 + bytes owner_address = 1;
 + bytes to_address = 2;
 + int64 amount = 3; + 
} + + `TransferAssetContract`包含4种参数: + `asset_name`:资产名称——比如:_”SiCongsaccount”_。 + `to_address`:接收方地址——比如:_“0xu82h…7237”_。 + `owner_address`:合约持有人地址——比如:_“0xu82h…7237”_。 + `amount`:目标资产数量——比如:_12353_。 + + message TransferAssetContract {
 + bytes asset_name = 1;
 + bytes owner_address = 2;
 + bytes to_address = 3;
 + int64 amount = 4;
 + } + + `VoteAssetContract`包含4种参数: + `vote_address`:投票人地址——比如:_“0xu82h…7237”_。 + `support`:投票赞成与否——比如:_true_。 + `owner_address`:合约持有人地址——比如:_“0xu82h…7237”_。 + `count`:投票数目——比如:_2324234_。 + + message VoteAssetContract {
 + bytes owner_address = 1;
 + repeated bytes vote_address = 2;
 + bool support = 3;
 + int32 count = 5; + } + + `VoteWitnessContract`包含4种参数: + `vote_address`:投票人地址——比如:_“0xu82h…7237”_。 + `support`:投票赞成与否——比如:_true_。 + `owner_address`:合约持有人地址——比如:_“0xu82h…7237”_。 + `count`:投票数目——比如:_32632_。 + + message VoteWitnessContract {
 + bytes owner_address = 1;
 + repeated bytes vote_address = 2;
 + bool support = 3;
 + int32 count = 5;
 + } + + `WitnessCreateContract`包含3种参数: + `private_key`:合约的私钥——比如:_“0xu82h…7237”_。 + `owner_address`:合约持有人地址——比如:_“0xu82h…7237”_。 + `url`:合约的url链接。 + + message WitnessCreateContract {
 + bytes owner_address = 1;
 + bytes private_key = 2;
 + bytes url = 12; + 
} + + `WitnessUpdateContract`包含2种参数: + `owner_address`:合约持有人地址——比如:_“0xu82h…7237”_。 + `update_url`:合约的url链接。 + + message WitnessUpdateContract { + bytes owner_address = 1; + bytes update_url = 12; + } + + `AssetIssueContract`包含11种参数: + `name`:合约名称——比如:_“SiCongcontract”_。 + `total_supply`:合约的赞成总票数——比如:_100000000_。 + `owner_address`:合约持有人地址——比如:_“0xu82h…7237”_。 + `trx_num`:对应TRX数量——比如:_232241_。 + `num`: 对应的自定义资产数目。 + `start_time`:开始时间——比如:_20170312_。 + `end_time`:结束时间——比如:_20170512_。 + `vote_score`:合约的评分——比如:_12343_。 + `description`:合约的描述——比如:_”trondada”_。 + `url`:合约的url地址链接。 + + message AssetIssueContract {
 + bytes owner_address = 1;
 + bytes name = 2;
 + int64 total_supply = 4;
 + int32 trx_num = 6;
 + int32 num = 8;
 + int64 start_time = 9;
 + int64 end_time = 10;
 + int32 vote_score = 16;
 + bytes description = 20;
 + bytes url = 21;
 + } + + `ParticipateAssetIssueContract`包含4种参数: + `owner_address`:合约持有人地址——比如:_“0xu82h…7237”_。 + `to_address`:接收方地址——比如:_“0xu82h…7237”_。 + `asset_name`: 目标资产的名称。 + `amount`: 小部分数量。 + + `DeployContract`包含2种参数: + `script`:脚本。 + `owner_address`:合约持有人地址——比如:_“0xu82h…7237”_。 + + message DeployContract {
 + bytes owner_address = 1;
 + bytes script = 2;
 + } + + 消息体 `Result` 包含 `fee` and `ret`2个参数. + `ret`: 交易结果。 + `fee`: 交易扣除的费用。 + + `code`是`ret`的类型定义,有`SUCCESS`和`FAILED`两种类型。 + + message Result { + enum code { + SUCESS = 0; + FAILED = 1; + } + int64 fee = 1; + code ret = 2; + } + ++ 每一个交易还包含多个输入与多个输出,以及其他一些相关属性。其中交易内的输入,交易本身,区块头均需签名。 + + 消息体 `Transaction`包括`raw_data`和`signature`。 + `raw_data`: 消息体`raw`。 + `signature`: 所有输入节点的签名。 + + `raw_data`包含8种参数: + `type`:消息体raw的交易类型。 + `vin`: 输入值。 + `vout`: 输出值。 + `expiration`:过期时间——比如:_20170312_。 + `data`: 数据。 + `contract`: 该交易内的合约。 + `script`: 脚本。 + `timestamp`:该消息体的时间戳。 + + 消息体 `Contract`包含`type`和`parameter`。 + `type`:合约的类型。 + `parameter`:任意参数。 + + 有八种账户类型合约:`AccountCreateContract`,`TransferContract`,`TransferAssetContract`,`VoteAssetContract`,`VoteWitnessContract`,`WitnessCreateContract`,`AssetIssueContract` 和`DeployContract`。 + + `TransactionType`包括`UtxoType`和`ContractType`。 + + message Transaction {
 + enum TranscationType {
 + UtxoType = 0;
 + ContractType = 1;
 + }
 + message Contract {
 + enum ContractType {
 + AccountCreateContract = 0;
 + TransferContract = 1;
 + TransferAssetContract = 2;
 + VoteAssetContract = 3;
 + VoteWitnessContract = 4;
 + WitnessCreateContract = 5;
 + AssetIssueContract = 6;
 + DeployContract = 7;
 + }
 + ContractType type = 1;
 + google.protobuf.Any parameter = 2;
 + }
 + message raw {
 + TranscationType type = 2;
 + repeated TXInput vin = 5;
 + repeated TXOutput vout = 7;
 + int64 expiration = 8;
 + bytes data = 10;
 + repeated Contract contract = 11;
 + bytes scripts = 16;
 + in64 timestamp = 17; + }
 + raw raw_data = 1;
 + repeated bytes signature = 5;
 + } + + 消息体 `TXOutputs`由`outputs`构成。 + `outputs`: 元素为`TXOutput`的数组。 + + message TXOutputs {
 + repeated TXOutput outputs = 1; + 
} + + 消息体 `TXOutput`包括`value`和`pubKeyHash`。 + `value`:输出值。 + `pubKeyhash`:公钥的哈希。 + + message TXOutput {
 + int64 value = 1;
 + bytes pubKeyHash = 2; + 
} + + 消息体 `TXIutput`包括`raw_data`和`signature`。 + `raw_data`:消息体`raw`。 + `signature`:`TXInput`的签名。 + + 消息体 `raw`包含`txID`,`vout`和 `pubKey`。 + `txID`:交易ID。 + `Vout`:上一个输出的值。 + `pubkey`:公钥。 + + message TXInput {
 + message raw {
 + bytes txID = 1;
 + int64 vout = 2;
 + bytes pubKey = 3;
 + }
 + raw raw_data = 1;
 + bytes signature = 4;
} + ++ 传输涉及的协议Inventory主要用于传输中告知接收方传输数据的清单。 + + `Inventory`包括`type`和`ids`。 + `type`:清单类型——比如:_0_ 代表`TRX`。 + `ids`:清单中的物品ID。 + + `InventoryType`包含`TRX`和 `BLOCK`。 + `TRX`:交易。 + `BLOCK`:区块。 + + // Inventory
 + message Inventory {
 + enum InventoryType {
 + TRX = 0;
 + BLOCK = 1;
 + }
 + InventoryType type = 1;
 + repeated bytes ids = 2; + 
} + + 消息体 `Items`包含4种参数: + `type`:物品类型——比如:_1_ 代表 `TRX`。 + `blocks`:物品中区块。 + `blockheaders`:区块头。 + `transactions`:交易。 + + `Items`有四种类型,分别是 `ERR`, `TRX`,`BLOCK` 和`BLOCKHEADER`。 + `ERR`:错误。 + `TRX`:交易。 + `BLOCK`:区块。 + `BLOCKHEADER`:区块头。 + + message Items {
 + enum ItemType {
 + ERR = 0;
 + TRX = 1;
 + BLOCK = 2;
 + BLOCKHEADER = 3;
 + }
 + ItemType type = 1;
 + repeated Block blocks = 2;
 + repeated BlockHeader block_headers = 3;
 + repeated Transaction transactions = 4;
 + } + + `Inventory`包含`type`和`items`。 + `type`:物品种类。 + `items`:物品清单。 + + message InventoryItems {
 + int32 type = 1;
 + repeated bytes items = 2;
 + } + + 消息体 `BlockInventory` 包含 `type`。 + `type`: 清单种类. + + 有三种类型:`SYNC`, `ADVTISE`, `FETCH`。 + + // Inventory + message BlockInventory { + enum Type { + SYNC = 0; + ADVTISE = 1; + FETCH = 2; + } + + 消息体 `BlockId` 包括 `ids` and `type`。 + `ids`: 区块身份信息。 + `type`: 区块类型。 + + `ids` 包含2种参数: + `hash`: 区块的哈希值。 + `number`: 哈希值和区块高度即为当前区块号。 + + message BlockId { + bytes hash = 1; + int64 number = 2; + } + repeated BlockId ids = 1; + Type type = 2; + } + + `ReasonCode` 有15种可能断开的原因: + `REQUESTED` + `TCP_ERROR` + `BAD_PROTOCOL` + `USELESS_PEER` + `TOO_MANY_PEERS` + `DUPLICATE_PEER` + `INCOMPATIBLE_PROTOCOL` + `NULL_IDENTITY` + `PEER_QUITING` + `UNEXPECTED_IDENTITY` + `LOCAL_IDENTITY` + `PING_TIMEOU` + `USER_REASON` + `RESET` + `UNKNOWN` + + enum ReasonCode { + REQUESTED = 0; + TCP_ERROR = 1; + BAD_PROTOCOL = 2; + USELESS_PEER = 3; + TOO_MANY_PEERS = 4; + DUPLICATE_PEER = 5; + INCOMPATIBLE_PROTOCOL = 6; + NULL_IDENTITY = 7; + PEER_QUITING = 8; + UNEXPECTED_IDENTITY = 9; + LOCAL_IDENTITY = 10; + PING_TIMEOUT = 11; + USER_REASON = 12; + RESET = 16; + UNKNOWN = 255; + } + + 消息体`DisconnectMessage`包含`reason`。 + `DisconnectMessage`:断开连接是的消息。 + `reason`:断开连接时的原因。 + + 消息体`HelloMessage`包含2个参数: + `from`请:求建立连接的节点。 + `version`:建立连接的节点。 + ++ 钱包服务RPC和区块链浏览器。 + + `Wallet`钱包服务包含多个RPC。 + __`Getbalance`__:获取`Account`的余额。 + __`CreatTransaction`__:通过`TransferContract`创建交易。 + __`BroadcastTransaction`__:广播`Transaction`。 + __`CreateAccount`__:通过`AccountCreateContract`创建账户。 + __`CreatAssetIssue`__:通过`AssetIssueContract`发布一个资产。 + __`ListAccounts`__:通过`ListAccounts`查看账户列表。 + __`UpdateAccount`__:通过`UpdateAccountContract`发布一个资产。 + __`VoteWitnessAccount`__:通过`VoteWitnessContract`发布一个资产。 + __`WitnessList`__:通过`WitnessList`查看见证节点列表。 + __`UpdateWitness`__:通过`WitnessUpdateContract`发布一个资产。 + __`CreateWitness`__:通过`WitnessCreateContract`发布一个资产。 + __`TransferAsset`__:通过`TransferAssetContract`发布一个资产。 + __`ParticipateAssetIssue`__:通过`ParticipateAssetIssueContract`发布一个资产。 + __`ListNodes`__:通过`ListNodes`查看节点列表。 + __`GetAssetIssueList`__:通过`GetAssetIssueList`查看资产发布节点列表。 + __`GetAssetIssueByAccount`__:通过`Account`获取发行资产。 + __`GetAssetIssueByName`__:通过`Name`获取发行资产。 + __`GetNowBlock`__:获取区块。 + __`GetBlockByNum`__:根据块号获取区块。 + __`TotalTransaction`__:查看总交易量。 + + service Wallet { + + rpc GetAccount (Account) returns (Account) { + + }; + + rpc CreateTransaction (TransferContract) returns (Transaction) { + + }; + + rpc BroadcastTransaction (Transaction) returns (Return) { + + }; + + rpc ListAccounts (EmptyMessage) returns (AccountList) { + + }; + + rpc UpdateAccount (AccountUpdateContract) returns (Transaction) { + + }; + + rpc CreateAccount (AccountCreateContract) returns (Transaction) { + + }; + + rpc VoteWitnessAccount (VoteWitnessContract) returns (Transaction) { + + }; + + rpc CreateAssetIssue (AssetIssueContract) returns (Transaction) { + + }; + + rpc WitnessList (EmptyMessage) returns (WitnessList) { + + }; + + rpc UpdateWitness (WitnessUpdateContract) returns (Transaction) { + + }; + + rpc CreateWitness (WitnessCreateContract) returns (Transaction) { + + }; + + rpc TransferAsset (TransferAssetContract) returns (Transaction) { + + } + + rpc ParticipateAssetIssue (ParticipateAssetIssueContract) returns (Transaction) { + + } + + rpc ListNodes (EmptyMessage) returns (NodeList) { + + } + rpc GetAssetIssueList (EmptyMessage) returns (AssetIssueList) { + + } + rpc GetAssetIssueByAccount (Account) returns (AssetIssueList) { + + } + rpc GetAssetIssueByName (BytesMessage) returns (AssetIssueContract) { + + } + rpc GetNowBlock (EmptyMessage) returns (Block) { + + } + rpc GetBlockByNum (NumberMessage) returns (Block) { + + } + rpc TotalTransaction (EmptyMessage) returns (NumberMessage) { + + } + }; + + `AccountList`: 区块链浏览器中的账户列表。 + 消息体 `AccountList` 包含1个参数: + `account`: + + message AccountList { + repeated Account accounts = 1; + } + + `WitnessList`:区块链浏览器中的见证节点列表。 + 消息体 `WitnessList` 包含1个参数: + `witnesses`: + + message WitnessList { + repeated Witness witnesses = 1; + } + + `AssetIssueList`:区块链浏览器中的发布资产列表。 + 消息体 `AssetIssueList` 包含1个参数: + `assetIssue`: + + message AssetIssueList { + repeated AssetIssueContract assetIssue = 1; + } + + + `NodeList`: 分布节点图中的节点列表。 + 消息体 `NodeList` 包含1个参数: + `nodes`: + + message NodeList { + repeated Node nodes = 1; + } + + `Address`: 节点地址。 + 消息体`Address` 包含2个参数: + `host`:节点所有者。 + `port`:节点的端口号。 + + message Address { + bytes host = 1; + int32 port = 2; + } + + + 消息体`Return`只含有一个参数: + `result`: 布尔表类型标志位。 + + message `Return` {
 + bool result = 1;
 + } + ++ 网络UDP消息结构。 + + `Endpoint`:网络中节点信息存储结构. + 消息体`Endpoint` 包含3个参数: + `address`:节点地址。 + `port`:端口号。 + `nodeId`: 节点ID信息。 + + message Endpoint { + bytes address = 1; + int32 port = 2; + bytes nodeId = 3; + } + + `PingMessage`:节点建立连接时所发送的消息。 + 消息体`PingMessage` 包含4个参数: + `from`:消息来自的节点。 + `to`: 消息发送的节点。 + `version`: 网络版本。 + `timestamp`:消息创建时的时间戳。 + + message PingMessage { + Endpoint from = 1; + Endpoint to = 2; + int32 version = 3; + int64 timestamp = 4; + } + + `PongMessage`:连接建立成功时的回复消息。 + 消息体`PongMessage` 包含3个参数: + `from`:消息来自的节点。 + `echo`: + `timestamp`:消息创建时的时间戳。 + + message PongMessage { + Endpoint from = 1; + int32 echo = 2; + int64 timestamp = 3; + } + + `FindNeighbours`:节点查询相邻节点时所发送的消息。 + 消息体`FindNeighbours` 包含3个参数: + `from`: 消息来自的节点。 + `targetId`: 目标节点的信息。 + `timestamp`: 消息创建时的时间戳。 + + message FindNeighbours { + Endpoint from = 1; + bytes targetId = 2; + int64 timestamp = 3; + } + + `Neighbour`:相邻接点回复消息。 + 消息体`Neighbours` 包含3个参数: + `from`: 消息来自的节点。 + `neighbours`: 相邻节点。 + `timestamp`: 消息创建时的时间戳。 + + message Neighbours { + Endpoint from = 1; + repeated Endpoint neighbours = 2; + int64 timestamp = 3; + } + +# 详细的协议见附属文件。详细协议随着程序的迭代随时都可能发生变化,请以最新的版本为准。 \ No newline at end of file diff --git a/packages/kos/src/protos/tron/English version of TRON Protocol document.md b/packages/kos/src/protos/tron/English version of TRON Protocol document.md new file mode 100644 index 0000000..e282f4b --- /dev/null +++ b/packages/kos/src/protos/tron/English version of TRON Protocol document.md @@ -0,0 +1,736 @@ + +# Protobuf protocol + +## The protocol of TRON is defined by Google Protobuf and contains a range of layers, from account, block to transfer. + ++ There are 3 types of account—basic account, asset release account and contract account, and attributes included in each account are name, types, address, balance and related asset. ++ A basic account is able to apply to be a validation node, which has serval parameters, including extra attributes, public key, URL, voting statistics, history performance, etc. + + There are three different `Account types`: `Normal`, `AssetIssue`, `Contract`. +```protobuf +enum AccountType {
 + Normal = 0;
 + AssetIssue = 1;
 + Contract = 2;
 +
} +``` + + + An `Account` contains 7 parameters: + `account_name`: the name for this account – e.g. “_BillsAccount_”. + `type`: what type of this account is – e.g. _0_ stands for type `Normal`. + `balance`: balance of this account – e.g. _4213312_. + `votes`: received votes on this account – e.g. _{(“0x1b7w…9xj3”,323), (“0x8djq…j12m”,88),…,(“0x82nd…mx6i”,10001)}_. + `asset`: other assets expect TRX in this account – e.g. _{<“WishToken”,66666>,<”Dogie”,233>}_. + `latest_operation_time`: the latest operation time of this account. +```protobuf +// Account
 +message Account {
 + message Vote {
 + bytes vote_address = 1;
 + int64 vote_count = 2;
 }
 + bytes accout_name = 1;
 + AccountType type = 2;
 + bytes address = 3;
 + int64 balance = 4;
 + repeated Vote votes = 5;
 + map asset = 6; + int64 latest_operation_time = 10;
 +} +``` + A `Witness` contains 8 parameters: + `address`: the address of this witness – e.g. “_0xu82h…7237_”. + `voteCount`: number of received votes on this witness – e.g. _234234_. + `pubKey`: the public key for this witness – e.g. “_0xu82h…7237_”. + `url`: the url for this witness – e.g. “_https://www.noonetrust.com_”. + `totalProduced`: the number of blocks this witness produced – e.g. _2434_. + `totalMissed`: the number of blocks this witness missed – e.g. _7_. + `latestBlockNum`: the latest height of block – e.g. _4522_. + `isjobs`: a bool flag. +```protobuf +// Witness
 +message Witness{
 + bytes address = 1;
 + int64 voteCount = 2;
 + bytes pubKey = 3;
 + string url = 4;
 + int64 totalProduced = 5;
 + int64 totalMissed = 6;
 + int64 latestBlockNum = 7;
 + bool isJobs = 9; +} +``` ++ A block typically contains transaction data and a blockheader, which is a list of basic block information, including timestamp, signature, parent hash, root of Merkle tree and so on. + + A block contains `transactions` and a `block_header`. + `transactions`: transaction data of this block. + `block_header`: one part of a block. + ```protobuf + // block +message Block {
 + repeated Transaction transactions = 1;
 + BlockHeader block_header = 2;
 +} +``` + A `BlockHeader` contains `raw_data` and `witness_signature`. + `raw_data`: a `raw` message. + `witness_signature`: signature for this block header from witness node. + + A message `raw` contains 6 parameters: + `timestamp`: timestamp of this message – e.g. _14356325_. + `txTrieRoot`: the root of Merkle Tree in this block – e.g. “_7dacsa…3ed_.” + `parentHash`: the hash of last block – e.g. “_7dacsa…3ed_.” + `number`: the height of this block – e.g. _13534657_. + `witness_id`: the id of witness which packed this block – e.g. “_0xu82h…7237_”. + `witness_address`: the adresss of the witness packed this block – e.g. “_0xu82h…7237_”. +```protobuf +message BlockHeader {
 + message raw {
 + int64 timestamp = 1;
 + bytes txTrieRoot = 2;
 + bytes parentHash = 3;
 + //bytes nonce = 5;
 + //bytes difficulty = 6;
 + uint64 number = 7;
 + uint64 witness_id = 8;
 + bytes witness_address = 9;
 + }
 + raw raw_data = 1;
 + bytes witness_signature = 2;
 +} +``` + message `ChainInventory` contains `BlockId` and `remain_num`. + `BlockId`: the identification of block. + `remain_num`:the remain number of blocks in the synchronizing process. + + A `BlockId` contains 2 parameters: + `hash`: the hash of block. + `number`: the hash and height of block. +```protobuf +message ChainInventory { + message BlockId { + bytes hash = 1; + int64 number = 2; + } + repeated BlockId ids = 1; + int64 remain_num = 2; +} +``` ++ Transaction contracts mainly includes account create contract, account update contract transfer contract, transfer asset contract, vote asset contract, vote witness contract, witness creation contract, witness update contract, asset issue contract, participate asset issue contract and deploy contract. + + An `AccountCreateContract` contains 3 parameters: + `type`: What type this account is – e.g. _0_ stands for `Normal`. + `account_name`: the name for this account – e.g.”_Billsaccount_”. + `owner_address`: the address of contract owner – e.g. “_0xu82h…7237_”. +```protobuf +message AccountCreateContract {
 + AccountType type = 1;
 + bytes account_name = 2;
 + bytes owner_address = 3;
 +} +``` + A `AccountUpdateContract` contains 2 paremeters: + `account_name`: the name for this account – e.g.”_Billsaccount_”. + `owner_address`: the address of contract owner – e.g. “_0xu82h…7237_”. +```protobuf +message AccountUpdateContract { + bytes account_name = 1; + bytes owner_address = 2; +} +``` + A `TransferContract` contains 3 parameters: + `amount`: the amount of TRX – e.g. _12534_. + `to_address`: the receiver address – e.g. “_0xu82h…7237_”. + `owner_address`: the address of contract owner – e.g. “_0xu82h…7237_”. +```protobuf +message TransferContract {
 + bytes owner_address = 1;
 + bytes to_address = 2;
 + int64 amount = 3; +} +``` + A `TransferAssetContract` contains 4 parameters: + `asset_name`: the name for asset – e.g.”_Billsaccount_”. + `to_address`: the receiver address – e.g. “_0xu82h…7237_”. + `owner_address`: the address of contract owner – e.g. “_0xu82h…7237_”. + `amount`: the amount of target asset - e.g._12353_. +```protobuf +message TransferAssetContract {
 + bytes asset_name = 1;
 + bytes owner_address = 2;
 + bytes to_address = 3;
 + int64 amount = 4;
 +} +``` + A `VoteAssetContract` contains 4 parameters: + `vote_address`: the voted address of the asset. + `support`: is the votes supportive or not – e.g. _true_. + `owner_address`: the address of contract owner – e.g. “_0xu82h…7237_”. + `count`: the count number of votes- e.g. _2324234_. +```protobuf + message VoteAssetContract {
 + bytes owner_address = 1;
 + repeated bytes vote_address = 2;
 + bool support = 3;
 + int32 count = 5;
 + } +``` + A `VoteWitnessContract` contains 4 parameters: + `vote_address`: the addresses of those who voted. + `support`: is the votes supportive or not - e.g. _true_. + `owner_address`: the address of contract owner – e.g. “_0xu82h…7237_”. + `count`: - e.g. the count number of vote – e.g. _32632_. + + message VoteWitnessContract {
 + bytes owner_address = 1;
 + repeated bytes vote_address = 2;
 + bool support = 3;
 + int32 count = 5; + 
} + + A `WitnessCreateContract` contains 3 parameters: + `private_key`: the private key of contract– e.g. “_0xu82h…7237_”. + `owner_address`: the address of contract owner – e.g. “_0xu82h…7237_”. + `url`: the url for the witness – e.g. “_https://www.noonetrust.com_”. + + message WitnessCreateContract {
 + bytes owner_address = 1;
 + bytes private_key = 2;
 + bytes url = 12;
 + } + + A `WitnessUpdateContract` contains 2 parameters: + `owner_address`: the address of contract owner – e.g. “_0xu82h…7237_”. + `update_url`: the url for the witness – e.g. “_https://www.noonetrust.com_”. + + message WitnessUpdateContract { + bytes owner_address = 1; + bytes update_url = 12; + } + + An `AssetIssueContract` contains 11 parameters: + `owner_address`: the address for contract owner – e.g. “_0xu82h…7237_”. + `name`: the name for this contract – e.g. “Billscontract”. + `total_supply`: the maximum supply of this asset – e.g. _1000000000_. + `trx_num`: the number of TRONIX – e.g._232241_. + `num`: number of corresponding asset. + `start_time`: the starting date of this contract – e.g._20170312_. + `end_time`: the expiring date of this contract – e.g. _20170512_. + `vote_score`: the vote score of this contract received – e.g. _12343_. + `description`: the description of this contract – e.g.”_trondada_”. + `url`: the url of this contract – e.g. “_https://www.noonetrust.com_”. + + message AssetIssueContract {
 + bytes owner_address = 1;
 + bytes name = 2;
 + int64 total_supply = 4;
 + int32 trx_num = 6;
 + int32 num = 8;
 + int64 start_time = 9;
 + int64 end_time = 10;
 + int32 vote_score = 16;
 + bytes description = 20;
 + bytes url = 21;
 + } + + A `ParticipateAssetIssueContract` contains 4 parameters: + `owner_address`: the address for contract owner – e.g. “_0xu82h…7237_”. + `to_address`: the receiver address – e.g. “_0xu82h…7237_”. + `asset_name`: the name of target asset. + `amount`: the amount of drops. + + message ParticipateAssetIssueContract { + bytes owner_address = 1; + bytes to_address = 2; + bytes asset_name = 3; + int64 amount = 4; + } + + A `DeployContract` contains 2 parameters: + `script`: the script of this contract. + `owner_address`: the address for contract owner – e.g. “_0xu82h…7237_”. + + message DeployContract {
 + bytes owner_address = 1;
 + bytes script = 2; + 
} t + ++ Each transaction contains several TXInputs, TXOutputs and other related qualities. +Input, transaction and head block all require signature. + + message `Transaction` contains `raw_data` and `signature`. + `raw_data`: message `raw`. + `signature`: signatures form all input nodes. + + `raw` contains 8 parameters: + `type`: the transaction type of `raw` message. + `vin`: input values. + `vout`: output values. + `expiration`: the expiration date of transaction – e.g._20170312_. + `data`: data. + `contract`: contracts in this transaction. + `scripts`:scripts in the transaction. + `timestamp`: timestamp of this raw data – e.g. _14356325_. + + message `Contract` contains `type` and `parameter`. + `type`: what type of the message contract. + `parameter`: It can be any form. + + There are 8 different of contract types: `AccountCreateContract`, `TransferContract`, `TransferAssetContract`, `VoteAssetContract`, `VoteWitnessContract`,`WitnessCreateContract`, `AssetIssueContract` and `DeployContract`. + `TransactionType` have two types: `UtxoType` and `ContractType`. + + message Transaction {
 + enum TranscationType {
 + UtxoType = 0;
 + ContractType = 1;
 + }
 + message Contract {
 + enum ContractType {
 + AccountCreateContract = 0;
 + TransferContract = 1;
 + TransferAssetContract = 2;
 + VoteAssetContract = 3;
 + VoteWitnessContract = 4;
 + WitnessCreateContract = 5;
 + AssetIssueContract = 6;
 + DeployContract = 7;
 + WitnessUpdateContract = 8; + ParticipateAssetIssueContract = 9 + }
 + ContractType type = 1;
 + google.protobuf.Any parameter = 2;
 + }
 + message raw {
 + TranscationType type = 2;
 + repeated TXInput vin = 5;
 + repeated TXOutput vout = 7;
 + int64 expiration = 8;
 + bytes data = 10;
 + repeated Contract contract = 11;
 + bytes scripts = 16;
 + int64 timestamp = 17; + }
 + raw raw_data = 1;
 + repeated bytes signature = 5; + 
} + + message `TXOutputs` contains `outputs`. + `outputs`: an array of `TXOutput`. + + message TXOutputs {
 + repeated TXOutput outputs = 1;
 + } + + message `TXOutput` contains `value` and `pubKeyHash`. + `value`: output value. + `pubKeyHash`: Hash of public key + + message TXOutput {
 + int64 value = 1;
 + bytes pubKeyHash = 2;
 + } + + message `TXInput` contains `raw_data` and `signature`. + `raw_data`: a message `raw`. + `signature`: signature for this `TXInput`. + + message `raw` contains `txID`, `vout` and `pubKey`. + `txID`: transaction ID. + `vout`: value of last output. + `pubKey`: public key. + + message TXInput {
 + message raw {
 + bytes txID = 1;
 + int64 vout = 2;
 + bytes pubKey = 3;
 + }
 + raw raw_data = 1;
 + bytes signature = 4; + 
} + + message `Result` contains `fee` and `ret`. + `ret`: the state of transaction. + `fee`: the fee for transaction. + + `code` is definition of `ret` and contains 2 types:`SUCCESS` and `FAILED`. + + message Result { + enum code { + SUCESS = 0; + FAILED = 1; + } + int64 fee = 1; + code ret = 2; + } + ++ Inventory is mainly used to inform peer nodes the list of items. + + `Inventory` contains `type` and `ids`. + `type`: what type this `Inventory` is. – e.g. _0_ stands for `TRX`. + `ids`: ID of things in this `Inventory`. + + Two `Inventory` types: `TRX` and `BLOCK`. + `TRX`: transaction. + `BLOCK`: block. + + // Inventory
 + message Inventory {
 + enum InventoryType {
 + TRX = 0;
 + BLOCK = 1;
 + }
 + InventoryType type = 1;
 + repeated bytes ids = 2;
 + } + + message `Items` contains 4 parameters: + `type`: type of items – e.g. _1_ stands for `TRX`. + `blocks`: blocks in `Items` if there is any. + `block_headers`: block headers if there is any. + `transactions`: transactions if there is any. + + `Items` have four types: `ERR`, `TRX`, `BLOCK` and `BLOCKHEADER`. + `ERR`: error. + `TRX`: transaction. + `BLOCK`: block. + `BLOCKHEADER`: block header. + + message Items {
 + enum ItemType {
 + ERR = 0;
 + TRX = 1;
 + BLOCK = 2;
 + BLOCKHEADER = 3;
 + }
 + ItemType type = 1;
 + repeated Block blocks = 2;
 + repeated BlockHeader + block_headers = 3;
 + repeated Transaction transactions = 4; + } + + `InventoryItems` contains `type` and `items`. + `type`: what type of item. + `items`: items in an `InventoryItems`. + + message InventoryItems {
 + int32 type = 1;
 + repeated bytes items = 2; + 
} + + message `BlockInventory` contains `type`. + `type`: what type of inventory. + + There are 3 types:`SYNC`, `ADVTISE`, `FETCH`. + + // Inventory + message BlockInventory { + enum Type { + SYNC = 0; + ADVTISE = 1; + FETCH = 2; + } + + message `BlockId` contains `ids` and `type`. + `ids`: the identification of block. + `type`: what type of the block. + + `ids` contains 2 paremeters: + `hash`: the hash of block. + `number`: the hash and height of block. + + message BlockId { + bytes hash = 1; + int64 number = 2; + } + repeated BlockId ids = 1; + Type type = 2; + } + + `ReasonCode`: the type of reason. + + `ReasonCode` contains 15 types of disconnect reasons: + `REQUESTED` + `TCP_ERROR` + `BAD_PROTOCOL` + `USELESS_PEER` + `TOO_MANY_PEERS` + `DUPLICATE_PEER` + `INCOMPATIBLE_PROTOCOL` + `NULL_IDENTITY` + `PEER_QUITING` + `UNEXPECTED_IDENTITY` + `LOCAL_IDENTITY` + `PING_TIMEOUT` + `USER_REASON` + `RESET` + `UNKNOWN` + + enum ReasonCode { + REQUESTED = 0; + TCP_ERROR = 1; + BAD_PROTOCOL = 2; + USELESS_PEER = 3; + TOO_MANY_PEERS = 4; + DUPLICATE_PEER = 5; + INCOMPATIBLE_PROTOCOL = 6; + NULL_IDENTITY = 7; + PEER_QUITING = 8; + UNEXPECTED_IDENTITY = 9; + LOCAL_IDENTITY = 10; + PING_TIMEOUT = 11; + USER_REASON = 12; + RESET = 16; + UNKNOWN = 255; + } + + message`DisconnectMessage` contains `reason`. + `DisconnectMessage`: the message when disconnection occurs. + `reason`: the reason for disconnecting. + + message`HelloMessage` contains 2 parameters: + `HelloMessage`: the message for building connection. + `from`: the nodes that request for building connection. + `version`: the version when connection is built. + + + ++ Wallet Service RPC and blockchain explorer + + `Wallet` service contains several RPCs. + __`GetBalance`__ : + Return balance of an `Account`. + __`CreateTransaction`__ : + Create a transaction by giving a `TransferContract`. A Transaction containing a transaction creation will be returned. + __`BroadcastTransaction`__ : + Broadcast a `Transaction`. A `Return` will be returned indicating if broadcast is success of not. + __`CreateAccount`__ : + Create an account by giving a `AccountCreateContract`. + __`CreatAssetIssue`__ : + Issue an asset by giving a `AssetIssueContract`. + __`ListAccounts`__: + Check out the list of accounts by giving a `ListAccounts`. + __`UpdateAccount`__: + Issue an asset by giving a `UpdateAccountContract`. + __`VoteWitnessAccount`__: + Issue an asset by giving a `VoteWitnessContract`. + __`WitnessList`__: + Check out the list of witnesses by giving a `WitnessList`. + __`UpdateWitness`__: + Issue an asset by giving a `WitnessUpdateContract`. + __`CreateWitness`__: + Issue an asset by giving a `WitnessCreateContract`. + __`TransferAsset`__: + Issue an asset by giving a `TransferAssetContract`. + __`ParticipateAssetIssue`__: + Issue an asset by giving a `ParticipateAssetIssueContract`. + __`ListNodes`__: + Check out the list of nodes by giving a `ListNodes`. + __`GetAssetIssueList`__: + Get the list of issue asset by giving a `GetAssetIssueList`. + __`GetAssetIssueByAccount`__: + Get issue asset by giving a `Account`. + __`GetAssetIssueByName`__: + Get issue asset by giving a`Name`. + __`GetNowBlock`__: + Get block. + __`GetBlockByNum`__: + Get block by block number. + __`TotalTransaction`__: + Check out the total transaction. + + service Wallet { + + rpc GetAccount (Account) returns (Account) { + + }; + + rpc CreateTransaction (TransferContract) returns (Transaction) { + + }; + + rpc BroadcastTransaction (Transaction) returns (Return) { + + }; + + rpc ListAccounts (EmptyMessage) returns (AccountList) { + + }; + + rpc UpdateAccount (AccountUpdateContract) returns (Transaction) { + + }; + + rpc CreateAccount (AccountCreateContract) returns (Transaction) { + + }; + + rpc VoteWitnessAccount (VoteWitnessContract) returns (Transaction) { + + }; + + rpc CreateAssetIssue (AssetIssueContract) returns (Transaction) { + + }; + + rpc ListWitnesses (EmptyMessage) returns (WitnessList) { + + }; + + rpc UpdateWitness (WitnessUpdateContract) returns (Transaction) { + + }; + + rpc CreateWitness (WitnessCreateContract) returns (Transaction) { + + }; + + rpc TransferAsset (TransferAssetContract) returns (Transaction) { + + } + + rpc ParticipateAssetIssue (ParticipateAssetIssueContract) returns (Transaction) { + + } + + rpc ListNodes (EmptyMessage) returns (NodeList) { + + } + rpc GetAssetIssueList (EmptyMessage) returns (AssetIssueList) { + + } + rpc GetAssetIssueByAccount (Account) returns (AssetIssueList) { + + } + rpc GetAssetIssueByName (BytesMessage) returns (AssetIssueContract) { + + } + rpc GetNowBlock (EmptyMessage) returns (Block) { + + } + rpc GetBlockByNum (NumberMessage) returns (Block) { + + } + rpc TotalTransaction (EmptyMessage) returns (NumberMessage) { + + } + }; + + `AccountList`: the list of acounts in the blockchain explorer. + message `AccountList` contains one parameter: + `account`: + + message AccountList { + repeated Account accounts = 1; + } + + `WitnessList`: the list of witnesses in the blockchain explorer. + message `WitnessList` contains one parameter: + `witnesses`: + + message WitnessList { + repeated Witness witnesses = 1; + } + + `AssetIssueList`: the list of issue asset in the blockchain explorer. + message `AssetIssueList` contains one parameter: + `assetIssue`: + + message AssetIssueList { + repeated AssetIssueContract assetIssue = 1; + } + + `NodeList`: the list of nodes in the node distribution map. + message `NodeList` contains one parameter: + `nodes`: + + message NodeList { + repeated Node nodes = 1; + } + + `Address`: the address of nodes. + message`Address` contains 2 parameters: + `host`: the host of nodes. + `port`: the port number of nodes. + + message Address { + bytes host = 1; + int32 port = 2; + } + + message `Return` has only one parameter: + `result`: a bool flag. + + message `Return` {
 + bool result = 1; + 
} + ++ The message structure of UDP. + + `Endpoint`: the storage structure of nodes' information. + message`Endpoint` contains 3 parameters: + `address`: the address of nodes. + `port`: the port number. + `nodeId`:the ID of nodes. + + + message Endpoint { + bytes address = 1; + int32 port = 2; + bytes nodeId = 3; + } + + `PingMessage`: the message sent from one node to another in the connecting process. + message`PingMessage` contains 4 parameters: + `from`: which node does the message send from. + `to`: which node will the message send to. + `version`: the version of the Internet. + `timestamp`: the timestamp of message. + + message PingMessage { + Endpoint from = 1; + Endpoint to = 2; + int32 version = 3; + int64 timestamp = 4; + } + + `PongMessage`: the message implies that nodes are connected. + message`PongMessage` contains 3 parameters: + `from`: which node does the message send from. + `echo`: + `timestamp`: the timestamp of message. + + message PongMessage { + Endpoint from = 1; + int32 echo = 2; + int64 timestamp = 3; + } + + `FindNeighbours`: the message sent from one node to find another one. + message`FindNeighbours` contains 3 parameters: + `from`: which node does the message send from. + `targetId`: the ID of targeted node. + `timestamp`: the timestamp of message. + + message FindNeighbours { + Endpoint from = 1; + bytes targetId = 2; + int64 timestamp = 3; + } + + `FindNeighbour`: the message replied by the neighbour node. + message`Neighbours` contains 3 parameters: + `from`: which node does the message send from. + `neighbours`: the neighbour node. + `timestamp`: the timestamp of message. + + message Neighbours { + Endpoint from = 1; + repeated Endpoint neighbours = 2; + int64 timestamp = 3; + } + + + +# Please check detailed protocol document that may change with the iteration of the program at any time. Please refer to the latest version. diff --git a/packages/kos/src/protos/tron/LICENSE b/packages/kos/src/protos/tron/LICENSE new file mode 100644 index 0000000..65c5ca8 --- /dev/null +++ b/packages/kos/src/protos/tron/LICENSE @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/packages/kos/src/protos/tron/README.md b/packages/kos/src/protos/tron/README.md new file mode 100644 index 0000000..e409e04 --- /dev/null +++ b/packages/kos/src/protos/tron/README.md @@ -0,0 +1,13 @@ +# protocol [![Build Status](https://travis-ci.org/tronprotocol/protocol.svg?branch=master)](https://travis-ci.org/tronprotocol/protocol) + + +# The protocol of Tron including api and message. + +The protocol is an independent project. You can use it for building other application. + +java-tron, wallet-cli and grpc-gateway + +git subtree pull --prefix src/main/protos/ protocol master + +## Run the included *.sh files to initialize the dependencies + diff --git a/packages/kos/src/protos/tron/api/api.proto b/packages/kos/src/protos/tron/api/api.proto new file mode 100644 index 0000000..9a7534c --- /dev/null +++ b/packages/kos/src/protos/tron/api/api.proto @@ -0,0 +1,1534 @@ +syntax = "proto3"; +package protocol; + +import "core/Tron.proto"; +import "google/api/annotations.proto"; + +import "core/contract/asset_issue_contract.proto"; +import "core/contract/account_contract.proto"; +import "core/contract/witness_contract.proto"; +import "core/contract/balance_contract.proto"; +import "core/contract/proposal_contract.proto"; +import "core/contract/storage_contract.proto"; +import "core/contract/exchange_contract.proto"; +import "core/contract/market_contract.proto"; +import "core/contract/smart_contract.proto"; +import "core/contract/shield_contract.proto"; + +option java_package = "org.tron.api"; //Specify the name of the package that generated the Java file +option java_outer_classname = "GrpcAPI"; //Specify the class name of the generated Java file +option go_package = "github.com/tronprotocol/grpc-gateway/api"; + +service Wallet { + + rpc GetAccount (Account) returns (Account) { + option (google.api.http) = { + post: "/wallet/getaccount" + body: "*" + additional_bindings { + get: "/wallet/getaccount" + } + }; + }; + + rpc GetAccountById (Account) returns (Account) { + option (google.api.http) = { + post: "/wallet/getaccountbyid" + body: "*" + additional_bindings { + get: "/wallet/getaccountbyid" + } + }; + }; + + rpc GetAccountBalance (AccountBalanceRequest) returns (AccountBalanceResponse) { + option (google.api.http) = { + post: "/wallet/getaccountbalance" + body: "*" + additional_bindings { + get: "/wallet/getaccountbalance" + } + }; + }; + + rpc GetBlockBalanceTrace (BlockBalanceTrace.BlockIdentifier) returns (BlockBalanceTrace) { + option (google.api.http) = { + post: "/wallet/getblockbalancetrace" + body: "*" + additional_bindings { + get: "/wallet/getblockbalancetrace" + } + }; + }; + + //Please use CreateTransaction2 instead of this function. + rpc CreateTransaction (TransferContract) returns (Transaction) { + option (google.api.http) = { + post: "/wallet/createtransaction" + body: "*" + additional_bindings { + get: "/wallet/createtransaction" + } + }; + }; + //Use this function instead of CreateTransaction. + rpc CreateTransaction2 (TransferContract) returns (TransactionExtention) { + }; + + rpc BroadcastTransaction (Transaction) returns (Return) { + option (google.api.http) = { + post: "/wallet/broadcasttransaction" + body: "*" + additional_bindings { + get: "/wallet/broadcasttransaction" + } + }; + }; + //Please use UpdateAccount2 instead of this function. + rpc UpdateAccount (AccountUpdateContract) returns (Transaction) { + option (google.api.http) = { + post: "/wallet/updateaccount" + body: "*" + additional_bindings { + get: "/wallet/updateaccount" + } + }; + }; + + + rpc SetAccountId (SetAccountIdContract) returns (Transaction) { + option (google.api.http) = { + post: "/wallet/setaccountid" + body: "*" + additional_bindings { + get: "/wallet/setaccountid" + } + }; + }; + + //Use this function instead of UpdateAccount. + rpc UpdateAccount2 (AccountUpdateContract) returns (TransactionExtention) { + }; + + //Please use VoteWitnessAccount2 instead of this function. + rpc VoteWitnessAccount (VoteWitnessContract) returns (Transaction) { + option (google.api.http) = { + post: "/wallet/votewitnessaccount" + body: "*" + additional_bindings { + get: "/wallet/votewitnessaccount" + } + }; + }; + + //modify the consume_user_resource_percent + rpc UpdateSetting (UpdateSettingContract) returns (TransactionExtention) { + }; + + //modify the energy_limit + rpc UpdateEnergyLimit (UpdateEnergyLimitContract) returns (TransactionExtention) { + }; + + //Use this function instead of VoteWitnessAccount. + rpc VoteWitnessAccount2 (VoteWitnessContract) returns (TransactionExtention) { + }; + //Please use CreateAssetIssue2 instead of this function. + rpc CreateAssetIssue (AssetIssueContract) returns (Transaction) { + option (google.api.http) = { + post: "/wallet/createassetissue" + body: "*" + additional_bindings { + get: "/wallet/createassetissue" + } + }; + }; + //Use this function instead of CreateAssetIssue. + rpc CreateAssetIssue2 (AssetIssueContract) returns (TransactionExtention) { + }; + //Please use UpdateWitness2 instead of this function. + rpc UpdateWitness (WitnessUpdateContract) returns (Transaction) { + option (google.api.http) = { + post: "/wallet/updatewitness" + body: "*" + additional_bindings { + get: "/wallet/updatewitness" + } + }; + }; + //Use this function instead of UpdateWitness. + rpc UpdateWitness2 (WitnessUpdateContract) returns (TransactionExtention) { + }; + //Please use CreateAccount2 instead of this function. + rpc CreateAccount (AccountCreateContract) returns (Transaction) { + option (google.api.http) = { + post: "/wallet/createaccount" + body: "*" + additional_bindings { + get: "/wallet/createaccount" + } + }; + }; + //Use this function instead of CreateAccount. + rpc CreateAccount2 (AccountCreateContract) returns (TransactionExtention) { + } + + //Please use CreateWitness2 instead of this function. + rpc CreateWitness (WitnessCreateContract) returns (Transaction) { + option (google.api.http) = { + post: "/wallet/createwitness" + body: "*" + additional_bindings { + get: "/wallet/createwitness" + } + }; + }; + //Use this function instead of CreateWitness. + rpc CreateWitness2 (WitnessCreateContract) returns (TransactionExtention) { + } + //Please use TransferAsset2 instead of this function. + rpc TransferAsset (TransferAssetContract) returns (Transaction) { + option (google.api.http) = { + post: "/wallet/transferasset" + body: "*" + additional_bindings { + get: "/wallet/transferasset" + } + }; + } + //Use this function instead of TransferAsset. + rpc TransferAsset2 (TransferAssetContract) returns (TransactionExtention) { + } + //Please use ParticipateAssetIssue2 instead of this function. + rpc ParticipateAssetIssue (ParticipateAssetIssueContract) returns (Transaction) { + option (google.api.http) = { + post: "/wallet/participateassetissue" + body: "*" + additional_bindings { + get: "/wallet/participateassetissue" + } + }; + } + //Use this function instead of ParticipateAssetIssue. + rpc ParticipateAssetIssue2 (ParticipateAssetIssueContract) returns (TransactionExtention) { + } + //Please use FreezeBalance2 instead of this function. + rpc FreezeBalance (FreezeBalanceContract) returns (Transaction) { + option (google.api.http) = { + post: "/wallet/freezebalance" + body: "*" + additional_bindings { + get: "/wallet/freezebalance" + } + }; + } + //Use this function instead of FreezeBalance. + rpc FreezeBalance2 (FreezeBalanceContract) returns (TransactionExtention) { + } + //Use this function when FreezeBalanceV2. + rpc FreezeBalanceV2 (FreezeBalanceV2Contract) returns (TransactionExtention) { + } + + //Please use UnfreezeBalance2 instead of this function. + rpc UnfreezeBalance (UnfreezeBalanceContract) returns (Transaction) { + option (google.api.http) = { + post: "/wallet/unfreezebalance" + body: "*" + additional_bindings { + get: "/wallet/unfreezebalance" + } + }; + } + //Use this function instead of UnfreezeBalance. + rpc UnfreezeBalance2 (UnfreezeBalanceContract) returns (TransactionExtention) { + } + //Use this function when UnfreezeBalanceV2. + rpc UnfreezeBalanceV2 (UnfreezeBalanceV2Contract) returns (TransactionExtention) { + } + + //Please use UnfreezeAsset2 instead of this function. + rpc UnfreezeAsset (UnfreezeAssetContract) returns (Transaction) { + option (google.api.http) = { + post: "/wallet/unfreezeasset" + body: "*" + additional_bindings { + get: "/wallet/unfreezeasset" + } + }; + } + //Use this function instead of UnfreezeAsset. + rpc UnfreezeAsset2 (UnfreezeAssetContract) returns (TransactionExtention) { + } + //Please use WithdrawBalance2 instead of this function. + rpc WithdrawBalance (WithdrawBalanceContract) returns (Transaction) { + option (google.api.http) = { + post: "/wallet/withdrawbalance" + body: "*" + additional_bindings { + get: "/wallet/withdrawbalance" + } + }; + } + //Use this function instead of WithdrawBalance. + rpc WithdrawBalance2 (WithdrawBalanceContract) returns (TransactionExtention) { + } + + rpc WithdrawExpireUnfreeze (WithdrawExpireUnfreezeContract) returns (TransactionExtention) { + } + + rpc DelegateResource (DelegateResourceContract) returns (TransactionExtention) { + } + + rpc UnDelegateResource (UnDelegateResourceContract) returns (TransactionExtention) { + } + + rpc CancelAllUnfreezeV2 (CancelAllUnfreezeV2Contract) returns (TransactionExtention) { + } + + //Please use UpdateAsset2 instead of this function. + rpc UpdateAsset (UpdateAssetContract) returns (Transaction) { + option (google.api.http) = { + post: "/wallet/updateasset" + body: "*" + additional_bindings { + get: "/wallet/updateasset" + } + }; + } + //Use this function instead of UpdateAsset. + rpc UpdateAsset2 (UpdateAssetContract) returns (TransactionExtention) { + } + + rpc ProposalCreate (ProposalCreateContract) returns (TransactionExtention) { + } + + rpc ProposalApprove (ProposalApproveContract) returns (TransactionExtention) { + } + + rpc ProposalDelete (ProposalDeleteContract) returns (TransactionExtention) { + } + + rpc BuyStorage (BuyStorageContract) returns (TransactionExtention) { + } + + rpc BuyStorageBytes (BuyStorageBytesContract) returns (TransactionExtention) { + } + + rpc SellStorage (SellStorageContract) returns (TransactionExtention) { + } + + rpc ExchangeCreate (ExchangeCreateContract) returns (TransactionExtention) { + } + + rpc ExchangeInject (ExchangeInjectContract) returns (TransactionExtention) { + } + + rpc ExchangeWithdraw (ExchangeWithdrawContract) returns (TransactionExtention) { + } + + rpc ExchangeTransaction (ExchangeTransactionContract) returns (TransactionExtention) { + } + + rpc MarketSellAsset (MarketSellAssetContract) returns (TransactionExtention) { + } + + rpc MarketCancelOrder (MarketCancelOrderContract) returns (TransactionExtention) { + } + + rpc GetMarketOrderById (BytesMessage) returns (MarketOrder) { + } + + rpc GetMarketOrderByAccount (BytesMessage) returns (MarketOrderList) { + } + + rpc GetMarketPriceByPair (MarketOrderPair) returns (MarketPriceList) { + } + + rpc GetMarketOrderListByPair (MarketOrderPair) returns (MarketOrderList) { + } + + rpc GetMarketPairList (EmptyMessage) returns (MarketOrderPairList) { + } + + + rpc ListNodes (EmptyMessage) returns (NodeList) { + option (google.api.http) = { + post: "/wallet/listnodes" + body: "*" + additional_bindings { + get: "/wallet/listnodes" + } + }; + } + + rpc GetAssetIssueByAccount (Account) returns (AssetIssueList) { + option (google.api.http) = { + post: "/wallet/getassetissuebyaccount" + body: "*" + additional_bindings { + get: "/wallet/getassetissuebyaccount" + } + }; + } + rpc GetAccountNet (Account) returns (AccountNetMessage) { + option (google.api.http) = { + post: "/wallet/getaccountnet" + body: "*" + additional_bindings { + get: "/wallet/getaccountnet" + } + }; + }; + rpc GetAccountResource (Account) returns (AccountResourceMessage) { + }; + rpc GetAssetIssueByName (BytesMessage) returns (AssetIssueContract) { + option (google.api.http) = { + post: "/wallet/getassetissuebyname" + body: "*" + additional_bindings { + get: "/wallet/getassetissuebyname" + } + }; + } + rpc GetAssetIssueListByName (BytesMessage) returns (AssetIssueList) { + } + rpc GetAssetIssueById (BytesMessage) returns (AssetIssueContract) { + } + //Please use GetNowBlock2 instead of this function. + rpc GetNowBlock (EmptyMessage) returns (Block) { + option (google.api.http) = { + post: "/wallet/getnowblock" + body: "*" + additional_bindings { + get: "/wallet/getnowblock" + } + }; + } + //Use this function instead of GetNowBlock. + rpc GetNowBlock2 (EmptyMessage) returns (BlockExtention) { + } + //Please use GetBlockByNum2 instead of this function. + rpc GetBlockByNum (NumberMessage) returns (Block) { + option (google.api.http) = { + post: "/wallet/getblockbynum" + body: "*" + additional_bindings { + get: "/wallet/getblockbynum" + } + }; + } + //Use this function instead of GetBlockByNum. + rpc GetBlockByNum2 (NumberMessage) returns (BlockExtention) { + } + + rpc GetTransactionCountByBlockNum (NumberMessage) returns (NumberMessage) { + } + + rpc GetBlockById (BytesMessage) returns (Block) { + option (google.api.http) = { + post: "/wallet/getblockbyid" + body: "*" + additional_bindings { + get: "/wallet/getblockbyid" + } + }; + } + //Please use GetBlockByLimitNext2 instead of this function. + rpc GetBlockByLimitNext (BlockLimit) returns (BlockList) { + option (google.api.http) = { + post: "/wallet/getblockbylimitnext" + body: "*" + additional_bindings { + get: "/wallet/getblockbylimitnext" + } + }; + } + //Use this function instead of GetBlockByLimitNext. + rpc GetBlockByLimitNext2 (BlockLimit) returns (BlockListExtention) { + } + //Please use GetBlockByLatestNum2 instead of this function. + rpc GetBlockByLatestNum (NumberMessage) returns (BlockList) { + option (google.api.http) = { + post: "/wallet/getblockbylatestnum" + body: "*" + additional_bindings { + get: "/wallet/getblockbylatestnum" + } + }; + } + //Use this function instead of GetBlockByLatestNum. + rpc GetBlockByLatestNum2 (NumberMessage) returns (BlockListExtention) { + } + rpc GetTransactionById (BytesMessage) returns (Transaction) { + option (google.api.http) = { + post: "/wallet/gettransactionbyid" + body: "*" + additional_bindings { + get: "/wallet/gettransactionbyid" + } + }; + } + + rpc DeployContract (CreateSmartContract) returns (TransactionExtention) { + } + + rpc GetContract (BytesMessage) returns (SmartContract) { + } + + rpc GetContractInfo (BytesMessage) returns (SmartContractDataWrapper) { + } + + rpc TriggerContract (TriggerSmartContract) returns (TransactionExtention) { + } + + rpc TriggerConstantContract (TriggerSmartContract) returns (TransactionExtention) { + } + + rpc EstimateEnergy (TriggerSmartContract) returns (EstimateEnergyMessage) { + } + + rpc ClearContractABI (ClearABIContract) returns (TransactionExtention) { + } + + rpc ListWitnesses (EmptyMessage) returns (WitnessList) { + option (google.api.http) = { + post: "/wallet/listwitnesses" + body: "*" + additional_bindings { + get: "/wallet/listwitnesses" + } + }; + }; + + + rpc GetDelegatedResource (DelegatedResourceMessage) returns (DelegatedResourceList) { + }; + + rpc GetDelegatedResourceV2 (DelegatedResourceMessage) returns (DelegatedResourceList) { + }; + + rpc GetDelegatedResourceAccountIndex (BytesMessage) returns (DelegatedResourceAccountIndex) { + }; + + rpc GetDelegatedResourceAccountIndexV2 (BytesMessage) returns (DelegatedResourceAccountIndex) { + }; + + rpc GetCanDelegatedMaxSize (CanDelegatedMaxSizeRequestMessage) returns (CanDelegatedMaxSizeResponseMessage) { + }; + + rpc GetAvailableUnfreezeCount (GetAvailableUnfreezeCountRequestMessage) + returns (GetAvailableUnfreezeCountResponseMessage) { + }; + + rpc GetCanWithdrawUnfreezeAmount (CanWithdrawUnfreezeAmountRequestMessage) + returns (CanWithdrawUnfreezeAmountResponseMessage) { + } + + rpc ListProposals (EmptyMessage) returns (ProposalList) { + option (google.api.http) = { + post: "/wallet/listproposals" + body: "*" + additional_bindings { + get: "/wallet/listproposals" + } + }; + }; + rpc GetPaginatedProposalList (PaginatedMessage) returns (ProposalList) { + option (google.api.http) = { + post: "/wallet/getpaginatedproposallist" + body: "*" + additional_bindings { + get: "/wallet/getpaginatedproposallist" + } + }; + } + rpc GetProposalById (BytesMessage) returns (Proposal) { + option (google.api.http) = { + post: "/wallet/getproposalbyid" + body: "*" + additional_bindings { + get: "/wallet/getproposalbyid" + } + }; + }; + + rpc ListExchanges (EmptyMessage) returns (ExchangeList) { + option (google.api.http) = { + post: "/wallet/listexchanges" + body: "*" + additional_bindings { + get: "/wallet/listexchanges" + } + }; + }; + rpc GetPaginatedExchangeList (PaginatedMessage) returns (ExchangeList) { + option (google.api.http) = { + post: "/wallet/getpaginatedexchangelist" + body: "*" + additional_bindings { + get: "/wallet/getpaginatedexchangelist" + } + }; + } + rpc GetExchangeById (BytesMessage) returns (Exchange) { + option (google.api.http) = { + post: "/wallet/getexchangebyid" + body: "*" + additional_bindings { + get: "/wallet/getexchangebyid" + } + }; + }; + + rpc GetChainParameters (EmptyMessage) returns (ChainParameters) { + option (google.api.http) = { + post: "/wallet/getchainparameters" + body: "*" + additional_bindings { + get: "/wallet/getchainparameters" + } + }; + }; + + rpc GetAssetIssueList (EmptyMessage) returns (AssetIssueList) { + option (google.api.http) = { + post: "/wallet/getassetissuelist" + body: "*" + additional_bindings { + get: "/wallet/getassetissuelist" + } + }; + } + rpc GetPaginatedAssetIssueList (PaginatedMessage) returns (AssetIssueList) { + option (google.api.http) = { + post: "/wallet/getpaginatedassetissuelist" + body: "*" + additional_bindings { + get: "/wallet/getpaginatedassetissuelist" + } + }; + } + + + rpc TotalTransaction (EmptyMessage) returns (NumberMessage) { + option (google.api.http) = { + post: "/wallet/totaltransaction" + body: "*" + additional_bindings { + get: "/wallet/totaltransaction" + } + }; + } + rpc GetNextMaintenanceTime (EmptyMessage) returns (NumberMessage) { + option (google.api.http) = { + post: "/wallet/getnextmaintenancetime" + body: "*" + additional_bindings { + get: "/wallet/getnextmaintenancetime" + } + }; + } + + rpc GetTransactionInfoById (BytesMessage) returns (TransactionInfo) { + option (google.api.http) = { + post: "/wallet/gettransactioninfobyid" + body: "*" + additional_bindings { + get: "/wallet/gettransactioninfobyid" + } + }; + } + + rpc AccountPermissionUpdate (AccountPermissionUpdateContract) returns (TransactionExtention) { + option (google.api.http) = { + post: "/wallet/accountpermissionupdate" + body: "*" + additional_bindings { + get: "/wallet/accountpermissionupdate" + } + }; + } + + rpc GetTransactionSignWeight (Transaction) returns (TransactionSignWeight) { + + } + + rpc GetTransactionApprovedList (Transaction) returns (TransactionApprovedList) { + + } + + rpc GetNodeInfo (EmptyMessage) returns (NodeInfo) { + }; + + rpc GetRewardInfo (BytesMessage) returns (NumberMessage) { + }; + + rpc GetBrokerageInfo (BytesMessage) returns (NumberMessage) { + }; + + rpc UpdateBrokerage (UpdateBrokerageContract) returns (TransactionExtention) { + + }; + + // for shiededTransaction + rpc CreateShieldedTransaction (PrivateParameters) returns (TransactionExtention) { + }; + + rpc GetMerkleTreeVoucherInfo (OutputPointInfo) returns (IncrementalMerkleVoucherInfo) { + } + + rpc ScanNoteByIvk (IvkDecryptParameters) returns (DecryptNotes) { + }; + + rpc ScanAndMarkNoteByIvk (IvkDecryptAndMarkParameters) returns (DecryptNotesMarked) { + }; + + rpc ScanNoteByOvk (OvkDecryptParameters) returns (DecryptNotes) { + }; + + rpc GetSpendingKey (EmptyMessage) returns (BytesMessage) { + } + + rpc GetExpandedSpendingKey (BytesMessage) returns (ExpandedSpendingKeyMessage) { + } + + rpc GetAkFromAsk (BytesMessage) returns (BytesMessage) { + } + + rpc GetNkFromNsk (BytesMessage) returns (BytesMessage) { + } + + rpc GetIncomingViewingKey (ViewingKeyMessage) returns (IncomingViewingKeyMessage) { + } + + rpc GetDiversifier (EmptyMessage) returns (DiversifierMessage) { + } + + rpc GetNewShieldedAddress (EmptyMessage) returns (ShieldedAddressInfo) { + } + + rpc GetZenPaymentAddress (IncomingViewingKeyDiversifierMessage) returns (PaymentAddressMessage) { + } + + rpc GetRcm (EmptyMessage) returns (BytesMessage) { + } + + rpc IsSpend (NoteParameters) returns (SpendResult) { + } + + rpc CreateShieldedTransactionWithoutSpendAuthSig (PrivateParametersWithoutAsk) returns (TransactionExtention) { + }; + + rpc GetShieldTransactionHash (Transaction) returns (BytesMessage) { + }; + + rpc CreateSpendAuthSig (SpendAuthSigParameters) returns (BytesMessage) { + }; + + rpc CreateShieldNullifier (NfParameters) returns (BytesMessage) { + }; + + //for shielded contract + rpc CreateShieldedContractParameters (PrivateShieldedTRC20Parameters) returns (ShieldedTRC20Parameters) { + }; + + rpc CreateShieldedContractParametersWithoutAsk (PrivateShieldedTRC20ParametersWithoutAsk) returns (ShieldedTRC20Parameters) { + }; + + rpc ScanShieldedTRC20NotesByIvk (IvkDecryptTRC20Parameters) returns (DecryptNotesTRC20) { + }; + + rpc ScanShieldedTRC20NotesByOvk (OvkDecryptTRC20Parameters) returns (DecryptNotesTRC20) { + }; + + rpc IsShieldedTRC20ContractNoteSpent (NfTRC20Parameters) returns (NullifierResult) { + }; + + rpc GetTriggerInputForShieldedTRC20Contract (ShieldedTRC20TriggerContractParameters) returns (BytesMessage) { + }; + // end for shiededTransaction + + rpc CreateCommonTransaction (Transaction) returns (TransactionExtention) { + }; + + rpc GetTransactionInfoByBlockNum (NumberMessage) returns (TransactionInfoList) { + } + + rpc GetBurnTrx (EmptyMessage) returns (NumberMessage) { + } + + rpc GetTransactionFromPending (BytesMessage) returns (Transaction) { + } + + rpc GetTransactionListFromPending (EmptyMessage) returns (TransactionIdList) { + } + + rpc GetPendingSize (EmptyMessage) returns (NumberMessage) { + } + + rpc GetBlock (BlockReq) returns (BlockExtention) { + } + + rpc GetBandwidthPrices (EmptyMessage) returns (PricesResponseMessage) { + } + + rpc GetEnergyPrices (EmptyMessage) returns (PricesResponseMessage) { + } + + rpc GetMemoFee (EmptyMessage) returns (PricesResponseMessage) { + } +}; + +service WalletSolidity { + + rpc GetAccount (Account) returns (Account) { + option (google.api.http) = { + post: "/walletsolidity/getaccount" + body: "*" + additional_bindings { + get: "/walletsolidity/getaccount" + } + }; + }; + rpc GetAccountById (Account) returns (Account) { + option (google.api.http) = { + post: "/walletsolidity/getaccountbyid" + body: "*" + additional_bindings { + get: "/walletsolidity/getaccountbyid" + } + }; + }; + + rpc ListWitnesses (EmptyMessage) returns (WitnessList) { + option (google.api.http) = { + post: "/walletsolidity/listwitnesses" + body: "*" + additional_bindings { + get: "/walletsolidity/listwitnesses" + } + }; + }; + rpc GetAssetIssueList (EmptyMessage) returns (AssetIssueList) { + option (google.api.http) = { + post: "/walletsolidity/getassetissuelist" + body: "*" + additional_bindings { + get: "/walletsolidity/getassetissuelist" + } + }; + } + rpc GetPaginatedAssetIssueList (PaginatedMessage) returns (AssetIssueList) { + option (google.api.http) = { + post: "/walletsolidity/getpaginatedassetissuelist" + body: "*" + additional_bindings { + get: "/walletsolidity/getpaginatedassetissuelist" + } + }; + } + + rpc GetAssetIssueByName (BytesMessage) returns (AssetIssueContract) { + } + rpc GetAssetIssueListByName (BytesMessage) returns (AssetIssueList) { + } + rpc GetAssetIssueById (BytesMessage) returns (AssetIssueContract) { + } + + //Please use GetNowBlock2 instead of this function. + rpc GetNowBlock (EmptyMessage) returns (Block) { + option (google.api.http) = { + post: "/walletsolidity/getnowblock" + body: "*" + additional_bindings { + get: "/walletsolidity/getnowblock" + } + }; + } + //Use this function instead of GetNowBlock. + rpc GetNowBlock2 (EmptyMessage) returns (BlockExtention) { + } + //Please use GetBlockByNum2 instead of this function. + rpc GetBlockByNum (NumberMessage) returns (Block) { + option (google.api.http) = { + post: "/walletsolidity/getblockbynum" + body: "*" + additional_bindings { + get: "/walletsolidity/getblockbynum" + } + }; + } + //Use this function instead of GetBlockByNum. + rpc GetBlockByNum2 (NumberMessage) returns (BlockExtention) { + } + + rpc GetTransactionCountByBlockNum (NumberMessage) returns (NumberMessage) { + } + + rpc GetDelegatedResource (DelegatedResourceMessage) returns (DelegatedResourceList) { + }; + + rpc GetDelegatedResourceV2 (DelegatedResourceMessage) returns (DelegatedResourceList) { + }; + + rpc GetDelegatedResourceAccountIndex (BytesMessage) returns (DelegatedResourceAccountIndex) { + }; + + rpc GetDelegatedResourceAccountIndexV2 (BytesMessage) returns (DelegatedResourceAccountIndex) { + }; + + rpc GetCanDelegatedMaxSize (CanDelegatedMaxSizeRequestMessage) returns (CanDelegatedMaxSizeResponseMessage) { + }; + + rpc GetAvailableUnfreezeCount (GetAvailableUnfreezeCountRequestMessage) + returns (GetAvailableUnfreezeCountResponseMessage) { + }; + + rpc GetCanWithdrawUnfreezeAmount (CanWithdrawUnfreezeAmountRequestMessage) + returns (CanWithdrawUnfreezeAmountResponseMessage) { + } + + rpc GetExchangeById (BytesMessage) returns (Exchange) { + }; + + rpc ListExchanges (EmptyMessage) returns (ExchangeList) { + }; + + + rpc GetTransactionById (BytesMessage) returns (Transaction) { + option (google.api.http) = { + post: "/walletsolidity/gettransactionbyid" + body: "*" + additional_bindings { + get: "/walletsolidity/gettransactionbyid" + } + }; + } + + rpc GetTransactionInfoById (BytesMessage) returns (TransactionInfo) { + option (google.api.http) = { + post: "/walletsolidity/gettransactioninfobyid" + body: "*" + additional_bindings { + get: "/walletsolidity/gettransactioninfobyid" + } + }; + } + + rpc GetMerkleTreeVoucherInfo (OutputPointInfo) returns (IncrementalMerkleVoucherInfo) { + } + + rpc ScanNoteByIvk (IvkDecryptParameters) returns (DecryptNotes) { + } + + rpc ScanAndMarkNoteByIvk (IvkDecryptAndMarkParameters) returns (DecryptNotesMarked) { + } + + rpc ScanNoteByOvk (OvkDecryptParameters) returns (DecryptNotes) { + } + + rpc IsSpend (NoteParameters) returns (SpendResult) { + } + + rpc ScanShieldedTRC20NotesByIvk (IvkDecryptTRC20Parameters) returns (DecryptNotesTRC20) { + }; + + rpc ScanShieldedTRC20NotesByOvk (OvkDecryptTRC20Parameters) returns (DecryptNotesTRC20) { + }; + + rpc IsShieldedTRC20ContractNoteSpent (NfTRC20Parameters) returns (NullifierResult) { + }; + + rpc GetRewardInfo (BytesMessage) returns (NumberMessage) { + }; + + rpc GetBrokerageInfo (BytesMessage) returns (NumberMessage) { + }; + + rpc TriggerConstantContract (TriggerSmartContract) returns (TransactionExtention) { + } + + rpc EstimateEnergy (TriggerSmartContract) returns (EstimateEnergyMessage) { + } + + rpc GetTransactionInfoByBlockNum (NumberMessage) returns (TransactionInfoList) { + } + + rpc GetMarketOrderById (BytesMessage) returns (MarketOrder) { + } + + rpc GetMarketOrderByAccount (BytesMessage) returns (MarketOrderList) { + } + + rpc GetMarketPriceByPair (MarketOrderPair) returns (MarketPriceList) { + } + + rpc GetMarketOrderListByPair (MarketOrderPair) returns (MarketOrderList) { + } + + rpc GetMarketPairList (EmptyMessage) returns (MarketOrderPairList) { + } + + rpc GetBurnTrx (EmptyMessage) returns (NumberMessage) { + } + rpc GetBlock (BlockReq) returns (BlockExtention) { + } + rpc GetBandwidthPrices (EmptyMessage) returns (PricesResponseMessage) { + } + + rpc GetEnergyPrices (EmptyMessage) returns (PricesResponseMessage) { + } +}; + +service WalletExtension { + //Please use GetTransactionsFromThis2 instead of this function. + rpc GetTransactionsFromThis (AccountPaginated) returns (TransactionList) { + option (google.api.http) = { + post: "/walletextension/gettransactionsfromthis" + body: "*" + additional_bindings { + get: "/walletextension/gettransactionsfromthis" + } + }; + } + //Use this function instead of GetTransactionsFromThis. + rpc GetTransactionsFromThis2 (AccountPaginated) returns (TransactionListExtention) { + } + //Please use GetTransactionsToThis2 instead of this function. + rpc GetTransactionsToThis (AccountPaginated) returns (TransactionList) { + option (google.api.http) = { + post: "/walletextension/gettransactionstothis" + body: "*" + additional_bindings { + get: "/walletextension/gettransactionstothis" + } + }; + } + //Use this function instead of GetTransactionsToThis. + rpc GetTransactionsToThis2 (AccountPaginated) returns (TransactionListExtention) { + } +}; + +// the api of tron's db +service Database { + // for tapos + rpc getBlockReference (EmptyMessage) returns (BlockReference) { + + } + rpc GetDynamicProperties (EmptyMessage) returns (DynamicProperties) { + + } + rpc GetNowBlock (EmptyMessage) returns (Block) { + + } + rpc GetBlockByNum (NumberMessage) returns (Block) { + + } +}; + +service Monitor { + rpc GetStatsInfo (EmptyMessage) returns (MetricsInfo) { + option (google.api.http) = { + post: "/monitor/getstatsinfo" + body: "*" + additional_bindings { + get: "/monitor/getstatsinfo" + } + }; + } +} + +message Return { + enum response_code { + SUCCESS = 0; + SIGERROR = 1; // error in signature + CONTRACT_VALIDATE_ERROR = 2; + CONTRACT_EXE_ERROR = 3; + BANDWITH_ERROR = 4; + DUP_TRANSACTION_ERROR = 5; + TAPOS_ERROR = 6; + TOO_BIG_TRANSACTION_ERROR = 7; + TRANSACTION_EXPIRATION_ERROR = 8; + SERVER_BUSY = 9; + NO_CONNECTION = 10; + NOT_ENOUGH_EFFECTIVE_CONNECTION = 11; + OTHER_ERROR = 20; + } + + bool result = 1; + response_code code = 2; + bytes message = 3; +} + +message BlockReference { + int64 block_num = 1; + bytes block_hash = 2; +} + +// the api of tron's network such as node list. +service Network { + +}; + +message WitnessList { + repeated Witness witnesses = 1; +} +message ProposalList { + repeated Proposal proposals = 1; +} +message ExchangeList { + repeated Exchange exchanges = 1; +} +message AssetIssueList { + repeated AssetIssueContract assetIssue = 1; +} +message BlockList { + repeated Block block = 1; +} +message TransactionList { + repeated Transaction transaction = 1; +} +message TransactionIdList { + repeated string txId = 1; +} +message DelegatedResourceMessage { + bytes fromAddress = 1; + bytes toAddress = 2; +} +message DelegatedResourceList { + repeated DelegatedResource delegatedResource = 1; +} + +message GetAvailableUnfreezeCountRequestMessage { + bytes owner_address = 1; +} +message GetAvailableUnfreezeCountResponseMessage { + int64 count = 1; +} + +message CanDelegatedMaxSizeRequestMessage { + int32 type = 1; + bytes owner_address = 2; +} +message CanDelegatedMaxSizeResponseMessage { + int64 max_size = 1; +} + +message CanWithdrawUnfreezeAmountRequestMessage { + bytes owner_address = 1; + int64 timestamp = 2; +} +message CanWithdrawUnfreezeAmountResponseMessage { + int64 amount = 1; +} + +message PricesResponseMessage { + string prices = 1; +} + +// Gossip node list +message NodeList { + repeated Node nodes = 1; +} + +// Gossip node +message Node { + Address address = 1; +} + +// Gossip node address +message Address { + bytes host = 1; + int32 port = 2; +} + +message EmptyMessage { +} +message NumberMessage { + int64 num = 1; +} +message BytesMessage { + bytes value = 1; +} +message TimeMessage { + int64 beginInMilliseconds = 1; + int64 endInMilliseconds = 2; +} +message BlockReq { + string id_or_num = 1; + bool detail = 2; +} +message BlockLimit { + int64 startNum = 1; + int64 endNum = 2; +} +message TransactionLimit { + bytes transactionId = 1; + int64 limitNum = 2; +} +message AccountPaginated { + Account account = 1; + int64 offset = 2; + int64 limit = 3; +} +message TimePaginatedMessage { + TimeMessage timeMessage = 1; + int64 offset = 2; + int64 limit = 3; +} +//deprecated +message AccountNetMessage { + int64 freeNetUsed = 1; + int64 freeNetLimit = 2; + int64 NetUsed = 3; + int64 NetLimit = 4; + map assetNetUsed = 5; + map assetNetLimit = 6; + int64 TotalNetLimit = 7; + int64 TotalNetWeight = 8; +} +message AccountResourceMessage { + int64 freeNetUsed = 1; + int64 freeNetLimit = 2; + int64 NetUsed = 3; + int64 NetLimit = 4; + map assetNetUsed = 5; + map assetNetLimit = 6; + int64 TotalNetLimit = 7; + int64 TotalNetWeight = 8; + int64 TotalTronPowerWeight = 9; + int64 tronPowerUsed = 10; + int64 tronPowerLimit = 11; + + int64 EnergyUsed = 13; + int64 EnergyLimit = 14; + int64 TotalEnergyLimit = 15; + int64 TotalEnergyWeight = 16; + + int64 storageUsed = 21; + int64 storageLimit = 22; +} + +message PaginatedMessage { + int64 offset = 1; + int64 limit = 2; +} + +message TransactionExtention { + Transaction transaction = 1; + bytes txid = 2; //transaction id = sha256(transaction.rowdata) + repeated bytes constant_result = 3; + Return result = 4; + int64 energy_used = 5; + repeated TransactionInfo.Log logs = 6; + repeated InternalTransaction internal_transactions = 7; + int64 energy_penalty = 8; +} + +message EstimateEnergyMessage { + Return result = 1; + int64 energy_required = 2; +} + +message BlockExtention { + repeated TransactionExtention transactions = 1; + BlockHeader block_header = 2; + bytes blockid = 3; +} + +message BlockListExtention { + repeated BlockExtention block = 1; +} + +message TransactionListExtention { + repeated TransactionExtention transaction = 1; +} + +message BlockIncrementalMerkleTree { + int64 number = 1; + IncrementalMerkleTree merkleTree = 2; +} + +message TransactionSignWeight { + message Result { + enum response_code { + ENOUGH_PERMISSION = 0; + NOT_ENOUGH_PERMISSION = 1; // error in + SIGNATURE_FORMAT_ERROR = 2; + COMPUTE_ADDRESS_ERROR = 3; + PERMISSION_ERROR = 4; //The key is not in permission + OTHER_ERROR = 20; + } + response_code code = 1; + string message = 2; + } + + Permission permission = 1; + repeated bytes approved_list = 2; + int64 current_weight = 3; + Result result = 4; + TransactionExtention transaction = 5; +} + +message TransactionApprovedList { + message Result { + enum response_code { + SUCCESS = 0; + SIGNATURE_FORMAT_ERROR = 1; + COMPUTE_ADDRESS_ERROR = 2; + OTHER_ERROR = 20; + } + response_code code = 1; + string message = 2; + } + + repeated bytes approved_list = 2; + Result result = 4; + TransactionExtention transaction = 5; +} + +message IvkDecryptParameters { + int64 start_block_index = 1; + int64 end_block_index = 2; + bytes ivk = 3; +} + +message IvkDecryptAndMarkParameters { + int64 start_block_index = 1; + int64 end_block_index = 2; + bytes ivk = 5; + bytes ak = 3; + bytes nk = 4; +} + +message OvkDecryptParameters { + int64 start_block_index = 1; + int64 end_block_index = 2; + bytes ovk = 3; +} + +message DecryptNotes { + message NoteTx { + Note note = 1; + bytes txid = 2; //transaction id = sha256(transaction.rowdata) + int32 index = 3; //the index of note in receive + } + repeated NoteTx noteTxs = 1; +} + +message DecryptNotesMarked { + message NoteTx { + Note note = 1; + bytes txid = 2; //transaction id = sha256(transaction.rowdata) + int32 index = 3; //the index of note in receive + bool is_spend = 4; + } + repeated NoteTx noteTxs = 1; +} + +message Note { + int64 value = 1; + string payment_address = 2; + bytes rcm = 3; // random 32 + bytes memo = 4; +} + +message SpendNote { + Note note = 3; + bytes alpha = 4; // random number for spend authority signature + IncrementalMerkleVoucher voucher = 5; + bytes path = 6; // path for cm from leaf to root in merkle tree +} + +message ReceiveNote { + Note note = 1; +} + +message PrivateParameters { + bytes transparent_from_address = 1; + bytes ask = 2; + bytes nsk = 3; + bytes ovk = 4; + int64 from_amount = 5; + repeated SpendNote shielded_spends = 6; + repeated ReceiveNote shielded_receives = 7; + bytes transparent_to_address = 8; + int64 to_amount = 9; + int64 timeout = 10; // timeout in seconds, it works only when it bigger than 0 +} + +message PrivateParametersWithoutAsk { + bytes transparent_from_address = 1; + bytes ak = 2; + bytes nsk = 3; + bytes ovk = 4; + int64 from_amount = 5; + repeated SpendNote shielded_spends = 6; + repeated ReceiveNote shielded_receives = 7; + bytes transparent_to_address = 8; + int64 to_amount = 9; + int64 timeout = 10; // timeout in seconds, it works only when it bigger than 0 +} + +message SpendAuthSigParameters { + bytes ask = 1; + bytes tx_hash = 2; + bytes alpha = 3; +} + +message NfParameters { + Note note = 1; + IncrementalMerkleVoucher voucher = 2; + bytes ak = 3; + bytes nk = 4; +} + +message ExpandedSpendingKeyMessage { + bytes ask = 1; + bytes nsk = 2; + bytes ovk = 3; +} + +message ViewingKeyMessage { + bytes ak = 1; + bytes nk = 2; +} + +message IncomingViewingKeyMessage { + bytes ivk = 1; +} + +message DiversifierMessage { + bytes d = 1; +} + +message IncomingViewingKeyDiversifierMessage { + IncomingViewingKeyMessage ivk = 1; + DiversifierMessage d = 2; +} + +message PaymentAddressMessage { + DiversifierMessage d = 1; + bytes pkD = 2; + string payment_address = 3; +} + +message ShieldedAddressInfo { + bytes sk = 1; + bytes ask = 2; + bytes nsk = 3; + bytes ovk = 4; + bytes ak = 5; + bytes nk = 6; + bytes ivk = 7; + bytes d = 8; + bytes pkD = 9; + string payment_address = 10; +} + +message NoteParameters { + bytes ak = 1; + bytes nk = 2; + Note note = 3; + bytes txid = 4; + int32 index = 5; +} + +message SpendResult { + bool result = 1; + string message = 2; +} + +message TransactionInfoList { + repeated TransactionInfo transactionInfo = 1; +} + +message SpendNoteTRC20 { + Note note = 1; + bytes alpha = 2; + bytes root = 3; + bytes path = 4; + int64 pos = 5; +} + +message PrivateShieldedTRC20Parameters { + bytes ask = 1; + bytes nsk = 2; + bytes ovk = 3; + string from_amount = 4; + repeated SpendNoteTRC20 shielded_spends = 5; + repeated ReceiveNote shielded_receives = 6; + bytes transparent_to_address = 7; + string to_amount = 8; + bytes shielded_TRC20_contract_address = 9; +} + +message PrivateShieldedTRC20ParametersWithoutAsk { + bytes ak = 1; + bytes nsk = 2; + bytes ovk = 3; + string from_amount = 4; + repeated SpendNoteTRC20 shielded_spends = 5; + repeated ReceiveNote shielded_receives = 6; + bytes transparent_to_address = 7; + string to_amount = 8; + bytes shielded_TRC20_contract_address = 9; +} + +message ShieldedTRC20Parameters { + repeated SpendDescription spend_description = 1; + repeated ReceiveDescription receive_description = 2; + bytes binding_signature = 3; + bytes message_hash = 4; + string trigger_contract_input = 5; + string parameter_type = 6; +} + +message IvkDecryptTRC20Parameters { + int64 start_block_index = 1; + int64 end_block_index = 2; + bytes shielded_TRC20_contract_address = 3; + bytes ivk = 4; + bytes ak = 5; + bytes nk = 6; + repeated string events = 7; +} + +message OvkDecryptTRC20Parameters { + int64 start_block_index = 1; + int64 end_block_index = 2; + bytes ovk = 3; + bytes shielded_TRC20_contract_address = 4; + repeated string events = 5; +} + +message DecryptNotesTRC20 { + message NoteTx { + Note note = 1; + int64 position = 2; + bool is_spent = 3; + bytes txid = 4; + int32 index = 5; //the index of note in txid + string to_amount = 6; + bytes transparent_to_address = 7; + } + repeated NoteTx noteTxs = 1; +} + +message NfTRC20Parameters { + Note note = 1; + bytes ak = 2; + bytes nk = 3; + int64 position = 4; + bytes shielded_TRC20_contract_address = 5; +} + +message NullifierResult { + bool is_spent = 1; +} + +message ShieldedTRC20TriggerContractParameters { + ShieldedTRC20Parameters shielded_TRC20_Parameters = 1; + repeated BytesMessage spend_authority_signature = 2; + string amount = 3; + bytes transparent_to_address = 4; +} diff --git a/packages/kos/src/protos/tron/api/zksnark.proto b/packages/kos/src/protos/tron/api/zksnark.proto new file mode 100644 index 0000000..bc0764c --- /dev/null +++ b/packages/kos/src/protos/tron/api/zksnark.proto @@ -0,0 +1,33 @@ +syntax = "proto3"; +package protocol; + +import "core/Tron.proto"; + +option java_package = "org.tron.api"; //Specify the name of the package that generated the Java file +option java_outer_classname = "ZksnarkGrpcAPI"; //Specify the class name of the generated Java file +option go_package = "github.com/tronprotocol/grpc-gateway/api"; + +service TronZksnark { + rpc CheckZksnarkProof (ZksnarkRequest) returns (ZksnarkResponse) { + } +}; + +message ZksnarkRequest { + Transaction transaction = 1; + bytes sighash = 2; + int64 valueBalance = 3; + string txId = 4; +} + +message ZksnarkResponse { + enum Code { + SUCCESS = 0; + FAILED = 1; + } + + Code code = 1; +} + + + + diff --git a/packages/kos/src/protos/tron/core/Discover.proto b/packages/kos/src/protos/tron/core/Discover.proto new file mode 100644 index 0000000..4cc0d83 --- /dev/null +++ b/packages/kos/src/protos/tron/core/Discover.proto @@ -0,0 +1,44 @@ +syntax = "proto3"; + +package protocol; + + +option java_package = "org.tron.protos"; //Specify the name of the package that generated the Java file +option java_outer_classname = "Discover"; //Specify the class name of the generated Java file +option go_package = "github.com/tronprotocol/grpc-gateway/core"; + +message Endpoint { + bytes address = 1; + int32 port = 2; + bytes nodeId = 3; +} + +message PingMessage { + Endpoint from = 1; + Endpoint to = 2; + int32 version = 3; + int64 timestamp = 4; +} + +message PongMessage { + Endpoint from = 1; + int32 echo = 2; + int64 timestamp = 3; +} + +message FindNeighbours { + Endpoint from = 1; + bytes targetId = 2; + int64 timestamp = 3; +} + +message Neighbours { + Endpoint from = 1; + repeated Endpoint neighbours = 2; + int64 timestamp = 3; +} + +message BackupMessage { + bool flag = 1; + int32 priority = 2; +} \ No newline at end of file diff --git a/packages/kos/src/protos/tron/core/Tron.proto b/packages/kos/src/protos/tron/core/Tron.proto new file mode 100644 index 0000000..2fc0890 --- /dev/null +++ b/packages/kos/src/protos/tron/core/Tron.proto @@ -0,0 +1,891 @@ +syntax = "proto3"; + +import "google/protobuf/any.proto"; +import "core/Discover.proto"; +import "core/contract/common.proto"; + +package protocol; + + +option java_package = "org.tron.protos"; //Specify the name of the package that generated the Java file +option java_outer_classname = "Protocol"; //Specify the class name of the generated Java file +option go_package = "github.com/tronprotocol/grpc-gateway/core"; + +enum AccountType { + Normal = 0; + AssetIssue = 1; + Contract = 2; +} + +// AccountId, (name, address) use name, (null, address) use address, (name, null) use name, +message AccountId { + bytes name = 1; + bytes address = 2; +} + +// vote message +message Vote { + // the super rep address + bytes vote_address = 1; + // the vote num to this super rep. + int64 vote_count = 2; +} + +// Proposal +message Proposal { + int64 proposal_id = 1; + bytes proposer_address = 2; + map parameters = 3; + int64 expiration_time = 4; + int64 create_time = 5; + repeated bytes approvals = 6; + enum State { + PENDING = 0; + DISAPPROVED = 1; + APPROVED = 2; + CANCELED = 3; + } + State state = 7; +} + +// Exchange +message Exchange { + int64 exchange_id = 1; + bytes creator_address = 2; + int64 create_time = 3; + bytes first_token_id = 6; + int64 first_token_balance = 7; + bytes second_token_id = 8; + int64 second_token_balance = 9; +} + +// market +message MarketOrder { + bytes order_id = 1; + bytes owner_address = 2; + int64 create_time = 3; + bytes sell_token_id = 4; + int64 sell_token_quantity = 5; + bytes buy_token_id = 6; + int64 buy_token_quantity = 7; // min to receive + int64 sell_token_quantity_remain = 9; + // When state != ACTIVE and sell_token_quantity_return !=0, + //it means that some sell tokens are returned to the account due to insufficient remaining amount + int64 sell_token_quantity_return = 10; + + enum State { + ACTIVE = 0; + INACTIVE = 1; + CANCELED = 2; + } + State state = 11; + + bytes prev = 12; + bytes next = 13; +} + +message MarketOrderList { + repeated MarketOrder orders = 1; +} + +message MarketOrderPairList { + repeated MarketOrderPair orderPair = 1; +} + +message MarketOrderPair{ + bytes sell_token_id = 1; + bytes buy_token_id = 2; +} + +message MarketAccountOrder { + bytes owner_address = 1; + repeated bytes orders = 2; // order_id list + int64 count = 3; // active count + int64 total_count = 4; +} + +message MarketPrice { + int64 sell_token_quantity = 1; + int64 buy_token_quantity = 2; +} + +message MarketPriceList { + bytes sell_token_id = 1; + bytes buy_token_id = 2; + repeated MarketPrice prices = 3; +} + +message MarketOrderIdList { + bytes head = 1; + bytes tail = 2; +} + +message ChainParameters { + repeated ChainParameter chainParameter = 1; + message ChainParameter { + string key = 1; + int64 value = 2; + } +} + +/* Account */ +message Account { + /* frozen balance */ + message Frozen { + int64 frozen_balance = 1; // the frozen trx balance + int64 expire_time = 2; // the expire time + } + // account nick name + bytes account_name = 1; + AccountType type = 2; + // the create address + bytes address = 3; + // the trx balance + int64 balance = 4; + // the votes + repeated Vote votes = 5; + // the other asset owned by this account + map asset = 6; + + // the other asset owned by this account,key is assetId + map assetV2 = 56; + + // the frozen balance for bandwidth + repeated Frozen frozen = 7; + // bandwidth, get from frozen + int64 net_usage = 8; + //Frozen balance provided by other accounts to this account + int64 acquired_delegated_frozen_balance_for_bandwidth = 41; + //Freeze and provide balances to other accounts + int64 delegated_frozen_balance_for_bandwidth = 42; + + int64 old_tron_power = 46; + Frozen tron_power = 47; + + bool asset_optimized = 60; + + // this account create time + int64 create_time = 0x09; + // this last operation time, including transfer, voting and so on. //FIXME fix grammar + int64 latest_opration_time = 10; + // witness block producing allowance + int64 allowance = 0x0B; + // last withdraw time + int64 latest_withdraw_time = 0x0C; + // not used so far + bytes code = 13; + bool is_witness = 14; + bool is_committee = 15; + // frozen asset(for asset issuer) + repeated Frozen frozen_supply = 16; + // asset_issued_name + bytes asset_issued_name = 17; + bytes asset_issued_ID = 57; + map latest_asset_operation_time = 18; + map latest_asset_operation_timeV2 = 58; + int64 free_net_usage = 19; + map free_asset_net_usage = 20; + map free_asset_net_usageV2 = 59; + int64 latest_consume_time = 21; + int64 latest_consume_free_time = 22; + + // the identity of this account, case insensitive + bytes account_id = 23; + + int64 net_window_size = 24; + bool net_window_optimized = 25; + + message AccountResource { + // energy resource, get from frozen + int64 energy_usage = 1; + // the frozen balance for energy + Frozen frozen_balance_for_energy = 2; + int64 latest_consume_time_for_energy = 3; + + //Frozen balance provided by other accounts to this account + int64 acquired_delegated_frozen_balance_for_energy = 4; + //Frozen balances provided to other accounts + int64 delegated_frozen_balance_for_energy = 5; + + // storage resource, get from market + int64 storage_limit = 6; + int64 storage_usage = 7; + int64 latest_exchange_storage_time = 8; + + int64 energy_window_size = 9; + + int64 delegated_frozenV2_balance_for_energy = 10; + int64 acquired_delegated_frozenV2_balance_for_energy = 11; + bool energy_window_optimized = 12; + } + AccountResource account_resource = 26; + bytes codeHash = 30; + Permission owner_permission = 31; + Permission witness_permission = 32; + repeated Permission active_permission = 33; + + message FreezeV2 { + ResourceCode type = 1; + int64 amount = 2; + } + message UnFreezeV2 { + ResourceCode type = 1; + int64 unfreeze_amount = 3; + int64 unfreeze_expire_time = 4; + } + repeated FreezeV2 frozenV2 = 34; + repeated UnFreezeV2 unfrozenV2 = 35; + + int64 delegated_frozenV2_balance_for_bandwidth = 36; + int64 acquired_delegated_frozenV2_balance_for_bandwidth = 37; +} + +message Key { + bytes address = 1; + int64 weight = 2; +} + +message DelegatedResource { + bytes from = 1; + bytes to = 2; + int64 frozen_balance_for_bandwidth = 3; + int64 frozen_balance_for_energy = 4; + int64 expire_time_for_bandwidth = 5; + int64 expire_time_for_energy = 6; +} + +message authority { + AccountId account = 1; + bytes permission_name = 2; +} + +message Permission { + enum PermissionType { + Owner = 0; + Witness = 1; + Active = 2; + } + PermissionType type = 1; + int32 id = 2; //Owner id=0, Witness id=1, Active id start by 2 + string permission_name = 3; + int64 threshold = 4; + int32 parent_id = 5; + bytes operations = 6; //1 bit 1 contract + repeated Key keys = 7; +} + +// Witness +message Witness { + bytes address = 1; + int64 voteCount = 2; + bytes pubKey = 3; + string url = 4; + int64 totalProduced = 5; + int64 totalMissed = 6; + int64 latestBlockNum = 7; + int64 latestSlotNum = 8; + bool isJobs = 9; +} + +// Vote Change +message Votes { + bytes address = 1; + repeated Vote old_votes = 2; + repeated Vote new_votes = 3; +} + +// Transcation + +message TXOutput { + int64 value = 1; + bytes pubKeyHash = 2; +} + +message TXInput { + message raw { + bytes txID = 1; + int64 vout = 2; + bytes pubKey = 3; + } + raw raw_data = 1; + bytes signature = 4; +} + +message TXOutputs { + repeated TXOutput outputs = 1; +} + +message ResourceReceipt { + int64 energy_usage = 1; + int64 energy_fee = 2; + int64 origin_energy_usage = 3; + int64 energy_usage_total = 4; + int64 net_usage = 5; + int64 net_fee = 6; + Transaction.Result.contractResult result = 7; + int64 energy_penalty_total = 8; +} + +message MarketOrderDetail { + bytes makerOrderId = 1; + bytes takerOrderId = 2; + int64 fillSellQuantity = 3; + int64 fillBuyQuantity = 4; +} + +message Transaction { + message Contract { + enum ContractType { + AccountCreateContract = 0; + TransferContract = 1; + TransferAssetContract = 2; + VoteAssetContract = 3; + VoteWitnessContract = 4; + WitnessCreateContract = 5; + AssetIssueContract = 6; + WitnessUpdateContract = 8; + ParticipateAssetIssueContract = 9; + AccountUpdateContract = 10; + FreezeBalanceContract = 11; + UnfreezeBalanceContract = 12; + WithdrawBalanceContract = 13; + UnfreezeAssetContract = 14; + UpdateAssetContract = 15; + ProposalCreateContract = 16; + ProposalApproveContract = 17; + ProposalDeleteContract = 18; + SetAccountIdContract = 19; + CustomContract = 20; + CreateSmartContract = 30; + TriggerSmartContract = 31; + GetContract = 32; + UpdateSettingContract = 33; + ExchangeCreateContract = 41; + ExchangeInjectContract = 42; + ExchangeWithdrawContract = 43; + ExchangeTransactionContract = 44; + UpdateEnergyLimitContract = 45; + AccountPermissionUpdateContract = 46; + ClearABIContract = 48; + UpdateBrokerageContract = 49; + ShieldedTransferContract = 51; + MarketSellAssetContract = 52; + MarketCancelOrderContract = 53; + FreezeBalanceV2Contract = 54; + UnfreezeBalanceV2Contract = 55; + WithdrawExpireUnfreezeContract = 56; + DelegateResourceContract = 57; + UnDelegateResourceContract = 58; + CancelAllUnfreezeV2Contract = 59; + } + ContractType type = 1; + google.protobuf.Any parameter = 2; + bytes provider = 3; + bytes ContractName = 4; + int32 Permission_id = 5; + } + + message Result { + enum code { + SUCESS = 0; + FAILED = 1; + } + enum contractResult { + DEFAULT = 0; + SUCCESS = 1; + REVERT = 2; + BAD_JUMP_DESTINATION = 3; + OUT_OF_MEMORY = 4; + PRECOMPILED_CONTRACT = 5; + STACK_TOO_SMALL = 6; + STACK_TOO_LARGE = 7; + ILLEGAL_OPERATION = 8; + STACK_OVERFLOW = 9; + OUT_OF_ENERGY = 10; + OUT_OF_TIME = 11; + JVM_STACK_OVER_FLOW = 12; + UNKNOWN = 13; + TRANSFER_FAILED = 14; + INVALID_CODE = 15; + } + int64 fee = 1; + code ret = 2; + contractResult contractRet = 3; + + string assetIssueID = 14; + int64 withdraw_amount = 15; + int64 unfreeze_amount = 16; + int64 exchange_received_amount = 18; + int64 exchange_inject_another_amount = 19; + int64 exchange_withdraw_another_amount = 20; + int64 exchange_id = 21; + int64 shielded_transaction_fee = 22; + + + bytes orderId = 25; + repeated MarketOrderDetail orderDetails = 26; + int64 withdraw_expire_amount = 27; + map cancel_unfreezeV2_amount = 28; + } + + message raw { + bytes ref_block_bytes = 1; + int64 ref_block_num = 3; + bytes ref_block_hash = 4; + int64 expiration = 8; + repeated authority auths = 9; + // data not used + bytes data = 10; + //only support size = 1, repeated list here for extension + repeated Contract contract = 11; + // scripts not used + bytes scripts = 12; + int64 timestamp = 14; + int64 fee_limit = 18; + } + + raw raw_data = 1; + // only support size = 1, repeated list here for muti-sig extension + repeated bytes signature = 2; + repeated Result ret = 5; +} + +message TransactionInfo { + enum code { + SUCESS = 0; + FAILED = 1; + } + message Log { + bytes address = 1; + repeated bytes topics = 2; + bytes data = 3; + } + bytes id = 1; + int64 fee = 2; + int64 blockNumber = 3; + int64 blockTimeStamp = 4; + repeated bytes contractResult = 5; + bytes contract_address = 6; + ResourceReceipt receipt = 7; + repeated Log log = 8; + code result = 9; + bytes resMessage = 10; + + string assetIssueID = 14; + int64 withdraw_amount = 15; + int64 unfreeze_amount = 16; + repeated InternalTransaction internal_transactions = 17; + int64 exchange_received_amount = 18; + int64 exchange_inject_another_amount = 19; + int64 exchange_withdraw_another_amount = 20; + int64 exchange_id = 21; + int64 shielded_transaction_fee = 22; + + bytes orderId = 25; + repeated MarketOrderDetail orderDetails = 26; + int64 packingFee = 27; + + int64 withdraw_expire_amount = 28; + map cancel_unfreezeV2_amount = 29; +} + +message TransactionRet { + int64 blockNumber = 1; + int64 blockTimeStamp = 2; + repeated TransactionInfo transactioninfo = 3; +} + +message Transactions { + repeated Transaction transactions = 1; +} + +message BlockHeader { + message raw { + int64 timestamp = 1; + bytes txTrieRoot = 2; + bytes parentHash = 3; + //bytes nonce = 5; + //bytes difficulty = 6; + int64 number = 7; + int64 witness_id = 8; + bytes witness_address = 9; + int32 version = 10; + bytes accountStateRoot = 11; + } + raw raw_data = 1; + bytes witness_signature = 2; +} + +// block +message Block { + repeated Transaction transactions = 1; + BlockHeader block_header = 2; +} + +message ChainInventory { + message BlockId { + bytes hash = 1; + int64 number = 2; + } + repeated BlockId ids = 1; + int64 remain_num = 2; +} + +// Inventory +message BlockInventory { + enum Type { + SYNC = 0; + ADVTISE = 1; + FETCH = 2; + } + + message BlockId { + bytes hash = 1; + int64 number = 2; + } + repeated BlockId ids = 1; + Type type = 2; +} + +message Inventory { + enum InventoryType { + TRX = 0; + BLOCK = 1; + } + InventoryType type = 1; + repeated bytes ids = 2; +} + +message Items { + enum ItemType { + ERR = 0; + TRX = 1; + BLOCK = 2; + BLOCKHEADER = 3; + } + + ItemType type = 1; + repeated Block blocks = 2; + repeated BlockHeader block_headers = 3; + repeated Transaction transactions = 4; +} + +// DynamicProperties +message DynamicProperties { + int64 last_solidity_block_num = 1; +} + +enum ReasonCode { + REQUESTED = 0x00; + BAD_PROTOCOL = 0x02; + TOO_MANY_PEERS = 0x04; + DUPLICATE_PEER = 0x05; + INCOMPATIBLE_PROTOCOL = 0x06; + RANDOM_ELIMINATION = 0x07; + PEER_QUITING = 0x08; + UNEXPECTED_IDENTITY = 0x09; + LOCAL_IDENTITY = 0x0A; + PING_TIMEOUT = 0x0B; + USER_REASON = 0x10; + RESET = 0x11; + SYNC_FAIL = 0x12; + FETCH_FAIL = 0x13; + BAD_TX = 0x14; + BAD_BLOCK = 0x15; + FORKED = 0x16; + UNLINKABLE = 0x17; + INCOMPATIBLE_VERSION = 0x18; + INCOMPATIBLE_CHAIN = 0x19; + TIME_OUT = 0x20; + CONNECT_FAIL = 0x21; + TOO_MANY_PEERS_WITH_SAME_IP = 0x22; + LIGHT_NODE_SYNC_FAIL = 0x23; + BELOW_THAN_ME = 0X24; + NOT_WITNESS = 0x25; + NO_SUCH_MESSAGE = 0x26; + UNKNOWN = 0xFF; +} + +message DisconnectMessage { + ReasonCode reason = 1; +} + +message HelloMessage { + message BlockId { + bytes hash = 1; + int64 number = 2; + } + + Endpoint from = 1; + int32 version = 2; + int64 timestamp = 3; + BlockId genesisBlockId = 4; + BlockId solidBlockId = 5; + BlockId headBlockId = 6; + bytes address = 7; + bytes signature = 8; + int32 nodeType = 9; + int64 lowestBlockNum = 10; +} + +message InternalTransaction { + // internalTransaction identity, the root InternalTransaction hash + // should equals to root transaction id. + bytes hash = 1; + // the one send trx (TBD: or token) via function + bytes caller_address = 2; + // the one recieve trx (TBD: or token) via function + bytes transferTo_address = 3; + message CallValueInfo { + // trx (TBD: or token) value + int64 callValue = 1; + // TBD: tokenName, trx should be empty + string tokenId = 2; + } + repeated CallValueInfo callValueInfo = 4; + bytes note = 5; + bool rejected = 6; + string extra = 7; +} + +message DelegatedResourceAccountIndex { + bytes account = 1; + repeated bytes fromAccounts = 2; + repeated bytes toAccounts = 3; + int64 timestamp = 4; +} + +message NodeInfo { + int64 beginSyncNum = 1; + string block = 2; + string solidityBlock = 3; + //connect information + int32 currentConnectCount = 4; + int32 activeConnectCount = 5; + int32 passiveConnectCount = 6; + int64 totalFlow = 7; + repeated PeerInfo peerInfoList = 8; + ConfigNodeInfo configNodeInfo = 9; + MachineInfo machineInfo = 10; + map cheatWitnessInfoMap = 11; + + message PeerInfo { + string lastSyncBlock = 1; + int64 remainNum = 2; + int64 lastBlockUpdateTime = 3; + bool syncFlag = 4; + int64 headBlockTimeWeBothHave = 5; + bool needSyncFromPeer = 6; + bool needSyncFromUs = 7; + string host = 8; + int32 port = 9; + string nodeId = 10; + int64 connectTime = 11; + double avgLatency = 12; + int32 syncToFetchSize = 13; + int64 syncToFetchSizePeekNum = 14; + int32 syncBlockRequestedSize = 15; + int64 unFetchSynNum = 16; + int32 blockInPorcSize = 17; + string headBlockWeBothHave = 18; + bool isActive = 19; + int32 score = 20; + int32 nodeCount = 21; + int64 inFlow = 22; + int32 disconnectTimes = 23; + string localDisconnectReason = 24; + string remoteDisconnectReason = 25; + } + + message ConfigNodeInfo { + string codeVersion = 1; + string p2pVersion = 2; + int32 listenPort = 3; + bool discoverEnable = 4; + int32 activeNodeSize = 5; + int32 passiveNodeSize = 6; + int32 sendNodeSize = 7; + int32 maxConnectCount = 8; + int32 sameIpMaxConnectCount = 9; + int32 backupListenPort = 10; + int32 backupMemberSize = 11; + int32 backupPriority = 12; + int32 dbVersion = 13; + int32 minParticipationRate = 14; + bool supportConstant = 15; + double minTimeRatio = 16; + double maxTimeRatio = 17; + int64 allowCreationOfContracts = 18; + int64 allowAdaptiveEnergy = 19; + } + + message MachineInfo { + int32 threadCount = 1; + int32 deadLockThreadCount = 2; + int32 cpuCount = 3; + int64 totalMemory = 4; + int64 freeMemory = 5; + double cpuRate = 6; + string javaVersion = 7; + string osName = 8; + int64 jvmTotalMemory = 9; + int64 jvmFreeMemory = 10; + double processCpuRate = 11; + repeated MemoryDescInfo memoryDescInfoList = 12; + repeated DeadLockThreadInfo deadLockThreadInfoList = 13; + + message MemoryDescInfo { + string name = 1; + int64 initSize = 2; + int64 useSize = 3; + int64 maxSize = 4; + double useRate = 5; + } + + message DeadLockThreadInfo { + string name = 1; + string lockName = 2; + string lockOwner = 3; + string state = 4; + int64 blockTime = 5; + int64 waitTime = 6; + string stackTrace = 7; + } + } +} + +message MetricsInfo { + int64 interval = 1; + NodeInfo node = 2; + BlockChainInfo blockchain = 3; + NetInfo net = 4; + + message NodeInfo { + string ip = 1; + int32 nodeType = 2; + string version = 3; + int32 backupStatus = 4; + } + + message BlockChainInfo { + int64 headBlockNum = 1; + int64 headBlockTimestamp = 2; + string headBlockHash = 3; + int32 forkCount = 4; + int32 failForkCount = 5; + RateInfo blockProcessTime = 6; + RateInfo tps = 7; + int32 transactionCacheSize = 8; + RateInfo missedTransaction = 9; + repeated Witness witnesses = 10; + int64 failProcessBlockNum = 11; + string failProcessBlockReason = 12; + repeated DupWitness dupWitness = 13; + + message Witness { + string address = 1; + int32 version = 2; + } + + message DupWitness { + string address = 1; + int64 blockNum = 2; + int32 count = 3; + } + } + + message RateInfo { + int64 count = 1; + double meanRate = 2; + double oneMinuteRate = 3; + double fiveMinuteRate = 4; + double fifteenMinuteRate = 5; + } + + message NetInfo { + int32 errorProtoCount = 1; + ApiInfo api = 2; + int32 connectionCount = 3; + int32 validConnectionCount = 4; + RateInfo tcpInTraffic = 5; + RateInfo tcpOutTraffic = 6; + int32 disconnectionCount = 7; + repeated DisconnectionDetailInfo disconnectionDetail = 8; + RateInfo udpInTraffic = 9; + RateInfo udpOutTraffic = 10; + LatencyInfo latency = 11; + + message ApiInfo { + RateInfo qps = 1; + RateInfo failQps = 2; + RateInfo outTraffic = 3; + repeated ApiDetailInfo detail = 4; + + message ApiDetailInfo { + string name = 1; + RateInfo qps = 2; + RateInfo failQps = 3; + RateInfo outTraffic = 4; + } + } + + message DisconnectionDetailInfo { + string reason = 1; + int32 count = 2; + } + + message LatencyInfo { + int32 top99 = 1; + int32 top95 = 2; + int32 top75 = 3; + int32 totalCount = 4; + int32 delay1S = 5; + int32 delay2S = 6; + int32 delay3S = 7; + repeated LatencyDetailInfo detail = 8; + + message LatencyDetailInfo { + string witness = 1; + int32 top99 = 2; + int32 top95 = 3; + int32 top75 = 4; + int32 count = 5; + int32 delay1S = 6; + int32 delay2S = 7; + int32 delay3S = 8; + } + } + } +} + +message PBFTMessage { + enum MsgType { + VIEW_CHANGE = 0; + REQUEST = 1; + PREPREPARE = 2; + PREPARE = 3; + COMMIT = 4; + } + enum DataType { + BLOCK = 0; + SRL = 1; + } + message Raw { + MsgType msg_type = 1; + DataType data_type = 2; + int64 view_n = 3; + int64 epoch = 4; + bytes data = 5; + } + Raw raw_data = 1; + bytes signature = 2; +} + +message PBFTCommitResult { + bytes data = 1; + repeated bytes signature = 2; +} + +message SRL { + repeated bytes srAddress = 1; +} diff --git a/packages/kos/src/protos/tron/core/TronInventoryItems.proto b/packages/kos/src/protos/tron/core/TronInventoryItems.proto new file mode 100644 index 0000000..a82d2de --- /dev/null +++ b/packages/kos/src/protos/tron/core/TronInventoryItems.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; + +package protocol; + +option java_package = "org.tron.protos"; //Specify the name of the package that generated the Java file +option java_outer_classname = "TronInventoryItems"; //Specify the class name of the generated Java file +option go_package = "github.com/tronprotocol/grpc-gateway/core"; + +message InventoryItems { + int32 type = 1; + repeated bytes items = 2; +} \ No newline at end of file diff --git a/packages/kos/src/protos/tron/core/contract/account_contract.proto b/packages/kos/src/protos/tron/core/contract/account_contract.proto new file mode 100644 index 0000000..d318004 --- /dev/null +++ b/packages/kos/src/protos/tron/core/contract/account_contract.proto @@ -0,0 +1,50 @@ +/* + * java-tron is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * java-tron is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +syntax = "proto3"; + +package protocol; + +option java_package = "org.tron.protos.contract"; //Specify the name of the package that generated the Java file +//option java_outer_classname = "Contract"; //Specify the class name of the generated Java file +option go_package = "github.com/tronprotocol/grpc-gateway/core"; + +import "core/Tron.proto"; + +message AccountCreateContract { + bytes owner_address = 1; + bytes account_address = 2; + AccountType type = 3; +} + +// Update account name. Account name is not unique now. +message AccountUpdateContract { + bytes account_name = 1; + bytes owner_address = 2; +} + +// Set account id if the account has no id. Account id is unique and case insensitive. +message SetAccountIdContract { + bytes account_id = 1; + bytes owner_address = 2; +} + +message AccountPermissionUpdateContract { + bytes owner_address = 1; + Permission owner = 2; //Empty is invalidate + Permission witness = 3; //Can be empty + repeated Permission actives = 4; //Empty is invalidate +} + diff --git a/packages/kos/src/protos/tron/core/contract/asset_issue_contract.proto b/packages/kos/src/protos/tron/core/contract/asset_issue_contract.proto new file mode 100644 index 0000000..eb86b17 --- /dev/null +++ b/packages/kos/src/protos/tron/core/contract/asset_issue_contract.proto @@ -0,0 +1,60 @@ +syntax = "proto3"; + +package protocol; + +option java_package = "org.tron.protos.contract"; //Specify the name of the package that generated the Java file +//option java_outer_classname = "AssetIssueContract"; //Specify the class name of the generated Java file +option go_package = "github.com/tronprotocol/grpc-gateway/core"; + +message AssetIssueContract { + string id = 41; + + message FrozenSupply { + int64 frozen_amount = 1; + int64 frozen_days = 2; + } + bytes owner_address = 1; + bytes name = 2; + bytes abbr = 3; + int64 total_supply = 4; + repeated FrozenSupply frozen_supply = 5; + int32 trx_num = 6; + int32 precision = 7; + int32 num = 8; + int64 start_time = 9; + int64 end_time = 10; + int64 order = 11; // useless + int32 vote_score = 16; + bytes description = 20; + bytes url = 21; + int64 free_asset_net_limit = 22; + int64 public_free_asset_net_limit = 23; + int64 public_free_asset_net_usage = 24; + int64 public_latest_free_net_time = 25; +} + +message TransferAssetContract { + bytes asset_name = 1; // this field is token name before the proposal ALLOW_SAME_TOKEN_NAME is active, otherwise it is token id and token is should be in string format. + bytes owner_address = 2; + bytes to_address = 3; + int64 amount = 4; +} + +message UnfreezeAssetContract { + bytes owner_address = 1; +} + +message UpdateAssetContract { + bytes owner_address = 1; + bytes description = 2; + bytes url = 3; + int64 new_limit = 4; + int64 new_public_limit = 5; +} + +message ParticipateAssetIssueContract { + bytes owner_address = 1; + bytes to_address = 2; + bytes asset_name = 3; // this field is token name before the proposal ALLOW_SAME_TOKEN_NAME is active, otherwise it is token id and token is should be in string format. + int64 amount = 4; // the amount of drops +} \ No newline at end of file diff --git a/packages/kos/src/protos/tron/core/contract/balance_contract.proto b/packages/kos/src/protos/tron/core/contract/balance_contract.proto new file mode 100644 index 0000000..ea1c962 --- /dev/null +++ b/packages/kos/src/protos/tron/core/contract/balance_contract.proto @@ -0,0 +1,118 @@ +syntax = "proto3"; + +package protocol; + +option java_package = "org.tron.protos.contract"; //Specify the name of the package that generated the Java file +//option java_outer_classname = "FreezeBalanceContract"; //Specify the class name of the generated Java file +option go_package = "github.com/tronprotocol/grpc-gateway/core"; + +import "core/contract/common.proto"; + +message FreezeBalanceContract { + bytes owner_address = 1; + int64 frozen_balance = 2; + int64 frozen_duration = 3; + + ResourceCode resource = 10; + bytes receiver_address = 15; +} + + +message UnfreezeBalanceContract { + bytes owner_address = 1; + + ResourceCode resource = 10; + bytes receiver_address = 15; +} + +message WithdrawBalanceContract { + bytes owner_address = 1; +} + +message TransferContract { + bytes owner_address = 1; + bytes to_address = 2; + int64 amount = 3; +} + +message TransactionBalanceTrace { + message Operation { + int64 operation_identifier = 1; + bytes address = 2; + int64 amount = 3; + } + + bytes transaction_identifier = 1; + repeated Operation operation = 2; + string type = 3; + string status = 4; +} + + + +message BlockBalanceTrace { + message BlockIdentifier { + bytes hash = 1; + int64 number = 2; + } + + BlockIdentifier block_identifier = 1; + int64 timestamp = 2; + repeated TransactionBalanceTrace transaction_balance_trace = 3; +// BlockIdentifier parent_block_identifier = 4; +} + +message AccountTrace { + int64 balance = 1; + int64 placeholder = 99; +} + +message AccountIdentifier { + bytes address = 1; +} + +message AccountBalanceRequest { + AccountIdentifier account_identifier = 1; + BlockBalanceTrace.BlockIdentifier block_identifier = 2; +} + +message AccountBalanceResponse { + int64 balance = 1; + BlockBalanceTrace.BlockIdentifier block_identifier = 2; +} + +message FreezeBalanceV2Contract { + bytes owner_address = 1; + int64 frozen_balance = 2; + ResourceCode resource = 3; +} + +message UnfreezeBalanceV2Contract { + bytes owner_address = 1; + int64 unfreeze_balance = 2; + ResourceCode resource = 3; +} + +message WithdrawExpireUnfreezeContract { + bytes owner_address = 1; +} + +message DelegateResourceContract { + bytes owner_address = 1; + ResourceCode resource = 2; + int64 balance = 3; + bytes receiver_address = 4; + bool lock = 5; + int64 lock_period = 6; +} + +message UnDelegateResourceContract { + bytes owner_address = 1; + ResourceCode resource = 2; + int64 balance = 3; + bytes receiver_address = 4; +} + +message CancelAllUnfreezeV2Contract { + bytes owner_address = 1; +} \ No newline at end of file diff --git a/packages/kos/src/protos/tron/core/contract/common.proto b/packages/kos/src/protos/tron/core/contract/common.proto new file mode 100644 index 0000000..8af929b --- /dev/null +++ b/packages/kos/src/protos/tron/core/contract/common.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; + +package protocol; + +option java_package = "org.tron.protos.contract"; //Specify the name of the package that generated the Java file +//option java_outer_classname = "common"; //Specify the class name of the generated Java file +option go_package = "github.com/tronprotocol/grpc-gateway/core"; + +enum ResourceCode { + BANDWIDTH = 0x00; + ENERGY = 0x01; + TRON_POWER = 0x02; +} \ No newline at end of file diff --git a/packages/kos/src/protos/tron/core/contract/exchange_contract.proto b/packages/kos/src/protos/tron/core/contract/exchange_contract.proto new file mode 100644 index 0000000..8b8878f --- /dev/null +++ b/packages/kos/src/protos/tron/core/contract/exchange_contract.proto @@ -0,0 +1,37 @@ +syntax = "proto3"; + +package protocol; + +option java_package = "org.tron.protos.contract"; //Specify the name of the package that generated the Java file +//option java_outer_classname = "ExchangeCreateContract"; //Specify the class name of the generated Java file +option go_package = "github.com/tronprotocol/grpc-gateway/core"; + +message ExchangeCreateContract { + bytes owner_address = 1; + bytes first_token_id = 2; + int64 first_token_balance = 3; + bytes second_token_id = 4; + int64 second_token_balance = 5; +} + +message ExchangeInjectContract { + bytes owner_address = 1; + int64 exchange_id = 2; + bytes token_id = 3; + int64 quant = 4; +} + +message ExchangeWithdrawContract { + bytes owner_address = 1; + int64 exchange_id = 2; + bytes token_id = 3; + int64 quant = 4; +} + +message ExchangeTransactionContract { + bytes owner_address = 1; + int64 exchange_id = 2; + bytes token_id = 3; + int64 quant = 4; + int64 expected = 5; +} \ No newline at end of file diff --git a/packages/kos/src/protos/tron/core/contract/market_contract.proto b/packages/kos/src/protos/tron/core/contract/market_contract.proto new file mode 100644 index 0000000..e127435 --- /dev/null +++ b/packages/kos/src/protos/tron/core/contract/market_contract.proto @@ -0,0 +1,19 @@ +syntax = "proto3"; + +package protocol; + +option java_package = "org.tron.protos.contract"; //Specify the name of the package that generated the Java file +option go_package = "github.com/tronprotocol/grpc-gateway/core"; + +message MarketSellAssetContract { + bytes owner_address = 1; + bytes sell_token_id = 2; + int64 sell_token_quantity = 3; + bytes buy_token_id = 4; + int64 buy_token_quantity = 5; // min to receive +} + +message MarketCancelOrderContract { + bytes owner_address = 1; + bytes order_id = 2; +} \ No newline at end of file diff --git a/packages/kos/src/protos/tron/core/contract/proposal_contract.proto b/packages/kos/src/protos/tron/core/contract/proposal_contract.proto new file mode 100644 index 0000000..35bb9ca --- /dev/null +++ b/packages/kos/src/protos/tron/core/contract/proposal_contract.proto @@ -0,0 +1,23 @@ +syntax = "proto3"; + +package protocol; + +option java_package = "org.tron.protos.contract"; //Specify the name of the package that generated the Java file +//option java_outer_classname = "ProposalApproveContract"; //Specify the class name of the generated Java file +option go_package = "github.com/tronprotocol/grpc-gateway/core"; + +message ProposalApproveContract { + bytes owner_address = 1; + int64 proposal_id = 2; + bool is_add_approval = 3; // add or remove approval +} + +message ProposalCreateContract { + bytes owner_address = 1; + map parameters = 2; +} + +message ProposalDeleteContract { + bytes owner_address = 1; + int64 proposal_id = 2; +} \ No newline at end of file diff --git a/packages/kos/src/protos/tron/core/contract/shield_contract.proto b/packages/kos/src/protos/tron/core/contract/shield_contract.proto new file mode 100644 index 0000000..660f9dd --- /dev/null +++ b/packages/kos/src/protos/tron/core/contract/shield_contract.proto @@ -0,0 +1,81 @@ +syntax = "proto3"; + +package protocol; + +option java_package = "org.tron.protos.contract"; //Specify the name of the package that generated the Java file +//option java_outer_classname = "ShieldedTransferContract"; //Specify the class name of the generated Java file +option go_package = "github.com/tronprotocol/grpc-gateway/core"; + +// for shielded transaction + +message AuthenticationPath { + repeated bool value = 1; +} + +message MerklePath { + repeated AuthenticationPath authentication_paths = 1; + repeated bool index = 2; + bytes rt = 3; +} + +message OutputPoint { + bytes hash = 1; + int32 index = 2; +} + +message OutputPointInfo { + repeated OutputPoint out_points = 1; + int32 block_num = 2; +} + +message PedersenHash { + bytes content = 1; +} + +message IncrementalMerkleTree { + PedersenHash left = 1; + PedersenHash right = 2; + repeated PedersenHash parents = 3; +} + +message IncrementalMerkleVoucher { + IncrementalMerkleTree tree = 1; + repeated PedersenHash filled = 2; + IncrementalMerkleTree cursor = 3; + int64 cursor_depth = 4; + bytes rt = 5; + OutputPoint output_point = 10; +} + +message IncrementalMerkleVoucherInfo { + repeated IncrementalMerkleVoucher vouchers = 1; + repeated bytes paths = 2; +} + +message SpendDescription { + bytes value_commitment = 1; + bytes anchor = 2; // merkle root + bytes nullifier = 3; // used for check double spend + bytes rk = 4; // used for check spend authority signature + bytes zkproof = 5; + bytes spend_authority_signature = 6; +} + +message ReceiveDescription { + bytes value_commitment = 1; + bytes note_commitment = 2; + bytes epk = 3; // for Encryption + bytes c_enc = 4; // Encryption for incoming, decrypt it with ivk + bytes c_out = 5; // Encryption for audit, decrypt it with ovk + bytes zkproof = 6; +} + +message ShieldedTransferContract { + bytes transparent_from_address = 1; // transparent address + int64 from_amount = 2; + repeated SpendDescription spend_description = 3; + repeated ReceiveDescription receive_description = 4; + bytes binding_signature = 5; + bytes transparent_to_address = 6; // transparent address + int64 to_amount = 7; // the amount to transparent to_address +} diff --git a/packages/kos/src/protos/tron/core/contract/smart_contract.proto b/packages/kos/src/protos/tron/core/contract/smart_contract.proto new file mode 100644 index 0000000..84598ed --- /dev/null +++ b/packages/kos/src/protos/tron/core/contract/smart_contract.proto @@ -0,0 +1,104 @@ +syntax = "proto3"; + +package protocol; + +option java_package = "org.tron.protos.contract"; //Specify the name of the package that generated the Java file +//option java_outer_classname = "CreateSmartContract"; //Specify the class name of the generated Java file +option go_package = "github.com/tronprotocol/grpc-gateway/core"; + +import "core/Tron.proto"; + +message SmartContract { + message ABI { + message Entry { + enum EntryType { + UnknownEntryType = 0; + Constructor = 1; + Function = 2; + Event = 3; + Fallback = 4; + Receive = 5; + Error = 6; + } + message Param { + bool indexed = 1; + string name = 2; + string type = 3; + // SolidityType type = 3; + } + enum StateMutabilityType { + UnknownMutabilityType = 0; + Pure = 1; + View = 2; + Nonpayable = 3; + Payable = 4; + } + + bool anonymous = 1; + bool constant = 2; + string name = 3; + repeated Param inputs = 4; + repeated Param outputs = 5; + EntryType type = 6; + bool payable = 7; + StateMutabilityType stateMutability = 8; + } + repeated Entry entrys = 1; + } + bytes origin_address = 1; + bytes contract_address = 2; + ABI abi = 3; + bytes bytecode = 4; + int64 call_value = 5; + int64 consume_user_resource_percent = 6; + string name = 7; + int64 origin_energy_limit = 8; + bytes code_hash = 9; + bytes trx_hash = 10; + int32 version = 11; +} + +message ContractState { + int64 energy_usage = 1; + int64 energy_factor = 2; + int64 update_cycle = 3; +} + +message CreateSmartContract { + bytes owner_address = 1; + SmartContract new_contract = 2; + int64 call_token_value = 3; + int64 token_id = 4; +} + +message TriggerSmartContract { + bytes owner_address = 1; + bytes contract_address = 2; + int64 call_value = 3; + bytes data = 4; + int64 call_token_value = 5; + int64 token_id = 6; +} + +message ClearABIContract { + bytes owner_address = 1; + bytes contract_address = 2; +} + +message UpdateSettingContract { + bytes owner_address = 1; + bytes contract_address = 2; + int64 consume_user_resource_percent = 3; +} + +message UpdateEnergyLimitContract { + bytes owner_address = 1; + bytes contract_address = 2; + int64 origin_energy_limit = 3; +} + +message SmartContractDataWrapper { + SmartContract smart_contract = 1; + bytes runtimecode = 2; + ContractState contract_state = 3; +} diff --git a/packages/kos/src/protos/tron/core/contract/storage_contract.proto b/packages/kos/src/protos/tron/core/contract/storage_contract.proto new file mode 100644 index 0000000..f04bf71 --- /dev/null +++ b/packages/kos/src/protos/tron/core/contract/storage_contract.proto @@ -0,0 +1,27 @@ +syntax = "proto3"; + +package protocol; + +option java_package = "org.tron.protos.contract"; //Specify the name of the package that generated the Java file +//option java_outer_classname = "BuyStorageBytesContract"; //Specify the class name of the generated Java file +option go_package = "github.com/tronprotocol/grpc-gateway/core"; + +message BuyStorageBytesContract { + bytes owner_address = 1; + int64 bytes = 2; // storage bytes for buy +} + +message BuyStorageContract { + bytes owner_address = 1; + int64 quant = 2; // trx quantity for buy storage (sun) +} + +message SellStorageContract { + bytes owner_address = 1; + int64 storage_bytes = 2; +} + +message UpdateBrokerageContract { + bytes owner_address = 1; + int32 brokerage = 2; // 1 mean 1% +} diff --git a/packages/kos/src/protos/tron/core/contract/vote_asset_contract.proto b/packages/kos/src/protos/tron/core/contract/vote_asset_contract.proto new file mode 100644 index 0000000..d3b8e5b --- /dev/null +++ b/packages/kos/src/protos/tron/core/contract/vote_asset_contract.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + +package protocol; + +option java_package = "org.tron.protos.contract"; //Specify the name of the package that generated the Java file +//option java_outer_classname = "VoteAssetContract"; //Specify the class name of the generated Java file +option go_package = "github.com/tronprotocol/grpc-gateway/core"; + +message VoteAssetContract { + bytes owner_address = 1; + repeated bytes vote_address = 2; + bool support = 3; + int32 count = 5; +} \ No newline at end of file diff --git a/packages/kos/src/protos/tron/core/contract/witness_contract.proto b/packages/kos/src/protos/tron/core/contract/witness_contract.proto new file mode 100644 index 0000000..5021fbf --- /dev/null +++ b/packages/kos/src/protos/tron/core/contract/witness_contract.proto @@ -0,0 +1,27 @@ +syntax = "proto3"; + +package protocol; + +option java_package = "org.tron.protos.contract"; //Specify the name of the package that generated the Java file +//option java_outer_classname = "WitnessCreateContract"; //Specify the class name of the generated Java file +option go_package = "github.com/tronprotocol/grpc-gateway/core"; + +message WitnessCreateContract { + bytes owner_address = 1; + bytes url = 2; +} + +message WitnessUpdateContract { + bytes owner_address = 1; + bytes update_url = 12; +} + +message VoteWitnessContract { + message Vote { + bytes vote_address = 1; + int64 vote_count = 2; + } + bytes owner_address = 1; + repeated Vote votes = 2; + bool support = 3; +} \ No newline at end of file diff --git a/packages/kos/src/protos/tron/core/tron/account.proto b/packages/kos/src/protos/tron/core/tron/account.proto new file mode 100644 index 0000000..e69de29 diff --git a/packages/kos/src/protos/tron/core/tron/block.proto b/packages/kos/src/protos/tron/core/tron/block.proto new file mode 100644 index 0000000..e69de29 diff --git a/packages/kos/src/protos/tron/core/tron/delegated_resource.proto b/packages/kos/src/protos/tron/core/tron/delegated_resource.proto new file mode 100644 index 0000000..e69de29 diff --git a/packages/kos/src/protos/tron/core/tron/p2p.proto b/packages/kos/src/protos/tron/core/tron/p2p.proto new file mode 100644 index 0000000..e69de29 diff --git a/packages/kos/src/protos/tron/core/tron/proposal.proto b/packages/kos/src/protos/tron/core/tron/proposal.proto new file mode 100644 index 0000000..e69de29 diff --git a/packages/kos/src/protos/tron/core/tron/transaction.proto b/packages/kos/src/protos/tron/core/tron/transaction.proto new file mode 100644 index 0000000..e69de29 diff --git a/packages/kos/src/protos/tron/core/tron/vote.proto b/packages/kos/src/protos/tron/core/tron/vote.proto new file mode 100644 index 0000000..e69de29 diff --git a/packages/kos/src/protos/tron/core/tron/witness.proto b/packages/kos/src/protos/tron/core/tron/witness.proto new file mode 100644 index 0000000..e69de29 diff --git a/packages/kos/src/protos/tron/install-googleapis.sh b/packages/kos/src/protos/tron/install-googleapis.sh new file mode 100644 index 0000000..e1c1df8 --- /dev/null +++ b/packages/kos/src/protos/tron/install-googleapis.sh @@ -0,0 +1,14 @@ +#!/bin/sh +set -e + +go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway +go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger +go get -u github.com/golang/protobuf/protoc-gen-go + +wget https://repo1.maven.org/maven2/com/google/api/grpc/googleapis-common-protos/0.0.3/googleapis-common-protos-0.0.3.jar +jar xvf googleapis-common-protos-0.0.3.jar +cp -r google/ $HOME/protobuf/include/ +ls -l + + + diff --git a/packages/kos/src/protos/tron/install-protobuf.sh b/packages/kos/src/protos/tron/install-protobuf.sh new file mode 100644 index 0000000..b3a8cb5 --- /dev/null +++ b/packages/kos/src/protos/tron/install-protobuf.sh @@ -0,0 +1,10 @@ +#!/bin/sh +set -e +# check to see if protobuf folder is empty +if [ ! -d "$HOME/protobuf/lib" ]; then + wget https://github.com/google/protobuf/releases/download/v3.5.1/protobuf-all-3.5.1.tar.gz + tar -xzvf protobuf-all-3.5.1.tar.gz + cd protobuf-3.5.1 && ./configure --prefix=$HOME/protobuf && make && make install +else + echo "Using cached directory." +fi From e6d578ce6d7148281c477f53cada694edb054f7a Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Tue, 5 Nov 2024 14:22:47 -0300 Subject: [PATCH 02/42] chore: adjust submodule path --- .gitmodules | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 13bf6f8..bffcdef 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ -[submodule "packages/kos/protos/tron"] - path = packages/kos/protos/tron +[submodule "packages/kos/src/protos/tron"] + path = packages/kos/src/protos/tron url = https://github.com/tronprotocol/protocol From 5412bcbc19b4a6e112e04e27dd3842b45ec3e1a3 Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Tue, 5 Nov 2024 14:32:46 -0300 Subject: [PATCH 03/42] chore: adjust submodule path --- .gitmodules | 1 + packages/kos/src/protos/tron/api/api.proto | 2 ++ packages/kos/src/protos/tron/core/Tron.proto | 1 + 3 files changed, 4 insertions(+) diff --git a/.gitmodules b/.gitmodules index bffcdef..d024297 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,4 @@ [submodule "packages/kos/src/protos/tron"] path = packages/kos/src/protos/tron url = https://github.com/tronprotocol/protocol + diff --git a/packages/kos/src/protos/tron/api/api.proto b/packages/kos/src/protos/tron/api/api.proto index 9a7534c..2505fa4 100644 --- a/packages/kos/src/protos/tron/api/api.proto +++ b/packages/kos/src/protos/tron/api/api.proto @@ -1051,6 +1051,8 @@ message Return { SERVER_BUSY = 9; NO_CONNECTION = 10; NOT_ENOUGH_EFFECTIVE_CONNECTION = 11; + BLOCK_UNSOLIDIFIED = 12; + OTHER_ERROR = 20; } diff --git a/packages/kos/src/protos/tron/core/Tron.proto b/packages/kos/src/protos/tron/core/Tron.proto index 2fc0890..41ef968 100644 --- a/packages/kos/src/protos/tron/core/Tron.proto +++ b/packages/kos/src/protos/tron/core/Tron.proto @@ -626,6 +626,7 @@ message HelloMessage { bytes signature = 8; int32 nodeType = 9; int64 lowestBlockNum = 10; + bytes codeVersion = 11; } message InternalTransaction { From afffea6c7d51bfaf66d893a750fa4d6854775c69 Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Tue, 5 Nov 2024 14:39:18 -0300 Subject: [PATCH 04/42] chore: add build file --- packages/kos/Cargo.toml | 21 ++++---- packages/kos/build.rs | 49 +++++++++++++++++++ packages/kos/src/crypto/bip32.rs | 2 +- .../kos/src/protos/generated/trx/protocol.rs | 2 + 4 files changed, 63 insertions(+), 11 deletions(-) create mode 100644 packages/kos/build.rs diff --git a/packages/kos/Cargo.toml b/packages/kos/Cargo.toml index 17ef695..46516fe 100644 --- a/packages/kos/Cargo.toml +++ b/packages/kos/Cargo.toml @@ -7,20 +7,21 @@ license.workspace = true repository.workspace = true rust-version.workspace = true version.workspace = true +build = "build.rs" ## Only necessary if using Protobuf well-known types: -#[lib] -#name = "kos" -#crate-type = ["staticlib", "cdylib"] +[lib] +name = "kos" +crate-type = ["staticlib", "cdylib", "rlib"] # # -## See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html -#[profile.release] -#opt-level = 'z' # Optimize for size -#lto = true # Enable Link Time Optimization -#panic = 'abort' # Generally reduces size for embedded systems -#codegen-units = 1 # more aggressive code merging -#strip = true # Strip symbols from the final binary +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[profile.release] +opt-level = 'z' # Optimize for size +lto = true # Enable Link Time Optimization +panic = 'abort' # Generally reduces size for embedded systems +codegen-units = 1 # more aggressive code merging +strip = true # Strip symbols from the final binary [profile.dev] panic = 'abort' diff --git a/packages/kos/build.rs b/packages/kos/build.rs new file mode 100644 index 0000000..6997821 --- /dev/null +++ b/packages/kos/build.rs @@ -0,0 +1,49 @@ +use std::path::PathBuf; + +fn main() { + let mut config = prost_build::Config::new(); + config.btree_map(&["."]); + + let protos = vec![ + "src/protos/tron/core/Discover.proto", + "src/protos/tron/core/Tron.proto", + "src/protos/tron/core/TronInventoryItems.proto", + "src/protos/tron/core/contract/account_contract.proto", + "src/protos/tron/core/contract/asset_issue_contract.proto", + "src/protos/tron/core/contract/balance_contract.proto", + "src/protos/tron/core/contract/common.proto", + "src/protos/tron/core/contract/exchange_contract.proto", + "src/protos/tron/core/contract/market_contract.proto", + "src/protos/tron/core/contract/proposal_contract.proto", + "src/protos/tron/core/contract/shield_contract.proto", + "src/protos/tron/core/contract/smart_contract.proto", + "src/protos/tron/core/contract/storage_contract.proto", + "src/protos/tron/core/contract/vote_asset_contract.proto", + "src/protos/tron/core/contract/witness_contract.proto", + ]; + + // Specify the output directory where the generated Rust code should be placed. + config.out_dir("src/protos/generated/trx"); + + config + .compile_protos(&protos, &["src/protos/tron"]) + .unwrap(); + + let out_dir = PathBuf::from("src/protos/generated/klv"); + + config.extern_path(".google.protobuf", "crate::protos"); + config.protoc_arg("--experimental_allow_proto3_optional"); + config.compile_well_known_types(); + + let klv_protos = vec![ + "src/protos/klever/contracts.proto", + "src/protos/klever/transaction.proto", + "src/protos/klever/userAccountData.proto", + ]; + + config.out_dir(out_dir.clone()); + + config + .compile_protos(&klv_protos, &["src/protos/klever"]) + .unwrap(); +} diff --git a/packages/kos/src/crypto/bip32.rs b/packages/kos/src/crypto/bip32.rs index 56dcb14..7782995 100644 --- a/packages/kos/src/crypto/bip32.rs +++ b/packages/kos/src/crypto/bip32.rs @@ -6,7 +6,7 @@ use crate::crypto::sr25519::{Sr25519, Sr25519Error, Sr25519Trait}; use alloc::string::{String, ToString}; use alloc::vec; use alloc::vec::Vec; -use bip39_dict::{Entropy, ENGLISH}; +use bip39_dict::Entropy; use core::fmt::{Display, Formatter}; use core::num::ParseIntError; use core::str::FromStr; diff --git a/packages/kos/src/protos/generated/trx/protocol.rs b/packages/kos/src/protos/generated/trx/protocol.rs index dc668a3..9f8192c 100644 --- a/packages/kos/src/protos/generated/trx/protocol.rs +++ b/packages/kos/src/protos/generated/trx/protocol.rs @@ -1504,6 +1504,8 @@ pub struct HelloMessage { pub node_type: i32, #[prost(int64, tag = "10")] pub lowest_block_num: i64, + #[prost(bytes = "vec", tag = "11")] + pub code_version: ::prost::alloc::vec::Vec, } /// Nested message and enum types in `HelloMessage`. pub mod hello_message { From 596476ef725d1ff14a7e1419377287023b7c4283 Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Tue, 5 Nov 2024 14:47:07 -0300 Subject: [PATCH 05/42] fix: proto submodule --- .gitmodules | 4 - packages/kos/src/protos/tron/.gitignore | 4 - packages/kos/src/protos/tron/.travis.yml | 13 - ...inese version of TRON Protocol document.md | 696 -------- ...glish version of TRON Protocol document.md | 736 -------- packages/kos/src/protos/tron/LICENSE | 165 -- packages/kos/src/protos/tron/README.md | 13 - packages/kos/src/protos/tron/api/api.proto | 1536 ----------------- .../kos/src/protos/tron/api/zksnark.proto | 33 - .../kos/src/protos/tron/core/Discover.proto | 44 - packages/kos/src/protos/tron/core/Tron.proto | 892 ---------- .../protos/tron/core/TronInventoryItems.proto | 12 - .../tron/core/contract/account_contract.proto | 50 - .../core/contract/asset_issue_contract.proto | 60 - .../tron/core/contract/balance_contract.proto | 118 -- .../protos/tron/core/contract/common.proto | 13 - .../core/contract/exchange_contract.proto | 37 - .../tron/core/contract/market_contract.proto | 19 - .../core/contract/proposal_contract.proto | 23 - .../tron/core/contract/shield_contract.proto | 81 - .../tron/core/contract/smart_contract.proto | 104 -- .../tron/core/contract/storage_contract.proto | 27 - .../core/contract/vote_asset_contract.proto | 14 - .../tron/core/contract/witness_contract.proto | 27 - .../src/protos/tron/core/tron/account.proto | 0 .../kos/src/protos/tron/core/tron/block.proto | 0 .../tron/core/tron/delegated_resource.proto | 0 .../kos/src/protos/tron/core/tron/p2p.proto | 0 .../src/protos/tron/core/tron/proposal.proto | 0 .../protos/tron/core/tron/transaction.proto | 0 .../kos/src/protos/tron/core/tron/vote.proto | 0 .../src/protos/tron/core/tron/witness.proto | 0 .../kos/src/protos/tron/install-googleapis.sh | 14 - .../kos/src/protos/tron/install-protobuf.sh | 10 - 34 files changed, 4745 deletions(-) delete mode 100644 .gitmodules delete mode 100644 packages/kos/src/protos/tron/.gitignore delete mode 100644 packages/kos/src/protos/tron/.travis.yml delete mode 100644 packages/kos/src/protos/tron/Chinese version of TRON Protocol document.md delete mode 100644 packages/kos/src/protos/tron/English version of TRON Protocol document.md delete mode 100644 packages/kos/src/protos/tron/LICENSE delete mode 100644 packages/kos/src/protos/tron/README.md delete mode 100644 packages/kos/src/protos/tron/api/api.proto delete mode 100644 packages/kos/src/protos/tron/api/zksnark.proto delete mode 100644 packages/kos/src/protos/tron/core/Discover.proto delete mode 100644 packages/kos/src/protos/tron/core/Tron.proto delete mode 100644 packages/kos/src/protos/tron/core/TronInventoryItems.proto delete mode 100644 packages/kos/src/protos/tron/core/contract/account_contract.proto delete mode 100644 packages/kos/src/protos/tron/core/contract/asset_issue_contract.proto delete mode 100644 packages/kos/src/protos/tron/core/contract/balance_contract.proto delete mode 100644 packages/kos/src/protos/tron/core/contract/common.proto delete mode 100644 packages/kos/src/protos/tron/core/contract/exchange_contract.proto delete mode 100644 packages/kos/src/protos/tron/core/contract/market_contract.proto delete mode 100644 packages/kos/src/protos/tron/core/contract/proposal_contract.proto delete mode 100644 packages/kos/src/protos/tron/core/contract/shield_contract.proto delete mode 100644 packages/kos/src/protos/tron/core/contract/smart_contract.proto delete mode 100644 packages/kos/src/protos/tron/core/contract/storage_contract.proto delete mode 100644 packages/kos/src/protos/tron/core/contract/vote_asset_contract.proto delete mode 100644 packages/kos/src/protos/tron/core/contract/witness_contract.proto delete mode 100644 packages/kos/src/protos/tron/core/tron/account.proto delete mode 100644 packages/kos/src/protos/tron/core/tron/block.proto delete mode 100644 packages/kos/src/protos/tron/core/tron/delegated_resource.proto delete mode 100644 packages/kos/src/protos/tron/core/tron/p2p.proto delete mode 100644 packages/kos/src/protos/tron/core/tron/proposal.proto delete mode 100644 packages/kos/src/protos/tron/core/tron/transaction.proto delete mode 100644 packages/kos/src/protos/tron/core/tron/vote.proto delete mode 100644 packages/kos/src/protos/tron/core/tron/witness.proto delete mode 100644 packages/kos/src/protos/tron/install-googleapis.sh delete mode 100644 packages/kos/src/protos/tron/install-protobuf.sh diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index d024297..0000000 --- a/.gitmodules +++ /dev/null @@ -1,4 +0,0 @@ -[submodule "packages/kos/src/protos/tron"] - path = packages/kos/src/protos/tron - url = https://github.com/tronprotocol/protocol - diff --git a/packages/kos/src/protos/tron/.gitignore b/packages/kos/src/protos/tron/.gitignore deleted file mode 100644 index 1554c5e..0000000 --- a/packages/kos/src/protos/tron/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -# IDEA -.idea -*iml -.DS_Store diff --git a/packages/kos/src/protos/tron/.travis.yml b/packages/kos/src/protos/tron/.travis.yml deleted file mode 100644 index 2cc9ce9..0000000 --- a/packages/kos/src/protos/tron/.travis.yml +++ /dev/null @@ -1,13 +0,0 @@ -language: ruby -cache: - directories: - - "$HOME/protobuf" -sudo: false -before_install: -before_script: -script: -- ls -l -notifications: - slack: - secure: lCDOgsHefxu0Sd7J4N9wyo6Y/dvAentdf+q+R6R+SpJUym+tI7h4lPVwDFl9iQabFahLC6bV4lgfv/US0aqjL4QE/c3ZsWBDo2dtkfCzGmkCiU6mGd/bPWLFP9e28OHEFBzUT8ukc5O3GDJREnzscIqGk7Knv3QYQGsoZw563grzVG9VVfqKhsVgrAjhzDwiCoUNSiND09ZNifGrHr7JBQ2u0wrZRR+E9yOQ1K3pNnfq5wAJjbJ0LiuxRlLZoajR7z8VeP8ytet+u2XQE1+fd089XEa/thYxtt0ZvhnyOYk1vmEldDdVakqMqVaa9MKiyLBNnLby1xdSosrM55ZB3tFmXQo6EMIaNKyO07xMUJ/hK0gEppQhHMDlbOW31YmOshVutp2yN4tRF8D3ot1OcYPXsVeXFG+kMUR0PYM71YiqZy8UVgoslKgRgEehvxjuAhbMYXMG878bznco9L64TzubFcjOx0+owR8H0kCXDNf5Xwm+tlc2onWlUDerEWIAignVOT1iR8KK0U+EnhTfw2BWfDV+BkSBvaeFbmnsFgz00d7qSvzbtCJ9KdDj3f4FUjUuORNv5ykMGCv1MrvAvttAZPTNIc/wOFJ9yRC2NhoUfbNILYg7bYhmqKiicnflln03Bh7Ml2mzldzPaRMm7eUBUwYTFbgC83YusX4fxBg= - if: branch = master diff --git a/packages/kos/src/protos/tron/Chinese version of TRON Protocol document.md b/packages/kos/src/protos/tron/Chinese version of TRON Protocol document.md deleted file mode 100644 index 283bd5f..0000000 --- a/packages/kos/src/protos/tron/Chinese version of TRON Protocol document.md +++ /dev/null @@ -1,696 +0,0 @@ -# TRON protobuf protocol - -## TRON使用Google protobuf协议,协议内容涉及到账户,区块,传输多个层面。 - -+ 账户有基本账户、资产发布账户和合约账户三种类型。一个账户包含:账户名称,账户类型,地址,余额,投票,其他资产6种属性。 -+ 更进一步的,基本账户可以申请成为验证节点,验证节点具有额外的属性,投票统计数目,公钥,URL,以及历史表现等参数。 - - 3种`Account`类型:`Normal`,`AssetIssue`,`Contract`。 - - enum AccountType {
 - Normal = 0;
 - AssetIssue = 1;
 - Contract = 2;
 - } - - 一个`Account`包含7种参数: - `account_name`:该账户的名称——比如: ”_SicCongsAccount_”。 - `type`:该账户的类型——比如: _0_ 代表的账户类型是`Normal`。 - `balance`:该账户的TRX余额——比如:_4213312_。 - `votes`:账户所得投票数——比如:_{(“0x1b7w…9xj3”,323),(“0x8djq…j12m”,88),…,(“0x82nd…mx6i”,10001)}_。 - `asset`:除TRX以外账户上的其他资产——比如:_{<”WishToken”,66666>,<”Dogie”,233>}_。 - `latest_operation_time`: 该账户的最新活跃时间。 - - // Account
 - message Account {
 - message Vote {
 - bytes vote_address = 1;
 - int64 vote_count = 2;
 - }
 - bytes accout_name = 1;
 - AccountType type = 2;
 - bytes address = 3;
 - int64 balance = 4;
 - repeated Vote votes = 5;
 - map asset = 6;
 - int64 latest_operation_time = 10; - } - - 一个`Witness`包含8种参数: - `address`:验证节点的地址——比如:_“0xu82h…7237”_。 - `voteCount`:验证节点所得投票数——比如:_234234_。 - `pubKey`:验证节点的公钥——比如:_“0xu82h…7237”_。 - `url`:验证节点的url链接。 - `totalProduce`:验证节点产生的区块数——比如:_2434_。 - `totalMissed`:验证节点丢失的区块数——比如:_7_。 - `latestBlockNum`:最新的区块高度——比如:_4522_。 - `isJobs`:布尔表类型标志位。 - - // Witness
 - message Witness {
 - bytes address = 1;
 - int64 voteCount = 2;
 - bytes pubKey = 3;
 - string url = 4;
 - int64 totalProduced = 5;
 - int64 totalMissed = 6;
 - int64 latestBlockNum = 7; - bool isJobs = 9; - 
} - -+ 一个区块由区块头和多笔交易构成。区块头包含时间戳,交易字典树的根,父哈希,签名等区块基本信息。 - - 一个`block`包含`transactions`和`block_header`。 - `transactions`:区块里的交易信息。 - `block_header`:区块的组成部分之一。 - - // block
 - message Block {
 - repeated Transaction transactions = 1;
 - BlockHeader block_header = 2; - 
} - - `BlockHeader` 包括`raw_data`和`witness_signature`。 - `raw_data`:`raw`信息。 - `witness_signature`:区块头到验证节点的签名。 - - message `raw`包含6种参数: - `timestamp`:该消息体的时间戳——比如:_14356325_。 - `txTrieRoot`:Merkle Tree的根——比如:_“7dacsa…3ed”_。 - `parentHash`:上一个区块的哈希值——比如:_“7dacsa…3ed”_。 - `number`:区块高度——比如:_13534657_。 - `witness_id`:验证节点的id——比如:_“0xu82h…7237”_。 - `witness_address`:验证节点的地址——比如:_“0xu82h…7237”_。 - - message BlockHeader {
 - message raw {
 - int64 timestamp = 1;
 - bytes txTrieRoot = 2;
 - bytes parentHash = 3;
 - //bytes nonce = 5;
 - //bytes difficulty = 6;
 - uint64 number = 7;
 - uint64 witness_id = 8;
 - bytes witness_address = 9;
 - }
 - raw raw_data = 1;
 - bytes witness_signature = 2; - 
} - - 消息体 `ChainInventory` 包括 `BlockId` 和 `remain_num`。 - `BlockId`: block的身份信息。 - `remain_num`:在同步过程中,剩余的区块数量。 - - A `BlockId` contains 2 parameters: - `hash`: 该区块的哈希值。 - `number`: 哈希值和高度即为当前区块块号。 - - message ChainInventory { - message BlockId { - bytes hash = 1; - int64 number = 2; - } - repeated BlockId ids = 1; - int64 remain_num = 2; - } - -+ 交易合约有多种类型,包括账户创建合约、账户更新合约、转账合约、转账断言合约、资产投票合约、见证节点投票合约、见证节点创建合约、见证节点更新合约、资产发布合约、参与资产发布和与部署合约11种类型。 - - `AccountCreatContract`包含3种参数: - `type`:账户类型——比如:_0_ 代表的账户类型是`Normal`。 - `account_name`: 账户名称——比如: _"SiCongsaccount”_。 - `owner_address`:合约持有人地址——比如: _“0xu82h…7237”_。 - - message AccountCreateContract {
 - AccountType type = 1;
 - bytes account_name = 2;
 - bytes owner_address = 3;
 - } - `AccountUpdateContract`包含2种参数: - `account_name`: 账户名称——比如: _"SiCongsaccount”_。 - `owner_address`:合约持有人地址——比如: _“0xu82h…7237”_。 - - message AccountUpdateContract { - bytes account_name = 1; - bytes owner_address = 2; - } - - `TransferContract`包含3种参数: - `amount`:TRX数量——比如:_12534_。 - `to_address`: 接收方地址——比如:_“0xu82h…7237”_。 - `owner_address`:合约持有人地址——比如:_“0xu82h…7237”_。 - - message TransferContract {
 - bytes owner_address = 1;
 - bytes to_address = 2;
 - int64 amount = 3; - 
} - - `TransferAssetContract`包含4种参数: - `asset_name`:资产名称——比如:_”SiCongsaccount”_。 - `to_address`:接收方地址——比如:_“0xu82h…7237”_。 - `owner_address`:合约持有人地址——比如:_“0xu82h…7237”_。 - `amount`:目标资产数量——比如:_12353_。 - - message TransferAssetContract {
 - bytes asset_name = 1;
 - bytes owner_address = 2;
 - bytes to_address = 3;
 - int64 amount = 4;
 - } - - `VoteAssetContract`包含4种参数: - `vote_address`:投票人地址——比如:_“0xu82h…7237”_。 - `support`:投票赞成与否——比如:_true_。 - `owner_address`:合约持有人地址——比如:_“0xu82h…7237”_。 - `count`:投票数目——比如:_2324234_。 - - message VoteAssetContract {
 - bytes owner_address = 1;
 - repeated bytes vote_address = 2;
 - bool support = 3;
 - int32 count = 5; - } - - `VoteWitnessContract`包含4种参数: - `vote_address`:投票人地址——比如:_“0xu82h…7237”_。 - `support`:投票赞成与否——比如:_true_。 - `owner_address`:合约持有人地址——比如:_“0xu82h…7237”_。 - `count`:投票数目——比如:_32632_。 - - message VoteWitnessContract {
 - bytes owner_address = 1;
 - repeated bytes vote_address = 2;
 - bool support = 3;
 - int32 count = 5;
 - } - - `WitnessCreateContract`包含3种参数: - `private_key`:合约的私钥——比如:_“0xu82h…7237”_。 - `owner_address`:合约持有人地址——比如:_“0xu82h…7237”_。 - `url`:合约的url链接。 - - message WitnessCreateContract {
 - bytes owner_address = 1;
 - bytes private_key = 2;
 - bytes url = 12; - 
} - - `WitnessUpdateContract`包含2种参数: - `owner_address`:合约持有人地址——比如:_“0xu82h…7237”_。 - `update_url`:合约的url链接。 - - message WitnessUpdateContract { - bytes owner_address = 1; - bytes update_url = 12; - } - - `AssetIssueContract`包含11种参数: - `name`:合约名称——比如:_“SiCongcontract”_。 - `total_supply`:合约的赞成总票数——比如:_100000000_。 - `owner_address`:合约持有人地址——比如:_“0xu82h…7237”_。 - `trx_num`:对应TRX数量——比如:_232241_。 - `num`: 对应的自定义资产数目。 - `start_time`:开始时间——比如:_20170312_。 - `end_time`:结束时间——比如:_20170512_。 - `vote_score`:合约的评分——比如:_12343_。 - `description`:合约的描述——比如:_”trondada”_。 - `url`:合约的url地址链接。 - - message AssetIssueContract {
 - bytes owner_address = 1;
 - bytes name = 2;
 - int64 total_supply = 4;
 - int32 trx_num = 6;
 - int32 num = 8;
 - int64 start_time = 9;
 - int64 end_time = 10;
 - int32 vote_score = 16;
 - bytes description = 20;
 - bytes url = 21;
 - } - - `ParticipateAssetIssueContract`包含4种参数: - `owner_address`:合约持有人地址——比如:_“0xu82h…7237”_。 - `to_address`:接收方地址——比如:_“0xu82h…7237”_。 - `asset_name`: 目标资产的名称。 - `amount`: 小部分数量。 - - `DeployContract`包含2种参数: - `script`:脚本。 - `owner_address`:合约持有人地址——比如:_“0xu82h…7237”_。 - - message DeployContract {
 - bytes owner_address = 1;
 - bytes script = 2;
 - } - - 消息体 `Result` 包含 `fee` and `ret`2个参数. - `ret`: 交易结果。 - `fee`: 交易扣除的费用。 - - `code`是`ret`的类型定义,有`SUCCESS`和`FAILED`两种类型。 - - message Result { - enum code { - SUCESS = 0; - FAILED = 1; - } - int64 fee = 1; - code ret = 2; - } - -+ 每一个交易还包含多个输入与多个输出,以及其他一些相关属性。其中交易内的输入,交易本身,区块头均需签名。 - - 消息体 `Transaction`包括`raw_data`和`signature`。 - `raw_data`: 消息体`raw`。 - `signature`: 所有输入节点的签名。 - - `raw_data`包含8种参数: - `type`:消息体raw的交易类型。 - `vin`: 输入值。 - `vout`: 输出值。 - `expiration`:过期时间——比如:_20170312_。 - `data`: 数据。 - `contract`: 该交易内的合约。 - `script`: 脚本。 - `timestamp`:该消息体的时间戳。 - - 消息体 `Contract`包含`type`和`parameter`。 - `type`:合约的类型。 - `parameter`:任意参数。 - - 有八种账户类型合约:`AccountCreateContract`,`TransferContract`,`TransferAssetContract`,`VoteAssetContract`,`VoteWitnessContract`,`WitnessCreateContract`,`AssetIssueContract` 和`DeployContract`。 - - `TransactionType`包括`UtxoType`和`ContractType`。 - - message Transaction {
 - enum TranscationType {
 - UtxoType = 0;
 - ContractType = 1;
 - }
 - message Contract {
 - enum ContractType {
 - AccountCreateContract = 0;
 - TransferContract = 1;
 - TransferAssetContract = 2;
 - VoteAssetContract = 3;
 - VoteWitnessContract = 4;
 - WitnessCreateContract = 5;
 - AssetIssueContract = 6;
 - DeployContract = 7;
 - }
 - ContractType type = 1;
 - google.protobuf.Any parameter = 2;
 - }
 - message raw {
 - TranscationType type = 2;
 - repeated TXInput vin = 5;
 - repeated TXOutput vout = 7;
 - int64 expiration = 8;
 - bytes data = 10;
 - repeated Contract contract = 11;
 - bytes scripts = 16;
 - in64 timestamp = 17; - }
 - raw raw_data = 1;
 - repeated bytes signature = 5;
 - } - - 消息体 `TXOutputs`由`outputs`构成。 - `outputs`: 元素为`TXOutput`的数组。 - - message TXOutputs {
 - repeated TXOutput outputs = 1; - 
} - - 消息体 `TXOutput`包括`value`和`pubKeyHash`。 - `value`:输出值。 - `pubKeyhash`:公钥的哈希。 - - message TXOutput {
 - int64 value = 1;
 - bytes pubKeyHash = 2; - 
} - - 消息体 `TXIutput`包括`raw_data`和`signature`。 - `raw_data`:消息体`raw`。 - `signature`:`TXInput`的签名。 - - 消息体 `raw`包含`txID`,`vout`和 `pubKey`。 - `txID`:交易ID。 - `Vout`:上一个输出的值。 - `pubkey`:公钥。 - - message TXInput {
 - message raw {
 - bytes txID = 1;
 - int64 vout = 2;
 - bytes pubKey = 3;
 - }
 - raw raw_data = 1;
 - bytes signature = 4;
} - -+ 传输涉及的协议Inventory主要用于传输中告知接收方传输数据的清单。 - - `Inventory`包括`type`和`ids`。 - `type`:清单类型——比如:_0_ 代表`TRX`。 - `ids`:清单中的物品ID。 - - `InventoryType`包含`TRX`和 `BLOCK`。 - `TRX`:交易。 - `BLOCK`:区块。 - - // Inventory
 - message Inventory {
 - enum InventoryType {
 - TRX = 0;
 - BLOCK = 1;
 - }
 - InventoryType type = 1;
 - repeated bytes ids = 2; - 
} - - 消息体 `Items`包含4种参数: - `type`:物品类型——比如:_1_ 代表 `TRX`。 - `blocks`:物品中区块。 - `blockheaders`:区块头。 - `transactions`:交易。 - - `Items`有四种类型,分别是 `ERR`, `TRX`,`BLOCK` 和`BLOCKHEADER`。 - `ERR`:错误。 - `TRX`:交易。 - `BLOCK`:区块。 - `BLOCKHEADER`:区块头。 - - message Items {
 - enum ItemType {
 - ERR = 0;
 - TRX = 1;
 - BLOCK = 2;
 - BLOCKHEADER = 3;
 - }
 - ItemType type = 1;
 - repeated Block blocks = 2;
 - repeated BlockHeader block_headers = 3;
 - repeated Transaction transactions = 4;
 - } - - `Inventory`包含`type`和`items`。 - `type`:物品种类。 - `items`:物品清单。 - - message InventoryItems {
 - int32 type = 1;
 - repeated bytes items = 2;
 - } - - 消息体 `BlockInventory` 包含 `type`。 - `type`: 清单种类. - - 有三种类型:`SYNC`, `ADVTISE`, `FETCH`。 - - // Inventory - message BlockInventory { - enum Type { - SYNC = 0; - ADVTISE = 1; - FETCH = 2; - } - - 消息体 `BlockId` 包括 `ids` and `type`。 - `ids`: 区块身份信息。 - `type`: 区块类型。 - - `ids` 包含2种参数: - `hash`: 区块的哈希值。 - `number`: 哈希值和区块高度即为当前区块号。 - - message BlockId { - bytes hash = 1; - int64 number = 2; - } - repeated BlockId ids = 1; - Type type = 2; - } - - `ReasonCode` 有15种可能断开的原因: - `REQUESTED` - `TCP_ERROR` - `BAD_PROTOCOL` - `USELESS_PEER` - `TOO_MANY_PEERS` - `DUPLICATE_PEER` - `INCOMPATIBLE_PROTOCOL` - `NULL_IDENTITY` - `PEER_QUITING` - `UNEXPECTED_IDENTITY` - `LOCAL_IDENTITY` - `PING_TIMEOU` - `USER_REASON` - `RESET` - `UNKNOWN` - - enum ReasonCode { - REQUESTED = 0; - TCP_ERROR = 1; - BAD_PROTOCOL = 2; - USELESS_PEER = 3; - TOO_MANY_PEERS = 4; - DUPLICATE_PEER = 5; - INCOMPATIBLE_PROTOCOL = 6; - NULL_IDENTITY = 7; - PEER_QUITING = 8; - UNEXPECTED_IDENTITY = 9; - LOCAL_IDENTITY = 10; - PING_TIMEOUT = 11; - USER_REASON = 12; - RESET = 16; - UNKNOWN = 255; - } - - 消息体`DisconnectMessage`包含`reason`。 - `DisconnectMessage`:断开连接是的消息。 - `reason`:断开连接时的原因。 - - 消息体`HelloMessage`包含2个参数: - `from`请:求建立连接的节点。 - `version`:建立连接的节点。 - -+ 钱包服务RPC和区块链浏览器。 - - `Wallet`钱包服务包含多个RPC。 - __`Getbalance`__:获取`Account`的余额。 - __`CreatTransaction`__:通过`TransferContract`创建交易。 - __`BroadcastTransaction`__:广播`Transaction`。 - __`CreateAccount`__:通过`AccountCreateContract`创建账户。 - __`CreatAssetIssue`__:通过`AssetIssueContract`发布一个资产。 - __`ListAccounts`__:通过`ListAccounts`查看账户列表。 - __`UpdateAccount`__:通过`UpdateAccountContract`发布一个资产。 - __`VoteWitnessAccount`__:通过`VoteWitnessContract`发布一个资产。 - __`WitnessList`__:通过`WitnessList`查看见证节点列表。 - __`UpdateWitness`__:通过`WitnessUpdateContract`发布一个资产。 - __`CreateWitness`__:通过`WitnessCreateContract`发布一个资产。 - __`TransferAsset`__:通过`TransferAssetContract`发布一个资产。 - __`ParticipateAssetIssue`__:通过`ParticipateAssetIssueContract`发布一个资产。 - __`ListNodes`__:通过`ListNodes`查看节点列表。 - __`GetAssetIssueList`__:通过`GetAssetIssueList`查看资产发布节点列表。 - __`GetAssetIssueByAccount`__:通过`Account`获取发行资产。 - __`GetAssetIssueByName`__:通过`Name`获取发行资产。 - __`GetNowBlock`__:获取区块。 - __`GetBlockByNum`__:根据块号获取区块。 - __`TotalTransaction`__:查看总交易量。 - - service Wallet { - - rpc GetAccount (Account) returns (Account) { - - }; - - rpc CreateTransaction (TransferContract) returns (Transaction) { - - }; - - rpc BroadcastTransaction (Transaction) returns (Return) { - - }; - - rpc ListAccounts (EmptyMessage) returns (AccountList) { - - }; - - rpc UpdateAccount (AccountUpdateContract) returns (Transaction) { - - }; - - rpc CreateAccount (AccountCreateContract) returns (Transaction) { - - }; - - rpc VoteWitnessAccount (VoteWitnessContract) returns (Transaction) { - - }; - - rpc CreateAssetIssue (AssetIssueContract) returns (Transaction) { - - }; - - rpc WitnessList (EmptyMessage) returns (WitnessList) { - - }; - - rpc UpdateWitness (WitnessUpdateContract) returns (Transaction) { - - }; - - rpc CreateWitness (WitnessCreateContract) returns (Transaction) { - - }; - - rpc TransferAsset (TransferAssetContract) returns (Transaction) { - - } - - rpc ParticipateAssetIssue (ParticipateAssetIssueContract) returns (Transaction) { - - } - - rpc ListNodes (EmptyMessage) returns (NodeList) { - - } - rpc GetAssetIssueList (EmptyMessage) returns (AssetIssueList) { - - } - rpc GetAssetIssueByAccount (Account) returns (AssetIssueList) { - - } - rpc GetAssetIssueByName (BytesMessage) returns (AssetIssueContract) { - - } - rpc GetNowBlock (EmptyMessage) returns (Block) { - - } - rpc GetBlockByNum (NumberMessage) returns (Block) { - - } - rpc TotalTransaction (EmptyMessage) returns (NumberMessage) { - - } - }; - - `AccountList`: 区块链浏览器中的账户列表。 - 消息体 `AccountList` 包含1个参数: - `account`: - - message AccountList { - repeated Account accounts = 1; - } - - `WitnessList`:区块链浏览器中的见证节点列表。 - 消息体 `WitnessList` 包含1个参数: - `witnesses`: - - message WitnessList { - repeated Witness witnesses = 1; - } - - `AssetIssueList`:区块链浏览器中的发布资产列表。 - 消息体 `AssetIssueList` 包含1个参数: - `assetIssue`: - - message AssetIssueList { - repeated AssetIssueContract assetIssue = 1; - } - - - `NodeList`: 分布节点图中的节点列表。 - 消息体 `NodeList` 包含1个参数: - `nodes`: - - message NodeList { - repeated Node nodes = 1; - } - - `Address`: 节点地址。 - 消息体`Address` 包含2个参数: - `host`:节点所有者。 - `port`:节点的端口号。 - - message Address { - bytes host = 1; - int32 port = 2; - } - - - 消息体`Return`只含有一个参数: - `result`: 布尔表类型标志位。 - - message `Return` {
 - bool result = 1;
 - } - -+ 网络UDP消息结构。 - - `Endpoint`:网络中节点信息存储结构. - 消息体`Endpoint` 包含3个参数: - `address`:节点地址。 - `port`:端口号。 - `nodeId`: 节点ID信息。 - - message Endpoint { - bytes address = 1; - int32 port = 2; - bytes nodeId = 3; - } - - `PingMessage`:节点建立连接时所发送的消息。 - 消息体`PingMessage` 包含4个参数: - `from`:消息来自的节点。 - `to`: 消息发送的节点。 - `version`: 网络版本。 - `timestamp`:消息创建时的时间戳。 - - message PingMessage { - Endpoint from = 1; - Endpoint to = 2; - int32 version = 3; - int64 timestamp = 4; - } - - `PongMessage`:连接建立成功时的回复消息。 - 消息体`PongMessage` 包含3个参数: - `from`:消息来自的节点。 - `echo`: - `timestamp`:消息创建时的时间戳。 - - message PongMessage { - Endpoint from = 1; - int32 echo = 2; - int64 timestamp = 3; - } - - `FindNeighbours`:节点查询相邻节点时所发送的消息。 - 消息体`FindNeighbours` 包含3个参数: - `from`: 消息来自的节点。 - `targetId`: 目标节点的信息。 - `timestamp`: 消息创建时的时间戳。 - - message FindNeighbours { - Endpoint from = 1; - bytes targetId = 2; - int64 timestamp = 3; - } - - `Neighbour`:相邻接点回复消息。 - 消息体`Neighbours` 包含3个参数: - `from`: 消息来自的节点。 - `neighbours`: 相邻节点。 - `timestamp`: 消息创建时的时间戳。 - - message Neighbours { - Endpoint from = 1; - repeated Endpoint neighbours = 2; - int64 timestamp = 3; - } - -# 详细的协议见附属文件。详细协议随着程序的迭代随时都可能发生变化,请以最新的版本为准。 \ No newline at end of file diff --git a/packages/kos/src/protos/tron/English version of TRON Protocol document.md b/packages/kos/src/protos/tron/English version of TRON Protocol document.md deleted file mode 100644 index e282f4b..0000000 --- a/packages/kos/src/protos/tron/English version of TRON Protocol document.md +++ /dev/null @@ -1,736 +0,0 @@ - -# Protobuf protocol - -## The protocol of TRON is defined by Google Protobuf and contains a range of layers, from account, block to transfer. - -+ There are 3 types of account—basic account, asset release account and contract account, and attributes included in each account are name, types, address, balance and related asset. -+ A basic account is able to apply to be a validation node, which has serval parameters, including extra attributes, public key, URL, voting statistics, history performance, etc. - - There are three different `Account types`: `Normal`, `AssetIssue`, `Contract`. -```protobuf -enum AccountType {
 - Normal = 0;
 - AssetIssue = 1;
 - Contract = 2;
 -
} -``` - - - An `Account` contains 7 parameters: - `account_name`: the name for this account – e.g. “_BillsAccount_”. - `type`: what type of this account is – e.g. _0_ stands for type `Normal`. - `balance`: balance of this account – e.g. _4213312_. - `votes`: received votes on this account – e.g. _{(“0x1b7w…9xj3”,323), (“0x8djq…j12m”,88),…,(“0x82nd…mx6i”,10001)}_. - `asset`: other assets expect TRX in this account – e.g. _{<“WishToken”,66666>,<”Dogie”,233>}_. - `latest_operation_time`: the latest operation time of this account. -```protobuf -// Account
 -message Account {
 - message Vote {
 - bytes vote_address = 1;
 - int64 vote_count = 2;
 }
 - bytes accout_name = 1;
 - AccountType type = 2;
 - bytes address = 3;
 - int64 balance = 4;
 - repeated Vote votes = 5;
 - map asset = 6; - int64 latest_operation_time = 10;
 -} -``` - A `Witness` contains 8 parameters: - `address`: the address of this witness – e.g. “_0xu82h…7237_”. - `voteCount`: number of received votes on this witness – e.g. _234234_. - `pubKey`: the public key for this witness – e.g. “_0xu82h…7237_”. - `url`: the url for this witness – e.g. “_https://www.noonetrust.com_”. - `totalProduced`: the number of blocks this witness produced – e.g. _2434_. - `totalMissed`: the number of blocks this witness missed – e.g. _7_. - `latestBlockNum`: the latest height of block – e.g. _4522_. - `isjobs`: a bool flag. -```protobuf -// Witness
 -message Witness{
 - bytes address = 1;
 - int64 voteCount = 2;
 - bytes pubKey = 3;
 - string url = 4;
 - int64 totalProduced = 5;
 - int64 totalMissed = 6;
 - int64 latestBlockNum = 7;
 - bool isJobs = 9; -} -``` -+ A block typically contains transaction data and a blockheader, which is a list of basic block information, including timestamp, signature, parent hash, root of Merkle tree and so on. - - A block contains `transactions` and a `block_header`. - `transactions`: transaction data of this block. - `block_header`: one part of a block. - ```protobuf - // block -message Block {
 - repeated Transaction transactions = 1;
 - BlockHeader block_header = 2;
 -} -``` - A `BlockHeader` contains `raw_data` and `witness_signature`. - `raw_data`: a `raw` message. - `witness_signature`: signature for this block header from witness node. - - A message `raw` contains 6 parameters: - `timestamp`: timestamp of this message – e.g. _14356325_. - `txTrieRoot`: the root of Merkle Tree in this block – e.g. “_7dacsa…3ed_.” - `parentHash`: the hash of last block – e.g. “_7dacsa…3ed_.” - `number`: the height of this block – e.g. _13534657_. - `witness_id`: the id of witness which packed this block – e.g. “_0xu82h…7237_”. - `witness_address`: the adresss of the witness packed this block – e.g. “_0xu82h…7237_”. -```protobuf -message BlockHeader {
 - message raw {
 - int64 timestamp = 1;
 - bytes txTrieRoot = 2;
 - bytes parentHash = 3;
 - //bytes nonce = 5;
 - //bytes difficulty = 6;
 - uint64 number = 7;
 - uint64 witness_id = 8;
 - bytes witness_address = 9;
 - }
 - raw raw_data = 1;
 - bytes witness_signature = 2;
 -} -``` - message `ChainInventory` contains `BlockId` and `remain_num`. - `BlockId`: the identification of block. - `remain_num`:the remain number of blocks in the synchronizing process. - - A `BlockId` contains 2 parameters: - `hash`: the hash of block. - `number`: the hash and height of block. -```protobuf -message ChainInventory { - message BlockId { - bytes hash = 1; - int64 number = 2; - } - repeated BlockId ids = 1; - int64 remain_num = 2; -} -``` -+ Transaction contracts mainly includes account create contract, account update contract transfer contract, transfer asset contract, vote asset contract, vote witness contract, witness creation contract, witness update contract, asset issue contract, participate asset issue contract and deploy contract. - - An `AccountCreateContract` contains 3 parameters: - `type`: What type this account is – e.g. _0_ stands for `Normal`. - `account_name`: the name for this account – e.g.”_Billsaccount_”. - `owner_address`: the address of contract owner – e.g. “_0xu82h…7237_”. -```protobuf -message AccountCreateContract {
 - AccountType type = 1;
 - bytes account_name = 2;
 - bytes owner_address = 3;
 -} -``` - A `AccountUpdateContract` contains 2 paremeters: - `account_name`: the name for this account – e.g.”_Billsaccount_”. - `owner_address`: the address of contract owner – e.g. “_0xu82h…7237_”. -```protobuf -message AccountUpdateContract { - bytes account_name = 1; - bytes owner_address = 2; -} -``` - A `TransferContract` contains 3 parameters: - `amount`: the amount of TRX – e.g. _12534_. - `to_address`: the receiver address – e.g. “_0xu82h…7237_”. - `owner_address`: the address of contract owner – e.g. “_0xu82h…7237_”. -```protobuf -message TransferContract {
 - bytes owner_address = 1;
 - bytes to_address = 2;
 - int64 amount = 3; -} -``` - A `TransferAssetContract` contains 4 parameters: - `asset_name`: the name for asset – e.g.”_Billsaccount_”. - `to_address`: the receiver address – e.g. “_0xu82h…7237_”. - `owner_address`: the address of contract owner – e.g. “_0xu82h…7237_”. - `amount`: the amount of target asset - e.g._12353_. -```protobuf -message TransferAssetContract {
 - bytes asset_name = 1;
 - bytes owner_address = 2;
 - bytes to_address = 3;
 - int64 amount = 4;
 -} -``` - A `VoteAssetContract` contains 4 parameters: - `vote_address`: the voted address of the asset. - `support`: is the votes supportive or not – e.g. _true_. - `owner_address`: the address of contract owner – e.g. “_0xu82h…7237_”. - `count`: the count number of votes- e.g. _2324234_. -```protobuf - message VoteAssetContract {
 - bytes owner_address = 1;
 - repeated bytes vote_address = 2;
 - bool support = 3;
 - int32 count = 5;
 - } -``` - A `VoteWitnessContract` contains 4 parameters: - `vote_address`: the addresses of those who voted. - `support`: is the votes supportive or not - e.g. _true_. - `owner_address`: the address of contract owner – e.g. “_0xu82h…7237_”. - `count`: - e.g. the count number of vote – e.g. _32632_. - - message VoteWitnessContract {
 - bytes owner_address = 1;
 - repeated bytes vote_address = 2;
 - bool support = 3;
 - int32 count = 5; - 
} - - A `WitnessCreateContract` contains 3 parameters: - `private_key`: the private key of contract– e.g. “_0xu82h…7237_”. - `owner_address`: the address of contract owner – e.g. “_0xu82h…7237_”. - `url`: the url for the witness – e.g. “_https://www.noonetrust.com_”. - - message WitnessCreateContract {
 - bytes owner_address = 1;
 - bytes private_key = 2;
 - bytes url = 12;
 - } - - A `WitnessUpdateContract` contains 2 parameters: - `owner_address`: the address of contract owner – e.g. “_0xu82h…7237_”. - `update_url`: the url for the witness – e.g. “_https://www.noonetrust.com_”. - - message WitnessUpdateContract { - bytes owner_address = 1; - bytes update_url = 12; - } - - An `AssetIssueContract` contains 11 parameters: - `owner_address`: the address for contract owner – e.g. “_0xu82h…7237_”. - `name`: the name for this contract – e.g. “Billscontract”. - `total_supply`: the maximum supply of this asset – e.g. _1000000000_. - `trx_num`: the number of TRONIX – e.g._232241_. - `num`: number of corresponding asset. - `start_time`: the starting date of this contract – e.g._20170312_. - `end_time`: the expiring date of this contract – e.g. _20170512_. - `vote_score`: the vote score of this contract received – e.g. _12343_. - `description`: the description of this contract – e.g.”_trondada_”. - `url`: the url of this contract – e.g. “_https://www.noonetrust.com_”. - - message AssetIssueContract {
 - bytes owner_address = 1;
 - bytes name = 2;
 - int64 total_supply = 4;
 - int32 trx_num = 6;
 - int32 num = 8;
 - int64 start_time = 9;
 - int64 end_time = 10;
 - int32 vote_score = 16;
 - bytes description = 20;
 - bytes url = 21;
 - } - - A `ParticipateAssetIssueContract` contains 4 parameters: - `owner_address`: the address for contract owner – e.g. “_0xu82h…7237_”. - `to_address`: the receiver address – e.g. “_0xu82h…7237_”. - `asset_name`: the name of target asset. - `amount`: the amount of drops. - - message ParticipateAssetIssueContract { - bytes owner_address = 1; - bytes to_address = 2; - bytes asset_name = 3; - int64 amount = 4; - } - - A `DeployContract` contains 2 parameters: - `script`: the script of this contract. - `owner_address`: the address for contract owner – e.g. “_0xu82h…7237_”. - - message DeployContract {
 - bytes owner_address = 1;
 - bytes script = 2; - 
} t - -+ Each transaction contains several TXInputs, TXOutputs and other related qualities. -Input, transaction and head block all require signature. - - message `Transaction` contains `raw_data` and `signature`. - `raw_data`: message `raw`. - `signature`: signatures form all input nodes. - - `raw` contains 8 parameters: - `type`: the transaction type of `raw` message. - `vin`: input values. - `vout`: output values. - `expiration`: the expiration date of transaction – e.g._20170312_. - `data`: data. - `contract`: contracts in this transaction. - `scripts`:scripts in the transaction. - `timestamp`: timestamp of this raw data – e.g. _14356325_. - - message `Contract` contains `type` and `parameter`. - `type`: what type of the message contract. - `parameter`: It can be any form. - - There are 8 different of contract types: `AccountCreateContract`, `TransferContract`, `TransferAssetContract`, `VoteAssetContract`, `VoteWitnessContract`,`WitnessCreateContract`, `AssetIssueContract` and `DeployContract`. - `TransactionType` have two types: `UtxoType` and `ContractType`. - - message Transaction {
 - enum TranscationType {
 - UtxoType = 0;
 - ContractType = 1;
 - }
 - message Contract {
 - enum ContractType {
 - AccountCreateContract = 0;
 - TransferContract = 1;
 - TransferAssetContract = 2;
 - VoteAssetContract = 3;
 - VoteWitnessContract = 4;
 - WitnessCreateContract = 5;
 - AssetIssueContract = 6;
 - DeployContract = 7;
 - WitnessUpdateContract = 8; - ParticipateAssetIssueContract = 9 - }
 - ContractType type = 1;
 - google.protobuf.Any parameter = 2;
 - }
 - message raw {
 - TranscationType type = 2;
 - repeated TXInput vin = 5;
 - repeated TXOutput vout = 7;
 - int64 expiration = 8;
 - bytes data = 10;
 - repeated Contract contract = 11;
 - bytes scripts = 16;
 - int64 timestamp = 17; - }
 - raw raw_data = 1;
 - repeated bytes signature = 5; - 
} - - message `TXOutputs` contains `outputs`. - `outputs`: an array of `TXOutput`. - - message TXOutputs {
 - repeated TXOutput outputs = 1;
 - } - - message `TXOutput` contains `value` and `pubKeyHash`. - `value`: output value. - `pubKeyHash`: Hash of public key - - message TXOutput {
 - int64 value = 1;
 - bytes pubKeyHash = 2;
 - } - - message `TXInput` contains `raw_data` and `signature`. - `raw_data`: a message `raw`. - `signature`: signature for this `TXInput`. - - message `raw` contains `txID`, `vout` and `pubKey`. - `txID`: transaction ID. - `vout`: value of last output. - `pubKey`: public key. - - message TXInput {
 - message raw {
 - bytes txID = 1;
 - int64 vout = 2;
 - bytes pubKey = 3;
 - }
 - raw raw_data = 1;
 - bytes signature = 4; - 
} - - message `Result` contains `fee` and `ret`. - `ret`: the state of transaction. - `fee`: the fee for transaction. - - `code` is definition of `ret` and contains 2 types:`SUCCESS` and `FAILED`. - - message Result { - enum code { - SUCESS = 0; - FAILED = 1; - } - int64 fee = 1; - code ret = 2; - } - -+ Inventory is mainly used to inform peer nodes the list of items. - - `Inventory` contains `type` and `ids`. - `type`: what type this `Inventory` is. – e.g. _0_ stands for `TRX`. - `ids`: ID of things in this `Inventory`. - - Two `Inventory` types: `TRX` and `BLOCK`. - `TRX`: transaction. - `BLOCK`: block. - - // Inventory
 - message Inventory {
 - enum InventoryType {
 - TRX = 0;
 - BLOCK = 1;
 - }
 - InventoryType type = 1;
 - repeated bytes ids = 2;
 - } - - message `Items` contains 4 parameters: - `type`: type of items – e.g. _1_ stands for `TRX`. - `blocks`: blocks in `Items` if there is any. - `block_headers`: block headers if there is any. - `transactions`: transactions if there is any. - - `Items` have four types: `ERR`, `TRX`, `BLOCK` and `BLOCKHEADER`. - `ERR`: error. - `TRX`: transaction. - `BLOCK`: block. - `BLOCKHEADER`: block header. - - message Items {
 - enum ItemType {
 - ERR = 0;
 - TRX = 1;
 - BLOCK = 2;
 - BLOCKHEADER = 3;
 - }
 - ItemType type = 1;
 - repeated Block blocks = 2;
 - repeated BlockHeader - block_headers = 3;
 - repeated Transaction transactions = 4; - } - - `InventoryItems` contains `type` and `items`. - `type`: what type of item. - `items`: items in an `InventoryItems`. - - message InventoryItems {
 - int32 type = 1;
 - repeated bytes items = 2; - 
} - - message `BlockInventory` contains `type`. - `type`: what type of inventory. - - There are 3 types:`SYNC`, `ADVTISE`, `FETCH`. - - // Inventory - message BlockInventory { - enum Type { - SYNC = 0; - ADVTISE = 1; - FETCH = 2; - } - - message `BlockId` contains `ids` and `type`. - `ids`: the identification of block. - `type`: what type of the block. - - `ids` contains 2 paremeters: - `hash`: the hash of block. - `number`: the hash and height of block. - - message BlockId { - bytes hash = 1; - int64 number = 2; - } - repeated BlockId ids = 1; - Type type = 2; - } - - `ReasonCode`: the type of reason. - - `ReasonCode` contains 15 types of disconnect reasons: - `REQUESTED` - `TCP_ERROR` - `BAD_PROTOCOL` - `USELESS_PEER` - `TOO_MANY_PEERS` - `DUPLICATE_PEER` - `INCOMPATIBLE_PROTOCOL` - `NULL_IDENTITY` - `PEER_QUITING` - `UNEXPECTED_IDENTITY` - `LOCAL_IDENTITY` - `PING_TIMEOUT` - `USER_REASON` - `RESET` - `UNKNOWN` - - enum ReasonCode { - REQUESTED = 0; - TCP_ERROR = 1; - BAD_PROTOCOL = 2; - USELESS_PEER = 3; - TOO_MANY_PEERS = 4; - DUPLICATE_PEER = 5; - INCOMPATIBLE_PROTOCOL = 6; - NULL_IDENTITY = 7; - PEER_QUITING = 8; - UNEXPECTED_IDENTITY = 9; - LOCAL_IDENTITY = 10; - PING_TIMEOUT = 11; - USER_REASON = 12; - RESET = 16; - UNKNOWN = 255; - } - - message`DisconnectMessage` contains `reason`. - `DisconnectMessage`: the message when disconnection occurs. - `reason`: the reason for disconnecting. - - message`HelloMessage` contains 2 parameters: - `HelloMessage`: the message for building connection. - `from`: the nodes that request for building connection. - `version`: the version when connection is built. - - - -+ Wallet Service RPC and blockchain explorer - - `Wallet` service contains several RPCs. - __`GetBalance`__ : - Return balance of an `Account`. - __`CreateTransaction`__ : - Create a transaction by giving a `TransferContract`. A Transaction containing a transaction creation will be returned. - __`BroadcastTransaction`__ : - Broadcast a `Transaction`. A `Return` will be returned indicating if broadcast is success of not. - __`CreateAccount`__ : - Create an account by giving a `AccountCreateContract`. - __`CreatAssetIssue`__ : - Issue an asset by giving a `AssetIssueContract`. - __`ListAccounts`__: - Check out the list of accounts by giving a `ListAccounts`. - __`UpdateAccount`__: - Issue an asset by giving a `UpdateAccountContract`. - __`VoteWitnessAccount`__: - Issue an asset by giving a `VoteWitnessContract`. - __`WitnessList`__: - Check out the list of witnesses by giving a `WitnessList`. - __`UpdateWitness`__: - Issue an asset by giving a `WitnessUpdateContract`. - __`CreateWitness`__: - Issue an asset by giving a `WitnessCreateContract`. - __`TransferAsset`__: - Issue an asset by giving a `TransferAssetContract`. - __`ParticipateAssetIssue`__: - Issue an asset by giving a `ParticipateAssetIssueContract`. - __`ListNodes`__: - Check out the list of nodes by giving a `ListNodes`. - __`GetAssetIssueList`__: - Get the list of issue asset by giving a `GetAssetIssueList`. - __`GetAssetIssueByAccount`__: - Get issue asset by giving a `Account`. - __`GetAssetIssueByName`__: - Get issue asset by giving a`Name`. - __`GetNowBlock`__: - Get block. - __`GetBlockByNum`__: - Get block by block number. - __`TotalTransaction`__: - Check out the total transaction. - - service Wallet { - - rpc GetAccount (Account) returns (Account) { - - }; - - rpc CreateTransaction (TransferContract) returns (Transaction) { - - }; - - rpc BroadcastTransaction (Transaction) returns (Return) { - - }; - - rpc ListAccounts (EmptyMessage) returns (AccountList) { - - }; - - rpc UpdateAccount (AccountUpdateContract) returns (Transaction) { - - }; - - rpc CreateAccount (AccountCreateContract) returns (Transaction) { - - }; - - rpc VoteWitnessAccount (VoteWitnessContract) returns (Transaction) { - - }; - - rpc CreateAssetIssue (AssetIssueContract) returns (Transaction) { - - }; - - rpc ListWitnesses (EmptyMessage) returns (WitnessList) { - - }; - - rpc UpdateWitness (WitnessUpdateContract) returns (Transaction) { - - }; - - rpc CreateWitness (WitnessCreateContract) returns (Transaction) { - - }; - - rpc TransferAsset (TransferAssetContract) returns (Transaction) { - - } - - rpc ParticipateAssetIssue (ParticipateAssetIssueContract) returns (Transaction) { - - } - - rpc ListNodes (EmptyMessage) returns (NodeList) { - - } - rpc GetAssetIssueList (EmptyMessage) returns (AssetIssueList) { - - } - rpc GetAssetIssueByAccount (Account) returns (AssetIssueList) { - - } - rpc GetAssetIssueByName (BytesMessage) returns (AssetIssueContract) { - - } - rpc GetNowBlock (EmptyMessage) returns (Block) { - - } - rpc GetBlockByNum (NumberMessage) returns (Block) { - - } - rpc TotalTransaction (EmptyMessage) returns (NumberMessage) { - - } - }; - - `AccountList`: the list of acounts in the blockchain explorer. - message `AccountList` contains one parameter: - `account`: - - message AccountList { - repeated Account accounts = 1; - } - - `WitnessList`: the list of witnesses in the blockchain explorer. - message `WitnessList` contains one parameter: - `witnesses`: - - message WitnessList { - repeated Witness witnesses = 1; - } - - `AssetIssueList`: the list of issue asset in the blockchain explorer. - message `AssetIssueList` contains one parameter: - `assetIssue`: - - message AssetIssueList { - repeated AssetIssueContract assetIssue = 1; - } - - `NodeList`: the list of nodes in the node distribution map. - message `NodeList` contains one parameter: - `nodes`: - - message NodeList { - repeated Node nodes = 1; - } - - `Address`: the address of nodes. - message`Address` contains 2 parameters: - `host`: the host of nodes. - `port`: the port number of nodes. - - message Address { - bytes host = 1; - int32 port = 2; - } - - message `Return` has only one parameter: - `result`: a bool flag. - - message `Return` {
 - bool result = 1; - 
} - -+ The message structure of UDP. - - `Endpoint`: the storage structure of nodes' information. - message`Endpoint` contains 3 parameters: - `address`: the address of nodes. - `port`: the port number. - `nodeId`:the ID of nodes. - - - message Endpoint { - bytes address = 1; - int32 port = 2; - bytes nodeId = 3; - } - - `PingMessage`: the message sent from one node to another in the connecting process. - message`PingMessage` contains 4 parameters: - `from`: which node does the message send from. - `to`: which node will the message send to. - `version`: the version of the Internet. - `timestamp`: the timestamp of message. - - message PingMessage { - Endpoint from = 1; - Endpoint to = 2; - int32 version = 3; - int64 timestamp = 4; - } - - `PongMessage`: the message implies that nodes are connected. - message`PongMessage` contains 3 parameters: - `from`: which node does the message send from. - `echo`: - `timestamp`: the timestamp of message. - - message PongMessage { - Endpoint from = 1; - int32 echo = 2; - int64 timestamp = 3; - } - - `FindNeighbours`: the message sent from one node to find another one. - message`FindNeighbours` contains 3 parameters: - `from`: which node does the message send from. - `targetId`: the ID of targeted node. - `timestamp`: the timestamp of message. - - message FindNeighbours { - Endpoint from = 1; - bytes targetId = 2; - int64 timestamp = 3; - } - - `FindNeighbour`: the message replied by the neighbour node. - message`Neighbours` contains 3 parameters: - `from`: which node does the message send from. - `neighbours`: the neighbour node. - `timestamp`: the timestamp of message. - - message Neighbours { - Endpoint from = 1; - repeated Endpoint neighbours = 2; - int64 timestamp = 3; - } - - - -# Please check detailed protocol document that may change with the iteration of the program at any time. Please refer to the latest version. diff --git a/packages/kos/src/protos/tron/LICENSE b/packages/kos/src/protos/tron/LICENSE deleted file mode 100644 index 65c5ca8..0000000 --- a/packages/kos/src/protos/tron/LICENSE +++ /dev/null @@ -1,165 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. diff --git a/packages/kos/src/protos/tron/README.md b/packages/kos/src/protos/tron/README.md deleted file mode 100644 index e409e04..0000000 --- a/packages/kos/src/protos/tron/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# protocol [![Build Status](https://travis-ci.org/tronprotocol/protocol.svg?branch=master)](https://travis-ci.org/tronprotocol/protocol) - - -# The protocol of Tron including api and message. - -The protocol is an independent project. You can use it for building other application. - -java-tron, wallet-cli and grpc-gateway - -git subtree pull --prefix src/main/protos/ protocol master - -## Run the included *.sh files to initialize the dependencies - diff --git a/packages/kos/src/protos/tron/api/api.proto b/packages/kos/src/protos/tron/api/api.proto deleted file mode 100644 index 2505fa4..0000000 --- a/packages/kos/src/protos/tron/api/api.proto +++ /dev/null @@ -1,1536 +0,0 @@ -syntax = "proto3"; -package protocol; - -import "core/Tron.proto"; -import "google/api/annotations.proto"; - -import "core/contract/asset_issue_contract.proto"; -import "core/contract/account_contract.proto"; -import "core/contract/witness_contract.proto"; -import "core/contract/balance_contract.proto"; -import "core/contract/proposal_contract.proto"; -import "core/contract/storage_contract.proto"; -import "core/contract/exchange_contract.proto"; -import "core/contract/market_contract.proto"; -import "core/contract/smart_contract.proto"; -import "core/contract/shield_contract.proto"; - -option java_package = "org.tron.api"; //Specify the name of the package that generated the Java file -option java_outer_classname = "GrpcAPI"; //Specify the class name of the generated Java file -option go_package = "github.com/tronprotocol/grpc-gateway/api"; - -service Wallet { - - rpc GetAccount (Account) returns (Account) { - option (google.api.http) = { - post: "/wallet/getaccount" - body: "*" - additional_bindings { - get: "/wallet/getaccount" - } - }; - }; - - rpc GetAccountById (Account) returns (Account) { - option (google.api.http) = { - post: "/wallet/getaccountbyid" - body: "*" - additional_bindings { - get: "/wallet/getaccountbyid" - } - }; - }; - - rpc GetAccountBalance (AccountBalanceRequest) returns (AccountBalanceResponse) { - option (google.api.http) = { - post: "/wallet/getaccountbalance" - body: "*" - additional_bindings { - get: "/wallet/getaccountbalance" - } - }; - }; - - rpc GetBlockBalanceTrace (BlockBalanceTrace.BlockIdentifier) returns (BlockBalanceTrace) { - option (google.api.http) = { - post: "/wallet/getblockbalancetrace" - body: "*" - additional_bindings { - get: "/wallet/getblockbalancetrace" - } - }; - }; - - //Please use CreateTransaction2 instead of this function. - rpc CreateTransaction (TransferContract) returns (Transaction) { - option (google.api.http) = { - post: "/wallet/createtransaction" - body: "*" - additional_bindings { - get: "/wallet/createtransaction" - } - }; - }; - //Use this function instead of CreateTransaction. - rpc CreateTransaction2 (TransferContract) returns (TransactionExtention) { - }; - - rpc BroadcastTransaction (Transaction) returns (Return) { - option (google.api.http) = { - post: "/wallet/broadcasttransaction" - body: "*" - additional_bindings { - get: "/wallet/broadcasttransaction" - } - }; - }; - //Please use UpdateAccount2 instead of this function. - rpc UpdateAccount (AccountUpdateContract) returns (Transaction) { - option (google.api.http) = { - post: "/wallet/updateaccount" - body: "*" - additional_bindings { - get: "/wallet/updateaccount" - } - }; - }; - - - rpc SetAccountId (SetAccountIdContract) returns (Transaction) { - option (google.api.http) = { - post: "/wallet/setaccountid" - body: "*" - additional_bindings { - get: "/wallet/setaccountid" - } - }; - }; - - //Use this function instead of UpdateAccount. - rpc UpdateAccount2 (AccountUpdateContract) returns (TransactionExtention) { - }; - - //Please use VoteWitnessAccount2 instead of this function. - rpc VoteWitnessAccount (VoteWitnessContract) returns (Transaction) { - option (google.api.http) = { - post: "/wallet/votewitnessaccount" - body: "*" - additional_bindings { - get: "/wallet/votewitnessaccount" - } - }; - }; - - //modify the consume_user_resource_percent - rpc UpdateSetting (UpdateSettingContract) returns (TransactionExtention) { - }; - - //modify the energy_limit - rpc UpdateEnergyLimit (UpdateEnergyLimitContract) returns (TransactionExtention) { - }; - - //Use this function instead of VoteWitnessAccount. - rpc VoteWitnessAccount2 (VoteWitnessContract) returns (TransactionExtention) { - }; - //Please use CreateAssetIssue2 instead of this function. - rpc CreateAssetIssue (AssetIssueContract) returns (Transaction) { - option (google.api.http) = { - post: "/wallet/createassetissue" - body: "*" - additional_bindings { - get: "/wallet/createassetissue" - } - }; - }; - //Use this function instead of CreateAssetIssue. - rpc CreateAssetIssue2 (AssetIssueContract) returns (TransactionExtention) { - }; - //Please use UpdateWitness2 instead of this function. - rpc UpdateWitness (WitnessUpdateContract) returns (Transaction) { - option (google.api.http) = { - post: "/wallet/updatewitness" - body: "*" - additional_bindings { - get: "/wallet/updatewitness" - } - }; - }; - //Use this function instead of UpdateWitness. - rpc UpdateWitness2 (WitnessUpdateContract) returns (TransactionExtention) { - }; - //Please use CreateAccount2 instead of this function. - rpc CreateAccount (AccountCreateContract) returns (Transaction) { - option (google.api.http) = { - post: "/wallet/createaccount" - body: "*" - additional_bindings { - get: "/wallet/createaccount" - } - }; - }; - //Use this function instead of CreateAccount. - rpc CreateAccount2 (AccountCreateContract) returns (TransactionExtention) { - } - - //Please use CreateWitness2 instead of this function. - rpc CreateWitness (WitnessCreateContract) returns (Transaction) { - option (google.api.http) = { - post: "/wallet/createwitness" - body: "*" - additional_bindings { - get: "/wallet/createwitness" - } - }; - }; - //Use this function instead of CreateWitness. - rpc CreateWitness2 (WitnessCreateContract) returns (TransactionExtention) { - } - //Please use TransferAsset2 instead of this function. - rpc TransferAsset (TransferAssetContract) returns (Transaction) { - option (google.api.http) = { - post: "/wallet/transferasset" - body: "*" - additional_bindings { - get: "/wallet/transferasset" - } - }; - } - //Use this function instead of TransferAsset. - rpc TransferAsset2 (TransferAssetContract) returns (TransactionExtention) { - } - //Please use ParticipateAssetIssue2 instead of this function. - rpc ParticipateAssetIssue (ParticipateAssetIssueContract) returns (Transaction) { - option (google.api.http) = { - post: "/wallet/participateassetissue" - body: "*" - additional_bindings { - get: "/wallet/participateassetissue" - } - }; - } - //Use this function instead of ParticipateAssetIssue. - rpc ParticipateAssetIssue2 (ParticipateAssetIssueContract) returns (TransactionExtention) { - } - //Please use FreezeBalance2 instead of this function. - rpc FreezeBalance (FreezeBalanceContract) returns (Transaction) { - option (google.api.http) = { - post: "/wallet/freezebalance" - body: "*" - additional_bindings { - get: "/wallet/freezebalance" - } - }; - } - //Use this function instead of FreezeBalance. - rpc FreezeBalance2 (FreezeBalanceContract) returns (TransactionExtention) { - } - //Use this function when FreezeBalanceV2. - rpc FreezeBalanceV2 (FreezeBalanceV2Contract) returns (TransactionExtention) { - } - - //Please use UnfreezeBalance2 instead of this function. - rpc UnfreezeBalance (UnfreezeBalanceContract) returns (Transaction) { - option (google.api.http) = { - post: "/wallet/unfreezebalance" - body: "*" - additional_bindings { - get: "/wallet/unfreezebalance" - } - }; - } - //Use this function instead of UnfreezeBalance. - rpc UnfreezeBalance2 (UnfreezeBalanceContract) returns (TransactionExtention) { - } - //Use this function when UnfreezeBalanceV2. - rpc UnfreezeBalanceV2 (UnfreezeBalanceV2Contract) returns (TransactionExtention) { - } - - //Please use UnfreezeAsset2 instead of this function. - rpc UnfreezeAsset (UnfreezeAssetContract) returns (Transaction) { - option (google.api.http) = { - post: "/wallet/unfreezeasset" - body: "*" - additional_bindings { - get: "/wallet/unfreezeasset" - } - }; - } - //Use this function instead of UnfreezeAsset. - rpc UnfreezeAsset2 (UnfreezeAssetContract) returns (TransactionExtention) { - } - //Please use WithdrawBalance2 instead of this function. - rpc WithdrawBalance (WithdrawBalanceContract) returns (Transaction) { - option (google.api.http) = { - post: "/wallet/withdrawbalance" - body: "*" - additional_bindings { - get: "/wallet/withdrawbalance" - } - }; - } - //Use this function instead of WithdrawBalance. - rpc WithdrawBalance2 (WithdrawBalanceContract) returns (TransactionExtention) { - } - - rpc WithdrawExpireUnfreeze (WithdrawExpireUnfreezeContract) returns (TransactionExtention) { - } - - rpc DelegateResource (DelegateResourceContract) returns (TransactionExtention) { - } - - rpc UnDelegateResource (UnDelegateResourceContract) returns (TransactionExtention) { - } - - rpc CancelAllUnfreezeV2 (CancelAllUnfreezeV2Contract) returns (TransactionExtention) { - } - - //Please use UpdateAsset2 instead of this function. - rpc UpdateAsset (UpdateAssetContract) returns (Transaction) { - option (google.api.http) = { - post: "/wallet/updateasset" - body: "*" - additional_bindings { - get: "/wallet/updateasset" - } - }; - } - //Use this function instead of UpdateAsset. - rpc UpdateAsset2 (UpdateAssetContract) returns (TransactionExtention) { - } - - rpc ProposalCreate (ProposalCreateContract) returns (TransactionExtention) { - } - - rpc ProposalApprove (ProposalApproveContract) returns (TransactionExtention) { - } - - rpc ProposalDelete (ProposalDeleteContract) returns (TransactionExtention) { - } - - rpc BuyStorage (BuyStorageContract) returns (TransactionExtention) { - } - - rpc BuyStorageBytes (BuyStorageBytesContract) returns (TransactionExtention) { - } - - rpc SellStorage (SellStorageContract) returns (TransactionExtention) { - } - - rpc ExchangeCreate (ExchangeCreateContract) returns (TransactionExtention) { - } - - rpc ExchangeInject (ExchangeInjectContract) returns (TransactionExtention) { - } - - rpc ExchangeWithdraw (ExchangeWithdrawContract) returns (TransactionExtention) { - } - - rpc ExchangeTransaction (ExchangeTransactionContract) returns (TransactionExtention) { - } - - rpc MarketSellAsset (MarketSellAssetContract) returns (TransactionExtention) { - } - - rpc MarketCancelOrder (MarketCancelOrderContract) returns (TransactionExtention) { - } - - rpc GetMarketOrderById (BytesMessage) returns (MarketOrder) { - } - - rpc GetMarketOrderByAccount (BytesMessage) returns (MarketOrderList) { - } - - rpc GetMarketPriceByPair (MarketOrderPair) returns (MarketPriceList) { - } - - rpc GetMarketOrderListByPair (MarketOrderPair) returns (MarketOrderList) { - } - - rpc GetMarketPairList (EmptyMessage) returns (MarketOrderPairList) { - } - - - rpc ListNodes (EmptyMessage) returns (NodeList) { - option (google.api.http) = { - post: "/wallet/listnodes" - body: "*" - additional_bindings { - get: "/wallet/listnodes" - } - }; - } - - rpc GetAssetIssueByAccount (Account) returns (AssetIssueList) { - option (google.api.http) = { - post: "/wallet/getassetissuebyaccount" - body: "*" - additional_bindings { - get: "/wallet/getassetissuebyaccount" - } - }; - } - rpc GetAccountNet (Account) returns (AccountNetMessage) { - option (google.api.http) = { - post: "/wallet/getaccountnet" - body: "*" - additional_bindings { - get: "/wallet/getaccountnet" - } - }; - }; - rpc GetAccountResource (Account) returns (AccountResourceMessage) { - }; - rpc GetAssetIssueByName (BytesMessage) returns (AssetIssueContract) { - option (google.api.http) = { - post: "/wallet/getassetissuebyname" - body: "*" - additional_bindings { - get: "/wallet/getassetissuebyname" - } - }; - } - rpc GetAssetIssueListByName (BytesMessage) returns (AssetIssueList) { - } - rpc GetAssetIssueById (BytesMessage) returns (AssetIssueContract) { - } - //Please use GetNowBlock2 instead of this function. - rpc GetNowBlock (EmptyMessage) returns (Block) { - option (google.api.http) = { - post: "/wallet/getnowblock" - body: "*" - additional_bindings { - get: "/wallet/getnowblock" - } - }; - } - //Use this function instead of GetNowBlock. - rpc GetNowBlock2 (EmptyMessage) returns (BlockExtention) { - } - //Please use GetBlockByNum2 instead of this function. - rpc GetBlockByNum (NumberMessage) returns (Block) { - option (google.api.http) = { - post: "/wallet/getblockbynum" - body: "*" - additional_bindings { - get: "/wallet/getblockbynum" - } - }; - } - //Use this function instead of GetBlockByNum. - rpc GetBlockByNum2 (NumberMessage) returns (BlockExtention) { - } - - rpc GetTransactionCountByBlockNum (NumberMessage) returns (NumberMessage) { - } - - rpc GetBlockById (BytesMessage) returns (Block) { - option (google.api.http) = { - post: "/wallet/getblockbyid" - body: "*" - additional_bindings { - get: "/wallet/getblockbyid" - } - }; - } - //Please use GetBlockByLimitNext2 instead of this function. - rpc GetBlockByLimitNext (BlockLimit) returns (BlockList) { - option (google.api.http) = { - post: "/wallet/getblockbylimitnext" - body: "*" - additional_bindings { - get: "/wallet/getblockbylimitnext" - } - }; - } - //Use this function instead of GetBlockByLimitNext. - rpc GetBlockByLimitNext2 (BlockLimit) returns (BlockListExtention) { - } - //Please use GetBlockByLatestNum2 instead of this function. - rpc GetBlockByLatestNum (NumberMessage) returns (BlockList) { - option (google.api.http) = { - post: "/wallet/getblockbylatestnum" - body: "*" - additional_bindings { - get: "/wallet/getblockbylatestnum" - } - }; - } - //Use this function instead of GetBlockByLatestNum. - rpc GetBlockByLatestNum2 (NumberMessage) returns (BlockListExtention) { - } - rpc GetTransactionById (BytesMessage) returns (Transaction) { - option (google.api.http) = { - post: "/wallet/gettransactionbyid" - body: "*" - additional_bindings { - get: "/wallet/gettransactionbyid" - } - }; - } - - rpc DeployContract (CreateSmartContract) returns (TransactionExtention) { - } - - rpc GetContract (BytesMessage) returns (SmartContract) { - } - - rpc GetContractInfo (BytesMessage) returns (SmartContractDataWrapper) { - } - - rpc TriggerContract (TriggerSmartContract) returns (TransactionExtention) { - } - - rpc TriggerConstantContract (TriggerSmartContract) returns (TransactionExtention) { - } - - rpc EstimateEnergy (TriggerSmartContract) returns (EstimateEnergyMessage) { - } - - rpc ClearContractABI (ClearABIContract) returns (TransactionExtention) { - } - - rpc ListWitnesses (EmptyMessage) returns (WitnessList) { - option (google.api.http) = { - post: "/wallet/listwitnesses" - body: "*" - additional_bindings { - get: "/wallet/listwitnesses" - } - }; - }; - - - rpc GetDelegatedResource (DelegatedResourceMessage) returns (DelegatedResourceList) { - }; - - rpc GetDelegatedResourceV2 (DelegatedResourceMessage) returns (DelegatedResourceList) { - }; - - rpc GetDelegatedResourceAccountIndex (BytesMessage) returns (DelegatedResourceAccountIndex) { - }; - - rpc GetDelegatedResourceAccountIndexV2 (BytesMessage) returns (DelegatedResourceAccountIndex) { - }; - - rpc GetCanDelegatedMaxSize (CanDelegatedMaxSizeRequestMessage) returns (CanDelegatedMaxSizeResponseMessage) { - }; - - rpc GetAvailableUnfreezeCount (GetAvailableUnfreezeCountRequestMessage) - returns (GetAvailableUnfreezeCountResponseMessage) { - }; - - rpc GetCanWithdrawUnfreezeAmount (CanWithdrawUnfreezeAmountRequestMessage) - returns (CanWithdrawUnfreezeAmountResponseMessage) { - } - - rpc ListProposals (EmptyMessage) returns (ProposalList) { - option (google.api.http) = { - post: "/wallet/listproposals" - body: "*" - additional_bindings { - get: "/wallet/listproposals" - } - }; - }; - rpc GetPaginatedProposalList (PaginatedMessage) returns (ProposalList) { - option (google.api.http) = { - post: "/wallet/getpaginatedproposallist" - body: "*" - additional_bindings { - get: "/wallet/getpaginatedproposallist" - } - }; - } - rpc GetProposalById (BytesMessage) returns (Proposal) { - option (google.api.http) = { - post: "/wallet/getproposalbyid" - body: "*" - additional_bindings { - get: "/wallet/getproposalbyid" - } - }; - }; - - rpc ListExchanges (EmptyMessage) returns (ExchangeList) { - option (google.api.http) = { - post: "/wallet/listexchanges" - body: "*" - additional_bindings { - get: "/wallet/listexchanges" - } - }; - }; - rpc GetPaginatedExchangeList (PaginatedMessage) returns (ExchangeList) { - option (google.api.http) = { - post: "/wallet/getpaginatedexchangelist" - body: "*" - additional_bindings { - get: "/wallet/getpaginatedexchangelist" - } - }; - } - rpc GetExchangeById (BytesMessage) returns (Exchange) { - option (google.api.http) = { - post: "/wallet/getexchangebyid" - body: "*" - additional_bindings { - get: "/wallet/getexchangebyid" - } - }; - }; - - rpc GetChainParameters (EmptyMessage) returns (ChainParameters) { - option (google.api.http) = { - post: "/wallet/getchainparameters" - body: "*" - additional_bindings { - get: "/wallet/getchainparameters" - } - }; - }; - - rpc GetAssetIssueList (EmptyMessage) returns (AssetIssueList) { - option (google.api.http) = { - post: "/wallet/getassetissuelist" - body: "*" - additional_bindings { - get: "/wallet/getassetissuelist" - } - }; - } - rpc GetPaginatedAssetIssueList (PaginatedMessage) returns (AssetIssueList) { - option (google.api.http) = { - post: "/wallet/getpaginatedassetissuelist" - body: "*" - additional_bindings { - get: "/wallet/getpaginatedassetissuelist" - } - }; - } - - - rpc TotalTransaction (EmptyMessage) returns (NumberMessage) { - option (google.api.http) = { - post: "/wallet/totaltransaction" - body: "*" - additional_bindings { - get: "/wallet/totaltransaction" - } - }; - } - rpc GetNextMaintenanceTime (EmptyMessage) returns (NumberMessage) { - option (google.api.http) = { - post: "/wallet/getnextmaintenancetime" - body: "*" - additional_bindings { - get: "/wallet/getnextmaintenancetime" - } - }; - } - - rpc GetTransactionInfoById (BytesMessage) returns (TransactionInfo) { - option (google.api.http) = { - post: "/wallet/gettransactioninfobyid" - body: "*" - additional_bindings { - get: "/wallet/gettransactioninfobyid" - } - }; - } - - rpc AccountPermissionUpdate (AccountPermissionUpdateContract) returns (TransactionExtention) { - option (google.api.http) = { - post: "/wallet/accountpermissionupdate" - body: "*" - additional_bindings { - get: "/wallet/accountpermissionupdate" - } - }; - } - - rpc GetTransactionSignWeight (Transaction) returns (TransactionSignWeight) { - - } - - rpc GetTransactionApprovedList (Transaction) returns (TransactionApprovedList) { - - } - - rpc GetNodeInfo (EmptyMessage) returns (NodeInfo) { - }; - - rpc GetRewardInfo (BytesMessage) returns (NumberMessage) { - }; - - rpc GetBrokerageInfo (BytesMessage) returns (NumberMessage) { - }; - - rpc UpdateBrokerage (UpdateBrokerageContract) returns (TransactionExtention) { - - }; - - // for shiededTransaction - rpc CreateShieldedTransaction (PrivateParameters) returns (TransactionExtention) { - }; - - rpc GetMerkleTreeVoucherInfo (OutputPointInfo) returns (IncrementalMerkleVoucherInfo) { - } - - rpc ScanNoteByIvk (IvkDecryptParameters) returns (DecryptNotes) { - }; - - rpc ScanAndMarkNoteByIvk (IvkDecryptAndMarkParameters) returns (DecryptNotesMarked) { - }; - - rpc ScanNoteByOvk (OvkDecryptParameters) returns (DecryptNotes) { - }; - - rpc GetSpendingKey (EmptyMessage) returns (BytesMessage) { - } - - rpc GetExpandedSpendingKey (BytesMessage) returns (ExpandedSpendingKeyMessage) { - } - - rpc GetAkFromAsk (BytesMessage) returns (BytesMessage) { - } - - rpc GetNkFromNsk (BytesMessage) returns (BytesMessage) { - } - - rpc GetIncomingViewingKey (ViewingKeyMessage) returns (IncomingViewingKeyMessage) { - } - - rpc GetDiversifier (EmptyMessage) returns (DiversifierMessage) { - } - - rpc GetNewShieldedAddress (EmptyMessage) returns (ShieldedAddressInfo) { - } - - rpc GetZenPaymentAddress (IncomingViewingKeyDiversifierMessage) returns (PaymentAddressMessage) { - } - - rpc GetRcm (EmptyMessage) returns (BytesMessage) { - } - - rpc IsSpend (NoteParameters) returns (SpendResult) { - } - - rpc CreateShieldedTransactionWithoutSpendAuthSig (PrivateParametersWithoutAsk) returns (TransactionExtention) { - }; - - rpc GetShieldTransactionHash (Transaction) returns (BytesMessage) { - }; - - rpc CreateSpendAuthSig (SpendAuthSigParameters) returns (BytesMessage) { - }; - - rpc CreateShieldNullifier (NfParameters) returns (BytesMessage) { - }; - - //for shielded contract - rpc CreateShieldedContractParameters (PrivateShieldedTRC20Parameters) returns (ShieldedTRC20Parameters) { - }; - - rpc CreateShieldedContractParametersWithoutAsk (PrivateShieldedTRC20ParametersWithoutAsk) returns (ShieldedTRC20Parameters) { - }; - - rpc ScanShieldedTRC20NotesByIvk (IvkDecryptTRC20Parameters) returns (DecryptNotesTRC20) { - }; - - rpc ScanShieldedTRC20NotesByOvk (OvkDecryptTRC20Parameters) returns (DecryptNotesTRC20) { - }; - - rpc IsShieldedTRC20ContractNoteSpent (NfTRC20Parameters) returns (NullifierResult) { - }; - - rpc GetTriggerInputForShieldedTRC20Contract (ShieldedTRC20TriggerContractParameters) returns (BytesMessage) { - }; - // end for shiededTransaction - - rpc CreateCommonTransaction (Transaction) returns (TransactionExtention) { - }; - - rpc GetTransactionInfoByBlockNum (NumberMessage) returns (TransactionInfoList) { - } - - rpc GetBurnTrx (EmptyMessage) returns (NumberMessage) { - } - - rpc GetTransactionFromPending (BytesMessage) returns (Transaction) { - } - - rpc GetTransactionListFromPending (EmptyMessage) returns (TransactionIdList) { - } - - rpc GetPendingSize (EmptyMessage) returns (NumberMessage) { - } - - rpc GetBlock (BlockReq) returns (BlockExtention) { - } - - rpc GetBandwidthPrices (EmptyMessage) returns (PricesResponseMessage) { - } - - rpc GetEnergyPrices (EmptyMessage) returns (PricesResponseMessage) { - } - - rpc GetMemoFee (EmptyMessage) returns (PricesResponseMessage) { - } -}; - -service WalletSolidity { - - rpc GetAccount (Account) returns (Account) { - option (google.api.http) = { - post: "/walletsolidity/getaccount" - body: "*" - additional_bindings { - get: "/walletsolidity/getaccount" - } - }; - }; - rpc GetAccountById (Account) returns (Account) { - option (google.api.http) = { - post: "/walletsolidity/getaccountbyid" - body: "*" - additional_bindings { - get: "/walletsolidity/getaccountbyid" - } - }; - }; - - rpc ListWitnesses (EmptyMessage) returns (WitnessList) { - option (google.api.http) = { - post: "/walletsolidity/listwitnesses" - body: "*" - additional_bindings { - get: "/walletsolidity/listwitnesses" - } - }; - }; - rpc GetAssetIssueList (EmptyMessage) returns (AssetIssueList) { - option (google.api.http) = { - post: "/walletsolidity/getassetissuelist" - body: "*" - additional_bindings { - get: "/walletsolidity/getassetissuelist" - } - }; - } - rpc GetPaginatedAssetIssueList (PaginatedMessage) returns (AssetIssueList) { - option (google.api.http) = { - post: "/walletsolidity/getpaginatedassetissuelist" - body: "*" - additional_bindings { - get: "/walletsolidity/getpaginatedassetissuelist" - } - }; - } - - rpc GetAssetIssueByName (BytesMessage) returns (AssetIssueContract) { - } - rpc GetAssetIssueListByName (BytesMessage) returns (AssetIssueList) { - } - rpc GetAssetIssueById (BytesMessage) returns (AssetIssueContract) { - } - - //Please use GetNowBlock2 instead of this function. - rpc GetNowBlock (EmptyMessage) returns (Block) { - option (google.api.http) = { - post: "/walletsolidity/getnowblock" - body: "*" - additional_bindings { - get: "/walletsolidity/getnowblock" - } - }; - } - //Use this function instead of GetNowBlock. - rpc GetNowBlock2 (EmptyMessage) returns (BlockExtention) { - } - //Please use GetBlockByNum2 instead of this function. - rpc GetBlockByNum (NumberMessage) returns (Block) { - option (google.api.http) = { - post: "/walletsolidity/getblockbynum" - body: "*" - additional_bindings { - get: "/walletsolidity/getblockbynum" - } - }; - } - //Use this function instead of GetBlockByNum. - rpc GetBlockByNum2 (NumberMessage) returns (BlockExtention) { - } - - rpc GetTransactionCountByBlockNum (NumberMessage) returns (NumberMessage) { - } - - rpc GetDelegatedResource (DelegatedResourceMessage) returns (DelegatedResourceList) { - }; - - rpc GetDelegatedResourceV2 (DelegatedResourceMessage) returns (DelegatedResourceList) { - }; - - rpc GetDelegatedResourceAccountIndex (BytesMessage) returns (DelegatedResourceAccountIndex) { - }; - - rpc GetDelegatedResourceAccountIndexV2 (BytesMessage) returns (DelegatedResourceAccountIndex) { - }; - - rpc GetCanDelegatedMaxSize (CanDelegatedMaxSizeRequestMessage) returns (CanDelegatedMaxSizeResponseMessage) { - }; - - rpc GetAvailableUnfreezeCount (GetAvailableUnfreezeCountRequestMessage) - returns (GetAvailableUnfreezeCountResponseMessage) { - }; - - rpc GetCanWithdrawUnfreezeAmount (CanWithdrawUnfreezeAmountRequestMessage) - returns (CanWithdrawUnfreezeAmountResponseMessage) { - } - - rpc GetExchangeById (BytesMessage) returns (Exchange) { - }; - - rpc ListExchanges (EmptyMessage) returns (ExchangeList) { - }; - - - rpc GetTransactionById (BytesMessage) returns (Transaction) { - option (google.api.http) = { - post: "/walletsolidity/gettransactionbyid" - body: "*" - additional_bindings { - get: "/walletsolidity/gettransactionbyid" - } - }; - } - - rpc GetTransactionInfoById (BytesMessage) returns (TransactionInfo) { - option (google.api.http) = { - post: "/walletsolidity/gettransactioninfobyid" - body: "*" - additional_bindings { - get: "/walletsolidity/gettransactioninfobyid" - } - }; - } - - rpc GetMerkleTreeVoucherInfo (OutputPointInfo) returns (IncrementalMerkleVoucherInfo) { - } - - rpc ScanNoteByIvk (IvkDecryptParameters) returns (DecryptNotes) { - } - - rpc ScanAndMarkNoteByIvk (IvkDecryptAndMarkParameters) returns (DecryptNotesMarked) { - } - - rpc ScanNoteByOvk (OvkDecryptParameters) returns (DecryptNotes) { - } - - rpc IsSpend (NoteParameters) returns (SpendResult) { - } - - rpc ScanShieldedTRC20NotesByIvk (IvkDecryptTRC20Parameters) returns (DecryptNotesTRC20) { - }; - - rpc ScanShieldedTRC20NotesByOvk (OvkDecryptTRC20Parameters) returns (DecryptNotesTRC20) { - }; - - rpc IsShieldedTRC20ContractNoteSpent (NfTRC20Parameters) returns (NullifierResult) { - }; - - rpc GetRewardInfo (BytesMessage) returns (NumberMessage) { - }; - - rpc GetBrokerageInfo (BytesMessage) returns (NumberMessage) { - }; - - rpc TriggerConstantContract (TriggerSmartContract) returns (TransactionExtention) { - } - - rpc EstimateEnergy (TriggerSmartContract) returns (EstimateEnergyMessage) { - } - - rpc GetTransactionInfoByBlockNum (NumberMessage) returns (TransactionInfoList) { - } - - rpc GetMarketOrderById (BytesMessage) returns (MarketOrder) { - } - - rpc GetMarketOrderByAccount (BytesMessage) returns (MarketOrderList) { - } - - rpc GetMarketPriceByPair (MarketOrderPair) returns (MarketPriceList) { - } - - rpc GetMarketOrderListByPair (MarketOrderPair) returns (MarketOrderList) { - } - - rpc GetMarketPairList (EmptyMessage) returns (MarketOrderPairList) { - } - - rpc GetBurnTrx (EmptyMessage) returns (NumberMessage) { - } - rpc GetBlock (BlockReq) returns (BlockExtention) { - } - rpc GetBandwidthPrices (EmptyMessage) returns (PricesResponseMessage) { - } - - rpc GetEnergyPrices (EmptyMessage) returns (PricesResponseMessage) { - } -}; - -service WalletExtension { - //Please use GetTransactionsFromThis2 instead of this function. - rpc GetTransactionsFromThis (AccountPaginated) returns (TransactionList) { - option (google.api.http) = { - post: "/walletextension/gettransactionsfromthis" - body: "*" - additional_bindings { - get: "/walletextension/gettransactionsfromthis" - } - }; - } - //Use this function instead of GetTransactionsFromThis. - rpc GetTransactionsFromThis2 (AccountPaginated) returns (TransactionListExtention) { - } - //Please use GetTransactionsToThis2 instead of this function. - rpc GetTransactionsToThis (AccountPaginated) returns (TransactionList) { - option (google.api.http) = { - post: "/walletextension/gettransactionstothis" - body: "*" - additional_bindings { - get: "/walletextension/gettransactionstothis" - } - }; - } - //Use this function instead of GetTransactionsToThis. - rpc GetTransactionsToThis2 (AccountPaginated) returns (TransactionListExtention) { - } -}; - -// the api of tron's db -service Database { - // for tapos - rpc getBlockReference (EmptyMessage) returns (BlockReference) { - - } - rpc GetDynamicProperties (EmptyMessage) returns (DynamicProperties) { - - } - rpc GetNowBlock (EmptyMessage) returns (Block) { - - } - rpc GetBlockByNum (NumberMessage) returns (Block) { - - } -}; - -service Monitor { - rpc GetStatsInfo (EmptyMessage) returns (MetricsInfo) { - option (google.api.http) = { - post: "/monitor/getstatsinfo" - body: "*" - additional_bindings { - get: "/monitor/getstatsinfo" - } - }; - } -} - -message Return { - enum response_code { - SUCCESS = 0; - SIGERROR = 1; // error in signature - CONTRACT_VALIDATE_ERROR = 2; - CONTRACT_EXE_ERROR = 3; - BANDWITH_ERROR = 4; - DUP_TRANSACTION_ERROR = 5; - TAPOS_ERROR = 6; - TOO_BIG_TRANSACTION_ERROR = 7; - TRANSACTION_EXPIRATION_ERROR = 8; - SERVER_BUSY = 9; - NO_CONNECTION = 10; - NOT_ENOUGH_EFFECTIVE_CONNECTION = 11; - BLOCK_UNSOLIDIFIED = 12; - - OTHER_ERROR = 20; - } - - bool result = 1; - response_code code = 2; - bytes message = 3; -} - -message BlockReference { - int64 block_num = 1; - bytes block_hash = 2; -} - -// the api of tron's network such as node list. -service Network { - -}; - -message WitnessList { - repeated Witness witnesses = 1; -} -message ProposalList { - repeated Proposal proposals = 1; -} -message ExchangeList { - repeated Exchange exchanges = 1; -} -message AssetIssueList { - repeated AssetIssueContract assetIssue = 1; -} -message BlockList { - repeated Block block = 1; -} -message TransactionList { - repeated Transaction transaction = 1; -} -message TransactionIdList { - repeated string txId = 1; -} -message DelegatedResourceMessage { - bytes fromAddress = 1; - bytes toAddress = 2; -} -message DelegatedResourceList { - repeated DelegatedResource delegatedResource = 1; -} - -message GetAvailableUnfreezeCountRequestMessage { - bytes owner_address = 1; -} -message GetAvailableUnfreezeCountResponseMessage { - int64 count = 1; -} - -message CanDelegatedMaxSizeRequestMessage { - int32 type = 1; - bytes owner_address = 2; -} -message CanDelegatedMaxSizeResponseMessage { - int64 max_size = 1; -} - -message CanWithdrawUnfreezeAmountRequestMessage { - bytes owner_address = 1; - int64 timestamp = 2; -} -message CanWithdrawUnfreezeAmountResponseMessage { - int64 amount = 1; -} - -message PricesResponseMessage { - string prices = 1; -} - -// Gossip node list -message NodeList { - repeated Node nodes = 1; -} - -// Gossip node -message Node { - Address address = 1; -} - -// Gossip node address -message Address { - bytes host = 1; - int32 port = 2; -} - -message EmptyMessage { -} -message NumberMessage { - int64 num = 1; -} -message BytesMessage { - bytes value = 1; -} -message TimeMessage { - int64 beginInMilliseconds = 1; - int64 endInMilliseconds = 2; -} -message BlockReq { - string id_or_num = 1; - bool detail = 2; -} -message BlockLimit { - int64 startNum = 1; - int64 endNum = 2; -} -message TransactionLimit { - bytes transactionId = 1; - int64 limitNum = 2; -} -message AccountPaginated { - Account account = 1; - int64 offset = 2; - int64 limit = 3; -} -message TimePaginatedMessage { - TimeMessage timeMessage = 1; - int64 offset = 2; - int64 limit = 3; -} -//deprecated -message AccountNetMessage { - int64 freeNetUsed = 1; - int64 freeNetLimit = 2; - int64 NetUsed = 3; - int64 NetLimit = 4; - map assetNetUsed = 5; - map assetNetLimit = 6; - int64 TotalNetLimit = 7; - int64 TotalNetWeight = 8; -} -message AccountResourceMessage { - int64 freeNetUsed = 1; - int64 freeNetLimit = 2; - int64 NetUsed = 3; - int64 NetLimit = 4; - map assetNetUsed = 5; - map assetNetLimit = 6; - int64 TotalNetLimit = 7; - int64 TotalNetWeight = 8; - int64 TotalTronPowerWeight = 9; - int64 tronPowerUsed = 10; - int64 tronPowerLimit = 11; - - int64 EnergyUsed = 13; - int64 EnergyLimit = 14; - int64 TotalEnergyLimit = 15; - int64 TotalEnergyWeight = 16; - - int64 storageUsed = 21; - int64 storageLimit = 22; -} - -message PaginatedMessage { - int64 offset = 1; - int64 limit = 2; -} - -message TransactionExtention { - Transaction transaction = 1; - bytes txid = 2; //transaction id = sha256(transaction.rowdata) - repeated bytes constant_result = 3; - Return result = 4; - int64 energy_used = 5; - repeated TransactionInfo.Log logs = 6; - repeated InternalTransaction internal_transactions = 7; - int64 energy_penalty = 8; -} - -message EstimateEnergyMessage { - Return result = 1; - int64 energy_required = 2; -} - -message BlockExtention { - repeated TransactionExtention transactions = 1; - BlockHeader block_header = 2; - bytes blockid = 3; -} - -message BlockListExtention { - repeated BlockExtention block = 1; -} - -message TransactionListExtention { - repeated TransactionExtention transaction = 1; -} - -message BlockIncrementalMerkleTree { - int64 number = 1; - IncrementalMerkleTree merkleTree = 2; -} - -message TransactionSignWeight { - message Result { - enum response_code { - ENOUGH_PERMISSION = 0; - NOT_ENOUGH_PERMISSION = 1; // error in - SIGNATURE_FORMAT_ERROR = 2; - COMPUTE_ADDRESS_ERROR = 3; - PERMISSION_ERROR = 4; //The key is not in permission - OTHER_ERROR = 20; - } - response_code code = 1; - string message = 2; - } - - Permission permission = 1; - repeated bytes approved_list = 2; - int64 current_weight = 3; - Result result = 4; - TransactionExtention transaction = 5; -} - -message TransactionApprovedList { - message Result { - enum response_code { - SUCCESS = 0; - SIGNATURE_FORMAT_ERROR = 1; - COMPUTE_ADDRESS_ERROR = 2; - OTHER_ERROR = 20; - } - response_code code = 1; - string message = 2; - } - - repeated bytes approved_list = 2; - Result result = 4; - TransactionExtention transaction = 5; -} - -message IvkDecryptParameters { - int64 start_block_index = 1; - int64 end_block_index = 2; - bytes ivk = 3; -} - -message IvkDecryptAndMarkParameters { - int64 start_block_index = 1; - int64 end_block_index = 2; - bytes ivk = 5; - bytes ak = 3; - bytes nk = 4; -} - -message OvkDecryptParameters { - int64 start_block_index = 1; - int64 end_block_index = 2; - bytes ovk = 3; -} - -message DecryptNotes { - message NoteTx { - Note note = 1; - bytes txid = 2; //transaction id = sha256(transaction.rowdata) - int32 index = 3; //the index of note in receive - } - repeated NoteTx noteTxs = 1; -} - -message DecryptNotesMarked { - message NoteTx { - Note note = 1; - bytes txid = 2; //transaction id = sha256(transaction.rowdata) - int32 index = 3; //the index of note in receive - bool is_spend = 4; - } - repeated NoteTx noteTxs = 1; -} - -message Note { - int64 value = 1; - string payment_address = 2; - bytes rcm = 3; // random 32 - bytes memo = 4; -} - -message SpendNote { - Note note = 3; - bytes alpha = 4; // random number for spend authority signature - IncrementalMerkleVoucher voucher = 5; - bytes path = 6; // path for cm from leaf to root in merkle tree -} - -message ReceiveNote { - Note note = 1; -} - -message PrivateParameters { - bytes transparent_from_address = 1; - bytes ask = 2; - bytes nsk = 3; - bytes ovk = 4; - int64 from_amount = 5; - repeated SpendNote shielded_spends = 6; - repeated ReceiveNote shielded_receives = 7; - bytes transparent_to_address = 8; - int64 to_amount = 9; - int64 timeout = 10; // timeout in seconds, it works only when it bigger than 0 -} - -message PrivateParametersWithoutAsk { - bytes transparent_from_address = 1; - bytes ak = 2; - bytes nsk = 3; - bytes ovk = 4; - int64 from_amount = 5; - repeated SpendNote shielded_spends = 6; - repeated ReceiveNote shielded_receives = 7; - bytes transparent_to_address = 8; - int64 to_amount = 9; - int64 timeout = 10; // timeout in seconds, it works only when it bigger than 0 -} - -message SpendAuthSigParameters { - bytes ask = 1; - bytes tx_hash = 2; - bytes alpha = 3; -} - -message NfParameters { - Note note = 1; - IncrementalMerkleVoucher voucher = 2; - bytes ak = 3; - bytes nk = 4; -} - -message ExpandedSpendingKeyMessage { - bytes ask = 1; - bytes nsk = 2; - bytes ovk = 3; -} - -message ViewingKeyMessage { - bytes ak = 1; - bytes nk = 2; -} - -message IncomingViewingKeyMessage { - bytes ivk = 1; -} - -message DiversifierMessage { - bytes d = 1; -} - -message IncomingViewingKeyDiversifierMessage { - IncomingViewingKeyMessage ivk = 1; - DiversifierMessage d = 2; -} - -message PaymentAddressMessage { - DiversifierMessage d = 1; - bytes pkD = 2; - string payment_address = 3; -} - -message ShieldedAddressInfo { - bytes sk = 1; - bytes ask = 2; - bytes nsk = 3; - bytes ovk = 4; - bytes ak = 5; - bytes nk = 6; - bytes ivk = 7; - bytes d = 8; - bytes pkD = 9; - string payment_address = 10; -} - -message NoteParameters { - bytes ak = 1; - bytes nk = 2; - Note note = 3; - bytes txid = 4; - int32 index = 5; -} - -message SpendResult { - bool result = 1; - string message = 2; -} - -message TransactionInfoList { - repeated TransactionInfo transactionInfo = 1; -} - -message SpendNoteTRC20 { - Note note = 1; - bytes alpha = 2; - bytes root = 3; - bytes path = 4; - int64 pos = 5; -} - -message PrivateShieldedTRC20Parameters { - bytes ask = 1; - bytes nsk = 2; - bytes ovk = 3; - string from_amount = 4; - repeated SpendNoteTRC20 shielded_spends = 5; - repeated ReceiveNote shielded_receives = 6; - bytes transparent_to_address = 7; - string to_amount = 8; - bytes shielded_TRC20_contract_address = 9; -} - -message PrivateShieldedTRC20ParametersWithoutAsk { - bytes ak = 1; - bytes nsk = 2; - bytes ovk = 3; - string from_amount = 4; - repeated SpendNoteTRC20 shielded_spends = 5; - repeated ReceiveNote shielded_receives = 6; - bytes transparent_to_address = 7; - string to_amount = 8; - bytes shielded_TRC20_contract_address = 9; -} - -message ShieldedTRC20Parameters { - repeated SpendDescription spend_description = 1; - repeated ReceiveDescription receive_description = 2; - bytes binding_signature = 3; - bytes message_hash = 4; - string trigger_contract_input = 5; - string parameter_type = 6; -} - -message IvkDecryptTRC20Parameters { - int64 start_block_index = 1; - int64 end_block_index = 2; - bytes shielded_TRC20_contract_address = 3; - bytes ivk = 4; - bytes ak = 5; - bytes nk = 6; - repeated string events = 7; -} - -message OvkDecryptTRC20Parameters { - int64 start_block_index = 1; - int64 end_block_index = 2; - bytes ovk = 3; - bytes shielded_TRC20_contract_address = 4; - repeated string events = 5; -} - -message DecryptNotesTRC20 { - message NoteTx { - Note note = 1; - int64 position = 2; - bool is_spent = 3; - bytes txid = 4; - int32 index = 5; //the index of note in txid - string to_amount = 6; - bytes transparent_to_address = 7; - } - repeated NoteTx noteTxs = 1; -} - -message NfTRC20Parameters { - Note note = 1; - bytes ak = 2; - bytes nk = 3; - int64 position = 4; - bytes shielded_TRC20_contract_address = 5; -} - -message NullifierResult { - bool is_spent = 1; -} - -message ShieldedTRC20TriggerContractParameters { - ShieldedTRC20Parameters shielded_TRC20_Parameters = 1; - repeated BytesMessage spend_authority_signature = 2; - string amount = 3; - bytes transparent_to_address = 4; -} diff --git a/packages/kos/src/protos/tron/api/zksnark.proto b/packages/kos/src/protos/tron/api/zksnark.proto deleted file mode 100644 index bc0764c..0000000 --- a/packages/kos/src/protos/tron/api/zksnark.proto +++ /dev/null @@ -1,33 +0,0 @@ -syntax = "proto3"; -package protocol; - -import "core/Tron.proto"; - -option java_package = "org.tron.api"; //Specify the name of the package that generated the Java file -option java_outer_classname = "ZksnarkGrpcAPI"; //Specify the class name of the generated Java file -option go_package = "github.com/tronprotocol/grpc-gateway/api"; - -service TronZksnark { - rpc CheckZksnarkProof (ZksnarkRequest) returns (ZksnarkResponse) { - } -}; - -message ZksnarkRequest { - Transaction transaction = 1; - bytes sighash = 2; - int64 valueBalance = 3; - string txId = 4; -} - -message ZksnarkResponse { - enum Code { - SUCCESS = 0; - FAILED = 1; - } - - Code code = 1; -} - - - - diff --git a/packages/kos/src/protos/tron/core/Discover.proto b/packages/kos/src/protos/tron/core/Discover.proto deleted file mode 100644 index 4cc0d83..0000000 --- a/packages/kos/src/protos/tron/core/Discover.proto +++ /dev/null @@ -1,44 +0,0 @@ -syntax = "proto3"; - -package protocol; - - -option java_package = "org.tron.protos"; //Specify the name of the package that generated the Java file -option java_outer_classname = "Discover"; //Specify the class name of the generated Java file -option go_package = "github.com/tronprotocol/grpc-gateway/core"; - -message Endpoint { - bytes address = 1; - int32 port = 2; - bytes nodeId = 3; -} - -message PingMessage { - Endpoint from = 1; - Endpoint to = 2; - int32 version = 3; - int64 timestamp = 4; -} - -message PongMessage { - Endpoint from = 1; - int32 echo = 2; - int64 timestamp = 3; -} - -message FindNeighbours { - Endpoint from = 1; - bytes targetId = 2; - int64 timestamp = 3; -} - -message Neighbours { - Endpoint from = 1; - repeated Endpoint neighbours = 2; - int64 timestamp = 3; -} - -message BackupMessage { - bool flag = 1; - int32 priority = 2; -} \ No newline at end of file diff --git a/packages/kos/src/protos/tron/core/Tron.proto b/packages/kos/src/protos/tron/core/Tron.proto deleted file mode 100644 index 41ef968..0000000 --- a/packages/kos/src/protos/tron/core/Tron.proto +++ /dev/null @@ -1,892 +0,0 @@ -syntax = "proto3"; - -import "google/protobuf/any.proto"; -import "core/Discover.proto"; -import "core/contract/common.proto"; - -package protocol; - - -option java_package = "org.tron.protos"; //Specify the name of the package that generated the Java file -option java_outer_classname = "Protocol"; //Specify the class name of the generated Java file -option go_package = "github.com/tronprotocol/grpc-gateway/core"; - -enum AccountType { - Normal = 0; - AssetIssue = 1; - Contract = 2; -} - -// AccountId, (name, address) use name, (null, address) use address, (name, null) use name, -message AccountId { - bytes name = 1; - bytes address = 2; -} - -// vote message -message Vote { - // the super rep address - bytes vote_address = 1; - // the vote num to this super rep. - int64 vote_count = 2; -} - -// Proposal -message Proposal { - int64 proposal_id = 1; - bytes proposer_address = 2; - map parameters = 3; - int64 expiration_time = 4; - int64 create_time = 5; - repeated bytes approvals = 6; - enum State { - PENDING = 0; - DISAPPROVED = 1; - APPROVED = 2; - CANCELED = 3; - } - State state = 7; -} - -// Exchange -message Exchange { - int64 exchange_id = 1; - bytes creator_address = 2; - int64 create_time = 3; - bytes first_token_id = 6; - int64 first_token_balance = 7; - bytes second_token_id = 8; - int64 second_token_balance = 9; -} - -// market -message MarketOrder { - bytes order_id = 1; - bytes owner_address = 2; - int64 create_time = 3; - bytes sell_token_id = 4; - int64 sell_token_quantity = 5; - bytes buy_token_id = 6; - int64 buy_token_quantity = 7; // min to receive - int64 sell_token_quantity_remain = 9; - // When state != ACTIVE and sell_token_quantity_return !=0, - //it means that some sell tokens are returned to the account due to insufficient remaining amount - int64 sell_token_quantity_return = 10; - - enum State { - ACTIVE = 0; - INACTIVE = 1; - CANCELED = 2; - } - State state = 11; - - bytes prev = 12; - bytes next = 13; -} - -message MarketOrderList { - repeated MarketOrder orders = 1; -} - -message MarketOrderPairList { - repeated MarketOrderPair orderPair = 1; -} - -message MarketOrderPair{ - bytes sell_token_id = 1; - bytes buy_token_id = 2; -} - -message MarketAccountOrder { - bytes owner_address = 1; - repeated bytes orders = 2; // order_id list - int64 count = 3; // active count - int64 total_count = 4; -} - -message MarketPrice { - int64 sell_token_quantity = 1; - int64 buy_token_quantity = 2; -} - -message MarketPriceList { - bytes sell_token_id = 1; - bytes buy_token_id = 2; - repeated MarketPrice prices = 3; -} - -message MarketOrderIdList { - bytes head = 1; - bytes tail = 2; -} - -message ChainParameters { - repeated ChainParameter chainParameter = 1; - message ChainParameter { - string key = 1; - int64 value = 2; - } -} - -/* Account */ -message Account { - /* frozen balance */ - message Frozen { - int64 frozen_balance = 1; // the frozen trx balance - int64 expire_time = 2; // the expire time - } - // account nick name - bytes account_name = 1; - AccountType type = 2; - // the create address - bytes address = 3; - // the trx balance - int64 balance = 4; - // the votes - repeated Vote votes = 5; - // the other asset owned by this account - map asset = 6; - - // the other asset owned by this account,key is assetId - map assetV2 = 56; - - // the frozen balance for bandwidth - repeated Frozen frozen = 7; - // bandwidth, get from frozen - int64 net_usage = 8; - //Frozen balance provided by other accounts to this account - int64 acquired_delegated_frozen_balance_for_bandwidth = 41; - //Freeze and provide balances to other accounts - int64 delegated_frozen_balance_for_bandwidth = 42; - - int64 old_tron_power = 46; - Frozen tron_power = 47; - - bool asset_optimized = 60; - - // this account create time - int64 create_time = 0x09; - // this last operation time, including transfer, voting and so on. //FIXME fix grammar - int64 latest_opration_time = 10; - // witness block producing allowance - int64 allowance = 0x0B; - // last withdraw time - int64 latest_withdraw_time = 0x0C; - // not used so far - bytes code = 13; - bool is_witness = 14; - bool is_committee = 15; - // frozen asset(for asset issuer) - repeated Frozen frozen_supply = 16; - // asset_issued_name - bytes asset_issued_name = 17; - bytes asset_issued_ID = 57; - map latest_asset_operation_time = 18; - map latest_asset_operation_timeV2 = 58; - int64 free_net_usage = 19; - map free_asset_net_usage = 20; - map free_asset_net_usageV2 = 59; - int64 latest_consume_time = 21; - int64 latest_consume_free_time = 22; - - // the identity of this account, case insensitive - bytes account_id = 23; - - int64 net_window_size = 24; - bool net_window_optimized = 25; - - message AccountResource { - // energy resource, get from frozen - int64 energy_usage = 1; - // the frozen balance for energy - Frozen frozen_balance_for_energy = 2; - int64 latest_consume_time_for_energy = 3; - - //Frozen balance provided by other accounts to this account - int64 acquired_delegated_frozen_balance_for_energy = 4; - //Frozen balances provided to other accounts - int64 delegated_frozen_balance_for_energy = 5; - - // storage resource, get from market - int64 storage_limit = 6; - int64 storage_usage = 7; - int64 latest_exchange_storage_time = 8; - - int64 energy_window_size = 9; - - int64 delegated_frozenV2_balance_for_energy = 10; - int64 acquired_delegated_frozenV2_balance_for_energy = 11; - bool energy_window_optimized = 12; - } - AccountResource account_resource = 26; - bytes codeHash = 30; - Permission owner_permission = 31; - Permission witness_permission = 32; - repeated Permission active_permission = 33; - - message FreezeV2 { - ResourceCode type = 1; - int64 amount = 2; - } - message UnFreezeV2 { - ResourceCode type = 1; - int64 unfreeze_amount = 3; - int64 unfreeze_expire_time = 4; - } - repeated FreezeV2 frozenV2 = 34; - repeated UnFreezeV2 unfrozenV2 = 35; - - int64 delegated_frozenV2_balance_for_bandwidth = 36; - int64 acquired_delegated_frozenV2_balance_for_bandwidth = 37; -} - -message Key { - bytes address = 1; - int64 weight = 2; -} - -message DelegatedResource { - bytes from = 1; - bytes to = 2; - int64 frozen_balance_for_bandwidth = 3; - int64 frozen_balance_for_energy = 4; - int64 expire_time_for_bandwidth = 5; - int64 expire_time_for_energy = 6; -} - -message authority { - AccountId account = 1; - bytes permission_name = 2; -} - -message Permission { - enum PermissionType { - Owner = 0; - Witness = 1; - Active = 2; - } - PermissionType type = 1; - int32 id = 2; //Owner id=0, Witness id=1, Active id start by 2 - string permission_name = 3; - int64 threshold = 4; - int32 parent_id = 5; - bytes operations = 6; //1 bit 1 contract - repeated Key keys = 7; -} - -// Witness -message Witness { - bytes address = 1; - int64 voteCount = 2; - bytes pubKey = 3; - string url = 4; - int64 totalProduced = 5; - int64 totalMissed = 6; - int64 latestBlockNum = 7; - int64 latestSlotNum = 8; - bool isJobs = 9; -} - -// Vote Change -message Votes { - bytes address = 1; - repeated Vote old_votes = 2; - repeated Vote new_votes = 3; -} - -// Transcation - -message TXOutput { - int64 value = 1; - bytes pubKeyHash = 2; -} - -message TXInput { - message raw { - bytes txID = 1; - int64 vout = 2; - bytes pubKey = 3; - } - raw raw_data = 1; - bytes signature = 4; -} - -message TXOutputs { - repeated TXOutput outputs = 1; -} - -message ResourceReceipt { - int64 energy_usage = 1; - int64 energy_fee = 2; - int64 origin_energy_usage = 3; - int64 energy_usage_total = 4; - int64 net_usage = 5; - int64 net_fee = 6; - Transaction.Result.contractResult result = 7; - int64 energy_penalty_total = 8; -} - -message MarketOrderDetail { - bytes makerOrderId = 1; - bytes takerOrderId = 2; - int64 fillSellQuantity = 3; - int64 fillBuyQuantity = 4; -} - -message Transaction { - message Contract { - enum ContractType { - AccountCreateContract = 0; - TransferContract = 1; - TransferAssetContract = 2; - VoteAssetContract = 3; - VoteWitnessContract = 4; - WitnessCreateContract = 5; - AssetIssueContract = 6; - WitnessUpdateContract = 8; - ParticipateAssetIssueContract = 9; - AccountUpdateContract = 10; - FreezeBalanceContract = 11; - UnfreezeBalanceContract = 12; - WithdrawBalanceContract = 13; - UnfreezeAssetContract = 14; - UpdateAssetContract = 15; - ProposalCreateContract = 16; - ProposalApproveContract = 17; - ProposalDeleteContract = 18; - SetAccountIdContract = 19; - CustomContract = 20; - CreateSmartContract = 30; - TriggerSmartContract = 31; - GetContract = 32; - UpdateSettingContract = 33; - ExchangeCreateContract = 41; - ExchangeInjectContract = 42; - ExchangeWithdrawContract = 43; - ExchangeTransactionContract = 44; - UpdateEnergyLimitContract = 45; - AccountPermissionUpdateContract = 46; - ClearABIContract = 48; - UpdateBrokerageContract = 49; - ShieldedTransferContract = 51; - MarketSellAssetContract = 52; - MarketCancelOrderContract = 53; - FreezeBalanceV2Contract = 54; - UnfreezeBalanceV2Contract = 55; - WithdrawExpireUnfreezeContract = 56; - DelegateResourceContract = 57; - UnDelegateResourceContract = 58; - CancelAllUnfreezeV2Contract = 59; - } - ContractType type = 1; - google.protobuf.Any parameter = 2; - bytes provider = 3; - bytes ContractName = 4; - int32 Permission_id = 5; - } - - message Result { - enum code { - SUCESS = 0; - FAILED = 1; - } - enum contractResult { - DEFAULT = 0; - SUCCESS = 1; - REVERT = 2; - BAD_JUMP_DESTINATION = 3; - OUT_OF_MEMORY = 4; - PRECOMPILED_CONTRACT = 5; - STACK_TOO_SMALL = 6; - STACK_TOO_LARGE = 7; - ILLEGAL_OPERATION = 8; - STACK_OVERFLOW = 9; - OUT_OF_ENERGY = 10; - OUT_OF_TIME = 11; - JVM_STACK_OVER_FLOW = 12; - UNKNOWN = 13; - TRANSFER_FAILED = 14; - INVALID_CODE = 15; - } - int64 fee = 1; - code ret = 2; - contractResult contractRet = 3; - - string assetIssueID = 14; - int64 withdraw_amount = 15; - int64 unfreeze_amount = 16; - int64 exchange_received_amount = 18; - int64 exchange_inject_another_amount = 19; - int64 exchange_withdraw_another_amount = 20; - int64 exchange_id = 21; - int64 shielded_transaction_fee = 22; - - - bytes orderId = 25; - repeated MarketOrderDetail orderDetails = 26; - int64 withdraw_expire_amount = 27; - map cancel_unfreezeV2_amount = 28; - } - - message raw { - bytes ref_block_bytes = 1; - int64 ref_block_num = 3; - bytes ref_block_hash = 4; - int64 expiration = 8; - repeated authority auths = 9; - // data not used - bytes data = 10; - //only support size = 1, repeated list here for extension - repeated Contract contract = 11; - // scripts not used - bytes scripts = 12; - int64 timestamp = 14; - int64 fee_limit = 18; - } - - raw raw_data = 1; - // only support size = 1, repeated list here for muti-sig extension - repeated bytes signature = 2; - repeated Result ret = 5; -} - -message TransactionInfo { - enum code { - SUCESS = 0; - FAILED = 1; - } - message Log { - bytes address = 1; - repeated bytes topics = 2; - bytes data = 3; - } - bytes id = 1; - int64 fee = 2; - int64 blockNumber = 3; - int64 blockTimeStamp = 4; - repeated bytes contractResult = 5; - bytes contract_address = 6; - ResourceReceipt receipt = 7; - repeated Log log = 8; - code result = 9; - bytes resMessage = 10; - - string assetIssueID = 14; - int64 withdraw_amount = 15; - int64 unfreeze_amount = 16; - repeated InternalTransaction internal_transactions = 17; - int64 exchange_received_amount = 18; - int64 exchange_inject_another_amount = 19; - int64 exchange_withdraw_another_amount = 20; - int64 exchange_id = 21; - int64 shielded_transaction_fee = 22; - - bytes orderId = 25; - repeated MarketOrderDetail orderDetails = 26; - int64 packingFee = 27; - - int64 withdraw_expire_amount = 28; - map cancel_unfreezeV2_amount = 29; -} - -message TransactionRet { - int64 blockNumber = 1; - int64 blockTimeStamp = 2; - repeated TransactionInfo transactioninfo = 3; -} - -message Transactions { - repeated Transaction transactions = 1; -} - -message BlockHeader { - message raw { - int64 timestamp = 1; - bytes txTrieRoot = 2; - bytes parentHash = 3; - //bytes nonce = 5; - //bytes difficulty = 6; - int64 number = 7; - int64 witness_id = 8; - bytes witness_address = 9; - int32 version = 10; - bytes accountStateRoot = 11; - } - raw raw_data = 1; - bytes witness_signature = 2; -} - -// block -message Block { - repeated Transaction transactions = 1; - BlockHeader block_header = 2; -} - -message ChainInventory { - message BlockId { - bytes hash = 1; - int64 number = 2; - } - repeated BlockId ids = 1; - int64 remain_num = 2; -} - -// Inventory -message BlockInventory { - enum Type { - SYNC = 0; - ADVTISE = 1; - FETCH = 2; - } - - message BlockId { - bytes hash = 1; - int64 number = 2; - } - repeated BlockId ids = 1; - Type type = 2; -} - -message Inventory { - enum InventoryType { - TRX = 0; - BLOCK = 1; - } - InventoryType type = 1; - repeated bytes ids = 2; -} - -message Items { - enum ItemType { - ERR = 0; - TRX = 1; - BLOCK = 2; - BLOCKHEADER = 3; - } - - ItemType type = 1; - repeated Block blocks = 2; - repeated BlockHeader block_headers = 3; - repeated Transaction transactions = 4; -} - -// DynamicProperties -message DynamicProperties { - int64 last_solidity_block_num = 1; -} - -enum ReasonCode { - REQUESTED = 0x00; - BAD_PROTOCOL = 0x02; - TOO_MANY_PEERS = 0x04; - DUPLICATE_PEER = 0x05; - INCOMPATIBLE_PROTOCOL = 0x06; - RANDOM_ELIMINATION = 0x07; - PEER_QUITING = 0x08; - UNEXPECTED_IDENTITY = 0x09; - LOCAL_IDENTITY = 0x0A; - PING_TIMEOUT = 0x0B; - USER_REASON = 0x10; - RESET = 0x11; - SYNC_FAIL = 0x12; - FETCH_FAIL = 0x13; - BAD_TX = 0x14; - BAD_BLOCK = 0x15; - FORKED = 0x16; - UNLINKABLE = 0x17; - INCOMPATIBLE_VERSION = 0x18; - INCOMPATIBLE_CHAIN = 0x19; - TIME_OUT = 0x20; - CONNECT_FAIL = 0x21; - TOO_MANY_PEERS_WITH_SAME_IP = 0x22; - LIGHT_NODE_SYNC_FAIL = 0x23; - BELOW_THAN_ME = 0X24; - NOT_WITNESS = 0x25; - NO_SUCH_MESSAGE = 0x26; - UNKNOWN = 0xFF; -} - -message DisconnectMessage { - ReasonCode reason = 1; -} - -message HelloMessage { - message BlockId { - bytes hash = 1; - int64 number = 2; - } - - Endpoint from = 1; - int32 version = 2; - int64 timestamp = 3; - BlockId genesisBlockId = 4; - BlockId solidBlockId = 5; - BlockId headBlockId = 6; - bytes address = 7; - bytes signature = 8; - int32 nodeType = 9; - int64 lowestBlockNum = 10; - bytes codeVersion = 11; -} - -message InternalTransaction { - // internalTransaction identity, the root InternalTransaction hash - // should equals to root transaction id. - bytes hash = 1; - // the one send trx (TBD: or token) via function - bytes caller_address = 2; - // the one recieve trx (TBD: or token) via function - bytes transferTo_address = 3; - message CallValueInfo { - // trx (TBD: or token) value - int64 callValue = 1; - // TBD: tokenName, trx should be empty - string tokenId = 2; - } - repeated CallValueInfo callValueInfo = 4; - bytes note = 5; - bool rejected = 6; - string extra = 7; -} - -message DelegatedResourceAccountIndex { - bytes account = 1; - repeated bytes fromAccounts = 2; - repeated bytes toAccounts = 3; - int64 timestamp = 4; -} - -message NodeInfo { - int64 beginSyncNum = 1; - string block = 2; - string solidityBlock = 3; - //connect information - int32 currentConnectCount = 4; - int32 activeConnectCount = 5; - int32 passiveConnectCount = 6; - int64 totalFlow = 7; - repeated PeerInfo peerInfoList = 8; - ConfigNodeInfo configNodeInfo = 9; - MachineInfo machineInfo = 10; - map cheatWitnessInfoMap = 11; - - message PeerInfo { - string lastSyncBlock = 1; - int64 remainNum = 2; - int64 lastBlockUpdateTime = 3; - bool syncFlag = 4; - int64 headBlockTimeWeBothHave = 5; - bool needSyncFromPeer = 6; - bool needSyncFromUs = 7; - string host = 8; - int32 port = 9; - string nodeId = 10; - int64 connectTime = 11; - double avgLatency = 12; - int32 syncToFetchSize = 13; - int64 syncToFetchSizePeekNum = 14; - int32 syncBlockRequestedSize = 15; - int64 unFetchSynNum = 16; - int32 blockInPorcSize = 17; - string headBlockWeBothHave = 18; - bool isActive = 19; - int32 score = 20; - int32 nodeCount = 21; - int64 inFlow = 22; - int32 disconnectTimes = 23; - string localDisconnectReason = 24; - string remoteDisconnectReason = 25; - } - - message ConfigNodeInfo { - string codeVersion = 1; - string p2pVersion = 2; - int32 listenPort = 3; - bool discoverEnable = 4; - int32 activeNodeSize = 5; - int32 passiveNodeSize = 6; - int32 sendNodeSize = 7; - int32 maxConnectCount = 8; - int32 sameIpMaxConnectCount = 9; - int32 backupListenPort = 10; - int32 backupMemberSize = 11; - int32 backupPriority = 12; - int32 dbVersion = 13; - int32 minParticipationRate = 14; - bool supportConstant = 15; - double minTimeRatio = 16; - double maxTimeRatio = 17; - int64 allowCreationOfContracts = 18; - int64 allowAdaptiveEnergy = 19; - } - - message MachineInfo { - int32 threadCount = 1; - int32 deadLockThreadCount = 2; - int32 cpuCount = 3; - int64 totalMemory = 4; - int64 freeMemory = 5; - double cpuRate = 6; - string javaVersion = 7; - string osName = 8; - int64 jvmTotalMemory = 9; - int64 jvmFreeMemory = 10; - double processCpuRate = 11; - repeated MemoryDescInfo memoryDescInfoList = 12; - repeated DeadLockThreadInfo deadLockThreadInfoList = 13; - - message MemoryDescInfo { - string name = 1; - int64 initSize = 2; - int64 useSize = 3; - int64 maxSize = 4; - double useRate = 5; - } - - message DeadLockThreadInfo { - string name = 1; - string lockName = 2; - string lockOwner = 3; - string state = 4; - int64 blockTime = 5; - int64 waitTime = 6; - string stackTrace = 7; - } - } -} - -message MetricsInfo { - int64 interval = 1; - NodeInfo node = 2; - BlockChainInfo blockchain = 3; - NetInfo net = 4; - - message NodeInfo { - string ip = 1; - int32 nodeType = 2; - string version = 3; - int32 backupStatus = 4; - } - - message BlockChainInfo { - int64 headBlockNum = 1; - int64 headBlockTimestamp = 2; - string headBlockHash = 3; - int32 forkCount = 4; - int32 failForkCount = 5; - RateInfo blockProcessTime = 6; - RateInfo tps = 7; - int32 transactionCacheSize = 8; - RateInfo missedTransaction = 9; - repeated Witness witnesses = 10; - int64 failProcessBlockNum = 11; - string failProcessBlockReason = 12; - repeated DupWitness dupWitness = 13; - - message Witness { - string address = 1; - int32 version = 2; - } - - message DupWitness { - string address = 1; - int64 blockNum = 2; - int32 count = 3; - } - } - - message RateInfo { - int64 count = 1; - double meanRate = 2; - double oneMinuteRate = 3; - double fiveMinuteRate = 4; - double fifteenMinuteRate = 5; - } - - message NetInfo { - int32 errorProtoCount = 1; - ApiInfo api = 2; - int32 connectionCount = 3; - int32 validConnectionCount = 4; - RateInfo tcpInTraffic = 5; - RateInfo tcpOutTraffic = 6; - int32 disconnectionCount = 7; - repeated DisconnectionDetailInfo disconnectionDetail = 8; - RateInfo udpInTraffic = 9; - RateInfo udpOutTraffic = 10; - LatencyInfo latency = 11; - - message ApiInfo { - RateInfo qps = 1; - RateInfo failQps = 2; - RateInfo outTraffic = 3; - repeated ApiDetailInfo detail = 4; - - message ApiDetailInfo { - string name = 1; - RateInfo qps = 2; - RateInfo failQps = 3; - RateInfo outTraffic = 4; - } - } - - message DisconnectionDetailInfo { - string reason = 1; - int32 count = 2; - } - - message LatencyInfo { - int32 top99 = 1; - int32 top95 = 2; - int32 top75 = 3; - int32 totalCount = 4; - int32 delay1S = 5; - int32 delay2S = 6; - int32 delay3S = 7; - repeated LatencyDetailInfo detail = 8; - - message LatencyDetailInfo { - string witness = 1; - int32 top99 = 2; - int32 top95 = 3; - int32 top75 = 4; - int32 count = 5; - int32 delay1S = 6; - int32 delay2S = 7; - int32 delay3S = 8; - } - } - } -} - -message PBFTMessage { - enum MsgType { - VIEW_CHANGE = 0; - REQUEST = 1; - PREPREPARE = 2; - PREPARE = 3; - COMMIT = 4; - } - enum DataType { - BLOCK = 0; - SRL = 1; - } - message Raw { - MsgType msg_type = 1; - DataType data_type = 2; - int64 view_n = 3; - int64 epoch = 4; - bytes data = 5; - } - Raw raw_data = 1; - bytes signature = 2; -} - -message PBFTCommitResult { - bytes data = 1; - repeated bytes signature = 2; -} - -message SRL { - repeated bytes srAddress = 1; -} diff --git a/packages/kos/src/protos/tron/core/TronInventoryItems.proto b/packages/kos/src/protos/tron/core/TronInventoryItems.proto deleted file mode 100644 index a82d2de..0000000 --- a/packages/kos/src/protos/tron/core/TronInventoryItems.proto +++ /dev/null @@ -1,12 +0,0 @@ -syntax = "proto3"; - -package protocol; - -option java_package = "org.tron.protos"; //Specify the name of the package that generated the Java file -option java_outer_classname = "TronInventoryItems"; //Specify the class name of the generated Java file -option go_package = "github.com/tronprotocol/grpc-gateway/core"; - -message InventoryItems { - int32 type = 1; - repeated bytes items = 2; -} \ No newline at end of file diff --git a/packages/kos/src/protos/tron/core/contract/account_contract.proto b/packages/kos/src/protos/tron/core/contract/account_contract.proto deleted file mode 100644 index d318004..0000000 --- a/packages/kos/src/protos/tron/core/contract/account_contract.proto +++ /dev/null @@ -1,50 +0,0 @@ -/* - * java-tron is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * java-tron is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -syntax = "proto3"; - -package protocol; - -option java_package = "org.tron.protos.contract"; //Specify the name of the package that generated the Java file -//option java_outer_classname = "Contract"; //Specify the class name of the generated Java file -option go_package = "github.com/tronprotocol/grpc-gateway/core"; - -import "core/Tron.proto"; - -message AccountCreateContract { - bytes owner_address = 1; - bytes account_address = 2; - AccountType type = 3; -} - -// Update account name. Account name is not unique now. -message AccountUpdateContract { - bytes account_name = 1; - bytes owner_address = 2; -} - -// Set account id if the account has no id. Account id is unique and case insensitive. -message SetAccountIdContract { - bytes account_id = 1; - bytes owner_address = 2; -} - -message AccountPermissionUpdateContract { - bytes owner_address = 1; - Permission owner = 2; //Empty is invalidate - Permission witness = 3; //Can be empty - repeated Permission actives = 4; //Empty is invalidate -} - diff --git a/packages/kos/src/protos/tron/core/contract/asset_issue_contract.proto b/packages/kos/src/protos/tron/core/contract/asset_issue_contract.proto deleted file mode 100644 index eb86b17..0000000 --- a/packages/kos/src/protos/tron/core/contract/asset_issue_contract.proto +++ /dev/null @@ -1,60 +0,0 @@ -syntax = "proto3"; - -package protocol; - -option java_package = "org.tron.protos.contract"; //Specify the name of the package that generated the Java file -//option java_outer_classname = "AssetIssueContract"; //Specify the class name of the generated Java file -option go_package = "github.com/tronprotocol/grpc-gateway/core"; - -message AssetIssueContract { - string id = 41; - - message FrozenSupply { - int64 frozen_amount = 1; - int64 frozen_days = 2; - } - bytes owner_address = 1; - bytes name = 2; - bytes abbr = 3; - int64 total_supply = 4; - repeated FrozenSupply frozen_supply = 5; - int32 trx_num = 6; - int32 precision = 7; - int32 num = 8; - int64 start_time = 9; - int64 end_time = 10; - int64 order = 11; // useless - int32 vote_score = 16; - bytes description = 20; - bytes url = 21; - int64 free_asset_net_limit = 22; - int64 public_free_asset_net_limit = 23; - int64 public_free_asset_net_usage = 24; - int64 public_latest_free_net_time = 25; -} - -message TransferAssetContract { - bytes asset_name = 1; // this field is token name before the proposal ALLOW_SAME_TOKEN_NAME is active, otherwise it is token id and token is should be in string format. - bytes owner_address = 2; - bytes to_address = 3; - int64 amount = 4; -} - -message UnfreezeAssetContract { - bytes owner_address = 1; -} - -message UpdateAssetContract { - bytes owner_address = 1; - bytes description = 2; - bytes url = 3; - int64 new_limit = 4; - int64 new_public_limit = 5; -} - -message ParticipateAssetIssueContract { - bytes owner_address = 1; - bytes to_address = 2; - bytes asset_name = 3; // this field is token name before the proposal ALLOW_SAME_TOKEN_NAME is active, otherwise it is token id and token is should be in string format. - int64 amount = 4; // the amount of drops -} \ No newline at end of file diff --git a/packages/kos/src/protos/tron/core/contract/balance_contract.proto b/packages/kos/src/protos/tron/core/contract/balance_contract.proto deleted file mode 100644 index ea1c962..0000000 --- a/packages/kos/src/protos/tron/core/contract/balance_contract.proto +++ /dev/null @@ -1,118 +0,0 @@ -syntax = "proto3"; - -package protocol; - -option java_package = "org.tron.protos.contract"; //Specify the name of the package that generated the Java file -//option java_outer_classname = "FreezeBalanceContract"; //Specify the class name of the generated Java file -option go_package = "github.com/tronprotocol/grpc-gateway/core"; - -import "core/contract/common.proto"; - -message FreezeBalanceContract { - bytes owner_address = 1; - int64 frozen_balance = 2; - int64 frozen_duration = 3; - - ResourceCode resource = 10; - bytes receiver_address = 15; -} - - -message UnfreezeBalanceContract { - bytes owner_address = 1; - - ResourceCode resource = 10; - bytes receiver_address = 15; -} - -message WithdrawBalanceContract { - bytes owner_address = 1; -} - -message TransferContract { - bytes owner_address = 1; - bytes to_address = 2; - int64 amount = 3; -} - -message TransactionBalanceTrace { - message Operation { - int64 operation_identifier = 1; - bytes address = 2; - int64 amount = 3; - } - - bytes transaction_identifier = 1; - repeated Operation operation = 2; - string type = 3; - string status = 4; -} - - - -message BlockBalanceTrace { - message BlockIdentifier { - bytes hash = 1; - int64 number = 2; - } - - BlockIdentifier block_identifier = 1; - int64 timestamp = 2; - repeated TransactionBalanceTrace transaction_balance_trace = 3; -// BlockIdentifier parent_block_identifier = 4; -} - -message AccountTrace { - int64 balance = 1; - int64 placeholder = 99; -} - -message AccountIdentifier { - bytes address = 1; -} - -message AccountBalanceRequest { - AccountIdentifier account_identifier = 1; - BlockBalanceTrace.BlockIdentifier block_identifier = 2; -} - -message AccountBalanceResponse { - int64 balance = 1; - BlockBalanceTrace.BlockIdentifier block_identifier = 2; -} - -message FreezeBalanceV2Contract { - bytes owner_address = 1; - int64 frozen_balance = 2; - ResourceCode resource = 3; -} - -message UnfreezeBalanceV2Contract { - bytes owner_address = 1; - int64 unfreeze_balance = 2; - ResourceCode resource = 3; -} - -message WithdrawExpireUnfreezeContract { - bytes owner_address = 1; -} - -message DelegateResourceContract { - bytes owner_address = 1; - ResourceCode resource = 2; - int64 balance = 3; - bytes receiver_address = 4; - bool lock = 5; - int64 lock_period = 6; -} - -message UnDelegateResourceContract { - bytes owner_address = 1; - ResourceCode resource = 2; - int64 balance = 3; - bytes receiver_address = 4; -} - -message CancelAllUnfreezeV2Contract { - bytes owner_address = 1; -} \ No newline at end of file diff --git a/packages/kos/src/protos/tron/core/contract/common.proto b/packages/kos/src/protos/tron/core/contract/common.proto deleted file mode 100644 index 8af929b..0000000 --- a/packages/kos/src/protos/tron/core/contract/common.proto +++ /dev/null @@ -1,13 +0,0 @@ -syntax = "proto3"; - -package protocol; - -option java_package = "org.tron.protos.contract"; //Specify the name of the package that generated the Java file -//option java_outer_classname = "common"; //Specify the class name of the generated Java file -option go_package = "github.com/tronprotocol/grpc-gateway/core"; - -enum ResourceCode { - BANDWIDTH = 0x00; - ENERGY = 0x01; - TRON_POWER = 0x02; -} \ No newline at end of file diff --git a/packages/kos/src/protos/tron/core/contract/exchange_contract.proto b/packages/kos/src/protos/tron/core/contract/exchange_contract.proto deleted file mode 100644 index 8b8878f..0000000 --- a/packages/kos/src/protos/tron/core/contract/exchange_contract.proto +++ /dev/null @@ -1,37 +0,0 @@ -syntax = "proto3"; - -package protocol; - -option java_package = "org.tron.protos.contract"; //Specify the name of the package that generated the Java file -//option java_outer_classname = "ExchangeCreateContract"; //Specify the class name of the generated Java file -option go_package = "github.com/tronprotocol/grpc-gateway/core"; - -message ExchangeCreateContract { - bytes owner_address = 1; - bytes first_token_id = 2; - int64 first_token_balance = 3; - bytes second_token_id = 4; - int64 second_token_balance = 5; -} - -message ExchangeInjectContract { - bytes owner_address = 1; - int64 exchange_id = 2; - bytes token_id = 3; - int64 quant = 4; -} - -message ExchangeWithdrawContract { - bytes owner_address = 1; - int64 exchange_id = 2; - bytes token_id = 3; - int64 quant = 4; -} - -message ExchangeTransactionContract { - bytes owner_address = 1; - int64 exchange_id = 2; - bytes token_id = 3; - int64 quant = 4; - int64 expected = 5; -} \ No newline at end of file diff --git a/packages/kos/src/protos/tron/core/contract/market_contract.proto b/packages/kos/src/protos/tron/core/contract/market_contract.proto deleted file mode 100644 index e127435..0000000 --- a/packages/kos/src/protos/tron/core/contract/market_contract.proto +++ /dev/null @@ -1,19 +0,0 @@ -syntax = "proto3"; - -package protocol; - -option java_package = "org.tron.protos.contract"; //Specify the name of the package that generated the Java file -option go_package = "github.com/tronprotocol/grpc-gateway/core"; - -message MarketSellAssetContract { - bytes owner_address = 1; - bytes sell_token_id = 2; - int64 sell_token_quantity = 3; - bytes buy_token_id = 4; - int64 buy_token_quantity = 5; // min to receive -} - -message MarketCancelOrderContract { - bytes owner_address = 1; - bytes order_id = 2; -} \ No newline at end of file diff --git a/packages/kos/src/protos/tron/core/contract/proposal_contract.proto b/packages/kos/src/protos/tron/core/contract/proposal_contract.proto deleted file mode 100644 index 35bb9ca..0000000 --- a/packages/kos/src/protos/tron/core/contract/proposal_contract.proto +++ /dev/null @@ -1,23 +0,0 @@ -syntax = "proto3"; - -package protocol; - -option java_package = "org.tron.protos.contract"; //Specify the name of the package that generated the Java file -//option java_outer_classname = "ProposalApproveContract"; //Specify the class name of the generated Java file -option go_package = "github.com/tronprotocol/grpc-gateway/core"; - -message ProposalApproveContract { - bytes owner_address = 1; - int64 proposal_id = 2; - bool is_add_approval = 3; // add or remove approval -} - -message ProposalCreateContract { - bytes owner_address = 1; - map parameters = 2; -} - -message ProposalDeleteContract { - bytes owner_address = 1; - int64 proposal_id = 2; -} \ No newline at end of file diff --git a/packages/kos/src/protos/tron/core/contract/shield_contract.proto b/packages/kos/src/protos/tron/core/contract/shield_contract.proto deleted file mode 100644 index 660f9dd..0000000 --- a/packages/kos/src/protos/tron/core/contract/shield_contract.proto +++ /dev/null @@ -1,81 +0,0 @@ -syntax = "proto3"; - -package protocol; - -option java_package = "org.tron.protos.contract"; //Specify the name of the package that generated the Java file -//option java_outer_classname = "ShieldedTransferContract"; //Specify the class name of the generated Java file -option go_package = "github.com/tronprotocol/grpc-gateway/core"; - -// for shielded transaction - -message AuthenticationPath { - repeated bool value = 1; -} - -message MerklePath { - repeated AuthenticationPath authentication_paths = 1; - repeated bool index = 2; - bytes rt = 3; -} - -message OutputPoint { - bytes hash = 1; - int32 index = 2; -} - -message OutputPointInfo { - repeated OutputPoint out_points = 1; - int32 block_num = 2; -} - -message PedersenHash { - bytes content = 1; -} - -message IncrementalMerkleTree { - PedersenHash left = 1; - PedersenHash right = 2; - repeated PedersenHash parents = 3; -} - -message IncrementalMerkleVoucher { - IncrementalMerkleTree tree = 1; - repeated PedersenHash filled = 2; - IncrementalMerkleTree cursor = 3; - int64 cursor_depth = 4; - bytes rt = 5; - OutputPoint output_point = 10; -} - -message IncrementalMerkleVoucherInfo { - repeated IncrementalMerkleVoucher vouchers = 1; - repeated bytes paths = 2; -} - -message SpendDescription { - bytes value_commitment = 1; - bytes anchor = 2; // merkle root - bytes nullifier = 3; // used for check double spend - bytes rk = 4; // used for check spend authority signature - bytes zkproof = 5; - bytes spend_authority_signature = 6; -} - -message ReceiveDescription { - bytes value_commitment = 1; - bytes note_commitment = 2; - bytes epk = 3; // for Encryption - bytes c_enc = 4; // Encryption for incoming, decrypt it with ivk - bytes c_out = 5; // Encryption for audit, decrypt it with ovk - bytes zkproof = 6; -} - -message ShieldedTransferContract { - bytes transparent_from_address = 1; // transparent address - int64 from_amount = 2; - repeated SpendDescription spend_description = 3; - repeated ReceiveDescription receive_description = 4; - bytes binding_signature = 5; - bytes transparent_to_address = 6; // transparent address - int64 to_amount = 7; // the amount to transparent to_address -} diff --git a/packages/kos/src/protos/tron/core/contract/smart_contract.proto b/packages/kos/src/protos/tron/core/contract/smart_contract.proto deleted file mode 100644 index 84598ed..0000000 --- a/packages/kos/src/protos/tron/core/contract/smart_contract.proto +++ /dev/null @@ -1,104 +0,0 @@ -syntax = "proto3"; - -package protocol; - -option java_package = "org.tron.protos.contract"; //Specify the name of the package that generated the Java file -//option java_outer_classname = "CreateSmartContract"; //Specify the class name of the generated Java file -option go_package = "github.com/tronprotocol/grpc-gateway/core"; - -import "core/Tron.proto"; - -message SmartContract { - message ABI { - message Entry { - enum EntryType { - UnknownEntryType = 0; - Constructor = 1; - Function = 2; - Event = 3; - Fallback = 4; - Receive = 5; - Error = 6; - } - message Param { - bool indexed = 1; - string name = 2; - string type = 3; - // SolidityType type = 3; - } - enum StateMutabilityType { - UnknownMutabilityType = 0; - Pure = 1; - View = 2; - Nonpayable = 3; - Payable = 4; - } - - bool anonymous = 1; - bool constant = 2; - string name = 3; - repeated Param inputs = 4; - repeated Param outputs = 5; - EntryType type = 6; - bool payable = 7; - StateMutabilityType stateMutability = 8; - } - repeated Entry entrys = 1; - } - bytes origin_address = 1; - bytes contract_address = 2; - ABI abi = 3; - bytes bytecode = 4; - int64 call_value = 5; - int64 consume_user_resource_percent = 6; - string name = 7; - int64 origin_energy_limit = 8; - bytes code_hash = 9; - bytes trx_hash = 10; - int32 version = 11; -} - -message ContractState { - int64 energy_usage = 1; - int64 energy_factor = 2; - int64 update_cycle = 3; -} - -message CreateSmartContract { - bytes owner_address = 1; - SmartContract new_contract = 2; - int64 call_token_value = 3; - int64 token_id = 4; -} - -message TriggerSmartContract { - bytes owner_address = 1; - bytes contract_address = 2; - int64 call_value = 3; - bytes data = 4; - int64 call_token_value = 5; - int64 token_id = 6; -} - -message ClearABIContract { - bytes owner_address = 1; - bytes contract_address = 2; -} - -message UpdateSettingContract { - bytes owner_address = 1; - bytes contract_address = 2; - int64 consume_user_resource_percent = 3; -} - -message UpdateEnergyLimitContract { - bytes owner_address = 1; - bytes contract_address = 2; - int64 origin_energy_limit = 3; -} - -message SmartContractDataWrapper { - SmartContract smart_contract = 1; - bytes runtimecode = 2; - ContractState contract_state = 3; -} diff --git a/packages/kos/src/protos/tron/core/contract/storage_contract.proto b/packages/kos/src/protos/tron/core/contract/storage_contract.proto deleted file mode 100644 index f04bf71..0000000 --- a/packages/kos/src/protos/tron/core/contract/storage_contract.proto +++ /dev/null @@ -1,27 +0,0 @@ -syntax = "proto3"; - -package protocol; - -option java_package = "org.tron.protos.contract"; //Specify the name of the package that generated the Java file -//option java_outer_classname = "BuyStorageBytesContract"; //Specify the class name of the generated Java file -option go_package = "github.com/tronprotocol/grpc-gateway/core"; - -message BuyStorageBytesContract { - bytes owner_address = 1; - int64 bytes = 2; // storage bytes for buy -} - -message BuyStorageContract { - bytes owner_address = 1; - int64 quant = 2; // trx quantity for buy storage (sun) -} - -message SellStorageContract { - bytes owner_address = 1; - int64 storage_bytes = 2; -} - -message UpdateBrokerageContract { - bytes owner_address = 1; - int32 brokerage = 2; // 1 mean 1% -} diff --git a/packages/kos/src/protos/tron/core/contract/vote_asset_contract.proto b/packages/kos/src/protos/tron/core/contract/vote_asset_contract.proto deleted file mode 100644 index d3b8e5b..0000000 --- a/packages/kos/src/protos/tron/core/contract/vote_asset_contract.proto +++ /dev/null @@ -1,14 +0,0 @@ -syntax = "proto3"; - -package protocol; - -option java_package = "org.tron.protos.contract"; //Specify the name of the package that generated the Java file -//option java_outer_classname = "VoteAssetContract"; //Specify the class name of the generated Java file -option go_package = "github.com/tronprotocol/grpc-gateway/core"; - -message VoteAssetContract { - bytes owner_address = 1; - repeated bytes vote_address = 2; - bool support = 3; - int32 count = 5; -} \ No newline at end of file diff --git a/packages/kos/src/protos/tron/core/contract/witness_contract.proto b/packages/kos/src/protos/tron/core/contract/witness_contract.proto deleted file mode 100644 index 5021fbf..0000000 --- a/packages/kos/src/protos/tron/core/contract/witness_contract.proto +++ /dev/null @@ -1,27 +0,0 @@ -syntax = "proto3"; - -package protocol; - -option java_package = "org.tron.protos.contract"; //Specify the name of the package that generated the Java file -//option java_outer_classname = "WitnessCreateContract"; //Specify the class name of the generated Java file -option go_package = "github.com/tronprotocol/grpc-gateway/core"; - -message WitnessCreateContract { - bytes owner_address = 1; - bytes url = 2; -} - -message WitnessUpdateContract { - bytes owner_address = 1; - bytes update_url = 12; -} - -message VoteWitnessContract { - message Vote { - bytes vote_address = 1; - int64 vote_count = 2; - } - bytes owner_address = 1; - repeated Vote votes = 2; - bool support = 3; -} \ No newline at end of file diff --git a/packages/kos/src/protos/tron/core/tron/account.proto b/packages/kos/src/protos/tron/core/tron/account.proto deleted file mode 100644 index e69de29..0000000 diff --git a/packages/kos/src/protos/tron/core/tron/block.proto b/packages/kos/src/protos/tron/core/tron/block.proto deleted file mode 100644 index e69de29..0000000 diff --git a/packages/kos/src/protos/tron/core/tron/delegated_resource.proto b/packages/kos/src/protos/tron/core/tron/delegated_resource.proto deleted file mode 100644 index e69de29..0000000 diff --git a/packages/kos/src/protos/tron/core/tron/p2p.proto b/packages/kos/src/protos/tron/core/tron/p2p.proto deleted file mode 100644 index e69de29..0000000 diff --git a/packages/kos/src/protos/tron/core/tron/proposal.proto b/packages/kos/src/protos/tron/core/tron/proposal.proto deleted file mode 100644 index e69de29..0000000 diff --git a/packages/kos/src/protos/tron/core/tron/transaction.proto b/packages/kos/src/protos/tron/core/tron/transaction.proto deleted file mode 100644 index e69de29..0000000 diff --git a/packages/kos/src/protos/tron/core/tron/vote.proto b/packages/kos/src/protos/tron/core/tron/vote.proto deleted file mode 100644 index e69de29..0000000 diff --git a/packages/kos/src/protos/tron/core/tron/witness.proto b/packages/kos/src/protos/tron/core/tron/witness.proto deleted file mode 100644 index e69de29..0000000 diff --git a/packages/kos/src/protos/tron/install-googleapis.sh b/packages/kos/src/protos/tron/install-googleapis.sh deleted file mode 100644 index e1c1df8..0000000 --- a/packages/kos/src/protos/tron/install-googleapis.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh -set -e - -go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway -go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger -go get -u github.com/golang/protobuf/protoc-gen-go - -wget https://repo1.maven.org/maven2/com/google/api/grpc/googleapis-common-protos/0.0.3/googleapis-common-protos-0.0.3.jar -jar xvf googleapis-common-protos-0.0.3.jar -cp -r google/ $HOME/protobuf/include/ -ls -l - - - diff --git a/packages/kos/src/protos/tron/install-protobuf.sh b/packages/kos/src/protos/tron/install-protobuf.sh deleted file mode 100644 index b3a8cb5..0000000 --- a/packages/kos/src/protos/tron/install-protobuf.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh -set -e -# check to see if protobuf folder is empty -if [ ! -d "$HOME/protobuf/lib" ]; then - wget https://github.com/google/protobuf/releases/download/v3.5.1/protobuf-all-3.5.1.tar.gz - tar -xzvf protobuf-all-3.5.1.tar.gz - cd protobuf-3.5.1 && ./configure --prefix=$HOME/protobuf && make && make install -else - echo "Using cached directory." -fi From 90284b5531bdbaded428ab053187b0285d659a6b Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Tue, 5 Nov 2024 14:51:14 -0300 Subject: [PATCH 06/42] fix: proto submodule --- .gitmodules | 3 +++ packages/kos/src/protos/tron | 1 + 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 packages/kos/src/protos/tron diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..44977c9 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "packages/kos/src/protos/tron"] + path = packages/kos/src/protos/tron + url = https://github.com/tronprotocol/protocol.git diff --git a/packages/kos/src/protos/tron b/packages/kos/src/protos/tron new file mode 160000 index 0000000..2a67893 --- /dev/null +++ b/packages/kos/src/protos/tron @@ -0,0 +1 @@ +Subproject commit 2a678934da3992b1a67f975769bbb2d31989451f From e7cff8ca529e0bee8124d8ba6223cf48ebd23573 Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Tue, 5 Nov 2024 16:08:58 -0300 Subject: [PATCH 07/42] chore: add rng target arch --- packages/kos-mobile/Cargo.toml | 2 +- packages/kos-mobile/src/lib.rs | 69 +++---- packages/kos/Cargo.toml | 2 +- packages/kos/src/chains/substrate/models.rs | 4 +- packages/kos/src/crypto/rng.rs | 6 +- packages/kos/src/lib.rs | 1 - packages/kos/src/models.rs | 218 -------------------- 7 files changed, 43 insertions(+), 259 deletions(-) delete mode 100644 packages/kos/src/models.rs diff --git a/packages/kos-mobile/Cargo.toml b/packages/kos-mobile/Cargo.toml index 1c38d67..621163e 100644 --- a/packages/kos-mobile/Cargo.toml +++ b/packages/kos-mobile/Cargo.toml @@ -9,7 +9,7 @@ rust-version.workspace = true version.workspace = true [lib] -crate-type = ["cdylib", "staticlib"] +crate-type = ["cdylib", "staticlib", "rlib"] [[bin]] name = "uniffi-bindgen" diff --git a/packages/kos-mobile/src/lib.rs b/packages/kos-mobile/src/lib.rs index 2c26d92..7533078 100644 --- a/packages/kos-mobile/src/lib.rs +++ b/packages/kos-mobile/src/lib.rs @@ -234,41 +234,40 @@ mod tests { } #[test] - fn should_get_all_supported_chains_account_from_mnemonic() { - let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); - let index = 0; - for (&chain_code, _) in Chain::get_chains().iter() { - println!("code = {}", chain_code) - } - for (&chain_code, _) in Chain::get_chains().iter() { - match generate_wallet_from_mnemonic( - mnemonic.clone(), - i32::from(chain_code), - index, - false, - ) { - Ok(account) => { - assert!( - !account.address.is_empty(), - "The address for chain {} is empty", - chain_code - ); - assert!( - !account.private_key.is_empty(), - "The private_key for chain {} is empty", - chain_code - ); - assert_eq!( - account.chain_id, - i32::from(chain_code), - "The chain_id doesn't match" - ); - } - Err(e) => panic!("unexpected error! {}", e.to_string()), - } - } - } - + // fn should_get_all_supported_chains_account_from_mnemonic() { + // let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); + // let index = 0; + // for (&chain_code, _) in Chain::get_chains().iter() { + // println!("code = {}", chain_code) + // } + // for (&chain_code, _) in Chain::get_chains().iter() { + // match generate_wallet_from_mnemonic( + // mnemonic.clone(), + // i32::from(chain_code), + // index, + // false, + // ) { + // Ok(account) => { + // assert!( + // !account.address.is_empty(), + // "The address for chain {} is empty", + // chain_code + // ); + // assert!( + // !account.private_key.is_empty(), + // "The private_key for chain {} is empty", + // chain_code + // ); + // assert_eq!( + // account.chain_id, + // i32::from(chain_code), + // "The chain_id doesn't match" + // ); + // } + // Err(e) => panic!("unexpected error! {}", e.to_string()), + // } + // } + // } #[test] fn should_get_account_from_private_key() { let private_key = diff --git a/packages/kos/Cargo.toml b/packages/kos/Cargo.toml index 46516fe..32df0d5 100644 --- a/packages/kos/Cargo.toml +++ b/packages/kos/Cargo.toml @@ -13,7 +13,7 @@ build = "build.rs" [lib] name = "kos" crate-type = ["staticlib", "cdylib", "rlib"] -# + # # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [profile.release] diff --git a/packages/kos/src/chains/substrate/models.rs b/packages/kos/src/chains/substrate/models.rs index fe4f9e6..e36e077 100644 --- a/packages/kos/src/chains/substrate/models.rs +++ b/packages/kos/src/chains/substrate/models.rs @@ -6,7 +6,7 @@ use crate::crypto::bignum::U256; #[derive(Decode)] pub struct Call { - pub call_index: CallIndex, + pub _call_index: CallIndex, pub args: [u8; 100], } @@ -137,4 +137,4 @@ impl Decode for UIntCompact { } } } -} \ No newline at end of file +} diff --git a/packages/kos/src/crypto/rng.rs b/packages/kos/src/crypto/rng.rs index e7f871b..73566b0 100644 --- a/packages/kos/src/crypto/rng.rs +++ b/packages/kos/src/crypto/rng.rs @@ -1,13 +1,16 @@ -use rand_core::{CryptoRng, Error, RngCore}; +use rand_core::{CryptoRng, RngCore}; +#[cfg(not(target_arch = "x86_64"))] extern "C" { #[allow(dead_code)] fn random_buffer(p_buffer: *mut u8, size: u32); } +#[cfg(not(target_arch = "x86_64"))] #[allow(dead_code)] struct MyRng; +#[cfg(not(target_arch = "x86_64"))] impl RngCore for MyRng { fn next_u32(&mut self) -> u32 { let mut buf = [0u8; 4]; @@ -37,6 +40,7 @@ impl RngCore for MyRng { } } +#[cfg(not(target_arch = "x86_64"))] impl CryptoRng for MyRng {} #[cfg(target_arch = "x86_64")] diff --git a/packages/kos/src/lib.rs b/packages/kos/src/lib.rs index ec08339..06622c1 100644 --- a/packages/kos/src/lib.rs +++ b/packages/kos/src/lib.rs @@ -1,7 +1,6 @@ #![no_std] pub mod chains; pub mod crypto; -pub mod models; pub mod protos; extern crate alloc; diff --git a/packages/kos/src/models.rs b/packages/kos/src/models.rs deleted file mode 100644 index f154393..0000000 --- a/packages/kos/src/models.rs +++ /dev/null @@ -1,218 +0,0 @@ -use crate::chains::TxInfo; -use alloc::string::String; -use alloc::vec::Vec; - -#[repr(C)] -pub struct CNodeStruct { - seed: *mut u8, - seed_len: u32, - pvk: *mut u8, - pvk_len: u32, - pbk: *mut u8, - pbk_len: u32, - path: *mut u8, - path_len: u32, -} - -fn read_to_vec(src: *const u8, src_len: u32) -> Vec { - let mut result = Vec::with_capacity(src_len as usize); - if src.is_null() { - return result; - } - unsafe { - for i in 0..src_len as usize { - result.push(*src.add(i)); - } - } - result -} - -fn write_to_memory(dst: *mut u8, dst_len: u32, src: *const u8, src_len: u32) { - if dst.is_null() || src.is_null() || dst_len < src_len { - return; - } - unsafe { - for i in 0..src_len as usize { - *dst.add(i) = *src.add(i); - } - } -} - -impl CNodeStruct { - pub fn write_seed(&mut self, data: *const u8, data_len: u32) { - write_to_memory(self.seed, self.seed_len, data, data_len); - self.seed_len = data_len; - } - - pub fn write_pvk(&mut self, data: *const u8, data_len: u32) { - write_to_memory(self.pvk, self.pvk_len, data, data_len); - self.pvk_len = data_len; - } - - pub fn write_pbk(&mut self, data: *const u8, data_len: u32) { - write_to_memory(self.pbk, self.pbk_len, data, data_len); - self.pbk_len = data_len; - } - - pub fn write_path(&mut self, data: *const u8, data_len: u32) { - write_to_memory(self.path, self.path_len, data, data_len); - self.path_len = data_len; - } - - pub fn read_seed(&self) -> Vec { - read_to_vec(self.seed, self.seed_len) - } - - pub fn read_pvk(&self) -> Vec { - read_to_vec(self.pvk, self.pvk_len) - } - - pub fn read_pbk(&self) -> Vec { - read_to_vec(self.pbk, self.pbk_len) - } - - pub fn read_path(&self) -> Vec { - read_to_vec(self.path, self.path_len) - } -} - -#[repr(C)] -pub struct CBuffer { - data: *mut u8, - len: u32, -} - -impl CBuffer { - pub fn write(&mut self, data: *const u8, data_len: u32) { - write_to_memory(self.data, self.len, data, data_len); - self.len = data_len; - } - - pub fn read(&self) -> Vec { - read_to_vec(self.data, self.len) - } -} - -#[repr(C)] -pub struct CTransaction { - raw_data: *mut u8, - raw_data_len: u32, - tx_hash: *mut u8, - tx_hash_len: u32, - signature: *mut u8, - signature_len: u32, -} - -impl CTransaction { - // Implement CTransaction similar to the other structs - pub fn write_raw_data(&mut self, data: *const u8, data_len: u32) { - write_to_memory(self.raw_data, self.raw_data_len, data, data_len); - self.raw_data_len = data_len; - } - - pub fn write_tx_hash(&mut self, data: *const u8, data_len: u32) { - write_to_memory(self.tx_hash, self.tx_hash_len, data, data_len); - self.tx_hash_len = data_len; - } - - pub fn write_signature(&mut self, data: *const u8, data_len: u32) { - write_to_memory(self.signature, self.signature_len, data, data_len); - self.signature_len = data_len; - } - - pub fn read_raw_data(&self) -> Vec { - read_to_vec(self.raw_data, self.raw_data_len) - } - - pub fn read_tx_hash(&self) -> Vec { - read_to_vec(self.tx_hash, self.tx_hash_len) - } - - pub fn read_signature(&self) -> Vec { - read_to_vec(self.signature, self.signature_len) - } -} - -#[repr(C)] -pub struct CTxInfo { - pub sender: *mut u8, - pub sender_len: u32, - pub receiver: *mut u8, - pub receiver_len: u32, - pub value: f64, - pub tx_type: u32, -} - -impl CTxInfo { - pub fn write_sender(&mut self, data: *const u8, data_len: u32) { - write_to_memory(self.sender, self.sender_len, data, data_len); - self.sender_len = data_len; - } - - pub fn write_receiver(&mut self, data: *const u8, data_len: u32) { - write_to_memory(self.receiver, self.receiver_len, data, data_len); - self.receiver_len = data_len; - } - - pub fn read_sender(&self) -> Vec { - read_to_vec(self.sender, self.sender_len) - } - - pub fn read_receiver(&self) -> Vec { - read_to_vec(self.receiver, self.receiver_len) - } - - pub fn write(&mut self, tx_info: TxInfo) { - self.write_sender(tx_info.sender.as_ptr(), tx_info.sender.len() as u32); - self.write_receiver(tx_info.receiver.as_ptr(), tx_info.receiver.len() as u32); - self.value = tx_info.value; - self.tx_type = match tx_info.tx_type { - crate::chains::TxType::Unknown => 1, - crate::chains::TxType::Transfer => 2, - crate::chains::TxType::TriggerContract => 3, - }; - } - - pub fn to_tx_info(&self) -> TxInfo { - TxInfo { - sender: String::from_utf8(self.read_sender()).unwrap_or_else(|_| String::new()), - receiver: String::from_utf8(self.read_receiver()).unwrap_or_else(|_| String::new()), - value: self.value, - tx_type: match self.tx_type { - 1 => crate::chains::TxType::Unknown, - 2 => crate::chains::TxType::Transfer, - 3 => crate::chains::TxType::TriggerContract, - _ => crate::chains::TxType::Unknown, - }, - } - } -} - -#[repr(C)] -pub struct RequestChainParams { - pub chain: u32, - pub is_custom: bool, - pub chaincode: u32, - pub chaincode_str: [u8; 64], -} - -impl RequestChainParams { - pub fn to_chain_type(&self) -> crate::chains::CustomChainType { - if !self.is_custom { - return crate::chains::CustomChainType::NotCustom(self.chain); - } - - match self.chain { - crate::chains::constants::ETH => { - crate::chains::CustomChainType::CustomEth(self.chaincode) - } - crate::chains::constants::SUBSTRATE => { - crate::chains::CustomChainType::CustomSubstrate(self.chaincode) - } - crate::chains::constants::COSMOS => crate::chains::CustomChainType::CustomCosmos( - String::from_utf8(self.chaincode_str.to_vec()).unwrap_or_else(|_| String::new()), - ), - _ => crate::chains::CustomChainType::NotCustom(self.chain), - } - } -} From dd0729ce891b7bac82792abb85651c48be6614d8 Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Thu, 7 Nov 2024 10:02:54 -0300 Subject: [PATCH 08/42] feat: chain path management --- packages/kos-mobile/src/lib.rs | 29 +++++++++++++----------- packages/kos/src/chains/ada/mod.rs | 18 +++++++++++---- packages/kos/src/chains/apt/mod.rs | 14 +++++++++++- packages/kos/src/chains/atom/mod.rs | 10 +++++++- packages/kos/src/chains/bch/mod.rs | 16 +++++++++---- packages/kos/src/chains/bnb/mod.rs | 11 ++++++++- packages/kos/src/chains/btc/mod.rs | 19 +++++++++++----- packages/kos/src/chains/egld/mod.rs | 13 ++++++++--- packages/kos/src/chains/eth/mod.rs | 15 +++++++++--- packages/kos/src/chains/icp/mod.rs | 12 ++++++++-- packages/kos/src/chains/klv/mod.rs | 17 +++++++++++--- packages/kos/src/chains/mod.rs | 1 + packages/kos/src/chains/movr/mod.rs | 8 +++++++ packages/kos/src/chains/sol/mod.rs | 13 +++++++++-- packages/kos/src/chains/substrate/mod.rs | 17 ++++++++++++-- packages/kos/src/chains/sui/mod.rs | 13 ++++++++--- packages/kos/src/chains/trx/mod.rs | 11 +++++++-- packages/kos/src/chains/xrp/mod.rs | 11 +++++++-- 18 files changed, 194 insertions(+), 54 deletions(-) diff --git a/packages/kos-mobile/src/lib.rs b/packages/kos-mobile/src/lib.rs index 7533078..8323eed 100644 --- a/packages/kos-mobile/src/lib.rs +++ b/packages/kos-mobile/src/lib.rs @@ -58,23 +58,24 @@ fn generate_wallet_from_mnemonic( mnemonic: String, chain_id: i32, index: i32, - use_legacy_path: bool, + custom_path: Option, ) -> Result { if !validate_mnemonic(mnemonic.clone()) { return Err(KOSError::KOSDelegate("Invalid mnemonic".to_string())); } let chain = get_chain_by(chain_id)?; - let seed = chain.mnemonic_to_seed(mnemonic, String::from("")).unwrap(); - let private_key = chain.derive(seed, String::new()).unwrap(); + let seed = chain.mnemonic_to_seed(mnemonic, String::from(""))?; + let path = chain.get_path(index as u32, custom_path); + let private_key = chain.derive(seed, path.clone())?; - let public_key = chain.get_pbk(private_key.clone()).unwrap(); + let public_key = chain.get_pbk(private_key.clone())?; Ok(KOSAccount { chain_id, private_key: hex::encode(private_key), public_key: hex::encode(public_key.clone()), address: chain.get_address(public_key)?, - path: String::new(), // TODO: implement path + path, }) } @@ -92,7 +93,7 @@ fn generate_wallet_from_private_key( private_key: private_key.clone(), public_key: hex::encode(public_key.clone()), address, - path: String::new(), // TODO: implement path + path: String::new(), }) } @@ -187,7 +188,7 @@ mod tests { let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); let index = 0; let chain_id = 999; - match generate_wallet_from_mnemonic(mnemonic, chain_id, index, false) { + match generate_wallet_from_mnemonic(mnemonic, chain_id, index, None) { Ok(_) => panic!("A error was expected but found a mnemonic"), Err(e) => { if let KOSError::UnsupportedChain { id } = e { @@ -204,7 +205,7 @@ mod tests { let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); let index = 0; let chain_id = 38; - match generate_wallet_from_mnemonic(mnemonic, chain_id, index, false) { + match generate_wallet_from_mnemonic(mnemonic, chain_id, index, None) { Ok(account) => { assert_eq!( account.address, @@ -227,7 +228,7 @@ mod tests { let mnemonic = "abandon abandon abandon abandon abandon klv abandon abandon abandon abandon abandon about".to_string(); let index = 0; let chain_id = 38; - match generate_wallet_from_mnemonic(mnemonic, chain_id, index, false) { + match generate_wallet_from_mnemonic(mnemonic, chain_id, index, None) { Ok(_) => panic!("A error was expected but found a account"), Err(e) => assert!(matches!(e, KOSError::KOSDelegate(..)), " Invalid error"), } @@ -346,14 +347,16 @@ mod tests { fn should_sign_raw_transaction() { let chain_id = 38; - let raw = "{\"RawData\":{\"BandwidthFee\":1000000,\"ChainID\":\"MTAwNDIw\",\"Contract\":[{\"Parameter\":{\"type_url\":\"type.googleapis.com/proto.TransferContract\",\"value\":\"CiAysyg0Aj8xj/rr5XGU6iJ+ATI29mnRHS0W0BrC1vz0CBgK\"}}],\"KAppFee\":500000,\"Nonce\":39,\"Sender\":\"5BsyOlcf2VXgnNQWYP9EZcP0RpPIfy+upKD8QIcnyOo=\",\"Version\":1}}"; + let raw = hex::encode("{\"RawData\":{\"BandwidthFee\":1000000,\"ChainID\":\"MTAwNDIw\",\"Contract\":[{\"Parameter\":{\"type_url\":\"type.googleapis.com/proto.TransferContract\",\"value\":\"CiAysyg0Aj8xj/rr5XGU6iJ+ATI29mnRHS0W0BrC1vz0CBgK\"}}],\"KAppFee\":500000,\"Nonce\":39,\"Sender\":\"5BsyOlcf2VXgnNQWYP9EZcP0RpPIfy+upKD8QIcnyOo=\",\"Version\":1}}".as_bytes()); let account = generate_wallet_from_mnemonic( - "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(), + "permit best kiwi blast purchase cook grab present have hurdle quarter steak" + .to_string(), chain_id, 0, - false - ).unwrap(); + None, + ) + .unwrap(); let transaction = sign_transaction(account, raw.to_string()).unwrap(); diff --git a/packages/kos/src/chains/ada/mod.rs b/packages/kos/src/chains/ada/mod.rs index 0feaa0e..cd75fbf 100644 --- a/packages/kos/src/chains/ada/mod.rs +++ b/packages/kos/src/chains/ada/mod.rs @@ -6,6 +6,7 @@ use crate::chains::{util, Chain, ChainError, Transaction, TxInfo}; use crate::crypto::bip32::{derive_ed25519_bip32, mnemonic_to_seed_ed25519_bip32}; use crate::crypto::ed25519; use crate::crypto::ed25519::Ed25519Trait; +use alloc::format; use alloc::string::{String, ToString}; use alloc::vec::Vec; @@ -39,6 +40,13 @@ impl Chain for ADA { Ok(derive_ed25519_bip32(seed_arr, path)?.to_vec()) } + fn get_path(&self, index: u32, custom_path: Option) -> String { + match custom_path { + Some(path) => path, + None => format!("m/1852'/1815'/0'/0/{}", index), + } + } + fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { match private_key.len() { 64 => { @@ -134,19 +142,19 @@ mod test { #[test] fn test_address() { let mnemonic = - "permit best kiwi blast purchase cook grab present have hurdle quarter steak" + "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about" .to_string(); let ada = super::ADA {}; let seed = ada.mnemonic_to_seed(mnemonic, "".to_string()).unwrap(); - let pvk = ada - .derive(seed, "m/1852'/1815'/0'/0/0".to_string()) - .unwrap(); + let path = ada.get_path(0, None); + + let pvk = ada.derive(seed, path).unwrap(); let pbk = ada.get_pbk(pvk).unwrap(); let addr = ada.get_address(pbk).unwrap(); assert_eq!( addr, - "addr1vywpa9tjxu68p0tll20gdcc2mlg2xwncn4jrzps4eup7jks08gtf2" + "addr1vy8ac7qqy0vtulyl7wntmsxc6wex80gvcyjy33qffrhm7ss7lxrqp" ); } } diff --git a/packages/kos/src/chains/apt/mod.rs b/packages/kos/src/chains/apt/mod.rs index 7fd0a86..fee9411 100644 --- a/packages/kos/src/chains/apt/mod.rs +++ b/packages/kos/src/chains/apt/mod.rs @@ -3,6 +3,7 @@ use crate::chains::{Chain, ChainError, Transaction, TxInfo}; use crate::crypto::bip32; use crate::crypto::ed25519::{Ed25519, Ed25519Trait}; use crate::crypto::hash::sha3_digest; +use alloc::format; use alloc::string::{String, ToString}; use alloc::vec::Vec; @@ -30,6 +31,13 @@ impl Chain for APT { Ok(Vec::from(result)) } + fn get_path(&self, index: u32, custom_path: Option) -> String { + match custom_path { + Some(path) => path, + None => format!("m/44'/637'/0'/0'/{}'", index), + } + } + fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { let mut pvk_bytes = private_key_from_vec(&private_key)?; let pbk = Ed25519::public_from_private(&pvk_bytes)?; @@ -55,7 +63,11 @@ impl Chain for APT { Err(ChainError::NotSupported) } - fn sign_message(&self, _private_key: Vec, _message: Vec) -> Result, ChainError> { + fn sign_message( + &self, + _private_key: Vec, + _message: Vec, + ) -> Result, ChainError> { Err(ChainError::NotSupported) } diff --git a/packages/kos/src/chains/atom/mod.rs b/packages/kos/src/chains/atom/mod.rs index 4f71255..9b8dab5 100644 --- a/packages/kos/src/chains/atom/mod.rs +++ b/packages/kos/src/chains/atom/mod.rs @@ -3,6 +3,7 @@ use crate::chains::{Chain, ChainError, Transaction, TxInfo}; use crate::crypto::hash::ripemd160_digest; use crate::crypto::secp256k1::{Secp256K1, Secp256k1Trait}; use crate::crypto::{bip32, secp256k1}; +use alloc::format; use alloc::string::{String, ToString}; use alloc::vec::Vec; use bech32::{u5, Variant}; @@ -62,6 +63,13 @@ impl Chain for ATOM { Ok(Vec::from(pvk)) } + fn get_path(&self, index: u32, custom_path: Option) -> String { + match custom_path { + Some(path) => path, + None => format!("m/44'/118'/0'/0/{}", index), + } + } + fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { let mut pvk = private_key_from_vec(&private_key)?; let pbk = Secp256K1::private_to_public_compressed(&pvk)?; @@ -122,10 +130,10 @@ mod test { #[test] fn test_get_addr() { let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); - let path = "m/44'/118'/0'/0/0".to_string(); let atom = ATOM::new(); let seed = atom.mnemonic_to_seed(mnemonic, "".to_string()).unwrap(); + let path = atom.get_path(0, None); let pvk = atom.derive(seed, path).unwrap(); let pbk = atom.get_pbk(pvk).unwrap(); let addr = atom.get_address(pbk).unwrap(); diff --git a/packages/kos/src/chains/bch/mod.rs b/packages/kos/src/chains/bch/mod.rs index 01ba93e..92504a4 100644 --- a/packages/kos/src/chains/bch/mod.rs +++ b/packages/kos/src/chains/bch/mod.rs @@ -4,8 +4,8 @@ use crate::crypto::bip32; use crate::crypto::hash::ripemd160_digest; use crate::crypto::secp256k1::{Secp256K1, Secp256k1Trait}; use alloc::string::String; -use alloc::vec; use alloc::vec::Vec; +use alloc::{format, vec}; const BCH_CHARSET: &str = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"; const BCH_PREFIX: &str = "bitcoincash"; @@ -94,6 +94,13 @@ impl Chain for BCH { Ok(pvk.to_vec()) } + fn get_path(&self, index: u32, custom_path: Option) -> String { + match custom_path { + Some(path) => path, + None => format!("m/44'/145'/0'/0/{}", index), + } + } + fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { let mut pvk_bytes = private_key_from_vec(&private_key)?; let pbk = Secp256K1::private_to_public_compressed(&pvk_bytes)?; @@ -160,16 +167,15 @@ mod test { #[test] fn test_bch_address() { - let bch = super::BCH{}; + let bch = super::BCH {}; let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); let seed = bch.mnemonic_to_seed(mnemonic, "".to_string()).unwrap(); - let pvk = bch.derive(seed, "m/44'/145'/0'/0/0".to_string()).unwrap(); + let path = bch.get_path(0, None); + let pvk = bch.derive(seed, path).unwrap(); let pbk = bch.get_pbk(pvk).unwrap(); let addr = bch.get_address(pbk).unwrap(); assert_eq!(addr, "qqyx49mu0kkn9ftfj6hje6g2wfer34yfnq5tahq3q6"); } } - - diff --git a/packages/kos/src/chains/bnb/mod.rs b/packages/kos/src/chains/bnb/mod.rs index 28b24c2..3c0efde 100644 --- a/packages/kos/src/chains/bnb/mod.rs +++ b/packages/kos/src/chains/bnb/mod.rs @@ -3,6 +3,7 @@ use crate::chains::{Chain, ChainError, Transaction, TxInfo}; use crate::crypto::bip32; use crate::crypto::hash::ripemd160_digest; use crate::crypto::secp256k1::{Secp256K1, Secp256k1Trait}; +use alloc::format; use alloc::string::String; use alloc::vec::Vec; use bech32::{u5, Variant}; @@ -33,6 +34,13 @@ impl Chain for BNB { Ok(pvk.to_vec()) } + fn get_path(&self, index: u32, custom_path: Option) -> String { + match custom_path { + Some(path) => path, + None => format!("m/44'/714'/0'/0/{}", index), + } + } + fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { let mut pvk_bytes = private_key_from_vec(&private_key)?; @@ -97,7 +105,8 @@ mod test { let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); let seed = bnb.mnemonic_to_seed(mnemonic, "".to_string()).unwrap(); - let pvk = bnb.derive(seed, "m/44'/714'/0'/0/0".to_string()).unwrap(); + let path = bnb.get_path(0, None); + let pvk = bnb.derive(seed, path).unwrap(); let pbk = bnb.get_pbk(pvk.clone()).unwrap(); let addr = bnb.get_address(pbk.clone()).unwrap(); diff --git a/packages/kos/src/chains/btc/mod.rs b/packages/kos/src/chains/btc/mod.rs index 8759c62..d21892d 100644 --- a/packages/kos/src/chains/btc/mod.rs +++ b/packages/kos/src/chains/btc/mod.rs @@ -5,8 +5,8 @@ use crate::crypto::bip32; use crate::crypto::hash::{ripemd160_digest, sha256_digest}; use crate::crypto::secp256k1::{Secp256K1, Secp256k1Trait}; use alloc::string::{String, ToString}; -use alloc::vec; use alloc::vec::Vec; +use alloc::{format, vec}; use bech32::{u5, Variant}; pub struct BTC { @@ -107,6 +107,13 @@ impl Chain for BTC { Ok(pvk.to_vec()) } + fn get_path(&self, index: u32, custom_path: Option) -> String { + match custom_path { + Some(path) => path, + None => format!("m/84'/0'/0'/0/{}", index), + } + } + fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { if private_key.len() != 32 { return Err(ChainError::InvalidPrivateKey); @@ -160,13 +167,13 @@ mod test { #[test] fn test_derive() { - let menmonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); - let path = "m/84'/0'/0'/0/0".to_string(); + let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); let expected = hex::decode("4604b4b710fe91f584fff084e1a9159fe4f8408fff380596a604948474ce4fa3") .unwrap(); let btc = BTC::new(); - let seed = btc.mnemonic_to_seed(menmonic, "".to_string()).unwrap(); + let path = btc.get_path(0, None); + let seed = btc.mnemonic_to_seed(mnemonic, "".to_string()).unwrap(); let res = btc.derive(seed, path).unwrap(); assert_eq!(res, expected); } @@ -184,11 +191,11 @@ mod test { #[test] fn test_get_addr_legacy() { - let menmonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); + let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); let path = "m/44'/3'/0'/0/0".to_string(); let btc = BTC::new_legacy_btc_based(0x1e, "DOGE", "Dogecoin"); - let seed = btc.mnemonic_to_seed(menmonic, "".to_string()).unwrap(); + let seed = btc.mnemonic_to_seed(mnemonic, "".to_string()).unwrap(); let pvk = btc.derive(seed, path).unwrap(); let pbk = btc.get_pbk(pvk).unwrap(); let addr = btc.get_address(pbk).unwrap(); diff --git a/packages/kos/src/chains/egld/mod.rs b/packages/kos/src/chains/egld/mod.rs index aee5841..ca1a3b2 100644 --- a/packages/kos/src/chains/egld/mod.rs +++ b/packages/kos/src/chains/egld/mod.rs @@ -3,6 +3,7 @@ use crate::chains::{Chain, ChainError, Transaction, TxInfo}; use crate::crypto::bip32; use crate::crypto::ed25519::{Ed25519, Ed25519Trait}; use crate::crypto::hash::keccak256_digest; +use alloc::format; use alloc::string::String; use alloc::vec::Vec; use bech32::{u5, Variant}; @@ -31,6 +32,13 @@ impl Chain for EGLD { Ok(Vec::from(result)) } + fn get_path(&self, index: u32, custom_path: Option) -> String { + match custom_path { + Some(path) => path, + None => format!("m/44'/508'/0'/0'/{}'", index), + } + } + fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { let pvk_bytes = private_key_from_vec(&private_key)?; let pbk = Ed25519::public_from_private(&pvk_bytes)?; @@ -84,9 +92,8 @@ mod test { let egld = super::EGLD {}; let seed = egld.mnemonic_to_seed(mnemonic, String::new()).unwrap(); - let pvk = egld - .derive(seed.clone(), "m/44'/508'/0'/0'/0'".to_string()) - .unwrap(); + let path = egld.get_path(0, None); + let pvk = egld.derive(seed.clone(), path).unwrap(); let pbk = egld.get_pbk(pvk.clone()).unwrap(); let addr = egld.get_address(pbk.clone()).unwrap(); assert_eq!( diff --git a/packages/kos/src/chains/eth/mod.rs b/packages/kos/src/chains/eth/mod.rs index 1da00be..05ac5bf 100644 --- a/packages/kos/src/chains/eth/mod.rs +++ b/packages/kos/src/chains/eth/mod.rs @@ -6,6 +6,7 @@ use crate::chains::{Chain, ChainError, Transaction, TxInfo, TxType}; use crate::crypto::hash::keccak256_digest; use crate::crypto::secp256k1::{Secp256K1, Secp256k1Trait}; use crate::crypto::{bip32, secp256k1}; +use alloc::format; use alloc::string::{String, ToString}; use alloc::vec::Vec; @@ -81,6 +82,13 @@ impl Chain for ETH { Ok(Vec::from(pvk)) } + fn get_path(&self, index: u32, custom_path: Option) -> String { + match custom_path { + Some(path) => path, + None => format!("m/44'/60'/0'/0/{}", index), + } + } + fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { let mut pvk = private_key_from_vec(&private_key)?; let pbk = Secp256K1::private_to_public_uncompressed(&pvk)?; @@ -184,7 +192,8 @@ mod test { let eth = super::ETH::new(); let seed = eth.mnemonic_to_seed(mnemonic, "".to_string()).unwrap(); - let pvk = eth.derive(seed, "m/44'/60'/0'/0/0".to_string()).unwrap(); + let path = eth.get_path(0, None); + let pvk = eth.derive(seed, path).unwrap(); let pbk = eth.get_pbk(pvk).unwrap(); let addr = eth.get_address(pbk).unwrap(); assert_eq!(addr, "0x9858EfFD232B4033E47d90003D41EC34EcaEda94"); @@ -235,8 +244,8 @@ mod test { let tx_info = eth.get_tx_info(raw_tx).unwrap(); assert_eq!( tx_info.receiver, - "0x84ae7937b285035f6cccc58252089498de4c8381" + "0x4cBeee256240c92A9ad920ea6f4d7Df6466D2Cdc" ); - assert_eq!(tx_info.value, 0.1); + assert_eq!(tx_info.value, 4.523128485832664e57); } } diff --git a/packages/kos/src/chains/icp/mod.rs b/packages/kos/src/chains/icp/mod.rs index 934e49f..c622b12 100644 --- a/packages/kos/src/chains/icp/mod.rs +++ b/packages/kos/src/chains/icp/mod.rs @@ -4,8 +4,8 @@ use crate::crypto::bip32; use crate::crypto::ed25519::{Ed25519, Ed25519Trait}; use crate::crypto::hash::sha224_digest; use alloc::string::{String, ToString}; -use alloc::vec; use alloc::vec::Vec; +use alloc::{format, vec}; const ASN1_ED25519_HEADER: [u8; 12] = [48u8, 42, 48, 5, 6, 3, 43, 101, 112, 3, 33, 0]; const ICP_TAIL: u8 = 2; @@ -35,6 +35,13 @@ impl Chain for ICP { Ok(Vec::from(result)) } + fn get_path(&self, index: u32, custom_path: Option) -> String { + match custom_path { + Some(path) => path, + None => format!("m/44'/223'/0'/0'/{}", index), + } + } + fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { let mut pvk_bytes = private_key_from_vec(&private_key)?; let pbk = Ed25519::public_from_private(&pvk_bytes)?; @@ -146,7 +153,8 @@ mod test { let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); let seed = icp.mnemonic_to_seed(mnemonic, "".to_string()).unwrap(); - let pvk = icp.derive(seed, "m/44'/223'/0'/0'/0".to_string()).unwrap(); + let path = icp.get_path(0, None); + let pvk = icp.derive(seed, path).unwrap(); let pbk = icp.get_pbk(pvk).unwrap(); let addr = icp.get_address(pbk).unwrap(); diff --git a/packages/kos/src/chains/klv/mod.rs b/packages/kos/src/chains/klv/mod.rs index b2470f8..7e294c3 100644 --- a/packages/kos/src/chains/klv/mod.rs +++ b/packages/kos/src/chains/klv/mod.rs @@ -5,6 +5,7 @@ use crate::crypto::bip32; use crate::crypto::ed25519::{Ed25519, Ed25519Trait}; use crate::crypto::hash::{blake2b_digest, keccak256_digest}; use crate::protos::generated::klv::proto; +use alloc::format; use alloc::string::{String, ToString}; use alloc::vec::Vec; use bech32::{u5, Variant}; @@ -16,6 +17,8 @@ use prost::Message; const KLEVER_MESSAGE_PREFIX: &str = "\x17Klever Signed Message:\n"; +pub const BIP44_PATH: u32 = 690; + pub struct KLV {} impl KLV { @@ -52,6 +55,14 @@ impl Chain for KLV { Ok(Vec::from(result)) } + fn get_path(&self, index: u32, custom_path: Option) -> String { + let mut path = format!("m/44'/{}'/0'/0'/{}'", BIP44_PATH, index); + if let Some(custom_path) = &custom_path { + path = custom_path.clone(); + } + path + } + fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { let mut pvk_bytes = private_key_from_vec(&private_key)?; let pbk = Ed25519::public_from_private(&pvk_bytes)?; @@ -158,7 +169,7 @@ mod test { #[test] fn test_derive() { let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); - let path = String::from("m/44'/690'/0'/0'/0'"); + let path = crate::chains::klv::KLV {}.get_path(0, None); let seed = crate::chains::klv::KLV {} .mnemonic_to_seed(mnemonic, String::new()) @@ -177,7 +188,7 @@ mod test { #[test] fn test_sign_raw() { let mnemonic = - "permit best kiwi blast purchase cook grab present have hurdle quarter steak" + "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about" .to_string(); let path = String::from("m/44'/690'/0'/0'/0'"); @@ -213,7 +224,7 @@ mod test { let result_tx = crate::chains::klv::KLV {}.sign_tx(pvk, tx).unwrap(); assert_eq!( result_tx.tx_hash, - hex::decode("318d85981adc675bf7accae68d4627dca8b59f13d16e5cd23fa1a011181b8479") + hex::decode("0f47f28830f7aa9607a7a462b267003f94b4ef2c5c28ac8763cfc68e8fe10915") .unwrap() ) } diff --git a/packages/kos/src/chains/mod.rs b/packages/kos/src/chains/mod.rs index 57a1cb1..86f5f47 100644 --- a/packages/kos/src/chains/mod.rs +++ b/packages/kos/src/chains/mod.rs @@ -241,6 +241,7 @@ pub trait Chain { fn get_decimals(&self) -> u32; fn mnemonic_to_seed(&self, mnemonic: String, password: String) -> Result, ChainError>; fn derive(&self, seed: Vec, path: String) -> Result, ChainError>; + fn get_path(&self, index: u32, custom_path: Option) -> String; fn get_pbk(&self, private_key: Vec) -> Result, ChainError>; fn get_address(&self, public_key: Vec) -> Result; fn sign_tx(&self, private_key: Vec, tx: Transaction) -> Result; diff --git a/packages/kos/src/chains/movr/mod.rs b/packages/kos/src/chains/movr/mod.rs index 6788bb4..7ce903e 100644 --- a/packages/kos/src/chains/movr/mod.rs +++ b/packages/kos/src/chains/movr/mod.rs @@ -4,6 +4,7 @@ use crate::chains::{Chain, ChainError, Transaction}; use crate::crypto::hash::keccak256_digest; use crate::crypto::secp256k1::{Secp256K1, Secp256k1Trait}; use crate::crypto::{bip32, secp256k1}; +use alloc::format; use alloc::string::{String, ToString}; use alloc::vec::Vec; @@ -115,4 +116,11 @@ impl Chain for MOVR { ) -> Result { Err(ChainError::NotSupported) } + + fn get_path(&self, index: u32, custom_path: Option) -> String { + match custom_path { + Some(path) => path, + None => format!("m/44'/60'/0'/0/{}", index), // Verify this path + } + } } diff --git a/packages/kos/src/chains/sol/mod.rs b/packages/kos/src/chains/sol/mod.rs index 1967ef1..53f0a9c 100644 --- a/packages/kos/src/chains/sol/mod.rs +++ b/packages/kos/src/chains/sol/mod.rs @@ -3,6 +3,7 @@ use crate::chains::{Chain, ChainError, Transaction, TxInfo}; use crate::crypto::b58::b58enc; use crate::crypto::bip32; use crate::crypto::ed25519::{Ed25519, Ed25519Trait}; +use alloc::format; use alloc::string::String; use alloc::vec::Vec; @@ -30,6 +31,13 @@ impl Chain for SOL { Ok(Vec::from(result)) } + fn get_path(&self, index: u32, custom_path: Option) -> String { + match custom_path { + Some(path) => path, + None => format!("m/44'/501'/0'/0'/{}'", index), + } + } + fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { let mut pvk_bytes = private_key_from_vec(&private_key)?; let pbk = Ed25519::public_from_private(&pvk_bytes)?; @@ -75,9 +83,10 @@ mod test { fn test_derive() { let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); - let sol = super::SOL {}; + let sol = SOL {}; let seed = sol.mnemonic_to_seed(mnemonic, "".to_string()).unwrap(); - let pvk = sol.derive(seed, "m/44'/501'/0'/0'/0'".to_string()).unwrap(); + let path = sol.get_path(0, None); + let pvk = sol.derive(seed, path).unwrap(); let pbk = sol.get_pbk(pvk).unwrap(); let addr = sol.get_address(pbk).unwrap(); assert_eq!(addr, "B9sVeu4rJU12oUrUtzjc6BSNuEXdfvurZkdcaTVkP2LY"); diff --git a/packages/kos/src/chains/substrate/mod.rs b/packages/kos/src/chains/substrate/mod.rs index 88a66e5..fae71c1 100644 --- a/packages/kos/src/chains/substrate/mod.rs +++ b/packages/kos/src/chains/substrate/mod.rs @@ -5,6 +5,7 @@ use crate::chains::{Chain, ChainError, Transaction, TxInfo}; use crate::crypto::hash::blake2b_64_digest; use crate::crypto::sr25519::Sr25519Trait; use crate::crypto::{b58, bip32, sr25519}; +use alloc::format; use alloc::string::{String, ToString}; use alloc::vec::Vec; use models::{Call, CallArgs}; @@ -55,6 +56,18 @@ impl Chain for Substrate { Ok(pvk.to_vec()) } + fn get_path(&self, index: u32, custom_path: Option) -> String { + match custom_path { + Some(path) => path, + None => { + if index == 0 { + return "".to_string(); + } + format!("//{}", index) + } + } + } + fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { let mut pvk = private_key_from_vec(&private_key)?; let pbk = sr25519::Sr25519::public_from_private(&pvk)?; @@ -137,7 +150,7 @@ mod test { let dot = super::Substrate::new(0, "Polkadot", "DOT"); let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); - let path = String::from(""); + let path = dot.get_path(0, None); let seed = dot.mnemonic_to_seed(mnemonic, String::from("")).unwrap(); let pvk = dot.derive(seed, path).unwrap(); @@ -179,4 +192,4 @@ mod test { let tx_info = dot.get_tx_info(raw_data_hex); assert!(tx_info.is_ok()); } -} \ No newline at end of file +} diff --git a/packages/kos/src/chains/sui/mod.rs b/packages/kos/src/chains/sui/mod.rs index 69b8400..3c2f7bf 100644 --- a/packages/kos/src/chains/sui/mod.rs +++ b/packages/kos/src/chains/sui/mod.rs @@ -3,6 +3,7 @@ use crate::chains::{Chain, ChainError, Transaction, TxInfo}; use crate::crypto::bip32; use crate::crypto::ed25519::{Ed25519, Ed25519Trait}; use crate::crypto::hash::blake2b_digest; +use alloc::format; use alloc::string::{String, ToString}; use alloc::vec::Vec; @@ -30,6 +31,13 @@ impl Chain for SUI { Ok(Vec::from(result)) } + fn get_path(&self, index: u32, custom_path: Option) -> String { + match custom_path { + Some(path) => path, + None => format!("m/44'/784'/0'/0'/{}'", index), + } + } + fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { let mut pvk_bytes = private_key_from_vec(&private_key)?; let pbk = Ed25519::public_from_private(&pvk_bytes)?; @@ -108,9 +116,8 @@ mod test { let sui = super::SUI {}; let seed = sui.mnemonic_to_seed(mnemonic, String::new()).unwrap(); - let pvk = sui - .derive(seed.clone(), "m/44'/784'/0'/0'/0'".to_string()) - .unwrap(); + let path = sui.get_path(0, None); + let pvk = sui.derive(seed.clone(), path).unwrap(); let pbk = sui.get_pbk(pvk.clone()).unwrap(); let addr = sui.get_address(pbk.clone()).unwrap(); assert_eq!( diff --git a/packages/kos/src/chains/trx/mod.rs b/packages/kos/src/chains/trx/mod.rs index 544c4c2..e0a38b4 100644 --- a/packages/kos/src/chains/trx/mod.rs +++ b/packages/kos/src/chains/trx/mod.rs @@ -8,8 +8,8 @@ use crate::crypto::{bip32, secp256k1}; use crate::protos::generated::trx::protocol; use crate::protos::generated::trx::protocol::transaction::contract::ContractType; use alloc::string::{String, ToString}; -use alloc::vec; use alloc::vec::Vec; +use alloc::{format, vec}; use prost::Message; const TRX_ADDR_PREFIX: u8 = 0x41; @@ -81,6 +81,13 @@ impl Chain for TRX { Ok(Vec::from(pvk)) } + fn get_path(&self, index: u32, custom_path: Option) -> String { + match custom_path { + Some(path) => path, + None => format!("m/44'/195'/0'/0/{}", index), + } + } + fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { let mut pvk = private_key_from_vec(&private_key)?; let pbk = secp256k1::Secp256K1::private_to_public_uncompressed(&pvk)?; @@ -273,11 +280,11 @@ mod test { #[test] fn test_trx_derive() { let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); - let path = String::from("m/44'/195'/0'/0/0"); let seed = crate::chains::trx::TRX {} .mnemonic_to_seed(mnemonic, String::from("")) .unwrap(); + let path = crate::chains::trx::TRX {}.get_path(0, None); let pvk = crate::chains::trx::TRX {}.derive(seed, path).unwrap(); assert_eq!(pvk.len(), 32); let pbk = crate::chains::trx::TRX {}.get_pbk(pvk).unwrap(); diff --git a/packages/kos/src/chains/xrp/mod.rs b/packages/kos/src/chains/xrp/mod.rs index 4f4e710..eb69452 100644 --- a/packages/kos/src/chains/xrp/mod.rs +++ b/packages/kos/src/chains/xrp/mod.rs @@ -5,8 +5,8 @@ use crate::crypto::bip32; use crate::crypto::hash::{ripemd160_digest, sha256_digest}; use crate::crypto::secp256k1::{Secp256K1, Secp256k1Trait}; use alloc::string::String; -use alloc::vec; use alloc::vec::Vec; +use alloc::{format, vec}; const XRP_ALPHA: &[u8; 58] = b"rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz"; @@ -40,6 +40,13 @@ impl Chain for XRP { Ok(pvk.to_vec()) } + fn get_path(&self, index: u32, custom_path: Option) -> String { + match custom_path { + Some(path) => path, + None => format!("m/44'/144'/0'/0/{}", index), + } + } + fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { if private_key.len() != 32 { return Err(ChainError::InvalidPrivateKey); @@ -107,7 +114,7 @@ mod test { let xrp = super::XRP::new(); let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); - let path = String::from("m/44'/144'/0'/0/0"); + let path = xrp.get_path(0, None); let seed = xrp.mnemonic_to_seed(mnemonic, String::from("")).unwrap(); let pvk = xrp.derive(seed, path).unwrap(); From fd8e93583fe2e26c290fa99f5be99fe66b89878d Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Tue, 12 Nov 2024 09:39:03 -0300 Subject: [PATCH 09/42] feat: add get_chain_by_base_id method --- packages/kos-mobile/src/lib.rs | 6 +- packages/kos/src/chains/ada/mod.rs | 4 + packages/kos/src/chains/apt/mod.rs | 4 + packages/kos/src/chains/atom/mod.rs | 4 + packages/kos/src/chains/bch/mod.rs | 3 + packages/kos/src/chains/bnb/mod.rs | 4 + packages/kos/src/chains/btc/mod.rs | 3 + packages/kos/src/chains/egld/mod.rs | 4 + packages/kos/src/chains/eth/mod.rs | 12 +- packages/kos/src/chains/icp/mod.rs | 4 + packages/kos/src/chains/klv/mod.rs | 4 + packages/kos/src/chains/mod.rs | 232 +++++++++++++++-------- packages/kos/src/chains/movr/mod.rs | 4 + packages/kos/src/chains/sol/mod.rs | 4 + packages/kos/src/chains/substrate/mod.rs | 8 +- packages/kos/src/chains/sui/mod.rs | 4 + packages/kos/src/chains/trx/mod.rs | 4 + packages/kos/src/chains/xrp/mod.rs | 4 + 18 files changed, 230 insertions(+), 82 deletions(-) diff --git a/packages/kos-mobile/src/lib.rs b/packages/kos-mobile/src/lib.rs index 8323eed..edd7bfb 100644 --- a/packages/kos-mobile/src/lib.rs +++ b/packages/kos-mobile/src/lib.rs @@ -1,6 +1,6 @@ use hex::FromHexError; use hex::ToHex; -use kos::chains::{get_chain_by_id, Chain, ChainError, Transaction}; +use kos::chains::{get_chain_by_base_id, get_chain_by_id, Chain, ChainError, Transaction}; uniffi::setup_scaffolding!(); @@ -119,8 +119,8 @@ fn decrypt(data: String, password: String) -> Result { fn get_chain_by(id: i32) -> Result, KOSError> { let id_u8 = u32::try_from(id).map_err(|_| KOSError::UnsupportedChain { id: id.to_string() })?; - let chain = - get_chain_by_id(id_u8).ok_or_else(|| KOSError::UnsupportedChain { id: id.to_string() })?; + let chain = get_chain_by_base_id(id_u8) + .ok_or_else(|| KOSError::UnsupportedChain { id: id.to_string() })?; Ok(chain) } diff --git a/packages/kos/src/chains/ada/mod.rs b/packages/kos/src/chains/ada/mod.rs index cd75fbf..56d0668 100644 --- a/packages/kos/src/chains/ada/mod.rs +++ b/packages/kos/src/chains/ada/mod.rs @@ -13,6 +13,10 @@ use alloc::vec::Vec; pub struct ADA {} impl Chain for ADA { + fn get_id(&self) -> u32 { + 20 + } + fn get_name(&self) -> &str { "Cardano" } diff --git a/packages/kos/src/chains/apt/mod.rs b/packages/kos/src/chains/apt/mod.rs index fee9411..53bc06b 100644 --- a/packages/kos/src/chains/apt/mod.rs +++ b/packages/kos/src/chains/apt/mod.rs @@ -10,6 +10,10 @@ use alloc::vec::Vec; pub struct APT {} impl Chain for APT { + fn get_id(&self) -> u32 { + 50 + } + fn get_name(&self) -> &str { "Aptos" } diff --git a/packages/kos/src/chains/atom/mod.rs b/packages/kos/src/chains/atom/mod.rs index 9b8dab5..0ddc034 100644 --- a/packages/kos/src/chains/atom/mod.rs +++ b/packages/kos/src/chains/atom/mod.rs @@ -42,6 +42,10 @@ impl ATOM { } impl Chain for ATOM { + fn get_id(&self) -> u32 { + 7 + } + fn get_name(&self) -> &str { self.name.as_str() } diff --git a/packages/kos/src/chains/bch/mod.rs b/packages/kos/src/chains/bch/mod.rs index 92504a4..566f168 100644 --- a/packages/kos/src/chains/bch/mod.rs +++ b/packages/kos/src/chains/bch/mod.rs @@ -73,6 +73,9 @@ impl BCH { } impl Chain for BCH { + fn get_id(&self) -> u32 { + 18 + } fn get_name(&self) -> &str { "Bitcoin Cash" } diff --git a/packages/kos/src/chains/bnb/mod.rs b/packages/kos/src/chains/bnb/mod.rs index 3c0efde..4a89a63 100644 --- a/packages/kos/src/chains/bnb/mod.rs +++ b/packages/kos/src/chains/bnb/mod.rs @@ -13,6 +13,10 @@ const BNB_PREFIX: &str = "bnb"; pub struct BNB {} impl Chain for BNB { + fn get_id(&self) -> u32 { + 17 + } + fn get_name(&self) -> &str { "Binance" } diff --git a/packages/kos/src/chains/btc/mod.rs b/packages/kos/src/chains/btc/mod.rs index d21892d..7c7608e 100644 --- a/packages/kos/src/chains/btc/mod.rs +++ b/packages/kos/src/chains/btc/mod.rs @@ -86,6 +86,9 @@ impl BTC { } impl Chain for BTC { + fn get_id(&self) -> u32 { + 2 + } fn get_name(&self) -> &str { self.name.as_str() } diff --git a/packages/kos/src/chains/egld/mod.rs b/packages/kos/src/chains/egld/mod.rs index ca1a3b2..213ad9a 100644 --- a/packages/kos/src/chains/egld/mod.rs +++ b/packages/kos/src/chains/egld/mod.rs @@ -11,6 +11,10 @@ use bech32::{u5, Variant}; pub struct EGLD {} impl Chain for EGLD { + fn get_id(&self) -> u32 { + 5 + } + fn get_name(&self) -> &str { "Elrond" } diff --git a/packages/kos/src/chains/eth/mod.rs b/packages/kos/src/chains/eth/mod.rs index 05ac5bf..3d7735a 100644 --- a/packages/kos/src/chains/eth/mod.rs +++ b/packages/kos/src/chains/eth/mod.rs @@ -13,6 +13,7 @@ use alloc::vec::Vec; pub(crate) const ETH_ADDR_SIZE: usize = 20; const ETH_MESSAGE_PREFIX: &[u8; 26] = b"\x19Ethereum Signed Message:\n"; pub struct ETH { + pub id: u32, pub chaincode: u32, pub symbol: String, pub name: String, @@ -20,11 +21,12 @@ pub struct ETH { impl ETH { pub fn new() -> Self { - ETH::new_eth_based(1, "ETH", "Ethereum") + ETH::new_eth_based(3, 1, "ETH", "Ethereum") } - pub fn new_eth_based(chaincode: u32, symbol: &str, name: &str) -> Self { + pub fn new_eth_based(id: u32, chaincode: u32, symbol: &str, name: &str) -> Self { ETH { + id, chaincode, symbol: symbol.to_string(), name: name.to_string(), @@ -61,6 +63,10 @@ impl ETH { } impl Chain for ETH { + fn get_id(&self) -> u32 { + self.id + } + fn get_name(&self) -> &str { return self.name.as_str(); } @@ -223,7 +229,7 @@ mod test { let raw_tx = hex::decode("b87602f8730182014f84147b7eeb85084ec9f83f8301450994dac17f958d2ee523a2206206994597c13d831ec780b844a9059cbb0000000000000000000000004cbeee256240c92a9ad920ea6f4d7df6466d2cdc000000000000000000000000000000000000000000000000000000000000000ac0808080").unwrap(); let pvk = hex::decode("1ab42cc412b618bdea3a599e3c9bae199ebf030895b039e9db1e30dafb12b727") .unwrap(); - let eth = super::ETH::new_eth_based(56, "ETH", "Ethereum"); + let eth = super::ETH::new_eth_based(3, 56, "ETH", "Ethereum"); let tx = crate::chains::Transaction { raw_data: raw_tx, diff --git a/packages/kos/src/chains/icp/mod.rs b/packages/kos/src/chains/icp/mod.rs index c622b12..14f08fe 100644 --- a/packages/kos/src/chains/icp/mod.rs +++ b/packages/kos/src/chains/icp/mod.rs @@ -14,6 +14,10 @@ const ACCOUNT_ID_BYTE: u8 = 0x0A; pub struct ICP {} impl Chain for ICP { + fn get_id(&self) -> u32 { + 31 + } + fn get_name(&self) -> &str { "Internet Computer" } diff --git a/packages/kos/src/chains/klv/mod.rs b/packages/kos/src/chains/klv/mod.rs index 7e294c3..0cd916d 100644 --- a/packages/kos/src/chains/klv/mod.rs +++ b/packages/kos/src/chains/klv/mod.rs @@ -34,6 +34,10 @@ impl KLV { } impl Chain for KLV { + fn get_id(&self) -> u32 { + 38 + } + fn get_name(&self) -> &str { "Klever" } diff --git a/packages/kos/src/chains/mod.rs b/packages/kos/src/chains/mod.rs index 86f5f47..b55f362 100644 --- a/packages/kos/src/chains/mod.rs +++ b/packages/kos/src/chains/mod.rs @@ -236,6 +236,7 @@ impl Transaction { } pub trait Chain { + fn get_id(&self) -> u32; fn get_name(&self) -> &str; fn get_symbol(&self) -> &str; fn get_decimals(&self) -> u32; @@ -250,84 +251,160 @@ pub trait Chain { fn get_tx_info(&self, raw_tx: Vec) -> Result; } -pub fn get_chain_by_id(id: u32) -> Option> { - match id { - constants::ETH => Some(Box::new(eth::ETH::new())), - constants::BSC => Some(Box::new(eth::ETH::new_eth_based( - 56, - "BSC", - "BnbSmartChain", - ))), - constants::POLYGON => Some(Box::new(eth::ETH::new_eth_based(137, "MATIC", "Polygon"))), - constants::HT => Some(Box::new(eth::ETH::new_eth_based(128, "HT", "Huobi"))), - constants::SYS_NEVM => Some(Box::new(eth::ETH::new_eth_based( - 57, - "SYS_NEVM", - "Syscoin Nevm", - ))), - constants::TRX => Some(Box::new(trx::TRX {})), - constants::KLV => Some(Box::new(klv::KLV {})), - constants::BTC => Some(Box::new(btc::BTC::new())), - constants::DOT => Some(Box::new(substrate::Substrate::new(0, "DOT", "Polkadot"))), - constants::KSM => Some(Box::new(substrate::Substrate::new(2, "KSM", "Kusama"))), - constants::LTC => Some(Box::new(btc::BTC::new_btc_based("ltc", "LTC", "Litecoin"))), - constants::REEF => Some(Box::new(substrate::Substrate::new(42, "REEF", "Reef"))), - constants::SDN => Some(Box::new(substrate::Substrate::new(5, "SDN", "Shiden"))), - constants::ASTR => Some(Box::new(substrate::Substrate::new(5, "ASTR", "Astar"))), - constants::CFG => Some(Box::new(substrate::Substrate::new(36, "CFG", "Centrifuge"))), - constants::SYS => Some(Box::new(btc::BTC::new_btc_based("sys", "SYS", "Syscoin"))), - constants::KILT => Some(Box::new(substrate::Substrate::new(38, "KILT", "KILT"))), - constants::ALTAIR => Some(Box::new(substrate::Substrate::new(136, "ALTAIR", "Altair"))), - constants::DOGE => Some(Box::new(btc::BTC::new_legacy_btc_based( - 0x1E, "DOGE", "Dogecoin", - ))), - constants::DASH => Some(Box::new(btc::BTC::new_legacy_btc_based( - 0x4C, "DASH", "Dash", - ))), - constants::XRP => Some(Box::new(xrp::XRP::new())), - constants::DGB => Some(Box::new(btc::BTC::new_btc_based("dgb", "DGB", "Digibyte"))), - constants::COSMOS => Some(Box::new(atom::ATOM::new())), - constants::CELESTIA => Some(Box::new(atom::ATOM::new_cosmos_based( - "celestia", "celestia", "Celestia", "TIA", - ))), - constants::CUDOS => Some(Box::new(atom::ATOM::new_cosmos_based( - "cudos", "cudos-1", "Cudos", "CUDOS", - ))), - constants::AURA => Some(Box::new(atom::ATOM::new_cosmos_based( - "aura", "xstaxy-1", "Aura", "AURA", - ))), - constants::ICP => Some(Box::new(icp::ICP {})), - constants::SOL => Some(Box::new(sol::SOL {})), - constants::MOVR => Some(Box::new(movr::MOVR::new())), - constants::GLMR => Some(Box::new(movr::MOVR::new_glmr())), - constants::BNB => Some(Box::new(bnb::BNB {})), - constants::BCH => Some(Box::new(bch::BCH {})), - constants::ADA => Some(Box::new(ada::ADA {})), - constants::SUI => Some(Box::new(sui::SUI {})), - constants::APT => Some(Box::new(apt::APT {})), - constants::AVAIL => Some(Box::new(substrate::Substrate::new(42, "AVAIL", "Avail"))), - constants::ROLLUX => Some(Box::new(eth::ETH::new_eth_based(570, "ROLLUX", "Rollux"))), - constants::AVAX => Some(Box::new(eth::ETH::new_eth_based( - 43114, - "AVAX", - "Avalanche", - ))), - constants::ARB => Some(Box::new(eth::ETH::new_eth_based(42161, "ARB", "Arbitrum"))), - constants::BASE => Some(Box::new(eth::ETH::new_eth_based(8453, "BASE", "Base"))), - constants::NEAR => Some(Box::new(eth::ETH::new_eth_based(397, "NEAR", "Near"))), - constants::FTM => Some(Box::new(eth::ETH::new_eth_based(250, "FTM", "Fantom"))), - constants::CHZ => Some(Box::new(eth::ETH::new_eth_based(88888, "CHZ", "Chiliz"))), - constants::OP => Some(Box::new(eth::ETH::new_eth_based(10, "OP", "Optimism"))), - constants::POLYGON_ZKEVM => Some(Box::new(eth::ETH::new_eth_based( - 1101, - "ZKEVM", - "Polygon zkEVM", - ))), - constants::STOLZ => Some(Box::new(eth::ETH::new_eth_based(2344, "STOLZ", "Stolz"))), - _ => None, +type ChainFactory = fn() -> Box; + +struct ChainRegistry { + registry: &'static [(u32, ChainFactory)], +} + +impl ChainRegistry { + fn new() -> Self { + static REGISTRY: [(u32, ChainFactory); 46] = [ + (constants::ETH, || Box::new(eth::ETH::new())), + (constants::BSC, || { + Box::new(eth::ETH::new_eth_based(26, 56, "BSC", "BnbSmartChain")) + }), + (constants::POLYGON, || { + Box::new(eth::ETH::new_eth_based(28, 137, "MATIC", "Polygon")) + }), + (constants::HT, || { + Box::new(eth::ETH::new_eth_based(30, 128, "HT", "Huobi")) + }), + (constants::SYS_NEVM, || { + Box::new(eth::ETH::new_eth_based(37, 57, "SYS_NEVM", "Syscoin Nevm")) + }), + (constants::TRX, || Box::new(trx::TRX {})), + (constants::KLV, || Box::new(klv::KLV {})), + (constants::BTC, || Box::new(btc::BTC::new())), + (constants::DOT, || { + Box::new(substrate::Substrate::new(21, 0, "DOT", "Polkadot")) + }), + (constants::KSM, || { + Box::new(substrate::Substrate::new(27, 2, "KSM", "Kusama")) + }), + (constants::LTC, || { + Box::new(btc::BTC::new_btc_based("ltc", "LTC", "Litecoin")) + }), + (constants::REEF, || { + Box::new(substrate::Substrate::new(29, 42, "REEF", "Reef")) + }), + (constants::SDN, || { + Box::new(substrate::Substrate::new(35, 5, "SDN", "Shiden")) + }), + (constants::ASTR, || { + Box::new(substrate::Substrate::new(36, 5, "ASTR", "Astar")) + }), + (constants::CFG, || { + Box::new(substrate::Substrate::new(47, 36, "CFG", "Centrifuge")) + }), + (constants::SYS, || { + Box::new(btc::BTC::new_btc_based("sys", "SYS", "Syscoin")) + }), + (constants::KILT, || { + Box::new(substrate::Substrate::new(44, 38, "KILT", "KILT")) + }), + (constants::ALTAIR, || { + Box::new(substrate::Substrate::new(42, 136, "ALTAIR", "Altair")) + }), + (constants::DOGE, || { + Box::new(btc::BTC::new_legacy_btc_based(0x1E, "DOGE", "Dogecoin")) + }), + (constants::DASH, || { + Box::new(btc::BTC::new_legacy_btc_based(0x4C, "DASH", "Dash")) + }), + (constants::XRP, || Box::new(xrp::XRP::new())), + (constants::DGB, || { + Box::new(btc::BTC::new_btc_based("dgb", "DGB", "Digibyte")) + }), + (constants::COSMOS, || Box::new(atom::ATOM::new())), + (constants::CELESTIA, || { + Box::new(atom::ATOM::new_cosmos_based( + "celestia", "celestia", "Celestia", "TIA", + )) + }), + (constants::CUDOS, || { + Box::new(atom::ATOM::new_cosmos_based( + "cudos", "cudos-1", "Cudos", "CUDOS", + )) + }), + (constants::AURA, || { + Box::new(atom::ATOM::new_cosmos_based( + "aura", "xstaxy-1", "Aura", "AURA", + )) + }), + (constants::ICP, || Box::new(icp::ICP {})), + (constants::SOL, || Box::new(sol::SOL {})), + (constants::MOVR, || Box::new(movr::MOVR::new())), + (constants::GLMR, || Box::new(movr::MOVR::new_glmr())), + (constants::BNB, || Box::new(bnb::BNB {})), + (constants::BCH, || Box::new(bch::BCH {})), + (constants::ADA, || Box::new(ada::ADA {})), + (constants::SUI, || Box::new(sui::SUI {})), + (constants::APT, || Box::new(apt::APT {})), + (constants::AVAIL, || { + Box::new(substrate::Substrate::new(62, 42, "AVAIL", "Avail")) + }), + (constants::ROLLUX, || { + Box::new(eth::ETH::new_eth_based(63, 570, "ROLLUX", "Rollux")) + }), + (constants::AVAX, || { + Box::new(eth::ETH::new_eth_based(39, 43114, "AVAX", "Avalanche")) + }), + (constants::ARB, || { + Box::new(eth::ETH::new_eth_based(57, 42161, "ARB", "Arbitrum")) + }), + (constants::BASE, || { + Box::new(eth::ETH::new_eth_based(60, 8453, "BASE", "Base")) + }), + (constants::NEAR, || { + Box::new(eth::ETH::new_eth_based(64, 397, "NEAR", "Near")) + }), + (constants::FTM, || { + Box::new(eth::ETH::new_eth_based(54, 250, "FTM", "Fantom")) + }), + (constants::CHZ, || { + Box::new(eth::ETH::new_eth_based(61, 88888, "CHZ", "Chiliz")) + }), + (constants::OP, || { + Box::new(eth::ETH::new_eth_based(53, 10, "OP", "Optimism")) + }), + (constants::POLYGON_ZKEVM, || { + Box::new(eth::ETH::new_eth_based(52, 1101, "ZKEVM", "Polygon zkEVM")) + }), + (constants::STOLZ, || { + Box::new(eth::ETH::new_eth_based(67, 2344, "STOLZ", "Stolz")) + }), + ]; + + Self { + registry: ®ISTRY, + } + } + + fn get_chain_by_id(&self, id: u32) -> Option> { + for &(chain_id, factory) in self.registry { + if chain_id == id { + return Some(factory()); + } + } + None + } + + fn get_chain_by_base_id(&self, base_id: u32) -> Option> { + for &(_, factory) in self.registry { + let chain = factory(); + if chain.get_id() == base_id { + return Some(chain); + } + } + None } } +pub fn get_chain_by_id(id: u32) -> Option> { + ChainRegistry::new().get_chain_by_id(id) +} + pub enum CustomChainType { NotCustom(u32), CustomEth(u32), @@ -339,6 +416,7 @@ pub fn get_chain_by_params(params: CustomChainType) -> Option> { return match params { CustomChainType::NotCustom(c) => get_chain_by_id(c), CustomChainType::CustomEth(chaincode) => Some(Box::new(eth::ETH::new_eth_based( + 0, chaincode, format!("ETH {}", chaincode).as_str(), format!("Eth Based {}", chaincode).as_str(), @@ -347,3 +425,7 @@ pub fn get_chain_by_params(params: CustomChainType) -> Option> { CustomChainType::CustomCosmos(_) => None, }; } + +pub fn get_chain_by_base_id(base_id: u32) -> Option> { + ChainRegistry::new().get_chain_by_base_id(base_id) +} diff --git a/packages/kos/src/chains/movr/mod.rs b/packages/kos/src/chains/movr/mod.rs index 7ce903e..47cf9e1 100644 --- a/packages/kos/src/chains/movr/mod.rs +++ b/packages/kos/src/chains/movr/mod.rs @@ -123,4 +123,8 @@ impl Chain for MOVR { None => format!("m/44'/60'/0'/0/{}", index), // Verify this path } } + + fn get_id(&self) -> u32 { + 32 + } } diff --git a/packages/kos/src/chains/sol/mod.rs b/packages/kos/src/chains/sol/mod.rs index 53f0a9c..110caf5 100644 --- a/packages/kos/src/chains/sol/mod.rs +++ b/packages/kos/src/chains/sol/mod.rs @@ -10,6 +10,10 @@ use alloc::vec::Vec; pub struct SOL {} impl Chain for SOL { + fn get_id(&self) -> u32 { + 40 + } + fn get_name(&self) -> &str { "Solana" } diff --git a/packages/kos/src/chains/substrate/mod.rs b/packages/kos/src/chains/substrate/mod.rs index fae71c1..7047764 100644 --- a/packages/kos/src/chains/substrate/mod.rs +++ b/packages/kos/src/chains/substrate/mod.rs @@ -19,14 +19,16 @@ const IDENTIFIER_LOWER_PREFIX: u8 = 0x40; const SUBSTRATE_NETWORK_PREFIX: &str = "SS58PRE"; pub struct Substrate { + id: u32, network_id: u16, name: String, symbol: String, } impl Substrate { - pub fn new(network_id: u16, name: &str, symbol: &str) -> Self { + pub fn new(id: u32, network_id: u16, name: &str, symbol: &str) -> Self { Self { + id, network_id, name: name.to_string(), symbol: symbol.to_string(), @@ -35,6 +37,10 @@ impl Substrate { } impl Chain for Substrate { + fn get_id(&self) -> u32 { + self.id + } + fn get_name(&self) -> &str { self.name.as_str() } diff --git a/packages/kos/src/chains/sui/mod.rs b/packages/kos/src/chains/sui/mod.rs index 3c2f7bf..8fdcca1 100644 --- a/packages/kos/src/chains/sui/mod.rs +++ b/packages/kos/src/chains/sui/mod.rs @@ -10,6 +10,10 @@ use alloc::vec::Vec; pub struct SUI {} impl Chain for SUI { + fn get_id(&self) -> u32 { + 51 + } + fn get_name(&self) -> &str { "Sui" } diff --git a/packages/kos/src/chains/trx/mod.rs b/packages/kos/src/chains/trx/mod.rs index e0a38b4..d6dbf77 100644 --- a/packages/kos/src/chains/trx/mod.rs +++ b/packages/kos/src/chains/trx/mod.rs @@ -60,6 +60,10 @@ impl TRX { } impl Chain for TRX { + fn get_id(&self) -> u32 { + 1 + } + fn get_name(&self) -> &str { return "TRON"; } diff --git a/packages/kos/src/chains/xrp/mod.rs b/packages/kos/src/chains/xrp/mod.rs index eb69452..f39ef35 100644 --- a/packages/kos/src/chains/xrp/mod.rs +++ b/packages/kos/src/chains/xrp/mod.rs @@ -19,6 +19,10 @@ impl XRP { } impl Chain for XRP { + fn get_id(&self) -> u32 { + 4 + } + fn get_name(&self) -> &str { "Ripple" } From 521e9efe62dd2f4bb70652f186c7c306261cf18b Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Tue, 12 Nov 2024 10:06:01 -0300 Subject: [PATCH 10/42] feat: add cipher decrypt --- Cargo.lock | 1071 +++++++++++++++++++++++++++- Cargo.toml | 7 +- packages/kos-crypto/Cargo.toml | 33 + packages/kos-crypto/src/blake2b.rs | 218 ++++++ packages/kos-crypto/src/cipher.rs | 355 +++++++++ packages/kos-crypto/src/hash.rs | 31 + packages/kos-crypto/src/lib.rs | 3 + packages/kos-mobile/Cargo.toml | 2 + packages/kos-mobile/src/lib.rs | 22 +- packages/kos-types/Cargo.toml | 30 + packages/kos-types/src/error.rs | 157 ++++ packages/kos-types/src/lib.rs | 1 + 12 files changed, 1906 insertions(+), 24 deletions(-) create mode 100644 packages/kos-crypto/Cargo.toml create mode 100644 packages/kos-crypto/src/blake2b.rs create mode 100644 packages/kos-crypto/src/cipher.rs create mode 100644 packages/kos-crypto/src/hash.rs create mode 100644 packages/kos-crypto/src/lib.rs create mode 100644 packages/kos-types/Cargo.toml create mode 100644 packages/kos-types/src/error.rs create mode 100644 packages/kos-types/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 3a244f7..082a923 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,56 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array", +] + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "aes-gcm" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "ghash", + "subtle", +] + [[package]] name = "aho-corasick" version = "1.1.3" @@ -125,6 +175,21 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +[[package]] +name = "backtrace" +version = "0.3.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "base16ct" version = "0.2.0" @@ -143,6 +208,12 @@ version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "base64ct" version = "1.6.0" @@ -182,6 +253,21 @@ dependencies = [ "cryptoxide", ] +[[package]] +name = "bitcoin-private" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73290177011694f38ec25e165d0387ab7ea749a4b81cd4c80dae5988229f7a57" + +[[package]] +name = "bitcoin_hashes" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d7066118b13d4b20b23645932dfb3a81ce7e29f95726c2036fa33cd7b092501" +dependencies = [ + "bitcoin-private", +] + [[package]] name = "bitflags" version = "2.5.0" @@ -224,6 +310,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-padding" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" +dependencies = [ + "generic-array", +] + [[package]] name = "bs58" version = "0.5.1" @@ -234,6 +329,12 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + [[package]] name = "byte-slice-cast" version = "1.2.2" @@ -284,6 +385,33 @@ dependencies = [ "thiserror", ] +[[package]] +name = "cbc" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" +dependencies = [ + "cipher", +] + +[[package]] +name = "cc" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aeb932158bd710538c73702db6945cb68a8fb08c519e6e12706b94263b36db8" +dependencies = [ + "shlex", +] + +[[package]] +name = "cfb-mode" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "738b8d467867f80a71351933f70461f5b56f24d5c93e0cf216e59229c968d330" +dependencies = [ + "cipher", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -300,6 +428,16 @@ dependencies = [ "serde", ] +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + [[package]] name = "clap" version = "4.5.16" @@ -438,6 +576,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", + "rand_core", "typenum", ] @@ -457,6 +596,15 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "382ce8820a5bb815055d3553a610e8cb542b2d767bbacea99038afda96cd760d" +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + [[package]] name = "curve25519-dalek" version = "4.1.3" @@ -515,6 +663,17 @@ dependencies = [ "subtle", ] +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "ecdsa" version = "0.16.9" @@ -535,6 +694,8 @@ version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" dependencies = [ + "pkcs8", + "serde", "signature", ] @@ -546,8 +707,10 @@ checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" dependencies = [ "curve25519-dalek", "ed25519", + "serde", "sha2 0.10.8", "subtle", + "zeroize", ] [[package]] @@ -629,6 +792,21 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + [[package]] name = "fs-err" version = "2.11.0" @@ -644,6 +822,39 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "pin-utils", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -675,6 +886,22 @@ dependencies = [ "rand_core", ] +[[package]] +name = "ghash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" +dependencies = [ + "opaque-debug", + "polyval", +] + +[[package]] +name = "gimli" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" + [[package]] name = "glob" version = "0.3.1" @@ -721,6 +948,12 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + [[package]] name = "hex" version = "0.4.3" @@ -757,6 +990,223 @@ dependencies = [ "hmac 0.8.1", ] +[[package]] +name = "http" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +dependencies = [ + "bytes", + "futures-util", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" + +[[package]] +name = "hyper" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbbff0a806a4728c99295b254c8838933b5b082d75e3cb70c8dab21fdfbcfa9a" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-util" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", +] + +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "idna" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + [[package]] name = "impl-trait-for-tuples" version = "0.2.2" @@ -778,12 +1228,28 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "block-padding", + "generic-array", +] + [[package]] name = "inventory" version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f958d3d68f4167080a18141e10381e7634563984a537f2a49a30fd8e53ac5767" +[[package]] +name = "ipnet" +version = "2.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" + [[package]] name = "is_terminal_polyfill" version = "1.70.1" @@ -805,6 +1271,15 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +[[package]] +name = "js-sys" +version = "0.3.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" +dependencies = [ + "wasm-bindgen", +] + [[package]] name = "k256" version = "0.13.4" @@ -860,17 +1335,66 @@ dependencies = [ "tiny-json-rs", ] +[[package]] +name = "kos-crypto" +version = "0.1.2" +dependencies = [ + "aes", + "aes-gcm", + "base64 0.21.7", + "cbc", + "cfb-mode", + "coins-bip32", + "coins-bip39", + "ed25519-dalek", + "hex", + "hmac 0.12.1", + "kos-types", + "log", + "pbkdf2", + "pem", + "rand", + "secp256k1", + "serde", + "sha1", + "sha2 0.10.8", + "sha3", + "wasm-bindgen", + "zeroize", +] + [[package]] name = "kos-mobile" version = "0.1.2" dependencies = [ "hex", "kos", + "kos-crypto", + "kos-types", "lazy_static", "thiserror", "uniffi", ] +[[package]] +name = "kos-types" +version = "0.1.2" +dependencies = [ + "coins-bip32", + "coins-bip39", + "ed25519-dalek", + "hex", + "log", + "num-bigint", + "num-traits", + "rand", + "reqwest", + "secp256k1", + "serde", + "serde_json", + "wasm-bindgen", +] + [[package]] name = "kos-web" version = "0.1.2" @@ -944,6 +1468,12 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +[[package]] +name = "litemap" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" + [[package]] name = "log" version = "0.4.21" @@ -990,6 +1520,27 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" +[[package]] +name = "miniz_oxide" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +dependencies = [ + "hermit-abi", + "libc", + "wasi", + "windows-sys", +] + [[package]] name = "multimap" version = "0.10.0" @@ -1006,6 +1557,25 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -1015,6 +1585,15 @@ dependencies = [ "autocfg", ] +[[package]] +name = "object" +version = "0.36.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.19.0" @@ -1080,6 +1659,22 @@ dependencies = [ "sha2 0.10.8", ] +[[package]] +name = "pem" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658fae" +dependencies = [ + "base64 0.22.1", + "serde", +] + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + [[package]] name = "petgraph" version = "0.6.5" @@ -1090,6 +1685,18 @@ dependencies = [ "indexmap", ] +[[package]] +name = "pin-project-lite" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + [[package]] name = "pkcs8" version = "0.10.2" @@ -1106,6 +1713,18 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" +[[package]] +name = "polyval" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + [[package]] name = "ppv-lite86" version = "0.2.20" @@ -1316,6 +1935,41 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" +[[package]] +name = "reqwest" +version = "0.12.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a77c62af46e79de0a562e1a9849205ffcb7fc1238876e9bd743357570e04046f" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-core", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-util", + "ipnet", + "js-sys", + "log", + "mime", + "once_cell", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "windows-registry", +] + [[package]] name = "rfc6979" version = "0.4.0" @@ -1345,6 +1999,12 @@ dependencies = [ "rustc-hex", ] +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + [[package]] name = "rustc-hex" version = "2.1.0" @@ -1430,6 +2090,27 @@ dependencies = [ "zeroize", ] +[[package]] +name = "secp256k1" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25996b82292a7a57ed3508f052cfff8640d38d32018784acd714758b43da9c8f" +dependencies = [ + "bitcoin_hashes", + "rand", + "secp256k1-sys", + "serde", +] + +[[package]] +name = "secp256k1-sys" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70a129b9e9efbfb223753b9163c4ab3b13cff7fd9c7f010fbac25ab4099fa07e" +dependencies = [ + "cc", +] + [[package]] name = "semver" version = "1.0.23" @@ -1470,6 +2151,29 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + [[package]] name = "sha2" version = "0.9.9" @@ -1504,6 +2208,12 @@ dependencies = [ "keccak", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "signature" version = "2.2.0" @@ -1520,12 +2230,28 @@ version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + [[package]] name = "smawk" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" +[[package]] +name = "socket2" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +dependencies = [ + "libc", + "windows-sys", +] + [[package]] name = "spki" version = "0.7.3" @@ -1536,6 +2262,12 @@ dependencies = [ "der", ] +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "static_assertions" version = "1.1.0" @@ -1576,6 +2308,26 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" +dependencies = [ + "futures-core", +] + +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "tap" version = "1.0.1" @@ -1643,6 +2395,16 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "tinystr" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", +] + [[package]] name = "tinyvec" version = "1.8.0" @@ -1658,6 +2420,20 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +[[package]] +name = "tokio" +version = "1.41.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33" +dependencies = [ + "backtrace", + "libc", + "mio", + "pin-project-lite", + "socket2", + "windows-sys", +] + [[package]] name = "toml" version = "0.5.11" @@ -1684,6 +2460,37 @@ dependencies = [ "winnow", ] +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + [[package]] name = "typeid" version = "1.0.0" @@ -1866,6 +2673,39 @@ dependencies = [ "weedle2", ] +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] + +[[package]] +name = "url" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d157f1b96d14500ffdc1f10ba712e780825526c03d9a49b4d0324b0d9113ada" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "utf8parse" version = "0.2.2" @@ -1878,12 +2718,98 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasm-bindgen" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" +dependencies = [ + "cfg-if", + "once_cell", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.66", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" + +[[package]] +name = "web-sys" +version = "0.3.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "weedle2" version = "5.0.0" @@ -1893,6 +2819,36 @@ dependencies = [ "nom", ] +[[package]] +name = "windows-registry" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" +dependencies = [ + "windows-result", + "windows-strings", + "windows-targets", +] + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result", + "windows-targets", +] + [[package]] name = "windows-sys" version = "0.52.0" @@ -1904,9 +2860,9 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", @@ -1920,51 +2876,51 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" @@ -1975,6 +2931,18 @@ dependencies = [ "memchr", ] +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + [[package]] name = "wyz" version = "0.5.1" @@ -1984,6 +2952,30 @@ dependencies = [ "tap", ] +[[package]] +name = "yoke" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", + "synstructure", +] + [[package]] name = "zerocopy" version = "0.7.35" @@ -2005,6 +2997,27 @@ dependencies = [ "syn 2.0.66", ] +[[package]] +name = "zerofrom" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", + "synstructure", +] + [[package]] name = "zeroize" version = "1.8.1" @@ -2024,3 +3037,25 @@ dependencies = [ "quote", "syn 2.0.66", ] + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] diff --git a/Cargo.toml b/Cargo.toml index 49fc44a..cd5bcd6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,8 +2,8 @@ # https://doc.rust-lang.org/edition-guide/rust-2021/default-cargo-resolver.html#details resolver = "2" members = [ - "packages/kos", - "packages/kos-mobile", "packages/kos-web", + "packages/kos", "packages/kos-crypto", + "packages/kos-mobile", "packages/kos-types", "packages/kos-web", ] # This makes the compiled code faster and smaller, but it makes compiling slower, # so it's only enabled in release mode. @@ -52,3 +52,6 @@ lazy_static = "1.4.0" thiserror = "1.0" kos = { version = "0.1.0", path = "./packages/kos", default-features = false } +kos-crypto = { version = "0.1.0", path = "./packages/kos-crypto", default-features = false } +kos-mobile = { version = "0.1.0", path = "./packages/kos-mobile", default-features = false } +kos-types = { version = "0.1.0", path = "./packages/kos-types", default-features = false } diff --git a/packages/kos-crypto/Cargo.toml b/packages/kos-crypto/Cargo.toml new file mode 100644 index 0000000..86fdaff --- /dev/null +++ b/packages/kos-crypto/Cargo.toml @@ -0,0 +1,33 @@ +[package] +name = "kos-crypto" +version = { workspace = true } +authors = { workspace = true } +edition = { workspace = true } +homepage = { workspace = true } +license = { workspace = true } +repository = { workspace = true } +rust-version = { workspace = true } + +[dependencies] +kos-types = { workspace = true, features = ["serde"] } +serde = { workspace = true, features = ["derive"] } +log = { workspace = true } +wasm-bindgen = { workspace = true } +rand = { workspace = true } +zeroize = { workspace = true } +coins-bip32 = { workspace = true } +coins-bip39 = { workspace = true } +hex = { workspace = true } +sha1 = "0.10" +sha2 = { workspace = true } +sha3 = { workspace = true } +hmac = { workspace = true } +secp256k1 = { workspace = true, features = ["rand", "serde", "bitcoin_hashes"] } +ed25519-dalek = { workspace = true, features = ["serde"] } +aes-gcm = "0.10" +aes = { version = "0.8" } +cfb-mode = "0.8" +cbc = { version = "0.1", features = ["block-padding", "std"] } +pem = "3" +pbkdf2 = { version = "0.12", features = ["simple"] } +base64 = "0.21" \ No newline at end of file diff --git a/packages/kos-crypto/src/blake2b.rs b/packages/kos-crypto/src/blake2b.rs new file mode 100644 index 0000000..2bdbbe8 --- /dev/null +++ b/packages/kos-crypto/src/blake2b.rs @@ -0,0 +1,218 @@ +pub const BLOCK_BYTES: usize = 128; +pub const KEY_BYTES: usize = 64; +pub const OUT_BYTES: usize = 64; + +#[rustfmt::skip] +static IV : [u64; 8] = [ + 0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1, + 0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179, +]; + +#[rustfmt::skip] +static SIGMA : [[u8; 16]; 12] = [ + [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ], + [ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 ], + [ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 ], + [ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 ], + [ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 ], + [ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 ], + [ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 ], + [ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 ], + [ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 ], + [ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 ], + [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ], + [ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 ], +]; + +pub struct Blake2b { + h: [u64; 8], + t: [u64; 2], + f: [u64; 2], + buf: [u8; 2 * BLOCK_BYTES], + buf_len: usize, + output_len: usize, +} + +impl Copy for Blake2b {} +impl Clone for Blake2b { + fn clone(&self) -> Blake2b { + *self + } +} + +impl Blake2b { + pub fn new(size: usize) -> Blake2b { + assert!(size > 0 && size <= OUT_BYTES); + + let param = encode_params(size as u8, 0); + let mut state = IV; + + for i in 0..state.len() { + state[i] ^= load64(¶m[i * 8..]); + } + + Blake2b { + h: state, + t: [0, 0], + f: [0, 0], + buf: [0u8; 2 * BLOCK_BYTES], + buf_len: 0, + output_len: size, + } + } + + pub fn new_with_key(size: usize, key: &[u8]) -> Blake2b { + assert!(size > 0 && size <= OUT_BYTES); + assert!(!key.is_empty() && key.len() <= KEY_BYTES); + + let param = encode_params(size as u8, key.len() as u8); + let mut state = IV; + + for i in 0..state.len() { + println!("i2: {} ", i); + state[i] ^= load64(¶m[i * 8..]); + } + + let mut b = Blake2b { + h: state, + t: [0, 0], + f: [0, 0], + buf: [0u8; 2 * BLOCK_BYTES], + buf_len: 0, + output_len: size, + }; + + let mut block = [0u8; BLOCK_BYTES]; + block[..key.len()].copy_from_slice(key); + b.update(block.as_ref()); + b + } + + pub fn update(&mut self, m: &[u8]) { + let mut m = m; + + while !m.is_empty() { + let left = self.buf_len; + let fill = 2 * BLOCK_BYTES - left; + + if m.len() > fill { + self.buf[left..(fill + left)].copy_from_slice(&m[..fill]); + self.buf_len += fill; + m = &m[fill..]; + self.increment_counter(BLOCK_BYTES as u64); + self.compress(); + for i in 0..BLOCK_BYTES { + self.buf[i] = self.buf[i + BLOCK_BYTES]; + } + self.buf_len -= BLOCK_BYTES; + } else { + self.buf[left..(m.len() + left)].copy_from_slice(m); + self.buf_len += m.len(); + m = &m[m.len()..]; + } + } + } + + pub fn finalize(&mut self) -> Vec { + let mut buf = [0u8; OUT_BYTES]; + if self.buf_len > BLOCK_BYTES { + self.increment_counter(BLOCK_BYTES as u64); + self.compress(); + for i in 0..BLOCK_BYTES { + self.buf[i] = self.buf[i + BLOCK_BYTES]; + } + self.buf_len -= BLOCK_BYTES; + } + let n = self.buf_len as u64; + self.increment_counter(n); + self.f[0] = !0; + for i in self.buf_len..self.buf.len() { + self.buf[i] = 0; + } + self.compress(); + for i in 0..self.h.len() { + store64(&mut buf[i * 8..], self.h[i]); + } + + buf[..self.output_len].to_vec() + } + + fn increment_counter(&mut self, inc: u64) { + self.t[0] += inc; + self.t[1] += if self.t[0] < inc { 1 } else { 0 }; + } + + fn compress(&mut self) { + let mut m = [0u64; 16]; + let mut v = [0u64; 16]; + let block = self.buf.as_ref(); + + assert!(block.len() >= BLOCK_BYTES); + + for i in 0..m.len() { + m[i] = load64(&block[i * 8..]); + } + + v[..8].copy_from_slice(&self.h[..8]); + + v[8] = IV[0]; + v[9] = IV[1]; + v[10] = IV[2]; + v[11] = IV[3]; + v[12] = self.t[0] ^ IV[4]; + v[13] = self.t[1] ^ IV[5]; + v[14] = self.f[0] ^ IV[6]; + v[15] = self.f[1] ^ IV[7]; + + macro_rules! g( + ($r: expr, $i: expr, $a: expr, $b: expr, $c: expr, $d: expr) => ({ + $a = $a.wrapping_add($b).wrapping_add(m[SIGMA[$r][2*$i+0] as usize]); + $d = ($d ^ $a).rotate_right(32); + $c = $c.wrapping_add($d); + $b = ($b ^ $c).rotate_right(24); + $a = $a.wrapping_add($b).wrapping_add(m[SIGMA[$r][2*$i+1] as usize]); + $d = ($d ^ $a).rotate_right(16); + $c = $c.wrapping_add($d); + $b = ($b ^ $c).rotate_right(63); + }); + ); + + macro_rules! round( + ($r: expr) => ({ + g!($r, 0, v[ 0], v[ 4], v[ 8], v[12]); + g!($r, 1, v[ 1], v[ 5], v[ 9], v[13]); + g!($r, 2, v[ 2], v[ 6], v[10], v[14]); + g!($r, 3, v[ 3], v[ 7], v[11], v[15]); + g!($r, 4, v[ 0], v[ 5], v[10], v[15]); + g!($r, 5, v[ 1], v[ 6], v[11], v[12]); + g!($r, 6, v[ 2], v[ 7], v[ 8], v[13]); + g!($r, 7, v[ 3], v[ 4], v[ 9], v[14]); + }); + ); + + for i in 0..12 { + round!(i); + } + + for i in 0..8 { + self.h[i] = self.h[i] ^ v[i] ^ v[i + 8] + } + } +} + +fn encode_params(size: u8, key_len: u8) -> [u8; 64] { + let mut param = [0u8; 64]; + param[0] = size; + param[1] = key_len; + param[2] = 1; // fanout + param[3] = 1; // depth + param +} + +fn load64(b: &[u8]) -> u64 { + u64::from_le_bytes(b[..8].try_into().expect("slice with incorrect length")) +} + +fn store64(b: &mut [u8], v: u64) { + b[..8].copy_from_slice(&v.to_le_bytes()); +} diff --git a/packages/kos-crypto/src/cipher.rs b/packages/kos-crypto/src/cipher.rs new file mode 100644 index 0000000..b40f44e --- /dev/null +++ b/packages/kos-crypto/src/cipher.rs @@ -0,0 +1,355 @@ +use base64::{engine::general_purpose as b64_engine, Engine}; +use kos_types::error::Error; + +use aes::cipher::{ + block_padding::Pkcs7, generic_array::GenericArray, AsyncStreamCipher, BlockDecryptMut, + BlockEncryptMut, KeyIvInit, +}; +use aes_gcm::{ + aead::{Aead, AeadCore, KeyInit as GCMKeyInit, OsRng}, + Aes256Gcm, + Key, // Or `Aes128Gcm` + Nonce, +}; + +use hmac::Hmac; +use pbkdf2::pbkdf2; +use pbkdf2::{ + password_hash::{PasswordHash, PasswordHasher, SaltString}, + Pbkdf2, +}; +use pem::{parse as parse_pem, Pem}; +use rand::Rng; +use sha2::Sha256; + +use wasm_bindgen::prelude::*; + +const KEY_SIZE: usize = 32; // SALTSIZE +const NONCE_SIZE: usize = 12; // NONCESIZE +const IV_SIZE: usize = 16; // IVSIZE +const BLOCK_SIZE: usize = 16; // BLOCKSIZE + +const ITERATIONS: u32 = 10000; + +#[derive(Debug, Clone)] +#[wasm_bindgen] +pub enum CipherAlgo { + GMC = 0, + CBC = 1, + CFB = 2, +} +// todo!("build with macro") +impl CipherAlgo { + pub fn to_vec(&self) -> Vec { + match self { + CipherAlgo::GMC => vec![0], + CipherAlgo::CBC => vec![1], + CipherAlgo::CFB => vec![2], + } + } + + pub fn from_u8(value: u8) -> Result { + match value { + 0 => Ok(CipherAlgo::GMC), + 1 => Ok(CipherAlgo::CBC), + 2 => Ok(CipherAlgo::CFB), + _ => Err(Error::CipherError("Invalid cipher algorithm".to_owned())), + } + } + + pub fn encrypt(&self, data: &[u8], password: &str) -> Result, Error> { + match self { + CipherAlgo::GMC => gcm_encrypt(data, password), + CipherAlgo::CBC => cbc_encrypt(data, password), + CipherAlgo::CFB => cfb_encrypt(data, password), + } + } + + pub fn decrypt(&self, data: &[u8], password: &str) -> Result, Error> { + match self { + CipherAlgo::GMC => gcm_decrypt(data, password), + CipherAlgo::CBC => cbc_decrypt(data, password), + CipherAlgo::CFB => cfb_decrypt(data, password), + } + } +} + +pub fn to_pem(tag: String, data: &[u8]) -> Result { + Ok(Pem::new(tag, data)) +} + +pub fn from_pem(pem: Pem) -> Vec { + pem.contents().to_vec() +} + +pub fn string_to_pem(data: &str) -> Result { + parse_pem(data.as_bytes()).map_err(|e| Error::CipherError(format!("{}", e))) +} + +pub fn create_checksum(password: &str) -> String { + let rng = rand::thread_rng(); + let salt = SaltString::generate(rng); + let password_hash = pbkdf2::Pbkdf2 + .hash_password(password.as_bytes(), &salt) + .unwrap(); + + password_hash.to_string() +} + +pub fn check_checksum(password: &str, checksum: String) -> bool { + let parsed_hash = PasswordHash::new(&checksum).unwrap(); + let result = parsed_hash.verify_password(&[&Pbkdf2], password); + + result.is_ok() +} + +pub fn derive_key(salt: &[u8], password: &str) -> Vec { + let mut key = vec![0u8; KEY_SIZE]; + pbkdf2::>(password.as_bytes(), salt, ITERATIONS, &mut key) + .expect("Error deriving key"); + key +} + +pub fn encrypt(algo: CipherAlgo, data: &[u8], password: &str) -> Result, Error> { + algo.encrypt(data, password) +} + +pub fn decrypt(data: &[u8], password: &str) -> Result, Error> { + if data.is_empty() { + return Err(Error::CipherError("Invalid PEM data".to_owned())); + } + + // get algo + let algo = CipherAlgo::from_u8(data[0])?; + algo.decrypt(&data[1..], password) +} + +pub fn gcm_encrypt(data: &[u8], password: &str) -> Result, Error> { + // Derive key from password + let salt: [u8; 32] = rand::thread_rng().gen(); + let derived_key = derive_key(&salt, password); + let key = Key::::from_slice(&derived_key); + let cipher = Aes256Gcm::new(key); + + // Generate a unique nonce + let nonce = Aes256Gcm::generate_nonce(&mut OsRng); + + // Encrypt data + let ciphertext = cipher + .encrypt(&nonce, data) + .map_err(|e| Error::CipherError(format!("encryption failed: {}", e)))?; + + // Create PEM + let mut result = CipherAlgo::GMC.to_vec(); + result.extend_from_slice(&salt); + result.extend_from_slice(&nonce); + result.extend_from_slice(&ciphertext); + + Ok(result) +} + +pub fn gcm_decrypt(encrypted: &[u8], password: &str) -> Result, Error> { + if encrypted.len() < KEY_SIZE + NONCE_SIZE { + return Err(Error::CipherError("Invalid PEM data".to_owned())); + } + let salt = &encrypted[..KEY_SIZE]; + let nonce = &encrypted[KEY_SIZE..KEY_SIZE + NONCE_SIZE]; + let encrypted_data = &encrypted[KEY_SIZE + NONCE_SIZE..]; + let derived_key = derive_key(salt, password); + let key = Key::::from_slice(&derived_key); + let cipher = Aes256Gcm::new(key); + cipher + .decrypt(Nonce::from_slice(nonce), encrypted_data) + .map_err(|e| Error::CipherError(format!("decryption failed: {}", e))) +} + +type Aes256CbcEnc = cbc::Encryptor; +type Aes256CbcDec = cbc::Decryptor; +pub fn cbc_encrypt(data: &[u8], password: &str) -> Result, Error> { + let iv: [u8; IV_SIZE] = rand::thread_rng().gen(); + let derived_key = derive_key(&iv, password); // KeySize [u8; 32] + let key = GenericArray::from_slice(&derived_key); + + let padding_size = BLOCK_SIZE - data.len() % BLOCK_SIZE; + let buf_len = data.len() + padding_size; + + let mut buf = vec![0; buf_len]; + + buf[..data.len()].copy_from_slice(data); + + let ct = Aes256CbcEnc::new(key, &iv.into()) + .encrypt_padded_mut::(&mut buf, data.len()) + .map_err(|e| Error::CipherError(format!("encryption failed: {}", e)))?; + + // Create PEM + let mut result = CipherAlgo::CBC.to_vec(); + result.extend_from_slice(&iv); + result.extend_from_slice(ct); + + Ok(result) +} + +pub fn cbc_decrypt(encrypted: &[u8], password: &str) -> Result, Error> { + if encrypted.len() < IV_SIZE { + return Err(Error::CipherError("Invalid PEM data".to_owned())); + } + + let iv = GenericArray::from_slice(&encrypted[..IV_SIZE]); + let encrypted_data = &encrypted[IV_SIZE..]; + let derived_key = derive_key(iv, password); + let key = GenericArray::from_slice(&derived_key); + + let mut buf = encrypted_data.to_vec(); + let pt: &[u8] = Aes256CbcDec::new(key, iv) + .decrypt_padded_mut::(&mut buf) + .map_err(|e| Error::CipherError(format!("decryption failed: {}", e)))?; + + Ok(pt.to_vec()) +} + +type Aes256CfbEnc = cfb_mode::Encryptor; +type Aes256CfbDec = cfb_mode::Decryptor; +pub fn cfb_encrypt(data: &[u8], password: &str) -> Result, Error> { + let iv: [u8; IV_SIZE] = rand::thread_rng().gen(); + let derived_key = derive_key(&iv, password); // KeySize [u8; 32] + let key = GenericArray::from_slice(&derived_key); + + let mut buf = data.to_vec(); + Aes256CfbEnc::new(key, &iv.into()).encrypt(&mut buf); + + // Create PEM + let mut result = CipherAlgo::CFB.to_vec(); + result.extend_from_slice(&iv); + result.extend_from_slice(&buf); + + Ok(result) +} + +pub fn cfb_decrypt(encrypted: &[u8], password: &str) -> Result, Error> { + if encrypted.len() < IV_SIZE { + return Err(Error::CipherError("Invalid PEM data".to_owned())); + } + + let iv = GenericArray::from_slice(&encrypted[..IV_SIZE]); + let encrypted_data = &encrypted[IV_SIZE..]; + let derived_key = derive_key(iv, password); + let key = GenericArray::from_slice(&derived_key); + + let mut buf = encrypted_data.to_vec(); + Aes256CfbDec::new(key, iv).decrypt(&mut buf); + + Ok(buf) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_encrypt_decrypt() { + for algo in vec![CipherAlgo::GMC, CipherAlgo::CBC, CipherAlgo::CFB] { + let data = b"hello world"; + let password = "password"; + + let encrypted = encrypt(algo.to_owned(), data, password).unwrap(); + let decrypted = decrypt(&encrypted, password).unwrap(); + assert_eq!(data, decrypted.as_slice()); + } + } + + #[test] + fn test_encrypt_decrypt_invalid_password() { + for algo in vec![CipherAlgo::GMC, CipherAlgo::CBC, CipherAlgo::CFB] { + let data = b"hello world"; + let password = "password"; + + let encrypted = encrypt(algo, data, password).unwrap(); + let decrypted = decrypt(&encrypted, "invalid password"); + match decrypted { + Ok(decrypted) => { + assert_ne!(data, decrypted.as_slice()); + } + _ => {} + } + } + } + + #[test] + fn test_encrypt_decrypt_invalid_data() { + for algo in vec![CipherAlgo::GMC, CipherAlgo::CBC, CipherAlgo::CFB] { + let data = b"hello world"; + let password = "password"; + + let encrypted = encrypt(algo.clone(), data, password).unwrap(); + let decrypted = decrypt(&encrypted[..encrypted.len() - 1], password); + match decrypted { + Ok(decrypted) => { + assert_ne!(data, decrypted.as_slice()); + } + _ => {} + } + } + } + + #[test] + fn test_to_pem() { + let data = b"hello world"; + let tag = "TEST"; + let pem = to_pem(tag.to_owned(), data).unwrap(); + assert_eq!(pem.tag(), tag); + assert_eq!(pem.contents(), data); + } + + #[test] + fn test_from_pem() { + let data = b"hello world"; + let tag = "TEST"; + let pem = to_pem(tag.to_owned(), data).unwrap(); + let pem_data = from_pem(pem); + assert_eq!(pem_data, data); + } + + #[test] + fn test_create_checksum() { + let password = "password"; + let checksum = create_checksum(password); + assert!(check_checksum(password, checksum)); + } +} + +/* + LEGACY GCM DECRYPT SHA1 KEY no SALT +*/ +use sha1::Sha1; +#[wasm_bindgen(js_name = gcmDecryptByKey)] +pub fn gcm_decrypt_by_key(encrypted: &str, key: &str) -> Result, Error> { + if encrypted.len() < NONCE_SIZE { + return Err(Error::CipherError("invalid data len".to_owned())); + } + + // convert hex to bytes + let encrypted = hex::decode(encrypted) + .map_err(|e| Error::CipherError(format!("decryption failed: {}", e)))?; + + let b64 = b64_engine::STANDARD; + // convert base64 to bytes + let key = b64 + .decode(key) + .map_err(|e| Error::CipherError(format!("decryption failed: {}", e)))?; + + // compute encrypt key + let salt = crate::hash::sha256("".as_bytes()); + let key_hash = crate::hash::sha256(&key[..]); + let mut key = vec![0u8; KEY_SIZE]; + pbkdf2::>(&key_hash, &salt, 4096, &mut key).expect("Error deriving key"); + + // retrieve nonce and encrypted data + let nonce = &encrypted[..NONCE_SIZE]; + let encrypted_data = &encrypted[NONCE_SIZE..]; + + let key = Key::::from_slice(&key); + let cipher = Aes256Gcm::new(key); + cipher + .decrypt(Nonce::from_slice(nonce), encrypted_data) + .map_err(|e| Error::CipherError(format!("decryption failed: {}", e))) +} diff --git a/packages/kos-crypto/src/hash.rs b/packages/kos-crypto/src/hash.rs new file mode 100644 index 0000000..4f513fa --- /dev/null +++ b/packages/kos-crypto/src/hash.rs @@ -0,0 +1,31 @@ +use crate::blake2b::Blake2b; +use sha2::{Digest, Sha256, Sha512}; +use sha3::Keccak256; + +#[inline] +pub fn sha256(input: &[u8]) -> [u8; 32] { + let mut hasher = Sha256::new(); + hasher.update(input); + hasher.finalize().into() +} + +#[inline] +pub fn keccak256(input: &[u8]) -> [u8; 32] { + let mut hasher = Keccak256::new(); + hasher.update(input); + hasher.finalize().into() +} + +#[inline] +pub fn blake2b256(input: &[u8]) -> [u8; 32] { + let mut hasher = Blake2b::new(32); + hasher.update(input); + hasher.finalize().try_into().unwrap() +} + +#[inline] +pub fn sha512(input: &[u8]) -> [u8; 64] { + let mut hasher = Sha512::new(); + hasher.update(input); + hasher.finalize().into() +} diff --git a/packages/kos-crypto/src/lib.rs b/packages/kos-crypto/src/lib.rs new file mode 100644 index 0000000..91697c5 --- /dev/null +++ b/packages/kos-crypto/src/lib.rs @@ -0,0 +1,3 @@ +mod blake2b; +pub mod cipher; +pub mod hash; diff --git a/packages/kos-mobile/Cargo.toml b/packages/kos-mobile/Cargo.toml index 621163e..5cc049d 100644 --- a/packages/kos-mobile/Cargo.toml +++ b/packages/kos-mobile/Cargo.toml @@ -16,6 +16,8 @@ name = "uniffi-bindgen" path = "src/bin/uniffi-bindgen.rs" [dependencies] +kos-crypto = { workspace = true } +kos-types = { workspace = true, features = ["serde"] } kos = { workspace = true } hex = { workspace = true } diff --git a/packages/kos-mobile/src/lib.rs b/packages/kos-mobile/src/lib.rs index edd7bfb..18cd61a 100644 --- a/packages/kos-mobile/src/lib.rs +++ b/packages/kos-mobile/src/lib.rs @@ -1,6 +1,9 @@ use hex::FromHexError; use hex::ToHex; use kos::chains::{get_chain_by_base_id, get_chain_by_id, Chain, ChainError, Transaction}; +use kos_crypto::cipher; +use kos_crypto::cipher::CipherAlgo; +use kos_types::error::Error as KosError; uniffi::setup_scaffolding!(); @@ -26,6 +29,12 @@ impl From for KOSError { } } +impl From for KOSError { + fn from(err: KosError) -> Self { + KOSError::KOSDelegate(err.to_string()) + } +} + #[derive(uniffi::Record)] struct KOSAccount { pub chain_id: i32, @@ -99,22 +108,27 @@ fn generate_wallet_from_private_key( #[uniffi::export] fn encrypt_with_gmc(data: String, password: String) -> Result { - todo!() + let encrypted_data = CipherAlgo::GMC.encrypt(data.as_bytes(), password.as_str())?; + Ok(encrypted_data.encode_hex()) } #[uniffi::export] fn encrypt_with_cbc(data: String, password: String) -> Result { - todo!() + let encrypted_data = CipherAlgo::CBC.encrypt(data.as_bytes(), password.as_str())?; + Ok(encrypted_data.encode_hex()) } #[uniffi::export] fn encrypt_with_cfb(data: String, password: String) -> Result { - todo!() + let encrypted_data = CipherAlgo::CFB.encrypt(data.as_bytes(), password.as_str())?; + Ok(encrypted_data.encode_hex()) } #[uniffi::export] fn decrypt(data: String, password: String) -> Result { - todo!() + let data_in_byte = hex::decode(data)?; + let decrypted_data = cipher::decrypt(&data_in_byte, password.as_str())?; + Ok(String::from_utf8_lossy(&decrypted_data).to_string()) } fn get_chain_by(id: i32) -> Result, KOSError> { diff --git a/packages/kos-types/Cargo.toml b/packages/kos-types/Cargo.toml new file mode 100644 index 0000000..f218026 --- /dev/null +++ b/packages/kos-types/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "kos-types" +version = { workspace = true } +authors = { workspace = true } +edition = { workspace = true } +homepage = { workspace = true } +license = { workspace = true } +repository = { workspace = true } +rust-version = { workspace = true } + +[features] +alloc = ["hex/alloc"] +serde = ["dep:serde", "alloc"] +std = ["alloc", "serde?/std"] +random = ["rand"] + +[dependencies] +rand = { workspace = true, optional = true } +coins-bip32 = { workspace = true } +coins-bip39 = { workspace = true } +secp256k1 = { workspace = true, features = ["recovery", "rand"] } +ed25519-dalek = { workspace = true } +log = { workspace = true } +serde = { workspace = true, features = ["derive", "alloc"], optional = true } +serde_json = { workspace = true } +hex = { workspace = true } +reqwest = { workspace = true, default-features = false } +wasm-bindgen = { workspace = true } +num-bigint = "0.4" +num-traits = "0.2" \ No newline at end of file diff --git a/packages/kos-types/src/error.rs b/packages/kos-types/src/error.rs new file mode 100644 index 0000000..a73cb16 --- /dev/null +++ b/packages/kos-types/src/error.rs @@ -0,0 +1,157 @@ +use core::convert::Infallible; +use ed25519_dalek::SignatureError; +use reqwest::Error as ReqwestError; +use secp256k1::Error as Secp256k1Error; +use std::{error, fmt, str}; +use wasm_bindgen::JsValue; + +/// Crypto error variants +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum Error { + // Invalid string + InvalidString(String), + // JSON serialization error + JSONSerde(String), + // UnsupportedChain, + UnsupportedChain(&'static str), + // InvalidMnemonic, + InvalidMnemonic(&'static str), + // InvalidPath, + InvalidPath(&'static str), + // InvalidPrivateKey, + InvalidPrivateKey(&'static str), + // InvalidPublicKey, + InvalidPublicKey(String), + // InvalidAddress, + InvalidAddress(String), + // InvalidChecksum, + InvalidChecksum(&'static str), + /// Invalid secp256k1 signature + InvalidSignature(&'static str), + /// Invalid secp256k1 signature message + InvalidMessage(String), + /// Out of preallocated memory + NotEnoughMemory(String), + /// Reqwest error + ReqwestError(String), + /// Invalid Enum Variant + InvalidEnumVariant(String), + /// Invalid Len + InvalidLen(String), + /// InvalidNumberParse + InvalidNumberParse(String), + /// InvalidTransaction + InvalidTransaction(String), + /// WalletManagerError + WalletManagerError(String), + /// CipherError + CipherError(String), + /// TransportError + TransportError(String), +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Error::InvalidString(e) => write!(f, "Invalid string: {}", e), + Error::JSONSerde(e) => write!(f, "JSON serialization: {}", e), + Error::UnsupportedChain(e) => write!(f, "Unsupported chain: {}", e), + Error::InvalidMnemonic(e) => write!(f, "Invalid mnemonic: {}", e), + Error::InvalidPath(e) => write!(f, "Invalid path: {}", e), + Error::InvalidPrivateKey(e) => write!(f, "Invalid private key: {}", e), + Error::InvalidPublicKey(e) => write!(f, "Invalid public key: {}", e), + Error::InvalidAddress(e) => write!(f, "Invalid address: {}", e), + Error::InvalidChecksum(e) => write!(f, "Invalid checksum: {}", e), + Error::InvalidSignature(e) => write!(f, "Invalid signature: {}", e), + Error::InvalidMessage(e) => write!(f, "Invalid message: {}", e), + Error::NotEnoughMemory(e) => write!(f, "Not enough memory: {}", e), + Error::ReqwestError(e) => write!(f, "Reqwest error: {}", e), + Error::InvalidEnumVariant(e) => write!(f, "Invalid Enum Variant error: {}", e), + Error::InvalidLen(e) => write!(f, "Invalid Len: {}", e), + Error::InvalidNumberParse(e) => write!(f, "Invalid number parse: {}", e), + Error::InvalidTransaction(e) => write!(f, "Invalid transaction: {}", e), + Error::WalletManagerError(e) => write!(f, "WalletManager error: {}", e), + Error::CipherError(e) => write!(f, "Cipher error: {}", e), + Error::TransportError(e) => write!(f, "Transport error: {}", e), + } + } +} + +impl From for Error { + fn from(secp: Secp256k1Error) -> Self { + match secp { + Secp256k1Error::IncorrectSignature + | Secp256k1Error::InvalidSignature + | Secp256k1Error::InvalidTweak + | Secp256k1Error::InvalidSharedSecret + | Secp256k1Error::InvalidPublicKeySum + | Secp256k1Error::InvalidParityValue(_) + | Secp256k1Error::InvalidRecoveryId => Self::InvalidSignature("Secp256k1Error"), + Secp256k1Error::InvalidMessage => Self::InvalidMessage(secp.to_string()), + Secp256k1Error::InvalidPublicKey => Self::InvalidPublicKey(secp.to_string()), + Secp256k1Error::InvalidSecretKey => Self::InvalidPrivateKey("Secp256k1Error"), + Secp256k1Error::NotEnoughMemory => Self::NotEnoughMemory(secp.to_string()), + } + } +} + +impl From for Error { + fn from(_: SignatureError) -> Self { + Self::InvalidSignature("Invalid signature") + } +} + +impl From for Error { + fn from(_: coins_bip39::MnemonicError) -> Self { + Self::InvalidMnemonic("Invalid mnemonic") + } +} + +impl From for Error { + fn from(_: coins_bip32::Bip32Error) -> Self { + Self::InvalidPath("Invalid path") + } +} + +impl From for Error { + fn from(e: serde_json::Error) -> Self { + Self::JSONSerde(e.to_string()) + } +} + +impl error::Error for Error { + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + None + } +} + +impl From for JsValue { + fn from(e: Error) -> Self { + JsValue::from_str(&format!("{}", e)) + } +} + +impl From for Error { + fn from(e: ReqwestError) -> Self { + Self::ReqwestError(e.to_string()) + } +} + +impl From for Error { + fn from(e: hex::FromHexError) -> Self { + Self::InvalidString(e.to_string()) + } +} + +impl From for Infallible { + fn from(_: Error) -> Infallible { + unreachable!() + } +} + +impl From for Error { + fn from(_: Infallible) -> Error { + unreachable!() + } +} diff --git a/packages/kos-types/src/lib.rs b/packages/kos-types/src/lib.rs new file mode 100644 index 0000000..a91e735 --- /dev/null +++ b/packages/kos-types/src/lib.rs @@ -0,0 +1 @@ +pub mod error; From f789c987e1585106585b7ce3d5027bce585dea1c Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Tue, 12 Nov 2024 14:23:17 -0300 Subject: [PATCH 11/42] feat: add sign message --- packages/kos-mobile/src/lib.rs | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/packages/kos-mobile/src/lib.rs b/packages/kos-mobile/src/lib.rs index 18cd61a..1cbd2e1 100644 --- a/packages/kos-mobile/src/lib.rs +++ b/packages/kos-mobile/src/lib.rs @@ -161,6 +161,15 @@ fn sign_transaction(account: KOSAccount, raw: String) -> Result Result, KOSError> { + let chain = get_chain_by(account.chain_id)?; + let message = message.as_bytes(); + let signature = + chain.sign_message(hex::decode(account.private_key).unwrap(), message.to_vec())?; + Ok(signature) +} + #[cfg(test)] mod tests { use crate::*; @@ -364,8 +373,7 @@ mod tests { let raw = hex::encode("{\"RawData\":{\"BandwidthFee\":1000000,\"ChainID\":\"MTAwNDIw\",\"Contract\":[{\"Parameter\":{\"type_url\":\"type.googleapis.com/proto.TransferContract\",\"value\":\"CiAysyg0Aj8xj/rr5XGU6iJ+ATI29mnRHS0W0BrC1vz0CBgK\"}}],\"KAppFee\":500000,\"Nonce\":39,\"Sender\":\"5BsyOlcf2VXgnNQWYP9EZcP0RpPIfy+upKD8QIcnyOo=\",\"Version\":1}}".as_bytes()); let account = generate_wallet_from_mnemonic( - "permit best kiwi blast purchase cook grab present have hurdle quarter steak" - .to_string(), + "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(), chain_id, 0, None, @@ -380,12 +388,28 @@ mod tests { "The sender doesn't match" ); assert_eq!( - transaction.raw, "{\"RawData\":{\"Nonce\":39,\"Sender\":\"5BsyOlcf2VXgnNQWYP9EZcP0RpPIfy+upKD8QIcnyOo=\",\"Contract\":[{\"Parameter\":{\"typeUrl\":\"type.googleapis.com/proto.TransferContract\",\"value\":\"CiAysyg0Aj8xj/rr5XGU6iJ+ATI29mnRHS0W0BrC1vz0CBgK\"}}],\"KAppFee\":500000,\"BandwidthFee\":1000000,\"Version\":1,\"ChainID\":\"MTAwNDIw\"},\"Signature\":[\"gUZDIPSxSq40QjTBM38/DAAuWTm7D1THo2KWVqhiTYCum5O+OSWwTYlgIU0RgJ6ungg1cuCJPcmYWNgjDKA/DA==\"]}", + transaction.raw, "7b22426c6f636b223a6e756c6c2c2252617744617461223a7b2242616e647769647468466565223a313030303030302c22436861696e4944223a224d5441774e444977222c22436f6e7472616374223a5b7b22506172616d65746572223a7b22747970655f75726c223a22747970652e676f6f676c65617069732e636f6d2f70726f746f2e5472616e73666572436f6e7472616374222c2276616c7565223a224369417973796730416a38786a2f72723558475536694a2b41544932396d6e52485330573042724331767a304342674b227d7d5d2c2244617461223a6e756c6c2c224b417070466565223a3530303030302c224b6461466565223a6e756c6c2c224e6f6e6365223a33392c225065726d697373696f6e4944223a6e756c6c2c2253656e646572223a22354273794f6c6366325658676e4e5157595039455a6350305270504966792b75704b44385149636e794f6f3d222c2256657273696f6e223a317d2c225265636569707473223a6e756c6c2c22526573756c74223a6e756c6c2c22526573756c74436f6465223a6e756c6c2c225369676e6174757265223a5b2267555a444950537853713430516a54424d33382f4441417557546d37443154486f324b5756716869545943756d354f2b4f53577754596c6749553052674a36756e6767316375434a50636d59574e676a444b412f44413d3d225d7d", "The raw doesn't match" ); assert_eq!( - transaction.signature, "gUZDIPSxSq40QjTBM38/DAAuWTm7D1THo2KWVqhiTYCum5O+OSWwTYlgIU0RgJ6ungg1cuCJPcmYWNgjDKA/DA==", + transaction.signature, "81464320f4b14aae344234c1337f3f0c002e5939bb0f54c7a3629656a8624d80ae9b93be3925b04d8960214d11809eae9e083572e0893dc99858d8230ca03f0c", "The signature doesn't match" ); } + + #[test] + fn should_sign_message() { + let chain_id = 38; + let message = "Hello World".to_string(); + + let account = generate_wallet_from_mnemonic( + "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(), + chain_id, + 0, + None + ).unwrap(); + + let signature = sign_message(account, message).unwrap(); + assert_eq!(signature.len(), 64, "The signature length doesn't match"); + } } From 9ec62ddc633d43893be1b9f17c18d138f10f6ce3 Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Tue, 12 Nov 2024 14:32:59 -0300 Subject: [PATCH 12/42] chore: spec should_get_all_supported_chains_account_from_mnemonic --- packages/kos-mobile/src/lib.rs | 72 +++++++++++++++------------------- packages/kos/src/chains/mod.rs | 13 ++++++ 2 files changed, 44 insertions(+), 41 deletions(-) diff --git a/packages/kos-mobile/src/lib.rs b/packages/kos-mobile/src/lib.rs index 1cbd2e1..403bcbd 100644 --- a/packages/kos-mobile/src/lib.rs +++ b/packages/kos-mobile/src/lib.rs @@ -1,6 +1,6 @@ use hex::FromHexError; use hex::ToHex; -use kos::chains::{get_chain_by_base_id, get_chain_by_id, Chain, ChainError, Transaction}; +use kos::chains::{get_chain_by_base_id, Chain, ChainError, Transaction}; use kos_crypto::cipher; use kos_crypto::cipher::CipherAlgo; use kos_types::error::Error as KosError; @@ -37,7 +37,7 @@ impl From for KOSError { #[derive(uniffi::Record)] struct KOSAccount { - pub chain_id: i32, + pub chain_id: u32, pub private_key: String, pub public_key: String, pub address: String, @@ -46,7 +46,7 @@ struct KOSAccount { #[derive(uniffi::Record)] struct KOSTransaction { - pub chain_id: i32, + pub chain_id: u32, pub raw: String, pub sender: String, pub signature: String, @@ -65,8 +65,8 @@ fn validate_mnemonic(mnemonic: String) -> bool { #[uniffi::export] fn generate_wallet_from_mnemonic( mnemonic: String, - chain_id: i32, - index: i32, + chain_id: u32, + index: u32, custom_path: Option, ) -> Result { if !validate_mnemonic(mnemonic.clone()) { @@ -90,7 +90,7 @@ fn generate_wallet_from_mnemonic( #[uniffi::export] fn generate_wallet_from_private_key( - chain_id: i32, + chain_id: u32, private_key: String, ) -> Result { let chain = get_chain_by(chain_id)?; @@ -131,7 +131,7 @@ fn decrypt(data: String, password: String) -> Result { Ok(String::from_utf8_lossy(&decrypted_data).to_string()) } -fn get_chain_by(id: i32) -> Result, KOSError> { +fn get_chain_by(id: u32) -> Result, KOSError> { let id_u8 = u32::try_from(id).map_err(|_| KOSError::UnsupportedChain { id: id.to_string() })?; let chain = get_chain_by_base_id(id_u8) .ok_or_else(|| KOSError::UnsupportedChain { id: id.to_string() })?; @@ -173,6 +173,7 @@ fn sign_message(account: KOSAccount, message: String) -> Result, KOSErro #[cfg(test)] mod tests { use crate::*; + use kos::chains::get_chains; #[test] fn should_generate_mnemonic() { @@ -258,40 +259,29 @@ mod tests { } #[test] - // fn should_get_all_supported_chains_account_from_mnemonic() { - // let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); - // let index = 0; - // for (&chain_code, _) in Chain::get_chains().iter() { - // println!("code = {}", chain_code) - // } - // for (&chain_code, _) in Chain::get_chains().iter() { - // match generate_wallet_from_mnemonic( - // mnemonic.clone(), - // i32::from(chain_code), - // index, - // false, - // ) { - // Ok(account) => { - // assert!( - // !account.address.is_empty(), - // "The address for chain {} is empty", - // chain_code - // ); - // assert!( - // !account.private_key.is_empty(), - // "The private_key for chain {} is empty", - // chain_code - // ); - // assert_eq!( - // account.chain_id, - // i32::from(chain_code), - // "The chain_id doesn't match" - // ); - // } - // Err(e) => panic!("unexpected error! {}", e.to_string()), - // } - // } - // } + fn should_get_all_supported_chains_account_from_mnemonic() { + let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); + let index = 0; + + for chain_code in get_chains() { + match generate_wallet_from_mnemonic(mnemonic.clone(), chain_code, index, None) { + Ok(account) => { + assert!( + !account.address.is_empty(), + "The address for chain {} is empty", + chain_code + ); + assert!( + !account.private_key.is_empty(), + "The private_key for chain {} is empty", + chain_code + ); + assert_eq!(account.chain_id, chain_code, "The chain_id doesn't match"); + } + Err(e) => panic!("unexpected error! {}", e.to_string()), + } + } + } #[test] fn should_get_account_from_private_key() { let private_key = diff --git a/packages/kos/src/chains/mod.rs b/packages/kos/src/chains/mod.rs index b55f362..6ca185a 100644 --- a/packages/kos/src/chains/mod.rs +++ b/packages/kos/src/chains/mod.rs @@ -399,6 +399,15 @@ impl ChainRegistry { } None } + + fn get_chains(&self) -> Vec { + let mut ids = Vec::new(); + for &(_, factory) in self.registry { + let chain = factory(); + ids.push(chain.get_id()); + } + ids + } } pub fn get_chain_by_id(id: u32) -> Option> { @@ -429,3 +438,7 @@ pub fn get_chain_by_params(params: CustomChainType) -> Option> { pub fn get_chain_by_base_id(base_id: u32) -> Option> { ChainRegistry::new().get_chain_by_base_id(base_id) } + +pub fn get_chains() -> Vec { + ChainRegistry::new().get_chains() +} From 84f01accd13aaad4beb99b1917feca46204ac4c5 Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Tue, 12 Nov 2024 18:07:32 -0300 Subject: [PATCH 13/42] chore: use_legacy_path param --- packages/kos-mobile/src/lib.rs | 16 ++++++++-------- packages/kos/src/chains/ada/mod.rs | 9 +++------ packages/kos/src/chains/apt/mod.rs | 7 ++----- packages/kos/src/chains/atom/mod.rs | 9 +++------ packages/kos/src/chains/bch/mod.rs | 9 +++------ packages/kos/src/chains/bnb/mod.rs | 9 +++------ packages/kos/src/chains/btc/mod.rs | 9 +++------ packages/kos/src/chains/egld/mod.rs | 9 +++------ packages/kos/src/chains/eth/mod.rs | 9 +++------ packages/kos/src/chains/icp/mod.rs | 9 +++------ packages/kos/src/chains/klv/mod.rs | 10 +++------- packages/kos/src/chains/mod.rs | 2 +- packages/kos/src/chains/movr/mod.rs | 7 ++----- packages/kos/src/chains/sol/mod.rs | 9 +++------ packages/kos/src/chains/substrate/mod.rs | 23 +++++++++-------------- packages/kos/src/chains/sui/mod.rs | 9 +++------ packages/kos/src/chains/trx/mod.rs | 13 ++++++++----- packages/kos/src/chains/xrp/mod.rs | 9 +++------ 18 files changed, 66 insertions(+), 111 deletions(-) diff --git a/packages/kos-mobile/src/lib.rs b/packages/kos-mobile/src/lib.rs index 403bcbd..04e9362 100644 --- a/packages/kos-mobile/src/lib.rs +++ b/packages/kos-mobile/src/lib.rs @@ -67,14 +67,14 @@ fn generate_wallet_from_mnemonic( mnemonic: String, chain_id: u32, index: u32, - custom_path: Option, + use_legacy_path: bool, ) -> Result { if !validate_mnemonic(mnemonic.clone()) { return Err(KOSError::KOSDelegate("Invalid mnemonic".to_string())); } let chain = get_chain_by(chain_id)?; let seed = chain.mnemonic_to_seed(mnemonic, String::from(""))?; - let path = chain.get_path(index as u32, custom_path); + let path = chain.get_path(index, use_legacy_path); let private_key = chain.derive(seed, path.clone())?; let public_key = chain.get_pbk(private_key.clone())?; @@ -212,7 +212,7 @@ mod tests { let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); let index = 0; let chain_id = 999; - match generate_wallet_from_mnemonic(mnemonic, chain_id, index, None) { + match generate_wallet_from_mnemonic(mnemonic, chain_id, index, false) { Ok(_) => panic!("A error was expected but found a mnemonic"), Err(e) => { if let KOSError::UnsupportedChain { id } = e { @@ -229,7 +229,7 @@ mod tests { let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); let index = 0; let chain_id = 38; - match generate_wallet_from_mnemonic(mnemonic, chain_id, index, None) { + match generate_wallet_from_mnemonic(mnemonic, chain_id, index, false) { Ok(account) => { assert_eq!( account.address, @@ -252,7 +252,7 @@ mod tests { let mnemonic = "abandon abandon abandon abandon abandon klv abandon abandon abandon abandon abandon about".to_string(); let index = 0; let chain_id = 38; - match generate_wallet_from_mnemonic(mnemonic, chain_id, index, None) { + match generate_wallet_from_mnemonic(mnemonic, chain_id, index, false) { Ok(_) => panic!("A error was expected but found a account"), Err(e) => assert!(matches!(e, KOSError::KOSDelegate(..)), " Invalid error"), } @@ -264,7 +264,7 @@ mod tests { let index = 0; for chain_code in get_chains() { - match generate_wallet_from_mnemonic(mnemonic.clone(), chain_code, index, None) { + match generate_wallet_from_mnemonic(mnemonic.clone(), chain_code, index, false) { Ok(account) => { assert!( !account.address.is_empty(), @@ -366,7 +366,7 @@ mod tests { "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(), chain_id, 0, - None, + false, ) .unwrap(); @@ -396,7 +396,7 @@ mod tests { "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(), chain_id, 0, - None + false ).unwrap(); let signature = sign_message(account, message).unwrap(); diff --git a/packages/kos/src/chains/ada/mod.rs b/packages/kos/src/chains/ada/mod.rs index 56d0668..4ce637b 100644 --- a/packages/kos/src/chains/ada/mod.rs +++ b/packages/kos/src/chains/ada/mod.rs @@ -44,11 +44,8 @@ impl Chain for ADA { Ok(derive_ed25519_bip32(seed_arr, path)?.to_vec()) } - fn get_path(&self, index: u32, custom_path: Option) -> String { - match custom_path { - Some(path) => path, - None => format!("m/1852'/1815'/0'/0/{}", index), - } + fn get_path(&self, index: u32, _is_legacy: bool) -> String { + format!("m/1852'/1815'/0'/0/{}", index) } fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { @@ -151,7 +148,7 @@ mod test { let ada = super::ADA {}; let seed = ada.mnemonic_to_seed(mnemonic, "".to_string()).unwrap(); - let path = ada.get_path(0, None); + let path = ada.get_path(0, false); let pvk = ada.derive(seed, path).unwrap(); let pbk = ada.get_pbk(pvk).unwrap(); diff --git a/packages/kos/src/chains/apt/mod.rs b/packages/kos/src/chains/apt/mod.rs index 53bc06b..2d08a44 100644 --- a/packages/kos/src/chains/apt/mod.rs +++ b/packages/kos/src/chains/apt/mod.rs @@ -35,11 +35,8 @@ impl Chain for APT { Ok(Vec::from(result)) } - fn get_path(&self, index: u32, custom_path: Option) -> String { - match custom_path { - Some(path) => path, - None => format!("m/44'/637'/0'/0'/{}'", index), - } + fn get_path(&self, index: u32, _is_legacy: bool) -> String { + format!("m/44'/637'/0'/0'/{}'", index) } fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { diff --git a/packages/kos/src/chains/atom/mod.rs b/packages/kos/src/chains/atom/mod.rs index 0ddc034..8dfa571 100644 --- a/packages/kos/src/chains/atom/mod.rs +++ b/packages/kos/src/chains/atom/mod.rs @@ -67,11 +67,8 @@ impl Chain for ATOM { Ok(Vec::from(pvk)) } - fn get_path(&self, index: u32, custom_path: Option) -> String { - match custom_path { - Some(path) => path, - None => format!("m/44'/118'/0'/0/{}", index), - } + fn get_path(&self, index: u32, _is_legacy: bool) -> String { + format!("m/44'/118'/0'/0/{}", index) } fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { @@ -137,7 +134,7 @@ mod test { let atom = ATOM::new(); let seed = atom.mnemonic_to_seed(mnemonic, "".to_string()).unwrap(); - let path = atom.get_path(0, None); + let path = atom.get_path(0, false); let pvk = atom.derive(seed, path).unwrap(); let pbk = atom.get_pbk(pvk).unwrap(); let addr = atom.get_address(pbk).unwrap(); diff --git a/packages/kos/src/chains/bch/mod.rs b/packages/kos/src/chains/bch/mod.rs index 566f168..0e0133c 100644 --- a/packages/kos/src/chains/bch/mod.rs +++ b/packages/kos/src/chains/bch/mod.rs @@ -97,11 +97,8 @@ impl Chain for BCH { Ok(pvk.to_vec()) } - fn get_path(&self, index: u32, custom_path: Option) -> String { - match custom_path { - Some(path) => path, - None => format!("m/44'/145'/0'/0/{}", index), - } + fn get_path(&self, index: u32, _is_legacy: bool) -> String { + format!("m/44'/145'/0'/0/{}", index) } fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { @@ -174,7 +171,7 @@ mod test { let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); let seed = bch.mnemonic_to_seed(mnemonic, "".to_string()).unwrap(); - let path = bch.get_path(0, None); + let path = bch.get_path(0, false); let pvk = bch.derive(seed, path).unwrap(); let pbk = bch.get_pbk(pvk).unwrap(); let addr = bch.get_address(pbk).unwrap(); diff --git a/packages/kos/src/chains/bnb/mod.rs b/packages/kos/src/chains/bnb/mod.rs index 4a89a63..eea5699 100644 --- a/packages/kos/src/chains/bnb/mod.rs +++ b/packages/kos/src/chains/bnb/mod.rs @@ -38,11 +38,8 @@ impl Chain for BNB { Ok(pvk.to_vec()) } - fn get_path(&self, index: u32, custom_path: Option) -> String { - match custom_path { - Some(path) => path, - None => format!("m/44'/714'/0'/0/{}", index), - } + fn get_path(&self, index: u32, _is_legacy: bool) -> String { + format!("m/44'/714'/0'/0/{}", index) } fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { @@ -109,7 +106,7 @@ mod test { let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); let seed = bnb.mnemonic_to_seed(mnemonic, "".to_string()).unwrap(); - let path = bnb.get_path(0, None); + let path = bnb.get_path(0, false); let pvk = bnb.derive(seed, path).unwrap(); let pbk = bnb.get_pbk(pvk.clone()).unwrap(); diff --git a/packages/kos/src/chains/btc/mod.rs b/packages/kos/src/chains/btc/mod.rs index 7c7608e..f0c6188 100644 --- a/packages/kos/src/chains/btc/mod.rs +++ b/packages/kos/src/chains/btc/mod.rs @@ -110,11 +110,8 @@ impl Chain for BTC { Ok(pvk.to_vec()) } - fn get_path(&self, index: u32, custom_path: Option) -> String { - match custom_path { - Some(path) => path, - None => format!("m/84'/0'/0'/0/{}", index), - } + fn get_path(&self, index: u32, _is_legacy: bool) -> String { + format!("m/84'/0'/0'/0/{}", index) } fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { @@ -175,7 +172,7 @@ mod test { hex::decode("4604b4b710fe91f584fff084e1a9159fe4f8408fff380596a604948474ce4fa3") .unwrap(); let btc = BTC::new(); - let path = btc.get_path(0, None); + let path = btc.get_path(0, false); let seed = btc.mnemonic_to_seed(mnemonic, "".to_string()).unwrap(); let res = btc.derive(seed, path).unwrap(); assert_eq!(res, expected); diff --git a/packages/kos/src/chains/egld/mod.rs b/packages/kos/src/chains/egld/mod.rs index 213ad9a..1ba113e 100644 --- a/packages/kos/src/chains/egld/mod.rs +++ b/packages/kos/src/chains/egld/mod.rs @@ -36,11 +36,8 @@ impl Chain for EGLD { Ok(Vec::from(result)) } - fn get_path(&self, index: u32, custom_path: Option) -> String { - match custom_path { - Some(path) => path, - None => format!("m/44'/508'/0'/0'/{}'", index), - } + fn get_path(&self, index: u32, _is_legacy: bool) -> String { + format!("m/44'/508'/0'/0'/{}'", index) } fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { @@ -96,7 +93,7 @@ mod test { let egld = super::EGLD {}; let seed = egld.mnemonic_to_seed(mnemonic, String::new()).unwrap(); - let path = egld.get_path(0, None); + let path = egld.get_path(0, false); let pvk = egld.derive(seed.clone(), path).unwrap(); let pbk = egld.get_pbk(pvk.clone()).unwrap(); let addr = egld.get_address(pbk.clone()).unwrap(); diff --git a/packages/kos/src/chains/eth/mod.rs b/packages/kos/src/chains/eth/mod.rs index 3d7735a..5911d57 100644 --- a/packages/kos/src/chains/eth/mod.rs +++ b/packages/kos/src/chains/eth/mod.rs @@ -88,11 +88,8 @@ impl Chain for ETH { Ok(Vec::from(pvk)) } - fn get_path(&self, index: u32, custom_path: Option) -> String { - match custom_path { - Some(path) => path, - None => format!("m/44'/60'/0'/0/{}", index), - } + fn get_path(&self, index: u32, _is_legacy: bool) -> String { + format!("m/44'/60'/0'/0/{}", index) } fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { @@ -198,7 +195,7 @@ mod test { let eth = super::ETH::new(); let seed = eth.mnemonic_to_seed(mnemonic, "".to_string()).unwrap(); - let path = eth.get_path(0, None); + let path = eth.get_path(0, false); let pvk = eth.derive(seed, path).unwrap(); let pbk = eth.get_pbk(pvk).unwrap(); let addr = eth.get_address(pbk).unwrap(); diff --git a/packages/kos/src/chains/icp/mod.rs b/packages/kos/src/chains/icp/mod.rs index 14f08fe..c792290 100644 --- a/packages/kos/src/chains/icp/mod.rs +++ b/packages/kos/src/chains/icp/mod.rs @@ -39,11 +39,8 @@ impl Chain for ICP { Ok(Vec::from(result)) } - fn get_path(&self, index: u32, custom_path: Option) -> String { - match custom_path { - Some(path) => path, - None => format!("m/44'/223'/0'/0'/{}", index), - } + fn get_path(&self, index: u32, _is_legacy: bool) -> String { + format!("m/44'/223'/0'/0'/{}", index) } fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { @@ -157,7 +154,7 @@ mod test { let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); let seed = icp.mnemonic_to_seed(mnemonic, "".to_string()).unwrap(); - let path = icp.get_path(0, None); + let path = icp.get_path(0, false); let pvk = icp.derive(seed, path).unwrap(); let pbk = icp.get_pbk(pvk).unwrap(); diff --git a/packages/kos/src/chains/klv/mod.rs b/packages/kos/src/chains/klv/mod.rs index 0cd916d..5a5e6b3 100644 --- a/packages/kos/src/chains/klv/mod.rs +++ b/packages/kos/src/chains/klv/mod.rs @@ -59,12 +59,8 @@ impl Chain for KLV { Ok(Vec::from(result)) } - fn get_path(&self, index: u32, custom_path: Option) -> String { - let mut path = format!("m/44'/{}'/0'/0'/{}'", BIP44_PATH, index); - if let Some(custom_path) = &custom_path { - path = custom_path.clone(); - } - path + fn get_path(&self, index: u32, _is_legacy: bool) -> String { + format!("m/44'/{}'/0'/0'/{}'", BIP44_PATH, index) } fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { @@ -173,7 +169,7 @@ mod test { #[test] fn test_derive() { let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); - let path = crate::chains::klv::KLV {}.get_path(0, None); + let path = crate::chains::klv::KLV {}.get_path(0, false); let seed = crate::chains::klv::KLV {} .mnemonic_to_seed(mnemonic, String::new()) diff --git a/packages/kos/src/chains/mod.rs b/packages/kos/src/chains/mod.rs index 6ca185a..0e214d1 100644 --- a/packages/kos/src/chains/mod.rs +++ b/packages/kos/src/chains/mod.rs @@ -242,7 +242,7 @@ pub trait Chain { fn get_decimals(&self) -> u32; fn mnemonic_to_seed(&self, mnemonic: String, password: String) -> Result, ChainError>; fn derive(&self, seed: Vec, path: String) -> Result, ChainError>; - fn get_path(&self, index: u32, custom_path: Option) -> String; + fn get_path(&self, index: u32, is_legacy: bool) -> String; fn get_pbk(&self, private_key: Vec) -> Result, ChainError>; fn get_address(&self, public_key: Vec) -> Result; fn sign_tx(&self, private_key: Vec, tx: Transaction) -> Result; diff --git a/packages/kos/src/chains/movr/mod.rs b/packages/kos/src/chains/movr/mod.rs index 47cf9e1..b452309 100644 --- a/packages/kos/src/chains/movr/mod.rs +++ b/packages/kos/src/chains/movr/mod.rs @@ -117,11 +117,8 @@ impl Chain for MOVR { Err(ChainError::NotSupported) } - fn get_path(&self, index: u32, custom_path: Option) -> String { - match custom_path { - Some(path) => path, - None => format!("m/44'/60'/0'/0/{}", index), // Verify this path - } + fn get_path(&self, index: u32, _is_legacy: bool) -> String { + format!("m/44'/60'/0'/0/{}", index) } fn get_id(&self) -> u32 { diff --git a/packages/kos/src/chains/sol/mod.rs b/packages/kos/src/chains/sol/mod.rs index 110caf5..f6f0e4f 100644 --- a/packages/kos/src/chains/sol/mod.rs +++ b/packages/kos/src/chains/sol/mod.rs @@ -35,11 +35,8 @@ impl Chain for SOL { Ok(Vec::from(result)) } - fn get_path(&self, index: u32, custom_path: Option) -> String { - match custom_path { - Some(path) => path, - None => format!("m/44'/501'/0'/0'/{}'", index), - } + fn get_path(&self, index: u32, _is_legacy: bool) -> String { + format!("m/44'/501'/0'/0'/{}'", index) } fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { @@ -89,7 +86,7 @@ mod test { let sol = SOL {}; let seed = sol.mnemonic_to_seed(mnemonic, "".to_string()).unwrap(); - let path = sol.get_path(0, None); + let path = sol.get_path(0, false); let pvk = sol.derive(seed, path).unwrap(); let pbk = sol.get_pbk(pvk).unwrap(); let addr = sol.get_address(pbk).unwrap(); diff --git a/packages/kos/src/chains/substrate/mod.rs b/packages/kos/src/chains/substrate/mod.rs index 7047764..a711120 100644 --- a/packages/kos/src/chains/substrate/mod.rs +++ b/packages/kos/src/chains/substrate/mod.rs @@ -62,16 +62,11 @@ impl Chain for Substrate { Ok(pvk.to_vec()) } - fn get_path(&self, index: u32, custom_path: Option) -> String { - match custom_path { - Some(path) => path, - None => { - if index == 0 { - return "".to_string(); - } - format!("//{}", index) - } + fn get_path(&self, index: u32, _is_legacy: bool) -> String { + if index == 0 { + return "".to_string(); } + format!("//{}", index) } fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { @@ -153,10 +148,10 @@ mod test { #[test] fn test_get_addr() { - let dot = super::Substrate::new(0, "Polkadot", "DOT"); + let dot = super::Substrate::new(21, 0, "Polkadot", "DOT"); let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); - let path = dot.get_path(0, None); + let path = dot.get_path(0, false); let seed = dot.mnemonic_to_seed(mnemonic, String::from("")).unwrap(); let pvk = dot.derive(seed, path).unwrap(); @@ -167,7 +162,7 @@ mod test { #[test] fn test_sign_raw() { - let dot = super::Substrate::new(0, "Polkadot", "DOT"); + let dot = super::Substrate::new(21, 0, "Polkadot", "DOT"); let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); let path = String::from(""); @@ -180,7 +175,7 @@ mod test { #[test] fn sign_tx() { - let dot = super::Substrate::new(0, "Polkadot", "DOT"); + let dot = super::Substrate::new(21, 0, "Polkadot", "DOT"); let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); let path = String::from(""); @@ -191,7 +186,7 @@ mod test { #[test] fn test_get_tx_info() { - let dot = super::Substrate::new(0, "Polkadot", "DOT"); + let dot = super::Substrate::new(21, 0, "Polkadot", "DOT"); let raw_data = "05030092fb4dc4e0790663aa4be18e6c49d62e8db091a6e1c4d0727c14906cf79f0f7a280000002b460f001900000091b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c391b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3".to_string(); let raw_data_hex = hex::decode(raw_data).unwrap(); diff --git a/packages/kos/src/chains/sui/mod.rs b/packages/kos/src/chains/sui/mod.rs index 8fdcca1..fd49815 100644 --- a/packages/kos/src/chains/sui/mod.rs +++ b/packages/kos/src/chains/sui/mod.rs @@ -35,11 +35,8 @@ impl Chain for SUI { Ok(Vec::from(result)) } - fn get_path(&self, index: u32, custom_path: Option) -> String { - match custom_path { - Some(path) => path, - None => format!("m/44'/784'/0'/0'/{}'", index), - } + fn get_path(&self, index: u32, _is_legacy: bool) -> String { + format!("m/44'/784'/0'/0'/{}'", index) } fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { @@ -120,7 +117,7 @@ mod test { let sui = super::SUI {}; let seed = sui.mnemonic_to_seed(mnemonic, String::new()).unwrap(); - let path = sui.get_path(0, None); + let path = sui.get_path(0, false); let pvk = sui.derive(seed.clone(), path).unwrap(); let pbk = sui.get_pbk(pvk.clone()).unwrap(); let addr = sui.get_address(pbk.clone()).unwrap(); diff --git a/packages/kos/src/chains/trx/mod.rs b/packages/kos/src/chains/trx/mod.rs index d6dbf77..0dc3e04 100644 --- a/packages/kos/src/chains/trx/mod.rs +++ b/packages/kos/src/chains/trx/mod.rs @@ -16,6 +16,8 @@ const TRX_ADDR_PREFIX: u8 = 0x41; const TRX_ADD_RAW_LEN: usize = 21; const TRX_ADD_SIZE: usize = 25; +pub const BIP44_PATH: u32 = 195; + const TRON_MESSAGE_PREFIX: &str = "\x19TRON Signed Message:\n"; pub struct TRX {} @@ -85,10 +87,11 @@ impl Chain for TRX { Ok(Vec::from(pvk)) } - fn get_path(&self, index: u32, custom_path: Option) -> String { - match custom_path { - Some(path) => path, - None => format!("m/44'/195'/0'/0/{}", index), + fn get_path(&self, index: u32, is_legacy: bool) -> String { + if is_legacy { + format!("m/44'/{}'/{}'", BIP44_PATH, index) + } else { + format!("m/44'/{}'/0'/0/{}", BIP44_PATH, index) } } @@ -288,7 +291,7 @@ mod test { let seed = crate::chains::trx::TRX {} .mnemonic_to_seed(mnemonic, String::from("")) .unwrap(); - let path = crate::chains::trx::TRX {}.get_path(0, None); + let path = crate::chains::trx::TRX {}.get_path(0, false); let pvk = crate::chains::trx::TRX {}.derive(seed, path).unwrap(); assert_eq!(pvk.len(), 32); let pbk = crate::chains::trx::TRX {}.get_pbk(pvk).unwrap(); diff --git a/packages/kos/src/chains/xrp/mod.rs b/packages/kos/src/chains/xrp/mod.rs index f39ef35..2a4b4d5 100644 --- a/packages/kos/src/chains/xrp/mod.rs +++ b/packages/kos/src/chains/xrp/mod.rs @@ -44,11 +44,8 @@ impl Chain for XRP { Ok(pvk.to_vec()) } - fn get_path(&self, index: u32, custom_path: Option) -> String { - match custom_path { - Some(path) => path, - None => format!("m/44'/144'/0'/0/{}", index), - } + fn get_path(&self, index: u32, _is_legacy: bool) -> String { + format!("m/44'/144'/0'/0/{}", index) } fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { @@ -118,7 +115,7 @@ mod test { let xrp = super::XRP::new(); let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); - let path = xrp.get_path(0, None); + let path = xrp.get_path(0, false); let seed = xrp.mnemonic_to_seed(mnemonic, String::from("")).unwrap(); let pvk = xrp.derive(seed, path).unwrap(); From 4e9b94e860343ea2e51105ec78743eb19228f6d6 Mon Sep 17 00:00:00 2001 From: Patrick Monteiro Date: Wed, 13 Nov 2024 15:21:49 -0300 Subject: [PATCH 14/42] feat: add ksafe feature checking --- packages/kos/Cargo.toml | 7 +++--- packages/kos/src/crypto/mod.rs | 4 ++- packages/kos/src/crypto/pbkdf2.rs | 6 ++--- packages/kos/src/crypto/rng.rs | 15 +++++------ packages/kos/src/crypto/secp256k1.rs | 8 +++--- packages/kos/src/lib.rs | 37 ++++++++++++++++++++++++++++ 6 files changed, 59 insertions(+), 18 deletions(-) diff --git a/packages/kos/Cargo.toml b/packages/kos/Cargo.toml index 32df0d5..ca819f6 100644 --- a/packages/kos/Cargo.toml +++ b/packages/kos/Cargo.toml @@ -44,13 +44,12 @@ pbkdf2 = { version = "0.12.2 ", features = ["sha2", "hmac", "password-hash"], de bip39-dict = { version = "0.1.0", features = ["english"], default-features = false } libsecp256k1 = { version = "0.7.1", features = ["hmac", "static-context"], default-features = false } rand_core = { version = "0.6.4", default-features = false } -rand = "0.8" -coins-bip39 = { version = "0.8", default-features = false, features = ["english"] } parity-scale-codec = { version = "3.6.9", default-features = false, features = ["derive"] } [target.'cfg(target_arch = "x86_64")'.dependencies] rand_core = { version = "0.6.4", features = ["getrandom"], default-features = false } - +rand = "0.8" +coins-bip39 = { version = "0.8", default-features = false, features = ["english"] } [build-dependencies] prost-build = "0.12.1" @@ -61,3 +60,5 @@ prost-wkt-types = { version = "0.5.0", default-features = false } heck = "0.4.1" +[features] +ksafe = [] diff --git a/packages/kos/src/crypto/mod.rs b/packages/kos/src/crypto/mod.rs index eee419a..4300c94 100644 --- a/packages/kos/src/crypto/mod.rs +++ b/packages/kos/src/crypto/mod.rs @@ -5,12 +5,14 @@ pub mod bip32; pub mod ed25519; mod ed25519_bip32; pub mod hash; -pub mod mnemonic; mod pbkdf2; mod rng; pub mod secp256k1; pub mod sr25519; +#[cfg(not(feature = "ksafe"))] +pub mod mnemonic; + mod crypto {} #[cfg(test)] diff --git a/packages/kos/src/crypto/pbkdf2.rs b/packages/kos/src/crypto/pbkdf2.rs index e7ed815..4914443 100644 --- a/packages/kos/src/crypto/pbkdf2.rs +++ b/packages/kos/src/crypto/pbkdf2.rs @@ -1,4 +1,4 @@ -#[cfg(not(target_arch = "x86_64"))] +#[cfg(feature = "ksafe")] extern "C" { fn c_pbkdf2_hmac_sha512( pass: *const u8, @@ -17,7 +17,7 @@ pub trait Pbkdf2Trait { pub struct Pbkdf2 {} -#[cfg(target_arch = "x86_64")] +#[cfg(not(feature = "ksafe"))] impl Pbkdf2Trait for Pbkdf2 { fn pbkdf2_hmac_512(password: &[u8], salt: &[u8], rounds: u32) -> [u8; N] { let icarus_key = pbkdf2::pbkdf2_hmac_array::(password, &salt, rounds); @@ -25,7 +25,7 @@ impl Pbkdf2Trait for Pbkdf2 { } } -#[cfg(not(target_arch = "x86_64"))] +#[cfg(feature = "ksafe")] impl Pbkdf2Trait for Pbkdf2 { fn pbkdf2_hmac_512(password: &[u8], salt: &[u8], rounds: u32) -> [u8; N] { let mut out = [0u8; N]; diff --git a/packages/kos/src/crypto/rng.rs b/packages/kos/src/crypto/rng.rs index 73566b0..384f1e0 100644 --- a/packages/kos/src/crypto/rng.rs +++ b/packages/kos/src/crypto/rng.rs @@ -1,16 +1,17 @@ -use rand_core::{CryptoRng, RngCore}; +#[allow(unused_imports)] +use rand_core::{CryptoRng, Error, RngCore}; -#[cfg(not(target_arch = "x86_64"))] +#[cfg(feature = "ksafe")] extern "C" { #[allow(dead_code)] fn random_buffer(p_buffer: *mut u8, size: u32); } -#[cfg(not(target_arch = "x86_64"))] +#[cfg(feature = "ksafe")] #[allow(dead_code)] struct MyRng; -#[cfg(not(target_arch = "x86_64"))] +#[cfg(feature = "ksafe")] impl RngCore for MyRng { fn next_u32(&mut self) -> u32 { let mut buf = [0u8; 4]; @@ -40,15 +41,15 @@ impl RngCore for MyRng { } } -#[cfg(not(target_arch = "x86_64"))] +#[cfg(feature = "ksafe")] impl CryptoRng for MyRng {} -#[cfg(target_arch = "x86_64")] +#[cfg(not(feature = "ksafe"))] pub fn getrandom_or_panic() -> impl RngCore + CryptoRng { rand_core::OsRng } -#[cfg(not(target_arch = "x86_64"))] +#[cfg(feature = "ksafe")] pub fn getrandom_or_panic() -> impl RngCore + CryptoRng { MyRng } diff --git a/packages/kos/src/crypto/secp256k1.rs b/packages/kos/src/crypto/secp256k1.rs index 4429fa3..2dd6e6e 100644 --- a/packages/kos/src/crypto/secp256k1.rs +++ b/packages/kos/src/crypto/secp256k1.rs @@ -14,7 +14,7 @@ impl Display for Secp256Err { } } -#[cfg(target_arch = "x86_64")] +#[cfg(not(feature = "ksafe"))] impl From for Secp256Err { fn from(_: libsecp256k1::Error) -> Self { Secp256Err::ErrDerive @@ -23,7 +23,7 @@ impl From for Secp256Err { pub struct Secp256K1 {} -#[cfg(not(target_arch = "x86_64"))] +#[cfg(feature = "ksafe")] extern "C" { fn c_ecdsa_secp256k1_sign(msg: *const u8, msg_len: u32, pvk: *const u8, sig: *mut u8); @@ -41,7 +41,7 @@ pub trait Secp256k1Trait { fn sign(msg: &[u8; 32], pvk: &[u8; 32]) -> Result<[u8; 65], Secp256Err>; } -#[cfg(not(target_arch = "x86_64"))] +#[cfg(feature = "ksafe")] impl Secp256k1Trait for Secp256K1 { fn add_scalars(a: &[u8; 32], b: &[u8; 32]) -> Result<[u8; 32], Secp256Err> { let mut c = [0; 32]; @@ -85,7 +85,7 @@ impl Secp256k1Trait for Secp256K1 { } } -#[cfg(target_arch = "x86_64")] +#[cfg(not(feature = "ksafe"))] impl Secp256k1Trait for Secp256K1 { fn add_scalars(a: &[u8; 32], b: &[u8; 32]) -> Result<[u8; 32], Secp256Err> { let mut a = libsecp256k1::SecretKey::parse(a)?; diff --git a/packages/kos/src/lib.rs b/packages/kos/src/lib.rs index 06622c1..6b10b25 100644 --- a/packages/kos/src/lib.rs +++ b/packages/kos/src/lib.rs @@ -4,3 +4,40 @@ pub mod crypto; pub mod protos; extern crate alloc; + +#[cfg(feature = "ksafe")] +use core::alloc::{GlobalAlloc, Layout}; + +#[cfg(feature = "ksafe")] +#[allow(dead_code)] +struct FreeRtosAllocator; + +#[cfg(feature = "ksafe")] +#[allow(dead_code)] +extern "C" { + fn pvPortMalloc(size: u32) -> *mut u8; // Using u32 instead of libc::size_t + fn vPortFree(ptr: *mut u8); + fn HardFault_Handler(); + fn DebugErrorHandler(log: *const u8); +} + +#[cfg(feature = "ksafe")] +unsafe impl GlobalAlloc for FreeRtosAllocator { + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + pvPortMalloc(layout.size() as u32) // Cast to u32 + } + unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) { + vPortFree(ptr); + } +} + +#[cfg(all(feature = "ksafe", not(test)))] +#[global_allocator] +static ALLOCATOR: FreeRtosAllocator = FreeRtosAllocator; + +#[cfg(all(feature = "ksafe", not(test)))] +#[panic_handler] +unsafe fn my_panic(_info: &core::panic::PanicInfo) -> ! { + HardFault_Handler(); + loop {} +} \ No newline at end of file From c9a4f626a0c01457bc4b404a509456e4b764b020 Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Wed, 13 Nov 2024 19:49:52 -0300 Subject: [PATCH 15/42] fix: BTC based ids & changed sign message to receive hex bytes --- Cargo.lock | 341 +++++++++++++++-------------- packages/kos-mobile/src/lib.rs | 9 +- packages/kos/src/chains/btc/mod.rs | 13 +- packages/kos/src/chains/mod.rs | 10 +- 4 files changed, 191 insertions(+), 182 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 082a923..134a782 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,18 +4,18 @@ version = 3 [[package]] name = "addr2line" -version = "0.22.0" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ "gimli", ] [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "aead" @@ -63,9 +63,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.15" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ "anstyle", "anstyle-parse", @@ -78,43 +78,43 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.8" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anstyle-parse" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ - "windows-sys", + "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.4" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" dependencies = [ "anstyle", - "windows-sys", + "windows-sys 0.59.0", ] [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" [[package]] name = "arrayref" @@ -124,9 +124,9 @@ checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "askama" @@ -151,7 +151,7 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.66", + "syn 2.0.87", ] [[package]] @@ -171,23 +171,23 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "backtrace" -version = "0.3.73" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", + "windows-targets", ] [[package]] @@ -270,9 +270,9 @@ dependencies = [ [[package]] name = "bitflags" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "bitvec" @@ -349,9 +349,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.7.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" +checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" [[package]] name = "camino" @@ -440,9 +440,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.16" +version = "4.5.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed6719fffa43d0d87e5fd8caeab59be1554fb028cd30edc88fc4369b17971019" +checksum = "fb3b4b9e5a7c7514dfa52869339ee98b3156b0bfb4e8a77c4ff4babb64b1604f" dependencies = [ "clap_builder", "clap_derive", @@ -450,9 +450,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.15" +version = "4.5.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6" +checksum = "b17a95aa67cc7b5ebd32aa5370189aa0d79069ef1c64ce893bd30fb24bff20ec" dependencies = [ "anstream", "anstyle", @@ -462,21 +462,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.13" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.87", ] [[package]] name = "clap_lex" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" +checksum = "afb84c814227b90d6895e01398aee0d8033c00e7466aca416fb6a8e0eb19d8a7" [[package]] name = "coins-bip32" @@ -532,9 +532,9 @@ dependencies = [ [[package]] name = "colorchoice" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "const-oid" @@ -544,9 +544,9 @@ checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "cpufeatures" -version = "0.2.12" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "0ca741a962e1b0bff6d724a1a0958b686406e853bb14061f218562e1896f95e6" dependencies = [ "libc", ] @@ -629,7 +629,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.87", ] [[package]] @@ -671,7 +671,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.87", ] [[package]] @@ -715,9 +715,9 @@ dependencies = [ [[package]] name = "either" -version = "1.12.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "elliptic-curve" @@ -761,14 +761,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] name = "fastrand" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" +checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" [[package]] name = "ff" @@ -898,9 +898,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.29.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "glob" @@ -932,9 +932,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.5" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" [[package]] name = "heck" @@ -1183,7 +1183,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.87", ] [[package]] @@ -1220,9 +1220,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.6" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", "hashbrown", @@ -1404,15 +1404,15 @@ dependencies = [ [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.155" +version = "0.2.162" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" [[package]] name = "libsecp256k1" @@ -1476,15 +1476,15 @@ checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" [[package]] name = "log" -version = "0.4.21" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "memchr" -version = "2.7.2" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "merlin" @@ -1522,11 +1522,11 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.4" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" dependencies = [ - "adler", + "adler2", ] [[package]] @@ -1538,7 +1538,7 @@ dependencies = [ "hermit-abi", "libc", "wasi", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -1596,9 +1596,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "opaque-debug" @@ -1736,28 +1736,28 @@ dependencies = [ [[package]] name = "prettyplease" -version = "0.2.20" +version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" +checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" dependencies = [ "proc-macro2", - "syn 2.0.66", + "syn 2.0.87", ] [[package]] name = "proc-macro-crate" -version = "3.1.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" dependencies = [ "toml_edit", ] [[package]] name = "proc-macro2" -version = "1.0.85" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" +checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" dependencies = [ "unicode-ident", ] @@ -1789,7 +1789,7 @@ dependencies = [ "prost", "prost-types", "regex", - "syn 2.0.66", + "syn 2.0.87", "tempfile", ] @@ -1803,7 +1803,7 @@ dependencies = [ "itertools", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.87", ] [[package]] @@ -1863,9 +1863,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -1908,9 +1908,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.4" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", @@ -1920,9 +1920,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.6" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", @@ -1931,9 +1931,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "reqwest" @@ -2013,24 +2013,24 @@ checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" [[package]] name = "rustc_version" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ "semver", ] [[package]] name = "rustix" -version = "0.38.34" +version = "0.38.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "99e4ea3e1cdc4b559b8e5650f9c8e5998e3e5c1343b4eaf034565f32318d63c0" dependencies = [ "bitflags", "errno", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -2073,7 +2073,7 @@ checksum = "7f81c2fde025af7e69b1d1420531c8a8811ca898919db177141a85313b1cb932" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.87", ] [[package]] @@ -2122,31 +2122,32 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.203" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.203" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.87", ] [[package]] name = "serde_json" -version = "1.0.117" +version = "1.0.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" +checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] @@ -2249,7 +2250,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -2282,9 +2283,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "subtle" -version = "2.5.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" @@ -2299,9 +2300,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.66" +version = "2.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" dependencies = [ "proc-macro2", "quote", @@ -2325,7 +2326,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.87", ] [[package]] @@ -2336,14 +2337,15 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.10.1" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" dependencies = [ "cfg-if", "fastrand", + "once_cell", "rustix", - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -2357,22 +2359,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.61" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.61" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.87", ] [[package]] @@ -2431,7 +2433,7 @@ dependencies = [ "mio", "pin-project-lite", "socket2", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -2445,15 +2447,15 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.6" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" [[package]] name = "toml_edit" -version = "0.21.1" +version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ "indexmap", "toml_datetime", @@ -2493,9 +2495,9 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "typeid" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "059d83cc991e7a42fc37bd50941885db0888e34209f8cfd9aab07ddec03bc9cf" +checksum = "0e13db2e0ccd5e14a544e8a246ba2312cd25223f616442d7f2cb0e3db614236e" [[package]] name = "typenum" @@ -2505,9 +2507,9 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "typetag" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "661d18414ec032a49ece2d56eee03636e43c4e8d577047ab334c0ba892e29aaf" +checksum = "52ba3b6e86ffe0054b2c44f2d86407388b933b16cb0a70eea3929420db1d9bbe" dependencies = [ "erased-serde", "inventory", @@ -2518,35 +2520,32 @@ dependencies = [ [[package]] name = "typetag-impl" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac73887f47b9312552aa90ef477927ff014d63d1920ca8037c6c1951eab64bb1" +checksum = "70b20a22c42c8f1cd23ce5e34f165d4d37038f5b663ad20fb6adbdf029172483" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.87", ] [[package]] name = "unicase" -version = "2.7.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" -dependencies = [ - "version_check", -] +checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "uniffi" -version = "0.28.1" +version = "0.28.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2db87def739fe4183947f8419d572d1849a4a09355eba4e988a2105cfd0ac6a7" +checksum = "51ce6280c581045879e11b400bae14686a819df22b97171215d15549efa04ddb" dependencies = [ "anyhow", "camino", @@ -2560,9 +2559,9 @@ dependencies = [ [[package]] name = "uniffi_bindgen" -version = "0.28.1" +version = "0.28.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a112599c9556d1581e4a3d72019a74c2c3e122cc27f4af12577a429c4d5e614" +checksum = "5e9f25730c9db2e878521d606f54e921edb719cdd94d735e7f97705d6796d024" dependencies = [ "anyhow", "askama", @@ -2583,9 +2582,9 @@ dependencies = [ [[package]] name = "uniffi_build" -version = "0.28.1" +version = "0.28.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2b12684401d2a8508ca9c72a95bbc45906417e42fc80942abaf033bbf01aa33" +checksum = "88dba57ac699bd8ec53d6a352c8dd0e479b33f698c5659831bb1e4ce468c07bd" dependencies = [ "anyhow", "camino", @@ -2594,23 +2593,22 @@ dependencies = [ [[package]] name = "uniffi_checksum_derive" -version = "0.28.1" +version = "0.28.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a22dbe67c1c957ac6e7611bdf605a6218aa86b0eebeb8be58b70ae85ad7d73dc" +checksum = "d2c801f0f05b06df456a2da4c41b9c2c4fdccc6b9916643c6c67275c4c9e4d07" dependencies = [ "quote", - "syn 2.0.66", + "syn 2.0.87", ] [[package]] name = "uniffi_core" -version = "0.28.1" +version = "0.28.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a0c35aaad30e3a9e6d4fe34e358d64dbc92ee09045b48591b05fc9f12e0905b" +checksum = "61049e4db6212d0ede80982adf0e1d6fa224e6118387324c5cfbe3083dfb2252" dependencies = [ "anyhow", "bytes", - "camino", "log", "once_cell", "paste", @@ -2619,9 +2617,9 @@ dependencies = [ [[package]] name = "uniffi_macros" -version = "0.28.1" +version = "0.28.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db66474c5c61b0f7afc3b4995fecf9b72b340daa5ca0ef3da7778d75eb5482ea" +checksum = "b40fd2249e0c5dcbd2bfa3c263db1ec981f7273dca7f4132bf06a272359a586c" dependencies = [ "bincode", "camino", @@ -2630,16 +2628,16 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.66", + "syn 2.0.87", "toml", "uniffi_meta", ] [[package]] name = "uniffi_meta" -version = "0.28.1" +version = "0.28.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d898893f102e0e39b8bcb7e3d2188f4156ba280db32db9e8af1f122d057e9526" +checksum = "c9ad57039b4fafdbf77428d74fff40e0908e5a1731e023c19cfe538f6d4a8ed6" dependencies = [ "anyhow", "bytes", @@ -2649,9 +2647,9 @@ dependencies = [ [[package]] name = "uniffi_testing" -version = "0.28.1" +version = "0.28.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6aa4f0cf9d12172d84fc00a35a6c1f3522b526daad05ae739f709f6941b9b6" +checksum = "21fa171d4d258dc51bbd01893cc9608c1b62273d2f9ea55fb64f639e77824567" dependencies = [ "anyhow", "camino", @@ -2662,9 +2660,9 @@ dependencies = [ [[package]] name = "uniffi_udl" -version = "0.28.1" +version = "0.28.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b044e9c519e0bb51e516ab6f6d8f4f4dcf900ce30d5ad07c03f924e2824f28e" +checksum = "f52299e247419e7e2934bef2f94d7cccb0e6566f3248b1d48b160d8f369a2668" dependencies = [ "anyhow", "textwrap", @@ -2714,9 +2712,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "want" @@ -2755,7 +2753,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.87", "wasm-bindgen-shared", ] @@ -2789,7 +2787,7 @@ checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.87", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2858,6 +2856,15 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-targets" version = "0.52.6" @@ -2924,9 +2931,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.5.40" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" dependencies = [ "memchr", ] @@ -2972,7 +2979,7 @@ checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.87", "synstructure", ] @@ -2994,7 +3001,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.87", ] [[package]] @@ -3014,7 +3021,7 @@ checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.87", "synstructure", ] @@ -3035,7 +3042,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.87", ] [[package]] @@ -3057,5 +3064,5 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.87", ] diff --git a/packages/kos-mobile/src/lib.rs b/packages/kos-mobile/src/lib.rs index 04e9362..cc3271c 100644 --- a/packages/kos-mobile/src/lib.rs +++ b/packages/kos-mobile/src/lib.rs @@ -162,11 +162,10 @@ fn sign_transaction(account: KOSAccount, raw: String) -> Result Result, KOSError> { +fn sign_message(account: KOSAccount, hex: String) -> Result, KOSError> { let chain = get_chain_by(account.chain_id)?; - let message = message.as_bytes(); - let signature = - chain.sign_message(hex::decode(account.private_key).unwrap(), message.to_vec())?; + let message = hex::decode(hex)?; + let signature = chain.sign_message(hex::decode(account.private_key).unwrap(), message)?; Ok(signature) } @@ -390,7 +389,7 @@ mod tests { #[test] fn should_sign_message() { let chain_id = 38; - let message = "Hello World".to_string(); + let message = hex::encode("Hello World".as_bytes()); let account = generate_wallet_from_mnemonic( "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(), diff --git a/packages/kos/src/chains/btc/mod.rs b/packages/kos/src/chains/btc/mod.rs index f0c6188..a1d09e4 100644 --- a/packages/kos/src/chains/btc/mod.rs +++ b/packages/kos/src/chains/btc/mod.rs @@ -10,6 +10,7 @@ use alloc::{format, vec}; use bech32::{u5, Variant}; pub struct BTC { + pub id: u32, pub addr_prefix: String, pub symbol: String, pub name: String, @@ -19,11 +20,12 @@ pub struct BTC { impl BTC { pub fn new() -> Self { - BTC::new_btc_based("bc", "BTC", "Bitcoin") + BTC::new_btc_based(2, "bc", "BTC", "Bitcoin") } - pub fn new_btc_based(addr_prefix: &str, symbol: &str, name: &str) -> Self { + pub fn new_btc_based(id: u32, addr_prefix: &str, symbol: &str, name: &str) -> Self { BTC { + id, addr_prefix: addr_prefix.to_string(), symbol: symbol.to_string(), name: name.to_string(), @@ -32,8 +34,9 @@ impl BTC { } } - pub fn new_legacy_btc_based(legacy_version: u8, symbol: &str, name: &str) -> Self { + pub fn new_legacy_btc_based(id: u32, legacy_version: u8, symbol: &str, name: &str) -> Self { BTC { + id, addr_prefix: "".to_string(), symbol: symbol.to_string(), name: name.to_string(), @@ -87,7 +90,7 @@ impl BTC { impl Chain for BTC { fn get_id(&self) -> u32 { - 2 + self.id } fn get_name(&self) -> &str { self.name.as_str() @@ -194,7 +197,7 @@ mod test { let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); let path = "m/44'/3'/0'/0/0".to_string(); - let btc = BTC::new_legacy_btc_based(0x1e, "DOGE", "Dogecoin"); + let btc = BTC::new_legacy_btc_based(12, 0x1e, "DOGE", "Dogecoin"); let seed = btc.mnemonic_to_seed(mnemonic, "".to_string()).unwrap(); let pvk = btc.derive(seed, path).unwrap(); let pbk = btc.get_pbk(pvk).unwrap(); diff --git a/packages/kos/src/chains/mod.rs b/packages/kos/src/chains/mod.rs index 0e214d1..a7796b4 100644 --- a/packages/kos/src/chains/mod.rs +++ b/packages/kos/src/chains/mod.rs @@ -283,7 +283,7 @@ impl ChainRegistry { Box::new(substrate::Substrate::new(27, 2, "KSM", "Kusama")) }), (constants::LTC, || { - Box::new(btc::BTC::new_btc_based("ltc", "LTC", "Litecoin")) + Box::new(btc::BTC::new_btc_based(5, "ltc", "LTC", "Litecoin")) }), (constants::REEF, || { Box::new(substrate::Substrate::new(29, 42, "REEF", "Reef")) @@ -298,7 +298,7 @@ impl ChainRegistry { Box::new(substrate::Substrate::new(47, 36, "CFG", "Centrifuge")) }), (constants::SYS, || { - Box::new(btc::BTC::new_btc_based("sys", "SYS", "Syscoin")) + Box::new(btc::BTC::new_btc_based(15, "sys", "SYS", "Syscoin")) }), (constants::KILT, || { Box::new(substrate::Substrate::new(44, 38, "KILT", "KILT")) @@ -307,14 +307,14 @@ impl ChainRegistry { Box::new(substrate::Substrate::new(42, 136, "ALTAIR", "Altair")) }), (constants::DOGE, || { - Box::new(btc::BTC::new_legacy_btc_based(0x1E, "DOGE", "Dogecoin")) + Box::new(btc::BTC::new_legacy_btc_based(12, 0x1E, "DOGE", "Dogecoin")) }), (constants::DASH, || { - Box::new(btc::BTC::new_legacy_btc_based(0x4C, "DASH", "Dash")) + Box::new(btc::BTC::new_legacy_btc_based(11, 0x4C, "DASH", "Dash")) }), (constants::XRP, || Box::new(xrp::XRP::new())), (constants::DGB, || { - Box::new(btc::BTC::new_btc_based("dgb", "DGB", "Digibyte")) + Box::new(btc::BTC::new_btc_based(16, "dgb", "DGB", "Digibyte")) }), (constants::COSMOS, || Box::new(atom::ATOM::new())), (constants::CELESTIA, || { From aff76f72623ca158f7523e85beee6627bfbf25df Mon Sep 17 00:00:00 2001 From: Jordan Date: Thu, 14 Nov 2024 10:34:14 -0300 Subject: [PATCH 16/42] update android build config --- packages/kos-mobile/android/lib/build.gradle.kts | 7 ++++++- packages/kos/Cargo.toml | 3 +++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/kos-mobile/android/lib/build.gradle.kts b/packages/kos-mobile/android/lib/build.gradle.kts index 9fd6331..f04208d 100644 --- a/packages/kos-mobile/android/lib/build.gradle.kts +++ b/packages/kos-mobile/android/lib/build.gradle.kts @@ -34,7 +34,12 @@ android { } dependencies { - implementation(libs.java.jna) + implementation(libs.java.jna) { + artifact { + extension ="aar" + type = "aar" + } + } testImplementation(libs.junit) } diff --git a/packages/kos/Cargo.toml b/packages/kos/Cargo.toml index ca819f6..1a3c3a8 100644 --- a/packages/kos/Cargo.toml +++ b/packages/kos/Cargo.toml @@ -45,6 +45,9 @@ bip39-dict = { version = "0.1.0", features = ["english"], default-features = fal libsecp256k1 = { version = "0.7.1", features = ["hmac", "static-context"], default-features = false } rand_core = { version = "0.6.4", default-features = false } parity-scale-codec = { version = "3.6.9", default-features = false, features = ["derive"] } +rand = { workspace = true } +coins-bip32 = { workspace = true } +coins-bip39 = { workspace = true } [target.'cfg(target_arch = "x86_64")'.dependencies] rand_core = { version = "0.6.4", features = ["getrandom"], default-features = false } From 759508a0b448dd233fb3673fa3a5b8dd22ebae83 Mon Sep 17 00:00:00 2001 From: Patrick Monteiro Date: Thu, 14 Nov 2024 15:58:32 -0300 Subject: [PATCH 17/42] add android feature checking --- packages/kos/Cargo.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/kos/Cargo.toml b/packages/kos/Cargo.toml index 1a3c3a8..85531a2 100644 --- a/packages/kos/Cargo.toml +++ b/packages/kos/Cargo.toml @@ -45,6 +45,8 @@ bip39-dict = { version = "0.1.0", features = ["english"], default-features = fal libsecp256k1 = { version = "0.7.1", features = ["hmac", "static-context"], default-features = false } rand_core = { version = "0.6.4", default-features = false } parity-scale-codec = { version = "3.6.9", default-features = false, features = ["derive"] } + +[target.'cfg(feature = "android")'.dependencies] rand = { workspace = true } coins-bip32 = { workspace = true } coins-bip39 = { workspace = true } @@ -65,3 +67,4 @@ heck = "0.4.1" [features] ksafe = [] +android = [] \ No newline at end of file From 8de5c55d64f966ef041138c013a6b644b63adcc5 Mon Sep 17 00:00:00 2001 From: Patrick Monteiro Date: Thu, 14 Nov 2024 18:20:14 -0300 Subject: [PATCH 18/42] add f64 and string methods for bignum type --- Cargo.lock | 1 + packages/kos/src/crypto/bignum.rs | 70 +++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 134a782..21093f2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1310,6 +1310,7 @@ dependencies = [ "bech32", "bip39-dict", "blake2b-ref", + "coins-bip32", "coins-bip39", "ed25519-dalek", "heck 0.4.1", diff --git a/packages/kos/src/crypto/bignum.rs b/packages/kos/src/crypto/bignum.rs index 303984c..c7fc086 100644 --- a/packages/kos/src/crypto/bignum.rs +++ b/packages/kos/src/crypto/bignum.rs @@ -1,5 +1,7 @@ +use alloc::string::{String, ToString}; use alloc::vec::Vec; use core::f64; +use core::fmt::Write; use rlp::{DecoderError, Rlp, RlpStream}; pub struct U256(pub [u8; 32]); @@ -32,6 +34,21 @@ impl rlp::Encodable for U256 { } impl U256 { + #[allow(dead_code)] + pub fn from_f64(value: f64, precision: u32) -> Result { + if value.is_nan() || value.is_infinite() || value < 0.0 { + return Err("Invalid input: NaN, infinity, or negative value."); + } + + let scaled_value = value * powi(10.0, precision as i32); + if scaled_value > (u64::MAX as f64) { + return Err("Input too large to fit in U256."); + } + + let integer_value = scaled_value as u64; + Ok(U256::from_u64(integer_value)) + } + pub fn to_f64(&self, precision: u32) -> f64 { let bytes = self.0; let mut value: f64 = 0.0; @@ -56,6 +73,40 @@ impl U256 { U256(bytes) } + #[allow(dead_code)] + pub fn from_string(value: &str) -> Result { + if value.len() > 64 { + return Err("String length exceeds U256 size."); + } + + let mut padded = String::new(); + for _ in 0..(64 - value.len()) { + // Zero-padding to ensure 64 characters. + padded.push('0'); + } + padded.push_str(value); + + let bytes = hex::decode(&padded).map_err(|_| "Invalid hex string")?; + let mut data = [0u8; 32]; + data.copy_from_slice(&bytes); + Ok(U256(data)) + } + + #[allow(dead_code)] + pub fn to_string(&self) -> String { + let mut hex_string = String::new(); + for byte in self.0.iter() { + write!(&mut hex_string, "{:02x}", byte).unwrap(); // Safely format bytes as hex. + } + + let trimmed = hex_string.trim_start_matches('0'); + if trimmed.is_empty() { + "0".to_string() + } else { + trimmed.to_string() + } + } + #[allow(dead_code)] pub fn to_u64_be(&self) -> u64 { let bytes = self.0; @@ -148,5 +199,24 @@ mod test { let precision = 6; let float_value = value.to_f64(precision); assert_eq!(float_value, 1e-6); + + let reconstructed = U256::from_f64(float_value, precision).unwrap(); + assert_eq!(reconstructed.0, value.0); + + let large_value = 12345.6789; + let large_precision = 4; + let u256_value = U256::from_f64(large_value, large_precision).unwrap(); + let back_to_f64 = u256_value.to_f64(large_precision); + assert_eq!(back_to_f64, large_value); + } + + #[test] + fn test_string_conversion() { + let value = U256::from_u64(123456789); + let hex_string = value.to_string(); + assert_eq!(hex_string, "75bcd15"); + + let parsed = U256::from_string(&hex_string).unwrap(); + assert_eq!(parsed.0, value.0); } } From 7e5b780f1a93269fbf51b8f321b0fa932c2d7cba Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Mon, 18 Nov 2024 21:59:51 -0300 Subject: [PATCH 19/42] feat: kos-web wallet manager --- Cargo.lock | 184 ++++++++++++++++- packages/kos-crypto/src/lib.rs | 1 + packages/kos-crypto/src/mnemonic.rs | 16 ++ packages/kos-mobile/src/lib.rs | 4 +- packages/kos-web/Cargo.toml | 19 ++ packages/kos-web/src/lib.rs | 17 +- packages/kos-web/src/models.rs | 45 ++++ packages/kos-web/src/utils.rs | 13 ++ packages/kos-web/src/wallet.rs | 305 ++++++++++++++++++++++++++++ packages/kos/Cargo.toml | 2 - packages/kos/src/crypto/mnemonic.rs | 17 -- packages/kos/src/crypto/mod.rs | 1 - 12 files changed, 586 insertions(+), 38 deletions(-) create mode 100644 packages/kos-crypto/src/mnemonic.rs create mode 100644 packages/kos-web/src/models.rs create mode 100644 packages/kos-web/src/utils.rs create mode 100644 packages/kos-web/src/wallet.rs delete mode 100644 packages/kos/src/crypto/mnemonic.rs diff --git a/Cargo.lock b/Cargo.lock index 082a923..5f3d1c5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -169,6 +169,15 @@ dependencies = [ "nom", ] +[[package]] +name = "atomic-polyfill" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" +dependencies = [ + "critical-section", +] + [[package]] name = "autocfg" version = "1.3.0" @@ -478,6 +487,12 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" +[[package]] +name = "cobs" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" + [[package]] name = "coins-bip32" version = "0.8.7" @@ -551,6 +566,12 @@ dependencies = [ "libc", ] +[[package]] +name = "critical-section" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" + [[package]] name = "crunchy" version = "0.2.2" @@ -738,6 +759,54 @@ dependencies = [ "zeroize", ] +[[package]] +name = "embedded-io" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" + +[[package]] +name = "embedded-io" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" + +[[package]] +name = "enum_delegate" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8ea75f31022cba043afe037940d73684327e915f88f62478e778c3de914cd0a" +dependencies = [ + "enum_delegate_lib", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "enum_delegate_lib" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e1f6c3800b304a6be0012039e2a45a322a093539c45ab818d9e6895a39c90fe" +dependencies = [ + "proc-macro2", + "quote", + "rand", + "syn 1.0.109", +] + +[[package]] +name = "enum_dispatch" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa18ce2bc66555b3218614519ac839ddb759a7d6720732f979ef8d13be147ecd" +dependencies = [ + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "equivalent" version = "1.0.1" @@ -930,12 +999,35 @@ dependencies = [ "subtle", ] +[[package]] +name = "hash32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +dependencies = [ + "byteorder", +] + [[package]] name = "hashbrown" version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +[[package]] +name = "heapless" +version = "0.7.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" +dependencies = [ + "atomic-polyfill", + "hash32", + "rustc_version", + "serde", + "spin", + "stable_deref_trait", +] + [[package]] name = "heck" version = "0.4.1" @@ -1310,7 +1402,6 @@ dependencies = [ "bech32", "bip39-dict", "blake2b-ref", - "coins-bip39", "ed25519-dalek", "heck 0.4.1", "hex", @@ -1325,7 +1416,6 @@ dependencies = [ "prost-wkt-build", "prost-wkt-types", "quote", - "rand", "rand_core", "ripemd", "rlp", @@ -1399,7 +1489,20 @@ dependencies = [ name = "kos-web" version = "0.1.2" dependencies = [ + "enum_delegate", + "enum_dispatch", + "hex", "kos", + "kos-crypto", + "kos-types", + "lazy_static", + "pem", + "postcard", + "serde", + "serde-wasm-bindgen", + "serde_json", + "strum", + "wasm-bindgen", ] [[package]] @@ -1474,6 +1577,16 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + [[package]] name = "log" version = "0.4.21" @@ -1725,6 +1838,19 @@ dependencies = [ "universal-hash", ] +[[package]] +name = "postcard" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f7f0a8d620d71c457dd1d47df76bb18960378da56af4527aaa10f515eee732e" +dependencies = [ + "cobs", + "embedded-io 0.4.0", + "embedded-io 0.6.1", + "heapless", + "serde", +] + [[package]] name = "ppv-lite86" version = "0.2.20" @@ -2033,6 +2159,12 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "rustversion" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" + [[package]] name = "ryu" version = "1.0.18" @@ -2056,6 +2188,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + [[package]] name = "scroll" version = "0.12.0" @@ -2129,6 +2267,17 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde-wasm-bindgen" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3b143e2833c57ab9ad3ea280d21fd34e285a42837aeb0ee301f4f41890fa00e" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + [[package]] name = "serde_derive" version = "1.0.203" @@ -2252,6 +2401,15 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + [[package]] name = "spki" version = "0.7.3" @@ -2280,6 +2438,28 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "strum" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.66", +] + [[package]] name = "subtle" version = "2.5.0" diff --git a/packages/kos-crypto/src/lib.rs b/packages/kos-crypto/src/lib.rs index 91697c5..60550d1 100644 --- a/packages/kos-crypto/src/lib.rs +++ b/packages/kos-crypto/src/lib.rs @@ -1,3 +1,4 @@ mod blake2b; pub mod cipher; pub mod hash; +pub mod mnemonic; diff --git a/packages/kos-crypto/src/mnemonic.rs b/packages/kos-crypto/src/mnemonic.rs new file mode 100644 index 0000000..9c1cd2c --- /dev/null +++ b/packages/kos-crypto/src/mnemonic.rs @@ -0,0 +1,16 @@ +use kos_types::error::Error; + +use coins_bip39::{English, Mnemonic}; + +pub fn generate_mnemonic(count: usize) -> Result, Error> { + // create rng + let mut rng = rand::thread_rng(); + // generate mnemonic phrase + Ok(Mnemonic::::new_with_count(&mut rng, count)?) +} + +pub fn validate_mnemonic(phrase: &str) -> Result<(), Error> { + // validate mnemonic phrase + let _mnemonic: Mnemonic = phrase.parse()?; + Ok(()) +} diff --git a/packages/kos-mobile/src/lib.rs b/packages/kos-mobile/src/lib.rs index 04e9362..4298b6e 100644 --- a/packages/kos-mobile/src/lib.rs +++ b/packages/kos-mobile/src/lib.rs @@ -54,12 +54,12 @@ struct KOSTransaction { #[uniffi::export] fn generate_mnemonic(size: i32) -> Result { - Ok(kos::crypto::mnemonic::generate_mnemonic(size as usize)?.to_phrase()) + Ok(kos_crypto::mnemonic::generate_mnemonic(size as usize)?.to_phrase()) } #[uniffi::export] fn validate_mnemonic(mnemonic: String) -> bool { - kos::crypto::mnemonic::validate_mnemonic(mnemonic.as_str()).is_ok() + kos_crypto::mnemonic::validate_mnemonic(mnemonic.as_str()).is_ok() } #[uniffi::export] diff --git a/packages/kos-web/Cargo.toml b/packages/kos-web/Cargo.toml index 0923ed7..3e398fe 100644 --- a/packages/kos-web/Cargo.toml +++ b/packages/kos-web/Cargo.toml @@ -8,5 +8,24 @@ repository.workspace = true rust-version.workspace = true version.workspace = true +[lib] +crate-type = ["cdylib", "rlib"] + +[features] +default = ["serde"] + [dependencies] +strum = { version = "0.25", features = ["derive"] } +serde = { workspace = true, features = ["derive"], optional = true } +serde_json = { workspace = true } +serde-wasm-bindgen = "0.5" +enum_delegate = { workspace = true } +hex = { workspace = true } +enum_dispatch = "0.3" +pem = "3" +postcard = { version = "1.0.6", features = ["use-std"] } +lazy_static = { workspace = true } kos = { workspace = true } +kos-crypto = { workspace = true } +kos-types = { workspace = true } +wasm-bindgen = { workspace = true } diff --git a/packages/kos-web/src/lib.rs b/packages/kos-web/src/lib.rs index b93cf3f..83c570c 100644 --- a/packages/kos-web/src/lib.rs +++ b/packages/kos-web/src/lib.rs @@ -1,14 +1,3 @@ -pub fn add(left: u64, right: u64) -> u64 { - left + right -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); - } -} +mod models; +mod utils; +pub mod wallet; diff --git a/packages/kos-web/src/models.rs b/packages/kos-web/src/models.rs new file mode 100644 index 0000000..a9d029c --- /dev/null +++ b/packages/kos-web/src/models.rs @@ -0,0 +1,45 @@ +use serde::{Deserialize, Serialize}; +use wasm_bindgen::prelude::*; + +#[derive(Default, Deserialize, Serialize, Clone, Debug)] +#[wasm_bindgen] +pub struct PathOptions { + #[wasm_bindgen(skip)] + pub index: u32, + #[wasm_bindgen(skip)] + pub is_legacy: Option, +} + +#[wasm_bindgen] +impl PathOptions { + #[wasm_bindgen(constructor)] + pub fn constructor() -> Self { + Self::default() + } + + pub fn new(index: u32) -> Self { + Self { + index, + is_legacy: Some(false), + } + } + #[wasm_bindgen(js_name = setIndex)] + pub fn set_index(&mut self, index: u32) { + self.index = index; + } + #[wasm_bindgen(js_name = setLegacy)] + pub fn set_legacy(&mut self, is_legacy: bool) { + self.is_legacy = Some(is_legacy); + } +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[wasm_bindgen] +pub struct Transaction { + #[wasm_bindgen(skip)] + pub raw_data: Vec, + #[wasm_bindgen(skip)] + pub tx_hash: Vec, + #[wasm_bindgen(skip)] + pub signature: Vec, +} diff --git a/packages/kos-web/src/utils.rs b/packages/kos-web/src/utils.rs new file mode 100644 index 0000000..59d8f0c --- /dev/null +++ b/packages/kos-web/src/utils.rs @@ -0,0 +1,13 @@ +use kos_types::error::Error; +use serde::{Deserialize, Serialize}; + +pub fn pack(t: &T) -> Result, Error> +where + T: Serialize + ?Sized, +{ + postcard::to_stdvec(t).map_err(|e| Error::InvalidString(e.to_string())) +} + +pub fn unpack<'a, T: Deserialize<'a>>(bytes: &'a [u8]) -> Result { + postcard::from_bytes(bytes).map_err(|e| Error::InvalidString(e.to_string())) +} diff --git a/packages/kos-web/src/wallet.rs b/packages/kos-web/src/wallet.rs new file mode 100644 index 0000000..0259537 --- /dev/null +++ b/packages/kos-web/src/wallet.rs @@ -0,0 +1,305 @@ +use crate::models::{PathOptions, Transaction}; + +use pem::{encode as encode_pem, parse as parse_pem, Pem}; +use serde::{Deserialize, Serialize}; +use strum::{EnumCount, IntoStaticStr}; + +use crate::utils::{pack, unpack}; +use kos::chains::{get_chain_by_base_id, Chain, Transaction as KosTransaction}; +use kos_types::error::Error; +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Copy, EnumCount, IntoStaticStr)] +pub enum AccountType { + Mnemonic, + PrivateKey, + KleverSafe, + ReadOnly, +} + +#[wasm_bindgen] +#[derive(Debug, Clone)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct Wallet { + chain: u32, + account_type: AccountType, + public_address: String, + index: Option, + encrypted_data: Option>, + mnemonic: Option, + private_key: Option, + path: Option, +} + +#[wasm_bindgen] +impl Wallet { + #[wasm_bindgen(js_name = "fromMnemonic")] + /// restore wallet from mnemonic + pub fn from_mnemonic( + chain_id: u32, + mnemonic: String, + path: String, + password: Option, + ) -> Result { + // validate mnemonic entropy + kos_crypto::mnemonic::validate_mnemonic(&mnemonic)?; + + let chain = get_chain_by_base_id(chain_id) + .ok_or_else(|| Error::WalletManagerError("Invalid chain".to_string()))?; + + let seed = chain + .mnemonic_to_seed(mnemonic.clone(), String::from("")) + .map_err(|e| { + Error::WalletManagerError(format!("mnemonic to seed: {}", e.to_string())) + })?; + let private_key = chain + .derive(seed, path.clone()) + .map_err(|e| Error::WalletManagerError(format!("derive keypair: {}", e.to_string())))?; + + let public_key = chain + .get_pbk(private_key.clone()) + .map_err(|e| Error::WalletManagerError(format!("get public key: {}", e.to_string())))?; + let address = chain + .get_address(public_key) + .map_err(|e| Error::WalletManagerError(format!("get address: {}", e.to_string())))?; + + Ok(Wallet { + chain: chain_id, + account_type: AccountType::Mnemonic, + public_address: address, + index: None, + encrypted_data: None, + private_key: Some(hex::encode(private_key)), + mnemonic: Some(mnemonic), + path: Some(path), + }) + } + + #[wasm_bindgen(js_name = "fromMnemonicIndex")] + /// restore wallet from mnemonic + pub fn from_mnemonic_index( + chain_id: u32, + mnemonic: String, + path_options: &PathOptions, + password: Option, + ) -> Result { + let chain = get_chain_by_base_id(chain_id) + .ok_or_else(|| Error::WalletManagerError("Invalid chain".to_string()))?; + let path = chain.get_path(path_options.index, path_options.is_legacy.unwrap()); + + let mut wallet = Wallet::from_mnemonic(chain_id, mnemonic, path, password)?; + wallet.index = Some(path_options.index); + + Ok(wallet) + } + + #[wasm_bindgen(js_name = "fromPrivateKey")] + /// restore wallet from mnemonic + pub fn from_private_key(chain_id: u32, private_key: String) -> Result { + // convert hex to bytes + let private_key_bytes = hex::decode(private_key.clone())?; + + // check size of private key + if private_key_bytes.len() != 32 { + return Err(Error::WalletManagerError("Invalid private key".to_string())); + } + + let chain = get_chain_by_base_id(chain_id) + .ok_or_else(|| Error::WalletManagerError("Invalid chain".to_string()))?; + + let public_key = chain + .get_pbk(hex::decode(private_key_bytes.clone())?) + .map_err(|e| Error::WalletManagerError(format!("get public key: {}", e.to_string())))?; + let address = chain + .get_address(public_key.clone()) + .map_err(|e| Error::WalletManagerError(format!("get address: {}", e.to_string())))?; + + // create wallet from keypair + Ok(Wallet { + chain: chain_id, + account_type: AccountType::PrivateKey, + public_address: address, + index: None, + encrypted_data: None, + mnemonic: None, + private_key: Some(private_key), + path: None, + }) + } + + #[wasm_bindgen(js_name = "fromKCPem")] + /// restore wallet from mnemonic + pub fn from_kc_pem(chain: u32, data: &[u8]) -> Result { + // decode pem file + let pem = parse_pem(data) + .map_err(|_| Error::WalletManagerError("Invalid PEM data".to_string()))?; + + let content = String::from_utf8(pem.contents().to_vec()) + .map_err(|_| Error::WalletManagerError("Invalid PEM data".to_string()))?; + + let pk_hex = content.chars().take(64).collect::(); + + // import from private key + Wallet::from_private_key(chain, pk_hex) + } + + #[wasm_bindgen(js_name = "fromPem")] + pub fn from_pem(data: &[u8]) -> Result { + // parse pem + let pem = parse_pem(data) + .map_err(|_| Error::WalletManagerError("Invalid PEM data".to_string()))?; + + Wallet::import(pem) + } +} + +// wallet properties +impl Wallet { + pub fn import(pem: Pem) -> Result { + // Deserialize decrypted bytes to WalletManager + let wallet: Wallet = unpack(pem.contents()) + .map_err(|e| Error::CipherError(format!("deserialize data: {}", e)))?; + + Ok(wallet) + } +} + +#[wasm_bindgen] +// wallet properties +impl Wallet { + // #[wasm_bindgen(js_name = "getChain")] + // /// get wallet chain type + // pub fn get_chain(&self) -> Chain { + // self.chain + // } + + #[wasm_bindgen(js_name = "getAccountType")] + /// get wallet account type + pub fn get_account_type(&self) -> AccountType { + self.account_type + } + + #[wasm_bindgen(js_name = "getAddress")] + /// get wallet address + pub fn get_address(&self) -> String { + self.public_address.clone() + } + + #[wasm_bindgen(js_name = "getPath")] + /// get wallet path if wallet is created from mnemonic + pub fn get_path(&self) -> String { + match self.path { + Some(ref path) => path.clone(), + None => String::new(), + } + } + + #[wasm_bindgen(js_name = "getIndex")] + /// get wallet index if wallet is created from mnemonic index + pub fn get_index(&self) -> Result { + self.index.ok_or(Error::WalletManagerError( + "Wallet is not created from mnemonic index".to_string(), + )) + } + + #[wasm_bindgen(js_name = "getPrivateKey")] + /// get wallet private key + pub fn get_private_key(&self) -> String { + match self.private_key { + Some(ref pk) => pk.clone(), + None => String::new(), + } + } + + #[wasm_bindgen(js_name = "getMnemonic")] + /// get wallet mnemonic if wallet is created from mnemonic + pub fn get_mnemonic(&self) -> String { + match self.mnemonic { + Some(ref mnemonic) => mnemonic.clone(), + None => String::new(), + } + } +} + +#[wasm_bindgen] +// wallet methods +impl Wallet { + #[wasm_bindgen(js_name = "signMessage")] + /// sign message with keypair + pub fn sign_message(&self, message: &[u8]) -> Result, Error> { + match self.private_key { + Some(ref pk_hex) => { + let pk_bytes = hex::decode(pk_hex)?; + let chain = get_chain_by_base_id(self.chain) + .ok_or_else(|| Error::WalletManagerError("Invalid chain".to_string()))?; + + chain + .sign_message(pk_bytes, message.to_vec()) + .or_else(|e| Err(Error::WalletManagerError(format!("sign message: {}", e)))) + } + None => Err(Error::WalletManagerError("no keypair".to_string())), + } + } + + #[wasm_bindgen(js_name = "sign")] + pub fn sign(&self, tx_raw: &[u8]) -> Result { + match self.private_key { + Some(ref pk_hex) => { + let pk_bytes = hex::decode(pk_hex)?; + + let tx = KosTransaction { + raw_data: tx_raw.to_vec(), + signature: vec![], + tx_hash: vec![], + }; + + let chain = get_chain_by_base_id(self.chain) + .ok_or_else(|| Error::WalletManagerError("Invalid chain".to_string()))?; + + let signed_tx = chain.sign_tx(pk_bytes, tx).or_else(|e| { + Err(Error::WalletManagerError(format!( + "sign transaction: {}", + e + ))) + })?; + + Ok(Transaction { + raw_data: signed_tx.raw_data, + tx_hash: signed_tx.tx_hash, + signature: signed_tx.signature, + }) + } + None => Err(Error::WalletManagerError("no keypair".to_string())), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use kos::chains::get_chain_by_base_id; + + #[test] + fn test_export_import() { + let default_password = "password"; + + let chain = get_chain_by_base_id(38).unwrap(); + + // create wallet + let mut w1 = Wallet::from_mnemonic( + 38, + "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(), + chain.get_path(0, false), + None, + ).unwrap(); + + // check if secret keys restored + assert_eq!( + w1.get_private_key(), + "8734062c1158f26a3ca8a4a0da87b527a7c168653f7f4c77045e5cf571497d9d" + ); + assert_eq!(w1.get_mnemonic(), "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"); + assert_eq!(w1.get_path(), "m/44'/690'/0'/0'/0'"); + } +} diff --git a/packages/kos/Cargo.toml b/packages/kos/Cargo.toml index 32df0d5..2fe7e8d 100644 --- a/packages/kos/Cargo.toml +++ b/packages/kos/Cargo.toml @@ -44,8 +44,6 @@ pbkdf2 = { version = "0.12.2 ", features = ["sha2", "hmac", "password-hash"], de bip39-dict = { version = "0.1.0", features = ["english"], default-features = false } libsecp256k1 = { version = "0.7.1", features = ["hmac", "static-context"], default-features = false } rand_core = { version = "0.6.4", default-features = false } -rand = "0.8" -coins-bip39 = { version = "0.8", default-features = false, features = ["english"] } parity-scale-codec = { version = "3.6.9", default-features = false, features = ["derive"] } [target.'cfg(target_arch = "x86_64")'.dependencies] diff --git a/packages/kos/src/crypto/mnemonic.rs b/packages/kos/src/crypto/mnemonic.rs deleted file mode 100644 index e11f42c..0000000 --- a/packages/kos/src/crypto/mnemonic.rs +++ /dev/null @@ -1,17 +0,0 @@ -use crate::chains::ChainError; -use crate::crypto::bip32::Bip32Err; -use coins_bip39::{English, Mnemonic}; - -pub fn generate_mnemonic(count: usize) -> Result, ChainError> { - // create rng - let mut rng = rand::thread_rng(); - // generate mnemonic phrase - Ok(Mnemonic::::new_with_count(&mut rng, count) - .map_err(|_| Bip32Err::InvalidMnemonic)?) -} - -pub fn validate_mnemonic(phrase: &str) -> Result<(), ChainError> { - // validate mnemonic phrase - let _mnemonic: Mnemonic = phrase.parse().map_err(|_| Bip32Err::InvalidMnemonic)?; - Ok(()) -} diff --git a/packages/kos/src/crypto/mod.rs b/packages/kos/src/crypto/mod.rs index eee419a..39c5441 100644 --- a/packages/kos/src/crypto/mod.rs +++ b/packages/kos/src/crypto/mod.rs @@ -5,7 +5,6 @@ pub mod bip32; pub mod ed25519; mod ed25519_bip32; pub mod hash; -pub mod mnemonic; mod pbkdf2; mod rng; pub mod secp256k1; From 8b10edb77e67eb09ce322e0b5c8baa9bca00a0a0 Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Mon, 18 Nov 2024 22:27:30 -0300 Subject: [PATCH 20/42] fix: wasm_bindgen binds --- Cargo.lock | 117 ++++++++++++++++++++++++++++++++- Makefile | 4 +- packages/kos-web/Cargo.toml | 1 + packages/kos-web/src/lib.rs | 61 +++++++++++++++++ packages/kos/Cargo.toml | 7 +- packages/kos/src/crypto/mod.rs | 2 +- 6 files changed, 183 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 53dd470..227d83f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -277,6 +277,12 @@ dependencies = [ "bitcoin-private", ] +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + [[package]] name = "bitflags" version = "2.6.0" @@ -350,6 +356,12 @@ version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" +[[package]] +name = "bytemuck" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8334215b81e418a0a7bdb8ef0849474f40bb10c8b71f1c4ed315cff49f32494d" + [[package]] name = "byteorder" version = "1.5.0" @@ -545,6 +557,12 @@ dependencies = [ "thiserror", ] +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + [[package]] name = "colorchoice" version = "1.0.3" @@ -566,6 +584,15 @@ dependencies = [ "libc", ] +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + [[package]] name = "critical-section" version = "1.2.0" @@ -839,6 +866,15 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" +[[package]] +name = "fdeflate" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07c6f4c64c1d33a3111c4466f7365ebdcc37c5bd1ea0d62aae2e3d722aacbedb" +dependencies = [ + "simd-adler32", +] + [[package]] name = "ff" version = "0.13.0" @@ -861,6 +897,16 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" +[[package]] +name = "flate2" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + [[package]] name = "fnv" version = "1.0.7" @@ -942,8 +988,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi", + "wasm-bindgen", ] [[package]] @@ -1082,6 +1130,15 @@ dependencies = [ "hmac 0.8.1", ] +[[package]] +name = "html-escape" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d1ad449764d627e22bfd7cd5e8868264fc9236e07c752972b4080cd351cb476" +dependencies = [ + "utf8-width", +] + [[package]] name = "http" version = "1.1.0" @@ -1299,6 +1356,19 @@ dependencies = [ "icu_properties", ] +[[package]] +name = "image" +version = "0.24.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "num-traits", + "png", +] + [[package]] name = "impl-trait-for-tuples" version = "0.2.2" @@ -1405,6 +1475,7 @@ dependencies = [ "coins-bip32", "coins-bip39", "ed25519-dalek", + "getrandom", "heck 0.4.1", "hex", "hmac 0.12.1", @@ -1501,6 +1572,7 @@ dependencies = [ "lazy_static", "pem", "postcard", + "qrcode-generator", "serde", "serde-wasm-bindgen", "serde_json", @@ -1643,6 +1715,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" dependencies = [ "adler2", + "simd-adler32", ] [[package]] @@ -1829,6 +1902,19 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" +[[package]] +name = "png" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52f9d46a34a05a6a57566bc2bfae066ef07585a6e3fa30fbbdff5936380623f0" +dependencies = [ + "bitflags 1.3.2", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + [[package]] name = "polyval" version = "0.6.2" @@ -1990,6 +2076,23 @@ dependencies = [ "serde_json", ] +[[package]] +name = "qrcode-generator" +version = "4.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d06cb9646c7a14096231a2474d7f21e5e8c13de090c68d13bde6157cfe7f159" +dependencies = [ + "html-escape", + "image", + "qrcodegen", +] + +[[package]] +name = "qrcodegen" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4339fc7a1021c9c1621d87f5e3505f2805c8c105420ba2f2a4df86814590c142" + [[package]] name = "quote" version = "1.0.37" @@ -2155,7 +2258,7 @@ version = "0.38.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99e4ea3e1cdc4b559b8e5650f9c8e5998e3e5c1343b4eaf034565f32318d63c0" dependencies = [ - "bitflags", + "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", @@ -2377,6 +2480,12 @@ dependencies = [ "rand_core", ] +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + [[package]] name = "siphasher" version = "0.3.11" @@ -2881,6 +2990,12 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" +[[package]] +name = "utf8-width" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3" + [[package]] name = "utf8_iter" version = "1.0.4" diff --git a/Makefile b/Makefile index feadc9b..19ab23f 100644 --- a/Makefile +++ b/Makefile @@ -31,10 +31,10 @@ grcov: # grcov ./target/debug/ -s . -t lcov --llvm --branch --ignore-not-existing --ignore "/*" -o lcov.info webpack: - wasm-pack build --scope klever --target web --out-name index --out-dir ../../demo/kos ./packages/kos + wasm-pack build --scope klever --target web --out-name index --out-dir ../../demo/kos ./packages/kos-web webpack-npm: - wasm-pack build --scope klever --target bundler --release --out-name index --out-dir ../../demo/kos ./packages/kos + wasm-pack build --scope klever --target bundler --release --out-name index --out-dir ../../demo/kos ./packages/kos-web clean-mobile-build: cd packages/kos-mobile && ./build_clean.sh diff --git a/packages/kos-web/Cargo.toml b/packages/kos-web/Cargo.toml index 3e398fe..c0771f9 100644 --- a/packages/kos-web/Cargo.toml +++ b/packages/kos-web/Cargo.toml @@ -19,6 +19,7 @@ strum = { version = "0.25", features = ["derive"] } serde = { workspace = true, features = ["derive"], optional = true } serde_json = { workspace = true } serde-wasm-bindgen = "0.5" +qrcode-generator = "4.1" enum_delegate = { workspace = true } hex = { workspace = true } enum_dispatch = "0.3" diff --git a/packages/kos-web/src/lib.rs b/packages/kos-web/src/lib.rs index 83c570c..5d97a52 100644 --- a/packages/kos-web/src/lib.rs +++ b/packages/kos-web/src/lib.rs @@ -1,3 +1,64 @@ +use kos_crypto::cipher; +use kos_crypto::cipher::CipherAlgo; +use kos_crypto::mnemonic::generate_mnemonic; +use kos_types::error::Error; +use qrcode_generator::QrCodeEcc; +use wasm_bindgen::prelude::*; + mod models; mod utils; + pub mod wallet; + +/// Generates a random mnemonic phrase given the number of words to generate, `count`. +#[wasm_bindgen(js_name = "generateMnemonicPhrase")] +pub fn generate_mnemonic_phrase(count: usize) -> Result { + Ok(generate_mnemonic(count)?.to_phrase()) +} + +/// Converts the given string to bytes. +#[wasm_bindgen(js_name = "toBytes")] +pub fn to_bytes(data: &str) -> Result, Error> { + Ok(data.as_bytes().to_vec()) +} + +/// Converts the given bytes to a string. +#[wasm_bindgen(js_name = "toString")] +pub fn to_string(data: &[u8]) -> Result { + String::from_utf8(data.to_vec()) + .map_err(|e| Error::InvalidString(format!("Invalid UTF-8 string: {}", e))) +} + +/// Encrypts the given data with the given password. +#[wasm_bindgen(js_name = "encrypt")] +pub fn encrypt(algo: CipherAlgo, data: &[u8], password: &str) -> Result, Error> { + algo.encrypt(data, password) +} + +/// Decrypts the given data with the given password. +/// Data will have the algorithm tag prepended to it (1 byte). +#[wasm_bindgen(js_name = "decrypt")] +pub fn decrypt(data: &[u8], password: &str) -> Result, Error> { + cipher::decrypt(data, password) +} + +/// Create pem file from tag and data +#[wasm_bindgen(js_name = "toPem")] +pub fn to_pem(tag: String, data: &[u8]) -> Result { + let result = cipher::to_pem(tag, data)?; + Ok(result.to_string()) +} + +/// Decrypt pem file to bytes +#[wasm_bindgen(js_name = "fromPem")] +pub fn from_pem(data: &str, password: &str) -> Result, Error> { + let pem = cipher::string_to_pem(data)?; + decrypt(pem.contents(), password) +} + +/// Create QRCode based on data +#[wasm_bindgen(js_name = "generateQR")] +pub fn generate_qr(data: &str) -> Result, Error> { + qrcode_generator::to_png_to_vec(data, QrCodeEcc::Low, 1024) + .map_err(|e| Error::InvalidString(format!("Invalid QRCode data: {}", e))) +} diff --git a/packages/kos/Cargo.toml b/packages/kos/Cargo.toml index 85531a2..e66f0c0 100644 --- a/packages/kos/Cargo.toml +++ b/packages/kos/Cargo.toml @@ -46,15 +46,12 @@ libsecp256k1 = { version = "0.7.1", features = ["hmac", "static-context"], defau rand_core = { version = "0.6.4", default-features = false } parity-scale-codec = { version = "3.6.9", default-features = false, features = ["derive"] } -[target.'cfg(feature = "android")'.dependencies] +[target.'cfg(not(feature = "ksafe"))'.dependencies] rand = { workspace = true } coins-bip32 = { workspace = true } coins-bip39 = { workspace = true } - -[target.'cfg(target_arch = "x86_64")'.dependencies] rand_core = { version = "0.6.4", features = ["getrandom"], default-features = false } -rand = "0.8" -coins-bip39 = { version = "0.8", default-features = false, features = ["english"] } +getrandom = { version = "0.2", features = ["js"] } [build-dependencies] prost-build = "0.12.1" diff --git a/packages/kos/src/crypto/mod.rs b/packages/kos/src/crypto/mod.rs index 4300c94..cf03445 100644 --- a/packages/kos/src/crypto/mod.rs +++ b/packages/kos/src/crypto/mod.rs @@ -11,7 +11,7 @@ pub mod secp256k1; pub mod sr25519; #[cfg(not(feature = "ksafe"))] -pub mod mnemonic; +// pub mod mnemonic; mod crypto {} From 7dc16e3ad429aae9b10604d0c4d8a1aa8affac83 Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Tue, 19 Nov 2024 14:31:44 -0300 Subject: [PATCH 21/42] chore: add moonbeam --- packages/kos/src/chains/movr/mod.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/kos/src/chains/movr/mod.rs b/packages/kos/src/chains/movr/mod.rs index b452309..78139a8 100644 --- a/packages/kos/src/chains/movr/mod.rs +++ b/packages/kos/src/chains/movr/mod.rs @@ -9,6 +9,7 @@ use alloc::string::{String, ToString}; use alloc::vec::Vec; pub struct MOVR { + id: u32, name: String, symbol: String, decimals: u32, @@ -17,6 +18,7 @@ pub struct MOVR { impl MOVR { pub fn new() -> Self { MOVR { + id: 32, name: "Moonriver".to_string(), symbol: "MOVR".to_string(), decimals: 18, @@ -25,6 +27,7 @@ impl MOVR { pub fn new_glmr() -> Self { MOVR { + id: 34, name: "Moonbeam".to_string(), symbol: "GLMR".to_string(), decimals: 18, @@ -122,6 +125,6 @@ impl Chain for MOVR { } fn get_id(&self) -> u32 { - 32 + self.id } } From 88739fa0b7b40970b09782e6d5a681e771f663de Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Thu, 21 Nov 2024 15:03:33 -0300 Subject: [PATCH 22/42] feat: eth sign_typed_data --- Cargo.lock | 667 ++++++++++++++++++++++++++++- packages/kos/Cargo.toml | 2 + packages/kos/src/chains/eth/mod.rs | 60 +++ packages/kos/src/lib.rs | 4 +- 4 files changed, 725 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 227d83f..dc498dd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -61,6 +61,144 @@ dependencies = [ "memchr", ] +[[package]] +name = "alloy-dyn-abi" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef2364c782a245cf8725ea6dbfca5f530162702b5d685992ea03ce64529136cc" +dependencies = [ + "alloy-json-abi", + "alloy-primitives", + "alloy-sol-type-parser", + "alloy-sol-types", + "const-hex", + "derive_more", + "itoa", + "serde", + "serde_json", + "winnow", +] + +[[package]] +name = "alloy-json-abi" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b84c506bf264110fa7e90d9924f742f40ef53c6572ea56a0b0bd714a567ed389" +dependencies = [ + "alloy-primitives", + "alloy-sol-type-parser", + "serde", + "serde_json", +] + +[[package]] +name = "alloy-primitives" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fce5dbd6a4f118eecc4719eaa9c7ffc31c315e6c5ccde3642db927802312425" +dependencies = [ + "alloy-rlp", + "bytes", + "cfg-if", + "const-hex", + "derive_more", + "foldhash", + "hashbrown", + "hex-literal", + "indexmap", + "itoa", + "k256", + "keccak-asm", + "paste", + "proptest", + "rand", + "ruint", + "rustc-hash", + "serde", + "sha3", + "tiny-keccak", +] + +[[package]] +name = "alloy-rlp" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0822426598f95e45dd1ea32a738dac057529a709ee645fcc516ffa4cbde08f" +dependencies = [ + "arrayvec", + "bytes", +] + +[[package]] +name = "alloy-sol-macro" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9343289b4a7461ed8bab8618504c995c049c082b70c7332efd7b32125633dc05" +dependencies = [ + "alloy-sol-macro-expander", + "alloy-sol-macro-input", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "alloy-sol-macro-expander" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4222d70bec485ceccc5d8fd4f2909edd65b5d5e43d4aca0b5dcee65d519ae98f" +dependencies = [ + "alloy-sol-macro-input", + "const-hex", + "heck 0.5.0", + "indexmap", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.87", + "syn-solidity", + "tiny-keccak", +] + +[[package]] +name = "alloy-sol-macro-input" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e17f2677369571b976e51ea1430eb41c3690d344fef567b840bfc0b01b6f83a" +dependencies = [ + "const-hex", + "dunce", + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.87", + "syn-solidity", +] + +[[package]] +name = "alloy-sol-type-parser" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa64d80ae58ffaafdff9d5d84f58d03775f66c84433916dc9a64ed16af5755da" +dependencies = [ + "serde", + "winnow", +] + +[[package]] +name = "alloy-sol-types" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6520d427d4a8eb7aa803d852d7a52ceb0c519e784c292f64bb339e636918cf27" +dependencies = [ + "alloy-json-abi", + "alloy-primitives", + "alloy-sol-macro", + "const-hex", + "serde", +] + [[package]] name = "anstream" version = "0.6.18" @@ -116,6 +254,130 @@ version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" +[[package]] +name = "ark-ff" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b3235cc41ee7a12aaaf2c575a2ad7b46713a8a50bda2fc3b003a04845c05dd6" +dependencies = [ + "ark-ff-asm 0.3.0", + "ark-ff-macros 0.3.0", + "ark-serialize 0.3.0", + "ark-std 0.3.0", + "derivative", + "num-bigint", + "num-traits", + "paste", + "rustc_version 0.3.3", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm 0.4.2", + "ark-ff-macros 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", + "derivative", + "digest 0.10.7", + "itertools 0.10.5", + "num-bigint", + "num-traits", + "paste", + "rustc_version 0.4.1", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db02d390bf6643fb404d3d22d31aee1c4bc4459600aef9113833d17e786c6e44" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fd794a08ccb318058009eefdf15bcaaaaf6f8161eb3345f907222bac38b20" +dependencies = [ + "num-bigint", + "num-traits", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-serialize" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6c2b318ee6e10f8c2853e73a83adc0ccb88995aa978d8a3408d492ab2ee671" +dependencies = [ + "ark-std 0.3.0", + "digest 0.9.0", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-std 0.4.0", + "digest 0.10.7", + "num-bigint", +] + +[[package]] +name = "ark-std" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1df2c09229cbc5a028b1d70e00fdb2acee28b1055dfb5ca73eea49c5a25c4e7c" +dependencies = [ + "num-traits", + "rand", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand", +] + [[package]] name = "arrayref" version = "0.3.9" @@ -178,6 +440,17 @@ dependencies = [ "critical-section", ] +[[package]] +name = "auto_impl" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "autocfg" version = "1.4.0" @@ -262,6 +535,21 @@ dependencies = [ "cryptoxide", ] +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + [[package]] name = "bitcoin-private" version = "0.1.0" @@ -373,6 +661,9 @@ name = "bytes" version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" +dependencies = [ + "serde", +] [[package]] name = "camino" @@ -400,7 +691,7 @@ checksum = "eee4243f1f26fc7a42710e7439c149e2b10b05472f88090acce52632f231a73a" dependencies = [ "camino", "cargo-platform", - "semver", + "semver 1.0.23", "serde", "serde_json", "thiserror", @@ -569,6 +860,19 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" +[[package]] +name = "const-hex" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0121754e84117e65f9d90648ee6aa4882a6e63110307ab73967a4c5e7e69e586" +dependencies = [ + "cfg-if", + "cpufeatures", + "hex", + "proptest", + "serde", +] + [[package]] name = "const-oid" version = "0.9.6" @@ -664,7 +968,7 @@ dependencies = [ "curve25519-dalek-derive", "digest 0.10.7", "fiat-crypto", - "rustc_version", + "rustc_version 0.4.1", "subtle", "zeroize", ] @@ -690,6 +994,38 @@ dependencies = [ "zeroize", ] +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive_more" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", + "unicode-xid", +] + [[package]] name = "digest" version = "0.9.0" @@ -722,6 +1058,12 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + [[package]] name = "ecdsa" version = "0.16.9" @@ -866,6 +1208,17 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" +[[package]] +name = "fastrlp" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139834ddba373bbdd213dffe02c8d110508dcf1726c2be27e8d1f7d7e1856418" +dependencies = [ + "arrayvec", + "auto_impl", + "bytes", +] + [[package]] name = "fdeflate" version = "0.3.6" @@ -891,6 +1244,18 @@ version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" +[[package]] +name = "fixed-hash" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" +dependencies = [ + "byteorder", + "rand", + "rustc-hex", + "static_assertions", +] + [[package]] name = "fixedbitset" version = "0.4.2" @@ -913,6 +1278,12 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -1061,6 +1432,10 @@ name = "hashbrown" version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" +dependencies = [ + "foldhash", + "serde", +] [[package]] name = "heapless" @@ -1070,7 +1445,7 @@ checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" dependencies = [ "atomic-polyfill", "hash32", - "rustc_version", + "rustc_version 0.4.1", "serde", "spin", "stable_deref_trait", @@ -1099,6 +1474,15 @@ name = "hex" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +dependencies = [ + "serde", +] + +[[package]] +name = "hex-literal" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "hmac" @@ -1369,6 +1753,15 @@ dependencies = [ "png", ] +[[package]] +name = "impl-codec" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" +dependencies = [ + "parity-scale-codec", +] + [[package]] name = "impl-trait-for-tuples" version = "0.2.2" @@ -1388,6 +1781,7 @@ checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", "hashbrown", + "serde", ] [[package]] @@ -1418,6 +1812,15 @@ version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + [[package]] name = "itertools" version = "0.12.1" @@ -1465,10 +1868,21 @@ dependencies = [ "cpufeatures", ] +[[package]] +name = "keccak-asm" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "505d1856a39b200489082f90d897c3f07c455563880bc5952e38eabf731c83b6" +dependencies = [ + "digest 0.10.7", + "sha3-asm", +] + [[package]] name = "kos" version = "0.1.2" dependencies = [ + "alloy-dyn-abi", "bech32", "bip39-dict", "blake2b-ref", @@ -1494,6 +1908,7 @@ dependencies = [ "ripemd", "rlp", "schnorrkel", + "serde_json", "sha2 0.10.8", "sha3", "tiny-json-rs", @@ -1592,6 +2007,12 @@ version = "0.2.162" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" +[[package]] +name = "libm" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" + [[package]] name = "libsecp256k1" version = "0.7.1" @@ -1772,6 +2193,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -1802,9 +2224,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" dependencies = [ "arrayvec", + "bitvec", "byte-slice-cast", "impl-trait-for-tuples", "parity-scale-codec-derive", + "serde", ] [[package]] @@ -1864,6 +2288,17 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "pest" +version = "2.7.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + [[package]] name = "petgraph" version = "0.6.5" @@ -1959,6 +2394,17 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "primitive-types" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" +dependencies = [ + "fixed-hash", + "impl-codec", + "uint", +] + [[package]] name = "proc-macro-crate" version = "3.2.0" @@ -1968,6 +2414,28 @@ dependencies = [ "toml_edit", ] +[[package]] +name = "proc-macro-error-attr2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "proc-macro-error2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +dependencies = [ + "proc-macro-error-attr2", + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "proc-macro2" version = "1.0.89" @@ -1977,6 +2445,26 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "proptest" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4c2511913b88df1637da85cc8d96ec8e43a3f8bb8ccb71ee1ac240d6f3df58d" +dependencies = [ + "bit-set", + "bit-vec", + "bitflags 2.6.0", + "lazy_static", + "num-traits", + "rand", + "rand_chacha", + "rand_xorshift", + "regex-syntax", + "rusty-fork", + "tempfile", + "unarray", +] + [[package]] name = "prost" version = "0.12.6" @@ -1995,7 +2483,7 @@ checksum = "22505a5c94da8e3b7c2996394d1c933236c4d743e81a410bcca4e6989fc066a4" dependencies = [ "bytes", "heck 0.5.0", - "itertools", + "itertools 0.12.1", "log", "multimap", "once_cell", @@ -2015,7 +2503,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1" dependencies = [ "anyhow", - "itertools", + "itertools 0.12.1", "proc-macro2", "quote", "syn 2.0.87", @@ -2093,6 +2581,12 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4339fc7a1021c9c1621d87f5e3505f2805c8c105420ba2f2a4df86814590c142" +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + [[package]] name = "quote" version = "1.0.37" @@ -2117,6 +2611,7 @@ dependencies = [ "libc", "rand_chacha", "rand_core", + "serde", ] [[package]] @@ -2138,6 +2633,15 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rand_xorshift" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" +dependencies = [ + "rand_core", +] + [[package]] name = "regex" version = "1.11.1" @@ -2231,25 +2735,70 @@ dependencies = [ "rustc-hex", ] +[[package]] +name = "ruint" +version = "1.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c3cc4c2511671f327125da14133d0c5c5d137f006a1017a16f557bc85b16286" +dependencies = [ + "alloy-rlp", + "ark-ff 0.3.0", + "ark-ff 0.4.2", + "bytes", + "fastrlp", + "num-bigint", + "num-traits", + "parity-scale-codec", + "primitive-types", + "proptest", + "rand", + "rlp", + "ruint-macro", + "serde", + "valuable", + "zeroize", +] + +[[package]] +name = "ruint-macro" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" + [[package]] name = "rustc-demangle" version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +[[package]] +name = "rustc-hash" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" + [[package]] name = "rustc-hex" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" +[[package]] +name = "rustc_version" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +dependencies = [ + "semver 0.11.0", +] + [[package]] name = "rustc_version" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ - "semver", + "semver 1.0.23", ] [[package]] @@ -2271,6 +2820,18 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" +[[package]] +name = "rusty-fork" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" +dependencies = [ + "fnv", + "quick-error", + "tempfile", + "wait-timeout", +] + [[package]] name = "ryu" version = "1.0.18" @@ -2355,6 +2916,15 @@ dependencies = [ "cc", ] +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser", +] + [[package]] name = "semver" version = "1.0.23" @@ -2364,6 +2934,15 @@ dependencies = [ "serde", ] +[[package]] +name = "semver-parser" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9900206b54a3527fdc7b8a938bffd94a568bac4f4aa8113b209df75a09c0dec2" +dependencies = [ + "pest", +] + [[package]] name = "serde" version = "1.0.215" @@ -2464,6 +3043,16 @@ dependencies = [ "keccak", ] +[[package]] +name = "sha3-asm" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28efc5e327c837aa837c59eae585fc250715ef939ac32881bcc11677cd02d46" +dependencies = [ + "cc", + "cfg-if", +] + [[package]] name = "shlex" version = "1.3.0" @@ -2601,6 +3190,18 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn-solidity" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f76fe0a3e1476bdaa0775b9aec5b869ed9520c2b2fedfe9c6df3618f8ea6290b" +dependencies = [ + "paste", + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "sync_wrapper" version = "1.0.1" @@ -2678,6 +3279,15 @@ dependencies = [ "tiny_json_derive", ] +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + [[package]] name = "tiny_json_derive" version = "0.1.2" @@ -2821,6 +3431,30 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "ucd-trie" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" + +[[package]] +name = "uint" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + [[package]] name = "unicase" version = "2.8.0" @@ -2833,6 +3467,12 @@ version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + [[package]] name = "uniffi" version = "0.28.2" @@ -3008,12 +3648,27 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + [[package]] name = "version_check" version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "wait-timeout" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +dependencies = [ + "libc", +] + [[package]] name = "want" version = "0.3.1" diff --git a/packages/kos/Cargo.toml b/packages/kos/Cargo.toml index e66f0c0..34ef491 100644 --- a/packages/kos/Cargo.toml +++ b/packages/kos/Cargo.toml @@ -52,6 +52,8 @@ coins-bip32 = { workspace = true } coins-bip39 = { workspace = true } rand_core = { version = "0.6.4", features = ["getrandom"], default-features = false } getrandom = { version = "0.2", features = ["js"] } +alloy-dyn-abi = { version = "0.8.5", features = ["eip712"] } +serde_json = { workspace = true } [build-dependencies] prost-build = "0.12.1" diff --git a/packages/kos/src/chains/eth/mod.rs b/packages/kos/src/chains/eth/mod.rs index 5911d57..7c5ba67 100644 --- a/packages/kos/src/chains/eth/mod.rs +++ b/packages/kos/src/chains/eth/mod.rs @@ -9,6 +9,7 @@ use crate::crypto::{bip32, secp256k1}; use alloc::format; use alloc::string::{String, ToString}; use alloc::vec::Vec; +use alloy_dyn_abi::TypedData; pub(crate) const ETH_ADDR_SIZE: usize = 20; const ETH_MESSAGE_PREFIX: &[u8; 26] = b"\x19Ethereum Signed Message:\n"; @@ -140,6 +141,16 @@ impl Chain for ETH { } fn sign_message(&self, private_key: Vec, message: Vec) -> Result, ChainError> { + #[cfg(not(feature = "ksafe"))] + { + if let Ok(data) = std::str::from_utf8(&message) { + if let Ok(typed_data) = serde_json::from_str::(data) { + let digest = typed_data.eip712_signing_hash().unwrap(); + return self.sign_raw(private_key, digest.to_vec()); + } + } + } + let to_sign = [ ETH_MESSAGE_PREFIX, message.len().to_string().as_bytes(), @@ -251,4 +262,53 @@ mod test { ); assert_eq!(tx_info.value, 4.523128485832664e57); } + + #[test] + fn test_sign_typed_data() { + let data = r#"{ + "types": { + "EIP712Domain": [ + { "name": "name", "type": "string" }, + { "name": "version", "type": "string" }, + { "name": "chainId", "type": "uint256" }, + { "name": "verifyingContract", "type": "address" } + ], + "Person": [ + { "name": "name", "type": "string" }, + { "name": "wallet", "type": "address" } + ], + "Mail": [ + { "name": "from", "type": "Person" }, + { "name": "to", "type": "Person" }, + { "name": "contents", "type": "string" } + ] + }, + "primaryType": "Mail", + "domain": { + "name": "Ether Mail", + "version": "1", + "chainId": 1, + "verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" + }, + "message": { + "from": { + "name": "Cow", + "wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826" + }, + "to": { + "name": "Bob", + "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB" + }, + "contents": "Hello, Bob!" + } + }"#; + + let eth = super::ETH::new(); + let pvk = hex::decode("1ab42cc412b618bdea3a599e3c9bae199ebf030895b039e9db1e30dafb12b727") + .unwrap(); + let message = data.as_bytes(); + + let signature = eth.sign_message(pvk, message.to_vec()).unwrap(); + assert_eq!(signature.len(), 65); + } } diff --git a/packages/kos/src/lib.rs b/packages/kos/src/lib.rs index 6b10b25..fd34da9 100644 --- a/packages/kos/src/lib.rs +++ b/packages/kos/src/lib.rs @@ -1,4 +1,4 @@ -#![no_std] +#![cfg_attr(feature = "ksafe", no_std)] pub mod chains; pub mod crypto; pub mod protos; @@ -40,4 +40,4 @@ static ALLOCATOR: FreeRtosAllocator = FreeRtosAllocator; unsafe fn my_panic(_info: &core::panic::PanicInfo) -> ! { HardFault_Handler(); loop {} -} \ No newline at end of file +} From d9b9eea497351761e49c15f9e9741b1e245c20e2 Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Thu, 21 Nov 2024 15:27:35 -0300 Subject: [PATCH 23/42] chore: get transaction fields --- packages/kos-web/src/models.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/packages/kos-web/src/models.rs b/packages/kos-web/src/models.rs index a9d029c..ea1b6a8 100644 --- a/packages/kos-web/src/models.rs +++ b/packages/kos-web/src/models.rs @@ -43,3 +43,21 @@ pub struct Transaction { #[wasm_bindgen(skip)] pub signature: Vec, } + +#[wasm_bindgen] +impl Transaction { + #[wasm_bindgen(js_name = getRawData)] + pub fn get_raw_data(&self) -> Vec { + self.raw_data.clone() + } + + #[wasm_bindgen(js_name = getTxHash)] + pub fn get_tx_hash(&self) -> Vec { + self.tx_hash.clone() + } + + #[wasm_bindgen(js_name = getSignature)] + pub fn get_signature(&self) -> Vec { + self.signature.clone() + } +} From 91ddc9a81a65faafca3dffa0fa21c59f491618c0 Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Thu, 21 Nov 2024 17:28:32 -0300 Subject: [PATCH 24/42] fix: clippy errors --- packages/kos-crypto/src/blake2b.rs | 28 ----------------- packages/kos-mobile/src/lib.rs | 3 +- packages/kos-web/src/utils.rs | 1 + packages/kos-web/src/wallet.rs | 33 +++++++++------------ packages/kos/build.rs | 2 +- packages/kos/src/chains/ada/address.rs | 4 +-- packages/kos/src/chains/ada/mod.rs | 4 +-- packages/kos/src/chains/apt/mod.rs | 1 + packages/kos/src/chains/atom/mod.rs | 1 + packages/kos/src/chains/bch/mod.rs | 9 +++++- packages/kos/src/chains/bnb/mod.rs | 1 + packages/kos/src/chains/btc/mod.rs | 2 ++ packages/kos/src/chains/constants.rs | 2 +- packages/kos/src/chains/eth/mod.rs | 10 ++++--- packages/kos/src/chains/eth/models.rs | 3 +- packages/kos/src/chains/icp/mod.rs | 2 ++ packages/kos/src/chains/klv/mod.rs | 3 +- packages/kos/src/chains/klv/models.rs | 14 +++++++-- packages/kos/src/chains/mod.rs | 1 + packages/kos/src/chains/movr/mod.rs | 3 +- packages/kos/src/chains/sol/mod.rs | 1 + packages/kos/src/chains/substrate/mod.rs | 2 +- packages/kos/src/chains/substrate/models.rs | 22 +++++++------- packages/kos/src/chains/sui/mod.rs | 1 + packages/kos/src/chains/trx/mod.rs | 15 +++++----- packages/kos/src/chains/util.rs | 10 +++---- packages/kos/src/chains/xrp/mod.rs | 1 + packages/kos/src/crypto/bignum.rs | 7 ++++- packages/kos/src/crypto/bip32.rs | 8 ++--- packages/kos/src/crypto/hash.rs | 6 ++-- packages/kos/src/crypto/mod.rs | 2 +- packages/kos/src/crypto/pbkdf2.rs | 3 +- packages/kos/src/crypto/sr25519.rs | 2 +- packages/kos/src/protos/generated/mod.rs | 1 + 34 files changed, 102 insertions(+), 106 deletions(-) diff --git a/packages/kos-crypto/src/blake2b.rs b/packages/kos-crypto/src/blake2b.rs index 2bdbbe8..9e04398 100644 --- a/packages/kos-crypto/src/blake2b.rs +++ b/packages/kos-crypto/src/blake2b.rs @@ -1,5 +1,4 @@ pub const BLOCK_BYTES: usize = 128; -pub const KEY_BYTES: usize = 64; pub const OUT_BYTES: usize = 64; #[rustfmt::skip] @@ -61,33 +60,6 @@ impl Blake2b { } } - pub fn new_with_key(size: usize, key: &[u8]) -> Blake2b { - assert!(size > 0 && size <= OUT_BYTES); - assert!(!key.is_empty() && key.len() <= KEY_BYTES); - - let param = encode_params(size as u8, key.len() as u8); - let mut state = IV; - - for i in 0..state.len() { - println!("i2: {} ", i); - state[i] ^= load64(¶m[i * 8..]); - } - - let mut b = Blake2b { - h: state, - t: [0, 0], - f: [0, 0], - buf: [0u8; 2 * BLOCK_BYTES], - buf_len: 0, - output_len: size, - }; - - let mut block = [0u8; BLOCK_BYTES]; - block[..key.len()].copy_from_slice(key); - b.update(block.as_ref()); - b - } - pub fn update(&mut self, m: &[u8]) { let mut m = m; diff --git a/packages/kos-mobile/src/lib.rs b/packages/kos-mobile/src/lib.rs index 5d6a00e..0a323a7 100644 --- a/packages/kos-mobile/src/lib.rs +++ b/packages/kos-mobile/src/lib.rs @@ -132,8 +132,7 @@ fn decrypt(data: String, password: String) -> Result { } fn get_chain_by(id: u32) -> Result, KOSError> { - let id_u8 = u32::try_from(id).map_err(|_| KOSError::UnsupportedChain { id: id.to_string() })?; - let chain = get_chain_by_base_id(id_u8) + let chain = get_chain_by_base_id(id) .ok_or_else(|| KOSError::UnsupportedChain { id: id.to_string() })?; Ok(chain) diff --git a/packages/kos-web/src/utils.rs b/packages/kos-web/src/utils.rs index 59d8f0c..64d9201 100644 --- a/packages/kos-web/src/utils.rs +++ b/packages/kos-web/src/utils.rs @@ -1,6 +1,7 @@ use kos_types::error::Error; use serde::{Deserialize, Serialize}; +#[allow(dead_code)] pub fn pack(t: &T) -> Result, Error> where T: Serialize + ?Sized, diff --git a/packages/kos-web/src/wallet.rs b/packages/kos-web/src/wallet.rs index 0259537..4a8eaa2 100644 --- a/packages/kos-web/src/wallet.rs +++ b/packages/kos-web/src/wallet.rs @@ -1,11 +1,11 @@ use crate::models::{PathOptions, Transaction}; -use pem::{encode as encode_pem, parse as parse_pem, Pem}; +use pem::{parse as parse_pem, Pem}; use serde::{Deserialize, Serialize}; use strum::{EnumCount, IntoStaticStr}; -use crate::utils::{pack, unpack}; -use kos::chains::{get_chain_by_base_id, Chain, Transaction as KosTransaction}; +use crate::utils::unpack; +use kos::chains::{get_chain_by_base_id, Transaction as KosTransaction}; use kos_types::error::Error; use wasm_bindgen::prelude::*; @@ -49,20 +49,18 @@ impl Wallet { .ok_or_else(|| Error::WalletManagerError("Invalid chain".to_string()))?; let seed = chain - .mnemonic_to_seed(mnemonic.clone(), String::from("")) - .map_err(|e| { - Error::WalletManagerError(format!("mnemonic to seed: {}", e.to_string())) - })?; + .mnemonic_to_seed(mnemonic.clone(), password.unwrap_or_default()) + .map_err(|e| Error::WalletManagerError(format!("mnemonic to seed: {}", e)))?; let private_key = chain .derive(seed, path.clone()) - .map_err(|e| Error::WalletManagerError(format!("derive keypair: {}", e.to_string())))?; + .map_err(|e| Error::WalletManagerError(format!("derive keypair: {}", e)))?; let public_key = chain .get_pbk(private_key.clone()) - .map_err(|e| Error::WalletManagerError(format!("get public key: {}", e.to_string())))?; + .map_err(|e| Error::WalletManagerError(format!("get public key: {}", e)))?; let address = chain .get_address(public_key) - .map_err(|e| Error::WalletManagerError(format!("get address: {}", e.to_string())))?; + .map_err(|e| Error::WalletManagerError(format!("get address: {}", e)))?; Ok(Wallet { chain: chain_id, @@ -110,10 +108,10 @@ impl Wallet { let public_key = chain .get_pbk(hex::decode(private_key_bytes.clone())?) - .map_err(|e| Error::WalletManagerError(format!("get public key: {}", e.to_string())))?; + .map_err(|e| Error::WalletManagerError(format!("get public key: {}", e)))?; let address = chain .get_address(public_key.clone()) - .map_err(|e| Error::WalletManagerError(format!("get address: {}", e.to_string())))?; + .map_err(|e| Error::WalletManagerError(format!("get address: {}", e)))?; // create wallet from keypair Ok(Wallet { @@ -236,7 +234,7 @@ impl Wallet { chain .sign_message(pk_bytes, message.to_vec()) - .or_else(|e| Err(Error::WalletManagerError(format!("sign message: {}", e)))) + .map_err(|e| Error::WalletManagerError(format!("sign message: {}", e))) } None => Err(Error::WalletManagerError("no keypair".to_string())), } @@ -257,12 +255,9 @@ impl Wallet { let chain = get_chain_by_base_id(self.chain) .ok_or_else(|| Error::WalletManagerError("Invalid chain".to_string()))?; - let signed_tx = chain.sign_tx(pk_bytes, tx).or_else(|e| { - Err(Error::WalletManagerError(format!( - "sign transaction: {}", - e - ))) - })?; + let signed_tx = chain + .sign_tx(pk_bytes, tx) + .map_err(|e| Error::WalletManagerError(format!("sign transaction: {}", e)))?; Ok(Transaction { raw_data: signed_tx.raw_data, diff --git a/packages/kos/build.rs b/packages/kos/build.rs index 6997821..5cba003 100644 --- a/packages/kos/build.rs +++ b/packages/kos/build.rs @@ -2,7 +2,7 @@ use std::path::PathBuf; fn main() { let mut config = prost_build::Config::new(); - config.btree_map(&["."]); + config.btree_map(["."]); let protos = vec![ "src/protos/tron/core/Discover.proto", diff --git a/packages/kos/src/chains/ada/address.rs b/packages/kos/src/chains/ada/address.rs index 40fac7e..bbbabc9 100644 --- a/packages/kos/src/chains/ada/address.rs +++ b/packages/kos/src/chains/ada/address.rs @@ -45,7 +45,7 @@ pub struct StakeCredential { impl StakeCredential { pub fn new(pbk: &[u8]) -> Self { - let key_hash = blake244_digest(&pbk); + let key_hash = blake244_digest(pbk); StakeCredential::from_key_hash(key_hash) } @@ -105,7 +105,7 @@ impl Address { addr_bytes.append(&mut payment_cred.get_hash()?.to_vec()); Ok(addr_bytes) } - AddressType::Pointer => return Err(ChainError::NotSupported), + AddressType::Pointer => Err(ChainError::NotSupported), } } diff --git a/packages/kos/src/chains/ada/mod.rs b/packages/kos/src/chains/ada/mod.rs index 4ce637b..bcc9ec0 100644 --- a/packages/kos/src/chains/ada/mod.rs +++ b/packages/kos/src/chains/ada/mod.rs @@ -85,8 +85,8 @@ impl Chain for ADA { let pbk = &public_key[..32]; let pbk_stake = &public_key[32..64]; - let payment = StakeCredential::new(&pbk); - let stake = StakeCredential::new(&pbk_stake); + let payment = StakeCredential::new(pbk); + let stake = StakeCredential::new(pbk_stake); let address = Address { network: 1, _type: AddressType::Base.to_u8(), diff --git a/packages/kos/src/chains/apt/mod.rs b/packages/kos/src/chains/apt/mod.rs index 2d08a44..d239b4a 100644 --- a/packages/kos/src/chains/apt/mod.rs +++ b/packages/kos/src/chains/apt/mod.rs @@ -7,6 +7,7 @@ use alloc::format; use alloc::string::{String, ToString}; use alloc::vec::Vec; +#[allow(clippy::upper_case_acronyms)] pub struct APT {} impl Chain for APT { diff --git a/packages/kos/src/chains/atom/mod.rs b/packages/kos/src/chains/atom/mod.rs index 8dfa571..cad2bbe 100644 --- a/packages/kos/src/chains/atom/mod.rs +++ b/packages/kos/src/chains/atom/mod.rs @@ -8,6 +8,7 @@ use alloc::string::{String, ToString}; use alloc::vec::Vec; use bech32::{u5, Variant}; +#[allow(clippy::upper_case_acronyms)] pub(crate) struct ATOM { pub addr_prefix: String, #[allow(dead_code)] diff --git a/packages/kos/src/chains/bch/mod.rs b/packages/kos/src/chains/bch/mod.rs index 0e0133c..cd20eea 100644 --- a/packages/kos/src/chains/bch/mod.rs +++ b/packages/kos/src/chains/bch/mod.rs @@ -11,19 +11,24 @@ const BCH_CHARSET: &str = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"; const BCH_PREFIX: &str = "bitcoincash"; const BCH_MASK: u8 = 0x1f; +#[allow(clippy::upper_case_acronyms)] pub struct BCH {} impl BCH { + #[allow(clippy::needless_range_loop)] + fn expand_prefix(prefix: &str) -> Result, ChainError> { let mut prefix_bytes = prefix.as_bytes().to_vec(); for i in 0..prefix_bytes.len() { - prefix_bytes[i] = prefix_bytes[i] & BCH_MASK; + prefix_bytes[i] &= BCH_MASK; } prefix_bytes.push(0u8); Ok(prefix_bytes) } + #[allow(clippy::needless_range_loop)] + fn create_checksum(prefix: &str, payload: &[u8]) -> Result, ChainError> { let expanded_prefix = BCH::expand_prefix(prefix)?; let to_encode = [expanded_prefix, payload.to_vec(), vec![0u8; 8]].concat(); @@ -108,6 +113,8 @@ impl Chain for BCH { Ok(pbk.to_vec()) } + #[allow(clippy::needless_range_loop)] + fn get_address(&self, public_key: Vec) -> Result { if public_key.len() != 33 { return Err(ChainError::InvalidPublicKey); diff --git a/packages/kos/src/chains/bnb/mod.rs b/packages/kos/src/chains/bnb/mod.rs index eea5699..085ca40 100644 --- a/packages/kos/src/chains/bnb/mod.rs +++ b/packages/kos/src/chains/bnb/mod.rs @@ -10,6 +10,7 @@ use bech32::{u5, Variant}; const BNB_PREFIX: &str = "bnb"; +#[allow(clippy::upper_case_acronyms)] pub struct BNB {} impl Chain for BNB { diff --git a/packages/kos/src/chains/btc/mod.rs b/packages/kos/src/chains/btc/mod.rs index a1d09e4..946135d 100644 --- a/packages/kos/src/chains/btc/mod.rs +++ b/packages/kos/src/chains/btc/mod.rs @@ -9,6 +9,7 @@ use alloc::vec::Vec; use alloc::{format, vec}; use bech32::{u5, Variant}; +#[allow(clippy::upper_case_acronyms)] pub struct BTC { pub id: u32, pub addr_prefix: String, @@ -129,6 +130,7 @@ impl Chain for BTC { Ok(pbk.to_vec()) } + #[allow(clippy::needless_question_mark)] fn get_address(&self, public_key: Vec) -> Result { if self.use_legacy_address { return Ok(self.get_addr_legacy(public_key)?); diff --git a/packages/kos/src/chains/constants.rs b/packages/kos/src/chains/constants.rs index 25736b4..e335334 100644 --- a/packages/kos/src/chains/constants.rs +++ b/packages/kos/src/chains/constants.rs @@ -54,4 +54,4 @@ pub const OP: u32 = 48; pub const HBAR: u32 = 49; pub const FLOW: u32 = 50; pub const POLYGON_ZKEVM: u32 = 51; -pub const STOLZ: u32 = 52; \ No newline at end of file +pub const STOLZ: u32 = 52; diff --git a/packages/kos/src/chains/eth/mod.rs b/packages/kos/src/chains/eth/mod.rs index 7c5ba67..6718427 100644 --- a/packages/kos/src/chains/eth/mod.rs +++ b/packages/kos/src/chains/eth/mod.rs @@ -13,6 +13,8 @@ use alloy_dyn_abi::TypedData; pub(crate) const ETH_ADDR_SIZE: usize = 20; const ETH_MESSAGE_PREFIX: &[u8; 26] = b"\x19Ethereum Signed Message:\n"; + +#[allow(clippy::upper_case_acronyms)] pub struct ETH { pub id: u32, pub chaincode: u32, @@ -69,15 +71,15 @@ impl Chain for ETH { } fn get_name(&self) -> &str { - return self.name.as_str(); + self.name.as_str() } fn get_symbol(&self) -> &str { - return self.symbol.as_str(); + self.symbol.as_str() } fn get_decimals(&self) -> u32 { - return 18; + 18 } fn mnemonic_to_seed(&self, mnemonic: String, password: String) -> Result, ChainError> { @@ -105,7 +107,7 @@ impl Chain for ETH { let mut address_bytes: [u8; ETH_ADDR_SIZE] = [0; ETH_ADDR_SIZE]; address_bytes.copy_from_slice(&pbk_hash[12..]); - return ETH::addr_bytes_to_string(address_bytes); + ETH::addr_bytes_to_string(address_bytes) } fn sign_tx( diff --git a/packages/kos/src/chains/eth/models.rs b/packages/kos/src/chains/eth/models.rs index fe6e15d..53fccab 100644 --- a/packages/kos/src/chains/eth/models.rs +++ b/packages/kos/src/chains/eth/models.rs @@ -26,6 +26,7 @@ pub struct EthereumTransaction { } impl EthereumTransaction { + #[allow(clippy::unnecessary_unwrap)] pub fn decode(rlp_data: &[u8]) -> Result { let rlp = Rlp::new(rlp_data); @@ -177,6 +178,6 @@ impl EthereumTransaction { } let rlp = Rlp::new(&byte_tx); - return EthereumTransaction::decode_eip155(rlp); + EthereumTransaction::decode_eip155(rlp) } } diff --git a/packages/kos/src/chains/icp/mod.rs b/packages/kos/src/chains/icp/mod.rs index c792290..0d0772a 100644 --- a/packages/kos/src/chains/icp/mod.rs +++ b/packages/kos/src/chains/icp/mod.rs @@ -11,6 +11,8 @@ const ASN1_ED25519_HEADER: [u8; 12] = [48u8, 42, 48, 5, 6, 3, 43, 101, 112, 3, 3 const ICP_TAIL: u8 = 2; const ACCOUNT_ID_STR: &str = "account-id"; const ACCOUNT_ID_BYTE: u8 = 0x0A; + +#[allow(clippy::upper_case_acronyms)] pub struct ICP {} impl Chain for ICP { diff --git a/packages/kos/src/chains/klv/mod.rs b/packages/kos/src/chains/klv/mod.rs index 5a5e6b3..0f0ba5b 100644 --- a/packages/kos/src/chains/klv/mod.rs +++ b/packages/kos/src/chains/klv/mod.rs @@ -28,8 +28,7 @@ impl KLV { msg.extend_from_slice(message.len().to_string().as_bytes()); msg.extend_from_slice(&message); - let hash_result = keccak256_digest(&msg[..]); - hash_result + keccak256_digest(&msg[..]) } } diff --git a/packages/kos/src/chains/klv/models.rs b/packages/kos/src/chains/klv/models.rs index a72b748..8a5f87c 100644 --- a/packages/kos/src/chains/klv/models.rs +++ b/packages/kos/src/chains/klv/models.rs @@ -92,6 +92,7 @@ pub enum ConversionError { impl TryFrom for proto::Transaction { type Error = ConversionError; + #[allow(clippy::needless_update)] fn try_from(value: chains::klv::models::Transaction) -> Result { let raw_data = match value.raw_data { Some(raw) => Some(proto::transaction::Raw::try_from(raw)?), @@ -100,14 +101,14 @@ impl TryFrom for proto::Transaction { let receipts = value .receipts - .unwrap_or(Vec::new()) + .unwrap_or_default() .into_iter() .map(proto::transaction::Receipt::try_from) .collect::>()?; let signatures = value .signature - .unwrap_or(Vec::new()) + .unwrap_or_default() .into_iter() .map(|s| simple_base64_decode(&s).map_err(|_| ConversionError::Base64Error)) .collect::, _>>()?; @@ -129,6 +130,8 @@ impl TryFrom for proto::Transaction { impl TryFrom for proto::transaction::Raw { type Error = ConversionError; + #[allow(clippy::needless_update)] + fn try_from(value: chains::klv::models::Raw) -> Result { let contracts = value .contract @@ -141,7 +144,7 @@ impl TryFrom for proto::transaction::Raw { let datas = value .data - .unwrap_or(Vec::new()) + .unwrap_or_default() .into_iter() .map(|d| simple_base64_decode(&d).map_err(|_| ConversionError::Base64Error)) .collect::, _>>()?; @@ -193,6 +196,8 @@ impl TryFrom for proto::TxContract { impl TryFrom for protos::Any { type Error = ConversionError; + #[allow(clippy::needless_update)] + fn try_from(value: chains::klv::models::Parameter) -> Result { let proto_parameter = protos::Any { type_url: value.type_url, @@ -207,6 +212,8 @@ impl TryFrom for protos::Any { impl TryFrom for proto::transaction::KdaFee { type Error = ConversionError; + #[allow(clippy::needless_update)] + fn try_from(value: chains::klv::models::KdaFee) -> Result { let kda_bytes = simple_base64_decode(&value.kda).map_err(|_| ConversionError::Base64Error)?; @@ -224,6 +231,7 @@ impl TryFrom for proto::transaction::KdaFee { impl TryFrom for proto::transaction::Receipt { type Error = ConversionError; + #[allow(clippy::needless_update)] fn try_from(value: chains::klv::models::Receipt) -> Result { let data = value .data diff --git a/packages/kos/src/chains/mod.rs b/packages/kos/src/chains/mod.rs index a7796b4..20a9c61 100644 --- a/packages/kos/src/chains/mod.rs +++ b/packages/kos/src/chains/mod.rs @@ -226,6 +226,7 @@ pub struct Transaction { #[allow(dead_code)] impl Transaction { + #[allow(clippy::should_implement_trait)] pub fn default() -> Self { Self { raw_data: Vec::new(), diff --git a/packages/kos/src/chains/movr/mod.rs b/packages/kos/src/chains/movr/mod.rs index 78139a8..23f1e61 100644 --- a/packages/kos/src/chains/movr/mod.rs +++ b/packages/kos/src/chains/movr/mod.rs @@ -8,6 +8,7 @@ use alloc::format; use alloc::string::{String, ToString}; use alloc::vec::Vec; +#[allow(clippy::upper_case_acronyms)] pub struct MOVR { id: u32, name: String, @@ -70,7 +71,7 @@ impl Chain for MOVR { [0; crate::chains::eth::ETH_ADDR_SIZE]; address_bytes.copy_from_slice(&pbk_hash[12..]); - return ETH::addr_bytes_to_string(address_bytes); + ETH::addr_bytes_to_string(address_bytes) } fn sign_tx( diff --git a/packages/kos/src/chains/sol/mod.rs b/packages/kos/src/chains/sol/mod.rs index f6f0e4f..d84bea2 100644 --- a/packages/kos/src/chains/sol/mod.rs +++ b/packages/kos/src/chains/sol/mod.rs @@ -7,6 +7,7 @@ use alloc::format; use alloc::string::String; use alloc::vec::Vec; +#[allow(clippy::upper_case_acronyms)] pub struct SOL {} impl Chain for SOL { diff --git a/packages/kos/src/chains/substrate/mod.rs b/packages/kos/src/chains/substrate/mod.rs index a711120..676086b 100644 --- a/packages/kos/src/chains/substrate/mod.rs +++ b/packages/kos/src/chains/substrate/mod.rs @@ -97,7 +97,7 @@ impl Chain for Substrate { .concat(); let digest = blake2b_64_digest(&data_to_hash); - let to_base_58 = [&prefix[..], &public_key[..], &digest[..2].to_vec()].concat(); + let to_base_58 = [&prefix[..], &public_key[..], &digest[..2]].concat(); let encoded = b58::b58enc(&to_base_58); let addr = String::from_utf8(encoded).unwrap(); Ok(addr) diff --git a/packages/kos/src/chains/substrate/models.rs b/packages/kos/src/chains/substrate/models.rs index e36e077..947a0ae 100644 --- a/packages/kos/src/chains/substrate/models.rs +++ b/packages/kos/src/chains/substrate/models.rs @@ -49,7 +49,7 @@ impl MultiAddress { if self.is_address32 { return self.as_address32.to_vec(); } - return self.as_address20.to_vec(); + self.as_address20.to_vec() } } @@ -75,27 +75,27 @@ impl Decode for MultiAddress { let mut as_index = [0u8; 4]; let _ = input.read(&mut as_index); address.as_index = u32::from_le_bytes(as_index); - return Ok(address); + Ok(address) } 2 => { address.is_raw = true; let _ = input.read(&mut address.as_raw); - return Ok(address); + Ok(address) } 3 => { address.is_address32 = true; let _ = input.read(&mut address.as_address32); - return Ok(address); + Ok(address) } 4 => { address.is_address20 = true; let _ = input.read(&mut address.as_address20); - return Ok(address); + Ok(address) } _ => { address.is_id = true; let _ = input.read(&mut address.as_id); - return Ok(address); + Ok(address) } } } @@ -114,14 +114,14 @@ impl Decode for UIntCompact { let mut r = bb as u64; r <<= 6; r += (b >> 2) as u64; - return Ok(U256::from_u64((r) as u64)); + Ok(U256::from_u64(r)) } 2 => { let mut buf = [0u8; 4]; let _ = input.read(&mut buf); let mut r = u32::from_le_bytes(buf); r >>= 2; - return Ok(U256::from_u64((r) as u64)); + Ok(U256::from_u64((r) as u64)) } 3 => { let l = b >> 2; @@ -130,11 +130,9 @@ impl Decode for UIntCompact { } let mut buf = vec![0u8; (l + 4) as usize]; input.read(&mut buf)?; - return Ok(U256::read_data_as_le(buf)); - } - _ => { - return Ok(U256::from_u64((b >> 2) as u64)); + Ok(U256::read_data_as_le(buf)) } + _ => Ok(U256::from_u64((b >> 2) as u64)), } } } diff --git a/packages/kos/src/chains/sui/mod.rs b/packages/kos/src/chains/sui/mod.rs index fd49815..0564324 100644 --- a/packages/kos/src/chains/sui/mod.rs +++ b/packages/kos/src/chains/sui/mod.rs @@ -7,6 +7,7 @@ use alloc::format; use alloc::string::{String, ToString}; use alloc::vec::Vec; +#[allow(clippy::upper_case_acronyms)] pub struct SUI {} impl Chain for SUI { diff --git a/packages/kos/src/chains/trx/mod.rs b/packages/kos/src/chains/trx/mod.rs index 0dc3e04..ba2e325 100644 --- a/packages/kos/src/chains/trx/mod.rs +++ b/packages/kos/src/chains/trx/mod.rs @@ -28,8 +28,7 @@ impl TRX { msg.extend_from_slice(message.len().to_string().as_bytes()); msg.extend_from_slice(&message); - let hash_result = keccak256_digest(&msg[..]); - hash_result + keccak256_digest(&msg[..]) } pub fn expand_address_with_checksum(address: &[u8; 21]) -> String { @@ -39,10 +38,10 @@ impl TRX { let hash = sha256_digest(&hash[..]); address_with_checksum[21..].copy_from_slice(&hash[0..4]); let bytes_addr = b58enc(&address_with_checksum[..]); - let addr = String::from_utf8(bytes_addr).unwrap(); - addr + String::from_utf8(bytes_addr).unwrap() } + #[allow(clippy::single_match)] pub fn decode_transaction(raw_tx: Vec) -> Result { let tx = protocol::Transaction::decode(raw_tx.as_slice()); match tx { @@ -67,15 +66,15 @@ impl Chain for TRX { } fn get_name(&self) -> &str { - return "TRON"; + "TRON" } fn get_symbol(&self) -> &str { - return "TRX"; + "TRX" } fn get_decimals(&self) -> u32 { - return 6; + 6 } fn mnemonic_to_seed(&self, mnemonic: String, password: String) -> Result, ChainError> { @@ -173,7 +172,7 @@ impl Chain for TRX { fn get_tx_info(&self, raw_tx: Vec) -> Result { let tx = TRX::decode_transaction(raw_tx)?; let raw = tx.raw_data.ok_or(ChainError::ProtoDecodeError)?; - if raw.contract.len() == 0 { + if raw.contract.is_empty() { return Err(ChainError::ProtoDecodeError); } diff --git a/packages/kos/src/chains/util.rs b/packages/kos/src/chains/util.rs index 5400088..2ed63ab 100644 --- a/packages/kos/src/chains/util.rs +++ b/packages/kos/src/chains/util.rs @@ -1,17 +1,15 @@ use crate::chains::ChainError; -use alloc::vec::Vec; -pub fn slice_from_vec(vec: &Vec) -> Result<[u8; N], ChainError> { +pub fn slice_from_vec(vec: &[u8]) -> Result<[u8; N], ChainError> { if vec.len() < N { return Err(ChainError::InvalidMessageSize); } let mut arr: [u8; N] = [0; N]; - arr.copy_from_slice(&vec[..]); + arr.copy_from_slice(vec); Ok(arr) } -pub fn private_key_from_vec(vec: &Vec) -> Result<[u8; N], ChainError> { - return slice_from_vec::(vec).map_err(|_| ChainError::InvalidPrivateKey); +pub fn private_key_from_vec(vec: &[u8]) -> Result<[u8; N], ChainError> { + slice_from_vec::(vec).map_err(|_| ChainError::InvalidPrivateKey) } - diff --git a/packages/kos/src/chains/xrp/mod.rs b/packages/kos/src/chains/xrp/mod.rs index 2a4b4d5..472a24f 100644 --- a/packages/kos/src/chains/xrp/mod.rs +++ b/packages/kos/src/chains/xrp/mod.rs @@ -10,6 +10,7 @@ use alloc::{format, vec}; const XRP_ALPHA: &[u8; 58] = b"rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz"; +#[allow(clippy::upper_case_acronyms)] pub(crate) struct XRP {} impl XRP { diff --git a/packages/kos/src/crypto/bignum.rs b/packages/kos/src/crypto/bignum.rs index c7fc086..c2487ba 100644 --- a/packages/kos/src/crypto/bignum.rs +++ b/packages/kos/src/crypto/bignum.rs @@ -49,6 +49,8 @@ impl U256 { Ok(U256::from_u64(integer_value)) } + #[allow(clippy::needless_range_loop)] + pub fn to_f64(&self, precision: u32) -> f64 { let bytes = self.0; let mut value: f64 = 0.0; @@ -58,7 +60,7 @@ impl U256 { value += bytes[i] as f64; } - value = value / (powi(10.0, precision as i32) as f64); + value /= powi(10.0, precision as i32); value } @@ -92,6 +94,7 @@ impl U256 { Ok(U256(data)) } + #[allow(clippy::inherent_to_string)] #[allow(dead_code)] pub fn to_string(&self) -> String { let mut hex_string = String::new(); @@ -115,6 +118,7 @@ impl U256 { u64::from_be_bytes(significant_part) } + #[allow(clippy::manual_memcpy)] #[allow(dead_code)] pub fn read_data_as_be(data: Vec) -> Self { let mut bytes: [u8; 32] = [0; 32]; @@ -146,6 +150,7 @@ impl U256 { data } + #[allow(clippy::needless_range_loop)] pub fn put_data_as_le(&self) -> Vec { let mut data: Vec = Vec::new(); //find the end of the data diff --git a/packages/kos/src/crypto/bip32.rs b/packages/kos/src/crypto/bip32.rs index 7782995..419f0c3 100644 --- a/packages/kos/src/crypto/bip32.rs +++ b/packages/kos/src/crypto/bip32.rs @@ -117,7 +117,7 @@ pub fn handle_path(path: String) -> Result, Bip32Err> { path_components.push(PathComponent { is_hardened, index }); } - return Ok(path_components); + Ok(path_components) } pub fn derive_private_key( @@ -144,7 +144,7 @@ pub fn derive_private_key( let x = Secp256K1::add_scalars(pvk, &new_data)?; - return Ok((x, new_ch)); + Ok((x, new_ch)) } pub fn derive_pk_from_path( @@ -200,7 +200,7 @@ pub fn derive_ed25519(input_key: &[u8], path: String) -> Result<[u8; 32], Bip32E pub fn derive_sr25519(input_key: &[u8], mut path: String) -> Result<[u8; 64], Bip32Err> { let mut chaincode = [0u8; 32]; let mut is_hardned = false; - if path != "" { + if !path.is_empty() { path = path .strip_prefix("//") .ok_or(Bip32Err::PathError)? @@ -299,7 +299,7 @@ pub fn mnemonic_to_seed_ed25519_bip32(mnemonic: String) -> Result, Bip32 pvk[31] &= 0x1f; pvk[31] |= 0x40; - return Ok(pvk); + Ok(pvk) } pub fn derive_ed25519_bip32(input_key: [u8; 96], path: String) -> Result<[u8; 96], Bip32Err> { diff --git a/packages/kos/src/crypto/hash.rs b/packages/kos/src/crypto/hash.rs index 333311b..000b12b 100644 --- a/packages/kos/src/crypto/hash.rs +++ b/packages/kos/src/crypto/hash.rs @@ -42,7 +42,7 @@ pub fn keccak256_digest(data: &[u8]) -> [u8; 32] { pub fn blake2b_digest(data: &[u8]) -> [u8; 32] { let mut hasher = Blake2bBuilder::new(32).build(); - hasher.update(&data); + hasher.update(data); let mut result_buffer: [u8; 32] = [0; 32]; hasher.finalize(result_buffer.as_mut_slice()); @@ -51,7 +51,7 @@ pub fn blake2b_digest(data: &[u8]) -> [u8; 32] { pub fn blake244_digest(data: &[u8]) -> [u8; 28] { let mut hasher = Blake2bBuilder::new(28).build(); - hasher.update(&data); + hasher.update(data); let mut result_buffer: [u8; 28] = [0; 28]; hasher.finalize(result_buffer.as_mut_slice()); @@ -60,7 +60,7 @@ pub fn blake244_digest(data: &[u8]) -> [u8; 28] { pub fn blake2b_64_digest(data: &[u8]) -> [u8; 64] { let mut hasher = Blake2bBuilder::new(64).build(); - hasher.update(&data); + hasher.update(data); let mut result_buffer: [u8; 64] = [0; 64]; hasher.finalize(result_buffer.as_mut_slice()); diff --git a/packages/kos/src/crypto/mod.rs b/packages/kos/src/crypto/mod.rs index cf03445..54847f9 100644 --- a/packages/kos/src/crypto/mod.rs +++ b/packages/kos/src/crypto/mod.rs @@ -10,9 +10,9 @@ mod rng; pub mod secp256k1; pub mod sr25519; +#[allow(clippy::module_inception)] #[cfg(not(feature = "ksafe"))] // pub mod mnemonic; - mod crypto {} #[cfg(test)] diff --git a/packages/kos/src/crypto/pbkdf2.rs b/packages/kos/src/crypto/pbkdf2.rs index 4914443..1b25c52 100644 --- a/packages/kos/src/crypto/pbkdf2.rs +++ b/packages/kos/src/crypto/pbkdf2.rs @@ -20,8 +20,7 @@ pub struct Pbkdf2 {} #[cfg(not(feature = "ksafe"))] impl Pbkdf2Trait for Pbkdf2 { fn pbkdf2_hmac_512(password: &[u8], salt: &[u8], rounds: u32) -> [u8; N] { - let icarus_key = pbkdf2::pbkdf2_hmac_array::(password, &salt, rounds); - icarus_key + pbkdf2::pbkdf2_hmac_array::(password, salt, rounds) } } diff --git a/packages/kos/src/crypto/sr25519.rs b/packages/kos/src/crypto/sr25519.rs index 955f4a2..d16bccf 100644 --- a/packages/kos/src/crypto/sr25519.rs +++ b/packages/kos/src/crypto/sr25519.rs @@ -48,13 +48,13 @@ impl Sr25519Trait for Sr25519 { Ok(sig.to_bytes().as_slice().to_vec()) } + #[allow(clippy::clone_on_copy)] fn hard_derive_mini_sk( seed: &[u8; 32], chaincode: &[u8; 32], ) -> Result<[u8; 32], Sr25519Error> { let seed = schnorrkel::MiniSecretKey::from_bytes(seed).map_err(|_| Sr25519Error::ErrDerive)?; - let chaincode = ChainCode(chaincode.clone()); let (new_seed, _) = seed.hard_derive_mini_secret_key( Some(chaincode), diff --git a/packages/kos/src/protos/generated/mod.rs b/packages/kos/src/protos/generated/mod.rs index ba0c8d6..f4905d5 100644 --- a/packages/kos/src/protos/generated/mod.rs +++ b/packages/kos/src/protos/generated/mod.rs @@ -1,2 +1,3 @@ +#![allow(clippy::all)] pub(crate) mod klv; pub(crate) mod trx; From 5187f2b0f63788342a29cf198d4c34b5a5547432 Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Fri, 22 Nov 2024 17:55:52 -0300 Subject: [PATCH 25/42] chore: organize crypto packages --- Cargo.lock | 771 +----------------- Cargo.toml | 5 +- packages/kos-crypto/Cargo.toml | 33 - packages/kos-crypto/src/blake2b.rs | 190 ----- packages/kos-crypto/src/hash.rs | 31 - packages/kos-crypto/src/lib.rs | 4 - packages/kos-mobile/Cargo.toml | 2 - packages/kos-mobile/src/lib.rs | 15 +- packages/kos-types/Cargo.toml | 30 - packages/kos-types/src/lib.rs | 1 - packages/kos-web/Cargo.toml | 2 - packages/{kos-types => kos-web}/src/error.rs | 77 +- packages/kos-web/src/lib.rs | 16 +- packages/kos-web/src/utils.rs | 2 +- packages/kos-web/src/wallet.rs | 58 +- packages/kos/Cargo.toml | 6 + packages/kos/src/chains/mod.rs | 15 + .../src => kos/src/crypto}/cipher.rs | 96 +-- .../src => kos/src/crypto}/mnemonic.rs | 13 +- packages/kos/src/crypto/mod.rs | 5 + 20 files changed, 121 insertions(+), 1251 deletions(-) delete mode 100644 packages/kos-crypto/Cargo.toml delete mode 100644 packages/kos-crypto/src/blake2b.rs delete mode 100644 packages/kos-crypto/src/hash.rs delete mode 100644 packages/kos-crypto/src/lib.rs delete mode 100644 packages/kos-types/Cargo.toml delete mode 100644 packages/kos-types/src/lib.rs rename packages/{kos-types => kos-web}/src/error.rs (58%) rename packages/{kos-crypto/src => kos/src/crypto}/cipher.rs (76%) rename packages/{kos-crypto/src => kos/src/crypto}/mnemonic.rs (57%) diff --git a/Cargo.lock b/Cargo.lock index dc498dd..f37f58a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,15 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "addr2line" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" -dependencies = [ - "gimli", -] - [[package]] name = "adler2" version = "2.0.0" @@ -457,21 +448,6 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" -[[package]] -name = "backtrace" -version = "0.3.74" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-targets", -] - [[package]] name = "base16ct" version = "0.2.0" @@ -550,21 +526,6 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" -[[package]] -name = "bitcoin-private" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73290177011694f38ec25e165d0387ab7ea749a4b81cd4c80dae5988229f7a57" - -[[package]] -name = "bitcoin_hashes" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d7066118b13d4b20b23645932dfb3a81ce7e29f95726c2036fa33cd7b092501" -dependencies = [ - "bitcoin-private", -] - [[package]] name = "bitflags" version = "1.3.2" @@ -1047,17 +1008,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "displaydoc" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - [[package]] name = "dunce" version = "1.0.5" @@ -1084,8 +1034,6 @@ version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" dependencies = [ - "pkcs8", - "serde", "signature", ] @@ -1097,10 +1045,8 @@ checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" dependencies = [ "curve25519-dalek", "ed25519", - "serde", "sha2 0.10.8", "subtle", - "zeroize", ] [[package]] @@ -1284,15 +1230,6 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" -[[package]] -name = "form_urlencoded" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" -dependencies = [ - "percent-encoding", -] - [[package]] name = "fs-err" version = "2.11.0" @@ -1308,39 +1245,6 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" -[[package]] -name = "futures-channel" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" -dependencies = [ - "futures-core", -] - -[[package]] -name = "futures-core" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" - -[[package]] -name = "futures-task" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" - -[[package]] -name = "futures-util" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" -dependencies = [ - "futures-core", - "futures-task", - "pin-project-lite", - "pin-utils", -] - [[package]] name = "generic-array" version = "0.14.7" @@ -1384,12 +1288,6 @@ dependencies = [ "polyval", ] -[[package]] -name = "gimli" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" - [[package]] name = "glob" version = "0.3.1" @@ -1463,12 +1361,6 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" -[[package]] -name = "hermit-abi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - [[package]] name = "hex" version = "0.4.3" @@ -1523,223 +1415,6 @@ dependencies = [ "utf8-width", ] -[[package]] -name = "http" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" -dependencies = [ - "bytes", - "http", -] - -[[package]] -name = "http-body-util" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" -dependencies = [ - "bytes", - "futures-util", - "http", - "http-body", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" - -[[package]] -name = "hyper" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbbff0a806a4728c99295b254c8838933b5b082d75e3cb70c8dab21fdfbcfa9a" -dependencies = [ - "bytes", - "futures-channel", - "futures-util", - "http", - "http-body", - "httparse", - "itoa", - "pin-project-lite", - "smallvec", - "tokio", - "want", -] - -[[package]] -name = "hyper-util" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" -dependencies = [ - "bytes", - "futures-channel", - "futures-util", - "http", - "http-body", - "hyper", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", -] - -[[package]] -name = "icu_collections" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" -dependencies = [ - "displaydoc", - "yoke", - "zerofrom", - "zerovec", -] - -[[package]] -name = "icu_locid" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" -dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", -] - -[[package]] -name = "icu_locid_transform" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" -dependencies = [ - "displaydoc", - "icu_locid", - "icu_locid_transform_data", - "icu_provider", - "tinystr", - "zerovec", -] - -[[package]] -name = "icu_locid_transform_data" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" - -[[package]] -name = "icu_normalizer" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" -dependencies = [ - "displaydoc", - "icu_collections", - "icu_normalizer_data", - "icu_properties", - "icu_provider", - "smallvec", - "utf16_iter", - "utf8_iter", - "write16", - "zerovec", -] - -[[package]] -name = "icu_normalizer_data" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" - -[[package]] -name = "icu_properties" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" -dependencies = [ - "displaydoc", - "icu_collections", - "icu_locid_transform", - "icu_properties_data", - "icu_provider", - "tinystr", - "zerovec", -] - -[[package]] -name = "icu_properties_data" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" - -[[package]] -name = "icu_provider" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" -dependencies = [ - "displaydoc", - "icu_locid", - "icu_provider_macros", - "stable_deref_trait", - "tinystr", - "writeable", - "yoke", - "zerofrom", - "zerovec", -] - -[[package]] -name = "icu_provider_macros" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - -[[package]] -name = "idna" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" -dependencies = [ - "idna_adapter", - "smallvec", - "utf8_iter", -] - -[[package]] -name = "idna_adapter" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" -dependencies = [ - "icu_normalizer", - "icu_properties", -] - [[package]] name = "image" version = "0.24.9" @@ -1800,12 +1475,6 @@ version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f958d3d68f4167080a18141e10381e7634563984a537f2a49a30fd8e53ac5767" -[[package]] -name = "ipnet" -version = "2.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" - [[package]] name = "is_terminal_polyfill" version = "1.70.1" @@ -1882,10 +1551,14 @@ dependencies = [ name = "kos" version = "0.1.2" dependencies = [ + "aes", + "aes-gcm", "alloy-dyn-abi", "bech32", "bip39-dict", "blake2b-ref", + "cbc", + "cfb-mode", "coins-bip32", "coins-bip39", "ed25519-dalek", @@ -1896,6 +1569,7 @@ dependencies = [ "libsecp256k1", "parity-scale-codec", "pbkdf2", + "pem", "prost", "prost-build", "prost-types", @@ -1914,66 +1588,17 @@ dependencies = [ "tiny-json-rs", ] -[[package]] -name = "kos-crypto" -version = "0.1.2" -dependencies = [ - "aes", - "aes-gcm", - "base64 0.21.7", - "cbc", - "cfb-mode", - "coins-bip32", - "coins-bip39", - "ed25519-dalek", - "hex", - "hmac 0.12.1", - "kos-types", - "log", - "pbkdf2", - "pem", - "rand", - "secp256k1", - "serde", - "sha1", - "sha2 0.10.8", - "sha3", - "wasm-bindgen", - "zeroize", -] - [[package]] name = "kos-mobile" version = "0.1.2" dependencies = [ "hex", "kos", - "kos-crypto", - "kos-types", "lazy_static", "thiserror", "uniffi", ] -[[package]] -name = "kos-types" -version = "0.1.2" -dependencies = [ - "coins-bip32", - "coins-bip39", - "ed25519-dalek", - "hex", - "log", - "num-bigint", - "num-traits", - "rand", - "reqwest", - "secp256k1", - "serde", - "serde_json", - "wasm-bindgen", -] - [[package]] name = "kos-web" version = "0.1.2" @@ -1982,8 +1607,6 @@ dependencies = [ "enum_dispatch", "hex", "kos", - "kos-crypto", - "kos-types", "lazy_static", "pem", "postcard", @@ -2067,12 +1690,6 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" -[[package]] -name = "litemap" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" - [[package]] name = "lock_api" version = "0.4.12" @@ -2139,18 +1756,6 @@ dependencies = [ "simd-adler32", ] -[[package]] -name = "mio" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" -dependencies = [ - "hermit-abi", - "libc", - "wasi", - "windows-sys 0.52.0", -] - [[package]] name = "multimap" version = "0.10.0" @@ -2196,15 +1801,6 @@ dependencies = [ "libm", ] -[[package]] -name = "object" -version = "0.36.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" -dependencies = [ - "memchr", -] - [[package]] name = "once_cell" version = "1.20.2" @@ -2282,12 +1878,6 @@ dependencies = [ "serde", ] -[[package]] -name = "percent-encoding" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" - [[package]] name = "pest" version = "2.7.14" @@ -2309,18 +1899,6 @@ dependencies = [ "indexmap", ] -[[package]] -name = "pin-project-lite" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - [[package]] name = "pkcs8" version = "0.10.2" @@ -2671,41 +2249,6 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" -[[package]] -name = "reqwest" -version = "0.12.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a77c62af46e79de0a562e1a9849205ffcb7fc1238876e9bd743357570e04046f" -dependencies = [ - "base64 0.22.1", - "bytes", - "futures-core", - "futures-util", - "http", - "http-body", - "http-body-util", - "hyper", - "hyper-util", - "ipnet", - "js-sys", - "log", - "mime", - "once_cell", - "percent-encoding", - "pin-project-lite", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper", - "tokio", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "windows-registry", -] - [[package]] name = "rfc6979" version = "0.4.0" @@ -2765,12 +2308,6 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" -[[package]] -name = "rustc-demangle" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" - [[package]] name = "rustc-hash" version = "2.0.0" @@ -2895,27 +2432,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "secp256k1" -version = "0.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25996b82292a7a57ed3508f052cfff8640d38d32018784acd714758b43da9c8f" -dependencies = [ - "bitcoin_hashes", - "rand", - "secp256k1-sys", - "serde", -] - -[[package]] -name = "secp256k1-sys" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70a129b9e9efbfb223753b9163c4ab3b13cff7fd9c7f010fbac25ab4099fa07e" -dependencies = [ - "cc", -] - [[package]] name = "semver" version = "0.11.0" @@ -2986,29 +2502,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "sha1" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest 0.10.7", -] - [[package]] name = "sha2" version = "0.9.9" @@ -3081,28 +2574,12 @@ version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" -[[package]] -name = "smallvec" -version = "1.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" - [[package]] name = "smawk" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" -[[package]] -name = "socket2" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - [[package]] name = "spin" version = "0.9.8" @@ -3202,26 +2679,6 @@ dependencies = [ "syn 2.0.87", ] -[[package]] -name = "sync_wrapper" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" -dependencies = [ - "futures-core", -] - -[[package]] -name = "synstructure" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - [[package]] name = "tap" version = "1.0.1" @@ -3299,16 +2756,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "tinystr" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" -dependencies = [ - "displaydoc", - "zerovec", -] - [[package]] name = "tinyvec" version = "1.8.0" @@ -3324,20 +2771,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" -[[package]] -name = "tokio" -version = "1.41.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33" -dependencies = [ - "backtrace", - "libc", - "mio", - "pin-project-lite", - "socket2", - "windows-sys 0.52.0", -] - [[package]] name = "toml" version = "0.5.11" @@ -3364,37 +2797,6 @@ dependencies = [ "winnow", ] -[[package]] -name = "tower-service" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" - -[[package]] -name = "tracing" -version = "0.1.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" -dependencies = [ - "pin-project-lite", - "tracing-core", -] - -[[package]] -name = "tracing-core" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" -dependencies = [ - "once_cell", -] - -[[package]] -name = "try-lock" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" - [[package]] name = "typeid" version = "1.0.2" @@ -3613,35 +3015,12 @@ dependencies = [ "subtle", ] -[[package]] -name = "url" -version = "2.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d157f1b96d14500ffdc1f10ba712e780825526c03d9a49b4d0324b0d9113ada" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", -] - -[[package]] -name = "utf16_iter" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" - [[package]] name = "utf8-width" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3" -[[package]] -name = "utf8_iter" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" - [[package]] name = "utf8parse" version = "0.2.2" @@ -3669,15 +3048,6 @@ dependencies = [ "libc", ] -[[package]] -name = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -3710,18 +3080,6 @@ dependencies = [ "wasm-bindgen-shared", ] -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - [[package]] name = "wasm-bindgen-macro" version = "0.2.95" @@ -3751,16 +3109,6 @@ version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" -[[package]] -name = "web-sys" -version = "0.3.72" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - [[package]] name = "weedle2" version = "5.0.0" @@ -3770,36 +3118,6 @@ dependencies = [ "nom", ] -[[package]] -name = "windows-registry" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" -dependencies = [ - "windows-result", - "windows-strings", - "windows-targets", -] - -[[package]] -name = "windows-result" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-strings" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" -dependencies = [ - "windows-result", - "windows-targets", -] - [[package]] name = "windows-sys" version = "0.52.0" @@ -3891,18 +3209,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "write16" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" - -[[package]] -name = "writeable" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" - [[package]] name = "wyz" version = "0.5.1" @@ -3912,30 +3218,6 @@ dependencies = [ "tap", ] -[[package]] -name = "yoke" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" -dependencies = [ - "serde", - "stable_deref_trait", - "yoke-derive", - "zerofrom", -] - -[[package]] -name = "yoke-derive" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", - "synstructure", -] - [[package]] name = "zerocopy" version = "0.7.35" @@ -3957,27 +3239,6 @@ dependencies = [ "syn 2.0.87", ] -[[package]] -name = "zerofrom" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" -dependencies = [ - "zerofrom-derive", -] - -[[package]] -name = "zerofrom-derive" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", - "synstructure", -] - [[package]] name = "zeroize" version = "1.8.1" @@ -3997,25 +3258,3 @@ dependencies = [ "quote", "syn 2.0.87", ] - -[[package]] -name = "zerovec" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" -dependencies = [ - "yoke", - "zerofrom", - "zerovec-derive", -] - -[[package]] -name = "zerovec-derive" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] diff --git a/Cargo.toml b/Cargo.toml index cd5bcd6..80f8ccb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,8 +2,7 @@ # https://doc.rust-lang.org/edition-guide/rust-2021/default-cargo-resolver.html#details resolver = "2" members = [ - "packages/kos", "packages/kos-crypto", - "packages/kos-mobile", "packages/kos-types", "packages/kos-web", + "packages/kos", "packages/kos-mobile", "packages/kos-web", ] # This makes the compiled code faster and smaller, but it makes compiling slower, # so it's only enabled in release mode. @@ -52,6 +51,4 @@ lazy_static = "1.4.0" thiserror = "1.0" kos = { version = "0.1.0", path = "./packages/kos", default-features = false } -kos-crypto = { version = "0.1.0", path = "./packages/kos-crypto", default-features = false } kos-mobile = { version = "0.1.0", path = "./packages/kos-mobile", default-features = false } -kos-types = { version = "0.1.0", path = "./packages/kos-types", default-features = false } diff --git a/packages/kos-crypto/Cargo.toml b/packages/kos-crypto/Cargo.toml deleted file mode 100644 index 86fdaff..0000000 --- a/packages/kos-crypto/Cargo.toml +++ /dev/null @@ -1,33 +0,0 @@ -[package] -name = "kos-crypto" -version = { workspace = true } -authors = { workspace = true } -edition = { workspace = true } -homepage = { workspace = true } -license = { workspace = true } -repository = { workspace = true } -rust-version = { workspace = true } - -[dependencies] -kos-types = { workspace = true, features = ["serde"] } -serde = { workspace = true, features = ["derive"] } -log = { workspace = true } -wasm-bindgen = { workspace = true } -rand = { workspace = true } -zeroize = { workspace = true } -coins-bip32 = { workspace = true } -coins-bip39 = { workspace = true } -hex = { workspace = true } -sha1 = "0.10" -sha2 = { workspace = true } -sha3 = { workspace = true } -hmac = { workspace = true } -secp256k1 = { workspace = true, features = ["rand", "serde", "bitcoin_hashes"] } -ed25519-dalek = { workspace = true, features = ["serde"] } -aes-gcm = "0.10" -aes = { version = "0.8" } -cfb-mode = "0.8" -cbc = { version = "0.1", features = ["block-padding", "std"] } -pem = "3" -pbkdf2 = { version = "0.12", features = ["simple"] } -base64 = "0.21" \ No newline at end of file diff --git a/packages/kos-crypto/src/blake2b.rs b/packages/kos-crypto/src/blake2b.rs deleted file mode 100644 index 9e04398..0000000 --- a/packages/kos-crypto/src/blake2b.rs +++ /dev/null @@ -1,190 +0,0 @@ -pub const BLOCK_BYTES: usize = 128; -pub const OUT_BYTES: usize = 64; - -#[rustfmt::skip] -static IV : [u64; 8] = [ - 0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1, - 0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179, -]; - -#[rustfmt::skip] -static SIGMA : [[u8; 16]; 12] = [ - [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ], - [ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 ], - [ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 ], - [ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 ], - [ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 ], - [ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 ], - [ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 ], - [ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 ], - [ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 ], - [ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 ], - [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ], - [ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 ], -]; - -pub struct Blake2b { - h: [u64; 8], - t: [u64; 2], - f: [u64; 2], - buf: [u8; 2 * BLOCK_BYTES], - buf_len: usize, - output_len: usize, -} - -impl Copy for Blake2b {} -impl Clone for Blake2b { - fn clone(&self) -> Blake2b { - *self - } -} - -impl Blake2b { - pub fn new(size: usize) -> Blake2b { - assert!(size > 0 && size <= OUT_BYTES); - - let param = encode_params(size as u8, 0); - let mut state = IV; - - for i in 0..state.len() { - state[i] ^= load64(¶m[i * 8..]); - } - - Blake2b { - h: state, - t: [0, 0], - f: [0, 0], - buf: [0u8; 2 * BLOCK_BYTES], - buf_len: 0, - output_len: size, - } - } - - pub fn update(&mut self, m: &[u8]) { - let mut m = m; - - while !m.is_empty() { - let left = self.buf_len; - let fill = 2 * BLOCK_BYTES - left; - - if m.len() > fill { - self.buf[left..(fill + left)].copy_from_slice(&m[..fill]); - self.buf_len += fill; - m = &m[fill..]; - self.increment_counter(BLOCK_BYTES as u64); - self.compress(); - for i in 0..BLOCK_BYTES { - self.buf[i] = self.buf[i + BLOCK_BYTES]; - } - self.buf_len -= BLOCK_BYTES; - } else { - self.buf[left..(m.len() + left)].copy_from_slice(m); - self.buf_len += m.len(); - m = &m[m.len()..]; - } - } - } - - pub fn finalize(&mut self) -> Vec { - let mut buf = [0u8; OUT_BYTES]; - if self.buf_len > BLOCK_BYTES { - self.increment_counter(BLOCK_BYTES as u64); - self.compress(); - for i in 0..BLOCK_BYTES { - self.buf[i] = self.buf[i + BLOCK_BYTES]; - } - self.buf_len -= BLOCK_BYTES; - } - let n = self.buf_len as u64; - self.increment_counter(n); - self.f[0] = !0; - for i in self.buf_len..self.buf.len() { - self.buf[i] = 0; - } - self.compress(); - for i in 0..self.h.len() { - store64(&mut buf[i * 8..], self.h[i]); - } - - buf[..self.output_len].to_vec() - } - - fn increment_counter(&mut self, inc: u64) { - self.t[0] += inc; - self.t[1] += if self.t[0] < inc { 1 } else { 0 }; - } - - fn compress(&mut self) { - let mut m = [0u64; 16]; - let mut v = [0u64; 16]; - let block = self.buf.as_ref(); - - assert!(block.len() >= BLOCK_BYTES); - - for i in 0..m.len() { - m[i] = load64(&block[i * 8..]); - } - - v[..8].copy_from_slice(&self.h[..8]); - - v[8] = IV[0]; - v[9] = IV[1]; - v[10] = IV[2]; - v[11] = IV[3]; - v[12] = self.t[0] ^ IV[4]; - v[13] = self.t[1] ^ IV[5]; - v[14] = self.f[0] ^ IV[6]; - v[15] = self.f[1] ^ IV[7]; - - macro_rules! g( - ($r: expr, $i: expr, $a: expr, $b: expr, $c: expr, $d: expr) => ({ - $a = $a.wrapping_add($b).wrapping_add(m[SIGMA[$r][2*$i+0] as usize]); - $d = ($d ^ $a).rotate_right(32); - $c = $c.wrapping_add($d); - $b = ($b ^ $c).rotate_right(24); - $a = $a.wrapping_add($b).wrapping_add(m[SIGMA[$r][2*$i+1] as usize]); - $d = ($d ^ $a).rotate_right(16); - $c = $c.wrapping_add($d); - $b = ($b ^ $c).rotate_right(63); - }); - ); - - macro_rules! round( - ($r: expr) => ({ - g!($r, 0, v[ 0], v[ 4], v[ 8], v[12]); - g!($r, 1, v[ 1], v[ 5], v[ 9], v[13]); - g!($r, 2, v[ 2], v[ 6], v[10], v[14]); - g!($r, 3, v[ 3], v[ 7], v[11], v[15]); - g!($r, 4, v[ 0], v[ 5], v[10], v[15]); - g!($r, 5, v[ 1], v[ 6], v[11], v[12]); - g!($r, 6, v[ 2], v[ 7], v[ 8], v[13]); - g!($r, 7, v[ 3], v[ 4], v[ 9], v[14]); - }); - ); - - for i in 0..12 { - round!(i); - } - - for i in 0..8 { - self.h[i] = self.h[i] ^ v[i] ^ v[i + 8] - } - } -} - -fn encode_params(size: u8, key_len: u8) -> [u8; 64] { - let mut param = [0u8; 64]; - param[0] = size; - param[1] = key_len; - param[2] = 1; // fanout - param[3] = 1; // depth - param -} - -fn load64(b: &[u8]) -> u64 { - u64::from_le_bytes(b[..8].try_into().expect("slice with incorrect length")) -} - -fn store64(b: &mut [u8], v: u64) { - b[..8].copy_from_slice(&v.to_le_bytes()); -} diff --git a/packages/kos-crypto/src/hash.rs b/packages/kos-crypto/src/hash.rs deleted file mode 100644 index 4f513fa..0000000 --- a/packages/kos-crypto/src/hash.rs +++ /dev/null @@ -1,31 +0,0 @@ -use crate::blake2b::Blake2b; -use sha2::{Digest, Sha256, Sha512}; -use sha3::Keccak256; - -#[inline] -pub fn sha256(input: &[u8]) -> [u8; 32] { - let mut hasher = Sha256::new(); - hasher.update(input); - hasher.finalize().into() -} - -#[inline] -pub fn keccak256(input: &[u8]) -> [u8; 32] { - let mut hasher = Keccak256::new(); - hasher.update(input); - hasher.finalize().into() -} - -#[inline] -pub fn blake2b256(input: &[u8]) -> [u8; 32] { - let mut hasher = Blake2b::new(32); - hasher.update(input); - hasher.finalize().try_into().unwrap() -} - -#[inline] -pub fn sha512(input: &[u8]) -> [u8; 64] { - let mut hasher = Sha512::new(); - hasher.update(input); - hasher.finalize().into() -} diff --git a/packages/kos-crypto/src/lib.rs b/packages/kos-crypto/src/lib.rs deleted file mode 100644 index 60550d1..0000000 --- a/packages/kos-crypto/src/lib.rs +++ /dev/null @@ -1,4 +0,0 @@ -mod blake2b; -pub mod cipher; -pub mod hash; -pub mod mnemonic; diff --git a/packages/kos-mobile/Cargo.toml b/packages/kos-mobile/Cargo.toml index 5cc049d..621163e 100644 --- a/packages/kos-mobile/Cargo.toml +++ b/packages/kos-mobile/Cargo.toml @@ -16,8 +16,6 @@ name = "uniffi-bindgen" path = "src/bin/uniffi-bindgen.rs" [dependencies] -kos-crypto = { workspace = true } -kos-types = { workspace = true, features = ["serde"] } kos = { workspace = true } hex = { workspace = true } diff --git a/packages/kos-mobile/src/lib.rs b/packages/kos-mobile/src/lib.rs index 0a323a7..6e2b408 100644 --- a/packages/kos-mobile/src/lib.rs +++ b/packages/kos-mobile/src/lib.rs @@ -1,9 +1,8 @@ use hex::FromHexError; use hex::ToHex; use kos::chains::{get_chain_by_base_id, Chain, ChainError, Transaction}; -use kos_crypto::cipher; -use kos_crypto::cipher::CipherAlgo; -use kos_types::error::Error as KosError; +use kos::crypto::cipher; +use kos::crypto::cipher::CipherAlgo; uniffi::setup_scaffolding!(); @@ -29,12 +28,6 @@ impl From for KOSError { } } -impl From for KOSError { - fn from(err: KosError) -> Self { - KOSError::KOSDelegate(err.to_string()) - } -} - #[derive(uniffi::Record)] struct KOSAccount { pub chain_id: u32, @@ -54,12 +47,12 @@ struct KOSTransaction { #[uniffi::export] fn generate_mnemonic(size: i32) -> Result { - Ok(kos_crypto::mnemonic::generate_mnemonic(size as usize)?.to_phrase()) + Ok(kos::crypto::mnemonic::generate_mnemonic(size as usize)?.to_phrase()) } #[uniffi::export] fn validate_mnemonic(mnemonic: String) -> bool { - kos_crypto::mnemonic::validate_mnemonic(mnemonic.as_str()).is_ok() + kos::crypto::mnemonic::validate_mnemonic(mnemonic.as_str()).is_ok() } #[uniffi::export] diff --git a/packages/kos-types/Cargo.toml b/packages/kos-types/Cargo.toml deleted file mode 100644 index f218026..0000000 --- a/packages/kos-types/Cargo.toml +++ /dev/null @@ -1,30 +0,0 @@ -[package] -name = "kos-types" -version = { workspace = true } -authors = { workspace = true } -edition = { workspace = true } -homepage = { workspace = true } -license = { workspace = true } -repository = { workspace = true } -rust-version = { workspace = true } - -[features] -alloc = ["hex/alloc"] -serde = ["dep:serde", "alloc"] -std = ["alloc", "serde?/std"] -random = ["rand"] - -[dependencies] -rand = { workspace = true, optional = true } -coins-bip32 = { workspace = true } -coins-bip39 = { workspace = true } -secp256k1 = { workspace = true, features = ["recovery", "rand"] } -ed25519-dalek = { workspace = true } -log = { workspace = true } -serde = { workspace = true, features = ["derive", "alloc"], optional = true } -serde_json = { workspace = true } -hex = { workspace = true } -reqwest = { workspace = true, default-features = false } -wasm-bindgen = { workspace = true } -num-bigint = "0.4" -num-traits = "0.2" \ No newline at end of file diff --git a/packages/kos-types/src/lib.rs b/packages/kos-types/src/lib.rs deleted file mode 100644 index a91e735..0000000 --- a/packages/kos-types/src/lib.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod error; diff --git a/packages/kos-web/Cargo.toml b/packages/kos-web/Cargo.toml index c0771f9..b6ae257 100644 --- a/packages/kos-web/Cargo.toml +++ b/packages/kos-web/Cargo.toml @@ -27,6 +27,4 @@ pem = "3" postcard = { version = "1.0.6", features = ["use-std"] } lazy_static = { workspace = true } kos = { workspace = true } -kos-crypto = { workspace = true } -kos-types = { workspace = true } wasm-bindgen = { workspace = true } diff --git a/packages/kos-types/src/error.rs b/packages/kos-web/src/error.rs similarity index 58% rename from packages/kos-types/src/error.rs rename to packages/kos-web/src/error.rs index a73cb16..8e55b7a 100644 --- a/packages/kos-types/src/error.rs +++ b/packages/kos-web/src/error.rs @@ -1,7 +1,4 @@ -use core::convert::Infallible; -use ed25519_dalek::SignatureError; -use reqwest::Error as ReqwestError; -use secp256k1::Error as Secp256k1Error; +use kos::chains::ChainError; use std::{error, fmt, str}; use wasm_bindgen::JsValue; @@ -33,8 +30,6 @@ pub enum Error { InvalidMessage(String), /// Out of preallocated memory NotEnoughMemory(String), - /// Reqwest error - ReqwestError(String), /// Invalid Enum Variant InvalidEnumVariant(String), /// Invalid Len @@ -44,11 +39,13 @@ pub enum Error { /// InvalidTransaction InvalidTransaction(String), /// WalletManagerError - WalletManagerError(String), + WalletManager(String), /// CipherError - CipherError(String), + Cipher(String), /// TransportError - TransportError(String), + Transport(String), + /// DelegateError + Delegate(String), } impl fmt::Display for Error { @@ -66,54 +63,18 @@ impl fmt::Display for Error { Error::InvalidSignature(e) => write!(f, "Invalid signature: {}", e), Error::InvalidMessage(e) => write!(f, "Invalid message: {}", e), Error::NotEnoughMemory(e) => write!(f, "Not enough memory: {}", e), - Error::ReqwestError(e) => write!(f, "Reqwest error: {}", e), Error::InvalidEnumVariant(e) => write!(f, "Invalid Enum Variant error: {}", e), Error::InvalidLen(e) => write!(f, "Invalid Len: {}", e), Error::InvalidNumberParse(e) => write!(f, "Invalid number parse: {}", e), Error::InvalidTransaction(e) => write!(f, "Invalid transaction: {}", e), - Error::WalletManagerError(e) => write!(f, "WalletManager error: {}", e), - Error::CipherError(e) => write!(f, "Cipher error: {}", e), - Error::TransportError(e) => write!(f, "Transport error: {}", e), + Error::WalletManager(e) => write!(f, "WalletManager error: {}", e), + Error::Cipher(e) => write!(f, "Cipher error: {}", e), + Error::Transport(e) => write!(f, "Transport error: {}", e), + Error::Delegate(e) => write!(f, "Delegate error: {}", e), } } } -impl From for Error { - fn from(secp: Secp256k1Error) -> Self { - match secp { - Secp256k1Error::IncorrectSignature - | Secp256k1Error::InvalidSignature - | Secp256k1Error::InvalidTweak - | Secp256k1Error::InvalidSharedSecret - | Secp256k1Error::InvalidPublicKeySum - | Secp256k1Error::InvalidParityValue(_) - | Secp256k1Error::InvalidRecoveryId => Self::InvalidSignature("Secp256k1Error"), - Secp256k1Error::InvalidMessage => Self::InvalidMessage(secp.to_string()), - Secp256k1Error::InvalidPublicKey => Self::InvalidPublicKey(secp.to_string()), - Secp256k1Error::InvalidSecretKey => Self::InvalidPrivateKey("Secp256k1Error"), - Secp256k1Error::NotEnoughMemory => Self::NotEnoughMemory(secp.to_string()), - } - } -} - -impl From for Error { - fn from(_: SignatureError) -> Self { - Self::InvalidSignature("Invalid signature") - } -} - -impl From for Error { - fn from(_: coins_bip39::MnemonicError) -> Self { - Self::InvalidMnemonic("Invalid mnemonic") - } -} - -impl From for Error { - fn from(_: coins_bip32::Bip32Error) -> Self { - Self::InvalidPath("Invalid path") - } -} - impl From for Error { fn from(e: serde_json::Error) -> Self { Self::JSONSerde(e.to_string()) @@ -132,26 +93,14 @@ impl From for JsValue { } } -impl From for Error { - fn from(e: ReqwestError) -> Self { - Self::ReqwestError(e.to_string()) - } -} - impl From for Error { fn from(e: hex::FromHexError) -> Self { Self::InvalidString(e.to_string()) } } -impl From for Infallible { - fn from(_: Error) -> Infallible { - unreachable!() - } -} - -impl From for Error { - fn from(_: Infallible) -> Error { - unreachable!() +impl From for Error { + fn from(err: ChainError) -> Self { + Error::Delegate(err.to_string()) } } diff --git a/packages/kos-web/src/lib.rs b/packages/kos-web/src/lib.rs index 5d97a52..832de79 100644 --- a/packages/kos-web/src/lib.rs +++ b/packages/kos-web/src/lib.rs @@ -1,13 +1,13 @@ -use kos_crypto::cipher; -use kos_crypto::cipher::CipherAlgo; -use kos_crypto::mnemonic::generate_mnemonic; -use kos_types::error::Error; +use crate::error::Error; +use kos::crypto::cipher; +use kos::crypto::mnemonic::generate_mnemonic; use qrcode_generator::QrCodeEcc; use wasm_bindgen::prelude::*; mod models; mod utils; +mod error; pub mod wallet; /// Generates a random mnemonic phrase given the number of words to generate, `count`. @@ -29,17 +29,11 @@ pub fn to_string(data: &[u8]) -> Result { .map_err(|e| Error::InvalidString(format!("Invalid UTF-8 string: {}", e))) } -/// Encrypts the given data with the given password. -#[wasm_bindgen(js_name = "encrypt")] -pub fn encrypt(algo: CipherAlgo, data: &[u8], password: &str) -> Result, Error> { - algo.encrypt(data, password) -} - /// Decrypts the given data with the given password. /// Data will have the algorithm tag prepended to it (1 byte). #[wasm_bindgen(js_name = "decrypt")] pub fn decrypt(data: &[u8], password: &str) -> Result, Error> { - cipher::decrypt(data, password) + cipher::decrypt(data, password).map_err(|e| Error::Cipher(format!("{}", e))) } /// Create pem file from tag and data diff --git a/packages/kos-web/src/utils.rs b/packages/kos-web/src/utils.rs index 64d9201..eb5e28e 100644 --- a/packages/kos-web/src/utils.rs +++ b/packages/kos-web/src/utils.rs @@ -1,4 +1,4 @@ -use kos_types::error::Error; +use crate::error::Error; use serde::{Deserialize, Serialize}; #[allow(dead_code)] diff --git a/packages/kos-web/src/wallet.rs b/packages/kos-web/src/wallet.rs index 4a8eaa2..cb0daa1 100644 --- a/packages/kos-web/src/wallet.rs +++ b/packages/kos-web/src/wallet.rs @@ -4,9 +4,9 @@ use pem::{parse as parse_pem, Pem}; use serde::{Deserialize, Serialize}; use strum::{EnumCount, IntoStaticStr}; +use crate::error::Error; use crate::utils::unpack; use kos::chains::{get_chain_by_base_id, Transaction as KosTransaction}; -use kos_types::error::Error; use wasm_bindgen::prelude::*; #[wasm_bindgen] @@ -43,24 +43,24 @@ impl Wallet { password: Option, ) -> Result { // validate mnemonic entropy - kos_crypto::mnemonic::validate_mnemonic(&mnemonic)?; + kos::crypto::mnemonic::validate_mnemonic(&mnemonic)?; let chain = get_chain_by_base_id(chain_id) - .ok_or_else(|| Error::WalletManagerError("Invalid chain".to_string()))?; + .ok_or_else(|| Error::WalletManager("Invalid chain".to_string()))?; let seed = chain .mnemonic_to_seed(mnemonic.clone(), password.unwrap_or_default()) - .map_err(|e| Error::WalletManagerError(format!("mnemonic to seed: {}", e)))?; + .map_err(|e| Error::WalletManager(format!("mnemonic to seed: {}", e)))?; let private_key = chain .derive(seed, path.clone()) - .map_err(|e| Error::WalletManagerError(format!("derive keypair: {}", e)))?; + .map_err(|e| Error::WalletManager(format!("derive keypair: {}", e)))?; let public_key = chain .get_pbk(private_key.clone()) - .map_err(|e| Error::WalletManagerError(format!("get public key: {}", e)))?; + .map_err(|e| Error::WalletManager(format!("get public key: {}", e)))?; let address = chain .get_address(public_key) - .map_err(|e| Error::WalletManagerError(format!("get address: {}", e)))?; + .map_err(|e| Error::WalletManager(format!("get address: {}", e)))?; Ok(Wallet { chain: chain_id, @@ -83,7 +83,7 @@ impl Wallet { password: Option, ) -> Result { let chain = get_chain_by_base_id(chain_id) - .ok_or_else(|| Error::WalletManagerError("Invalid chain".to_string()))?; + .ok_or_else(|| Error::WalletManager("Invalid chain".to_string()))?; let path = chain.get_path(path_options.index, path_options.is_legacy.unwrap()); let mut wallet = Wallet::from_mnemonic(chain_id, mnemonic, path, password)?; @@ -100,18 +100,18 @@ impl Wallet { // check size of private key if private_key_bytes.len() != 32 { - return Err(Error::WalletManagerError("Invalid private key".to_string())); + return Err(Error::WalletManager("Invalid private key".to_string())); } let chain = get_chain_by_base_id(chain_id) - .ok_or_else(|| Error::WalletManagerError("Invalid chain".to_string()))?; + .ok_or_else(|| Error::WalletManager("Invalid chain".to_string()))?; let public_key = chain .get_pbk(hex::decode(private_key_bytes.clone())?) - .map_err(|e| Error::WalletManagerError(format!("get public key: {}", e)))?; + .map_err(|e| Error::WalletManager(format!("get public key: {}", e)))?; let address = chain .get_address(public_key.clone()) - .map_err(|e| Error::WalletManagerError(format!("get address: {}", e)))?; + .map_err(|e| Error::WalletManager(format!("get address: {}", e)))?; // create wallet from keypair Ok(Wallet { @@ -130,11 +130,11 @@ impl Wallet { /// restore wallet from mnemonic pub fn from_kc_pem(chain: u32, data: &[u8]) -> Result { // decode pem file - let pem = parse_pem(data) - .map_err(|_| Error::WalletManagerError("Invalid PEM data".to_string()))?; + let pem = + parse_pem(data).map_err(|_| Error::WalletManager("Invalid PEM data".to_string()))?; let content = String::from_utf8(pem.contents().to_vec()) - .map_err(|_| Error::WalletManagerError("Invalid PEM data".to_string()))?; + .map_err(|_| Error::WalletManager("Invalid PEM data".to_string()))?; let pk_hex = content.chars().take(64).collect::(); @@ -145,8 +145,8 @@ impl Wallet { #[wasm_bindgen(js_name = "fromPem")] pub fn from_pem(data: &[u8]) -> Result { // parse pem - let pem = parse_pem(data) - .map_err(|_| Error::WalletManagerError("Invalid PEM data".to_string()))?; + let pem = + parse_pem(data).map_err(|_| Error::WalletManager("Invalid PEM data".to_string()))?; Wallet::import(pem) } @@ -157,7 +157,7 @@ impl Wallet { pub fn import(pem: Pem) -> Result { // Deserialize decrypted bytes to WalletManager let wallet: Wallet = unpack(pem.contents()) - .map_err(|e| Error::CipherError(format!("deserialize data: {}", e)))?; + .map_err(|e| Error::Cipher(format!("deserialize data: {}", e)))?; Ok(wallet) } @@ -166,11 +166,11 @@ impl Wallet { #[wasm_bindgen] // wallet properties impl Wallet { - // #[wasm_bindgen(js_name = "getChain")] + #[wasm_bindgen(js_name = "getChain")] // /// get wallet chain type - // pub fn get_chain(&self) -> Chain { - // self.chain - // } + pub fn get_chain(&self) -> u32 { + self.chain + } #[wasm_bindgen(js_name = "getAccountType")] /// get wallet account type @@ -196,7 +196,7 @@ impl Wallet { #[wasm_bindgen(js_name = "getIndex")] /// get wallet index if wallet is created from mnemonic index pub fn get_index(&self) -> Result { - self.index.ok_or(Error::WalletManagerError( + self.index.ok_or(Error::WalletManager( "Wallet is not created from mnemonic index".to_string(), )) } @@ -230,13 +230,13 @@ impl Wallet { Some(ref pk_hex) => { let pk_bytes = hex::decode(pk_hex)?; let chain = get_chain_by_base_id(self.chain) - .ok_or_else(|| Error::WalletManagerError("Invalid chain".to_string()))?; + .ok_or_else(|| Error::WalletManager("Invalid chain".to_string()))?; chain .sign_message(pk_bytes, message.to_vec()) - .map_err(|e| Error::WalletManagerError(format!("sign message: {}", e))) + .map_err(|e| Error::WalletManager(format!("sign message: {}", e))) } - None => Err(Error::WalletManagerError("no keypair".to_string())), + None => Err(Error::WalletManager("no keypair".to_string())), } } @@ -253,11 +253,11 @@ impl Wallet { }; let chain = get_chain_by_base_id(self.chain) - .ok_or_else(|| Error::WalletManagerError("Invalid chain".to_string()))?; + .ok_or_else(|| Error::WalletManager("Invalid chain".to_string()))?; let signed_tx = chain .sign_tx(pk_bytes, tx) - .map_err(|e| Error::WalletManagerError(format!("sign transaction: {}", e)))?; + .map_err(|e| Error::WalletManager(format!("sign transaction: {}", e)))?; Ok(Transaction { raw_data: signed_tx.raw_data, @@ -265,7 +265,7 @@ impl Wallet { signature: signed_tx.signature, }) } - None => Err(Error::WalletManagerError("no keypair".to_string())), + None => Err(Error::WalletManager("no private key".to_string())), } } } diff --git a/packages/kos/Cargo.toml b/packages/kos/Cargo.toml index 34ef491..b054bf0 100644 --- a/packages/kos/Cargo.toml +++ b/packages/kos/Cargo.toml @@ -54,6 +54,12 @@ rand_core = { version = "0.6.4", features = ["getrandom"], default-features = fa getrandom = { version = "0.2", features = ["js"] } alloy-dyn-abi = { version = "0.8.5", features = ["eip712"] } serde_json = { workspace = true } +aes-gcm = "0.10" +aes = { version = "0.8" } +pem = "3" +cfb-mode = "0.8" +cbc = { version = "0.1", features = ["block-padding", "std"] } +pbkdf2 = { version = "0.12", features = ["simple"] } [build-dependencies] prost-build = "0.12.1" diff --git a/packages/kos/src/chains/mod.rs b/packages/kos/src/chains/mod.rs index 20a9c61..77f9708 100644 --- a/packages/kos/src/chains/mod.rs +++ b/packages/kos/src/chains/mod.rs @@ -53,6 +53,9 @@ pub enum ChainError { InvalidPublicKey, InvalidSeed, InvalidCredential, + InvalidMnemonic, + CipherError(String), + InvalidString(String), } impl Display for ChainError { @@ -100,6 +103,15 @@ impl Display for ChainError { ChainError::InvalidCredential => { write!(f, "invalid credential") } + ChainError::InvalidMnemonic => { + write!(f, "invalid mnemonic") + } + ChainError::CipherError(e) => { + write!(f, "cipher error: {}", e) + } + ChainError::InvalidString(e) => { + write!(f, "invalid string: {}", e) + } } } } @@ -184,6 +196,9 @@ impl ChainError { ChainError::CurveErrorSr(_) => 14, ChainError::InvalidSeed => 15, ChainError::InvalidCredential => 16, + ChainError::InvalidMnemonic => 17, + ChainError::CipherError(_) => 18, + ChainError::InvalidString(_) => 19, } } } diff --git a/packages/kos-crypto/src/cipher.rs b/packages/kos/src/crypto/cipher.rs similarity index 76% rename from packages/kos-crypto/src/cipher.rs rename to packages/kos/src/crypto/cipher.rs index b40f44e..2b0fb66 100644 --- a/packages/kos-crypto/src/cipher.rs +++ b/packages/kos/src/crypto/cipher.rs @@ -1,6 +1,3 @@ -use base64::{engine::general_purpose as b64_engine, Engine}; -use kos_types::error::Error; - use aes::cipher::{ block_padding::Pkcs7, generic_array::GenericArray, AsyncStreamCipher, BlockDecryptMut, BlockEncryptMut, KeyIvInit, @@ -12,6 +9,7 @@ use aes_gcm::{ Nonce, }; +use crate::chains::ChainError; use hmac::Hmac; use pbkdf2::pbkdf2; use pbkdf2::{ @@ -22,8 +20,6 @@ use pem::{parse as parse_pem, Pem}; use rand::Rng; use sha2::Sha256; -use wasm_bindgen::prelude::*; - const KEY_SIZE: usize = 32; // SALTSIZE const NONCE_SIZE: usize = 12; // NONCESIZE const IV_SIZE: usize = 16; // IVSIZE @@ -32,13 +28,12 @@ const BLOCK_SIZE: usize = 16; // BLOCKSIZE const ITERATIONS: u32 = 10000; #[derive(Debug, Clone)] -#[wasm_bindgen] pub enum CipherAlgo { GMC = 0, CBC = 1, CFB = 2, } -// todo!("build with macro") + impl CipherAlgo { pub fn to_vec(&self) -> Vec { match self { @@ -48,16 +43,18 @@ impl CipherAlgo { } } - pub fn from_u8(value: u8) -> Result { + pub fn from_u8(value: u8) -> Result { match value { 0 => Ok(CipherAlgo::GMC), 1 => Ok(CipherAlgo::CBC), 2 => Ok(CipherAlgo::CFB), - _ => Err(Error::CipherError("Invalid cipher algorithm".to_owned())), + _ => Err(ChainError::CipherError( + "Invalid cipher algorithm".to_owned(), + )), } } - pub fn encrypt(&self, data: &[u8], password: &str) -> Result, Error> { + pub fn encrypt(&self, data: &[u8], password: &str) -> Result, ChainError> { match self { CipherAlgo::GMC => gcm_encrypt(data, password), CipherAlgo::CBC => cbc_encrypt(data, password), @@ -65,7 +62,7 @@ impl CipherAlgo { } } - pub fn decrypt(&self, data: &[u8], password: &str) -> Result, Error> { + pub fn decrypt(&self, data: &[u8], password: &str) -> Result, ChainError> { match self { CipherAlgo::GMC => gcm_decrypt(data, password), CipherAlgo::CBC => cbc_decrypt(data, password), @@ -74,7 +71,7 @@ impl CipherAlgo { } } -pub fn to_pem(tag: String, data: &[u8]) -> Result { +pub fn to_pem(tag: String, data: &[u8]) -> Result { Ok(Pem::new(tag, data)) } @@ -82,8 +79,8 @@ pub fn from_pem(pem: Pem) -> Vec { pem.contents().to_vec() } -pub fn string_to_pem(data: &str) -> Result { - parse_pem(data.as_bytes()).map_err(|e| Error::CipherError(format!("{}", e))) +pub fn string_to_pem(data: &str) -> Result { + parse_pem(data.as_bytes()).map_err(|e| ChainError::CipherError(format!("{}", e))) } pub fn create_checksum(password: &str) -> String { @@ -106,17 +103,17 @@ pub fn check_checksum(password: &str, checksum: String) -> bool { pub fn derive_key(salt: &[u8], password: &str) -> Vec { let mut key = vec![0u8; KEY_SIZE]; pbkdf2::>(password.as_bytes(), salt, ITERATIONS, &mut key) - .expect("Error deriving key"); + .expect("ChainError deriving key"); key } -pub fn encrypt(algo: CipherAlgo, data: &[u8], password: &str) -> Result, Error> { +pub fn encrypt(algo: CipherAlgo, data: &[u8], password: &str) -> Result, ChainError> { algo.encrypt(data, password) } -pub fn decrypt(data: &[u8], password: &str) -> Result, Error> { +pub fn decrypt(data: &[u8], password: &str) -> Result, ChainError> { if data.is_empty() { - return Err(Error::CipherError("Invalid PEM data".to_owned())); + return Err(ChainError::CipherError("Invalid PEM data".to_owned())); } // get algo @@ -124,7 +121,7 @@ pub fn decrypt(data: &[u8], password: &str) -> Result, Error> { algo.decrypt(&data[1..], password) } -pub fn gcm_encrypt(data: &[u8], password: &str) -> Result, Error> { +pub fn gcm_encrypt(data: &[u8], password: &str) -> Result, ChainError> { // Derive key from password let salt: [u8; 32] = rand::thread_rng().gen(); let derived_key = derive_key(&salt, password); @@ -137,7 +134,7 @@ pub fn gcm_encrypt(data: &[u8], password: &str) -> Result, Error> { // Encrypt data let ciphertext = cipher .encrypt(&nonce, data) - .map_err(|e| Error::CipherError(format!("encryption failed: {}", e)))?; + .map_err(|e| ChainError::CipherError(format!("encryption failed: {}", e)))?; // Create PEM let mut result = CipherAlgo::GMC.to_vec(); @@ -148,9 +145,9 @@ pub fn gcm_encrypt(data: &[u8], password: &str) -> Result, Error> { Ok(result) } -pub fn gcm_decrypt(encrypted: &[u8], password: &str) -> Result, Error> { +pub fn gcm_decrypt(encrypted: &[u8], password: &str) -> Result, ChainError> { if encrypted.len() < KEY_SIZE + NONCE_SIZE { - return Err(Error::CipherError("Invalid PEM data".to_owned())); + return Err(ChainError::CipherError("Invalid PEM data".to_owned())); } let salt = &encrypted[..KEY_SIZE]; let nonce = &encrypted[KEY_SIZE..KEY_SIZE + NONCE_SIZE]; @@ -160,12 +157,12 @@ pub fn gcm_decrypt(encrypted: &[u8], password: &str) -> Result, Error> { let cipher = Aes256Gcm::new(key); cipher .decrypt(Nonce::from_slice(nonce), encrypted_data) - .map_err(|e| Error::CipherError(format!("decryption failed: {}", e))) + .map_err(|e| ChainError::CipherError(format!("decryption failed: {}", e))) } type Aes256CbcEnc = cbc::Encryptor; type Aes256CbcDec = cbc::Decryptor; -pub fn cbc_encrypt(data: &[u8], password: &str) -> Result, Error> { +pub fn cbc_encrypt(data: &[u8], password: &str) -> Result, ChainError> { let iv: [u8; IV_SIZE] = rand::thread_rng().gen(); let derived_key = derive_key(&iv, password); // KeySize [u8; 32] let key = GenericArray::from_slice(&derived_key); @@ -179,7 +176,7 @@ pub fn cbc_encrypt(data: &[u8], password: &str) -> Result, Error> { let ct = Aes256CbcEnc::new(key, &iv.into()) .encrypt_padded_mut::(&mut buf, data.len()) - .map_err(|e| Error::CipherError(format!("encryption failed: {}", e)))?; + .map_err(|e| ChainError::CipherError(format!("encryption failed: {}", e)))?; // Create PEM let mut result = CipherAlgo::CBC.to_vec(); @@ -189,9 +186,9 @@ pub fn cbc_encrypt(data: &[u8], password: &str) -> Result, Error> { Ok(result) } -pub fn cbc_decrypt(encrypted: &[u8], password: &str) -> Result, Error> { +pub fn cbc_decrypt(encrypted: &[u8], password: &str) -> Result, ChainError> { if encrypted.len() < IV_SIZE { - return Err(Error::CipherError("Invalid PEM data".to_owned())); + return Err(ChainError::CipherError("Invalid PEM data".to_owned())); } let iv = GenericArray::from_slice(&encrypted[..IV_SIZE]); @@ -202,14 +199,14 @@ pub fn cbc_decrypt(encrypted: &[u8], password: &str) -> Result, Error> { let mut buf = encrypted_data.to_vec(); let pt: &[u8] = Aes256CbcDec::new(key, iv) .decrypt_padded_mut::(&mut buf) - .map_err(|e| Error::CipherError(format!("decryption failed: {}", e)))?; + .map_err(|e| ChainError::CipherError(format!("decryption failed: {}", e)))?; Ok(pt.to_vec()) } type Aes256CfbEnc = cfb_mode::Encryptor; type Aes256CfbDec = cfb_mode::Decryptor; -pub fn cfb_encrypt(data: &[u8], password: &str) -> Result, Error> { +pub fn cfb_encrypt(data: &[u8], password: &str) -> Result, ChainError> { let iv: [u8; IV_SIZE] = rand::thread_rng().gen(); let derived_key = derive_key(&iv, password); // KeySize [u8; 32] let key = GenericArray::from_slice(&derived_key); @@ -225,9 +222,9 @@ pub fn cfb_encrypt(data: &[u8], password: &str) -> Result, Error> { Ok(result) } -pub fn cfb_decrypt(encrypted: &[u8], password: &str) -> Result, Error> { +pub fn cfb_decrypt(encrypted: &[u8], password: &str) -> Result, ChainError> { if encrypted.len() < IV_SIZE { - return Err(Error::CipherError("Invalid PEM data".to_owned())); + return Err(ChainError::CipherError("Invalid PEM data".to_owned())); } let iv = GenericArray::from_slice(&encrypted[..IV_SIZE]); @@ -316,40 +313,3 @@ mod tests { assert!(check_checksum(password, checksum)); } } - -/* - LEGACY GCM DECRYPT SHA1 KEY no SALT -*/ -use sha1::Sha1; -#[wasm_bindgen(js_name = gcmDecryptByKey)] -pub fn gcm_decrypt_by_key(encrypted: &str, key: &str) -> Result, Error> { - if encrypted.len() < NONCE_SIZE { - return Err(Error::CipherError("invalid data len".to_owned())); - } - - // convert hex to bytes - let encrypted = hex::decode(encrypted) - .map_err(|e| Error::CipherError(format!("decryption failed: {}", e)))?; - - let b64 = b64_engine::STANDARD; - // convert base64 to bytes - let key = b64 - .decode(key) - .map_err(|e| Error::CipherError(format!("decryption failed: {}", e)))?; - - // compute encrypt key - let salt = crate::hash::sha256("".as_bytes()); - let key_hash = crate::hash::sha256(&key[..]); - let mut key = vec![0u8; KEY_SIZE]; - pbkdf2::>(&key_hash, &salt, 4096, &mut key).expect("Error deriving key"); - - // retrieve nonce and encrypted data - let nonce = &encrypted[..NONCE_SIZE]; - let encrypted_data = &encrypted[NONCE_SIZE..]; - - let key = Key::::from_slice(&key); - let cipher = Aes256Gcm::new(key); - cipher - .decrypt(Nonce::from_slice(nonce), encrypted_data) - .map_err(|e| Error::CipherError(format!("decryption failed: {}", e))) -} diff --git a/packages/kos-crypto/src/mnemonic.rs b/packages/kos/src/crypto/mnemonic.rs similarity index 57% rename from packages/kos-crypto/src/mnemonic.rs rename to packages/kos/src/crypto/mnemonic.rs index 9c1cd2c..e6e7800 100644 --- a/packages/kos-crypto/src/mnemonic.rs +++ b/packages/kos/src/crypto/mnemonic.rs @@ -1,16 +1,21 @@ -use kos_types::error::Error; - +use crate::chains::ChainError; use coins_bip39::{English, Mnemonic}; -pub fn generate_mnemonic(count: usize) -> Result, Error> { +pub fn generate_mnemonic(count: usize) -> Result, ChainError> { // create rng let mut rng = rand::thread_rng(); // generate mnemonic phrase Ok(Mnemonic::::new_with_count(&mut rng, count)?) } -pub fn validate_mnemonic(phrase: &str) -> Result<(), Error> { +pub fn validate_mnemonic(phrase: &str) -> Result<(), ChainError> { // validate mnemonic phrase let _mnemonic: Mnemonic = phrase.parse()?; Ok(()) } + +impl From for ChainError { + fn from(_: coins_bip39::MnemonicError) -> Self { + Self::InvalidMnemonic + } +} diff --git a/packages/kos/src/crypto/mod.rs b/packages/kos/src/crypto/mod.rs index 54847f9..7f98b97 100644 --- a/packages/kos/src/crypto/mod.rs +++ b/packages/kos/src/crypto/mod.rs @@ -10,6 +10,11 @@ mod rng; pub mod secp256k1; pub mod sr25519; +#[cfg(not(feature = "ksafe"))] +pub mod cipher; +#[cfg(not(feature = "ksafe"))] +pub mod mnemonic; + #[allow(clippy::module_inception)] #[cfg(not(feature = "ksafe"))] // pub mod mnemonic; From ee96fe4fde4d303077f03add1f38fb580a65b8d9 Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Tue, 26 Nov 2024 08:31:29 -0300 Subject: [PATCH 26/42] chore: fix fmt --- .../kos/src/protos/generated/klv/proto.rs | 282 +++--------------- .../kos/src/protos/generated/trx/protocol.rs | 268 +++-------------- 2 files changed, 81 insertions(+), 469 deletions(-) diff --git a/packages/kos/src/protos/generated/klv/proto.rs b/packages/kos/src/protos/generated/klv/proto.rs index d480efe..f6a9d77 100644 --- a/packages/kos/src/protos/generated/klv/proto.rs +++ b/packages/kos/src/protos/generated/klv/proto.rs @@ -50,17 +50,7 @@ pub struct CreateAssetContract { } /// Nested message and enum types in `CreateAssetContract`. pub mod create_asset_contract { - #[derive( - Clone, - Copy, - Debug, - PartialEq, - Eq, - Hash, - PartialOrd, - Ord, - ::prost::Enumeration - )] + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum EnumAssetType { Fungible = 0, @@ -136,17 +126,7 @@ pub struct StakingInfo { } /// Nested message and enum types in `StakingInfo`. pub mod staking_info { - #[derive( - Clone, - Copy, - Debug, - PartialEq, - Eq, - Hash, - PartialOrd, - Ord, - ::prost::Enumeration - )] + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum InterestType { Apri = 0, @@ -201,10 +181,8 @@ pub struct RoyaltiesInfo { #[prost(int64, tag = "5")] pub market_fixed: i64, #[prost(btree_map = "string, message", tag = "6")] - pub split_royalties: ::prost::alloc::collections::BTreeMap< - ::prost::alloc::string::String, - RoyaltySplitInfo, - >, + pub split_royalties: + ::prost::alloc::collections::BTreeMap<::prost::alloc::string::String, RoyaltySplitInfo>, #[prost(int64, tag = "7")] pub ito_fixed: i64, #[prost(uint32, tag = "8")] @@ -281,17 +259,7 @@ pub struct AssetTriggerContract { } /// Nested message and enum types in `AssetTriggerContract`. pub mod asset_trigger_contract { - #[derive( - Clone, - Copy, - Debug, - PartialEq, - Eq, - Hash, - PartialOrd, - Ord, - ::prost::Enumeration - )] + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum EnumTriggerType { Mint = 0, @@ -455,17 +423,7 @@ pub struct WithdrawContract { } /// Nested message and enum types in `WithdrawContract`. pub mod withdraw_contract { - #[derive( - Clone, - Copy, - Debug, - PartialEq, - Eq, - Hash, - PartialOrd, - Ord, - ::prost::Enumeration - )] + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum EnumWithdrawType { Staking = 0, @@ -503,17 +461,7 @@ pub struct ClaimContract { } /// Nested message and enum types in `ClaimContract`. pub mod claim_contract { - #[derive( - Clone, - Copy, - Debug, - PartialEq, - Eq, - Hash, - PartialOrd, - Ord, - ::prost::Enumeration - )] + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum EnumClaimType { StakingClaim = 0, @@ -559,10 +507,7 @@ pub struct SetAccountNameContract { #[derive(Clone, PartialEq, ::prost::Message)] pub struct ProposalContract { #[prost(btree_map = "int32, bytes", tag = "1")] - pub parameters: ::prost::alloc::collections::BTreeMap< - i32, - ::prost::alloc::vec::Vec, - >, + pub parameters: ::prost::alloc::collections::BTreeMap>, #[prost(bytes = "vec", tag = "2")] pub description: ::prost::alloc::vec::Vec, #[prost(uint32, tag = "3")] @@ -581,17 +526,7 @@ pub struct VoteContract { } /// Nested message and enum types in `VoteContract`. pub mod vote_contract { - #[derive( - Clone, - Copy, - Debug, - PartialEq, - Eq, - Hash, - PartialOrd, - Ord, - ::prost::Enumeration - )] + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum EnumVoteType { Yes = 0, @@ -631,19 +566,14 @@ pub struct ConfigItoContract { #[prost(int64, tag = "4")] pub max_amount: i64, #[prost(btree_map = "string, message", tag = "5")] - pub pack_info: ::prost::alloc::collections::BTreeMap< - ::prost::alloc::string::String, - PackInfo, - >, + pub pack_info: ::prost::alloc::collections::BTreeMap<::prost::alloc::string::String, PackInfo>, #[prost(int64, tag = "6")] pub default_limit_per_address: i64, #[prost(enumeration = "config_ito_contract::EnumItoStatus", tag = "7")] pub whitelist_status: i32, #[prost(btree_map = "string, message", tag = "8")] - pub whitelist_info: ::prost::alloc::collections::BTreeMap< - ::prost::alloc::string::String, - WhitelistInfo, - >, + pub whitelist_info: + ::prost::alloc::collections::BTreeMap<::prost::alloc::string::String, WhitelistInfo>, #[prost(int64, tag = "9")] pub whitelist_start_time: i64, #[prost(int64, tag = "10")] @@ -655,17 +585,7 @@ pub struct ConfigItoContract { } /// Nested message and enum types in `ConfigITOContract`. pub mod config_ito_contract { - #[derive( - Clone, - Copy, - Debug, - PartialEq, - Eq, - Hash, - PartialOrd, - Ord, - ::prost::Enumeration - )] + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum EnumItoStatus { DefaultIto = 0, @@ -708,10 +628,7 @@ pub struct SetItoPricesContract { #[prost(bytes = "vec", tag = "1")] pub asset_id: ::prost::alloc::vec::Vec, #[prost(btree_map = "string, message", tag = "2")] - pub pack_info: ::prost::alloc::collections::BTreeMap< - ::prost::alloc::string::String, - PackInfo, - >, + pub pack_info: ::prost::alloc::collections::BTreeMap<::prost::alloc::string::String, PackInfo>, } /// ITOTriggerContract triggers assets functions #[allow(clippy::derive_partial_eq_without_eq)] @@ -728,19 +645,14 @@ pub struct ItoTriggerContract { #[prost(int64, tag = "5")] pub max_amount: i64, #[prost(btree_map = "string, message", tag = "6")] - pub pack_info: ::prost::alloc::collections::BTreeMap< - ::prost::alloc::string::String, - PackInfo, - >, + pub pack_info: ::prost::alloc::collections::BTreeMap<::prost::alloc::string::String, PackInfo>, #[prost(int64, tag = "7")] pub default_limit_per_address: i64, #[prost(enumeration = "ito_trigger_contract::EnumItoStatus", tag = "8")] pub whitelist_status: i32, #[prost(btree_map = "string, message", tag = "9")] - pub whitelist_info: ::prost::alloc::collections::BTreeMap< - ::prost::alloc::string::String, - WhitelistInfo, - >, + pub whitelist_info: + ::prost::alloc::collections::BTreeMap<::prost::alloc::string::String, WhitelistInfo>, #[prost(int64, tag = "10")] pub whitelist_start_time: i64, #[prost(int64, tag = "11")] @@ -752,17 +664,7 @@ pub struct ItoTriggerContract { } /// Nested message and enum types in `ITOTriggerContract`. pub mod ito_trigger_contract { - #[derive( - Clone, - Copy, - Debug, - PartialEq, - Eq, - Hash, - PartialOrd, - Ord, - ::prost::Enumeration - )] + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum EnumItoTriggerType { SetItoPrices = 0, @@ -787,9 +689,7 @@ pub mod ito_trigger_contract { EnumItoTriggerType::UpdateStatus => "UpdateStatus", EnumItoTriggerType::UpdateReceiverAddress => "UpdateReceiverAddress", EnumItoTriggerType::UpdateMaxAmount => "UpdateMaxAmount", - EnumItoTriggerType::UpdateDefaultLimitPerAddress => { - "UpdateDefaultLimitPerAddress" - } + EnumItoTriggerType::UpdateDefaultLimitPerAddress => "UpdateDefaultLimitPerAddress", EnumItoTriggerType::UpdateTimes => "UpdateTimes", EnumItoTriggerType::UpdateWhitelistStatus => "UpdateWhitelistStatus", EnumItoTriggerType::AddToWhitelist => "AddToWhitelist", @@ -804,9 +704,7 @@ pub mod ito_trigger_contract { "UpdateStatus" => Some(Self::UpdateStatus), "UpdateReceiverAddress" => Some(Self::UpdateReceiverAddress), "UpdateMaxAmount" => Some(Self::UpdateMaxAmount), - "UpdateDefaultLimitPerAddress" => { - Some(Self::UpdateDefaultLimitPerAddress) - } + "UpdateDefaultLimitPerAddress" => Some(Self::UpdateDefaultLimitPerAddress), "UpdateTimes" => Some(Self::UpdateTimes), "UpdateWhitelistStatus" => Some(Self::UpdateWhitelistStatus), "AddToWhitelist" => Some(Self::AddToWhitelist), @@ -816,17 +714,7 @@ pub mod ito_trigger_contract { } } } - #[derive( - Clone, - Copy, - Debug, - PartialEq, - Eq, - Hash, - PartialOrd, - Ord, - ::prost::Enumeration - )] + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum EnumItoStatus { DefaultIto = 0, @@ -887,17 +775,7 @@ pub struct BuyContract { } /// Nested message and enum types in `BuyContract`. pub mod buy_contract { - #[derive( - Clone, - Copy, - Debug, - PartialEq, - Eq, - Hash, - PartialOrd, - Ord, - ::prost::Enumeration - )] + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum EnumBuyType { ItoBuy = 0, @@ -945,17 +823,7 @@ pub struct SellContract { } /// Nested message and enum types in `SellContract`. pub mod sell_contract { - #[derive( - Clone, - Copy, - Debug, - PartialEq, - Eq, - Hash, - PartialOrd, - Ord, - ::prost::Enumeration - )] + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum EnumMarketType { BuyItNowMarket = 0, @@ -1039,17 +907,7 @@ pub struct AccPermission { } /// Nested message and enum types in `AccPermission`. pub mod acc_permission { - #[derive( - Clone, - Copy, - Debug, - PartialEq, - Eq, - Hash, - PartialOrd, - Ord, - ::prost::Enumeration - )] + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum AccPermissionType { Owner = 0, @@ -1098,17 +956,7 @@ pub struct DepositContract { } /// Nested message and enum types in `DepositContract`. pub mod deposit_contract { - #[derive( - Clone, - Copy, - Debug, - PartialEq, - Eq, - Hash, - PartialOrd, - Ord, - ::prost::Enumeration - )] + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum EnumDepositType { FprDeposit = 0, @@ -1146,17 +994,7 @@ pub struct TxContract { } /// Nested message and enum types in `TXContract`. pub mod tx_contract { - #[derive( - Clone, - Copy, - Debug, - PartialEq, - Eq, - Hash, - PartialOrd, - Ord, - ::prost::Enumeration - )] + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum ContractType { TransferContractType = 0, @@ -1194,12 +1032,8 @@ pub mod tx_contract { match self { ContractType::TransferContractType => "TransferContractType", ContractType::CreateAssetContractType => "CreateAssetContractType", - ContractType::CreateValidatorContractType => { - "CreateValidatorContractType" - } - ContractType::ValidatorConfigContractType => { - "ValidatorConfigContractType" - } + ContractType::CreateValidatorContractType => "CreateValidatorContractType", + ContractType::ValidatorConfigContractType => "ValidatorConfigContractType", ContractType::FreezeContractType => "FreezeContractType", ContractType::UnfreezeContractType => "UnfreezeContractType", ContractType::DelegateContractType => "DelegateContractType", @@ -1215,15 +1049,9 @@ pub mod tx_contract { ContractType::SetItoPricesContractType => "SetITOPricesContractType", ContractType::BuyContractType => "BuyContractType", ContractType::SellContractType => "SellContractType", - ContractType::CancelMarketOrderContractType => { - "CancelMarketOrderContractType" - } - ContractType::CreateMarketplaceContractType => { - "CreateMarketplaceContractType" - } - ContractType::ConfigMarketplaceContractType => { - "ConfigMarketplaceContractType" - } + ContractType::CancelMarketOrderContractType => "CancelMarketOrderContractType", + ContractType::CreateMarketplaceContractType => "CreateMarketplaceContractType", + ContractType::ConfigMarketplaceContractType => "ConfigMarketplaceContractType", ContractType::UpdateAccountPermissionContractType => { "UpdateAccountPermissionContractType" } @@ -1253,15 +1081,9 @@ pub mod tx_contract { "SetITOPricesContractType" => Some(Self::SetItoPricesContractType), "BuyContractType" => Some(Self::BuyContractType), "SellContractType" => Some(Self::SellContractType), - "CancelMarketOrderContractType" => { - Some(Self::CancelMarketOrderContractType) - } - "CreateMarketplaceContractType" => { - Some(Self::CreateMarketplaceContractType) - } - "ConfigMarketplaceContractType" => { - Some(Self::ConfigMarketplaceContractType) - } + "CancelMarketOrderContractType" => Some(Self::CancelMarketOrderContractType), + "CreateMarketplaceContractType" => Some(Self::CreateMarketplaceContractType), + "ConfigMarketplaceContractType" => Some(Self::ConfigMarketplaceContractType), "UpdateAccountPermissionContractType" => { Some(Self::UpdateAccountPermissionContractType) } @@ -1330,17 +1152,7 @@ pub mod transaction { #[prost(bytes = "vec", repeated, tag = "1")] pub data: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec>, } - #[derive( - Clone, - Copy, - Debug, - PartialEq, - Eq, - Hash, - PartialOrd, - Ord, - ::prost::Enumeration - )] + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum TxResult { Success = 0, @@ -1366,17 +1178,7 @@ pub mod transaction { } } } - #[derive( - Clone, - Copy, - Debug, - PartialEq, - Eq, - Hash, - PartialOrd, - Ord, - ::prost::Enumeration - )] + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum TxResultCode { Ok = 0, @@ -1588,17 +1390,7 @@ pub struct Permission { } /// Nested message and enum types in `Permission`. pub mod permission { - #[derive( - Clone, - Copy, - Debug, - PartialEq, - Eq, - Hash, - PartialOrd, - Ord, - ::prost::Enumeration - )] + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum PermissionType { Owner = 0, diff --git a/packages/kos/src/protos/generated/trx/protocol.rs b/packages/kos/src/protos/generated/trx/protocol.rs index 9f8192c..0d6574e 100644 --- a/packages/kos/src/protos/generated/trx/protocol.rs +++ b/packages/kos/src/protos/generated/trx/protocol.rs @@ -129,17 +129,7 @@ pub struct Proposal { } /// Nested message and enum types in `Proposal`. pub mod proposal { - #[derive( - Clone, - Copy, - Debug, - PartialEq, - Eq, - Hash, - PartialOrd, - Ord, - ::prost::Enumeration - )] + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum State { Pending = 0, @@ -225,17 +215,7 @@ pub struct MarketOrder { } /// Nested message and enum types in `MarketOrder`. pub mod market_order { - #[derive( - Clone, - Copy, - Debug, - PartialEq, - Eq, - Hash, - PartialOrd, - Ord, - ::prost::Enumeration - )] + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum State { Active = 0, @@ -362,16 +342,10 @@ pub struct Account { pub votes: ::prost::alloc::vec::Vec, /// the other asset owned by this account #[prost(btree_map = "string, int64", tag = "6")] - pub asset: ::prost::alloc::collections::BTreeMap< - ::prost::alloc::string::String, - i64, - >, + pub asset: ::prost::alloc::collections::BTreeMap<::prost::alloc::string::String, i64>, /// the other asset owned by this account,key is assetId #[prost(btree_map = "string, int64", tag = "56")] - pub asset_v2: ::prost::alloc::collections::BTreeMap< - ::prost::alloc::string::String, - i64, - >, + pub asset_v2: ::prost::alloc::collections::BTreeMap<::prost::alloc::string::String, i64>, /// the frozen balance for bandwidth #[prost(message, repeated, tag = "7")] pub frozen: ::prost::alloc::vec::Vec, @@ -418,27 +392,19 @@ pub struct Account { #[prost(bytes = "vec", tag = "57")] pub asset_issued_id: ::prost::alloc::vec::Vec, #[prost(btree_map = "string, int64", tag = "18")] - pub latest_asset_operation_time: ::prost::alloc::collections::BTreeMap< - ::prost::alloc::string::String, - i64, - >, + pub latest_asset_operation_time: + ::prost::alloc::collections::BTreeMap<::prost::alloc::string::String, i64>, #[prost(btree_map = "string, int64", tag = "58")] - pub latest_asset_operation_time_v2: ::prost::alloc::collections::BTreeMap< - ::prost::alloc::string::String, - i64, - >, + pub latest_asset_operation_time_v2: + ::prost::alloc::collections::BTreeMap<::prost::alloc::string::String, i64>, #[prost(int64, tag = "19")] pub free_net_usage: i64, #[prost(btree_map = "string, int64", tag = "20")] - pub free_asset_net_usage: ::prost::alloc::collections::BTreeMap< - ::prost::alloc::string::String, - i64, - >, + pub free_asset_net_usage: + ::prost::alloc::collections::BTreeMap<::prost::alloc::string::String, i64>, #[prost(btree_map = "string, int64", tag = "59")] - pub free_asset_net_usage_v2: ::prost::alloc::collections::BTreeMap< - ::prost::alloc::string::String, - i64, - >, + pub free_asset_net_usage_v2: + ::prost::alloc::collections::BTreeMap<::prost::alloc::string::String, i64>, #[prost(int64, tag = "21")] pub latest_consume_time: i64, #[prost(int64, tag = "22")] @@ -588,17 +554,7 @@ pub struct Permission { } /// Nested message and enum types in `Permission`. pub mod permission { - #[derive( - Clone, - Copy, - Debug, - PartialEq, - Eq, - Hash, - PartialOrd, - Ord, - ::prost::Enumeration - )] + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum PermissionType { Owner = 0, @@ -759,15 +715,7 @@ pub mod transaction { /// Nested message and enum types in `Contract`. pub mod contract { #[derive( - Clone, - Copy, - Debug, - PartialEq, - Eq, - Hash, - PartialOrd, - Ord, - ::prost::Enumeration + Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration, )] #[repr(i32)] pub enum ContractType { @@ -828,9 +776,7 @@ pub mod transaction { ContractType::WitnessCreateContract => "WitnessCreateContract", ContractType::AssetIssueContract => "AssetIssueContract", ContractType::WitnessUpdateContract => "WitnessUpdateContract", - ContractType::ParticipateAssetIssueContract => { - "ParticipateAssetIssueContract" - } + ContractType::ParticipateAssetIssueContract => "ParticipateAssetIssueContract", ContractType::AccountUpdateContract => "AccountUpdateContract", ContractType::FreezeBalanceContract => "FreezeBalanceContract", ContractType::UnfreezeBalanceContract => "UnfreezeBalanceContract", @@ -849,12 +795,8 @@ pub mod transaction { ContractType::ExchangeCreateContract => "ExchangeCreateContract", ContractType::ExchangeInjectContract => "ExchangeInjectContract", ContractType::ExchangeWithdrawContract => "ExchangeWithdrawContract", - ContractType::ExchangeTransactionContract => { - "ExchangeTransactionContract" - } - ContractType::UpdateEnergyLimitContract => { - "UpdateEnergyLimitContract" - } + ContractType::ExchangeTransactionContract => "ExchangeTransactionContract", + ContractType::UpdateEnergyLimitContract => "UpdateEnergyLimitContract", ContractType::AccountPermissionUpdateContract => { "AccountPermissionUpdateContract" } @@ -862,23 +804,15 @@ pub mod transaction { ContractType::UpdateBrokerageContract => "UpdateBrokerageContract", ContractType::ShieldedTransferContract => "ShieldedTransferContract", ContractType::MarketSellAssetContract => "MarketSellAssetContract", - ContractType::MarketCancelOrderContract => { - "MarketCancelOrderContract" - } + ContractType::MarketCancelOrderContract => "MarketCancelOrderContract", ContractType::FreezeBalanceV2Contract => "FreezeBalanceV2Contract", - ContractType::UnfreezeBalanceV2Contract => { - "UnfreezeBalanceV2Contract" - } + ContractType::UnfreezeBalanceV2Contract => "UnfreezeBalanceV2Contract", ContractType::WithdrawExpireUnfreezeContract => { "WithdrawExpireUnfreezeContract" } ContractType::DelegateResourceContract => "DelegateResourceContract", - ContractType::UnDelegateResourceContract => { - "UnDelegateResourceContract" - } - ContractType::CancelAllUnfreezeV2Contract => { - "CancelAllUnfreezeV2Contract" - } + ContractType::UnDelegateResourceContract => "UnDelegateResourceContract", + ContractType::CancelAllUnfreezeV2Contract => "CancelAllUnfreezeV2Contract", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -892,9 +826,7 @@ pub mod transaction { "WitnessCreateContract" => Some(Self::WitnessCreateContract), "AssetIssueContract" => Some(Self::AssetIssueContract), "WitnessUpdateContract" => Some(Self::WitnessUpdateContract), - "ParticipateAssetIssueContract" => { - Some(Self::ParticipateAssetIssueContract) - } + "ParticipateAssetIssueContract" => Some(Self::ParticipateAssetIssueContract), "AccountUpdateContract" => Some(Self::AccountUpdateContract), "FreezeBalanceContract" => Some(Self::FreezeBalanceContract), "UnfreezeBalanceContract" => Some(Self::UnfreezeBalanceContract), @@ -913,9 +845,7 @@ pub mod transaction { "ExchangeCreateContract" => Some(Self::ExchangeCreateContract), "ExchangeInjectContract" => Some(Self::ExchangeInjectContract), "ExchangeWithdrawContract" => Some(Self::ExchangeWithdrawContract), - "ExchangeTransactionContract" => { - Some(Self::ExchangeTransactionContract) - } + "ExchangeTransactionContract" => Some(Self::ExchangeTransactionContract), "UpdateEnergyLimitContract" => Some(Self::UpdateEnergyLimitContract), "AccountPermissionUpdateContract" => { Some(Self::AccountPermissionUpdateContract) @@ -927,16 +857,10 @@ pub mod transaction { "MarketCancelOrderContract" => Some(Self::MarketCancelOrderContract), "FreezeBalanceV2Contract" => Some(Self::FreezeBalanceV2Contract), "UnfreezeBalanceV2Contract" => Some(Self::UnfreezeBalanceV2Contract), - "WithdrawExpireUnfreezeContract" => { - Some(Self::WithdrawExpireUnfreezeContract) - } + "WithdrawExpireUnfreezeContract" => Some(Self::WithdrawExpireUnfreezeContract), "DelegateResourceContract" => Some(Self::DelegateResourceContract), - "UnDelegateResourceContract" => { - Some(Self::UnDelegateResourceContract) - } - "CancelAllUnfreezeV2Contract" => { - Some(Self::CancelAllUnfreezeV2Contract) - } + "UnDelegateResourceContract" => Some(Self::UnDelegateResourceContract), + "CancelAllUnfreezeV2Contract" => Some(Self::CancelAllUnfreezeV2Contract), _ => None, } } @@ -974,23 +898,13 @@ pub mod transaction { #[prost(int64, tag = "27")] pub withdraw_expire_amount: i64, #[prost(btree_map = "string, int64", tag = "28")] - pub cancel_unfreeze_v2_amount: ::prost::alloc::collections::BTreeMap< - ::prost::alloc::string::String, - i64, - >, + pub cancel_unfreeze_v2_amount: + ::prost::alloc::collections::BTreeMap<::prost::alloc::string::String, i64>, } /// Nested message and enum types in `Result`. pub mod result { #[derive( - Clone, - Copy, - Debug, - PartialEq, - Eq, - Hash, - PartialOrd, - Ord, - ::prost::Enumeration + Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration, )] #[repr(i32)] pub enum Code { @@ -1018,15 +932,7 @@ pub mod transaction { } } #[derive( - Clone, - Copy, - Debug, - PartialEq, - Eq, - Hash, - PartialOrd, - Ord, - ::prost::Enumeration + Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration, )] #[repr(i32)] pub enum ContractResult { @@ -1174,10 +1080,8 @@ pub struct TransactionInfo { #[prost(int64, tag = "28")] pub withdraw_expire_amount: i64, #[prost(btree_map = "string, int64", tag = "29")] - pub cancel_unfreeze_v2_amount: ::prost::alloc::collections::BTreeMap< - ::prost::alloc::string::String, - i64, - >, + pub cancel_unfreeze_v2_amount: + ::prost::alloc::collections::BTreeMap<::prost::alloc::string::String, i64>, } /// Nested message and enum types in `TransactionInfo`. pub mod transaction_info { @@ -1191,17 +1095,7 @@ pub mod transaction_info { #[prost(bytes = "vec", tag = "3")] pub data: ::prost::alloc::vec::Vec, } - #[derive( - Clone, - Copy, - Debug, - PartialEq, - Eq, - Hash, - PartialOrd, - Ord, - ::prost::Enumeration - )] + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum Code { Sucess = 0, @@ -1324,17 +1218,7 @@ pub mod block_inventory { #[prost(int64, tag = "2")] pub number: i64, } - #[derive( - Clone, - Copy, - Debug, - PartialEq, - Eq, - Hash, - PartialOrd, - Ord, - ::prost::Enumeration - )] + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum Type { Sync = 0, @@ -1374,17 +1258,7 @@ pub struct Inventory { } /// Nested message and enum types in `Inventory`. pub mod inventory { - #[derive( - Clone, - Copy, - Debug, - PartialEq, - Eq, - Hash, - PartialOrd, - Ord, - ::prost::Enumeration - )] + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum InventoryType { Trx = 0, @@ -1425,17 +1299,7 @@ pub struct Items { } /// Nested message and enum types in `Items`. pub mod items { - #[derive( - Clone, - Copy, - Debug, - PartialEq, - Eq, - Hash, - PartialOrd, - Ord, - ::prost::Enumeration - )] + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum ItemType { Err = 0, @@ -1719,13 +1583,9 @@ pub mod node_info { #[prost(double, tag = "11")] pub process_cpu_rate: f64, #[prost(message, repeated, tag = "12")] - pub memory_desc_info_list: ::prost::alloc::vec::Vec< - machine_info::MemoryDescInfo, - >, + pub memory_desc_info_list: ::prost::alloc::vec::Vec, #[prost(message, repeated, tag = "13")] - pub dead_lock_thread_info_list: ::prost::alloc::vec::Vec< - machine_info::DeadLockThreadInfo, - >, + pub dead_lock_thread_info_list: ::prost::alloc::vec::Vec, } /// Nested message and enum types in `MachineInfo`. pub mod machine_info { @@ -1872,9 +1732,7 @@ pub mod metrics_info { #[prost(int32, tag = "7")] pub disconnection_count: i32, #[prost(message, repeated, tag = "8")] - pub disconnection_detail: ::prost::alloc::vec::Vec< - net_info::DisconnectionDetailInfo, - >, + pub disconnection_detail: ::prost::alloc::vec::Vec, #[prost(message, optional, tag = "9")] pub udp_in_traffic: ::core::option::Option, #[prost(message, optional, tag = "10")] @@ -1988,17 +1846,7 @@ pub mod pbft_message { #[prost(bytes = "vec", tag = "5")] pub data: ::prost::alloc::vec::Vec, } - #[derive( - Clone, - Copy, - Debug, - PartialEq, - Eq, - Hash, - PartialOrd, - Ord, - ::prost::Enumeration - )] + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum MsgType { ViewChange = 0, @@ -2033,17 +1881,7 @@ pub mod pbft_message { } } } - #[derive( - Clone, - Copy, - Debug, - PartialEq, - Eq, - Hash, - PartialOrd, - Ord, - ::prost::Enumeration - )] + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum DataType { Block = 0, @@ -2849,15 +2687,7 @@ pub mod smart_contract { pub r#type: ::prost::alloc::string::String, } #[derive( - Clone, - Copy, - Debug, - PartialEq, - Eq, - Hash, - PartialOrd, - Ord, - ::prost::Enumeration + Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration, )] #[repr(i32)] pub enum EntryType { @@ -2900,15 +2730,7 @@ pub mod smart_contract { } } #[derive( - Clone, - Copy, - Debug, - PartialEq, - Eq, - Hash, - PartialOrd, - Ord, - ::prost::Enumeration + Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration, )] #[repr(i32)] pub enum StateMutabilityType { @@ -2925,9 +2747,7 @@ pub mod smart_contract { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - StateMutabilityType::UnknownMutabilityType => { - "UnknownMutabilityType" - } + StateMutabilityType::UnknownMutabilityType => "UnknownMutabilityType", StateMutabilityType::Pure => "Pure", StateMutabilityType::View => "View", StateMutabilityType::Nonpayable => "Nonpayable", From 2ae71d2470a08d0f2026febeb856900eec0fdde3 Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Tue, 26 Nov 2024 09:16:14 -0300 Subject: [PATCH 27/42] chore: fix deny check --- deny.toml | 16 +- .../kos/src/protos/generated/klv/proto.rs | 282 +++++++++++++++--- .../kos/src/protos/generated/trx/protocol.rs | 268 ++++++++++++++--- 3 files changed, 482 insertions(+), 84 deletions(-) diff --git a/deny.toml b/deny.toml index 646ad73..1e74ce9 100644 --- a/deny.toml +++ b/deny.toml @@ -12,11 +12,20 @@ skip = [ { name = "http-body", version = "<=1.0.0" }, { name = "hyper", version = "<=1.3.1" }, { name = "reqwest", version = "<=0.12.4" }, - { name = "rustls-pemfile", version = "1.0.4" } + { name = "rustls-pemfile", version = "1.0.4" }, + { name = "block-buffer", version = "0.9.0" }, + { name = "digest", version = "0.9.0" }, + { name = "heck", version = "0.4.1" }, + { name = "hmac", version = "0.8.1" }, + { name = "sha2", version = "0.9.9" }, + { name = "syn", version = "1.0.109" }, + { name = "windows-sys", version = "0.52.0" } + + ] skip-tree = [ - { name = "prost-wkt-types", version = "=0.4.2", depth = 20 }, # prost-wkt-build - { name = "prost-wkt-build", version = "=0.4.2", depth = 20 }, # prost-wkt-build + { name = "prost-wkt-types", version = "=0.5.0", depth = 20 }, # prost-wkt-build + { name = "prost-wkt-build", version = "=0.5.0", depth = 20 }, # prost-wkt-build ] [sources] @@ -34,6 +43,7 @@ allow = [ "MIT", "MITNFA", "BSD-3-Clause", + "BSD-2-Clause", "CC0-1.0", "ISC", "MPL-2.0", diff --git a/packages/kos/src/protos/generated/klv/proto.rs b/packages/kos/src/protos/generated/klv/proto.rs index f6a9d77..d480efe 100644 --- a/packages/kos/src/protos/generated/klv/proto.rs +++ b/packages/kos/src/protos/generated/klv/proto.rs @@ -50,7 +50,17 @@ pub struct CreateAssetContract { } /// Nested message and enum types in `CreateAssetContract`. pub mod create_asset_contract { - #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] #[repr(i32)] pub enum EnumAssetType { Fungible = 0, @@ -126,7 +136,17 @@ pub struct StakingInfo { } /// Nested message and enum types in `StakingInfo`. pub mod staking_info { - #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] #[repr(i32)] pub enum InterestType { Apri = 0, @@ -181,8 +201,10 @@ pub struct RoyaltiesInfo { #[prost(int64, tag = "5")] pub market_fixed: i64, #[prost(btree_map = "string, message", tag = "6")] - pub split_royalties: - ::prost::alloc::collections::BTreeMap<::prost::alloc::string::String, RoyaltySplitInfo>, + pub split_royalties: ::prost::alloc::collections::BTreeMap< + ::prost::alloc::string::String, + RoyaltySplitInfo, + >, #[prost(int64, tag = "7")] pub ito_fixed: i64, #[prost(uint32, tag = "8")] @@ -259,7 +281,17 @@ pub struct AssetTriggerContract { } /// Nested message and enum types in `AssetTriggerContract`. pub mod asset_trigger_contract { - #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] #[repr(i32)] pub enum EnumTriggerType { Mint = 0, @@ -423,7 +455,17 @@ pub struct WithdrawContract { } /// Nested message and enum types in `WithdrawContract`. pub mod withdraw_contract { - #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] #[repr(i32)] pub enum EnumWithdrawType { Staking = 0, @@ -461,7 +503,17 @@ pub struct ClaimContract { } /// Nested message and enum types in `ClaimContract`. pub mod claim_contract { - #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] #[repr(i32)] pub enum EnumClaimType { StakingClaim = 0, @@ -507,7 +559,10 @@ pub struct SetAccountNameContract { #[derive(Clone, PartialEq, ::prost::Message)] pub struct ProposalContract { #[prost(btree_map = "int32, bytes", tag = "1")] - pub parameters: ::prost::alloc::collections::BTreeMap>, + pub parameters: ::prost::alloc::collections::BTreeMap< + i32, + ::prost::alloc::vec::Vec, + >, #[prost(bytes = "vec", tag = "2")] pub description: ::prost::alloc::vec::Vec, #[prost(uint32, tag = "3")] @@ -526,7 +581,17 @@ pub struct VoteContract { } /// Nested message and enum types in `VoteContract`. pub mod vote_contract { - #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] #[repr(i32)] pub enum EnumVoteType { Yes = 0, @@ -566,14 +631,19 @@ pub struct ConfigItoContract { #[prost(int64, tag = "4")] pub max_amount: i64, #[prost(btree_map = "string, message", tag = "5")] - pub pack_info: ::prost::alloc::collections::BTreeMap<::prost::alloc::string::String, PackInfo>, + pub pack_info: ::prost::alloc::collections::BTreeMap< + ::prost::alloc::string::String, + PackInfo, + >, #[prost(int64, tag = "6")] pub default_limit_per_address: i64, #[prost(enumeration = "config_ito_contract::EnumItoStatus", tag = "7")] pub whitelist_status: i32, #[prost(btree_map = "string, message", tag = "8")] - pub whitelist_info: - ::prost::alloc::collections::BTreeMap<::prost::alloc::string::String, WhitelistInfo>, + pub whitelist_info: ::prost::alloc::collections::BTreeMap< + ::prost::alloc::string::String, + WhitelistInfo, + >, #[prost(int64, tag = "9")] pub whitelist_start_time: i64, #[prost(int64, tag = "10")] @@ -585,7 +655,17 @@ pub struct ConfigItoContract { } /// Nested message and enum types in `ConfigITOContract`. pub mod config_ito_contract { - #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] #[repr(i32)] pub enum EnumItoStatus { DefaultIto = 0, @@ -628,7 +708,10 @@ pub struct SetItoPricesContract { #[prost(bytes = "vec", tag = "1")] pub asset_id: ::prost::alloc::vec::Vec, #[prost(btree_map = "string, message", tag = "2")] - pub pack_info: ::prost::alloc::collections::BTreeMap<::prost::alloc::string::String, PackInfo>, + pub pack_info: ::prost::alloc::collections::BTreeMap< + ::prost::alloc::string::String, + PackInfo, + >, } /// ITOTriggerContract triggers assets functions #[allow(clippy::derive_partial_eq_without_eq)] @@ -645,14 +728,19 @@ pub struct ItoTriggerContract { #[prost(int64, tag = "5")] pub max_amount: i64, #[prost(btree_map = "string, message", tag = "6")] - pub pack_info: ::prost::alloc::collections::BTreeMap<::prost::alloc::string::String, PackInfo>, + pub pack_info: ::prost::alloc::collections::BTreeMap< + ::prost::alloc::string::String, + PackInfo, + >, #[prost(int64, tag = "7")] pub default_limit_per_address: i64, #[prost(enumeration = "ito_trigger_contract::EnumItoStatus", tag = "8")] pub whitelist_status: i32, #[prost(btree_map = "string, message", tag = "9")] - pub whitelist_info: - ::prost::alloc::collections::BTreeMap<::prost::alloc::string::String, WhitelistInfo>, + pub whitelist_info: ::prost::alloc::collections::BTreeMap< + ::prost::alloc::string::String, + WhitelistInfo, + >, #[prost(int64, tag = "10")] pub whitelist_start_time: i64, #[prost(int64, tag = "11")] @@ -664,7 +752,17 @@ pub struct ItoTriggerContract { } /// Nested message and enum types in `ITOTriggerContract`. pub mod ito_trigger_contract { - #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] #[repr(i32)] pub enum EnumItoTriggerType { SetItoPrices = 0, @@ -689,7 +787,9 @@ pub mod ito_trigger_contract { EnumItoTriggerType::UpdateStatus => "UpdateStatus", EnumItoTriggerType::UpdateReceiverAddress => "UpdateReceiverAddress", EnumItoTriggerType::UpdateMaxAmount => "UpdateMaxAmount", - EnumItoTriggerType::UpdateDefaultLimitPerAddress => "UpdateDefaultLimitPerAddress", + EnumItoTriggerType::UpdateDefaultLimitPerAddress => { + "UpdateDefaultLimitPerAddress" + } EnumItoTriggerType::UpdateTimes => "UpdateTimes", EnumItoTriggerType::UpdateWhitelistStatus => "UpdateWhitelistStatus", EnumItoTriggerType::AddToWhitelist => "AddToWhitelist", @@ -704,7 +804,9 @@ pub mod ito_trigger_contract { "UpdateStatus" => Some(Self::UpdateStatus), "UpdateReceiverAddress" => Some(Self::UpdateReceiverAddress), "UpdateMaxAmount" => Some(Self::UpdateMaxAmount), - "UpdateDefaultLimitPerAddress" => Some(Self::UpdateDefaultLimitPerAddress), + "UpdateDefaultLimitPerAddress" => { + Some(Self::UpdateDefaultLimitPerAddress) + } "UpdateTimes" => Some(Self::UpdateTimes), "UpdateWhitelistStatus" => Some(Self::UpdateWhitelistStatus), "AddToWhitelist" => Some(Self::AddToWhitelist), @@ -714,7 +816,17 @@ pub mod ito_trigger_contract { } } } - #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] #[repr(i32)] pub enum EnumItoStatus { DefaultIto = 0, @@ -775,7 +887,17 @@ pub struct BuyContract { } /// Nested message and enum types in `BuyContract`. pub mod buy_contract { - #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] #[repr(i32)] pub enum EnumBuyType { ItoBuy = 0, @@ -823,7 +945,17 @@ pub struct SellContract { } /// Nested message and enum types in `SellContract`. pub mod sell_contract { - #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] #[repr(i32)] pub enum EnumMarketType { BuyItNowMarket = 0, @@ -907,7 +1039,17 @@ pub struct AccPermission { } /// Nested message and enum types in `AccPermission`. pub mod acc_permission { - #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] #[repr(i32)] pub enum AccPermissionType { Owner = 0, @@ -956,7 +1098,17 @@ pub struct DepositContract { } /// Nested message and enum types in `DepositContract`. pub mod deposit_contract { - #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] #[repr(i32)] pub enum EnumDepositType { FprDeposit = 0, @@ -994,7 +1146,17 @@ pub struct TxContract { } /// Nested message and enum types in `TXContract`. pub mod tx_contract { - #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] #[repr(i32)] pub enum ContractType { TransferContractType = 0, @@ -1032,8 +1194,12 @@ pub mod tx_contract { match self { ContractType::TransferContractType => "TransferContractType", ContractType::CreateAssetContractType => "CreateAssetContractType", - ContractType::CreateValidatorContractType => "CreateValidatorContractType", - ContractType::ValidatorConfigContractType => "ValidatorConfigContractType", + ContractType::CreateValidatorContractType => { + "CreateValidatorContractType" + } + ContractType::ValidatorConfigContractType => { + "ValidatorConfigContractType" + } ContractType::FreezeContractType => "FreezeContractType", ContractType::UnfreezeContractType => "UnfreezeContractType", ContractType::DelegateContractType => "DelegateContractType", @@ -1049,9 +1215,15 @@ pub mod tx_contract { ContractType::SetItoPricesContractType => "SetITOPricesContractType", ContractType::BuyContractType => "BuyContractType", ContractType::SellContractType => "SellContractType", - ContractType::CancelMarketOrderContractType => "CancelMarketOrderContractType", - ContractType::CreateMarketplaceContractType => "CreateMarketplaceContractType", - ContractType::ConfigMarketplaceContractType => "ConfigMarketplaceContractType", + ContractType::CancelMarketOrderContractType => { + "CancelMarketOrderContractType" + } + ContractType::CreateMarketplaceContractType => { + "CreateMarketplaceContractType" + } + ContractType::ConfigMarketplaceContractType => { + "ConfigMarketplaceContractType" + } ContractType::UpdateAccountPermissionContractType => { "UpdateAccountPermissionContractType" } @@ -1081,9 +1253,15 @@ pub mod tx_contract { "SetITOPricesContractType" => Some(Self::SetItoPricesContractType), "BuyContractType" => Some(Self::BuyContractType), "SellContractType" => Some(Self::SellContractType), - "CancelMarketOrderContractType" => Some(Self::CancelMarketOrderContractType), - "CreateMarketplaceContractType" => Some(Self::CreateMarketplaceContractType), - "ConfigMarketplaceContractType" => Some(Self::ConfigMarketplaceContractType), + "CancelMarketOrderContractType" => { + Some(Self::CancelMarketOrderContractType) + } + "CreateMarketplaceContractType" => { + Some(Self::CreateMarketplaceContractType) + } + "ConfigMarketplaceContractType" => { + Some(Self::ConfigMarketplaceContractType) + } "UpdateAccountPermissionContractType" => { Some(Self::UpdateAccountPermissionContractType) } @@ -1152,7 +1330,17 @@ pub mod transaction { #[prost(bytes = "vec", repeated, tag = "1")] pub data: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec>, } - #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] #[repr(i32)] pub enum TxResult { Success = 0, @@ -1178,7 +1366,17 @@ pub mod transaction { } } } - #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] #[repr(i32)] pub enum TxResultCode { Ok = 0, @@ -1390,7 +1588,17 @@ pub struct Permission { } /// Nested message and enum types in `Permission`. pub mod permission { - #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] #[repr(i32)] pub enum PermissionType { Owner = 0, diff --git a/packages/kos/src/protos/generated/trx/protocol.rs b/packages/kos/src/protos/generated/trx/protocol.rs index 0d6574e..9f8192c 100644 --- a/packages/kos/src/protos/generated/trx/protocol.rs +++ b/packages/kos/src/protos/generated/trx/protocol.rs @@ -129,7 +129,17 @@ pub struct Proposal { } /// Nested message and enum types in `Proposal`. pub mod proposal { - #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] #[repr(i32)] pub enum State { Pending = 0, @@ -215,7 +225,17 @@ pub struct MarketOrder { } /// Nested message and enum types in `MarketOrder`. pub mod market_order { - #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] #[repr(i32)] pub enum State { Active = 0, @@ -342,10 +362,16 @@ pub struct Account { pub votes: ::prost::alloc::vec::Vec, /// the other asset owned by this account #[prost(btree_map = "string, int64", tag = "6")] - pub asset: ::prost::alloc::collections::BTreeMap<::prost::alloc::string::String, i64>, + pub asset: ::prost::alloc::collections::BTreeMap< + ::prost::alloc::string::String, + i64, + >, /// the other asset owned by this account,key is assetId #[prost(btree_map = "string, int64", tag = "56")] - pub asset_v2: ::prost::alloc::collections::BTreeMap<::prost::alloc::string::String, i64>, + pub asset_v2: ::prost::alloc::collections::BTreeMap< + ::prost::alloc::string::String, + i64, + >, /// the frozen balance for bandwidth #[prost(message, repeated, tag = "7")] pub frozen: ::prost::alloc::vec::Vec, @@ -392,19 +418,27 @@ pub struct Account { #[prost(bytes = "vec", tag = "57")] pub asset_issued_id: ::prost::alloc::vec::Vec, #[prost(btree_map = "string, int64", tag = "18")] - pub latest_asset_operation_time: - ::prost::alloc::collections::BTreeMap<::prost::alloc::string::String, i64>, + pub latest_asset_operation_time: ::prost::alloc::collections::BTreeMap< + ::prost::alloc::string::String, + i64, + >, #[prost(btree_map = "string, int64", tag = "58")] - pub latest_asset_operation_time_v2: - ::prost::alloc::collections::BTreeMap<::prost::alloc::string::String, i64>, + pub latest_asset_operation_time_v2: ::prost::alloc::collections::BTreeMap< + ::prost::alloc::string::String, + i64, + >, #[prost(int64, tag = "19")] pub free_net_usage: i64, #[prost(btree_map = "string, int64", tag = "20")] - pub free_asset_net_usage: - ::prost::alloc::collections::BTreeMap<::prost::alloc::string::String, i64>, + pub free_asset_net_usage: ::prost::alloc::collections::BTreeMap< + ::prost::alloc::string::String, + i64, + >, #[prost(btree_map = "string, int64", tag = "59")] - pub free_asset_net_usage_v2: - ::prost::alloc::collections::BTreeMap<::prost::alloc::string::String, i64>, + pub free_asset_net_usage_v2: ::prost::alloc::collections::BTreeMap< + ::prost::alloc::string::String, + i64, + >, #[prost(int64, tag = "21")] pub latest_consume_time: i64, #[prost(int64, tag = "22")] @@ -554,7 +588,17 @@ pub struct Permission { } /// Nested message and enum types in `Permission`. pub mod permission { - #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] #[repr(i32)] pub enum PermissionType { Owner = 0, @@ -715,7 +759,15 @@ pub mod transaction { /// Nested message and enum types in `Contract`. pub mod contract { #[derive( - Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration, + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration )] #[repr(i32)] pub enum ContractType { @@ -776,7 +828,9 @@ pub mod transaction { ContractType::WitnessCreateContract => "WitnessCreateContract", ContractType::AssetIssueContract => "AssetIssueContract", ContractType::WitnessUpdateContract => "WitnessUpdateContract", - ContractType::ParticipateAssetIssueContract => "ParticipateAssetIssueContract", + ContractType::ParticipateAssetIssueContract => { + "ParticipateAssetIssueContract" + } ContractType::AccountUpdateContract => "AccountUpdateContract", ContractType::FreezeBalanceContract => "FreezeBalanceContract", ContractType::UnfreezeBalanceContract => "UnfreezeBalanceContract", @@ -795,8 +849,12 @@ pub mod transaction { ContractType::ExchangeCreateContract => "ExchangeCreateContract", ContractType::ExchangeInjectContract => "ExchangeInjectContract", ContractType::ExchangeWithdrawContract => "ExchangeWithdrawContract", - ContractType::ExchangeTransactionContract => "ExchangeTransactionContract", - ContractType::UpdateEnergyLimitContract => "UpdateEnergyLimitContract", + ContractType::ExchangeTransactionContract => { + "ExchangeTransactionContract" + } + ContractType::UpdateEnergyLimitContract => { + "UpdateEnergyLimitContract" + } ContractType::AccountPermissionUpdateContract => { "AccountPermissionUpdateContract" } @@ -804,15 +862,23 @@ pub mod transaction { ContractType::UpdateBrokerageContract => "UpdateBrokerageContract", ContractType::ShieldedTransferContract => "ShieldedTransferContract", ContractType::MarketSellAssetContract => "MarketSellAssetContract", - ContractType::MarketCancelOrderContract => "MarketCancelOrderContract", + ContractType::MarketCancelOrderContract => { + "MarketCancelOrderContract" + } ContractType::FreezeBalanceV2Contract => "FreezeBalanceV2Contract", - ContractType::UnfreezeBalanceV2Contract => "UnfreezeBalanceV2Contract", + ContractType::UnfreezeBalanceV2Contract => { + "UnfreezeBalanceV2Contract" + } ContractType::WithdrawExpireUnfreezeContract => { "WithdrawExpireUnfreezeContract" } ContractType::DelegateResourceContract => "DelegateResourceContract", - ContractType::UnDelegateResourceContract => "UnDelegateResourceContract", - ContractType::CancelAllUnfreezeV2Contract => "CancelAllUnfreezeV2Contract", + ContractType::UnDelegateResourceContract => { + "UnDelegateResourceContract" + } + ContractType::CancelAllUnfreezeV2Contract => { + "CancelAllUnfreezeV2Contract" + } } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -826,7 +892,9 @@ pub mod transaction { "WitnessCreateContract" => Some(Self::WitnessCreateContract), "AssetIssueContract" => Some(Self::AssetIssueContract), "WitnessUpdateContract" => Some(Self::WitnessUpdateContract), - "ParticipateAssetIssueContract" => Some(Self::ParticipateAssetIssueContract), + "ParticipateAssetIssueContract" => { + Some(Self::ParticipateAssetIssueContract) + } "AccountUpdateContract" => Some(Self::AccountUpdateContract), "FreezeBalanceContract" => Some(Self::FreezeBalanceContract), "UnfreezeBalanceContract" => Some(Self::UnfreezeBalanceContract), @@ -845,7 +913,9 @@ pub mod transaction { "ExchangeCreateContract" => Some(Self::ExchangeCreateContract), "ExchangeInjectContract" => Some(Self::ExchangeInjectContract), "ExchangeWithdrawContract" => Some(Self::ExchangeWithdrawContract), - "ExchangeTransactionContract" => Some(Self::ExchangeTransactionContract), + "ExchangeTransactionContract" => { + Some(Self::ExchangeTransactionContract) + } "UpdateEnergyLimitContract" => Some(Self::UpdateEnergyLimitContract), "AccountPermissionUpdateContract" => { Some(Self::AccountPermissionUpdateContract) @@ -857,10 +927,16 @@ pub mod transaction { "MarketCancelOrderContract" => Some(Self::MarketCancelOrderContract), "FreezeBalanceV2Contract" => Some(Self::FreezeBalanceV2Contract), "UnfreezeBalanceV2Contract" => Some(Self::UnfreezeBalanceV2Contract), - "WithdrawExpireUnfreezeContract" => Some(Self::WithdrawExpireUnfreezeContract), + "WithdrawExpireUnfreezeContract" => { + Some(Self::WithdrawExpireUnfreezeContract) + } "DelegateResourceContract" => Some(Self::DelegateResourceContract), - "UnDelegateResourceContract" => Some(Self::UnDelegateResourceContract), - "CancelAllUnfreezeV2Contract" => Some(Self::CancelAllUnfreezeV2Contract), + "UnDelegateResourceContract" => { + Some(Self::UnDelegateResourceContract) + } + "CancelAllUnfreezeV2Contract" => { + Some(Self::CancelAllUnfreezeV2Contract) + } _ => None, } } @@ -898,13 +974,23 @@ pub mod transaction { #[prost(int64, tag = "27")] pub withdraw_expire_amount: i64, #[prost(btree_map = "string, int64", tag = "28")] - pub cancel_unfreeze_v2_amount: - ::prost::alloc::collections::BTreeMap<::prost::alloc::string::String, i64>, + pub cancel_unfreeze_v2_amount: ::prost::alloc::collections::BTreeMap< + ::prost::alloc::string::String, + i64, + >, } /// Nested message and enum types in `Result`. pub mod result { #[derive( - Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration, + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration )] #[repr(i32)] pub enum Code { @@ -932,7 +1018,15 @@ pub mod transaction { } } #[derive( - Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration, + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration )] #[repr(i32)] pub enum ContractResult { @@ -1080,8 +1174,10 @@ pub struct TransactionInfo { #[prost(int64, tag = "28")] pub withdraw_expire_amount: i64, #[prost(btree_map = "string, int64", tag = "29")] - pub cancel_unfreeze_v2_amount: - ::prost::alloc::collections::BTreeMap<::prost::alloc::string::String, i64>, + pub cancel_unfreeze_v2_amount: ::prost::alloc::collections::BTreeMap< + ::prost::alloc::string::String, + i64, + >, } /// Nested message and enum types in `TransactionInfo`. pub mod transaction_info { @@ -1095,7 +1191,17 @@ pub mod transaction_info { #[prost(bytes = "vec", tag = "3")] pub data: ::prost::alloc::vec::Vec, } - #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] #[repr(i32)] pub enum Code { Sucess = 0, @@ -1218,7 +1324,17 @@ pub mod block_inventory { #[prost(int64, tag = "2")] pub number: i64, } - #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] #[repr(i32)] pub enum Type { Sync = 0, @@ -1258,7 +1374,17 @@ pub struct Inventory { } /// Nested message and enum types in `Inventory`. pub mod inventory { - #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] #[repr(i32)] pub enum InventoryType { Trx = 0, @@ -1299,7 +1425,17 @@ pub struct Items { } /// Nested message and enum types in `Items`. pub mod items { - #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] #[repr(i32)] pub enum ItemType { Err = 0, @@ -1583,9 +1719,13 @@ pub mod node_info { #[prost(double, tag = "11")] pub process_cpu_rate: f64, #[prost(message, repeated, tag = "12")] - pub memory_desc_info_list: ::prost::alloc::vec::Vec, + pub memory_desc_info_list: ::prost::alloc::vec::Vec< + machine_info::MemoryDescInfo, + >, #[prost(message, repeated, tag = "13")] - pub dead_lock_thread_info_list: ::prost::alloc::vec::Vec, + pub dead_lock_thread_info_list: ::prost::alloc::vec::Vec< + machine_info::DeadLockThreadInfo, + >, } /// Nested message and enum types in `MachineInfo`. pub mod machine_info { @@ -1732,7 +1872,9 @@ pub mod metrics_info { #[prost(int32, tag = "7")] pub disconnection_count: i32, #[prost(message, repeated, tag = "8")] - pub disconnection_detail: ::prost::alloc::vec::Vec, + pub disconnection_detail: ::prost::alloc::vec::Vec< + net_info::DisconnectionDetailInfo, + >, #[prost(message, optional, tag = "9")] pub udp_in_traffic: ::core::option::Option, #[prost(message, optional, tag = "10")] @@ -1846,7 +1988,17 @@ pub mod pbft_message { #[prost(bytes = "vec", tag = "5")] pub data: ::prost::alloc::vec::Vec, } - #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] #[repr(i32)] pub enum MsgType { ViewChange = 0, @@ -1881,7 +2033,17 @@ pub mod pbft_message { } } } - #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] #[repr(i32)] pub enum DataType { Block = 0, @@ -2687,7 +2849,15 @@ pub mod smart_contract { pub r#type: ::prost::alloc::string::String, } #[derive( - Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration, + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration )] #[repr(i32)] pub enum EntryType { @@ -2730,7 +2900,15 @@ pub mod smart_contract { } } #[derive( - Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration, + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration )] #[repr(i32)] pub enum StateMutabilityType { @@ -2747,7 +2925,9 @@ pub mod smart_contract { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - StateMutabilityType::UnknownMutabilityType => "UnknownMutabilityType", + StateMutabilityType::UnknownMutabilityType => { + "UnknownMutabilityType" + } StateMutabilityType::Pure => "Pure", StateMutabilityType::View => "View", StateMutabilityType::Nonpayable => "Nonpayable", From 6b0a0e755f18b4b5b00ac8c63eb3bd38673cf859 Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Tue, 26 Nov 2024 16:16:43 -0300 Subject: [PATCH 28/42] chore: fix fmt for proto generated --- packages/kos/src/protos/generated/klv/mod.rs | 1 + packages/kos/src/protos/generated/trx/mod.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/packages/kos/src/protos/generated/klv/mod.rs b/packages/kos/src/protos/generated/klv/mod.rs index febacec..89987f2 100644 --- a/packages/kos/src/protos/generated/klv/mod.rs +++ b/packages/kos/src/protos/generated/klv/mod.rs @@ -1 +1,2 @@ +#[rustfmt::skip] pub mod proto; diff --git a/packages/kos/src/protos/generated/trx/mod.rs b/packages/kos/src/protos/generated/trx/mod.rs index 1b800ec..8a1738d 100644 --- a/packages/kos/src/protos/generated/trx/mod.rs +++ b/packages/kos/src/protos/generated/trx/mod.rs @@ -1 +1,2 @@ +#[rustfmt::skip] pub mod protocol; From e6e6e7be78204c2f658950be660ca46577db0fa4 Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Tue, 26 Nov 2024 16:38:14 -0300 Subject: [PATCH 29/42] chore: remove env --- .github/workflows/pull-develop.yaml | 13 ++----------- .github/workflows/pull-master-release.yaml | 9 ++------- Makefile | 8 -------- 3 files changed, 4 insertions(+), 26 deletions(-) diff --git a/.github/workflows/pull-develop.yaml b/.github/workflows/pull-develop.yaml index 992e8f6..c0a0dbe 100644 --- a/.github/workflows/pull-develop.yaml +++ b/.github/workflows/pull-develop.yaml @@ -17,7 +17,7 @@ on: - '**/*.md' - '.gitignore' - '.github/**' - + jobs: format: runs-on: ubuntu-latest @@ -46,16 +46,12 @@ jobs: cargo deny check cargo pants - - name: Restore .env file - run: echo "$NODES_ENV" | base64 -d > packages/kos-sdk/.env.nodes - env: - NODES_ENV: ${{ secrets.NODES_ENV }} - name: Run Tests run: cargo test build: - needs: [format] + needs: [ format ] runs-on: ubuntu-latest steps: - name: Checkout repository @@ -68,10 +64,5 @@ jobs: with: with_cache: true - - name: Restore .env file - run: echo $NODES_ENV | base64 -d > packages/kos-sdk/.env.nodes - env: - NODES_ENV: ${{ secrets.NODES_ENV }} - - name: Build run: make webpack-npm diff --git a/.github/workflows/pull-master-release.yaml b/.github/workflows/pull-master-release.yaml index 01b5f5b..c269242 100644 --- a/.github/workflows/pull-master-release.yaml +++ b/.github/workflows/pull-master-release.yaml @@ -1,4 +1,4 @@ -name: KOS-RS Bump version && Release +name: KOS-RS Bump version && Release on: pull_request: @@ -24,17 +24,12 @@ jobs: with: submodules: recursive fetch-depth: 0 - + - name: RustUp uses: klever-io/kos-rs/.github/actions/rustup@develop with: with_cache: true - - name: Restore .env file - run: echo "$NODES_ENV" | base64 -d > packages/kos-sdk/.env.nodes - env: - NODES_ENV: ${{ secrets.NODES_ENV }} - - name: Run Tests run: cargo test diff --git a/Makefile b/Makefile index 19ab23f..5633901 100644 --- a/Makefile +++ b/Makefile @@ -11,14 +11,6 @@ fmt: clippy: cargo clippy --all -- -D warnings -encode-env: -ifeq ($(UNAME), Linux) - cat packages/kos-sdk/.env.nodes | base64 -w 0 > .env.nodes.base64 -endif -ifeq ($(UNAME), Darwin) - cat packages/kos-sdk/.env.nodes | base64 > .env.nodes.base64 -endif - check: fmt clippy cargo deny check # cargo outdated --exit-code 1 From f4c73fd0dc375414363d91dd43066399f3be96e5 Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Mon, 2 Dec 2024 18:16:10 -0300 Subject: [PATCH 30/42] feat: kos-web BigNumber --- Cargo.lock | 2 + packages/kos-web/Cargo.toml | 2 + packages/kos-web/src/lib.rs | 1 + packages/kos-web/src/number.rs | 251 +++++++++++++++++++++++++++++++++ packages/kos-web/src/wallet.rs | 4 +- 5 files changed, 257 insertions(+), 3 deletions(-) create mode 100644 packages/kos-web/src/number.rs diff --git a/Cargo.lock b/Cargo.lock index f37f58a..18f8d2e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1608,6 +1608,8 @@ dependencies = [ "hex", "kos", "lazy_static", + "num-bigint", + "num-traits", "pem", "postcard", "qrcode-generator", diff --git a/packages/kos-web/Cargo.toml b/packages/kos-web/Cargo.toml index b6ae257..1eccf7d 100644 --- a/packages/kos-web/Cargo.toml +++ b/packages/kos-web/Cargo.toml @@ -28,3 +28,5 @@ postcard = { version = "1.0.6", features = ["use-std"] } lazy_static = { workspace = true } kos = { workspace = true } wasm-bindgen = { workspace = true } +num-bigint = "0.4" +num-traits = "0.2" diff --git a/packages/kos-web/src/lib.rs b/packages/kos-web/src/lib.rs index 832de79..c3555cb 100644 --- a/packages/kos-web/src/lib.rs +++ b/packages/kos-web/src/lib.rs @@ -8,6 +8,7 @@ mod models; mod utils; mod error; +mod number; pub mod wallet; /// Generates a random mnemonic phrase given the number of words to generate, `count`. diff --git a/packages/kos-web/src/number.rs b/packages/kos-web/src/number.rs new file mode 100644 index 0000000..ac82c90 --- /dev/null +++ b/packages/kos-web/src/number.rs @@ -0,0 +1,251 @@ +use crate::error::Error; + +use core::cmp::Ordering; +use std::{ + fmt::{Display, Formatter}, + ops::{Add, Deref, Div, Mul, Sub}, + str::FromStr, +}; + +use num_bigint::BigInt; +use num_traits::{ToPrimitive, Zero}; +use serde::{Deserialize, Serialize, Serializer}; + +use wasm_bindgen::prelude::*; + +#[derive(Default, Debug, Clone)] +#[wasm_bindgen] +pub struct BigNumber { + v: BigInt, +} + +impl Deref for BigNumber { + type Target = BigInt; + + fn deref(&self) -> &Self::Target { + &self.v + } +} + +impl Serialize for BigNumber { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_str(&self.v.to_string()) + } +} + +impl<'de> Deserialize<'de> for BigNumber { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + String::deserialize(deserializer)? + .parse() + .map_err(serde::de::Error::custom) + .map(|v| BigNumber { v }) + } +} + +impl FromStr for BigNumber { + type Err = Error; + + fn from_str(s: &str) -> Result { + BigNumber::from_string(s) + } +} + +impl TryInto for &str { + type Error = Error; + + fn try_into(self) -> Result { + BigNumber::from_str(self) + } +} + +impl TryFrom for BigNumber { + type Error = Error; + + fn try_from(s: String) -> Result { + BigNumber::from_str(&s) + } +} + +#[wasm_bindgen] +impl BigNumber { + #[wasm_bindgen(js_name = "fromString")] + pub fn from_string(value: &str) -> Result { + let value = value.trim().replace('_', ""); + + Ok(BigNumber { + v: BigInt::from_str(value.as_str()) + .map_err(|e| Error::InvalidNumberParse(e.to_string()))?, + }) + } + + #[allow(clippy::inherent_to_string_shadow_display)] + #[wasm_bindgen(js_name = "toString")] + pub fn to_string(&self) -> String { + self.v.to_string() + } + + #[wasm_bindgen(js_name = "toHex")] + pub fn to_hex(&self) -> String { + format!("{:#x}", self.v) + } + + #[wasm_bindgen(js_name = "toNumber")] + pub fn to_number(&self) -> f64 { + self.v.to_f64().unwrap_or(0.0) + } + + #[wasm_bindgen(js_name = "toI64")] + pub fn to_i64(&self) -> i64 { + self.v.to_i64().unwrap_or(0) + } + + #[wasm_bindgen(js_name = "toU64")] + pub fn to_u64(&self) -> u64 { + self.v.to_u64().unwrap_or(0) + } + + #[wasm_bindgen(js_name = "withPrecision")] + pub fn with_precision(&self, precision: u32) -> String { + let mut s = self.v.to_string(); + let len = s.len(); + if len < precision as usize { + s.insert_str(0, &"0".repeat(precision as usize - len)); + } + let len = s.len(); + let index = len - precision as usize; + s.insert(index, '.'); + s + } + + pub fn is_zero(&self) -> bool { + self.v.is_zero() + } + + pub fn self_add(mut self, other: &BigNumber) -> Self { + self.v += &other.v; + self + } + + pub fn self_sub(mut self, other: &BigNumber) -> Self { + self.v -= &other.v; + self + } + + pub fn self_mul(mut self, other: &BigNumber) -> Self { + self.v *= &other.v; + self + } + + pub fn self_div(mut self, other: &BigNumber) -> Self { + self.v /= &other.v; + self + } + + pub fn gt(&self, other: &BigNumber) -> bool { + self.v > other.v + } + + pub fn gte(&self, other: &BigNumber) -> bool { + self.v >= other.v + } + + pub fn lt(&self, other: &BigNumber) -> bool { + self.v < other.v + } + + pub fn lte(&self, other: &BigNumber) -> bool { + self.v <= other.v + } +} + +impl Add for BigNumber { + type Output = Self; + + fn add(self, other: Self) -> Self::Output { + BigNumber { + v: self.v + &other.v, + } + } +} + +impl Sub for BigNumber { + type Output = Self; + + fn sub(self, other: Self) -> Self::Output { + BigNumber { + v: self.v - &other.v, + } + } +} + +impl Mul for BigNumber { + type Output = Self; + + fn mul(self, other: Self) -> Self::Output { + BigNumber { + v: self.v * &other.v, + } + } +} + +impl Div for BigNumber { + type Output = Self; + + fn div(self, other: Self) -> Self::Output { + BigNumber { + v: self.v / &other.v, + } + } +} + +impl PartialEq for BigNumber { + #[inline] + fn eq(&self, other: &BigNumber) -> bool { + self.v.eq(&other.v) + } +} + +impl Eq for BigNumber {} + +impl PartialOrd for BigNumber { + #[inline] + fn partial_cmp(&self, other: &BigNumber) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for BigNumber { + #[inline] + fn cmp(&self, other: &BigNumber) -> Ordering { + self.v.cmp(&other.v) + } +} + +macro_rules! impl_from { + ($($uint_type: ty),*) => { + $( + impl From<$uint_type> for BigNumber { + fn from(s: $uint_type) -> BigNumber { + BigNumber { + v: BigInt::from(s), + } + } + } + )* + } +} + +impl_from!(u8, u16, u32, u64, u128); +impl_from!(i8, i16, i32, i64, i128); + +impl Display for BigNumber { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.v) + } +} diff --git a/packages/kos-web/src/wallet.rs b/packages/kos-web/src/wallet.rs index cb0daa1..de8bead 100644 --- a/packages/kos-web/src/wallet.rs +++ b/packages/kos-web/src/wallet.rs @@ -277,12 +277,10 @@ mod tests { #[test] fn test_export_import() { - let default_password = "password"; - let chain = get_chain_by_base_id(38).unwrap(); // create wallet - let mut w1 = Wallet::from_mnemonic( + let w1 = Wallet::from_mnemonic( 38, "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(), chain.get_path(0, false), From dafc094dc544728b29f1c5a1194e4273f0b2b8d6 Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Tue, 3 Dec 2024 09:58:48 -0300 Subject: [PATCH 31/42] feat: kos-mobile BigNumber --- Cargo.lock | 3 + packages/kos-mobile/Cargo.toml | 6 ++ packages/kos-mobile/src/lib.rs | 2 + packages/kos-mobile/src/number.rs | 98 +++++++++++++++++++++++++++++++ 4 files changed, 109 insertions(+) create mode 100644 packages/kos-mobile/src/number.rs diff --git a/Cargo.lock b/Cargo.lock index 18f8d2e..17a57b9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1595,6 +1595,9 @@ dependencies = [ "hex", "kos", "lazy_static", + "num-bigint", + "num-traits", + "serde", "thiserror", "uniffi", ] diff --git a/packages/kos-mobile/Cargo.toml b/packages/kos-mobile/Cargo.toml index 621163e..be95ac9 100644 --- a/packages/kos-mobile/Cargo.toml +++ b/packages/kos-mobile/Cargo.toml @@ -11,6 +11,9 @@ version.workspace = true [lib] crate-type = ["cdylib", "staticlib", "rlib"] +[features] +default = ["serde"] + [[bin]] name = "uniffi-bindgen" path = "src/bin/uniffi-bindgen.rs" @@ -23,6 +26,9 @@ lazy_static = { workspace = true } thiserror = { workspace = true } uniffi = { workspace = true, features = ["cli"] } +serde = { workspace = true, features = ["derive"], optional = true } +num-bigint = "0.4" +num-traits = "0.2" [build-dependencies] uniffi = { workspace = true, features = ["build"] } \ No newline at end of file diff --git a/packages/kos-mobile/src/lib.rs b/packages/kos-mobile/src/lib.rs index 6e2b408..3117c94 100644 --- a/packages/kos-mobile/src/lib.rs +++ b/packages/kos-mobile/src/lib.rs @@ -1,3 +1,5 @@ +pub mod number; + use hex::FromHexError; use hex::ToHex; use kos::chains::{get_chain_by_base_id, Chain, ChainError, Transaction}; diff --git a/packages/kos-mobile/src/number.rs b/packages/kos-mobile/src/number.rs new file mode 100644 index 0000000..bfe7905 --- /dev/null +++ b/packages/kos-mobile/src/number.rs @@ -0,0 +1,98 @@ +use num_bigint::BigInt; +use num_traits::{One, Signed, Zero}; +use serde::{Deserialize, Serialize}; +use std::str::FromStr; + +#[derive(Debug, Clone, Default, Serialize, Deserialize, uniffi::Record)] +pub struct BigNumber { + pub value: String, +} + +impl BigNumber { + pub fn new(value: &str) -> Result { + BigInt::from_str(value) + .map(|_| BigNumber { + value: value.to_string(), + }) + .map_err(|_| format!("Invalid number format: {}", value)) + } + + pub fn to_bigint(&self) -> Result { + BigInt::from_str(&self.value).map_err(|_| format!("Failed to parse BigInt: {}", self.value)) + } +} + +#[uniffi::export] +fn big_number_new(value: String) -> Result { + BigNumber::new(&value) +} + +#[uniffi::export] +fn big_number_add(lhs: BigNumber, rhs: BigNumber) -> Result { + let left = lhs.to_bigint()?; + let right = rhs.to_bigint()?; + Ok(BigNumber { + value: (left + right).to_string(), + }) +} + +#[uniffi::export] +fn big_number_subtract(lhs: BigNumber, rhs: BigNumber) -> Result { + let left = lhs.to_bigint()?; + let right = rhs.to_bigint()?; + Ok(BigNumber { + value: (left - right).to_string(), + }) +} + +#[uniffi::export] +fn big_number_multiply(lhs: BigNumber, rhs: BigNumber) -> Result { + let left = lhs.to_bigint()?; + let right = rhs.to_bigint()?; + Ok(BigNumber { + value: (left * right).to_string(), + }) +} + +#[uniffi::export] +fn big_number_divide(lhs: BigNumber, rhs: BigNumber) -> Result { + let left = lhs.to_bigint()?; + let right = rhs.to_bigint()?; + if right.is_zero() { + return Err("Cannot divide by zero".to_string()); + } + Ok(BigNumber { + value: (left / right).to_string(), + }) +} + +#[uniffi::export] +fn big_number_is_zero(value: BigNumber) -> Result { + Ok(value.to_bigint()?.is_zero()) +} + +#[uniffi::export] +fn big_number_increment(value: BigNumber) -> Result { + let current = value.to_bigint()?; + Ok(BigNumber { + value: (current + BigInt::one()).to_string(), + }) +} + +#[uniffi::export] +fn big_number_decrement(value: BigNumber) -> Result { + let current = value.to_bigint()?; + Ok(BigNumber { + value: (current - BigInt::one()).to_string(), + }) +} + +#[uniffi::export] +fn big_number_is_positive(value: BigNumber) -> Result { + Ok(value.to_bigint()?.is_positive()) +} + +#[uniffi::export] +fn big_number_is_negative(value: BigNumber) -> Result { + Ok(value.to_bigint()?.is_negative()) +} From 5e30023e76b56bdc029ef7f4c4d1b78f212990bd Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Thu, 5 Dec 2024 09:27:56 -0300 Subject: [PATCH 32/42] feat: BTC sign message --- packages/kos/src/chains/btc/mod.rs | 35 +++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/packages/kos/src/chains/btc/mod.rs b/packages/kos/src/chains/btc/mod.rs index 946135d..1b58571 100644 --- a/packages/kos/src/chains/btc/mod.rs +++ b/packages/kos/src/chains/btc/mod.rs @@ -9,6 +9,8 @@ use alloc::vec::Vec; use alloc::{format, vec}; use bech32::{u5, Variant}; +const BITCOIN_MESSAGE_PREFIX: &str = "\x18Bitcoin Signed Message:\n"; + #[allow(clippy::upper_case_acronyms)] pub struct BTC { pub id: u32, @@ -87,6 +89,15 @@ impl BTC { let addr = String::from_utf8(res)?; Ok(addr) } + + pub fn prepare_message(message: Vec) -> [u8; 32] { + let mut msg = Vec::new(); + msg.extend_from_slice(BITCOIN_MESSAGE_PREFIX.as_bytes()); + msg.extend_from_slice(message.len().to_string().as_bytes()); + msg.extend_from_slice(&message); + + sha256_digest(&msg[..]) + } } impl Chain for BTC { @@ -143,12 +154,10 @@ impl Chain for BTC { Err(ChainError::NotSupported) } - fn sign_message( - &self, - _private_key: Vec, - _message: Vec, - ) -> Result, ChainError> { - Err(ChainError::NotSupported) + fn sign_message(&self, private_key: Vec, message: Vec) -> Result, ChainError> { + let prepared_message = BTC::prepare_message(message); + let signature = self.sign_raw(private_key, prepared_message.to_vec())?; + Ok(signature) } fn sign_raw(&self, private_key: Vec, payload: Vec) -> Result, ChainError> { @@ -206,4 +215,18 @@ mod test { let addr = btc.get_address(pbk).unwrap(); assert_eq!(addr, "DBus3bamQjgJULBJtYXpEzDWQRwF5iwxgC"); } + + #[test] + fn test_sign_message() { + let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(); + let path = "m/44'/0'/0'/0/0".to_string(); + + let btc = BTC::new(); + let seed = btc.mnemonic_to_seed(mnemonic, "".to_string()).unwrap(); + let pvk = btc.derive(seed, path).unwrap(); + let message = "Hello, World!".as_bytes().to_vec(); + let signature = btc.sign_message(pvk, message).unwrap(); + assert_eq!(hex::encode(signature.clone()), "9d561a0ba6ea562e61606e7f3b6a92c889246eec2c05e86e3f465f43469ae9436d7e46accdcfaea848460e42c83c52238b6956c4bfb192e67023b6024e95bdcf01"); + assert_eq!(signature.len(), 65); + } } From f68e2c46037b89668815bb63589418d60fc8d830 Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Fri, 6 Dec 2024 17:13:17 -0300 Subject: [PATCH 33/42] fix: uniffi throw Ok(String) --- packages/kos-mobile/src/lib.rs | 4 +++- packages/kos-mobile/src/number.rs | 31 ++++++++++++++++--------------- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/packages/kos-mobile/src/lib.rs b/packages/kos-mobile/src/lib.rs index 3117c94..13c8bd8 100644 --- a/packages/kos-mobile/src/lib.rs +++ b/packages/kos-mobile/src/lib.rs @@ -9,13 +9,15 @@ use kos::crypto::cipher::CipherAlgo; uniffi::setup_scaffolding!(); #[derive(Debug, thiserror::Error, uniffi::Error)] -enum KOSError { +pub enum KOSError { #[error("UnsupportedChainError: Unsupported chain {id}")] UnsupportedChain { id: String }, #[error("KOSDelegateError: {0}")] KOSDelegate(String), #[error("HexDecodeError: {0}")] HexDecode(String), + #[error("KOSNumberError: {0}")] + KOSNumber(String), } impl From for KOSError { diff --git a/packages/kos-mobile/src/number.rs b/packages/kos-mobile/src/number.rs index bfe7905..df62e1e 100644 --- a/packages/kos-mobile/src/number.rs +++ b/packages/kos-mobile/src/number.rs @@ -1,3 +1,4 @@ +use crate::KOSError; use num_bigint::BigInt; use num_traits::{One, Signed, Zero}; use serde::{Deserialize, Serialize}; @@ -9,26 +10,26 @@ pub struct BigNumber { } impl BigNumber { - pub fn new(value: &str) -> Result { + pub fn new(value: &str) -> Result { BigInt::from_str(value) .map(|_| BigNumber { value: value.to_string(), }) - .map_err(|_| format!("Invalid number format: {}", value)) + .map_err(|_| KOSError::KOSNumber("Invalid number".to_string())) } - pub fn to_bigint(&self) -> Result { - BigInt::from_str(&self.value).map_err(|_| format!("Failed to parse BigInt: {}", self.value)) + pub fn to_bigint(&self) -> Result { + BigInt::from_str(&self.value).map_err(|_| KOSError::KOSNumber("Invalid number".to_string())) } } #[uniffi::export] -fn big_number_new(value: String) -> Result { +fn big_number_new(value: String) -> Result { BigNumber::new(&value) } #[uniffi::export] -fn big_number_add(lhs: BigNumber, rhs: BigNumber) -> Result { +fn big_number_add(lhs: BigNumber, rhs: BigNumber) -> Result { let left = lhs.to_bigint()?; let right = rhs.to_bigint()?; Ok(BigNumber { @@ -37,7 +38,7 @@ fn big_number_add(lhs: BigNumber, rhs: BigNumber) -> Result { } #[uniffi::export] -fn big_number_subtract(lhs: BigNumber, rhs: BigNumber) -> Result { +fn big_number_subtract(lhs: BigNumber, rhs: BigNumber) -> Result { let left = lhs.to_bigint()?; let right = rhs.to_bigint()?; Ok(BigNumber { @@ -46,7 +47,7 @@ fn big_number_subtract(lhs: BigNumber, rhs: BigNumber) -> Result Result { +fn big_number_multiply(lhs: BigNumber, rhs: BigNumber) -> Result { let left = lhs.to_bigint()?; let right = rhs.to_bigint()?; Ok(BigNumber { @@ -55,11 +56,11 @@ fn big_number_multiply(lhs: BigNumber, rhs: BigNumber) -> Result Result { +fn big_number_divide(lhs: BigNumber, rhs: BigNumber) -> Result { let left = lhs.to_bigint()?; let right = rhs.to_bigint()?; if right.is_zero() { - return Err("Cannot divide by zero".to_string()); + return Err(KOSError::KOSNumber("Division by zero".to_string())); } Ok(BigNumber { value: (left / right).to_string(), @@ -67,12 +68,12 @@ fn big_number_divide(lhs: BigNumber, rhs: BigNumber) -> Result Result { +fn big_number_is_zero(value: BigNumber) -> Result { Ok(value.to_bigint()?.is_zero()) } #[uniffi::export] -fn big_number_increment(value: BigNumber) -> Result { +fn big_number_increment(value: BigNumber) -> Result { let current = value.to_bigint()?; Ok(BigNumber { value: (current + BigInt::one()).to_string(), @@ -80,7 +81,7 @@ fn big_number_increment(value: BigNumber) -> Result { } #[uniffi::export] -fn big_number_decrement(value: BigNumber) -> Result { +fn big_number_decrement(value: BigNumber) -> Result { let current = value.to_bigint()?; Ok(BigNumber { value: (current - BigInt::one()).to_string(), @@ -88,11 +89,11 @@ fn big_number_decrement(value: BigNumber) -> Result { } #[uniffi::export] -fn big_number_is_positive(value: BigNumber) -> Result { +fn big_number_is_positive(value: BigNumber) -> Result { Ok(value.to_bigint()?.is_positive()) } #[uniffi::export] -fn big_number_is_negative(value: BigNumber) -> Result { +fn big_number_is_negative(value: BigNumber) -> Result { Ok(value.to_bigint()?.is_negative()) } From c293ef6fc25524b346e8dfb835fa8e5d699310d7 Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Thu, 12 Dec 2024 10:31:38 -0300 Subject: [PATCH 34/42] feat: btc sign methods --- packages/kos/src/chains/btc/mod.rs | 30 +++- packages/kos/src/chains/btc/models.rs | 194 ++++++++++++++++++++++++++ 2 files changed, 222 insertions(+), 2 deletions(-) create mode 100644 packages/kos/src/chains/btc/models.rs diff --git a/packages/kos/src/chains/btc/mod.rs b/packages/kos/src/chains/btc/mod.rs index 1b58571..93961f4 100644 --- a/packages/kos/src/chains/btc/mod.rs +++ b/packages/kos/src/chains/btc/mod.rs @@ -1,3 +1,5 @@ +mod models; + use crate::chains::util::{private_key_from_vec, slice_from_vec}; use crate::chains::{Chain, ChainError, Transaction, TxInfo}; use crate::crypto::b58::b58enc; @@ -150,8 +152,15 @@ impl Chain for BTC { Ok(self.get_addr_new(public_key)?) } - fn sign_tx(&self, _private_key: Vec, _tx: Transaction) -> Result { - Err(ChainError::NotSupported) + fn sign_tx(&self, private_key: Vec, tx: Transaction) -> Result { + let mut tx = tx; + + let mut btc_tx = models::BTCTransaction::from_raw(tx.raw_data.clone())?; + btc_tx.sign(private_key)?; + + tx.raw_data = btc_tx.serialize(); + + Ok(tx) } fn sign_message(&self, private_key: Vec, message: Vec) -> Result, ChainError> { @@ -229,4 +238,21 @@ mod test { assert_eq!(hex::encode(signature.clone()), "9d561a0ba6ea562e61606e7f3b6a92c889246eec2c05e86e3f465f43469ae9436d7e46accdcfaea848460e42c83c52238b6956c4bfb192e67023b6024e95bdcf01"); assert_eq!(signature.len(), 65); } + + #[test] + fn decoded_and_sign_transaction() { + let raw = hex::decode("0100000001a3727243402a869948ccf6d1b61e9b7eabacaa1c1301fcef743bc59ba14664340100000000ffffffff021027000000000000225120236c88c2ba0bdaa1506c42168453629e33a7dbb203e310b069bb22bf67350d2c91c7470000000000160014dc6bf86354105de2fcd9868a2b0376d6731cb92f000000000100000001a3727243402a869948ccf6d1b61e9b7eabacaa1c1301fcef743bc59ba14664340100000000ffffffff021027000000000000225120236c88c2ba0bdaa1506c42168453629e33a7dbb203e310b069bb22bf67350d2c91c7470000000000160014dc6bf86354105de2fcd9868a2b0376d6731cb92f00000000").unwrap(); + + let pvk = hex::decode("4604b4b710fe91f584fff084e1a9159fe4f8408fff380596a604948474ce4fa3") + .unwrap(); + let btc = BTC::new(); + let transaction = Transaction { + raw_data: raw, + signature: vec![], + tx_hash: vec![], + }; + + let signed_tx = btc.sign_tx(pvk, transaction).unwrap(); + assert_eq!(signed_tx.raw_data.len(), 192); + } } diff --git a/packages/kos/src/chains/btc/models.rs b/packages/kos/src/chains/btc/models.rs new file mode 100644 index 0000000..f482238 --- /dev/null +++ b/packages/kos/src/chains/btc/models.rs @@ -0,0 +1,194 @@ +use crate::chains::util::{private_key_from_vec, slice_from_vec}; +use crate::chains::ChainError; +use crate::crypto::hash::sha256_digest; +use crate::crypto::secp256k1::{Secp256K1, Secp256k1Trait}; +use std::error::Error; + +#[derive(Debug, Clone)] +pub struct BTCTransaction { + pub version: u32, + pub lock_time: u32, + pub inputs: Vec, + pub outputs: Vec, +} + +#[derive(Debug, Clone)] +pub struct Input { + txid: [u8; 32], + vout: u32, + script_sig: Vec, + sequence: u32, +} + +#[derive(Debug, Clone)] +pub struct Output { + value: u64, + script_pubkey: Vec, +} + +impl BTCTransaction { + pub fn sign(&mut self, private_key: Vec) -> Result<(), ChainError> { + let mut tx = self.clone(); + let hash_type = 1; + + for i in 0..tx.inputs.len() { + let input = &tx.inputs[i]; + let script_sig = input.script_sig.clone(); + let script_pubkey = &tx.outputs[input.vout as usize].script_pubkey; + let mut script = script_sig.clone(); + script.extend_from_slice(&script_pubkey); + let hash = sha256_digest(&sha256_digest(&script)); + + let mut pvk_bytes = private_key_from_vec(&private_key)?; + let payload_bytes = slice_from_vec(&hash.to_vec())?; + let sig = Secp256K1::sign(&payload_bytes, &pvk_bytes)?; + + pvk_bytes.fill(0); + + let signature = sig.to_vec(); + let mut signature = signature.to_vec(); + signature.push(hash_type as u8); + let mut script_sig = vec![signature.len() as u8]; + script_sig.extend_from_slice(&signature); + tx.inputs[i].script_sig = script_sig; + } + *self = tx; + Ok(()) + } + + pub fn from_raw(raw: Vec) -> Result { + let mut cursor = &raw[..]; + + let version = read_u32(&mut cursor).unwrap(); + + let input_count = read_varint(&mut cursor).unwrap(); + let mut inputs = Vec::new(); + + for _ in 0..input_count { + let mut txid = [0u8; 32]; + txid.copy_from_slice(&cursor[..32]); + cursor = &cursor[32..]; + + let vout = read_u32(&mut cursor).unwrap(); + + let script_sig_len = read_varint(&mut cursor).unwrap(); + let script_sig = cursor[..script_sig_len as usize].to_vec(); + cursor = &cursor[script_sig_len as usize..]; + + let sequence = read_u32(&mut cursor).unwrap(); + + inputs.push(Input { + txid, + vout, + script_sig, + sequence, + }); + } + + let output_count = read_varint(&mut cursor).unwrap(); + let mut outputs = Vec::new(); + + for _ in 0..output_count { + let value = read_u64(&mut cursor).unwrap(); + + let script_pubkey_len = read_varint(&mut cursor).unwrap(); + let script_pubkey = cursor[..script_pubkey_len as usize].to_vec(); + cursor = &cursor[script_pubkey_len as usize..]; + + outputs.push(Output { + value, + script_pubkey, + }); + } + + let lock_time = read_u32(&mut cursor).unwrap(); + + Ok(Self { + version, + lock_time, + inputs, + outputs, + }) + } + + pub fn serialize(&self) -> Vec { + let mut raw_tx = Vec::new(); + + raw_tx.extend(&self.version.to_le_bytes()); + + raw_tx.push(self.inputs.len() as u8); + for input in &self.inputs { + raw_tx.extend(&input.txid); + raw_tx.extend(&input.vout.to_le_bytes()); + raw_tx.push(input.script_sig.len() as u8); + raw_tx.extend(&input.script_sig); + raw_tx.extend(&input.sequence.to_le_bytes()); + } + + raw_tx.push(self.outputs.len() as u8); + for output in &self.outputs { + raw_tx.extend(&output.value.to_le_bytes()); + raw_tx.push(output.script_pubkey.len() as u8); + raw_tx.extend(&output.script_pubkey); + } + + raw_tx.extend(&self.lock_time.to_le_bytes()); + + raw_tx + } +} + +fn read_u32(cursor: &mut &[u8]) -> Result> { + if cursor.len() < 4 { + return Err("Buffer underflow".into()); + } + let value = u32::from_le_bytes(cursor[..4].try_into().unwrap()); + *cursor = &cursor[4..]; + Ok(value) +} + +fn read_u64(cursor: &mut &[u8]) -> Result> { + if cursor.len() < 8 { + return Err("Buffer underflow".into()); + } + let value = u64::from_le_bytes(cursor[..8].try_into().unwrap()); + *cursor = &cursor[8..]; + Ok(value) +} + +fn read_varint(cursor: &mut &[u8]) -> Result> { + if cursor.is_empty() { + return Err("Buffer underflow".into()); + } + + let first = cursor[0]; + *cursor = &cursor[1..]; + + match first { + 0xFF => { + if cursor.len() < 8 { + return Err("Buffer underflow".into()); + } + let value = u64::from_le_bytes(cursor[..8].try_into().unwrap()); + *cursor = &cursor[8..]; + Ok(value) + } + 0xFE => { + if cursor.len() < 4 { + return Err("Buffer underflow".into()); + } + let value = u32::from_le_bytes(cursor[..4].try_into().unwrap()) as u64; + *cursor = &cursor[4..]; + Ok(value) + } + 0xFD => { + if cursor.len() < 2 { + return Err("Buffer underflow".into()); + } + let value = u16::from_le_bytes(cursor[..2].try_into().unwrap()) as u64; + *cursor = &cursor[2..]; + Ok(value) + } + _ => Ok(first as u64), + } +} From 91e11d93104092235906698ef5b46d75bf573b35 Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Tue, 17 Dec 2024 10:01:15 -0300 Subject: [PATCH 35/42] fix: btc tx witness --- packages/kos/src/chains/btc/mod.rs | 4 +- packages/kos/src/chains/btc/models.rs | 176 ++++++++++++++++++-------- packages/kos/src/chains/mod.rs | 5 + 3 files changed, 133 insertions(+), 52 deletions(-) diff --git a/packages/kos/src/chains/btc/mod.rs b/packages/kos/src/chains/btc/mod.rs index 93961f4..eeb3339 100644 --- a/packages/kos/src/chains/btc/mod.rs +++ b/packages/kos/src/chains/btc/mod.rs @@ -155,8 +155,8 @@ impl Chain for BTC { fn sign_tx(&self, private_key: Vec, tx: Transaction) -> Result { let mut tx = tx; - let mut btc_tx = models::BTCTransaction::from_raw(tx.raw_data.clone())?; - btc_tx.sign(private_key)?; + let mut btc_tx = models::BTCTransaction::from_raw(&tx.raw_data.clone())?; + btc_tx.sign(&private_key)?; tx.raw_data = btc_tx.serialize(); diff --git a/packages/kos/src/chains/btc/models.rs b/packages/kos/src/chains/btc/models.rs index f482238..7791067 100644 --- a/packages/kos/src/chains/btc/models.rs +++ b/packages/kos/src/chains/btc/models.rs @@ -14,54 +14,107 @@ pub struct BTCTransaction { #[derive(Debug, Clone)] pub struct Input { - txid: [u8; 32], - vout: u32, - script_sig: Vec, - sequence: u32, + pub txid: [u8; 32], + pub vout: u32, + pub script_sig: Vec, + pub sequence: u32, + pub witness: Vec>, } #[derive(Debug, Clone)] pub struct Output { - value: u64, - script_pubkey: Vec, + pub value: u64, + pub script_pubkey: Vec, } impl BTCTransaction { - pub fn sign(&mut self, private_key: Vec) -> Result<(), ChainError> { - let mut tx = self.clone(); - let hash_type = 1; - - for i in 0..tx.inputs.len() { - let input = &tx.inputs[i]; - let script_sig = input.script_sig.clone(); - let script_pubkey = &tx.outputs[input.vout as usize].script_pubkey; - let mut script = script_sig.clone(); - script.extend_from_slice(&script_pubkey); - let hash = sha256_digest(&sha256_digest(&script)); - - let mut pvk_bytes = private_key_from_vec(&private_key)?; - let payload_bytes = slice_from_vec(&hash.to_vec())?; + pub fn sign(&mut self, private_key: &[u8]) -> Result<(), ChainError> { + let hash_type = 1; // SIGHASH_ALL + + let outputs = self.outputs.clone(); + let inputs_data: Vec<_> = self + .inputs + .iter() + .enumerate() + .map(|(i, input)| { + let script_pubkey = outputs[input.vout as usize].script_pubkey.clone(); + let hash = self.calculate_segwit_hash(i, &script_pubkey)?; + Ok((hash, script_pubkey)) + }) + .collect::>()?; + + for (input, (hash, _script_pubkey)) in self.inputs.iter_mut().zip(inputs_data) { + let pvk_bytes = private_key_from_vec(private_key)?; + let payload_bytes = slice_from_vec(&hash)?; + let sig = Secp256K1::sign(&payload_bytes, &pvk_bytes)?; + let mut der = Secp256K1::convert_to_der(&sig)?; + + der.push(hash_type as u8); - pvk_bytes.fill(0); + let pbk = Secp256K1::private_to_public_compressed(&pvk_bytes)?; - let signature = sig.to_vec(); - let mut signature = signature.to_vec(); - signature.push(hash_type as u8); - let mut script_sig = vec![signature.len() as u8]; - script_sig.extend_from_slice(&signature); - tx.inputs[i].script_sig = script_sig; + input.witness = vec![der, pbk.to_vec()]; + input.script_sig.clear(); } - *self = tx; + Ok(()) } - pub fn from_raw(raw: Vec) -> Result { - let mut cursor = &raw[..]; + fn calculate_segwit_hash( + &self, + input_index: usize, + script_pubkey: &[u8], + ) -> Result<[u8; 32], ChainError> { + use crate::crypto::hash::sha256_digest; + + let mut hash_prevouts = Vec::new(); + let mut hash_sequence = Vec::new(); + + for input in &self.inputs { + hash_prevouts.extend(&input.txid); + hash_prevouts.extend(&input.vout.to_le_bytes()); + } + let hash_prevouts = sha256_digest(&sha256_digest(&hash_prevouts)); + + for input in &self.inputs { + hash_sequence.extend(&input.sequence.to_le_bytes()); + } + let hash_sequence = sha256_digest(&sha256_digest(&hash_sequence)); - let version = read_u32(&mut cursor).unwrap(); + let input = &self.inputs[input_index]; + let mut input_data: Vec = Vec::new(); + input_data.extend(&input.txid); + input_data.extend(&input.vout.to_le_bytes()); + input_data.extend(&(script_pubkey.len() as u64).to_le_bytes()); // Tamanho do script_pubkey + input_data.extend(script_pubkey); + input_data.extend(&input.sequence.to_le_bytes()); - let input_count = read_varint(&mut cursor).unwrap(); + let mut hash_outputs = Vec::new(); + for output in &self.outputs { + hash_outputs.extend(&output.value.to_le_bytes()); + hash_outputs.extend(&(output.script_pubkey.len() as u64).to_le_bytes()); + hash_outputs.extend(&output.script_pubkey); + } + let hash_outputs = sha256_digest(&sha256_digest(&hash_outputs)); + + let mut tx_hash_buffer = Vec::new(); + tx_hash_buffer.extend(&self.version.to_le_bytes()); + tx_hash_buffer.extend(&hash_prevouts); + tx_hash_buffer.extend(&hash_sequence); + tx_hash_buffer.extend(input_data); + tx_hash_buffer.extend(&hash_outputs); + tx_hash_buffer.extend(&self.lock_time.to_le_bytes()); + tx_hash_buffer.extend(&(1u32.to_le_bytes())); // hash type + + Ok(sha256_digest(&sha256_digest(&tx_hash_buffer))) + } + + pub fn from_raw(raw: &[u8]) -> Result { + let mut cursor = raw; + + let version = read_u32(&mut cursor)?; + let input_count = read_varint(&mut cursor)?; let mut inputs = Vec::new(); for _ in 0..input_count { @@ -69,29 +122,28 @@ impl BTCTransaction { txid.copy_from_slice(&cursor[..32]); cursor = &cursor[32..]; - let vout = read_u32(&mut cursor).unwrap(); - - let script_sig_len = read_varint(&mut cursor).unwrap(); + let vout = read_u32(&mut cursor)?; + let script_sig_len = read_varint(&mut cursor)?; let script_sig = cursor[..script_sig_len as usize].to_vec(); cursor = &cursor[script_sig_len as usize..]; - let sequence = read_u32(&mut cursor).unwrap(); + let sequence = read_u32(&mut cursor)?; inputs.push(Input { txid, vout, script_sig, sequence, + witness: Vec::new(), }); } - let output_count = read_varint(&mut cursor).unwrap(); + let output_count = read_varint(&mut cursor)?; let mut outputs = Vec::new(); for _ in 0..output_count { - let value = read_u64(&mut cursor).unwrap(); - - let script_pubkey_len = read_varint(&mut cursor).unwrap(); + let value = read_u64(&mut cursor)?; + let script_pubkey_len = read_varint(&mut cursor)?; let script_pubkey = cursor[..script_pubkey_len as usize].to_vec(); cursor = &cursor[script_pubkey_len as usize..]; @@ -101,7 +153,7 @@ impl BTCTransaction { }); } - let lock_time = read_u32(&mut cursor).unwrap(); + let lock_time = read_u32(&mut cursor)?; Ok(Self { version, @@ -116,6 +168,14 @@ impl BTCTransaction { raw_tx.extend(&self.version.to_le_bytes()); + let is_segwit = self.inputs.iter().any(|input| !input.witness.is_empty()); + + if is_segwit { + // Add SegWit marker and flag + raw_tx.push(0x00); // Marker + raw_tx.push(0x01); // Flag + } + raw_tx.push(self.inputs.len() as u8); for input in &self.inputs { raw_tx.extend(&input.txid); @@ -132,33 +192,43 @@ impl BTCTransaction { raw_tx.extend(&output.script_pubkey); } + if is_segwit { + for input in &self.inputs { + raw_tx.push(input.witness.len() as u8); + for item in &input.witness { + raw_tx.push(item.len() as u8); + raw_tx.extend(item); + } + } + } + raw_tx.extend(&self.lock_time.to_le_bytes()); raw_tx } } -fn read_u32(cursor: &mut &[u8]) -> Result> { +fn read_u32(cursor: &mut &[u8]) -> Result { if cursor.len() < 4 { - return Err("Buffer underflow".into()); + return Err(ChainError::InvalidData("Insufficient bytes for u32".into())); } let value = u32::from_le_bytes(cursor[..4].try_into().unwrap()); *cursor = &cursor[4..]; Ok(value) } -fn read_u64(cursor: &mut &[u8]) -> Result> { +fn read_u64(cursor: &mut &[u8]) -> Result { if cursor.len() < 8 { - return Err("Buffer underflow".into()); + return Err(ChainError::InvalidData("Buffer underflow".into())); } let value = u64::from_le_bytes(cursor[..8].try_into().unwrap()); *cursor = &cursor[8..]; Ok(value) } -fn read_varint(cursor: &mut &[u8]) -> Result> { +fn read_varint(cursor: &mut &[u8]) -> Result { if cursor.is_empty() { - return Err("Buffer underflow".into()); + return Err(ChainError::InvalidData("Empty cursor for varint".into())); } let first = cursor[0]; @@ -167,7 +237,9 @@ fn read_varint(cursor: &mut &[u8]) -> Result> { match first { 0xFF => { if cursor.len() < 8 { - return Err("Buffer underflow".into()); + return Err(ChainError::InvalidData( + "Insufficient bytes for varint u64".into(), + )); } let value = u64::from_le_bytes(cursor[..8].try_into().unwrap()); *cursor = &cursor[8..]; @@ -175,7 +247,9 @@ fn read_varint(cursor: &mut &[u8]) -> Result> { } 0xFE => { if cursor.len() < 4 { - return Err("Buffer underflow".into()); + return Err(ChainError::InvalidData( + "Insufficient bytes for varint u32".into(), + )); } let value = u32::from_le_bytes(cursor[..4].try_into().unwrap()) as u64; *cursor = &cursor[4..]; @@ -183,7 +257,9 @@ fn read_varint(cursor: &mut &[u8]) -> Result> { } 0xFD => { if cursor.len() < 2 { - return Err("Buffer underflow".into()); + return Err(ChainError::InvalidData( + "Insufficient bytes for varint u16".into(), + )); } let value = u16::from_le_bytes(cursor[..2].try_into().unwrap()) as u64; *cursor = &cursor[2..]; diff --git a/packages/kos/src/chains/mod.rs b/packages/kos/src/chains/mod.rs index 77f9708..fd2af49 100644 --- a/packages/kos/src/chains/mod.rs +++ b/packages/kos/src/chains/mod.rs @@ -56,6 +56,7 @@ pub enum ChainError { InvalidMnemonic, CipherError(String), InvalidString(String), + InvalidData(String), } impl Display for ChainError { @@ -112,6 +113,9 @@ impl Display for ChainError { ChainError::InvalidString(e) => { write!(f, "invalid string: {}", e) } + ChainError::InvalidData(e) => { + write!(f, "invalid data: {}", e) + } } } } @@ -199,6 +203,7 @@ impl ChainError { ChainError::InvalidMnemonic => 17, ChainError::CipherError(_) => 18, ChainError::InvalidString(_) => 19, + ChainError::InvalidData(_) => 20, } } } From dec379c05c43ac76050839e7f8fc8c6f58e736da Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Thu, 26 Dec 2024 10:46:22 -0300 Subject: [PATCH 36/42] fix: build --- packages/kos/src/chains/btc/mod.rs | 2 +- packages/kos/src/chains/btc/models.rs | 12 ++++-------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/packages/kos/src/chains/btc/mod.rs b/packages/kos/src/chains/btc/mod.rs index eeb3339..ef7fc55 100644 --- a/packages/kos/src/chains/btc/mod.rs +++ b/packages/kos/src/chains/btc/mod.rs @@ -253,6 +253,6 @@ mod test { }; let signed_tx = btc.sign_tx(pvk, transaction).unwrap(); - assert_eq!(signed_tx.raw_data.len(), 192); + assert_eq!(signed_tx.raw_data.len(), 229); } } diff --git a/packages/kos/src/chains/btc/models.rs b/packages/kos/src/chains/btc/models.rs index 7791067..20717da 100644 --- a/packages/kos/src/chains/btc/models.rs +++ b/packages/kos/src/chains/btc/models.rs @@ -2,7 +2,6 @@ use crate::chains::util::{private_key_from_vec, slice_from_vec}; use crate::chains::ChainError; use crate::crypto::hash::sha256_digest; use crate::crypto::secp256k1::{Secp256K1, Secp256k1Trait}; -use std::error::Error; #[derive(Debug, Clone)] pub struct BTCTransaction { @@ -47,14 +46,13 @@ impl BTCTransaction { let pvk_bytes = private_key_from_vec(private_key)?; let payload_bytes = slice_from_vec(&hash)?; - let sig = Secp256K1::sign(&payload_bytes, &pvk_bytes)?; - let mut der = Secp256K1::convert_to_der(&sig)?; + let mut sig = Secp256K1::sign(&payload_bytes, &pvk_bytes)?.to_vec(); - der.push(hash_type as u8); + sig.push(hash_type as u8); let pbk = Secp256K1::private_to_public_compressed(&pvk_bytes)?; - input.witness = vec![der, pbk.to_vec()]; + input.witness = vec![sig, pbk.to_vec()]; input.script_sig.clear(); } @@ -66,8 +64,6 @@ impl BTCTransaction { input_index: usize, script_pubkey: &[u8], ) -> Result<[u8; 32], ChainError> { - use crate::crypto::hash::sha256_digest; - let mut hash_prevouts = Vec::new(); let mut hash_sequence = Vec::new(); @@ -86,7 +82,7 @@ impl BTCTransaction { let mut input_data: Vec = Vec::new(); input_data.extend(&input.txid); input_data.extend(&input.vout.to_le_bytes()); - input_data.extend(&(script_pubkey.len() as u64).to_le_bytes()); // Tamanho do script_pubkey + input_data.extend(&(script_pubkey.len() as u64).to_le_bytes()); input_data.extend(script_pubkey); input_data.extend(&input.sequence.to_le_bytes()); From 200b2cc775064cc86416f791d5a12d0c556b423e Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Tue, 7 Jan 2025 09:04:49 -0300 Subject: [PATCH 37/42] feat: add method to return supported chains --- packages/kos-mobile/src/lib.rs | 33 +++ packages/kos-web/src/lib.rs | 10 + packages/kos/src/chains/mod.rs | 505 +++++++++++++++++++++++++-------- 3 files changed, 425 insertions(+), 123 deletions(-) diff --git a/packages/kos-mobile/src/lib.rs b/packages/kos-mobile/src/lib.rs index 13c8bd8..7f66379 100644 --- a/packages/kos-mobile/src/lib.rs +++ b/packages/kos-mobile/src/lib.rs @@ -165,6 +165,16 @@ fn sign_message(account: KOSAccount, hex: String) -> Result, KOSError> { Ok(signature) } +#[uniffi::export] +fn is_chain_supported(chain_id: u32) -> bool { + kos::chains::is_chain_supported(chain_id) +} + +#[uniffi::export] +fn get_supported_chains() -> Vec { + kos::chains::get_supported_chains() +} + #[cfg(test)] mod tests { use crate::*; @@ -397,4 +407,27 @@ mod tests { let signature = sign_message(account, message).unwrap(); assert_eq!(signature.len(), 64, "The signature length doesn't match"); } + + #[test] + fn should_return_true_for_supported_chain() { + let chain_id = 38; + let result = is_chain_supported(chain_id); + assert!(result, "The chain should be supported"); + } + + #[test] + fn should_return_false_for_unsupported_chain() { + let chain_id = 999; + let result = is_chain_supported(chain_id); + assert!(!result, "The chain should not be supported"); + } + + #[test] + fn should_get_supported_chains() { + let supported_chains = get_supported_chains(); + assert!( + !supported_chains.is_empty(), + "The supported chains should not be empty" + ); + } } diff --git a/packages/kos-web/src/lib.rs b/packages/kos-web/src/lib.rs index c3555cb..a99d418 100644 --- a/packages/kos-web/src/lib.rs +++ b/packages/kos-web/src/lib.rs @@ -57,3 +57,13 @@ pub fn generate_qr(data: &str) -> Result, Error> { qrcode_generator::to_png_to_vec(data, QrCodeEcc::Low, 1024) .map_err(|e| Error::InvalidString(format!("Invalid QRCode data: {}", e))) } + +#[wasm_bindgen(js_name = "isChainSupported")] +pub fn is_chain_supported(chain: u32) -> bool { + kos::chains::is_chain_supported(chain) +} + +#[wasm_bindgen(js_name = "getSupportedChains")] +pub fn get_supported_chains() -> Vec { + kos::chains::get_supported_chains() +} diff --git a/packages/kos/src/chains/mod.rs b/packages/kos/src/chains/mod.rs index fd2af49..d832033 100644 --- a/packages/kos/src/chains/mod.rs +++ b/packages/kos/src/chains/mod.rs @@ -274,127 +274,357 @@ pub trait Chain { type ChainFactory = fn() -> Box; -struct ChainRegistry { - registry: &'static [(u32, ChainFactory)], +struct ChainInfo { + factory: ChainFactory, + supported: bool, } +struct ChainRegistry { + registry: &'static [(u32, ChainInfo)], +} impl ChainRegistry { fn new() -> Self { - static REGISTRY: [(u32, ChainFactory); 46] = [ - (constants::ETH, || Box::new(eth::ETH::new())), - (constants::BSC, || { - Box::new(eth::ETH::new_eth_based(26, 56, "BSC", "BnbSmartChain")) - }), - (constants::POLYGON, || { - Box::new(eth::ETH::new_eth_based(28, 137, "MATIC", "Polygon")) - }), - (constants::HT, || { - Box::new(eth::ETH::new_eth_based(30, 128, "HT", "Huobi")) - }), - (constants::SYS_NEVM, || { - Box::new(eth::ETH::new_eth_based(37, 57, "SYS_NEVM", "Syscoin Nevm")) - }), - (constants::TRX, || Box::new(trx::TRX {})), - (constants::KLV, || Box::new(klv::KLV {})), - (constants::BTC, || Box::new(btc::BTC::new())), - (constants::DOT, || { - Box::new(substrate::Substrate::new(21, 0, "DOT", "Polkadot")) - }), - (constants::KSM, || { - Box::new(substrate::Substrate::new(27, 2, "KSM", "Kusama")) - }), - (constants::LTC, || { - Box::new(btc::BTC::new_btc_based(5, "ltc", "LTC", "Litecoin")) - }), - (constants::REEF, || { - Box::new(substrate::Substrate::new(29, 42, "REEF", "Reef")) - }), - (constants::SDN, || { - Box::new(substrate::Substrate::new(35, 5, "SDN", "Shiden")) - }), - (constants::ASTR, || { - Box::new(substrate::Substrate::new(36, 5, "ASTR", "Astar")) - }), - (constants::CFG, || { - Box::new(substrate::Substrate::new(47, 36, "CFG", "Centrifuge")) - }), - (constants::SYS, || { - Box::new(btc::BTC::new_btc_based(15, "sys", "SYS", "Syscoin")) - }), - (constants::KILT, || { - Box::new(substrate::Substrate::new(44, 38, "KILT", "KILT")) - }), - (constants::ALTAIR, || { - Box::new(substrate::Substrate::new(42, 136, "ALTAIR", "Altair")) - }), - (constants::DOGE, || { - Box::new(btc::BTC::new_legacy_btc_based(12, 0x1E, "DOGE", "Dogecoin")) - }), - (constants::DASH, || { - Box::new(btc::BTC::new_legacy_btc_based(11, 0x4C, "DASH", "Dash")) - }), - (constants::XRP, || Box::new(xrp::XRP::new())), - (constants::DGB, || { - Box::new(btc::BTC::new_btc_based(16, "dgb", "DGB", "Digibyte")) - }), - (constants::COSMOS, || Box::new(atom::ATOM::new())), - (constants::CELESTIA, || { - Box::new(atom::ATOM::new_cosmos_based( - "celestia", "celestia", "Celestia", "TIA", - )) - }), - (constants::CUDOS, || { - Box::new(atom::ATOM::new_cosmos_based( - "cudos", "cudos-1", "Cudos", "CUDOS", - )) - }), - (constants::AURA, || { - Box::new(atom::ATOM::new_cosmos_based( - "aura", "xstaxy-1", "Aura", "AURA", - )) - }), - (constants::ICP, || Box::new(icp::ICP {})), - (constants::SOL, || Box::new(sol::SOL {})), - (constants::MOVR, || Box::new(movr::MOVR::new())), - (constants::GLMR, || Box::new(movr::MOVR::new_glmr())), - (constants::BNB, || Box::new(bnb::BNB {})), - (constants::BCH, || Box::new(bch::BCH {})), - (constants::ADA, || Box::new(ada::ADA {})), - (constants::SUI, || Box::new(sui::SUI {})), - (constants::APT, || Box::new(apt::APT {})), - (constants::AVAIL, || { - Box::new(substrate::Substrate::new(62, 42, "AVAIL", "Avail")) - }), - (constants::ROLLUX, || { - Box::new(eth::ETH::new_eth_based(63, 570, "ROLLUX", "Rollux")) - }), - (constants::AVAX, || { - Box::new(eth::ETH::new_eth_based(39, 43114, "AVAX", "Avalanche")) - }), - (constants::ARB, || { - Box::new(eth::ETH::new_eth_based(57, 42161, "ARB", "Arbitrum")) - }), - (constants::BASE, || { - Box::new(eth::ETH::new_eth_based(60, 8453, "BASE", "Base")) - }), - (constants::NEAR, || { - Box::new(eth::ETH::new_eth_based(64, 397, "NEAR", "Near")) - }), - (constants::FTM, || { - Box::new(eth::ETH::new_eth_based(54, 250, "FTM", "Fantom")) - }), - (constants::CHZ, || { - Box::new(eth::ETH::new_eth_based(61, 88888, "CHZ", "Chiliz")) - }), - (constants::OP, || { - Box::new(eth::ETH::new_eth_based(53, 10, "OP", "Optimism")) - }), - (constants::POLYGON_ZKEVM, || { - Box::new(eth::ETH::new_eth_based(52, 1101, "ZKEVM", "Polygon zkEVM")) - }), - (constants::STOLZ, || { - Box::new(eth::ETH::new_eth_based(67, 2344, "STOLZ", "Stolz")) - }), + static REGISTRY: [(u32, ChainInfo); 46] = [ + ( + constants::ETH, + ChainInfo { + factory: || Box::new(eth::ETH::new()), + supported: true, + }, + ), + ( + constants::BSC, + ChainInfo { + factory: || Box::new(eth::ETH::new_eth_based(26, 56, "BSC", "BnbSmartChain")), + supported: true, + }, + ), + ( + constants::POLYGON, + ChainInfo { + factory: || Box::new(eth::ETH::new_eth_based(28, 137, "MATIC", "Polygon")), + supported: true, + }, + ), + ( + constants::HT, + ChainInfo { + factory: || Box::new(eth::ETH::new_eth_based(30, 128, "HT", "Huobi")), + supported: true, + }, + ), + ( + constants::SYS_NEVM, + ChainInfo { + factory: || { + Box::new(eth::ETH::new_eth_based(37, 57, "SYS_NEVM", "Syscoin Nevm")) + }, + supported: true, + }, + ), + ( + constants::TRX, + ChainInfo { + factory: || Box::new(trx::TRX {}), + supported: true, + }, + ), + ( + constants::KLV, + ChainInfo { + factory: || Box::new(klv::KLV {}), + supported: true, + }, + ), + ( + constants::BTC, + ChainInfo { + factory: || Box::new(btc::BTC::new()), + supported: false, + }, + ), + ( + constants::DOT, + ChainInfo { + factory: || Box::new(substrate::Substrate::new(21, 0, "DOT", "Polkadot")), + supported: true, + }, + ), + ( + constants::KSM, + ChainInfo { + factory: || Box::new(substrate::Substrate::new(27, 2, "KSM", "Kusama")), + supported: true, + }, + ), + ( + constants::LTC, + ChainInfo { + factory: || Box::new(btc::BTC::new_btc_based(5, "ltc", "LTC", "Litecoin")), + supported: false, + }, + ), + ( + constants::REEF, + ChainInfo { + factory: || Box::new(substrate::Substrate::new(29, 42, "REEF", "Reef")), + supported: true, + }, + ), + ( + constants::SDN, + ChainInfo { + factory: || Box::new(substrate::Substrate::new(35, 5, "SDN", "Shiden")), + supported: true, + }, + ), + ( + constants::ASTR, + ChainInfo { + factory: || Box::new(substrate::Substrate::new(36, 5, "ASTR", "Astar")), + supported: true, + }, + ), + ( + constants::CFG, + ChainInfo { + factory: || Box::new(substrate::Substrate::new(47, 36, "CFG", "Centrifuge")), + supported: true, + }, + ), + ( + constants::SYS, + ChainInfo { + factory: || Box::new(btc::BTC::new_btc_based(15, "sys", "SYS", "Syscoin")), + supported: false, + }, + ), + ( + constants::KILT, + ChainInfo { + factory: || Box::new(substrate::Substrate::new(44, 38, "KILT", "KILT")), + supported: true, + }, + ), + ( + constants::ALTAIR, + ChainInfo { + factory: || Box::new(substrate::Substrate::new(42, 136, "ALTAIR", "Altair")), + supported: true, + }, + ), + ( + constants::DOGE, + ChainInfo { + factory: || { + Box::new(btc::BTC::new_legacy_btc_based(12, 0x1E, "DOGE", "Dogecoin")) + }, + supported: false, + }, + ), + ( + constants::DASH, + ChainInfo { + factory: || Box::new(btc::BTC::new_legacy_btc_based(11, 0x4C, "DASH", "Dash")), + supported: false, + }, + ), + ( + constants::XRP, + ChainInfo { + factory: || Box::new(xrp::XRP::new()), + supported: false, + }, + ), + ( + constants::DGB, + ChainInfo { + factory: || Box::new(btc::BTC::new_btc_based(16, "dgb", "DGB", "Digibyte")), + supported: false, + }, + ), + ( + constants::COSMOS, + ChainInfo { + factory: || Box::new(atom::ATOM::new()), + supported: false, + }, + ), + ( + constants::CELESTIA, + ChainInfo { + factory: || { + Box::new(atom::ATOM::new_cosmos_based( + "celestia", "celestia", "Celestia", "TIA", + )) + }, + supported: false, + }, + ), + ( + constants::CUDOS, + ChainInfo { + factory: || { + Box::new(atom::ATOM::new_cosmos_based( + "cudos", "cudos-1", "Cudos", "CUDOS", + )) + }, + supported: false, + }, + ), + ( + constants::AURA, + ChainInfo { + factory: || { + Box::new(atom::ATOM::new_cosmos_based( + "aura", "xstaxy-1", "Aura", "AURA", + )) + }, + supported: false, + }, + ), + ( + constants::ICP, + ChainInfo { + factory: || Box::new(icp::ICP {}), + supported: false, + }, + ), + ( + constants::SOL, + ChainInfo { + factory: || Box::new(sol::SOL {}), + supported: false, + }, + ), + ( + constants::MOVR, + ChainInfo { + factory: || Box::new(movr::MOVR::new()), + supported: true, + }, + ), + ( + constants::GLMR, + ChainInfo { + factory: || Box::new(movr::MOVR::new_glmr()), + supported: true, + }, + ), + ( + constants::BNB, + ChainInfo { + factory: || Box::new(bnb::BNB {}), + supported: false, + }, + ), + ( + constants::BCH, + ChainInfo { + factory: || Box::new(bch::BCH {}), + supported: false, + }, + ), + ( + constants::ADA, + ChainInfo { + factory: || Box::new(ada::ADA {}), + supported: false, + }, + ), + ( + constants::SUI, + ChainInfo { + factory: || Box::new(sui::SUI {}), + supported: true, + }, + ), + ( + constants::APT, + ChainInfo { + factory: || Box::new(apt::APT {}), + supported: false, + }, + ), + ( + constants::AVAIL, + ChainInfo { + factory: || Box::new(substrate::Substrate::new(62, 42, "AVAIL", "Avail")), + supported: true, + }, + ), + ( + constants::ROLLUX, + ChainInfo { + factory: || Box::new(eth::ETH::new_eth_based(63, 570, "ROLLUX", "Rollux")), + supported: true, + }, + ), + ( + constants::AVAX, + ChainInfo { + factory: || Box::new(eth::ETH::new_eth_based(39, 43114, "AVAX", "Avalanche")), + supported: true, + }, + ), + ( + constants::ARB, + ChainInfo { + factory: || Box::new(eth::ETH::new_eth_based(57, 42161, "ARB", "Arbitrum")), + supported: true, + }, + ), + ( + constants::BASE, + ChainInfo { + factory: || Box::new(eth::ETH::new_eth_based(60, 8453, "BASE", "Base")), + supported: true, + }, + ), + ( + constants::NEAR, + ChainInfo { + factory: || Box::new(eth::ETH::new_eth_based(64, 397, "NEAR", "Near")), + supported: true, + }, + ), + ( + constants::FTM, + ChainInfo { + factory: || Box::new(eth::ETH::new_eth_based(54, 250, "FTM", "Fantom")), + supported: true, + }, + ), + ( + constants::CHZ, + ChainInfo { + factory: || Box::new(eth::ETH::new_eth_based(61, 88888, "CHZ", "Chiliz")), + supported: true, + }, + ), + ( + constants::OP, + ChainInfo { + factory: || Box::new(eth::ETH::new_eth_based(53, 10, "OP", "Optimism")), + supported: true, + }, + ), + ( + constants::POLYGON_ZKEVM, + ChainInfo { + factory: || { + Box::new(eth::ETH::new_eth_based(52, 1101, "ZKEVM", "Polygon zkEVM")) + }, + supported: true, + }, + ), + ( + constants::STOLZ, + ChainInfo { + factory: || Box::new(eth::ETH::new_eth_based(67, 2344, "STOLZ", "Stolz")), + supported: true, + }, + ), ]; Self { @@ -403,17 +633,17 @@ impl ChainRegistry { } fn get_chain_by_id(&self, id: u32) -> Option> { - for &(chain_id, factory) in self.registry { + for &(chain_id, ref chain_info) in self.registry { if chain_id == id { - return Some(factory()); + return Some((chain_info.factory)()); } } None } fn get_chain_by_base_id(&self, base_id: u32) -> Option> { - for &(_, factory) in self.registry { - let chain = factory(); + for &(_, ref chain_info) in self.registry { + let chain = (chain_info.factory)(); if chain.get_id() == base_id { return Some(chain); } @@ -423,12 +653,33 @@ impl ChainRegistry { fn get_chains(&self) -> Vec { let mut ids = Vec::new(); - for &(_, factory) in self.registry { - let chain = factory(); + for &(_, ref chain_info) in self.registry { + let chain = (chain_info.factory)(); ids.push(chain.get_id()); } ids } + + fn is_chain_supported(&self, id: u32) -> bool { + for &(_, ref chain_info) in self.registry { + let chain = (chain_info.factory)(); + if chain.get_id() == id { + return chain_info.supported; + } + } + false + } + + fn get_supported_chains(&self) -> Vec { + let mut ids = Vec::new(); + for &(_, ref chain_info) in self.registry { + let chain = (chain_info.factory)(); + if chain_info.supported { + ids.push(chain.get_id()); + } + } + ids + } } pub fn get_chain_by_id(id: u32) -> Option> { @@ -463,3 +714,11 @@ pub fn get_chain_by_base_id(base_id: u32) -> Option> { pub fn get_chains() -> Vec { ChainRegistry::new().get_chains() } + +pub fn is_chain_supported(id: u32) -> bool { + ChainRegistry::new().is_chain_supported(id) +} + +pub fn get_supported_chains() -> Vec { + ChainRegistry::new().get_supported_chains() +} From 4f7194912c098ddda316deb06c8e0253ceb3f798 Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Tue, 7 Jan 2025 09:31:55 -0300 Subject: [PATCH 38/42] fix: lint issues --- packages/kos/src/chains/bch/mod.rs | 3 --- packages/kos/src/chains/klv/models.rs | 3 --- packages/kos/src/chains/mod.rs | 12 ++++++------ packages/kos/src/crypto/bignum.rs | 1 - 4 files changed, 6 insertions(+), 13 deletions(-) diff --git a/packages/kos/src/chains/bch/mod.rs b/packages/kos/src/chains/bch/mod.rs index cd20eea..3d7519e 100644 --- a/packages/kos/src/chains/bch/mod.rs +++ b/packages/kos/src/chains/bch/mod.rs @@ -16,7 +16,6 @@ pub struct BCH {} impl BCH { #[allow(clippy::needless_range_loop)] - fn expand_prefix(prefix: &str) -> Result, ChainError> { let mut prefix_bytes = prefix.as_bytes().to_vec(); for i in 0..prefix_bytes.len() { @@ -28,7 +27,6 @@ impl BCH { } #[allow(clippy::needless_range_loop)] - fn create_checksum(prefix: &str, payload: &[u8]) -> Result, ChainError> { let expanded_prefix = BCH::expand_prefix(prefix)?; let to_encode = [expanded_prefix, payload.to_vec(), vec![0u8; 8]].concat(); @@ -114,7 +112,6 @@ impl Chain for BCH { } #[allow(clippy::needless_range_loop)] - fn get_address(&self, public_key: Vec) -> Result { if public_key.len() != 33 { return Err(ChainError::InvalidPublicKey); diff --git a/packages/kos/src/chains/klv/models.rs b/packages/kos/src/chains/klv/models.rs index 8a5f87c..bf98ebd 100644 --- a/packages/kos/src/chains/klv/models.rs +++ b/packages/kos/src/chains/klv/models.rs @@ -131,7 +131,6 @@ impl TryFrom for proto::transaction::Raw { type Error = ConversionError; #[allow(clippy::needless_update)] - fn try_from(value: chains::klv::models::Raw) -> Result { let contracts = value .contract @@ -197,7 +196,6 @@ impl TryFrom for protos::Any { type Error = ConversionError; #[allow(clippy::needless_update)] - fn try_from(value: chains::klv::models::Parameter) -> Result { let proto_parameter = protos::Any { type_url: value.type_url, @@ -213,7 +211,6 @@ impl TryFrom for proto::transaction::KdaFee { type Error = ConversionError; #[allow(clippy::needless_update)] - fn try_from(value: chains::klv::models::KdaFee) -> Result { let kda_bytes = simple_base64_decode(&value.kda).map_err(|_| ConversionError::Base64Error)?; diff --git a/packages/kos/src/chains/mod.rs b/packages/kos/src/chains/mod.rs index d832033..3914f5c 100644 --- a/packages/kos/src/chains/mod.rs +++ b/packages/kos/src/chains/mod.rs @@ -642,7 +642,7 @@ impl ChainRegistry { } fn get_chain_by_base_id(&self, base_id: u32) -> Option> { - for &(_, ref chain_info) in self.registry { + for (_, chain_info) in self.registry { let chain = (chain_info.factory)(); if chain.get_id() == base_id { return Some(chain); @@ -653,7 +653,7 @@ impl ChainRegistry { fn get_chains(&self) -> Vec { let mut ids = Vec::new(); - for &(_, ref chain_info) in self.registry { + for (_, chain_info) in self.registry { let chain = (chain_info.factory)(); ids.push(chain.get_id()); } @@ -661,7 +661,7 @@ impl ChainRegistry { } fn is_chain_supported(&self, id: u32) -> bool { - for &(_, ref chain_info) in self.registry { + for (_, chain_info) in self.registry { let chain = (chain_info.factory)(); if chain.get_id() == id { return chain_info.supported; @@ -672,7 +672,7 @@ impl ChainRegistry { fn get_supported_chains(&self) -> Vec { let mut ids = Vec::new(); - for &(_, ref chain_info) in self.registry { + for (_, chain_info) in self.registry { let chain = (chain_info.factory)(); if chain_info.supported { ids.push(chain.get_id()); @@ -694,7 +694,7 @@ pub enum CustomChainType { } pub fn get_chain_by_params(params: CustomChainType) -> Option> { - return match params { + match params { CustomChainType::NotCustom(c) => get_chain_by_id(c), CustomChainType::CustomEth(chaincode) => Some(Box::new(eth::ETH::new_eth_based( 0, @@ -704,7 +704,7 @@ pub fn get_chain_by_params(params: CustomChainType) -> Option> { ))), CustomChainType::CustomSubstrate(_) => None, CustomChainType::CustomCosmos(_) => None, - }; + } } pub fn get_chain_by_base_id(base_id: u32) -> Option> { diff --git a/packages/kos/src/crypto/bignum.rs b/packages/kos/src/crypto/bignum.rs index c2487ba..ea4aa87 100644 --- a/packages/kos/src/crypto/bignum.rs +++ b/packages/kos/src/crypto/bignum.rs @@ -50,7 +50,6 @@ impl U256 { } #[allow(clippy::needless_range_loop)] - pub fn to_f64(&self, precision: u32) -> f64 { let bytes = self.0; let mut value: f64 = 0.0; From a4b07178b4c06141c8c9faa7530ee51639b177e7 Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Tue, 7 Jan 2025 16:40:12 -0300 Subject: [PATCH 39/42] chore: set MOVR and GLMR as eth based --- packages/kos/src/chains/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/kos/src/chains/mod.rs b/packages/kos/src/chains/mod.rs index 3914f5c..9c92c61 100644 --- a/packages/kos/src/chains/mod.rs +++ b/packages/kos/src/chains/mod.rs @@ -500,14 +500,14 @@ impl ChainRegistry { ( constants::MOVR, ChainInfo { - factory: || Box::new(movr::MOVR::new()), + factory: || Box::new(eth::ETH::new_eth_based(32, 1285, "MOVR", "Moonriver")), supported: true, }, ), ( constants::GLMR, ChainInfo { - factory: || Box::new(movr::MOVR::new_glmr()), + factory: || Box::new(eth::ETH::new_eth_based(34, 1284, "GLMR", "Moonbeam")), supported: true, }, ), From e3990c6d393bd86ac569c539486141bd9e587b4e Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Tue, 7 Jan 2025 16:48:04 -0300 Subject: [PATCH 40/42] fix: lint warn --- packages/kos/src/chains/movr/mod.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/kos/src/chains/movr/mod.rs b/packages/kos/src/chains/movr/mod.rs index 23f1e61..54d13fd 100644 --- a/packages/kos/src/chains/movr/mod.rs +++ b/packages/kos/src/chains/movr/mod.rs @@ -17,6 +17,7 @@ pub struct MOVR { } impl MOVR { + #[allow(dead_code)] pub fn new() -> Self { MOVR { id: 32, @@ -26,6 +27,7 @@ impl MOVR { } } + #[allow(dead_code)] pub fn new_glmr() -> Self { MOVR { id: 34, From 7c6cb054e3c32899e9c037844e5739678ce58e01 Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Wed, 8 Jan 2025 21:11:42 -0300 Subject: [PATCH 41/42] feat: BTC sign transaction --- Cargo.lock | 103 +++++++++- deny.toml | 20 +- packages/kos-mobile/src/lib.rs | 1 + packages/kos-web/src/wallet.rs | 1 + packages/kos/Cargo.toml | 3 +- packages/kos/src/chains/btc/mod.rs | 102 +++++++++- packages/kos/src/chains/btc/models.rs | 266 -------------------------- packages/kos/src/chains/eth/mod.rs | 3 + packages/kos/src/chains/klv/mod.rs | 1 + packages/kos/src/chains/mod.rs | 35 +++- packages/kos/src/chains/movr/mod.rs | 133 ------------- packages/kos/src/chains/trx/mod.rs | 1 + 12 files changed, 234 insertions(+), 435 deletions(-) delete mode 100644 packages/kos/src/chains/btc/models.rs delete mode 100644 packages/kos/src/chains/movr/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 17a57b9..c35b239 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -454,6 +454,16 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" +[[package]] +name = "base58ck" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c8d66485a3a2ea485c1913c4572ce0256067a5377ac8c75c4960e1cda98605f" +dependencies = [ + "bitcoin-internals", + "bitcoin_hashes", +] + [[package]] name = "base64" version = "0.13.1" @@ -493,6 +503,12 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" +[[package]] +name = "bech32" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d965446196e3b7decd44aa7ee49e31d630118f90ef12f97900f262eb915c951d" + [[package]] name = "bincode" version = "1.3.3" @@ -526,6 +542,54 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" +[[package]] +name = "bitcoin" +version = "0.32.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6bc65742dea50536e35ad42492b234c27904a27f0abdcbce605015cb4ea026" +dependencies = [ + "base58ck", + "bech32 0.11.0", + "bitcoin-internals", + "bitcoin-io", + "bitcoin-units", + "bitcoin_hashes", + "hex-conservative", + "hex_lit", + "secp256k1", +] + +[[package]] +name = "bitcoin-internals" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30bdbe14aa07b06e6cfeffc529a1f099e5fbe249524f8125358604df99a4bed2" + +[[package]] +name = "bitcoin-io" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b47c4ab7a93edb0c7198c5535ed9b52b63095f4e9b45279c6736cec4b856baf" + +[[package]] +name = "bitcoin-units" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5285c8bcaa25876d07f37e3d30c303f2609179716e11d688f51e8f1fe70063e2" +dependencies = [ + "bitcoin-internals", +] + +[[package]] +name = "bitcoin_hashes" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb18c03d0db0247e147a21a6faafd5a7eb851c743db062de72018b6b7e8e4d16" +dependencies = [ + "bitcoin-io", + "hex-conservative", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -796,7 +860,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5286a0843c21f8367f7be734f89df9b822e0321d8bcce8d6e735aadff7d74979" dependencies = [ "base64 0.21.7", - "bech32", + "bech32 0.9.1", "bs58", "digest 0.10.7", "generic-array", @@ -1370,12 +1434,27 @@ dependencies = [ "serde", ] +[[package]] +name = "hex-conservative" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5313b072ce3c597065a808dbf612c4c8e8590bdbf8b579508bf7a762c5eae6cd" +dependencies = [ + "arrayvec", +] + [[package]] name = "hex-literal" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" +[[package]] +name = "hex_lit" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3011d1213f159867b13cfd6ac92d2cd5f1345762c63be3554e84092d85a50bbd" + [[package]] name = "hmac" version = "0.8.1" @@ -1554,8 +1633,9 @@ dependencies = [ "aes", "aes-gcm", "alloy-dyn-abi", - "bech32", + "bech32 0.9.1", "bip39-dict", + "bitcoin", "blake2b-ref", "cbc", "cfb-mode", @@ -2437,6 +2517,25 @@ dependencies = [ "zeroize", ] +[[package]] +name = "secp256k1" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9465315bc9d4566e1724f0fffcbcc446268cb522e60f9a27bcded6b19c108113" +dependencies = [ + "bitcoin_hashes", + "secp256k1-sys", +] + +[[package]] +name = "secp256k1-sys" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4387882333d3aa8cb20530a17c69a3752e97837832f34f6dccc760e715001d9" +dependencies = [ + "cc", +] + [[package]] name = "semver" version = "0.11.0" diff --git a/deny.toml b/deny.toml index 1e74ce9..4e88220 100644 --- a/deny.toml +++ b/deny.toml @@ -6,34 +6,20 @@ deny = [ skip = [ { name = "bitflags", version = "=1.3.2" }, # openssl { name = "base64", version = "<=0.22" }, # openssl - { name = "idna", version = "=0.4.0" }, # - { name = "winreg", version = "<=0.52" }, - { name = "http", version = "<=1.1" }, - { name = "http-body", version = "<=1.0.0" }, - { name = "hyper", version = "<=1.3.1" }, - { name = "reqwest", version = "<=0.12.4" }, - { name = "rustls-pemfile", version = "1.0.4" }, { name = "block-buffer", version = "0.9.0" }, { name = "digest", version = "0.9.0" }, { name = "heck", version = "0.4.1" }, { name = "hmac", version = "0.8.1" }, { name = "sha2", version = "0.9.9" }, { name = "syn", version = "1.0.109" }, - { name = "windows-sys", version = "0.52.0" } - - -] -skip-tree = [ - { name = "prost-wkt-types", version = "=0.5.0", depth = 20 }, # prost-wkt-build - { name = "prost-wkt-build", version = "=0.5.0", depth = 20 }, # prost-wkt-build + { name = "windows-sys", version = "0.52.0" }, + { name = "bech32", version = "0.9.1" } ] [sources] unknown-registry = "deny" unknown-git = "deny" -[sources.allow-org] -github = ["klever-io"] [licenses] confidence-threshold = 0.8 @@ -45,9 +31,7 @@ allow = [ "BSD-3-Clause", "BSD-2-Clause", "CC0-1.0", - "ISC", "MPL-2.0", - "OpenSSL", ] exceptions = [ { name = "unicode-ident", allow = ["Unicode-DFS-2016"] }, diff --git a/packages/kos-mobile/src/lib.rs b/packages/kos-mobile/src/lib.rs index 7f66379..16600be 100644 --- a/packages/kos-mobile/src/lib.rs +++ b/packages/kos-mobile/src/lib.rs @@ -143,6 +143,7 @@ fn sign_transaction(account: KOSAccount, raw: String) -> Result, tx: Transaction) -> Result { let mut tx = tx; - let mut btc_tx = models::BTCTransaction::from_raw(&tx.raw_data.clone())?; - btc_tx.sign(&private_key)?; + let options = tx.options.clone().ok_or(ChainError::MissingOptions)?; + + let (prev_scripts, input_amounts) = match options { + ChainOptions::BTC { + prev_scripts, + input_amounts, + } => (prev_scripts, input_amounts), + _ => { + return Err(ChainError::InvalidOptions); + } + }; + + let transaction: bitcoin::Transaction = + bitcoin::consensus::deserialize(tx.raw_data.as_ref()).unwrap(); + + let mut psbt = Psbt::from_unsigned_tx(transaction.clone()).unwrap(); + + let mut cache = sighash::SighashCache::new(transaction); + + let sk = secp256k1::SecretKey::from_slice(private_key.clone().as_slice()).unwrap(); + + let btc = BTC::new(); + let pk = btc.get_pbk(private_key)?; + + let public_key = bitcoin::PublicKey::from_slice(pk.as_slice()).unwrap(); + + let secp = bitcoin::secp256k1::Secp256k1::new(); + + let values = input_amounts + .iter() + .map(|x| Amount::from_str_in(&x.to_string(), Denomination::Satoshi).unwrap()) + .collect::>(); - tx.raw_data = btc_tx.serialize(); + for inp_idx in 0..psbt.inputs.len() { + let utxo = bitcoin::TxOut { + value: values[inp_idx], + script_pubkey: prev_scripts[inp_idx].clone().into(), + }; + psbt.inputs[inp_idx].witness_utxo = Some(utxo); + } + + // sign inputs + for inp_idx in 0..psbt.inputs.len() { + // compute sighash + let (msg, sighash_ty) = psbt.sighash_ecdsa(inp_idx, &mut cache).unwrap(); + + // sign + let sig = ecdsa::Signature { + signature: secp.sign_ecdsa(&msg, &sk), + sighash_type: sighash_ty, + }; + + // insert signature + psbt.inputs[inp_idx].partial_sigs.insert(public_key, sig); + } + + // finalize + for inp_idx in 0..psbt.inputs.len() { + let script_witness = { + match psbt.inputs[inp_idx].partial_sigs.first_key_value() { + Some((pubkey, sig)) => { + let mut script_witness = bitcoin::Witness::new(); + script_witness.push(sig.to_vec()); + script_witness.push(pubkey.to_bytes()); + script_witness + } + _ => bitcoin::Witness::default(), + } + }; + psbt.inputs[inp_idx].final_script_witness = Some(script_witness); + } + + let signed_tx = psbt.extract_tx().unwrap(); + + tx.raw_data = bitcoin::consensus::encode::serialize(&signed_tx); + + tx.signature = bitcoin::consensus::encode::serialize(&signed_tx.compute_wtxid()); + + tx.tx_hash = bitcoin::consensus::encode::serialize(&signed_tx.compute_txid()); Ok(tx) } @@ -240,8 +314,8 @@ mod test { } #[test] - fn decoded_and_sign_transaction() { - let raw = hex::decode("0100000001a3727243402a869948ccf6d1b61e9b7eabacaa1c1301fcef743bc59ba14664340100000000ffffffff021027000000000000225120236c88c2ba0bdaa1506c42168453629e33a7dbb203e310b069bb22bf67350d2c91c7470000000000160014dc6bf86354105de2fcd9868a2b0376d6731cb92f000000000100000001a3727243402a869948ccf6d1b61e9b7eabacaa1c1301fcef743bc59ba14664340100000000ffffffff021027000000000000225120236c88c2ba0bdaa1506c42168453629e33a7dbb203e310b069bb22bf67350d2c91c7470000000000160014dc6bf86354105de2fcd9868a2b0376d6731cb92f00000000").unwrap(); + fn sign_transaction() { + let raw = hex::decode("0100000002badfa0606bc6a1738d8ddf951b1ebf9e87779934a5774b836668efb5a6d643970000000000fffffffffe60fbeb66791b10c765a207c900a08b2a9bd7ef21e1dd6e5b2ef1e9d686e5230000000000ffffffff028813000000000000160014e4132ab9175345e24b344f50e6d6764a651a89e6c21f000000000000160014546d5f8e86641e4d1eec5b9155a540d953245e4a00000000").unwrap(); let pvk = hex::decode("4604b4b710fe91f584fff084e1a9159fe4f8408fff380596a604948474ce4fa3") .unwrap(); @@ -250,9 +324,19 @@ mod test { raw_data: raw, signature: vec![], tx_hash: vec![], + options: Option::from(ChainOptions::BTC { + prev_scripts: vec![ + hex::decode("0014546d5f8e86641e4d1eec5b9155a540d953245e4a").unwrap(), + hex::decode("0014546d5f8e86641e4d1eec5b9155a540d953245e4a").unwrap(), + ], + input_amounts: vec![5000, 10000], + }), }; let signed_tx = btc.sign_tx(pvk, transaction).unwrap(); - assert_eq!(signed_tx.raw_data.len(), 229); + + assert_eq!(signed_tx.signature.len(), 32); + assert_eq!(signed_tx.tx_hash.len(), 32); + assert_eq!(signed_tx.raw_data.len(), 372); } } diff --git a/packages/kos/src/chains/btc/models.rs b/packages/kos/src/chains/btc/models.rs deleted file mode 100644 index 20717da..0000000 --- a/packages/kos/src/chains/btc/models.rs +++ /dev/null @@ -1,266 +0,0 @@ -use crate::chains::util::{private_key_from_vec, slice_from_vec}; -use crate::chains::ChainError; -use crate::crypto::hash::sha256_digest; -use crate::crypto::secp256k1::{Secp256K1, Secp256k1Trait}; - -#[derive(Debug, Clone)] -pub struct BTCTransaction { - pub version: u32, - pub lock_time: u32, - pub inputs: Vec, - pub outputs: Vec, -} - -#[derive(Debug, Clone)] -pub struct Input { - pub txid: [u8; 32], - pub vout: u32, - pub script_sig: Vec, - pub sequence: u32, - pub witness: Vec>, -} - -#[derive(Debug, Clone)] -pub struct Output { - pub value: u64, - pub script_pubkey: Vec, -} - -impl BTCTransaction { - pub fn sign(&mut self, private_key: &[u8]) -> Result<(), ChainError> { - let hash_type = 1; // SIGHASH_ALL - - let outputs = self.outputs.clone(); - let inputs_data: Vec<_> = self - .inputs - .iter() - .enumerate() - .map(|(i, input)| { - let script_pubkey = outputs[input.vout as usize].script_pubkey.clone(); - let hash = self.calculate_segwit_hash(i, &script_pubkey)?; - Ok((hash, script_pubkey)) - }) - .collect::>()?; - - for (input, (hash, _script_pubkey)) in self.inputs.iter_mut().zip(inputs_data) { - let pvk_bytes = private_key_from_vec(private_key)?; - let payload_bytes = slice_from_vec(&hash)?; - - let mut sig = Secp256K1::sign(&payload_bytes, &pvk_bytes)?.to_vec(); - - sig.push(hash_type as u8); - - let pbk = Secp256K1::private_to_public_compressed(&pvk_bytes)?; - - input.witness = vec![sig, pbk.to_vec()]; - input.script_sig.clear(); - } - - Ok(()) - } - - fn calculate_segwit_hash( - &self, - input_index: usize, - script_pubkey: &[u8], - ) -> Result<[u8; 32], ChainError> { - let mut hash_prevouts = Vec::new(); - let mut hash_sequence = Vec::new(); - - for input in &self.inputs { - hash_prevouts.extend(&input.txid); - hash_prevouts.extend(&input.vout.to_le_bytes()); - } - let hash_prevouts = sha256_digest(&sha256_digest(&hash_prevouts)); - - for input in &self.inputs { - hash_sequence.extend(&input.sequence.to_le_bytes()); - } - let hash_sequence = sha256_digest(&sha256_digest(&hash_sequence)); - - let input = &self.inputs[input_index]; - let mut input_data: Vec = Vec::new(); - input_data.extend(&input.txid); - input_data.extend(&input.vout.to_le_bytes()); - input_data.extend(&(script_pubkey.len() as u64).to_le_bytes()); - input_data.extend(script_pubkey); - input_data.extend(&input.sequence.to_le_bytes()); - - let mut hash_outputs = Vec::new(); - for output in &self.outputs { - hash_outputs.extend(&output.value.to_le_bytes()); - hash_outputs.extend(&(output.script_pubkey.len() as u64).to_le_bytes()); - hash_outputs.extend(&output.script_pubkey); - } - let hash_outputs = sha256_digest(&sha256_digest(&hash_outputs)); - - let mut tx_hash_buffer = Vec::new(); - tx_hash_buffer.extend(&self.version.to_le_bytes()); - tx_hash_buffer.extend(&hash_prevouts); - tx_hash_buffer.extend(&hash_sequence); - tx_hash_buffer.extend(input_data); - tx_hash_buffer.extend(&hash_outputs); - tx_hash_buffer.extend(&self.lock_time.to_le_bytes()); - tx_hash_buffer.extend(&(1u32.to_le_bytes())); // hash type - - Ok(sha256_digest(&sha256_digest(&tx_hash_buffer))) - } - - pub fn from_raw(raw: &[u8]) -> Result { - let mut cursor = raw; - - let version = read_u32(&mut cursor)?; - let input_count = read_varint(&mut cursor)?; - let mut inputs = Vec::new(); - - for _ in 0..input_count { - let mut txid = [0u8; 32]; - txid.copy_from_slice(&cursor[..32]); - cursor = &cursor[32..]; - - let vout = read_u32(&mut cursor)?; - let script_sig_len = read_varint(&mut cursor)?; - let script_sig = cursor[..script_sig_len as usize].to_vec(); - cursor = &cursor[script_sig_len as usize..]; - - let sequence = read_u32(&mut cursor)?; - - inputs.push(Input { - txid, - vout, - script_sig, - sequence, - witness: Vec::new(), - }); - } - - let output_count = read_varint(&mut cursor)?; - let mut outputs = Vec::new(); - - for _ in 0..output_count { - let value = read_u64(&mut cursor)?; - let script_pubkey_len = read_varint(&mut cursor)?; - let script_pubkey = cursor[..script_pubkey_len as usize].to_vec(); - cursor = &cursor[script_pubkey_len as usize..]; - - outputs.push(Output { - value, - script_pubkey, - }); - } - - let lock_time = read_u32(&mut cursor)?; - - Ok(Self { - version, - lock_time, - inputs, - outputs, - }) - } - - pub fn serialize(&self) -> Vec { - let mut raw_tx = Vec::new(); - - raw_tx.extend(&self.version.to_le_bytes()); - - let is_segwit = self.inputs.iter().any(|input| !input.witness.is_empty()); - - if is_segwit { - // Add SegWit marker and flag - raw_tx.push(0x00); // Marker - raw_tx.push(0x01); // Flag - } - - raw_tx.push(self.inputs.len() as u8); - for input in &self.inputs { - raw_tx.extend(&input.txid); - raw_tx.extend(&input.vout.to_le_bytes()); - raw_tx.push(input.script_sig.len() as u8); - raw_tx.extend(&input.script_sig); - raw_tx.extend(&input.sequence.to_le_bytes()); - } - - raw_tx.push(self.outputs.len() as u8); - for output in &self.outputs { - raw_tx.extend(&output.value.to_le_bytes()); - raw_tx.push(output.script_pubkey.len() as u8); - raw_tx.extend(&output.script_pubkey); - } - - if is_segwit { - for input in &self.inputs { - raw_tx.push(input.witness.len() as u8); - for item in &input.witness { - raw_tx.push(item.len() as u8); - raw_tx.extend(item); - } - } - } - - raw_tx.extend(&self.lock_time.to_le_bytes()); - - raw_tx - } -} - -fn read_u32(cursor: &mut &[u8]) -> Result { - if cursor.len() < 4 { - return Err(ChainError::InvalidData("Insufficient bytes for u32".into())); - } - let value = u32::from_le_bytes(cursor[..4].try_into().unwrap()); - *cursor = &cursor[4..]; - Ok(value) -} - -fn read_u64(cursor: &mut &[u8]) -> Result { - if cursor.len() < 8 { - return Err(ChainError::InvalidData("Buffer underflow".into())); - } - let value = u64::from_le_bytes(cursor[..8].try_into().unwrap()); - *cursor = &cursor[8..]; - Ok(value) -} - -fn read_varint(cursor: &mut &[u8]) -> Result { - if cursor.is_empty() { - return Err(ChainError::InvalidData("Empty cursor for varint".into())); - } - - let first = cursor[0]; - *cursor = &cursor[1..]; - - match first { - 0xFF => { - if cursor.len() < 8 { - return Err(ChainError::InvalidData( - "Insufficient bytes for varint u64".into(), - )); - } - let value = u64::from_le_bytes(cursor[..8].try_into().unwrap()); - *cursor = &cursor[8..]; - Ok(value) - } - 0xFE => { - if cursor.len() < 4 { - return Err(ChainError::InvalidData( - "Insufficient bytes for varint u32".into(), - )); - } - let value = u32::from_le_bytes(cursor[..4].try_into().unwrap()) as u64; - *cursor = &cursor[4..]; - Ok(value) - } - 0xFD => { - if cursor.len() < 2 { - return Err(ChainError::InvalidData( - "Insufficient bytes for varint u16".into(), - )); - } - let value = u16::from_le_bytes(cursor[..2].try_into().unwrap()) as u64; - *cursor = &cursor[2..]; - Ok(value) - } - _ => Ok(first as u64), - } -} diff --git a/packages/kos/src/chains/eth/mod.rs b/packages/kos/src/chains/eth/mod.rs index 6718427..a290c74 100644 --- a/packages/kos/src/chains/eth/mod.rs +++ b/packages/kos/src/chains/eth/mod.rs @@ -9,6 +9,7 @@ use crate::crypto::{bip32, secp256k1}; use alloc::format; use alloc::string::{String, ToString}; use alloc::vec::Vec; +#[cfg(not(feature = "ksafe"))] use alloy_dyn_abi::TypedData; pub(crate) const ETH_ADDR_SIZE: usize = 20; @@ -229,6 +230,7 @@ mod test { raw_data: raw_tx, tx_hash: Vec::new(), signature: Vec::new(), + options: None, }; let _ = eth.sign_tx(pvk, tx).unwrap(); @@ -245,6 +247,7 @@ mod test { raw_data: raw_tx, tx_hash: Vec::new(), signature: Vec::new(), + options: None, }; let _ = eth.sign_tx(pvk, tx).unwrap(); diff --git a/packages/kos/src/chains/klv/mod.rs b/packages/kos/src/chains/klv/mod.rs index 0f0ba5b..e938d8f 100644 --- a/packages/kos/src/chains/klv/mod.rs +++ b/packages/kos/src/chains/klv/mod.rs @@ -218,6 +218,7 @@ mod test { raw_data: raw_tx, tx_hash: Vec::new(), signature: Vec::new(), + options: None, }; let result_tx = crate::chains::klv::KLV {}.sign_tx(pvk, tx).unwrap(); diff --git a/packages/kos/src/chains/mod.rs b/packages/kos/src/chains/mod.rs index 9c92c61..3c3397d 100644 --- a/packages/kos/src/chains/mod.rs +++ b/packages/kos/src/chains/mod.rs @@ -27,7 +27,6 @@ pub mod egld; mod eth; mod icp; pub mod klv; -mod movr; mod sol; mod substrate; mod sui; @@ -57,6 +56,8 @@ pub enum ChainError { CipherError(String), InvalidString(String), InvalidData(String), + MissingOptions, + InvalidOptions, } impl Display for ChainError { @@ -116,6 +117,12 @@ impl Display for ChainError { ChainError::InvalidData(e) => { write!(f, "invalid data: {}", e) } + ChainError::MissingOptions => { + write!(f, "missing option") + } + ChainError::InvalidOptions => { + write!(f, "invalid option") + } } } } @@ -168,8 +175,8 @@ impl From for ChainError { } } -impl From for ChainError { - fn from(_: tiny_json_rs::serializer::DecodeError) -> Self { +impl From for ChainError { + fn from(_: serializer::DecodeError) -> Self { ChainError::ProtoDecodeError } } @@ -204,6 +211,8 @@ impl ChainError { ChainError::CipherError(_) => 18, ChainError::InvalidString(_) => 19, ChainError::InvalidData(_) => 20, + ChainError::MissingOptions => 21, + ChainError::InvalidOptions => 22, } } } @@ -214,8 +223,8 @@ pub enum TxType { TriggerContract, } -impl tiny_json_rs::serializer::Serialize for TxType { - fn serialize(&self) -> tiny_json_rs::mapper::Value { +impl serializer::Serialize for TxType { + fn serialize(&self) -> mapper::Value { let str = match self { TxType::Unknown => "Unknown", TxType::Transfer => "Transfer", @@ -226,7 +235,7 @@ impl tiny_json_rs::serializer::Serialize for TxType { literal: str.to_string(), }; - tiny_json_rs::mapper::Value::Token(token) + mapper::Value::Token(token) } } @@ -242,6 +251,19 @@ pub struct Transaction { pub raw_data: Vec, pub tx_hash: Vec, pub signature: Vec, + pub options: Option, +} + +#[derive(Clone)] +pub enum ChainOptions { + EVM { + chain_id: u32, + network_type: u32, + }, + BTC { + prev_scripts: Vec>, + input_amounts: Vec, + }, } #[allow(dead_code)] @@ -252,6 +274,7 @@ impl Transaction { raw_data: Vec::new(), tx_hash: Vec::new(), signature: Vec::new(), + options: None, } } } diff --git a/packages/kos/src/chains/movr/mod.rs b/packages/kos/src/chains/movr/mod.rs deleted file mode 100644 index 54d13fd..0000000 --- a/packages/kos/src/chains/movr/mod.rs +++ /dev/null @@ -1,133 +0,0 @@ -use crate::chains::eth::ETH; -use crate::chains::util::{private_key_from_vec, slice_from_vec}; -use crate::chains::{Chain, ChainError, Transaction}; -use crate::crypto::hash::keccak256_digest; -use crate::crypto::secp256k1::{Secp256K1, Secp256k1Trait}; -use crate::crypto::{bip32, secp256k1}; -use alloc::format; -use alloc::string::{String, ToString}; -use alloc::vec::Vec; - -#[allow(clippy::upper_case_acronyms)] -pub struct MOVR { - id: u32, - name: String, - symbol: String, - decimals: u32, -} - -impl MOVR { - #[allow(dead_code)] - pub fn new() -> Self { - MOVR { - id: 32, - name: "Moonriver".to_string(), - symbol: "MOVR".to_string(), - decimals: 18, - } - } - - #[allow(dead_code)] - pub fn new_glmr() -> Self { - MOVR { - id: 34, - name: "Moonbeam".to_string(), - symbol: "GLMR".to_string(), - decimals: 18, - } - } -} - -impl Chain for MOVR { - fn get_name(&self) -> &str { - &self.name - } - - fn get_symbol(&self) -> &str { - &self.symbol - } - - fn get_decimals(&self) -> u32 { - self.decimals - } - - fn mnemonic_to_seed(&self, mnemonic: String, password: String) -> Result, ChainError> { - Ok(bip32::mnemonic_to_seed(mnemonic, password)?) - } - - fn derive(&self, seed: Vec, path: String) -> Result, ChainError> { - let result = bip32::derive(&seed, path)?; - Ok(Vec::from(result)) - } - - fn get_pbk(&self, private_key: Vec) -> Result, ChainError> { - let pvk = private_key_from_vec(&private_key)?; - - let pbk = Secp256K1::private_to_public_uncompressed(&pvk)?; - Ok(Vec::from(pbk)) - } - - fn get_address(&self, public_key: Vec) -> Result { - let pbk_hash = keccak256_digest(&public_key[1..]); - let mut address_bytes: [u8; crate::chains::eth::ETH_ADDR_SIZE] = - [0; crate::chains::eth::ETH_ADDR_SIZE]; - address_bytes.copy_from_slice(&pbk_hash[12..]); - - ETH::addr_bytes_to_string(address_bytes) - } - - fn sign_tx( - &self, - private_key: Vec, - mut tx: Transaction, - ) -> Result { - let tx_bytes = tx.raw_data.clone(); - let tx_hash = keccak256_digest(&tx_bytes); - - let sig = self.sign_raw(private_key, tx_hash.clone().to_vec())?; - tx.signature = sig; - tx.tx_hash = tx_hash.to_vec(); - - Ok(tx) - } - - fn sign_raw(&self, private_key: Vec, payload: Vec) -> Result, ChainError> { - let mut pvk_bytes = private_key_from_vec(&private_key)?; - let payload_bytes = slice_from_vec(&payload)?; - - let sig = secp256k1::Secp256K1::sign(&payload_bytes, &pvk_bytes)?; - - pvk_bytes.fill(0); - Ok(sig.to_vec()) - } - - fn sign_message(&self, private_key: Vec, message: Vec) -> Result, ChainError> { - if private_key.len() != 32 { - return Err(ChainError::InvalidPrivateKey); - } - - let mut pvk_bytes: [u8; 32] = [0; 32]; - pvk_bytes.copy_from_slice(&private_key[..32]); - - let mut payload_bytes: [u8; 32] = [0; 32]; - payload_bytes.copy_from_slice(&message[..32]); - - let sig = secp256k1::Secp256K1::sign(&payload_bytes, &pvk_bytes)?; - Ok(sig.to_vec()) - } - - fn get_tx_info( - &self, - _raw_tx: Vec, - ) -> Result { - Err(ChainError::NotSupported) - } - - fn get_path(&self, index: u32, _is_legacy: bool) -> String { - format!("m/44'/60'/0'/0/{}", index) - } - - fn get_id(&self) -> u32 { - self.id - } -} diff --git a/packages/kos/src/chains/trx/mod.rs b/packages/kos/src/chains/trx/mod.rs index ba2e325..5d8e5f6 100644 --- a/packages/kos/src/chains/trx/mod.rs +++ b/packages/kos/src/chains/trx/mod.rs @@ -323,6 +323,7 @@ mod test { raw_data: hex_tx, tx_hash: vec![], signature: vec![], + options: None, }; let _tx = crate::chains::trx::TRX {}.sign_tx(pvk, tx).unwrap(); } From 1c1bd2952685910fd39a27bf854bf32aba21a98c Mon Sep 17 00:00:00 2001 From: Pedro Camboim Date: Thu, 9 Jan 2025 18:09:14 -0300 Subject: [PATCH 42/42] feat: added kos-web sign options --- packages/kos-web/src/wallet.rs | 72 ++++++++++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 3 deletions(-) diff --git a/packages/kos-web/src/wallet.rs b/packages/kos-web/src/wallet.rs index 50c696e..0b46425 100644 --- a/packages/kos-web/src/wallet.rs +++ b/packages/kos-web/src/wallet.rs @@ -6,7 +6,8 @@ use strum::{EnumCount, IntoStaticStr}; use crate::error::Error; use crate::utils::unpack; -use kos::chains::{get_chain_by_base_id, Transaction as KosTransaction}; +use kos::chains::{get_chain_by_base_id, ChainOptions, Transaction as KosTransaction}; +use kos::crypto::base64; use wasm_bindgen::prelude::*; #[wasm_bindgen] @@ -32,6 +33,34 @@ pub struct Wallet { path: Option, } +#[wasm_bindgen] +#[derive(Clone)] +pub struct TransactionChainOptions { + #[wasm_bindgen(skip)] + pub data: ChainOptions, +} + +#[wasm_bindgen] +impl TransactionChainOptions { + #[wasm_bindgen(js_name = "newBitcoinSignOptions")] + pub fn new_bitcoin_sign_options( + input_amounts: Vec, + prev_scripts: Vec, + ) -> TransactionChainOptions { + let prev_scripts = prev_scripts + .iter() + .map(|s| base64::simple_base64_decode(s).unwrap_or_default()) + .collect(); + + TransactionChainOptions { + data: ChainOptions::BTC { + prev_scripts, + input_amounts, + }, + } + } +} + #[wasm_bindgen] impl Wallet { #[wasm_bindgen(js_name = "fromMnemonic")] @@ -241,16 +270,23 @@ impl Wallet { } #[wasm_bindgen(js_name = "sign")] - pub fn sign(&self, tx_raw: &[u8]) -> Result { + /// sign transaction with keypair + pub fn sign( + &self, + tx_raw: &[u8], + options: Option, + ) -> Result { match self.private_key { Some(ref pk_hex) => { let pk_bytes = hex::decode(pk_hex)?; + let options = options.map(|o| o.data); + let tx = KosTransaction { raw_data: tx_raw.to_vec(), signature: vec![], tx_hash: vec![], - options: None, + options, }; let chain = get_chain_by_base_id(self.chain) @@ -296,4 +332,34 @@ mod tests { assert_eq!(w1.get_mnemonic(), "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"); assert_eq!(w1.get_path(), "m/44'/690'/0'/0'/0'"); } + + #[test] + fn test_sign_transaction() { + let chain = get_chain_by_base_id(2).unwrap(); + + let w1 = Wallet::from_mnemonic( + 2, + "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string(), + chain.get_path(0, false), + None, + ).unwrap(); + + let sign_options = TransactionChainOptions::new_bitcoin_sign_options( + vec![5000, 10000], + vec![ + "ABRUbV+OhmQeTR7sW5FVpUDZUyReSg==".to_string(), + "ABRUbV+OhmQeTR7sW5FVpUDZUyReSg==".to_string(), + ], + ); + + let raw_tx = hex::decode("0100000002badfa0606bc6a1738d8ddf951b1ebf9e87779934a5774b836668efb5a6d643970000000000fffffffffe60fbeb66791b10c765a207c900a08b2a9bd7ef21e1dd6e5b2ef1e9d686e5230000000000ffffffff028813000000000000160014e4132ab9175345e24b344f50e6d6764a651a89e6c21f000000000000160014546d5f8e86641e4d1eec5b9155a540d953245e4a00000000").unwrap(); + + let signed_tx = w1.sign(&raw_tx, Some(sign_options)).unwrap(); + + assert_eq!(signed_tx.raw_data.len(), 372); + + assert_eq!(signed_tx.tx_hash.len(), 32); + + assert_eq!(signed_tx.signature.len(), 32); + } }