From 6179e10b886aad4e20a44121adbea1c591cdbf13 Mon Sep 17 00:00:00 2001 From: kent-3 <100624004+kent-3@users.noreply.github.com> Date: Fri, 26 Apr 2024 04:48:22 -0400 Subject: [PATCH 1/7] add image to README --- README.md | 4 ++++ banner.webp | Bin 0 -> 104562 bytes 2 files changed, 4 insertions(+) create mode 100644 banner.webp diff --git a/README.md b/README.md index 99562df..b91005a 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ +
+ +
+ # Secret Rust _Insert cool description here._ diff --git a/banner.webp b/banner.webp new file mode 100644 index 0000000000000000000000000000000000000000..6ba5a112ed89cd4e59cce40498cfdbf676058c19 GIT binary patch literal 104562 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 Date: Fri, 26 Apr 2024 11:21:32 -0400 Subject: [PATCH 2/7] update README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b91005a..628349d 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ # Secret Rust -_Insert cool description here._ +An extension of [Cosmos Rust](https://github.com/cosmos/cosmos-rust) for [Secret](https://github.com/scrtlabs/SecretNetwork). ## Crates @@ -25,7 +25,7 @@ _Insert cool description here._ - [x] `proto-build` crate like cosmos-rust and tendermint-rs each have - [x] `secret-sdk-proto` crate that re-exports `cosmos-sdk-proto` and adds secret protobuf structs - [x] `secretrs` crate that re-exports `cosmrs` and adds secret type conversions - - [x] `secret-utils` provide encryption and decryption tools for use with any client +- [x] `secret-utils` provide encryption and decryption tools for use with any client - [ ] `secret-grpc` crate with full gRPC client implementation - [ ] `secret-grpc-gateway` crate with full gRPC-gateway (REST) client implementation From cf584fd8e1a4f3e26e3890c73b1b56fb36318abb Mon Sep 17 00:00:00 2001 From: kent-3 <100624004+kent-3@users.noreply.github.com> Date: Fri, 26 Apr 2024 12:45:32 -0400 Subject: [PATCH 3/7] use Unlicense everywhere --- LICENSE | 201 ------------------------------------ UNLICENSE | 22 ++++ secret-grpc/Cargo.toml | 1 + secret-grpc/LICENSE | 201 ------------------------------------ secret-sdk-proto/Cargo.toml | 2 +- secret-sdk-proto/README.md | 6 +- secret-utils/Cargo.toml | 1 + secretrs/Cargo.toml | 2 +- secretrs/README.md | 6 +- 9 files changed, 32 insertions(+), 410 deletions(-) delete mode 100644 LICENSE create mode 100644 UNLICENSE delete mode 100644 secret-grpc/LICENSE diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 261eeb9..0000000 --- a/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - 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. diff --git a/UNLICENSE b/UNLICENSE new file mode 100644 index 0000000..b3dbff0 --- /dev/null +++ b/UNLICENSE @@ -0,0 +1,22 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/secret-grpc/Cargo.toml b/secret-grpc/Cargo.toml index 91c1a54..f033200 100644 --- a/secret-grpc/Cargo.toml +++ b/secret-grpc/Cargo.toml @@ -2,6 +2,7 @@ name = "secret-grpc" version = "0.1.0" authors = ["Kent"] +license = "Unlicense" edition = "2021" publish = false diff --git a/secret-grpc/LICENSE b/secret-grpc/LICENSE deleted file mode 100644 index 261eeb9..0000000 --- a/secret-grpc/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - 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. diff --git a/secret-sdk-proto/Cargo.toml b/secret-sdk-proto/Cargo.toml index 67fd4ce..4cf5e47 100644 --- a/secret-sdk-proto/Cargo.toml +++ b/secret-sdk-proto/Cargo.toml @@ -2,7 +2,7 @@ name = "secret-sdk-proto" version = "0.1.0" authors = ["Kent"] -license = "Apache-2.0" +license = "Unlicense" repository = "https://github.com/kent-3/secret-rust/tree/main/secret-sdk-proto" description = "Protobuf struct definitions for interacting with Secret" readme = "README.md" diff --git a/secret-sdk-proto/README.md b/secret-sdk-proto/README.md index e6f502a..68c9980 100644 --- a/secret-sdk-proto/README.md +++ b/secret-sdk-proto/README.md @@ -3,7 +3,7 @@ [![Crate][crate-image]][crate-link] [![Docs][docs-image]][docs-link] [![Build Status][build-image]][build-link] -[![Apache 2.0 Licensed][license-image]][license-link] +[![License][license-image]][license-link] ![MSRV][rustc-image] Rust crate for interacting with [Protobufs] defined by [Secret Network]. @@ -23,8 +23,8 @@ This crate is supported on Rust **1.72** or newer. [docs-link]: https://docs.rs/secret-sdk-proto/ [build-image]: https://github.com/kent-3/secret-rust/workflows/secret-sdk-proto/badge.svg [build-link]: https://github.com/kent-3/secret-rust/actions/workflows/secret-sdk-proto.yml -[license-image]: https://img.shields.io/badge/license-Apache2.0-blue.svg -[license-link]: https://github.com/kent-3/secret-rust/blob/master/LICENSE +[license-image]: https://img.shields.io/badge/license-Unlicense-blue.svg +[license-link]: https://github.com/kent-3/secret-rust/blob/master/UNLICENSE [rustc-image]: https://img.shields.io/badge/rustc-1.72+-blue.svg [//]: # "links" [Protobufs]: https://github.com/scrtlabs/SecretNetwork/tree/master/proto/secret diff --git a/secret-utils/Cargo.toml b/secret-utils/Cargo.toml index 3e5904b..64bda8f 100644 --- a/secret-utils/Cargo.toml +++ b/secret-utils/Cargo.toml @@ -1,6 +1,7 @@ [package] name = "secret-utils" version = "0.1.0" +license = "Unlicense" edition = "2021" [dependencies] diff --git a/secretrs/Cargo.toml b/secretrs/Cargo.toml index 34d1f59..97eb96e 100644 --- a/secretrs/Cargo.toml +++ b/secretrs/Cargo.toml @@ -2,7 +2,7 @@ name = "secretrs" version = "0.0.1" authors = ["Kent"] -license = "Apache-2.0" +license = "Unlicense" repository = "https://github.com/kent-3/secret-rust/tree/main/secretrs" description = "" readme = "README.md" diff --git a/secretrs/README.md b/secretrs/README.md index b084160..e4dc6ed 100644 --- a/secretrs/README.md +++ b/secretrs/README.md @@ -3,7 +3,7 @@ [![Crate][crate-image]][crate-link] [![Docs][docs-image]][docs-link] [![Build Status][build-image]][build-link] -[![Apache 2.0 Licensed][license-image]][license-link] +[![License][license-image]][license-link] ![MSRV][rustc-image] ## Examples @@ -24,6 +24,6 @@ This crate is supported on Rust **1.72** or newer. [docs-link]: https://docs.rs/secretrs/ [build-image]: https://github.com/kent-3/secret-rust/workflows/secretrs/badge.svg [build-link]: https://github.com/kent-3/secret-rust/actions/workflows/secretrs.yml -[license-image]: https://img.shields.io/badge/license-Apache2.0-blue.svg -[license-link]: https://github.com/kent-3/secret-rust/blob/master/LICENSE +[license-image]: https://img.shields.io/badge/license-Unlicense-blue.svg +[license-link]: https://github.com/kent-3/secret-rust/blob/master/UNLICENSE [rustc-image]: https://img.shields.io/badge/rustc-1.72+-blue.svg From 19f451140d8f75b0553b7ad4841984f4fabf82da Mon Sep 17 00:00:00 2001 From: kent-3 <100624004+kent-3@users.noreply.github.com> Date: Fri, 26 Apr 2024 13:10:45 -0400 Subject: [PATCH 4/7] prep for crates.io --- Cargo.lock | 5 +++-- secret-utils/Cargo.toml | 6 +++++- secretrs/Cargo.toml | 10 +++++++--- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7e49d98..4e99bca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1923,6 +1923,7 @@ dependencies = [ name = "secret-sdk-proto" version = "0.1.0" dependencies = [ + "bumpalo", "cosmos-sdk-proto", "getrandom", "prost", @@ -1932,7 +1933,7 @@ dependencies = [ [[package]] name = "secret-utils" -version = "0.1.0" +version = "0.0.0" dependencies = [ "aes-siv", "async-trait", @@ -1956,7 +1957,7 @@ dependencies = [ [[package]] name = "secretrs" -version = "0.0.1" +version = "0.0.0" dependencies = [ "base64 0.22.0", "color-eyre", diff --git a/secret-utils/Cargo.toml b/secret-utils/Cargo.toml index 64bda8f..b3f2bff 100644 --- a/secret-utils/Cargo.toml +++ b/secret-utils/Cargo.toml @@ -1,7 +1,11 @@ [package] name = "secret-utils" -version = "0.1.0" +version = "0.0.0" +authors = ["Kent"] license = "Unlicense" +repository = "https://github.com/kent-3/secret-rust/tree/main/secret-utils" +# description = "" +readme = "README.md" edition = "2021" [dependencies] diff --git a/secretrs/Cargo.toml b/secretrs/Cargo.toml index 97eb96e..1463eec 100644 --- a/secretrs/Cargo.toml +++ b/secretrs/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "secretrs" -version = "0.0.1" +version = "0.0.0" authors = ["Kent"] license = "Unlicense" repository = "https://github.com/kent-3/secret-rust/tree/main/secretrs" -description = "" +# description = "" readme = "README.md" categories = ["cryptography", "cryptography::cryptocurrencies"] keywords = ["blockchain", "cosmos"] @@ -24,7 +24,7 @@ required-features = ["grpc"] [dependencies] cosmrs = { version = "0.16.0" } secret-sdk-proto = { version = "0.1.0", default-features = false, path = "../secret-sdk-proto" } -secret-utils = { path = "../secret-utils" } +secret-utils = { version = "0.0.0", path = "../secret-utils" } [features] default = ["bip32"] @@ -52,3 +52,7 @@ tonic-web-wasm-client = "0.5.1" [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] tokio = { version = "1.37", features = ["rt", "sync", "time", "macros"] } tonic = { version = "0.11.0", features = ["tls", "tls-webpki-roots", "transport"] } + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] From 46db45ccda1caa6c451f4cf5c2486f313fd3c0b0 Mon Sep 17 00:00:00 2001 From: kent-3 <100624004+kent-3@users.noreply.github.com> Date: Fri, 26 Apr 2024 13:37:23 -0400 Subject: [PATCH 5/7] move secret-utils inside secretrs --- Cargo.lock | 11 +- secretrs/Cargo.toml | 27 +++- secretrs/examples/contract_query.rs | 6 +- secretrs/examples/encrypt.rs | 30 ++++ secretrs/src/lib.rs | 3 +- secretrs/src/utils/account.rs | 114 +++++++++++++++ secretrs/src/utils/consts.rs | 11 ++ secretrs/src/utils/crypto/cert.rs | 68 +++++++++ secretrs/src/utils/crypto/mod.rs | 173 ++++++++++++++++++++++ secretrs/src/utils/error.rs | 45 ++++++ secretrs/src/utils/mod.rs | 64 ++++++++ secretrs/src/utils/types.rs | 219 ++++++++++++++++++++++++++++ 12 files changed, 764 insertions(+), 7 deletions(-) create mode 100644 secretrs/examples/encrypt.rs create mode 100644 secretrs/src/utils/account.rs create mode 100644 secretrs/src/utils/consts.rs create mode 100644 secretrs/src/utils/crypto/cert.rs create mode 100644 secretrs/src/utils/crypto/mod.rs create mode 100644 secretrs/src/utils/error.rs create mode 100644 secretrs/src/utils/mod.rs create mode 100644 secretrs/src/utils/types.rs diff --git a/Cargo.lock b/Cargo.lock index 4e99bca..459f186 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1959,18 +1959,27 @@ dependencies = [ name = "secretrs" version = "0.0.0" dependencies = [ + "aes-siv", + "async-trait", "base64 0.22.0", + "bip32", + "bip39", "color-eyre", "cosmrs", "hex", + "hkdf", + "nanorand", "regex", + "secret-cosmwasm-std", "secret-sdk-proto", - "secret-utils", "serde", "serde_json", + "sha2 0.10.8", + "thiserror", "tokio", "tonic", "tonic-web-wasm-client", + "x25519-dalek", ] [[package]] diff --git a/secretrs/Cargo.toml b/secretrs/Cargo.toml index 1463eec..4abfbff 100644 --- a/secretrs/Cargo.toml +++ b/secretrs/Cargo.toml @@ -11,6 +11,10 @@ keywords = ["blockchain", "cosmos"] edition = "2021" rust-version = "1.72" +[[example]] +name = "encrypt" +path = "examples/encrypt.rs" + [[example]] name = "query" path = "examples/query.rs" @@ -22,9 +26,30 @@ path = "examples/contract_query.rs" required-features = ["grpc"] [dependencies] + +# blockchain cosmrs = { version = "0.16.0" } secret-sdk-proto = { version = "0.1.0", default-features = false, path = "../secret-sdk-proto" } -secret-utils = { version = "0.0.0", path = "../secret-utils" } +cosmwasm-std = { version = "=1.1.11", package = "secret-cosmwasm-std" } +bip32 = "0.5.1" +bip39 = "2.0.0" + +# general +async-trait = "0.1.80" +serde = "1.0.198" +serde_json = "1.0.116" +nanorand = { version = "0.7.0", features = ["getrandom", "zeroize"] } + +# crypto +base64 = "0.22.0" +hex = "0.4.3" +hkdf = "0.12.4" +sha2 = "0.10.8" +aes-siv = "0.7.0" +x25519-dalek = { version = "2.0.1", features = ["static_secrets"] } + +# errors +thiserror = "1.0.51" [features] default = ["bip32"] diff --git a/secretrs/examples/contract_query.rs b/secretrs/examples/contract_query.rs index fbe06e4..2f62c76 100644 --- a/secretrs/examples/contract_query.rs +++ b/secretrs/examples/contract_query.rs @@ -46,7 +46,7 @@ async fn main() -> Result<()> { // Encryption Utils section - let account = secret_utils::Account::random(); + let account = secretrs::utils::Account::random(); let (nonce, encrypted) = encrypt_msg(&query, &code_hash, &account, &enclave_key).await?; let decrypter = decrypter(&nonce, &account, &enclave_key).await?; @@ -84,9 +84,9 @@ async fn main() -> Result<()> { let encrypted_bytes = BASE64_STANDARD.decode(&caps[1])?; let decrypted_bytes = decrypter.decrypt(&encrypted_bytes)?; let decrypted_string = String::from_utf8(decrypted_bytes)?; - Err(secret_utils::Error::Generic(decrypted_string)) + Err(secretrs::utils::Error::Generic(decrypted_string)) } else { - Err(secret_utils::Error::Generic(error_message.to_string())) + Err(secretrs::utils::Error::Generic(error_message.to_string())) } } }?; diff --git a/secretrs/examples/encrypt.rs b/secretrs/examples/encrypt.rs new file mode 100644 index 0000000..140ab6e --- /dev/null +++ b/secretrs/examples/encrypt.rs @@ -0,0 +1,30 @@ +use color_eyre::Result; +use serde::{Deserialize, Serialize}; + +const CODE_HASH: &str = "9a00ca4ad505e9be7e6e6dddf8d939b7ec7e9ac8e109c8681f10db9cacb36d42"; +const TESTNET_ENCLAVE_KEY: &str = + "e24a22b31e3d34e0e00bcd32189548f1ccbdc9cda8f5a266219b908582b6f03f"; + +#[derive(Serialize, Deserialize)] +#[serde(rename_all = "snake_case")] +pub enum QueryMsg { + TokenInfo {}, +} + +#[tokio::main(flavor = "current_thread")] +async fn main() -> Result<()> { + let query = QueryMsg::TokenInfo {}; + let account = secretrs::utils::Account::random(); + + let (_nonce, encrypted) = + secretrs::utils::encrypt_msg(&query, CODE_HASH, &account, TESTNET_ENCLAVE_KEY).await?; + + println!("{}", hex::encode(&encrypted)); + + // Use this to decrypt responses from the enclave: + // + // let decrypter = secret_utils::decrypter(&nonce, &account, TESTNET_ENCLAVE_KEY).await?; + // let decrypted_bytes = decrypter.decrypt(&response.data)?; + + Ok(()) +} diff --git a/secretrs/src/lib.rs b/secretrs/src/lib.rs index 6a96a20..58b8158 100644 --- a/secretrs/src/lib.rs +++ b/secretrs/src/lib.rs @@ -2,8 +2,7 @@ pub use cosmrs::*; pub use secret_sdk_proto::{self as proto, SECRET_VERSION}; pub mod compute; - -pub use secret_utils as utils; +pub mod utils; #[cfg(feature = "grpc-core")] pub use crate::tonic::{query_clients::*, service_clients::*}; diff --git a/secretrs/src/utils/account.rs b/secretrs/src/utils/account.rs new file mode 100644 index 0000000..4dcbe37 --- /dev/null +++ b/secretrs/src/utils/account.rs @@ -0,0 +1,114 @@ +use cosmrs::{ + crypto::{secp256k1::SigningKey, PublicKey}, + AccountId, +}; +use cosmwasm_std::Addr; + +use crate::utils::{ + consts, + crypto::{self, Key}, +}; + +#[derive(Clone)] +pub struct Account { + prvk: bip32::XPrv, + pubk: PublicKey, +} + +impl Account { + pub fn from_mnemonic(s: &str) -> Option { + let mnemonic = bip39::Mnemonic::parse(s).ok()?; + // empty passphrase + Some(Account::from_seed(mnemonic.to_seed(""))) + } + + pub fn from_seed(seed: [u8; 64]) -> Account { + let path = consts::SCRT_DERIVATION_PATH + .parse() + .expect("invalid scrt derivation path"); + let prvk = + bip32::XPrv::derive_from_path(seed, &path).expect("private key derivation failed"); + let pubk = SigningKey::from(&prvk).public_key(); + Account { prvk, pubk } + } + + pub fn random() -> Account { + use nanorand::rand::Rng; + let mut seed = [0; 64]; + let mut rng = nanorand::rand::ChaCha8::new(); + rng.fill_bytes(&mut seed); + + let path = consts::SCRT_DERIVATION_PATH + .parse() + .expect("invalid scrt derivation path"); + let prvk = + bip32::XPrv::derive_from_path(seed, &path).expect("private key derivation failed"); + let pubk = SigningKey::from(&prvk).public_key(); + Account { prvk, pubk } + } + + pub fn addr(&self) -> Addr { + Addr::unchecked(self.id().as_ref()) + } + + #[allow(unused)] + pub(crate) fn signing_key(&self) -> SigningKey { + SigningKey::from(&self.prvk) + } + + pub(crate) fn id(&self) -> AccountId { + self.pubk + .account_id(consts::CHAIN_PREFIX) + .expect("invalid public key type") + } + + pub(crate) fn prv_pub_bytes(&self) -> (Key, Key) { + crypto::edd25519_keys(&self.prvk) + } +} + +pub fn a() -> Account { + Account::from_mnemonic(A_MNEMONIC).unwrap() +} + +pub fn b() -> Account { + Account::from_mnemonic(B_MNEMONIC).unwrap() +} + +pub fn c() -> Account { + Account::from_mnemonic(C_MNEMONIC).unwrap() +} + +pub fn d() -> Account { + Account::from_mnemonic(D_MNEMONIC).unwrap() +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn accounts_from_mnemonic() { + assert_eq!( + a().addr(), + Addr::unchecked("secret1ap26qrlp8mcq2pg6r47w43l0y8zkqm8a450s03") + ); + assert_eq!( + b().addr(), + Addr::unchecked("secret1fc3fzy78ttp0lwuujw7e52rhspxn8uj52zfyne") + ); + assert_eq!( + c().addr(), + Addr::unchecked("secret1ajz54hz8azwuy34qwy9fkjnfcrvf0dzswy0lqq") + ); + assert_eq!( + d().addr(), + Addr::unchecked("secret1ldjxljw7v4vk6zhyduywh04hpj0jdwxsmrlatf") + ); + } +} + +static A_MNEMONIC: &str = "grant rice replace explain federal release fix clever romance raise often wild taxi quarter soccer fiber love must tape steak together observe swap guitar"; +static B_MNEMONIC: &str = "jelly shadow frog dirt dragon use armed praise universe win jungle close inmate rain oil canvas beauty pioneer chef soccer icon dizzy thunder meadow"; +static C_MNEMONIC: &str = "chair love bleak wonder skirt permit say assist aunt credit roast size obtain minute throw sand usual age smart exact enough room shadow charge"; +static D_MNEMONIC: &str = "word twist toast cloth movie predict advance crumble escape whale sail such angry muffin balcony keen move employ cook valve hurt glimpse breeze brick"; diff --git a/secretrs/src/utils/consts.rs b/secretrs/src/utils/consts.rs new file mode 100644 index 0000000..fe21295 --- /dev/null +++ b/secretrs/src/utils/consts.rs @@ -0,0 +1,11 @@ +#![allow(unused)] + +// Chain info +pub static CHAIN_PREFIX: &str = "secret"; +pub static SCRT_DERIVATION_PATH: &str = "m/44'/529'/0'/0/0"; +pub static COIN_DENOM: &str = "uscrt"; + +// Host info +pub static TESTNET_HOST: &str = "http://rpc.testnet.secretsaturn.net"; +pub static TESTNET_ENCLAVE_KEY: &str = + "e24a22b31e3d34e0e00bcd32189548f1ccbdc9cda8f5a266219b908582b6f03f"; diff --git a/secretrs/src/utils/crypto/cert.rs b/secretrs/src/utils/crypto/cert.rs new file mode 100644 index 0000000..9685820 --- /dev/null +++ b/secretrs/src/utils/crypto/cert.rs @@ -0,0 +1,68 @@ +#![allow(unused)] + +use super::Key; +use base64::prelude::{Engine, BASE64_STANDARD}; + +#[derive(Debug, thiserror::Error)] +pub enum MalformedError { + #[error("The DER byte buffer is too short")] + IncorrectLength, + #[error("The Netscape Comment is invalid utf8: {0}")] + Utf8(#[from] std::str::Utf8Error), + #[error("The Netscape Comment has invalid base64 encoding: {0}")] + Base64(#[from] base64::DecodeError), +} + +// https://github.com/scrtlabs/SecretNetwork/blob/19bbd80307b4d6b49f04ad5c62008a3f25ba3f1e/cosmwasm/enclaves/execute/src/registration/cert.rs#L213 +fn extract_asn1_value<'a>(cert: &'a [u8], oid: &[u8]) -> Result<&'a [u8], MalformedError> { + let mut offset = cert + .windows(oid.len()) + .position(|window| window == oid) + .ok_or(MalformedError::IncorrectLength)?; + + offset += 12; // 11 + TAG (0x04) + + if offset + 2 >= cert.len() { + return Err(MalformedError::IncorrectLength); + } + + // Obtain Netscape Comment length + let mut len = cert[offset] as usize; + if len > 0x80 { + len = (cert[offset + 1] as usize) * 0x100 + (cert[offset + 2] as usize); + offset += 2; + } + + // Obtain Netscape Comment + offset += 1; + + if offset + len >= cert.len() { + return Err(MalformedError::IncorrectLength); + } + + Ok(&cert[offset..offset + len]) +} + +fn extract_netscape_comment(cert_der: &[u8]) -> Result<&[u8], MalformedError> { + // Search for Netscape Comment OID + let ns_cmt_oid = &[ + 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xF8, 0x42, 0x01, 0x0D, + ]; + extract_asn1_value(cert_der, ns_cmt_oid) +} + +pub(crate) fn consensus_io_pubk(cert_der: &[u8]) -> Result { + // localsecret used software SGX so we can just deserialise the payload: + // https://github.com/scrtlabs/SecretNetwork/blob/19bbd80307b4d6b49f04ad5c62008a3f25ba3f1e/x/registration/remote_attestation/remote_attestation.go#L25 + let buf = extract_netscape_comment(cert_der)?; + let b64 = std::str::from_utf8(buf)?; + let pubk = BASE64_STANDARD.decode(b64)?; + + if pubk.len() < super::KEY_LEN { + return Err(MalformedError::IncorrectLength); + } + + let pubk = super::clone_into_key(&pubk); + + Ok(pubk) +} diff --git a/secretrs/src/utils/crypto/mod.rs b/secretrs/src/utils/crypto/mod.rs new file mode 100644 index 0000000..7a74c6b --- /dev/null +++ b/secretrs/src/utils/crypto/mod.rs @@ -0,0 +1,173 @@ +use aes_siv::{siv::Aes128Siv as Siv, Key as SivKey, KeyInit}; + +pub mod cert; + +const KEY_LEN: usize = 256 / 8; // 32 bytes +const NONCE_LEN: usize = 32; + +pub type Nonce = [u8; NONCE_LEN]; +pub type Key = [u8; KEY_LEN]; + +#[derive(Debug, thiserror::Error)] +pub enum CryptoError { + #[error("Incorrect key length, expected 32 byte key")] + IncorrectKeyLength, + #[error("Encryption failed")] + Encrypt, + #[error("Decryption failed")] + Decrypt, +} + +pub fn edd25519_keys(secret: &bip32::XPrv) -> (Key, Key) { + let secret = clone_into_key(&secret.private_key().to_bytes()); + let secret = x25519_dalek::StaticSecret::from(secret); + let public = x25519_dalek::PublicKey::from(&secret); + (secret.to_bytes(), public.to_bytes()) +} + +pub fn encrypt( + secret: &Key, + public: &Key, + peer: &Key, + plaintext: &[u8], +) -> Result<(Nonce, Vec), CryptoError> { + let nonce = generate_nonce(); + + let shared_secret = encryption_key(secret, peer, &nonce)?; + + let mut cipher = Siv::new(&SivKey::::from(shared_secret)); + + let ciphertext = cipher + .encrypt([[]], plaintext) + .map_err(|_| CryptoError::Encrypt)?; + + let ciphertext = [nonce.as_slice(), public.as_slice(), &ciphertext].concat(); + + Ok((nonce, ciphertext)) +} + +pub fn decrypt( + secret: &Key, + peer: &Key, + nonce: &Nonce, + ciphertext: &[u8], +) -> Result, CryptoError> { + let shared_secret = encryption_key(secret, peer, nonce)?; + + let mut cipher = Siv::new(&SivKey::::from(shared_secret)); + + let plaintext = cipher + .decrypt([[]], ciphertext) + .map_err(|_| CryptoError::Decrypt)?; + + Ok(plaintext) +} + +#[derive(Debug, Clone, Copy)] +pub struct Decrypter { + secret: Key, + peer: Key, + nonce: Nonce, +} + +impl Decrypter { + pub fn new(secret: Key, peer: Key, nonce: Nonce) -> Self { + Decrypter { + secret, + peer, + nonce, + } + } + + pub fn decrypt(&self, ciphertext: &[u8]) -> Result, CryptoError> { + decrypt(&self.secret, &self.peer, &self.nonce, ciphertext) + } +} + +fn generate_nonce() -> Nonce { + use nanorand::rand::Rng; + let mut nonce = [0; NONCE_LEN]; + let mut rng = nanorand::rand::ChaCha8::new(); + rng.fill_bytes(&mut nonce); + nonce +} + +fn encryption_key(secret: &Key, public: &Key, nonce: &Nonce) -> Result { + let secret = x25519_dalek::StaticSecret::from(*secret); + let public = x25519_dalek::PublicKey::from(*public); + let shared = secret.diffie_hellman(&public); + + let ikm = &[shared.as_bytes(), nonce.as_slice()].concat(); + + let mut key = [0u8; KEY_LEN]; + hkdf::Hkdf::::new(Some(&HKDF_SALT), ikm) + .expand(&[], &mut key) + .map_err(|_| CryptoError::IncorrectKeyLength)?; + + Ok(key) +} + +// TODO - this could panic. impl TryFrom or something +pub fn clone_into_key(slice: &[u8]) -> Key { + let mut key = Default::default(); + Key::as_mut(&mut key).clone_from_slice(slice); + key +} + +static HKDF_SALT: [u8; 32] = [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x4b, 0xea, 0xd8, 0xdf, 0x69, 0x99, + 0x08, 0x52, 0xc2, 0x02, 0xdb, 0x0e, 0x00, 0x97, 0xc1, 0xa1, 0x2e, 0xa6, 0x37, 0xd7, 0xe9, 0x6d, +]; + +#[cfg(test)] +mod test { + use crate::utils::account::Account; + + use super::*; + + fn gen_seed() -> [u8; 64] { + use nanorand::rand::Rng; + let mut seed = [0; 64]; + let mut rng = nanorand::rand::ChaCha8::new(); + rng.fill_bytes(&mut seed); + seed + } + + fn gen_keypair() -> (Key, Key) { + let acc = Account::from_seed(gen_seed()); + acc.prv_pub_bytes() + } + + fn gen_bip32_key() -> bip32::XPrv { + bip32::XPrv::new(gen_seed()).unwrap() + } + + #[test] + fn x25519_works() { + let my_key = gen_bip32_key(); + let peer_key = gen_bip32_key(); + + let my_priv = clone_into_key(&my_key.private_key().to_bytes()); + let my_priv = x25519_dalek::StaticSecret::from(my_priv); + let my_pub = x25519_dalek::PublicKey::from(&my_priv); + + let peer_priv = clone_into_key(&peer_key.private_key().to_bytes()); + let peer_priv = x25519_dalek::StaticSecret::from(peer_priv); + let peer_pub = x25519_dalek::PublicKey::from(&peer_priv); + + let my_shared = my_priv.diffie_hellman(&peer_pub); + let peer_shared = peer_priv.diffie_hellman(&my_pub); + + assert_eq!(my_shared.to_bytes(), peer_shared.to_bytes()); + } + + #[test] + fn shared_encryption_key() { + let (my_priv, my_pub) = gen_keypair(); + let (peer_priv, peer_pub) = gen_keypair(); + let nonce = generate_nonce(); + let my_shared_key = encryption_key(&my_priv, &peer_pub, &nonce).unwrap(); + let peer_shared_key = encryption_key(&peer_priv, &my_pub, &nonce).unwrap(); + assert_eq!(my_shared_key, peer_shared_key) + } +} diff --git a/secretrs/src/utils/error.rs b/secretrs/src/utils/error.rs new file mode 100644 index 0000000..a40fb45 --- /dev/null +++ b/secretrs/src/utils/error.rs @@ -0,0 +1,45 @@ +pub type Result = std::result::Result; + +pub use crate::utils::crypto::cert::MalformedError; +pub use crate::utils::crypto::CryptoError; +pub use crate::utils::types::ParseError; + +#[derive(Debug, thiserror::Error)] +pub enum Error { + #[error("{0}")] + Generic(String), + #[error("Failed to read contract file: {0} - {1}")] + ContractFile(String, std::io::Error), + #[error("Contract with label {0} already deployed")] + ContractLabelExists(String), + #[error("Contract Info not found for code id: {0}")] + ContractInfoNotFound(crate::utils::CodeId), + #[error("Timed out waiting for first block after {0} seconds")] + FirstBlockTimeout(u128), + #[error("ABCI Query failed: {0}")] + AbciQuery(String), + #[error("CosmWasm Error: {0}")] + CosmWasm(#[from] cosmwasm_std::StdError), + #[error("Account {0} not found")] + AccountNotFound(cosmwasm_std::Addr), + #[error("CosmRs error: {0}")] + CosmRs(#[from] cosmrs::ErrorReport), + #[error("Broadcast error - check tx failed: {0}")] + BroadcastTxCheck(String), + #[error("Broadcast error - deliver tx failed: {0}")] + BroadcastTxDeliver(String), + #[error("Failed to parse message response: {0}")] + ParseMsgResponse(#[from] ParseError), + #[error("Parsing TEE cert failed: {0}")] + ParseTEECert(#[from] MalformedError), + #[error("Cryptographic error: {0}")] + Crypto(#[from] CryptoError), + #[error("Failed to deserialise JSON response: {0}")] + Json(#[from] serde_json::Error), + #[error("Failed to decode Base64 response: {0}")] + Base64(#[from] base64::DecodeError), + #[error(transparent)] + Utf8(#[from] std::string::FromUtf8Error), + #[error(transparent)] + ParseHex(#[from] hex::FromHexError), +} diff --git a/secretrs/src/utils/mod.rs b/secretrs/src/utils/mod.rs new file mode 100644 index 0000000..94a8f7f --- /dev/null +++ b/secretrs/src/utils/mod.rs @@ -0,0 +1,64 @@ +pub mod account; +pub(crate) mod consts; +pub(crate) mod crypto; +pub mod error; +pub mod types; + +pub use crate::utils::error::Error; +pub use account::Account; +pub use types::{CodeHash, CodeId, Contract, TxResponse}; + +use crate::utils::error::Result; +use crypto::{Decrypter, Nonce}; +use std::str::FromStr; + +// IDEA - for a nice API, take as input only a code_hash, enclave_public_key, and some entropy. +// do a sha256 on the entropy to get a [u8;32] to use as the prv_key. generate a pub_key. +// return a struct that has methods for encrypt and decrypt +// +// let enigma = secretrs::Enigma::new(code_hash, enclave_public_key, entropy); +// let encrypted = enigma.encrypt(msg); +// +// OR +// +// let (encrypter, decrypter) = secretrs::Enigma::new(code_hash, enclave_public_key, entropy); +// let encrypted = encrypter.encrypt(msg); + +// TODO - instead of `Account`, accept a key / seed [u8; 32] +// For queries, the specific keys don't matter, so it doesn't make sense to require `Account` +// as input. You only need to provide a private key / seed, and it returns a prv_pub pair. +pub async fn encrypt_msg( + msg: &M, + code_hash: &str, + account: &Account, + enclave_public_key: &str, +) -> Result<(Nonce, Vec)> { + let code_hash = CodeHash::from_str(code_hash)?; + + let enclave_key = crypto::clone_into_key(&hex::decode(enclave_public_key)?); + let msg = serde_json::to_vec(msg).expect("msg cannot be serialized as JSON"); + let plaintext = [code_hash.to_hex_string().as_bytes(), msg.as_slice()].concat(); + encrypt_msg_raw(&plaintext, account, enclave_key).await +} + +async fn encrypt_msg_raw( + msg: &[u8], + account: &Account, + enclave_public_key: crypto::Key, +) -> Result<(Nonce, Vec)> { + let (prvk, pubk) = account.prv_pub_bytes(); + let io_key = enclave_public_key; + let nonce_ciphertext = crypto::encrypt(&prvk, &pubk, &io_key, msg)?; + Ok(nonce_ciphertext) +} + +pub async fn decrypter( + nonce: &Nonce, + account: &Account, + enclave_public_key: &str, +) -> Result { + let (secret, _) = account.prv_pub_bytes(); + let enclave_key = crypto::clone_into_key(&hex::decode(enclave_public_key)?); + let io_key = enclave_key; + Ok(Decrypter::new(secret, io_key, *nonce)) +} diff --git a/secretrs/src/utils/types.rs b/secretrs/src/utils/types.rs new file mode 100644 index 0000000..736b79c --- /dev/null +++ b/secretrs/src/utils/types.rs @@ -0,0 +1,219 @@ +#![allow(unused)] + +use std::{collections::HashMap, str::FromStr}; + +use cosmrs::AccountId; + +use crate::utils::consts::CHAIN_PREFIX; + +#[derive(Debug, thiserror::Error)] +pub enum ParseError { + #[error("Failed to parse code id: {0}")] + CodeId(#[from] ParseCodeIdError), + #[error("Failed to parse code hash: {0}")] + CodeHash(#[from] hex::FromHexError), + #[error("Failed to parse contract address: {0}")] + ContractAddress(#[from] cosmrs::ErrorReport), + #[error("Failed to parse contract initialisation: {0}")] + ContractInit(#[from] ParseContractInitError), +} + +#[derive(Debug, Clone, Copy)] +pub struct CodeId(u64); + +impl std::fmt::Display for CodeId { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) + } +} + +impl From for u64 { + fn from(ci: CodeId) -> Self { + ci.0 + } +} + +#[derive(Debug, thiserror::Error)] +pub enum ParseCodeIdError { + #[error(transparent)] + Utf8(#[from] std::str::Utf8Error), + #[error(transparent)] + ParseInt(#[from] std::num::ParseIntError), +} + +impl TryFrom> for CodeId { + type Error = ParseError; + + fn try_from(value: Vec) -> Result { + fn parse(value: &[u8]) -> Result { + let s = std::str::from_utf8(value)?; + let code_id = s.parse()?; + Ok(CodeId(code_id)) + } + parse(&value).map_err(Self::Error::from) + } +} + +#[derive(Debug, Clone)] +pub(crate) struct ContractInit(AccountId); + +impl ContractInit { + pub fn into_contract(self, code_hash: CodeHash) -> Contract { + Contract { + id: self.0, + code_hash, + } + } +} + +#[derive(Debug, thiserror::Error)] +pub enum ParseContractInitError { + #[error("Failed to parse address bytes: {0}")] + Address(#[from] cosmrs::ErrorReport), +} + +impl TryFrom> for ContractInit { + type Error = ParseError; + + fn try_from(value: Vec) -> Result { + fn parse(value: &[u8]) -> Result { + let id = AccountId::new(CHAIN_PREFIX, value)?; + Ok(ContractInit(id)) + } + parse(&value).map_err(Self::Error::from) + } +} + +#[derive(Debug, Clone)] +pub struct Contract { + id: AccountId, + code_hash: CodeHash, +} + +impl Contract { + pub fn try_from_address_with_code_hash( + address: &str, + code_hash: &str, + ) -> Result { + let id = AccountId::from_str(address)?; + let code_hash = CodeHash::from_str(code_hash)?; + Ok(Contract { id, code_hash }) + } + pub fn addr(&self) -> cosmwasm_std::Addr { + cosmwasm_std::Addr::unchecked(self.id.as_ref()) + } + + pub fn code_hash_string(&self) -> String { + self.code_hash.to_hex_string() + } + + pub(crate) fn id(&self) -> AccountId { + self.id.clone() + } + + pub(crate) fn code_hash(&self) -> &CodeHash { + &self.code_hash + } +} + +#[derive(Debug, Clone)] +pub struct CodeHash(Vec); + +impl From> for CodeHash { + fn from(b: Vec) -> Self { + CodeHash(b) + } +} + +impl FromStr for CodeHash { + type Err = ParseError; + + fn from_str(s: &str) -> Result { + hex::decode(s).map(CodeHash).map_err(ParseError::from) + } +} + +impl CodeHash { + pub fn as_bytes(&self) -> &[u8] { + self.0.as_slice() + } + + pub fn to_hex_string(&self) -> String { + use core::fmt::Write; + let mut s = String::with_capacity(2 * self.0.len()); + for byte in self.as_bytes() { + write!(s, "{:02X}", byte).expect("could not write byte as hex to string"); + } + s + } +} + +impl std::fmt::Display for CodeHash { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.to_hex_string()) + } +} + +#[derive(Debug)] +pub struct Event { + pub(crate) _type: String, + pub(crate) attrs: HashMap, +} + +#[derive(Debug)] +pub struct TxResponse { + pub response: Option, + pub gas_used: u64, + pub(crate) events: Vec, +} + +impl TxResponse { + pub fn event_attr(&self, event_type: &str, attr: &str) -> Option<&str> { + self.events + .iter() + .find(|e| e._type == event_type) + .and_then(|e| e.attrs.get(attr)) + .map(String::as_str) + } + + /// panics if the response is `None` + pub fn into_inner(self) -> T { + self.response.unwrap() + } + + pub(crate) fn map U>(self, f: F) -> TxResponse { + TxResponse { + response: self.response.map(f), + gas_used: self.gas_used, + events: self.events, + } + } + + pub(crate) fn try_map(self, f: F) -> crate::utils::error::Result> + where + crate::utils::error::Error: From, + F: FnOnce(T) -> Result, + { + let response = self.response.map(f).transpose()?; + Ok(TxResponse { + response, + gas_used: self.gas_used, + events: self.events, + }) + } +} + +#[derive(Debug)] +pub(crate) struct AccountInfo { + pub account_number: u64, + pub sequence_number: cosmrs::tx::SequenceNumber, +} + +impl From for AccountInfo { + fn from(ba: cosmrs::proto::cosmos::auth::v1beta1::BaseAccount) -> Self { + AccountInfo { + account_number: ba.account_number, + sequence_number: ba.sequence, + } + } +} From 4bcd33b5738af28c6a565542b7e9c451f5ef405f Mon Sep 17 00:00:00 2001 From: kent-3 <100624004+kent-3@users.noreply.github.com> Date: Fri, 26 Apr 2024 13:40:34 -0400 Subject: [PATCH 6/7] add description --- secretrs/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/secretrs/Cargo.toml b/secretrs/Cargo.toml index 4abfbff..b48f54c 100644 --- a/secretrs/Cargo.toml +++ b/secretrs/Cargo.toml @@ -4,7 +4,7 @@ version = "0.0.0" authors = ["Kent"] license = "Unlicense" repository = "https://github.com/kent-3/secret-rust/tree/main/secretrs" -# description = "" +description = "An extension of `cosmrs` for Secret." readme = "README.md" categories = ["cryptography", "cryptography::cryptocurrencies"] keywords = ["blockchain", "cosmos"] From 90fbd09e83bbb3ba2317840df4e37018d8992695 Mon Sep 17 00:00:00 2001 From: kent-3 <100624004+kent-3@users.noreply.github.com> Date: Fri, 26 Apr 2024 13:52:27 -0400 Subject: [PATCH 7/7] tidy --- Cargo.toml | 4 ++-- README.md | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3da6692..d5ddc0b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [workspace] resolver = "2" -members = ["secret-sdk-proto", "secret-grpc", "secretrs", "secret-utils"] -exclude = ["proto-build"] +members = ["secret-sdk-proto", "secret-grpc", "secretrs"] +exclude = ["proto-build", "secret-utils"] # This patch adds target_arch = "wasm32" configurations to the rpc clients [patch.crates-io] diff --git a/README.md b/README.md index 628349d..2d0f41f 100644 --- a/README.md +++ b/README.md @@ -24,8 +24,7 @@ An extension of [Cosmos Rust](https://github.com/cosmos/cosmos-rust) for [Secret - [x] `proto-build` crate like cosmos-rust and tendermint-rs each have - [x] `secret-sdk-proto` crate that re-exports `cosmos-sdk-proto` and adds secret protobuf structs -- [x] `secretrs` crate that re-exports `cosmrs` and adds secret type conversions -- [x] `secret-utils` provide encryption and decryption tools for use with any client +- [x] `secretrs` crate that re-exports `cosmrs` and adds secret types, encryption tools - [ ] `secret-grpc` crate with full gRPC client implementation - [ ] `secret-grpc-gateway` crate with full gRPC-gateway (REST) client implementation