├── .github └── workflows │ └── main.yml ├── .gitignore ├── LICENSE ├── README.md ├── as-pect.config.js ├── assembly ├── AbstractInt.ts ├── Arrays │ ├── AbstractArray.ts │ ├── BoolArray.ts │ ├── ByteArray.ts │ ├── IntArray.ts │ ├── StringArray.ts │ ├── UInt128Array.ts │ └── index.ts ├── Bool.ts ├── Byte.ts ├── BytesReader.ts ├── Hash.ts ├── Int │ ├── CompactInt.ts │ ├── Int16.ts │ ├── Int32.ts │ ├── Int64.ts │ ├── Int8.ts │ └── index.ts ├── ScaleMap.ts ├── ScaleString.ts ├── UInt │ ├── UInt128.ts │ ├── UInt16.ts │ ├── UInt32.ts │ ├── UInt64.ts │ ├── UInt8.ts │ └── index.ts ├── __tests__ │ ├── Arrays │ │ ├── BoolArray.spec.ts │ │ ├── ByteArray.spec.ts │ │ ├── IntArray.spec.ts │ │ ├── StringArray.spec.ts │ │ └── UInt128Array.spec.ts │ ├── Bool.spec.ts │ ├── Byte.spec.ts │ ├── BytesReader.spec.ts │ ├── Hash.spec.ts │ ├── Int.spec.ts │ ├── ScaleMap.spec.ts │ ├── ScaleString.spec.ts │ ├── UInt.spec.ts │ └── as-pect.d.ts ├── index.ts ├── interfaces │ ├── Codec.ts │ ├── DecodedData.ts │ ├── UnwrappableCodec.ts │ └── index.ts ├── tsconfig.json └── utils │ ├── Arrays.ts │ ├── Bytes.ts │ └── BytesBuffer.ts ├── example ├── README.md ├── as-pect.config.js ├── assembly │ ├── __tests__ │ │ └── as-pect.d.ts │ ├── index.ts │ └── tsconfig.json ├── index.js ├── package-lock.json └── package.json ├── index.js ├── package-lock.json ├── package.json └── web3_badge_black.png /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | on: [push] 3 | jobs: 4 | tests: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - uses: actions/checkout@v2 8 | - name: run-tests 9 | run: | 10 | npm install 11 | npm run test:ci 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | build/ 3 | .idea/ 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

AssemblyScript SCALE Codec

2 | 3 | 4 | [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) 5 | ![Tests](https://github.com/LimeChain/as-scale-codec/workflows/Tests/badge.svg) 6 | [![npm version](https://img.shields.io/npm/v/as-scale-codec?color=light-green&label=npm%20package)](https://img.shields.io/npm/v/as-scale-codec?color=light-green&label=npm%20package) 7 | ![GitHub release (latest by date)](https://img.shields.io/github/v/release/LimeChain/as-scale-codec) 8 | 9 | **as-scale-codec** is AssemblyScript implementation of Polkadot SCALE Codec. The codec is used as a communication mechanism between Polkadot Hosts and Polkadot Runtimes. 10 | 11 | More detailed information about the SCALE codec specification can be found [here](https://substrate.dev/docs/en/knowledgebase/advanced/codec). 12 | 13 | This AssemblyScript implementation of the codec is funded by [Web3 Foundation](https://web3.foundation/) via their [Open Grants Program](https://github.com/w3f/Open-Grants-Program)! :pray: 14 | ![WEB3 Badge](./web3_badge_black.png) 15 | # Supported types 16 | The following table shows the status of the types and their arrays: 17 | 18 | | Type | Support | Array Support | 19 | |----------------------|:--------------------:|:------:| 20 | | `Fixed width number` | ✅ | ✅ | 21 | | `Compact Int` | ✅ |✅ | 22 | | `Big Integer` | :small_orange_diamond: *Limited Support* | :small_orange_diamond: *Limited Support* | 23 | | `Byte` |✅ |✅ | 24 | | `Bool` | ✅| ✅| 25 | | `Hash` |✅ | :heavy_minus_sign: | 26 | | `String` | ✅|✅ | 27 | | `Map` |✅| :heavy_minus_sign: | 28 | 29 | The following table shows the status of the fixed width numbers: 30 | 31 | | Тype | `8` | `16` | `32` | `64` | `128` | `256` | 32 | |--|:--:|:--:|:--:|:--:|:--:|:--:| 33 | | `int` | ✅ | ✅| ✅|✅ | :heavy_minus_sign:| :heavy_minus_sign:| 34 | | `uint` | ✅ | ✅| ✅|✅ |✅ |:heavy_minus_sign:| 35 | 36 | 37 | ## Special Types 38 | 39 | - **Compact Int** - [Documentation](https://substrate.dev/docs/en/knowledgebase/advanced/codec#compactgeneral-integers) 40 | 41 | ## **Getting Started** 42 | *You can find more information on AssemblyScript and how to get started with it in the AssemblyScript docs -> [https://www.assemblyscript.org/introduction.html](https://www.assemblyscript.org/introduction.html)* 43 | 44 | 1. In your AssemblyScript project execute: 45 | 46 | ```bash 47 | npm install as-scale-codec 48 | ``` 49 | 2. Once you have the library installed in your AssemblyScript project you can use it in your `assembly` files by importing the files from `as-scale-codec`. 50 | 51 | Detailed examples of the exported by the library types are listed below: 52 | 53 | 54 | ## Types 55 | 56 | ### Encoding 57 | 58 | Every type has а **toU8a** function. It encodes type value into an array of bytes 59 | 60 | ```jsx 61 | import { Bool, Byte, ScaleString, Hash, CompactInt } from "as-scale-codec" 62 | import { Int8, Int16, Int32, Int64 } from "as-scale-codec" 63 | import { UInt8, UInt16, UInt32, UInt64, UInt128 } from "as-scale-codec" 64 | // ScaleMap 65 | const scaleMap = new ScaleMap(); 66 | scaleMap.set(new Int32(1), new Bool(false)); 67 | scaleMap.toU8a() // => [4, 1, 0, 0, 0, 0]; 68 | 69 | // Bool 70 | const scaleBool = new Bool(true); 71 | scaleBool.toU8a() // => [0x01] 72 | 73 | // Byte 74 | const scaleByte = new Byte(0x01); 75 | scaleByte.toU8a() // => [0x01] 76 | 77 | // String 78 | const scaleString = new ScaleString("a"); 79 | scaleString.toU8a() // => [0x04, 0x61] 80 | 81 | // Hash 82 | const scaleHash = new Hash([0xff, 0x00, 0xab]); 83 | scaleHash.toU8a() // => [0xff, 0x00, 0xab, 0x00, ... 0x00] (32 bytes long) 84 | 85 | // Compact Int 86 | const scaleCompactInt = new CompactInt(1); 87 | scaleCompactInt.toU8a() // => [0x04] 88 | 89 | // Int 90 | const scaleInt8 = new Int8(-1); 91 | scaleInt8.toU8a() // => [0xff] 92 | 93 | const scaleInt16 = new Int16(-1); 94 | scaleInt16.toU8a() // => [0xff, 0xff] 95 | 96 | const scaleInt32 = new Int32(-1); 97 | scaleInt32.toU8a() // => [0xff, 0xff, 0xff, 0xff] 98 | 99 | const scaleInt64 = new Int64(-1); 100 | scaleInt64.toU8a() // => [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] 101 | 102 | // UInt 103 | const scaleUInt8 = new UInt8(1); 104 | scaleUInt8.toU8a() // => [0x01] 105 | 106 | const scaleUInt16 = new UInt16(1); 107 | scaleUInt16.toU8a() // => [0x01, 0x00] 108 | 109 | const scaleUInt32 = new UInt32(1); 110 | scaleUInt32.toU8a() // => [0x01, 0x00, 0x00, 0x00] 111 | 112 | const scaleUInt64 = new UInt64(1); 113 | scaleUInt64.toU8a() // => [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] 114 | 115 | const scaleUInt128 = new UInt128(u128.fromU64(18446744073709551615)); 116 | scaleUInt128.toU8a() // => [0x13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] 117 | ``` 118 | 119 | ### Decoding 120 | 121 | Every type has a **static** function **fromU8a**. It decodes an array of bytes to the desired type 122 | 123 | ```jsx 124 | import { ScaleMap, Bool, Byte, ScaleString, Hash, CompactInt } from "as-scale-codec" 125 | import { Int8, Int16, Int32, Int64 } from "as-scale-codec" 126 | import { UInt8, UInt16, UInt32, UInt64, UInt128 } from "as-scale-codec" 127 | 128 | // Bool 129 | Bool.fromU8a([0x01]); // => new Bool(true) 130 | 131 | // Byte 132 | Byte.fromU8a([0x01]); // => new Byte(0x01) 133 | 134 | // String 135 | Byte.fromU8a([0x04, 0x61]); // => new ScaleString('a') 136 | 137 | // Hash 138 | Hash.fromU8a([0xff, 0x00, 0xab]); 139 | // => [0xff, 0x00, 0xab, 0x00, ... 0x00] (32 bytes long) 140 | 141 | ScaleMap.fromU8a([4, 1, 0, 0, 0, 0]); 142 | // => const scaleMap = new ScaleMap() 143 | // => scaleMap.set(new Int32(1), new Bool(false)) 144 | 145 | // Compact Int 146 | CompactInt.fromU8a([0x04]); // => new CompactInt(1) 147 | 148 | // Int 149 | Int8.fromU8a([0xff]); // => new Int8(-1) 150 | Int16.fromU8a([0xff, 0xff]); // => new Int16(-1) 151 | Int32.fromU8a([0xff, 0xff, 0xff, 0xff]); // => new Int32(-1) 152 | Int64.fromU8a([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]); // => new Int64(-1) 153 | 154 | // UInt 155 | UInt8.fromU8a([0x01]); // => new UInt8(1) 156 | UInt16.fromU8a([0x01, 0x00]); // => new UInt16(1) 157 | UInt32.fromU8a([0x01, 0x00, 0x00, 0x00]); // => new UInt32(1) 158 | UInt64.fromU8a([0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]); // => new UInt64(1) 159 | UInt128.fromU8a([0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]); 160 | // => 340282366920938463444927863358058659840 161 | ``` 162 | 163 | ## Arrays 164 | 165 | ### Encoding 166 | 167 | Every array has **toU8a** function. It encodes the array values into an array of SCALE encoded bytes. 168 | 169 | ```jsx 170 | import { BoolArray, ByteArray, IntArray, StringArray } from "as-scale-codec" 171 | 172 | // Bool Array 173 | const boolArray = new BoolArray([true, false, true]); 174 | boolArray.toU8a(); // => [0x0c, 0x01, 0x00, 0x01] 175 | 176 | // Byte Array 177 | const byteArray = new ByteArray([0x01, 0x01, 0x01]); 178 | byteArray.toU8a(); // => [0x0c, 0x01, 0x01, 0x01] 179 | 180 | // Int Array 181 | const intArray = new IntArray([16384, 2, 3, 4]); 182 | intArray.toU8a() // => [0x10, 0x02, 0x00, 0x01, 0x00, 0x08, 0x0c, 0x10] 183 | 184 | // String Array 185 | const stringArray = new StringArray(["hello", "world"]); 186 | stringArray.toU8a() // => [0x08, 0x14, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x14, 0x77, 0x6f, 0x72, 0x6c, 0x64] 187 | ``` 188 | 189 | ### Decoding 190 | 191 | Every array has a **static** function **fromU8a**. It decodes an array of SCALE encoded bytes and creates an array instance of the desired type. 192 | 193 | ```jsx 194 | import { BoolArray, ByteArray, IntArray, StringArray } from "as-scale-codec" 195 | 196 | // Bool Array 197 | BoolArray.fromU8a([0x0c, 0x01, 0x00, 0x01]); 198 | // => new BoolArray([true, false, true]) 199 | 200 | // Byte Array 201 | ByteArray.fromU8a([0x0c, 0x01, 0x01, 0x01]) 202 | // => new ByteArray([0x01, 0x01, 0x01]) 203 | 204 | // Int Array 205 | IntArray.fromU8a([0x10, 0x02, 0x00, 0x01, 0x00, 0x08, 0x0c, 0x10]) 206 | // => new IntArray([16384, 2, 3, 4]) 207 | 208 | // String Array 209 | StringArray.fromU8a([0x08, 0x14, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x14, 0x77, 0x6f, 0x72, 0x6c, 0x64]) 210 | // => new StringArray(["hello", "world"]) 211 | ``` 212 | 213 | # BytesReader 214 | 215 | If you have an array of arbitrary SCALE encoded bytes that you need to decode, `BytesReader` class is a preferred way to do it: 216 | 217 | ```jsx 218 | import { BytesReader } from 'as-scale-codec'; 219 | // Arbitrary SCALE encoded bytes 220 | const bytes: u8[] = [ 221 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 222 | 69, 0, 0, 0, 223 | 110, 125, 239, 2, 224 | 56, 97, 115, 45, 115, 99, 97, 108, 101, 45, 99, 111, 100, 101, 99, 225 | 128, 1, 10, 0, 0, 0, 2, 2, 1, 123, 33, 3, 1, 35, 34, 5, 8, 22, 52, 1, 0, 0, 0, 1, 1, 1, 56, 21, 142, 13, 13, 1, 226 | 0 227 | ]; 228 | // Instantiate BytesReader instance with SCALE encoded bytes 229 | const bytesReader = new BytesReader(bytes); 230 | 231 | // Read Int64 232 | bytesReader.readInto(); 233 | // => new Int(-1) 234 | 235 | // Read UInt32 236 | bytesReader.readInto(); 237 | // => new UInt32(69) 238 | 239 | // Read CompactInt 240 | bytesReader.readInto(); 241 | // => new CompactInt(12312411) 242 | 243 | // Read ScaleString 244 | bytesReader.readInto(); 245 | // => new ScaleString("as-scale-codec") 246 | 247 | // Read Hash 248 | bytesReader.readInto(); 249 | // => new Hash([128, 1, 10, 0, 0, 0, 2, 2, 1, 123, 33, 3, 1, 35, 34, 5, 8, 22, 52, 1, 0, 0, 0, 1, 1, 1, 56, 21, 142, 13, 13, 1]) 250 | 251 | // Read Bool 252 | bytesReader.readInto(); 253 | // => new Bool(false) 254 | 255 | // If you have single SCALE encoded type, you can use static decodeInto() function of BytesReader 256 | 257 | const uInt64Bytes: u8[] = [1, 0, 0, 0, 0, 0, 0]; 258 | // Read UInt64 259 | BytesReader.decodeInto(uInt64Bytes); 260 | // => new UInt64(1) 261 | 262 | const hashBytes: u8[] = [0xff, 0x00, 0xab]; 263 | // Read Hash 264 | BytesReader.decodeInto(hashBytes); 265 | // new Hash([0xff, 0x00, 0xab]) 266 | 267 | const mapBytes: u8[] = [2, 1, 0, 1, 0, 0, 0, 3, 0, 3, 0, 0, 0]; 268 | // Read ScaleMap 269 | BytesReader.decodeInto>(mapBytes); 270 | // => const scaleMap = new ScaleMap(); 271 | // => scaleMap.set(new UInt16(1), new UInt32(1)) 272 | // => scaleMap.set(new UInt16(3), new UInt32(3)) 273 | 274 | const cmpBytes: u8[] = [169, 2]; 275 | // Read CompactInt 276 | BytesReader.decodeInto(cmpBytes); 277 | // new CompactInt(170) 278 | 279 | const int8Bytes: u8[] = [0xff]; 280 | // Read Int8 281 | BytesReader.decodeInto(int8Bytes); 282 | // new Int8(-1) 283 | 284 | ``` 285 | 286 | # Miscellaneous 287 | 288 | ### Convert bytes to hash 289 | 290 | ```jsx 291 | Hash.bytesToHash([0xff, 0x00, 0xab]); 292 | // => [0x00, ... , 0x00, 0xff, 0x00, 0xab] (32 bytes long) 293 | 294 | Hash.bytesToHash([0xff, 0x00, ..., 0x00]); // (32 bytes long) 295 | // => [0xff, ... , 0x00] (32 bytes long) 296 | ``` 297 | 298 | # **Tests** 299 | 300 | In order to run the unit tests, one must perform: 301 | 302 | ```bash 303 | npm run test 304 | ``` 305 | 306 | # **License** 307 | This repository is licensed under [Apache 2.0 license](https://github.com/LimeChain/as-scale-codec/blob/master/LICENSE) 308 | -------------------------------------------------------------------------------- /as-pect.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | /** 3 | * A set of globs passed to the glob package that qualify typescript files for testing. 4 | */ 5 | include: ["assembly/__tests__/**/*.spec.ts"], 6 | /** 7 | * A set of globs passed to the glob package that quality files to be added to each test. 8 | */ 9 | add: ["assembly/__tests__/**/*.include.ts"], 10 | /** 11 | * All the compiler flags needed for this test suite. Make sure that a binary file is output. 12 | */ 13 | flags: { 14 | /** To output a wat file, uncomment the following line. */ 15 | // "--textFile": ["output.wat"], 16 | /** A runtime must be provided here. */ 17 | "--runtime": ["stub"], // Acceptable values are: full, half, stub (arena), and none 18 | }, 19 | /** 20 | * A set of regexp that will disclude source files from testing. 21 | */ 22 | disclude: [/node_modules/], 23 | /** 24 | * Add your required AssemblyScript imports here. 25 | */ 26 | imports (memory, createImports, instantiateSync, binary) { 27 | let instance; // Imports can reference this 28 | const myImports = { 29 | // put your web assembly imports here, and return the module 30 | }; 31 | instance = instantiateSync(binary, createImports(myImports)); 32 | return instance; 33 | }, 34 | /** 35 | * Add a custom reporter here if you want one. The following example is in typescript. 36 | * 37 | * @example 38 | * import { TestReporter, TestGroup, TestResult, TestContext } from "as-pect"; 39 | * 40 | * export class CustomReporter extends TestReporter { 41 | * // implement each abstract method here 42 | * public abstract onStart(suite: TestContext): void; 43 | * public abstract onGroupStart(group: TestGroup): void; 44 | * public abstract onGroupFinish(group: TestGroup): void; 45 | * public abstract onTestStart(group: TestGroup, result: TestResult): void; 46 | * public abstract onTestFinish(group: TestGroup, result: TestResult): void; 47 | * public abstract onFinish(suite: TestContext): void; 48 | * } 49 | */ 50 | // reporter: new CustomReporter(), 51 | /** 52 | * Specify if the binary wasm file should be written to the file system. 53 | */ 54 | outputBinary: false, 55 | }; 56 | -------------------------------------------------------------------------------- /assembly/AbstractInt.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2020 LimeChain Ltd. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { UnwrappableCodec } from "./interfaces/UnwrappableCodec"; 16 | import { Bytes } from "./utils/Bytes"; 17 | 18 | /** Representation for a Int value in the system. */ 19 | export abstract class AbstractInt implements UnwrappableCodec { 20 | 21 | protected bitLength: i32; 22 | private _value: T; 23 | 24 | constructor (value: T, bitLength: i32) { 25 | this._value = value; 26 | this.bitLength = bitLength; 27 | } 28 | 29 | /** 30 | * @description Returns the inner native value 31 | */ 32 | public unwrap(): T{ 33 | return this._value; 34 | } 35 | 36 | /** Encodes the value as u8[] as per the SCALE codec specification */ 37 | public toU8a (): u8[] { 38 | let bytesEncoded = new Array(this.bitLength); 39 | Bytes.putUint(bytesEncoded, this.unwrap(), this.bitLength); 40 | return bytesEncoded; 41 | } 42 | 43 | public eq(other: AbstractInt): bool{ 44 | return this.unwrap() == other.unwrap(); 45 | } 46 | public notEq(other: AbstractInt): bool{ 47 | return this.unwrap() != other.unwrap(); 48 | } 49 | 50 | /** 51 | * @description Non-static constructor method used to populate defined properties of the model 52 | * @param bytes SCALE encoded bytes 53 | * @param index index to start decoding the bytes from 54 | */ 55 | public populateFromBytes(bytes: u8[], index: i32 = 0): void { 56 | assert(bytes.length - index > 0, "AbstractInt: Invalid bytes provided"); 57 | this._value = Bytes.toUint(bytes, this.bitLength, index); 58 | } 59 | 60 | /** 61 | * @description Returns the string representation of the value 62 | */ 63 | toString (): string { 64 | return this.unwrap().toString(); 65 | } 66 | /** 67 | * @description The length of Uint8Array when the value is encoded 68 | */ 69 | public encodedLength (): i32 { 70 | return this.bitLength; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /assembly/Arrays/AbstractArray.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2020 LimeChain Ltd. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { Codec } from "../interfaces/Codec"; 16 | import { DecodedData } from "../interfaces/DecodedData"; 17 | import { UnwrappableCodec } from "../interfaces/UnwrappableCodec"; 18 | import { ArrayUtils } from "../utils/Arrays"; 19 | import { Bytes } from "../utils/Bytes"; 20 | import { BytesBuffer } from "../utils/BytesBuffer"; 21 | 22 | export abstract class AbstractArray implements UnwrappableCodec>{ 23 | 24 | public values: Array; 25 | constructor(input: NativeType[] = []) { 26 | this.values = new Array(input.length); 27 | Bytes.copy(input, this.values); 28 | } 29 | 30 | /** 31 | * @description Returns the inner native value 32 | */ 33 | public unwrap(): Array{ 34 | return this.values; 35 | } 36 | 37 | public eq(other: AbstractArray): bool{ 38 | return ArrayUtils.areArraysEqual(this.values, other.values); 39 | }; 40 | 41 | public notEq(other: AbstractArray): bool{ 42 | return !ArrayUtils.areArraysEqual(this.values, other.values); 43 | }; 44 | 45 | /** 46 | * @description Encodes values of all elements in u8[] successively as per the SCALE codec specification 47 | */ 48 | public toU8a (): u8[] { 49 | const bytesBuffer = new BytesBuffer(); 50 | bytesBuffer.encodeCompactInt(this.values.length); 51 | 52 | for (let i = 0; i < this.values.length; i++) { 53 | const element = instantiate(this.values[i]); 54 | bytesBuffer.write(element.toU8a()); 55 | } 56 | 57 | return bytesBuffer.bytes; 58 | } 59 | 60 | /** 61 | * @description Returns encoded byte length of the type 62 | */ 63 | abstract encodedLength(): i32; 64 | 65 | /** 66 | * @description Non-static constructor method used to populate defined properties of the model 67 | * @param bytes SCALE encoded bytes 68 | * @param index index to start decoding the bytes from 69 | */ 70 | abstract populateFromBytes(bytes: u8[], index: i32): void; 71 | 72 | /** 73 | * @description Each child class has to provide decryption implementation for elements 74 | */ 75 | public abstract decodeElement (value: u8[]): DecodedData; 76 | 77 | /** 78 | * @description Instantiates type of ScaleArray from u8[] SCALE encoded bytes (Decode) 79 | */ 80 | static fromU8a (input: u8[]): TypeOfScaleArray { 81 | const data = Bytes.decodeCompactInt(input); 82 | let bytes = input.slice(data.decBytes); 83 | 84 | const scaleArray = instantiate([]); 85 | 86 | for (let i: u64 = 0; i < data.value; i++) { 87 | const element = scaleArray.decodeElement(bytes); 88 | scaleArray.values.push(element.value); 89 | 90 | bytes = bytes.slice(element.decBytes); 91 | } 92 | 93 | return scaleArray; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /assembly/Arrays/BoolArray.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2020 LimeChain Ltd. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { BytesReader, CompactInt } from ".."; 16 | import { DecodedData } from "../interfaces/DecodedData"; 17 | import { Bool } from "./../Bool"; 18 | import { AbstractArray } from "./AbstractArray"; 19 | 20 | 21 | // @ts-ignore 22 | export class BoolArray extends AbstractArray { 23 | 24 | /** 25 | * @description BoolArray elements decryption implementation 26 | */ 27 | public decodeElement (value: u8[]): DecodedData { 28 | const scaleBool = Bool.fromU8a([value[0]]); 29 | 30 | return new DecodedData( 31 | scaleBool.unwrap(), 32 | scaleBool.encodedLength() 33 | ) 34 | } 35 | 36 | /** 37 | * @description Returns encoded byte length of the type 38 | */ 39 | public encodedLength(): i32{ 40 | return (new CompactInt(this.values.length).encodedLength()) + super.values.length; 41 | } 42 | 43 | /** 44 | * @description Non-static constructor method used to populate defined properties of the model 45 | * @param bytes SCALE encoded bytes 46 | * @param index index to start decoding the bytes from 47 | */ 48 | populateFromBytes(bytes: u8[], index: i32 = 0): void{ 49 | const bytesReader = new BytesReader(bytes.slice(index)); 50 | const data = bytesReader.readInto(); 51 | 52 | for(let i: i32 = 0; i < data.unwrap() - index; i++){ 53 | const element = bytesReader.readInto(); 54 | this.values.push(element.unwrap()); 55 | } 56 | } 57 | /** 58 | * @description Instantiates ScaleBoolArray from u8[] SCALE encoded bytes (Decode) 59 | */ 60 | static fromU8a (input: u8[]): BoolArray { 61 | return AbstractArray.fromU8a(input); 62 | } 63 | 64 | @inline @operator('==') 65 | static eq(a: BoolArray, b: BoolArray): bool { 66 | return a.eq(b); 67 | } 68 | 69 | @inline @operator('!=') 70 | static notEq(a: BoolArray, b: BoolArray): bool { 71 | return a.notEq(b); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /assembly/Arrays/ByteArray.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2020 LimeChain Ltd. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { BytesReader } from ".."; 16 | import { Byte } from "../Byte"; 17 | import { CompactInt } from "../Int"; 18 | import { DecodedData } from "../interfaces/DecodedData"; 19 | import { AbstractArray } from "./AbstractArray"; 20 | 21 | // @ts-ignore 22 | export class ByteArray extends AbstractArray { 23 | 24 | /** 25 | * @description Return hex representation of ByteArray 26 | */ 27 | public toHexString (): string { 28 | let result = "0x"; 29 | for (let i = 0; i < super.values.length; i++) { 30 | const str = super.values[i].toString(16); 31 | if (str.length == 1) { 32 | result += "0"; 33 | } 34 | 35 | result += str; 36 | } 37 | 38 | return result; 39 | } 40 | /** 41 | * @description BoolArray elements decryption implementation 42 | */ 43 | public decodeElement(value: u8[]): DecodedData { 44 | const scaleByte = Byte.fromU8a([value[0]]); 45 | 46 | return new DecodedData( 47 | scaleByte.unwrap(), 48 | scaleByte.encodedLength() 49 | ) 50 | } 51 | 52 | /** 53 | * @description Returns encoded byte length of the type 54 | */ 55 | public encodedLength(): i32{ 56 | return (new CompactInt(this.values.length).encodedLength()) + super.values.length; 57 | } 58 | 59 | /** 60 | * @description Non-static constructor method used to populate defined properties of the model 61 | * @param bytes SCALE encoded bytes 62 | * @param index index to start decoding the bytes from 63 | */ 64 | populateFromBytes(bytes: u8[], index: i32 = 0): void { 65 | const bytesReader = new BytesReader(bytes.slice(index)); 66 | const data = bytesReader.readInto(); 67 | 68 | for(let i: i32 = 0; i < data.unwrap(); i++){ 69 | const element: Byte = bytesReader.readInto(); 70 | this.values.push(element.unwrap()); 71 | } 72 | } 73 | /** 74 | * @description Instantiates ScaleByteArray from u8[] SCALE encoded bytes (Decode) 75 | */ 76 | static fromU8a(input: u8[], index: i32 = 0): ByteArray { 77 | return AbstractArray.fromU8a(input.slice(index)); 78 | } 79 | 80 | @inline @operator('==') 81 | static eq(a: ByteArray, b: ByteArray): bool { 82 | return a.eq(b); 83 | } 84 | 85 | @inline @operator('!=') 86 | static notEq(a: ByteArray, b: ByteArray): bool { 87 | return a.notEq(b); 88 | } 89 | } 90 | 91 | -------------------------------------------------------------------------------- /assembly/Arrays/IntArray.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2020 LimeChain Ltd. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { BytesReader } from ".."; 16 | import { CompactInt } from "../Int/CompactInt"; 17 | import { DecodedData } from "../interfaces/DecodedData"; 18 | import { AbstractArray } from "./AbstractArray"; 19 | 20 | 21 | // @ts-ignore 22 | export class IntArray extends AbstractArray { 23 | 24 | /** 25 | * @description BoolArray elements decryption implementation 26 | */ 27 | public decodeElement (value: u8[]): DecodedData { 28 | const compactInt = CompactInt.fromU8a(value); 29 | 30 | return new DecodedData( 31 | compactInt.unwrap(), 32 | compactInt.encodedLength() 33 | ) 34 | } 35 | 36 | /** 37 | * @description Returns encoded byte length of the type 38 | */ 39 | public encodedLength(): i32{ 40 | let len: i32 = new CompactInt(this.values.length).encodedLength(); 41 | for (let i: i32 = 0; i < this.values.length; i++){ 42 | const value = new CompactInt(this.values[i]); 43 | len += value.encodedLength(); 44 | } 45 | return len; 46 | } 47 | /** 48 | * @description Non-static constructor method used to populate defined properties of the model 49 | * @param bytes SCALE encoded bytes 50 | * @param index index to start decoding the bytes from 51 | */ 52 | populateFromBytes(bytes: u8[], index: i32 = 0): void { 53 | const bytesReader = new BytesReader(bytes.slice(index)); 54 | const data = bytesReader.readInto(); 55 | 56 | for(let i: i32 = 0; i < data.unwrap(); i++){ 57 | const element: CompactInt = bytesReader.readInto(); 58 | this.values.push(element.unwrap()); 59 | } 60 | } 61 | /** 62 | * @description Instantiates ScaleIntArray from u8[] SCALE encoded bytes (Decode) 63 | */ 64 | static fromU8a (input: u8[]): IntArray { 65 | return AbstractArray.fromU8a(input); 66 | } 67 | 68 | @inline @operator('==') 69 | static eq(a: IntArray, b: IntArray): bool { 70 | return a.eq(b); 71 | } 72 | 73 | @inline @operator('!=') 74 | static notEq(a: IntArray, b: IntArray): bool { 75 | return a.notEq(b); 76 | } 77 | } 78 | 79 | -------------------------------------------------------------------------------- /assembly/Arrays/StringArray.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2020 LimeChain Ltd. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { BytesReader, CompactInt } from ".."; 16 | import { DecodedData } from "../interfaces/DecodedData"; 17 | import { ScaleString } from "../ScaleString"; 18 | import { Bytes } from "../utils/Bytes"; 19 | import { AbstractArray } from "./AbstractArray"; 20 | 21 | 22 | // @ts-ignore 23 | export class StringArray extends AbstractArray{ 24 | 25 | /** 26 | * @description BoolArray elements decryption implementation 27 | */ 28 | public decodeElement (value: u8[]): DecodedData { 29 | const stringLength = Bytes.decodeCompactInt(value); 30 | const encodedStringLength = i32(stringLength.decBytes + stringLength.value); 31 | 32 | return new DecodedData( 33 | ScaleString.fromU8a(value.slice(0, encodedStringLength)).toString(), 34 | encodedStringLength 35 | ) 36 | } 37 | 38 | /** 39 | * @description Returns encoded byte length of the type 40 | */ 41 | public encodedLength(): i32{ 42 | let len: i32 = new CompactInt(this.values.length).encodedLength(); 43 | for (let i: i32 = 0; i < this.values.length; i++){ 44 | const value = new ScaleString(this.values[i]); 45 | len += value.encodedLength(); 46 | } 47 | return len; 48 | } 49 | 50 | /** 51 | * @description Non-static constructor method used to populate defined properties of the model 52 | * @param bytes SCALE encoded bytes 53 | * @param index index to start decoding the bytes from 54 | */ 55 | populateFromBytes(bytes: u8[], index: i32 = 0): void { 56 | const bytesReader = new BytesReader(bytes.slice(index)); 57 | const data = bytesReader.readInto(); 58 | 59 | for(let i: i32 = 0; i < data.unwrap(); i++){ 60 | const element: ScaleString = bytesReader.readInto(); 61 | this.values.push(element.toString()); 62 | } 63 | } 64 | 65 | /** 66 | * @description Instantiates ScaleStringArray from u8[] SCALE encoded bytes (Decode) 67 | */ 68 | static fromU8a (input: u8[]): StringArray { 69 | return AbstractArray.fromU8a(input); 70 | } 71 | 72 | @inline @operator('==') 73 | static eq(a: StringArray, b: StringArray): bool { 74 | return a.eq(b); 75 | } 76 | 77 | @inline @operator('!=') 78 | static notEq(a: StringArray, b: StringArray): bool { 79 | return a.notEq(b); 80 | } 81 | } -------------------------------------------------------------------------------- /assembly/Arrays/UInt128Array.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2020 LimeChain Ltd. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { u128 } from "as-bignum"; 16 | import { BytesReader, CompactInt } from ".."; 17 | import { DecodedData } from "../interfaces/DecodedData"; 18 | import { UInt128 } from "../UInt/UInt128"; 19 | import { BIT_LENGTH } from "../utils/Bytes"; 20 | import { AbstractArray } from "./AbstractArray"; 21 | 22 | // @ts-ignore 23 | export class UInt128Array extends AbstractArray { 24 | 25 | /** 26 | * @description BoolArray elements decryption implementation 27 | */ 28 | public decodeElement(value: u8[]): DecodedData { 29 | const u128Instance = UInt128.fromU8a(value.slice(0, BIT_LENGTH.INT_128)); 30 | 31 | return new DecodedData( 32 | u128Instance.unwrap(), 33 | u128Instance.encodedLength() 34 | ) 35 | } 36 | 37 | /** 38 | * @description Non-static constructor method used to populate defined properties of the model 39 | * @param bytes SCALE encoded bytes 40 | * @param index index to start decoding the bytes from 41 | */ 42 | populateFromBytes(bytes: u8[], index: i32 = 0): void { 43 | const bytesReader = new BytesReader(bytes.slice(index)); 44 | const data = bytesReader.readInto(); 45 | for(let i: i32 = 0; i < data.unwrap(); i++){ 46 | const element: UInt128 = BytesReader.decodeInto(bytesReader.readBytes(BIT_LENGTH.INT_128)); 47 | this.values.push(element.unwrap()); 48 | } 49 | } 50 | 51 | /** 52 | * @description Instantiates ScaleIntArray from u8[] SCALE encoded bytes (Decode) 53 | */ 54 | static fromU8a (input: u8[]): UInt128Array { 55 | return AbstractArray.fromU8a(input); 56 | } 57 | 58 | /** 59 | * @description Returns encoded byte length of the type 60 | */ 61 | public encodedLength(): i32{ 62 | return (new CompactInt(this.values.length).encodedLength()) + super.values.length * BIT_LENGTH.INT_128; 63 | } 64 | 65 | @inline @operator('==') 66 | static eq(a: UInt128Array, b: UInt128Array): bool { 67 | return a.eq(b); 68 | } 69 | 70 | @inline @operator('!=') 71 | static notEq(a: UInt128Array, b: UInt128Array): bool { 72 | return a.notEq(b); 73 | } 74 | } 75 | 76 | -------------------------------------------------------------------------------- /assembly/Arrays/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./BoolArray"; 2 | export * from "./ByteArray"; 3 | export * from "./IntArray"; 4 | export * from "./StringArray"; 5 | export * from "./UInt128Array"; 6 | -------------------------------------------------------------------------------- /assembly/Bool.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2020 LimeChain Ltd. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { UnwrappableCodec } from "./interfaces/UnwrappableCodec"; 16 | 17 | /** Representation for a boolean value in the system. */ 18 | export class Bool implements UnwrappableCodec { 19 | 20 | private _value: bool; 21 | 22 | constructor (value: bool = false) { 23 | this._value = value; 24 | } 25 | 26 | /** 27 | * @description Returns the inner native value 28 | */ 29 | public unwrap(): bool{ 30 | return this._value; 31 | } 32 | 33 | /** Encodes the value as u8[] as per the SCALE codec specification 34 | * true -> [1] 35 | * false -> [0] 36 | */ 37 | toU8a (): u8[] { 38 | let bytesEncoded = new Array(1); 39 | bytesEncoded[0] = this._value ? 0x01 : 0x00; 40 | return bytesEncoded; 41 | } 42 | 43 | /** 44 | * @description Non-static constructor method used to populate defined properties of the model. 45 | * @param bytes SCALE encoded bytes 46 | * @param index index to start decoding the bytes from 47 | */ 48 | public populateFromBytes(bytes: u8[], index: i32 = 0): void{ 49 | assert(bytes.length > 0 && (bytes[index] == 1 || bytes[index] == 0), 'Bool: Cannot decode invalid input'); 50 | this._value = bytes[index] == 1; 51 | } 52 | 53 | /** 54 | * @description Returns the string representation of the value 55 | */ 56 | toString (): string { 57 | return this._value.toString(); 58 | } 59 | 60 | eq(other: Bool): bool { 61 | return this._value == other.unwrap(); 62 | } 63 | 64 | notEq(other: Bool): bool { 65 | return this._value != other.unwrap(); 66 | } 67 | /** 68 | * @description The length of Uint8Array when the value is encoded 69 | */ 70 | public encodedLength (): i32 { 71 | return 1; 72 | } 73 | 74 | /** Instantiates new Bool from u8[] SCALE encoded bytes */ 75 | static fromU8a (value: u8[], index: i32 = 0): Bool { 76 | assert(value.length - index > 0 && (value[index] == 1 || value[index] == 0), 'Bool: Cannot decode invalid input'); 77 | 78 | return new Bool(value[index] == 1); 79 | } 80 | 81 | @inline @operator('==') 82 | static eq(a: Bool, b: Bool): bool { 83 | return a.eq(b); 84 | } 85 | 86 | @inline @operator('!=') 87 | static notEq(a: Bool, b: Bool): bool { 88 | return a.notEq(b); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /assembly/Byte.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2020 LimeChain Ltd. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { UnwrappableCodec } from "./interfaces/UnwrappableCodec"; 16 | import { BIT_LENGTH } from "./utils/Bytes"; 17 | 18 | export class Byte implements UnwrappableCodec{ 19 | 20 | private _value: u8; 21 | protected bitLength: i32; 22 | 23 | constructor (value: u8 = 0) { 24 | this._value = value; 25 | this.bitLength = BIT_LENGTH.INT_8; 26 | } 27 | 28 | /** 29 | * @description Returns the inner native value 30 | */ 31 | public unwrap(): u8{ 32 | return this._value; 33 | } 34 | 35 | /** 36 | * @description Encodes Byte as u8[] as per the SCALE codec specification 37 | */ 38 | public toU8a (): u8[] { 39 | return [this._value]; 40 | } 41 | /** 42 | * @description Non-static constructor method used to populate defined properties of the model 43 | * @param bytes SCALE encoded bytes 44 | * @param index index to start decoding the bytes from 45 | */ 46 | public populateFromBytes(bytes: u8[], index: i32 = 0): void{ 47 | assert(bytes.length - index > 0, 'Bool: Cannot decode invalid input'); 48 | this._value = bytes[index]; 49 | } 50 | 51 | eq(other: Byte): bool { 52 | return this._value == other.unwrap(); 53 | } 54 | 55 | notEq(other: Byte): bool { 56 | return this._value != other.unwrap(); 57 | } 58 | 59 | /** 60 | * @description The length of Byte when the value is encoded 61 | */ 62 | public encodedLength (): i32 { 63 | return this.bitLength; 64 | } 65 | 66 | /** Instantiates new Byte from u8[] SCALE encoded bytes */ 67 | static fromU8a (value: u8[], index: i32 = 0): Byte { 68 | assert(value.length - index > 0, 'Byte: cannot decode invalid type'); 69 | return new Byte(value[index]); 70 | } 71 | 72 | @inline @operator('==') 73 | static eq(a: Byte, b: Byte): bool { 74 | return a.eq(b); 75 | } 76 | 77 | @inline @operator('!=') 78 | static notEq(a: Byte, b: Byte): bool { 79 | return a.notEq(b); 80 | } 81 | } -------------------------------------------------------------------------------- /assembly/BytesReader.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2020 LimeChain Ltd. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { Codec } from '.'; 16 | 17 | /** 18 | * @description BytesReader class that helps reading bytes into SCALE Codec types 19 | */ 20 | export class BytesReader{ 21 | /** 22 | * u8 bytes 23 | */ 24 | public readonly bytes: u8[]; 25 | /** 26 | * Current index to start decoding from 27 | */ 28 | private index: i32 = 0; 29 | 30 | constructor(bytes: u8[]){ 31 | this.bytes = bytes; 32 | } 33 | 34 | /** 35 | * @description Reads bytes into a given Type 36 | */ 37 | readInto(): T{ 38 | const instance: T = BytesReader.decodeInto(this.bytes, this.index); 39 | this.index += instance.encodedLength(); 40 | return instance; 41 | } 42 | /** 43 | * Returns the unread bytes from the reader 44 | */ 45 | getLeftoverBytes(): u8[]{ 46 | return this.bytes.slice(this.index); 47 | } 48 | /** 49 | * Read custom sized array of raw bytes 50 | * @param size byte array size 51 | */ 52 | readBytes(size: i32): u8[]{ 53 | const bytes: u8[] = this.bytes.slice(this.index, this.index + size); 54 | this.index += size; 55 | return bytes; 56 | } 57 | /** 58 | * @description Static variant of readInto() method 59 | * @param bytes 60 | * @param index 61 | */ 62 | static decodeInto(bytes: u8[], index: i32 = 0): T{ 63 | const instance: T = instantiate(); 64 | instance.populateFromBytes(bytes, index); 65 | return instance; 66 | } 67 | } -------------------------------------------------------------------------------- /assembly/Hash.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2020 LimeChain Ltd. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { UnwrappableCodec } from './interfaces/UnwrappableCodec'; 16 | import { Bytes } from './utils/Bytes'; 17 | 18 | export class Hash implements UnwrappableCodec> { 19 | 20 | private _values: Array; 21 | 22 | constructor(value: u8[] = []) { 23 | this._values = new Array(32); 24 | Bytes.copy(value, this._values); 25 | } 26 | 27 | /** 28 | * @description Returns the inner native value 29 | */ 30 | public unwrap(): Array{ 31 | return this._values; 32 | } 33 | 34 | /** 35 | * @description Encodes Hash as u8[] as per the SCALE codec specification 36 | */ 37 | public toU8a (): u8[] { 38 | const result: u8[] = new Array(this.encodedLength()); 39 | Bytes.copy(this._values, result); 40 | 41 | return result; 42 | } 43 | 44 | /** 45 | * @description Non-static constructor method used to populate defined properties of the model. 46 | * @param bytes SCALE encoded bytes 47 | * @param index index to start decoding the bytes from 48 | */ 49 | public populateFromBytes(bytes: u8[], index: i32 = 0): void{ 50 | assert(bytes.length - index >= 0, "Hash: Empty bytes array provided"); 51 | this._values = new Array(32); 52 | Bytes.copy(bytes, this._values, 0, index); 53 | } 54 | 55 | /** 56 | * @description Return string representation of Hash 57 | */ 58 | public toString (): string { 59 | return "0x" + this._values.join(''); 60 | } 61 | 62 | /** 63 | * @description Instantiate Hash from bytes cropped from the left. 64 | */ 65 | static bytesToHash (bytes: u8[]): Hash { 66 | let hash = new Hash([]); 67 | if (bytes.length > 32) { 68 | bytes = bytes.slice(bytes.length - 32); 69 | } 70 | 71 | const position: i32 = 32 - bytes.length; 72 | Bytes.copy(bytes, hash.unwrap(), position); 73 | return hash; 74 | } 75 | 76 | /** 77 | * @description The length of encoded Hash 78 | */ 79 | public encodedLength (): i32 { 80 | return 32; 81 | } 82 | 83 | /** 84 | * @description Instantiates Hash from u8[] SCALE encoded bytes 85 | * @param input SCALE encoded bytes 86 | * @param index an index of input to start decoding from 87 | */ 88 | static fromU8a (input: u8[], index: i32 = 0): Hash { 89 | assert(input.length - index >= 0, "Hash: Empty bytes array provided"); 90 | return new Hash(input.slice(index)); 91 | } 92 | 93 | eq(other: Hash): bool { 94 | let areEqual = true; 95 | for (let i = 0; i < this.unwrap().length; i++) { 96 | if (this.unwrap()[i] != other.unwrap()[i]) { 97 | areEqual = false; 98 | break; 99 | } 100 | } 101 | return areEqual; 102 | } 103 | 104 | notEq(other: Hash): bool { 105 | return !this.eq(other); 106 | } 107 | 108 | @inline @operator('==') 109 | static eq(a: Hash, b: Hash): bool { 110 | return a.eq(b); 111 | } 112 | 113 | @inline @operator('!=') 114 | static notEq(a: Hash, b: Hash): bool { 115 | return a.notEq(b); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /assembly/Int/CompactInt.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2020 LimeChain Ltd. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { UnwrappableCodec } from "../interfaces/UnwrappableCodec"; 16 | import { BIT_LENGTH, Bytes } from "../utils/Bytes"; 17 | import { BytesBuffer } from "../utils/BytesBuffer"; 18 | 19 | /** 20 | * @description Representation for a CompactInt value in the system. 21 | */ 22 | export class CompactInt implements UnwrappableCodec { 23 | 24 | private _value: i64; 25 | protected bitLength: i32; 26 | 27 | constructor (value: i64 = 0) { 28 | this._value = value; 29 | this.bitLength = CompactInt._computeBitLength(value); 30 | } 31 | 32 | /** 33 | * @description Return inner native value 34 | */ 35 | unwrap(): i64{ 36 | return this._value; 37 | } 38 | 39 | /** 40 | * @description Encodes the value as u8[] as per the SCALE codec specification 41 | */ 42 | public toU8a (): u8[] { 43 | const bytesBuffer = new BytesBuffer(); 44 | bytesBuffer.encodeCompactInt(this._value); 45 | 46 | return bytesBuffer.bytes; 47 | } 48 | /** 49 | * @description Non-static constructor method used to populate defined properties of the model 50 | * @param bytes SCALE encoded bytes 51 | * @param index index to start decoding the bytes from 52 | */ 53 | public populateFromBytes(bytes: u8[], index: i32 = 0): void{ 54 | assert(bytes.length - index > 0, "CompactInt: Empty bytes array provided"); 55 | const decodedData = Bytes.decodeCompactInt(bytes, index); 56 | this._value = decodedData.value; 57 | this.bitLength = CompactInt._computeBitLength(decodedData.value); 58 | } 59 | /** 60 | * @description Returns the string representation of the value 61 | */ 62 | toString (): string { 63 | return this._value.toString(); 64 | } 65 | 66 | /** 67 | * Internal private function to compute bit length of the value 68 | * @param value 69 | */ 70 | static _computeBitLength(value: u64): i32 { 71 | if (value < 1 << 6) return BIT_LENGTH.INT_8; 72 | else if (value < 1 << 14) return BIT_LENGTH.INT_16; 73 | else if (value < 1 << 30) return BIT_LENGTH.INT_32; 74 | else { 75 | return BIT_LENGTH.INT_64; 76 | } 77 | } 78 | /** 79 | * @description The length of Int when the value is encoded 80 | */ 81 | public encodedLength (): i32 { 82 | return this.bitLength; 83 | } 84 | 85 | 86 | eq(other: CompactInt): bool { 87 | return this._value == other.unwrap(); 88 | } 89 | 90 | notEq(other: CompactInt): bool { 91 | return this._value != other.unwrap(); 92 | } 93 | 94 | /** 95 | * @description Instantiates Compact Int from u8[] SCALE encoded bytes 96 | * Compact Int decodes int8, int16, int32, int64 size correctly 97 | * @param input SCALE encoded bytes 98 | * @param index an index of input to start decoding from 99 | */ 100 | static fromU8a (value: u8[], index: i32 = 0): CompactInt { 101 | assert(value.length - index > 0, "CompactInt: Empty bytes array provided"); 102 | const decodedData = Bytes.decodeCompactInt(value, index); 103 | return new CompactInt(decodedData.value); 104 | } 105 | 106 | @inline @operator('==') 107 | static eq(a: CompactInt, b: CompactInt): bool { 108 | return a.eq(b); 109 | } 110 | 111 | @inline @operator('!=') 112 | static notEq(a: CompactInt, b: CompactInt): bool { 113 | return a.notEq(b); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /assembly/Int/Int16.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2020 LimeChain Ltd. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { AbstractInt } from "../AbstractInt"; 16 | import { BIT_LENGTH, Bytes } from "../utils/Bytes"; 17 | 18 | /** Representation for a Int16 value in the system. */ 19 | export class Int16 extends AbstractInt { 20 | 21 | constructor (value: i16 = 0) { 22 | super(value, BIT_LENGTH.INT_16) 23 | } 24 | 25 | /** 26 | * @description Instantiates new Int16 from u8[] SCALE encoded bytes 27 | * NOTE: if the length of the provided value is less than the byte length of the Int16, 28 | * it is filled with 0 bytes 29 | * */ 30 | static fromU8a (value: u8[], index:i32 = 0): Int16 { 31 | assert(value.length - index > 0, 'Int16: Empty bytes array provided'); 32 | var res = Bytes.toUint(value, BIT_LENGTH.INT_16, index); 33 | return new Int16(res); 34 | } 35 | 36 | @inline @operator('==') 37 | static eq(a: Int16, b: Int16): bool { 38 | return a.eq(b); 39 | } 40 | 41 | @inline @operator('!=') 42 | static notEq(a: Int16, b: Int16): bool { 43 | return a.notEq(b); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /assembly/Int/Int32.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2020 LimeChain Ltd. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { AbstractInt } from "../AbstractInt"; 16 | import { BIT_LENGTH, Bytes } from "../utils/Bytes"; 17 | 18 | /** Representation for a Int32 value in the system. */ 19 | export class Int32 extends AbstractInt { 20 | 21 | constructor (value: i32 = 0) { 22 | super(value, BIT_LENGTH.INT_32) 23 | } 24 | 25 | /** 26 | * @description Instantiates new Int32 from u8[] SCALE encoded bytes 27 | * NOTE: if the length of the provided value is less than the byte length of the Int32, 28 | * it is filled with 0 bytes 29 | */ 30 | static fromU8a (value: u8[], index: i32 = 0): Int32 { 31 | assert(value.length - index > 0, 'Int32: Empty bytes array provided'); 32 | var res = Bytes.toUint(value, BIT_LENGTH.INT_32, index); 33 | return new Int32(res); 34 | } 35 | 36 | @inline @operator('==') 37 | static eq(a: Int32, b: Int32): bool { 38 | return a.eq(b); 39 | } 40 | 41 | @inline @operator('!=') 42 | static notEq(a: Int32, b: Int32): bool { 43 | return a.notEq(b); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /assembly/Int/Int64.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2020 LimeChain Ltd. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { AbstractInt } from "../AbstractInt"; 16 | import { BIT_LENGTH, Bytes } from "../utils/Bytes"; 17 | 18 | /** Representation for a Int64 value in the system. */ 19 | export class Int64 extends AbstractInt { 20 | 21 | constructor (value: i64 = 0) { 22 | super(value, BIT_LENGTH.INT_64) 23 | } 24 | 25 | /** 26 | * @description Instantiates new Int64 from u8[] SCALE encoded bytes 27 | * NOTE: if the length of the provided value is less than the byte length of the Int64, 28 | * it is filled with 0 bytes 29 | */ 30 | static fromU8a (value: u8[], index: i32 = 0): Int64 { 31 | assert(value.length - index > 0, "Int64: Empty bytes array provided"); 32 | var res = Bytes.toUint(value, BIT_LENGTH.INT_64, index); 33 | return new Int64(res); 34 | } 35 | 36 | @inline @operator('==') 37 | static eq(a: Int64, b: Int64): bool { 38 | return a.eq(b); 39 | } 40 | 41 | @inline @operator('!=') 42 | static notEq(a: Int64, b: Int64): bool { 43 | return a.notEq(b); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /assembly/Int/Int8.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2020 LimeChain Ltd. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { AbstractInt } from "../AbstractInt"; 16 | import { BIT_LENGTH } from "../utils/Bytes"; 17 | 18 | /** Representation for a Int8 value in the system. */ 19 | export class Int8 extends AbstractInt { 20 | 21 | constructor (value: i8 = 0) { 22 | super(value, BIT_LENGTH.INT_8) 23 | } 24 | 25 | /** 26 | * @description Instantiates new Int8 from u8[] SCALE encoded bytes 27 | * NOTE: if the length of the provided value is less than the byte length of the Int8, 28 | * it is filled with 0 bytes 29 | * */ 30 | static fromU8a (value: u8[], index: i32 = 0): Int8 { 31 | assert(value.length - index > 0, 'Int8: empty bytes array provided'); 32 | return new Int8(value[index]); 33 | } 34 | 35 | @inline @operator('==') 36 | static eq(a: Int8, b: Int8): bool { 37 | return a.eq(b); 38 | } 39 | 40 | @inline @operator('!=') 41 | static notEq(a: Int8, b: Int8): bool { 42 | return a.notEq(b); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /assembly/Int/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./CompactInt"; 2 | export * from "./Int8"; 3 | export * from "./Int16"; 4 | export * from "./Int32"; 5 | export * from "./Int64"; 6 | -------------------------------------------------------------------------------- /assembly/ScaleMap.ts: -------------------------------------------------------------------------------- 1 | import { CompactInt } from "."; 2 | import { BytesReader } from "./BytesReader"; 3 | import { Codec } from "./interfaces/Codec"; 4 | import { UnwrappableCodec } from "./interfaces/UnwrappableCodec"; 5 | 6 | /** 7 | * @description SCALE Codec support for native Map type 8 | */ 9 | export class ScaleMap implements UnwrappableCodec>{ 10 | /** 11 | * Map value of ScaleMap 12 | */ 13 | public readonly data: Map; 14 | 15 | constructor(data: Map = new Map()){ 16 | this.data = data; 17 | } 18 | 19 | /** 20 | * @description return underlying native type 21 | */ 22 | unwrap(): Map{ 23 | return this.data; 24 | } 25 | /** 26 | * Check if ScaleMap has given key 27 | * @param key 28 | */ 29 | has(key: K): bool{ 30 | return this.data.has(key); 31 | } 32 | /** 33 | * Get the value of given key 34 | * @param key 35 | */ 36 | get(key: K): V{ 37 | return this.data.get(key); 38 | } 39 | /** 40 | * Set this value to the given key 41 | * @param key 42 | * @param value 43 | */ 44 | set(key: K, value: V): void{ 45 | this.data.set(key, value); 46 | } 47 | /** 48 | * Delete the given key with its value from the ScaleMap 49 | * @param key 50 | */ 51 | delete(key: K): void{ 52 | this.data.delete(key); 53 | } 54 | /** 55 | * Get array of keys of the ScaleMap 56 | */ 57 | keys(): K[]{ 58 | return this.data.keys(); 59 | } 60 | /** 61 | * Get array of values of the ScaleMap 62 | */ 63 | values(): V[]{ 64 | return this.data.values(); 65 | } 66 | /** 67 | * The number of bytes this Map has 68 | */ 69 | encodedLength(): i32{ 70 | return this.toU8a().length; 71 | } 72 | /** 73 | * Convert ScaleMap to u8[] 74 | * Length is encoded first, followed by all key and value encodings concatenated 75 | */ 76 | toU8a(): u8[]{ 77 | let result: u8[] = []; 78 | let keys: K[] = this.data.keys(); 79 | let lenData: CompactInt = new CompactInt(keys.length); 80 | result = result.concat(lenData.toU8a()); 81 | for(let i = 0; i < keys.length; i++){ 82 | result = result 83 | .concat(keys[i].toU8a()) 84 | .concat(this.data.get(keys[i]).toU8a()); 85 | } 86 | return result; 87 | } 88 | 89 | /** 90 | * @description Non-static constructor 91 | * @param bytes 92 | * @param index 93 | */ 94 | populateFromBytes(bytes: u8[], index: i32 = 0): void { 95 | const bytesReader = new BytesReader(bytes.slice(index)); 96 | const lenComp = bytesReader.readInto(); 97 | for(let i: i32 = 0; i < lenComp.unwrap(); i++){ 98 | const key = bytesReader.readInto(); 99 | const value = bytesReader.readInto(); 100 | this.data.set(key, value); 101 | } 102 | } 103 | /** 104 | * @description Overloaded == operator 105 | * @param a instance of ExtrinsicData 106 | * @param b Instance of ExtrinsicData 107 | */ 108 | eq(other: ScaleMap): bool { 109 | let areEqual = true; 110 | const aKeys = this.data.keys(); 111 | const bKeys = other.data.keys(); 112 | 113 | if(aKeys.length != bKeys.length){ 114 | return false; 115 | } 116 | for (let i=0; i): bool { 131 | return !this.eq(other); 132 | } 133 | 134 | static fromU8a(input: u8[], index: i32 = 0): ScaleMap{ 135 | const data = new Map(); 136 | const bytesReader = new BytesReader(input); 137 | const lenComp = bytesReader.readInto(); 138 | 139 | for(let i: i32 = 0; i(); 141 | const value = bytesReader.readInto(); 142 | data.set(key, value); 143 | } 144 | return new ScaleMap(data); 145 | } 146 | } -------------------------------------------------------------------------------- /assembly/ScaleString.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2020 LimeChain Ltd. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { ByteArray } from "./Arrays/ByteArray"; 16 | import { Bytes } from "./utils/Bytes"; 17 | 18 | export class ScaleString extends ByteArray { 19 | 20 | private _valueStr: string; 21 | 22 | constructor (input: string = "") { 23 | super([]); 24 | this._valueStr = input; 25 | 26 | const inputBuffer: ArrayBuffer = String.UTF8.encode(input); 27 | const u8Input = Uint8Array.wrap(inputBuffer); 28 | 29 | for (let i = 0; i < u8Input.length; i++) { 30 | this.values[i] = u8Input[i]; 31 | } 32 | } 33 | /** 34 | * @description Non-static constructor method used to populate defined properties of the model 35 | * @param bytes SCALE encoded bytes 36 | * @param index index to start decoding the bytes from 37 | */ 38 | populateFromBytes(bytes: u8[], index: i32 = 0): void{ 39 | // constructor 40 | this._valueStr = ScaleString._computeValueStr(bytes, index); 41 | const inputBuffer: ArrayBuffer = String.UTF8.encode(this._valueStr); 42 | const u8Input = Uint8Array.wrap(inputBuffer); 43 | 44 | for (let i = 0; i < u8Input.length; i++) { 45 | this.values[i] = u8Input[i]; 46 | } 47 | } 48 | 49 | /** 50 | * @description Returns the string representation 51 | */ 52 | toString (): string { 53 | return this._valueStr; 54 | } 55 | 56 | /** 57 | * Internal private function to compute the string value from the bytes 58 | * @param bytes 59 | * @param index 60 | */ 61 | static _computeValueStr(bytes: u8[], index: i32 = 0): string { 62 | const len = Bytes.decodeCompactInt(bytes, index); 63 | const bytesLength = i32(len.value); 64 | const stringStart = i32(len.decBytes); 65 | assert(bytes.length - index - len.decBytes >= 1, "ScaleString: Incorrectly encoded input"); 66 | const buff = new Uint8Array(bytesLength); 67 | Bytes.copyToTyped(bytes, buff, 0, index+stringStart); 68 | return String.UTF8.decode(buff.buffer); 69 | } 70 | /** 71 | * @description Instantiates String from u8[] SCALE encoded bytes (Decode) 72 | */ 73 | static fromU8a (input: u8[], index: i32 = 0): ScaleString { 74 | return new ScaleString(ScaleString._computeValueStr(input, index)); 75 | } 76 | 77 | @inline @operator('==') 78 | static eq(a: ScaleString, b: ScaleString): bool { 79 | return a.eq(b); 80 | } 81 | 82 | @inline @operator('!=') 83 | static notEq(a: ScaleString, b: ScaleString): bool { 84 | return a.notEq(b); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /assembly/UInt/UInt128.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2020 LimeChain Ltd. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { u128 } from "as-bignum"; 16 | import { UnwrappableCodec } from "../interfaces/UnwrappableCodec"; 17 | import { ArrayUtils } from "../utils/Arrays"; 18 | import { BIT_LENGTH } from "../utils/Bytes"; 19 | 20 | /** Representation for a UInt128 value in the system. */ 21 | export class UInt128 implements UnwrappableCodec { 22 | 23 | private _value: u128; 24 | 25 | constructor (value: u128 = u128.Zero) { 26 | this._value = value; 27 | } 28 | 29 | /** 30 | * @description Return inner value 31 | */ 32 | unwrap(): u128{ 33 | return this._value; 34 | } 35 | 36 | /** 37 | * @description Encodes the value as u8[] as per the SCALE codec specification 38 | * */ 39 | toU8a (): u8[] { 40 | return ArrayUtils.toU8Array(this._value.toUint8Array(false)); 41 | } 42 | 43 | toString(): string { 44 | return this._value.toString(); 45 | } 46 | /** 47 | * @description Non-static constructor method used to populate defined properties of the model 48 | * @param bytes SCALE encoded bytes 49 | * @param index index to start decoding the bytes from 50 | */ 51 | populateFromBytes(bytes: u8[], index: i32 = 0): void{ 52 | assert(bytes.length - index > 0, 'Invalid input: Byte array should not be empty'); 53 | this._value = u128.fromBytesLE(bytes.slice(index)); 54 | } 55 | /** 56 | * @description The length of Int when the value is encoded 57 | */ 58 | public encodedLength (): i32 { 59 | return BIT_LENGTH.INT_128; 60 | } 61 | 62 | /** Instantiates new UInt128 from u8[] SCALE encoded bytes */ 63 | static fromU8a(input: u8[], index: i32 = 0): UInt128 { 64 | assert(input.length - index != 0, 'Invalid input: Byte array should not be empty'); 65 | return new UInt128(u128.fromBytesLE(input.slice(index))); 66 | } 67 | 68 | eq(other: UInt128): bool { 69 | return this._value == other.unwrap(); 70 | } 71 | 72 | notEq(other: UInt128): bool { 73 | return this._value != other.unwrap(); 74 | } 75 | 76 | // Commonly used values of UInt128 77 | @inline static get Zero(): UInt128 { return new UInt128(u128.Zero); } 78 | @inline static get One(): UInt128 { return new UInt128(u128.One); } 79 | @inline static get Min(): UInt128 { return new UInt128(new u128()); } 80 | @inline static get Max(): UInt128 { return new UInt128(new u128(-1, -1)); } 81 | 82 | static eq(a: UInt128, b: UInt128): bool { 83 | return a.eq(b); 84 | } 85 | 86 | static notEq(a: UInt128, b: UInt128): bool { 87 | return a.notEq(b); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /assembly/UInt/UInt16.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2020 LimeChain Ltd. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { AbstractInt } from "../AbstractInt"; 16 | import { BIT_LENGTH, Bytes } from "../utils/Bytes"; 17 | 18 | /** Representation for a UInt16 value in the system. */ 19 | export class UInt16 extends AbstractInt { 20 | 21 | constructor (value: u16 = 0) { 22 | super(value, BIT_LENGTH.INT_16) 23 | } 24 | 25 | /** 26 | * @description Instantiates new UInt16 from u8[] SCALE encoded bytes 27 | * NOTE: if the length of the provided value is less than the byte length of the UInt16, 28 | * it is filled with 0 bytes 29 | */ 30 | static fromU8a (value: u8[], index: i32 = 0): UInt16 { 31 | assert(value.length - index > 0, 'UInt16: Invalid bytes provided'); 32 | var res = Bytes.toUint(value, BIT_LENGTH.INT_16, index); 33 | return new UInt16(res); 34 | } 35 | 36 | @inline @operator('==') 37 | static eq(a: UInt16, b: UInt16): bool { 38 | return a.eq(b); 39 | } 40 | 41 | @inline @operator('!=') 42 | static notEq(a: UInt16, b: UInt16): bool { 43 | return a.notEq(b); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /assembly/UInt/UInt32.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2020 LimeChain Ltd. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { AbstractInt } from "../AbstractInt"; 16 | import { BIT_LENGTH, Bytes } from "../utils/Bytes"; 17 | 18 | /** Representation for a UInt32 value in the system. */ 19 | export class UInt32 extends AbstractInt { 20 | 21 | constructor (value: u32 = 0) { 22 | super(value, BIT_LENGTH.INT_32) 23 | } 24 | 25 | /** 26 | * @description Instantiates new UInt32 from u8[] SCALE encoded bytes 27 | * NOTE: if the length of the provided value is less than the byte length of the UInt32, 28 | * it is filled with 0 bytes 29 | */ 30 | static fromU8a (value: u8[], index: i32 = 0): UInt32 { 31 | assert(value.length - index > 0, 'UInt32: Invalid bytes provided'); 32 | var res = Bytes.toUint(value, BIT_LENGTH.INT_32, index); 33 | return new UInt32(res); 34 | } 35 | 36 | @inline @operator('==') 37 | static eq(a: UInt32, b: UInt32): bool { 38 | return a.eq(b); 39 | } 40 | 41 | @inline @operator('!=') 42 | static notEq(a: UInt32, b: UInt32): bool { 43 | return a.notEq(b); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /assembly/UInt/UInt64.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2020 LimeChain Ltd. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { AbstractInt } from "../AbstractInt"; 16 | import { BIT_LENGTH, Bytes } from "../utils/Bytes"; 17 | 18 | /** Representation for a UInt64 value in the system. */ 19 | export class UInt64 extends AbstractInt { 20 | 21 | constructor (value: u64 = 0) { 22 | super(value, BIT_LENGTH.INT_64) 23 | } 24 | 25 | /** 26 | * @description Instantiates new UInt64 from u8[] SCALE encoded bytes 27 | * NOTE: if the length of the provided value is less than the byte length of the UInt64, 28 | * it is filled with 0 bytes 29 | */ 30 | static fromU8a (value: u8[], index: i32 = 0): UInt64 { 31 | assert(value.length - index > 0, "UInt64: invalid bytes provided"); 32 | var res = Bytes.toUint(value, BIT_LENGTH.INT_64, index); 33 | return new UInt64(res); 34 | } 35 | 36 | @inline @operator('==') 37 | static eq(a: UInt64, b: UInt64): bool { 38 | return a.eq(b); 39 | } 40 | 41 | @inline @operator('!=') 42 | static notEq(a: UInt64, b: UInt64): bool { 43 | return a.notEq(b); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /assembly/UInt/UInt8.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2020 LimeChain Ltd. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { AbstractInt } from "../AbstractInt"; 16 | import { BIT_LENGTH } from "../utils/Bytes"; 17 | 18 | /** Representation for a UInt8 value in the system. */ 19 | export class UInt8 extends AbstractInt { 20 | 21 | constructor (value: u8 = 0) { 22 | super(value, BIT_LENGTH.INT_8) 23 | } 24 | 25 | /** 26 | * @description Instantiates new UInt8 from u8[] SCALE encoded bytes 27 | * NOTE: if the length of the provided value is less than the byte length of the UInt8, 28 | * it is filled with 0 bytes 29 | */ 30 | static fromU8a (value: u8[], index: i32 = 0): UInt8 { 31 | assert(value.length - index > 0, 'Uint8: cannot decode invalid u8 encoded value'); 32 | return new UInt8(value[index]); 33 | } 34 | 35 | @inline @operator('==') 36 | static eq(a: UInt8, b: UInt8): bool { 37 | return a.eq(b); 38 | } 39 | 40 | @inline @operator('!=') 41 | static notEq(a: UInt8, b: UInt8): bool { 42 | return a.notEq(b); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /assembly/UInt/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./UInt8"; 2 | export * from "./UInt16"; 3 | export * from "./UInt32"; 4 | export * from "./UInt64"; 5 | export * from "./UInt128"; 6 | -------------------------------------------------------------------------------- /assembly/__tests__/Arrays/BoolArray.spec.ts: -------------------------------------------------------------------------------- 1 | import { BoolArray } from "../../Arrays/BoolArray"; 2 | 3 | describe("Bool Array", () => { 4 | 5 | it("should encode bool array", () => { 6 | const boolArray: BoolArray = new BoolArray([true, false, true]); 7 | expect>(boolArray.toU8a()).toStrictEqual([0x0c, 0x01, 0x00, 0x01]); 8 | }); 9 | 10 | it("should decode bool array", () => { 11 | const boolTest1: u8[] = [0x00]; 12 | expect(BoolArray.fromU8a(boolTest1)).toStrictEqual(new BoolArray([])); 13 | 14 | const boolTest2: u8[] = [0x0c, 0x01, 0x00, 0x01]; 15 | expect(BoolArray.fromU8a(boolTest2)).toStrictEqual(new BoolArray([true, false, true])); 16 | }); 17 | 18 | it("should decode bool array with populate method", () => { 19 | const boolArray1 = new BoolArray(); 20 | boolArray1.populateFromBytes([0x08, 0x00, 0x01]); 21 | expect(boolArray1).toStrictEqual(new BoolArray([false, true])); 22 | const boolArray = new BoolArray(); 23 | boolArray.populateFromBytes([0x0c, 0x00, 0x01, 0x01]); 24 | expect(boolArray).toStrictEqual(new BoolArray([false, true, true])); 25 | }) 26 | itThrows("should throw because of invalid bytes", () => { 27 | const boolTest: u8[] = [0x0c, 0x00, 0x01, 0xff]; 28 | BoolArray.fromU8a(boolTest); 29 | }); 30 | 31 | itThrows("should throw on incorrect encoding", () => { 32 | const boolTest: u8[] = [0x0c]; // Encoded length = 3, actual data length = 0 33 | BoolArray.fromU8a(boolTest); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /assembly/__tests__/Arrays/ByteArray.spec.ts: -------------------------------------------------------------------------------- 1 | import { ByteArray } from "../../Arrays/ByteArray"; 2 | 3 | describe("ByteArray", () => { 4 | 5 | it("should encode bytes array", () => { 6 | const TEST_DATA_VAL: Array> = [ 7 | [0x01, 0x01, 0x01], 8 | [0xff], 9 | [0x01, 0x01], 10 | appendEmptyBytesTo([], 32), 11 | appendEmptyBytesTo([], 64), 12 | appendEmptyBytesTo([], 16384) 13 | ]; 14 | 15 | const TEST_DATA_OUT: Array> = [ 16 | [0x0c, 0x01, 0x01, 0x01], 17 | [0x04, 0xff], 18 | [0x08, 0x01, 0x01], 19 | appendEmptyBytesTo([0x80], 32), 20 | appendEmptyBytesTo([0x01, 0x01], 64), 21 | appendEmptyBytesTo([0x02, 0x00, 0x01, 0x00], 16384) 22 | ]; 23 | 24 | const ENCODED_BYTES: Array = [ 25 | 4, 26 | 2, 27 | 3, 28 | 33, 29 | 66, 30 | 16388 31 | ]; 32 | 33 | for (let i = 0; i < TEST_DATA_VAL.length; i++) { 34 | const byteArray = new ByteArray(TEST_DATA_VAL[i]); 35 | const encodedBytes = byteArray.toU8a(); 36 | 37 | expect(encodedBytes.length).toStrictEqual(ENCODED_BYTES[i]); 38 | expect(encodedBytes).toStrictEqual(TEST_DATA_OUT[i]); 39 | } 40 | }); 41 | 42 | it("should decode bytes array", () => { 43 | const TEST_DATA_VAL: Array> = [ 44 | [0x04, 0x01], // Output: [0x01] 45 | [0x04, 0xff], // Output: [0xff] 46 | [0x08, 0x01, 0x01], // Output: [0x01, 0x01] 47 | [0xc, 0x01, 0x01, 0x1], // Output: [0x01, 0x01, 0x01] 48 | [0x28, 0x42, 0x15, 0x50, 0x1c, 0x37, 0x7e, 0xd8, 0x66, 0x98, 0x2e], // Output: [0x42, 0x15, 0x50, 0x1c, 0x37, 0x7e, 0xd8, 0x66, 0x98, 0x2e] 49 | appendEmptyBytesTo([0x01, 0x01], 64), // Output: appendEmptyBytesTo([], 64), 50 | appendEmptyBytesTo([0xfd, 0xff], 16383), // Output: appendEmptyBytesTo([], 16383), 51 | appendEmptyBytesTo([0x02, 0x00, 0x01, 0x00], 16384) // Output: appendEmptyBytesTo([], 16384), 52 | ]; 53 | 54 | const TEST_DATA_OUT: Array> = [ 55 | [0x01], 56 | [0xff], 57 | [0x01, 0x01], 58 | [0x01, 0x01, 0x1], 59 | [0x42, 0x15, 0x50, 0x1c, 0x37, 0x7e, 0xd8, 0x66, 0x98, 0x2e], 60 | appendEmptyBytesTo([], 64), 61 | appendEmptyBytesTo([], 16383), 62 | appendEmptyBytesTo([], 16384) 63 | ]; 64 | 65 | for (let i = 0; i < TEST_DATA_VAL.length; i++) { 66 | const byteArray = ByteArray.fromU8a(TEST_DATA_VAL[i]); 67 | expect(byteArray).toStrictEqual(new ByteArray(TEST_DATA_OUT[i])); 68 | } 69 | }); 70 | 71 | it("should decode byte array with populate method", () => { 72 | const TEST_DATA_VAL: Array> = [ 73 | [0x04, 0x01], // Output: [0x01] 74 | [0x04, 0xff], // Output: [0xff] 75 | [0x08, 0x01, 0x01], // Output: [0x01, 0x01] 76 | [0xc, 0x01, 0x01, 0x1], // Output: [0x01, 0x01, 0x01] 77 | [0x28, 0x42, 0x15, 0x50, 0x1c, 0x37, 0x7e, 0xd8, 0x66, 0x98, 0x2e], // Output: [0x42, 0x15, 0x50, 0x1c, 0x37, 0x7e, 0xd8, 0x66, 0x98, 0x2e] 78 | appendEmptyBytesTo([0x01, 0x01], 64), // Output: appendEmptyBytesTo([], 64), 79 | appendEmptyBytesTo([0xfd, 0xff], 16383), // Output: appendEmptyBytesTo([], 16383), 80 | appendEmptyBytesTo([0x02, 0x00, 0x01, 0x00], 16384) // Output: appendEmptyBytesTo([], 16384), 81 | ]; 82 | 83 | const TEST_DATA_OUT: Array> = [ 84 | [0x01], 85 | [0xff], 86 | [0x01, 0x01], 87 | [0x01, 0x01, 0x1], 88 | [0x42, 0x15, 0x50, 0x1c, 0x37, 0x7e, 0xd8, 0x66, 0x98, 0x2e], 89 | appendEmptyBytesTo([], 64), 90 | appendEmptyBytesTo([], 16383), 91 | appendEmptyBytesTo([], 16384) 92 | ]; 93 | 94 | for (let i = 0; i < TEST_DATA_VAL.length; i++) { 95 | const byteArray = new ByteArray(); 96 | byteArray.populateFromBytes(TEST_DATA_VAL[i]); 97 | expect(byteArray).toStrictEqual(new ByteArray(TEST_DATA_OUT[i])); 98 | } 99 | }) 100 | 101 | it("should return hex representation of byte array", () => { 102 | const byteArray = ByteArray.fromU8a([0x08, 0x01, 0x01]); 103 | expect(byteArray.toHexString()).toStrictEqual("0x0101"); 104 | }); 105 | 106 | itThrows("should throw on incorrect encoding", () => { 107 | const byteTest: u8[] = [0x0c]; // Encoded length = 3, actual data length = 0 108 | ByteArray.fromU8a(byteTest); 109 | }); 110 | 111 | itThrows('should throw when index is out of range', () => { 112 | ByteArray.fromU8a([8, 0, 1, 12, 0, 1, 3], 8); 113 | }); 114 | }); 115 | 116 | function appendEmptyBytesTo (arr: u8[], bytesToAppend: i32): u8[] { 117 | for (let i = 0; i < bytesToAppend; i++) { 118 | arr.push(0xff); 119 | } 120 | 121 | return arr; 122 | } 123 | 124 | -------------------------------------------------------------------------------- /assembly/__tests__/Arrays/IntArray.spec.ts: -------------------------------------------------------------------------------- 1 | import { IntArray } from "../../Arrays/IntArray"; 2 | 3 | describe("IntArray", () => { 4 | 5 | it("should encode int array", () => { 6 | const dataInput: Array> = [ 7 | [1], // Expected output: [0x04, 0x04] 8 | [1, 2, 3, 4], // Expected output: [0x10, 0x04, 0x08, 0x0c, 0x10] 9 | [16384, 2, 3, 4], // Expected output: [0x10, 0x02, 0x00, 0x01, 0x00, 0x08, 0x0c, 0x10] 10 | [97222587, 260918714, 432884242, 497178323, 524283510, 530431722, 619955096, 629855926, 884757710, 947465305] 11 | ]; 12 | 13 | const expectedOutput: Array> = [ 14 | [0x04, 0x04], 15 | [0x10, 0x04, 0x08, 0x0c, 0x10], 16 | [0x10, 0x02, 0x00, 0x01, 0x00, 0x08, 0x0c, 0x10], 17 | [0x28, 0xee, 0xfe, 0x2d, 0x17, 0xea, 0x36, 0x35, 0x3e, 0x4a, 0x28, 0x35, 0x67, 0x4e, 0x5b, 0x89, 0x76, 0xda, 0xb9, 0xff, 0x7c, 0xaa, 0xfb, 0x76, 0x7e, 0x62, 0x0e, 0xcf, 0x93, 0xda, 0x5a, 0x2b, 0x96, 0x3a, 0x53, 0xf1, 0xd2, 0x66, 0xb1, 0xe4, 0xe1] 18 | ]; 19 | 20 | for (let i = 0; i < dataInput.length; i++) { 21 | const intArray = new IntArray(dataInput[i]); 22 | expect>(intArray.toU8a()).toStrictEqual(expectedOutput[i]); 23 | } 24 | }); 25 | 26 | it("should decode int array", () => { 27 | const dataInput: Array> = [ 28 | [0x04, 0x04], // Expected output: [1] 29 | [0x10, 0x04, 0x08, 0x0c, 0x10], // Expected output: [1, 2, 3, 4] 30 | [0x10, 0x02, 0x00, 0x01, 0x00, 0x08, 0x0c, 0x10], // Expected output: [16384, 2, 3, 4] 31 | [0x28, 0xee, 0xfe, 0x2d, 0x17, 0xea, 0x36, 0x35, 0x3e, 0x4a, 0x28, 0x35, 0x67, 0x4e, 0x5b, 0x89, 0x76, 0xda, 0xb9, 0xff, 0x7c, 0xaa, 0xfb, 0x76, 0x7e, 0x62, 0x0e, 0xcf, 0x93, 0xda, 0x5a, 0x2b, 0x96, 0x3a, 0x53, 0xf1, 0xd2, 0x66, 0xb1, 0xe4, 0xe1] 32 | ]; 33 | 34 | const expectedOutput: Array> = [ 35 | [1], 36 | [1, 2, 3, 4], 37 | [16384, 2, 3, 4], 38 | [97222587, 260918714, 432884242, 497178323, 524283510, 530431722, 619955096, 629855926, 884757710, 947465305] 39 | ]; 40 | 41 | for (let i = 0; i < dataInput.length; i++) { 42 | const result = IntArray.fromU8a(dataInput[i]); 43 | expect(result).toStrictEqual(new IntArray(expectedOutput[i])); 44 | } 45 | }); 46 | 47 | it("should decode int array with populate method", () => { 48 | const dataInput: Array> = [ 49 | [0x04, 0x04], // Expected output: [1] 50 | [0x10, 0x04, 0x08, 0x0c, 0x10], // Expected output: [1, 2, 3, 4] 51 | [0x10, 0x02, 0x00, 0x01, 0x00, 0x08, 0x0c, 0x10], // Expected output: [16384, 2, 3, 4] 52 | [0x28, 0xee, 0xfe, 0x2d, 0x17, 0xea, 0x36, 0x35, 0x3e, 0x4a, 0x28, 0x35, 0x67, 0x4e, 0x5b, 0x89, 0x76, 0xda, 0xb9, 0xff, 0x7c, 0xaa, 0xfb, 0x76, 0x7e, 0x62, 0x0e, 0xcf, 0x93, 0xda, 0x5a, 0x2b, 0x96, 0x3a, 0x53, 0xf1, 0xd2, 0x66, 0xb1, 0xe4, 0xe1] 53 | ]; 54 | 55 | const expectedOutput: Array> = [ 56 | [1], 57 | [1, 2, 3, 4], 58 | [16384, 2, 3, 4], 59 | [97222587, 260918714, 432884242, 497178323, 524283510, 530431722, 619955096, 629855926, 884757710, 947465305] 60 | ]; 61 | for (let i = 0; i < dataInput.length; i++) { 62 | const result = new IntArray(); 63 | result.populateFromBytes(dataInput[i]); 64 | expect(result).toStrictEqual(new IntArray(expectedOutput[i])); 65 | } 66 | }) 67 | 68 | itThrows("should throw on incorrect encoding", () => { 69 | const invalidEncodedArray1: u8[] = [0x10, 0x04]; 70 | IntArray.fromU8a(invalidEncodedArray1); 71 | 72 | const invalidEncodedArray2: u8[] = [0x10]; 73 | IntArray.fromU8a(invalidEncodedArray2); 74 | }); 75 | }); 76 | 77 | -------------------------------------------------------------------------------- /assembly/__tests__/Arrays/StringArray.spec.ts: -------------------------------------------------------------------------------- 1 | import { Bytes } from "../../utils/Bytes"; 2 | 3 | import { ScaleString } from "../../ScaleString"; 4 | import { StringArray } from "../../Arrays/StringArray"; 5 | 6 | describe("StringArray", () => { 7 | 8 | it("should encode string array", () => { 9 | const strArray = new StringArray(["hello", "world"]); 10 | expect>(strArray.toU8a()).toStrictEqual(([0x08, 0x14, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x14, 0x77, 0x6f, 0x72, 0x6c, 0x64])); 11 | }); 12 | 13 | it("should encode long string array", () => { 14 | const str = "The 1963 Impala featured rectilinear styling with an engine-turned aluminum rear taillight panel surrounded by a chrome border on SS models."; 15 | const strArray = new StringArray(["hello", "world", repeatString(str, 500), '™ ± Ã ¿ £ µ']); 16 | 17 | const longStr: Array = append([0xC2, 0x45, 0x04, 0x00], repeatString(str, 500)); 18 | const asciiStr: Array = append([0x48], '™ ± Ã ¿ £ µ'); 19 | 20 | let expectedResult: Array = [0x10, 0x14, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x14, 0x77, 0x6f, 0x72, 0x6c, 0x64]; 21 | expectedResult = expectedResult.concat(longStr).concat(asciiStr); 22 | 23 | expect>(strArray.toU8a()).toStrictEqual(expectedResult); 24 | }); 25 | 26 | it("should decode string array", () => { 27 | const scaleStrArray = StringArray.fromU8a([0x08, 0x14, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x14, 0x77, 0x6f, 0x72, 0x6c, 0x64]); 28 | expect(scaleStrArray.values.length).toStrictEqual(2); 29 | expect(scaleStrArray.values[0]).toStrictEqual("hello"); 30 | expect(scaleStrArray.values[1]).toStrictEqual("world"); 31 | }); 32 | 33 | it("should decode long string array", () => { 34 | const str = "The 1963 Impala featured rectilinear styling with an engine-turned aluminum rear taillight panel surrounded by a chrome border on SS models."; 35 | const scaleStrArray = StringArray.fromU8a(_getEncodedStrArray()); 36 | expect(scaleStrArray.values.length).toStrictEqual(5); 37 | expect(scaleStrArray.values[0]).toStrictEqual(repeatString(str, 500)); 38 | expect(scaleStrArray.values[1]).toStrictEqual("world"); 39 | expect(scaleStrArray.values[2]).toStrictEqual("wonderful_life"); 40 | expect(scaleStrArray.values[3]).toStrictEqual("™ ± Ã ¿ £ µ"); 41 | expect(scaleStrArray.values[4]).toStrictEqual(repeatString(str, 500)); 42 | }); 43 | 44 | it("should decode string array with populate method", () => { 45 | const scaleStrArray = new StringArray(); 46 | scaleStrArray.populateFromBytes([0x08, 0x14, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x14, 0x77, 0x6f, 0x72, 0x6c, 0x64]); 47 | expect(scaleStrArray.values.length).toStrictEqual(2); 48 | expect(scaleStrArray.values[0]).toStrictEqual("hello"); 49 | expect(scaleStrArray.values[1]).toStrictEqual("world"); 50 | }) 51 | 52 | it("should decode long string array with populate method", () => { 53 | const str = "The 1963 Impala featured rectilinear styling with an engine-turned aluminum rear taillight panel surrounded by a chrome border on SS models."; 54 | const scaleStrArray = new StringArray(); 55 | scaleStrArray.populateFromBytes(_getEncodedStrArray()); 56 | expect(scaleStrArray.values.length).toStrictEqual(5); 57 | expect(scaleStrArray.values[0]).toStrictEqual(repeatString(str, 500)); 58 | expect(scaleStrArray.values[1]).toStrictEqual("world"); 59 | expect(scaleStrArray.values[2]).toStrictEqual("wonderful_life"); 60 | expect(scaleStrArray.values[3]).toStrictEqual("™ ± Ã ¿ £ µ"); 61 | expect(scaleStrArray.values[4]).toStrictEqual(repeatString(str, 500)); 62 | }) 63 | 64 | itThrows("should throw on incorrect encoding", () => { 65 | const invalidEncodedArray1: u8[] = [0x10, 0x04]; 66 | StringArray.fromU8a(invalidEncodedArray1); 67 | 68 | const invalidEncodedArray2: u8[] = [0x10]; 69 | StringArray.fromU8a(invalidEncodedArray2); 70 | }); 71 | }); 72 | 73 | function append (to: Array, from: string): Array { 74 | const strToBytes: ArrayBuffer = String.UTF8.encode(from); 75 | const strArray: Uint8Array = Uint8Array.wrap(strToBytes); 76 | 77 | for (let i = 0; i < strArray.length; i++) { 78 | to.push(strArray[i]); 79 | } 80 | 81 | return to; 82 | } 83 | 84 | function repeatString (str: string, numberOfRepeats: i32): string { 85 | let result: string = str; 86 | for (let i = 1; i < numberOfRepeats; i++) { 87 | result += str; 88 | } 89 | 90 | return result; 91 | } 92 | 93 | function _getEncodedStrArray(): Array{ 94 | const str = "The 1963 Impala featured rectilinear styling with an engine-turned aluminum rear taillight panel surrounded by a chrome border on SS models."; 95 | const scaleStr = new ScaleString(repeatString(str, 500)); 96 | 97 | const encodedStrArray: Array = new Array(); 98 | encodedStrArray.push(0x14); 99 | Bytes.copy(scaleStr.toU8a(), encodedStrArray, encodedStrArray.length); 100 | Bytes.copy([0x14, 0x77, 0x6f, 0x72, 0x6c, 0x64], encodedStrArray, encodedStrArray.length); 101 | Bytes.copy([0x38, 0x77, 0x6f, 0x6e, 0x64, 0x65, 0x72, 0x66, 0x75, 0x6c, 0x5f, 0x6c, 0x69, 0x66, 0x65], encodedStrArray, encodedStrArray.length); 102 | Bytes.copy([0x48, 0xe2, 0x84, 0xa2, 0x20, 0xc2, 0xb1, 0x20, 0xc3, 0x83, 0x20, 0xc2, 0xbf, 0x20, 0xc2, 0xa3, 0x20, 0xc2, 0xb5], encodedStrArray, encodedStrArray.length) 103 | Bytes.copy(scaleStr.toU8a(), encodedStrArray, encodedStrArray.length); 104 | return encodedStrArray; 105 | } -------------------------------------------------------------------------------- /assembly/__tests__/Arrays/UInt128Array.spec.ts: -------------------------------------------------------------------------------- 1 | import { u128 } from "as-bignum"; 2 | import { UInt128Array } from "../../Arrays/UInt128Array"; 3 | 4 | describe("UInt128Array", () => { 5 | 6 | it("should encode uint128 array", () => { 7 | const dataInput: Array> = [ 8 | [u128.One], 9 | [u128.fromString('54321')], 10 | [u128.fromU32(20001), u128.fromU32(123456)], 11 | [ 12 | u128.fromU32(1), u128.fromU64(123456789), u128.fromString('123456789012345'), 13 | u128.fromString('12345678901234567890'), u128.fromString('1234567890123456789012345') 14 | ], 15 | [u128.fromU64(18446744073709551615), u128.fromU64(18446744073709551615), u128.Max], 16 | [u128.Max - u128.fromU64(u64.MAX_VALUE)] 17 | ]; 18 | 19 | const expectedOutput: Array> = [ 20 | [4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // Expected output: [1] 21 | [4, 49, 212, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // Expected output: 54321 22 | [8, 33, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 226, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // Expected output: [20001, 123456] 23 | [ 24 | 20, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 205, 91, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25 | 121, 223, 13, 134, 72, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 10, 31, 235, 140, 169, 84, 171, 0, 0, 0, 0, 0, 0, 0, 0, 26 | 121, 223, 226, 61, 68, 166, 54, 15, 110, 5, 1, 0, 0, 0, 0, 0 27 | ], 28 | [ 29 | 12, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 30 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 31 | ], 32 | [4, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255] 33 | ]; 34 | 35 | for (let i = 0; i < dataInput.length; i++) { 36 | const intArray = new UInt128Array(dataInput[i]); 37 | expect>(intArray.toU8a()).toStrictEqual(expectedOutput[i]); 38 | } 39 | }); 40 | 41 | it("should decode uint128 array", () => { 42 | const dataInput: Array> = [ 43 | [4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // Expected output: [1] 44 | [4, 49, 212, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // Expected output: 54321 45 | [8, 33, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 226, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // Expected output: [20001, 123456] 46 | [ 47 | 20, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 205, 91, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48 | 121, 223, 13, 134, 72, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 10, 31, 235, 140, 169, 84, 171, 0, 0, 0, 0, 0, 0, 0, 0, 49 | 121, 223, 226, 61, 68, 166, 54, 15, 110, 5, 1, 0, 0, 0, 0, 0 50 | ], 51 | [ 52 | 12, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 53 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 54 | ], 55 | [4, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255] 56 | ]; 57 | 58 | const expectedOutput: Array> = [ 59 | [u128.One], 60 | [u128.fromString('54321')], 61 | [u128.fromU32(20001), u128.fromU32(123456)], 62 | [ 63 | u128.fromU32(1), u128.fromU64(123456789), u128.fromString('123456789012345'), 64 | u128.fromString('12345678901234567890'), u128.fromString('1234567890123456789012345') 65 | ], 66 | [u128.fromU64(18446744073709551615), u128.fromU64(18446744073709551615), u128.Max], 67 | [u128.Max - u128.fromU64(u64.MAX_VALUE)] 68 | ]; 69 | 70 | for (let i = 0; i < dataInput.length; i++) { 71 | const result = UInt128Array.fromU8a(dataInput[i]); 72 | expect(result).toStrictEqual(new UInt128Array(expectedOutput[i])); 73 | } 74 | }); 75 | 76 | it("should decode uint128 array with populate method", () => { 77 | const dataInput: Array> = [ 78 | [4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // Expected output: [1] 79 | [4, 49, 212, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // Expected output: 54321 80 | [8, 33, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 226, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // Expected output: [20001, 123456] 81 | [ 82 | 20, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 205, 91, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83 | 121, 223, 13, 134, 72, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 10, 31, 235, 140, 169, 84, 171, 0, 0, 0, 0, 0, 0, 0, 0, 84 | 121, 223, 226, 61, 68, 166, 54, 15, 110, 5, 1, 0, 0, 0, 0, 0 85 | ], 86 | [ 87 | 12, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 88 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 89 | ], 90 | [4, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255] 91 | ]; 92 | const expectedOutput: Array> = [ 93 | [u128.One], 94 | [u128.fromString('54321')], 95 | [u128.fromU32(20001), u128.fromU32(123456)], 96 | [ 97 | u128.fromU32(1), u128.fromU64(123456789), u128.fromString('123456789012345'), 98 | u128.fromString('12345678901234567890'), u128.fromString('1234567890123456789012345') 99 | ], 100 | [u128.fromU64(18446744073709551615), u128.fromU64(18446744073709551615), u128.Max], 101 | [u128.Max - u128.fromU64(u64.MAX_VALUE)] 102 | ]; 103 | 104 | for(let i = 0; i < dataInput.length; i++){ 105 | const instance = new UInt128Array(); 106 | instance.populateFromBytes(dataInput[i]); 107 | expect(instance).toStrictEqual(new UInt128Array(expectedOutput[i])); 108 | } 109 | }) 110 | 111 | itThrows("should throw on incorrect encoding", () => { 112 | const invalidEncodedArray1: u8[] = [0x4, 0x02, 0x00, 0x01, 0x00, 0x08, 0x0c, 0x10]; 113 | UInt128Array.fromU8a(invalidEncodedArray1); 114 | 115 | const invalidEncodedArray2: u8[] = [0x13, 0x02, 0x00, 0x01, 0x00, 0x08, 0x0c, 0x10]; 116 | UInt128Array.fromU8a(invalidEncodedArray2); 117 | }); 118 | }); 119 | 120 | -------------------------------------------------------------------------------- /assembly/__tests__/Bool.spec.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2020 LimeChain Ltd. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { Bool } from "../Bool"; 16 | 17 | describe("Bool", () => { 18 | 19 | it("should encode bool with true", () => { 20 | let v = new Bool(true); 21 | expect(v.toU8a()).toStrictEqual([0x01]); 22 | }); 23 | 24 | it("should encode bool with false", () => { 25 | let v = new Bool(false); 26 | expect(v.toU8a()).toStrictEqual([0x00]); 27 | }); 28 | 29 | it("should instantiate true Bool from U8Array", () => { 30 | expect(Bool.fromU8a([0x01])).toStrictEqual(new Bool(true)); 31 | }); 32 | 33 | it("should instantiate false Bool from U8Array", () => { 34 | expect(Bool.fromU8a([0x00])).toStrictEqual(new Bool(false)); 35 | }); 36 | 37 | it('should read only first byte at current position', () => { 38 | expect(Bool.fromU8a([0x00, 0x01, 0xff], 1)).toStrictEqual(new Bool(true)); 39 | expect(Bool.fromU8a([0x00, 0x0f, 0xff, 0x00], 3)).toStrictEqual(new Bool(false)); 40 | }); 41 | 42 | it('should decode using populate from bytes', () => { 43 | const instance = new Bool(); 44 | instance.populateFromBytes([0]); 45 | expect(instance).toStrictEqual(new Bool(false)); 46 | instance.populateFromBytes([1]); 47 | expect(instance).toStrictEqual(new Bool(true)); 48 | }) 49 | 50 | itThrows('when provided invalid bool value', () => { 51 | Bool.fromU8a([0x05]); 52 | }) 53 | itThrows('should throw when index is out of range', () => { 54 | Bool.fromU8a([0, 1, 0, 1, 0], 5); 55 | }); 56 | 57 | }); 58 | -------------------------------------------------------------------------------- /assembly/__tests__/Byte.spec.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2020 LimeChain Ltd. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { Byte } from "../Byte"; 16 | 17 | describe("Byte", () => { 18 | 19 | it("should encode byte", () => { 20 | let v = new Byte(0xac); 21 | expect(v.toU8a()).toStrictEqual([0xac]); 22 | }); 23 | 24 | it("should decode byte", () => { 25 | expect(Byte.fromU8a([0x1f])).toStrictEqual(new Byte(0x1f)); 26 | }); 27 | 28 | it("should decode with populate method", () => { 29 | const instance = new Byte(); 30 | instance.populateFromBytes([1]); 31 | expect(instance).toStrictEqual(new Byte(1)); 32 | }) 33 | itThrows('when provided empty byte array', () => { 34 | Byte.fromU8a([]); 35 | }); 36 | }); 37 | -------------------------------------------------------------------------------- /assembly/__tests__/BytesReader.spec.ts: -------------------------------------------------------------------------------- 1 | import { BytesReader } from '../BytesReader'; 2 | import { Hash, Bool } from '../index'; 3 | import { UInt32, UInt16, UInt64, UInt8 } from '../UInt'; 4 | import { Int8, Int16, Int32, Int64, CompactInt } from '../Int'; 5 | import { ScaleString } from '../ScaleString'; 6 | import { ByteArray } from '../Arrays'; 7 | 8 | describe("BytesReader", () => { 9 | it("decodes single type", () => { 10 | const buffer = new BytesReader([0]); 11 | assert(buffer.readInto() == new Bool(false), "Not correctly decoded"); 12 | }) 13 | 14 | it("decoding simplified", () => { 15 | const buffer = new BytesReader([1, 1, 0]); 16 | expect(buffer.readInto()).toStrictEqual(new UInt8(1)); 17 | expect(buffer.readInto()).toStrictEqual(new UInt16(1)); 18 | }) 19 | 20 | it("decodes two types", () => { 21 | const buffer = new BytesReader([1, 69, 0, 0, 0]); 22 | expect(buffer.readInto()).toStrictEqual(new Bool(true)); 23 | expect(buffer.readInto()).toStrictEqual(new UInt32(69)); 24 | }) 25 | 26 | it("decodes many types", () => { 27 | const u32Bytes: u8[] = [12, 0, 0, 0]; 28 | const hashBytes: u8[] = [128, 1, 10, 0, 0, 0, 2, 2, 1, 123, 33, 3, 1, 35, 34, 5, 8, 22, 52, 1, 0, 0, 0, 1, 1, 1, 56, 21, 142, 13, 13, 1]; 29 | const scaleStringBytes: u8[] = [16, 110, 105, 99, 101]; 30 | const buffer = new BytesReader( 31 | u32Bytes.concat(hashBytes).concat([1]).concat(scaleStringBytes) 32 | ); 33 | expect(buffer.readInto()).toStrictEqual(new UInt32(12)); 34 | expect(buffer.readInto()).toStrictEqual(new Hash(hashBytes)); 35 | expect(buffer.readInto()).toStrictEqual(new Bool(true)); 36 | expect(buffer.readInto()).toStrictEqual(new ScaleString("nice")); 37 | }) 38 | 39 | it("decodes list of unsigned integers", () => { 40 | const bytes: u8[] = [1, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 4, 0, 223]; 41 | const buffer = new BytesReader(bytes); 42 | expect(buffer.readInto()).toStrictEqual(new UInt64(1)); 43 | expect(buffer.readInto()).toStrictEqual(new UInt32(69)); 44 | expect(buffer.readInto()).toStrictEqual(new UInt16(4)); 45 | expect(buffer.readInto()).toStrictEqual(new UInt8(223)); 46 | }) 47 | 48 | it("decodes list of signed integers", () => { 49 | const bytes: u8[] = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdd, 0xfe, 0xff, 0xf1]; 50 | const buffer = new BytesReader(bytes); 51 | expect(buffer.readInto()).toStrictEqual(new Int64(-1)); 52 | expect(buffer.readInto()).toStrictEqual(new Int32(-570425345)); 53 | expect(buffer.readInto()).toStrictEqual(new Int16(-2)); 54 | expect(buffer.readInto()).toStrictEqual(new Int8(-15)); 55 | }) 56 | 57 | it("decodes list of CompactInts correctly", () => { 58 | const bytes: u8[] = [4, 40, 69, 2, 21, 1, 110, 125, 239, 2]; 59 | const buffer = new BytesReader(bytes); 60 | expect(buffer.readInto()).toStrictEqual(new CompactInt(1)); 61 | expect(buffer.readInto()).toStrictEqual(new CompactInt(10)); 62 | expect(buffer.readInto()).toStrictEqual(new CompactInt(145)); 63 | expect(buffer.readInto()).toStrictEqual(new CompactInt(69)); 64 | expect(buffer.readInto()).toStrictEqual(new CompactInt(12312411)); 65 | }) 66 | 67 | it("decodes byteArray correctly", () => { 68 | const bytes: u8[] = [40, 12, 123, 1, 21, 12, 33, 12, 21, 12, 1]; 69 | const buffer = new BytesReader(bytes); 70 | expect(buffer.readInto()).toStrictEqual(new ByteArray(bytes.slice(1))); 71 | }) 72 | 73 | it("decodes ScaleString correctly", () => { 74 | const bytes: u8[] = [8, 97, 115, 20, 115, 99, 97, 108, 101, 20, 99, 111, 100, 101, 99]; 75 | const buffer = new BytesReader(bytes); 76 | expect(buffer.readInto()).toStrictEqual(new ScaleString("as")); 77 | expect(buffer.readInto()).toStrictEqual(new ScaleString("scale")); 78 | expect(buffer.readInto()).toStrictEqual(new ScaleString("codec")); 79 | }) 80 | it("static method works", () => { 81 | const byteArray: u8[] = [40, 12, 123, 1, 21, 12, 33, 12, 21, 12, 1]; 82 | expect(BytesReader.decodeInto(byteArray)).toStrictEqual(new ByteArray(byteArray.slice(1))); 83 | const uintU8a: u8[] = [1, 0, 0, 0, 0, 0, 0, 0]; 84 | expect(BytesReader.decodeInto(uintU8a)).toStrictEqual(new UInt64(1)); 85 | const stringU8a: u8[] = [20, 99, 111, 100, 101, 99]; 86 | expect(BytesReader.decodeInto(stringU8a)).toStrictEqual(new ScaleString("codec")); 87 | const compactU8a: u8[] = [110, 125, 239, 2]; 88 | expect(BytesReader.decodeInto(compactU8a)).toStrictEqual(new CompactInt(12312411)); 89 | const u32U8a: u8[] = [69, 0, 0, 0]; 90 | expect(BytesReader.decodeInto(u32U8a)).toStrictEqual(new UInt32(69)); 91 | const hashU8a: u8[] = [128, 1, 10, 0, 0, 0, 2, 2, 1, 123, 33, 3, 1, 35, 34, 5, 8, 22, 52, 1, 0, 0, 0, 1, 1, 1, 56, 21, 142, 13, 13, 1]; 92 | expect(BytesReader.decodeInto(hashU8a)).toStrictEqual(new Hash(hashU8a)); 93 | }) 94 | }) -------------------------------------------------------------------------------- /assembly/__tests__/Hash.spec.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2020 LimeChain Ltd. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { Hash } from "../Hash"; 16 | 17 | describe("Hash", () => { 18 | 19 | it("should encode hash", () => { 20 | let hash: Hash = new Hash([0xff]); 21 | expect>(hash.toU8a()).toStrictEqual([0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]); 22 | 23 | hash = new Hash([0xff, 0x00, 0xab]); 24 | expect>(hash.toU8a()).toStrictEqual([0xff, 0x00, 0xab, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]); 25 | 26 | hash = new Hash([0xff, 0x00, 0xab, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]); 27 | expect>(hash.toU8a()).toStrictEqual([0xff, 0x00, 0xab, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]); 28 | 29 | const longHash: Hash = new Hash([0xff, 0x00, 0xab, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff]); 30 | expect(longHash.unwrap().length).toStrictEqual(32); 31 | expect>(longHash.toU8a()).toStrictEqual([0xff, 0x00, 0xab, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]); 32 | }); 33 | 34 | it("should decode hash", () => { 35 | let hash: Hash = Hash.fromU8a([0xff]); 36 | const expected: Array = [0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; 37 | 38 | expect(hash.unwrap().length).toStrictEqual(32); 39 | expect(hash).toStrictEqual(new Hash(expected)); 40 | 41 | hash = Hash.fromU8a([0xff, 0x00, 0xab]); 42 | expect(hash).toStrictEqual(new Hash([0xff, 0x00, 0xab, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])); 43 | 44 | hash = Hash.fromU8a([0xff, 0x00, 0xab, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]); 45 | expect(hash).toStrictEqual(new Hash([0xff, 0x00, 0xab, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])); 46 | 47 | const longHash: Hash = Hash.fromU8a([0xff, 0x00, 0xab, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff]); 48 | expect(longHash.unwrap().length).toStrictEqual(32); 49 | expect(longHash).toStrictEqual(new Hash([0xff, 0x00, 0xab, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])); 50 | }); 51 | 52 | it("should decode using populate method", () => { 53 | const instance = new Hash(); 54 | instance.populateFromBytes([1, 12, 12, 12, 1, 1, 1, 0, 0, 0, 1, 12, 123, 123, 11, 123, 33, 121]); 55 | expect(instance).toStrictEqual(new Hash([1, 12, 12, 12, 1, 1, 1, 0, 0, 0, 1, 12, 123, 123, 11, 123, 33, 121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])); 56 | instance.populateFromBytes([0xff, 0x00, 0xab]); 57 | expect(instance).toStrictEqual(new Hash([0xff, 0x00, 0xab, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])); 58 | }); 59 | 60 | it("should convert bytes to hash", () => { 61 | let hash: Hash = Hash.bytesToHash([0xff]); 62 | 63 | expect(hash.unwrap().length).toStrictEqual(32); 64 | expect(hash).toStrictEqual(new Hash([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff])); 65 | 66 | hash = Hash.bytesToHash([0xff, 0x00, 0xab]); 67 | expect(hash).toStrictEqual(new Hash([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xab])); 68 | 69 | hash = Hash.bytesToHash([0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]); 70 | expect(hash).toStrictEqual(new Hash([0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])); 71 | }); 72 | 73 | it("should return hex representation of a hash", () => { 74 | let hash: Hash = new Hash([0xff]); 75 | expect(hash.toString()).toStrictEqual('0x2550000000000000000000000000000000'); 76 | 77 | hash = new Hash([0xff, 0x00, 0xff]); 78 | expect(hash.toString()).toStrictEqual('0x255025500000000000000000000000000000'); 79 | 80 | hash = new Hash([0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff]); 81 | expect(hash.toString()).toStrictEqual('0x255000000000000000000000000000000255'); 82 | }); 83 | 84 | it("equals should work", () => { 85 | let hash: Hash = new Hash([0xff]); 86 | let hash2: Hash = new Hash([0xff]); 87 | 88 | assert(hash == hash2, "hashes are not equal") 89 | }) 90 | 91 | it("should not be equal when hashes are different", () => { 92 | let hash1: Hash = new Hash([0x01]); 93 | let hash2: Hash = new Hash([0xff]); 94 | 95 | assert(hash1 != hash2, "hashes should be different"); 96 | }) 97 | 98 | itThrows('should throw when index is out of range', () => { 99 | Hash.fromU8a([8, 0, 1, 12, 0, 1, 12], 8); 100 | }); 101 | }); 102 | -------------------------------------------------------------------------------- /assembly/__tests__/Int.spec.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2020 LimeChain Ltd. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License.с 14 | 15 | import { Int8 } from "../Int/Int8"; 16 | import { Int16 } from "../Int/Int16"; 17 | import { Int32 } from "../Int/Int32"; 18 | import { Int64 } from "../Int/Int64"; 19 | 20 | describe("Int8", () => { 21 | 22 | it("should encode int8", () => { 23 | let v1 = new Int8(1); 24 | expect(v1.toU8a()).toStrictEqual([0x01]); 25 | expect(v1.encodedLength()).toStrictEqual(1); 26 | 27 | let v2 = new Int8(15); 28 | expect(v2.toU8a()).toStrictEqual([0xf]); 29 | expect(v2.encodedLength()).toStrictEqual(1); 30 | 31 | let v3 = new Int8(16); 32 | expect(v3.toU8a()).toStrictEqual([0x10]); 33 | expect(v3.encodedLength()).toStrictEqual(1); 34 | 35 | let v4 = new Int8(127); 36 | expect(v4.toU8a()).toStrictEqual([0x7f]); 37 | expect(v4.encodedLength()).toStrictEqual(1); 38 | 39 | let v5 = new Int8(-1); 40 | expect(v5.toU8a()).toStrictEqual([0xff]); 41 | expect(v5.encodedLength()).toStrictEqual(1); 42 | 43 | let v6 = new Int8(-15); 44 | expect(v6.toU8a()).toStrictEqual([0xf1]); 45 | expect(v6.encodedLength()).toStrictEqual(1); 46 | 47 | let v7 = new Int8(-127); 48 | expect(v7.toU8a()).toStrictEqual([0x81]); 49 | expect(v7.encodedLength()).toStrictEqual(1); 50 | }); 51 | 52 | it("should decode int8", () => { 53 | expect(Int8.fromU8a([0x01])).toStrictEqual(new Int8(1)); 54 | expect(Int8.fromU8a([0xf])).toStrictEqual(new Int8(15)); 55 | expect(Int8.fromU8a([0x10])).toStrictEqual(new Int8(16)); 56 | expect(Int8.fromU8a([0xf1])).toStrictEqual(new Int8(-15)) 57 | }); 58 | it("should decode using populate method", () => { 59 | const int8 = new Int8(); 60 | int8.populateFromBytes([0x7f]); 61 | expect(int8).toStrictEqual(new Int8(127)); 62 | int8.populateFromBytes([0xff]); 63 | expect(int8).toStrictEqual(new Int8(-1)); 64 | int8.populateFromBytes([0xf1]); 65 | expect(int8).toStrictEqual(new Int8(-15)); 66 | int8.populateFromBytes([0x81]); 67 | expect(int8).toStrictEqual(new Int8(-127)); 68 | }); 69 | 70 | it("should decode only first byte", () => { 71 | expect(Int8.fromU8a([0xff, 0])).toStrictEqual(new Int8(-1)); 72 | expect(Int8.fromU8a([0, 0, 1, 0xf1, 12], 3)).toStrictEqual(new Int8(-15)); 73 | }); 74 | 75 | itThrows('should throw when empty array is provided', () => { 76 | let v1 = Int8.fromU8a([]); 77 | }); 78 | itThrows('should throw when index is out of range', () => { 79 | let v1 = Int8.fromU8a([1, 0, 1], 3); 80 | }); 81 | }); 82 | 83 | describe("Int16", () => { 84 | 85 | it("should encode int16", () => { 86 | let v1 = new Int16(1); 87 | expect(v1.toU8a()).toStrictEqual([0x01, 0]); 88 | expect(v1.encodedLength()).toStrictEqual(2); 89 | 90 | let v2 = new Int16(15); 91 | expect(v2.toU8a()).toStrictEqual([0xf, 0]); 92 | expect(v2.encodedLength()).toStrictEqual(2); 93 | 94 | let v3 = new Int16(16); 95 | expect(v3.toU8a()).toStrictEqual([0x10, 0]); 96 | expect(v3.encodedLength()).toStrictEqual(2); 97 | 98 | let v4 = new Int16(127); 99 | expect(v4.toU8a()).toStrictEqual([0x7f, 0]); 100 | expect(v4.encodedLength()).toStrictEqual(2); 101 | 102 | let v5 = new Int16(-1); 103 | expect(v5.toU8a()).toStrictEqual([0xff, 0xff]); 104 | expect(v5.encodedLength()).toStrictEqual(2); 105 | 106 | let v6 = new Int16(-15); 107 | expect(v6.toU8a()).toStrictEqual([0xf1, 0xff]); 108 | expect(v6.encodedLength()).toStrictEqual(2); 109 | 110 | let v7 = new Int16(-127); 111 | expect(v7.toU8a()).toStrictEqual([0x81, 0xff]); 112 | expect(v7.encodedLength()).toStrictEqual(2); 113 | 114 | let v8 = new Int16(15000); 115 | expect(v8.toU8a()).toStrictEqual([0x98, 0x3a]); 116 | expect(v8.encodedLength()).toStrictEqual(2); 117 | 118 | let v9 = new Int16(16383); 119 | expect(v9.toU8a()).toStrictEqual([0xff, 0x3f]); 120 | expect(v9.encodedLength()).toStrictEqual(2); 121 | 122 | let v10 = new Int16(-15000); 123 | expect(v10.toU8a()).toStrictEqual([0x68, 0xc5]); 124 | expect(v10.encodedLength()).toStrictEqual(2); 125 | 126 | let v11 = new Int16(-16383); 127 | expect(v11.toU8a()).toStrictEqual([0x01, 0xc0]); 128 | expect(v11.encodedLength()).toStrictEqual(2); 129 | }); 130 | 131 | it("should decode int16", () => { 132 | expect(Int16.fromU8a([0x01])).toStrictEqual(new Int16(1)); 133 | expect(Int16.fromU8a([0xf])).toStrictEqual(new Int16(15)); 134 | expect(Int16.fromU8a([0x10])).toStrictEqual(new Int16(16)); 135 | expect(Int16.fromU8a([0x7f, 0])).toStrictEqual(new Int16(127)); 136 | expect(Int16.fromU8a([0xff, 0xff])).toStrictEqual(new Int16(-1)); 137 | expect(Int16.fromU8a([0xf1, 0xff])).toStrictEqual(new Int16(-15)); 138 | expect(Int16.fromU8a([0x81, 0xff])).toStrictEqual(new Int16(-127)); 139 | }); 140 | 141 | it("should decode int16 with populate method", () => { 142 | const int16 = new Int16(); 143 | int16.populateFromBytes([0x98, 0x3a]); 144 | expect(int16).toStrictEqual(new Int16(15000)); 145 | int16.populateFromBytes([0xff, 0x3f]); 146 | expect(int16).toStrictEqual(new Int16(16383)); 147 | int16.populateFromBytes([0x68, 0xc5]); 148 | expect(int16).toStrictEqual(new Int16(-15000)); 149 | int16.populateFromBytes([0x01, 0xc0]); 150 | expect(int16).toStrictEqual(new Int16(-16383)); 151 | }); 152 | 153 | it('should decode only two bytes', () => { 154 | expect(Int16.fromU8a([0x01, 0x81, 0xff, 0x01], 1)).toStrictEqual(new Int16(-127)); 155 | expect(Int16.fromU8a([0, 0, 0, 0, 0xff, 0x00, 0, 0, 0, 0], 4)).toStrictEqual(new Int16(255)); 156 | }); 157 | 158 | itThrows('should throw when empty array is provided', () => { 159 | let v1 = Int16.fromU8a([]); 160 | }); 161 | itThrows('should throw when index is out of range', () => { 162 | let v1 = Int16.fromU8a([1, 0, 1, 12, 123, 1], 6); 163 | }); 164 | }); 165 | 166 | describe("Int32", () => { 167 | it("should encode int32", () => { 168 | let v1 = new Int32(1); 169 | expect(v1.toU8a()).toStrictEqual([0x01, 0, 0, 0]); 170 | expect(v1.encodedLength()).toStrictEqual(4); 171 | 172 | let v2 = new Int32(16383); 173 | expect(v2.toU8a()).toStrictEqual([0xff, 0x3f, 0, 0]); 174 | expect(v2.encodedLength()).toStrictEqual(4); 175 | 176 | let v3 = new Int32(1073741823); 177 | expect(v3.toU8a()).toStrictEqual([0xff, 0xff, 0xff, 0x3f]); 178 | expect(v3.encodedLength()).toStrictEqual(4); 179 | 180 | let v4 = new Int32(-1); 181 | expect(v4.toU8a()).toStrictEqual([0xff, 0xff, 0xff, 0xff]); 182 | expect(v4.encodedLength()).toStrictEqual(4); 183 | 184 | let v5 = new Int32(-16383); 185 | expect(v5.toU8a()).toStrictEqual([0x01, 0xc0, 0xff, 0xff]); 186 | expect(v5.encodedLength()).toStrictEqual(4); 187 | 188 | let v6 = new Int32(-1073741823); 189 | expect(v6.toU8a()).toStrictEqual([0x01, 0x00, 0x00, 0xc0]); 190 | expect(v6.encodedLength()).toStrictEqual(4); 191 | }); 192 | 193 | it("should decode int32", () => { 194 | expect(Int32.fromU8a([0x01])).toStrictEqual(new Int32(1)); 195 | expect(Int32.fromU8a([0xff, 0x3f])).toStrictEqual(new Int32(16383)); 196 | expect(Int32.fromU8a([0xff, 0xff, 0xff, 0x3f])).toStrictEqual(new Int32(1073741823)); 197 | expect(Int32.fromU8a([0x01, 0xc0, 0xff, 0xff])).toStrictEqual(new Int32(-16383)); 198 | }); 199 | 200 | it("should decode int32 with populate method", () => { 201 | const int32 = new Int32(); 202 | int32.populateFromBytes([0xff, 0xff, 0xff, 0x3f]); 203 | expect(int32).toStrictEqual(new Int32(1073741823)); 204 | int32.populateFromBytes([0xff, 0xff, 0xff, 0xff]); 205 | expect(int32).toStrictEqual(new Int32(-1)); 206 | int32.populateFromBytes([0x01, 0xc0, 0xff, 0xff]); 207 | expect(int32).toStrictEqual(new Int32(-16383)); 208 | int32.populateFromBytes([0x01, 0x00, 0x00, 0xc0]); 209 | expect(int32).toStrictEqual(new Int32(-1073741823)); 210 | }) 211 | 212 | it('should decode only four bytes', () => { 213 | expect(Int32.fromU8a([0x01, 0x01, 0x00, 0x00, 0xc0], 1)).toStrictEqual(new Int32(-1073741823)); 214 | expect(Int32.fromU8a([0x01, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00], 3)).toStrictEqual(new Int32(255)); 215 | }); 216 | 217 | itThrows('should throw when empty array is provided', () => { 218 | let v1 = Int32.fromU8a([]); 219 | }); 220 | itThrows('should throw when index is out of range', () => { 221 | let v1 = Int32.fromU8a([0, 0, 1, 1, 0, 1, 12, 123, 12], 9); 222 | }); 223 | }); 224 | 225 | describe("Int64", () => { 226 | 227 | it("should encode int64", () => { 228 | let v1 = new Int64(1); 229 | expect(v1.toU8a()).toStrictEqual([0x01, 0, 0, 0, 0, 0, 0, 0]); 230 | expect(v1.encodedLength()).toStrictEqual(8); 231 | 232 | let v2 = new Int64(16383); 233 | expect(v2.toU8a()).toStrictEqual([0xff, 0x3f, 0, 0, 0, 0, 0, 0]); 234 | expect(v2.encodedLength()).toStrictEqual(8); 235 | 236 | let v3 = new Int64(1073741823); 237 | expect(v3.toU8a()).toStrictEqual([0xff, 0xff, 0xff, 0x3f, 0, 0, 0, 0]); 238 | expect(v3.encodedLength()).toStrictEqual(8); 239 | 240 | let v4 = new Int64(9223372036854775807); 241 | expect(v4.toU8a()).toStrictEqual([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f]); 242 | expect(v4.encodedLength()).toStrictEqual(8); 243 | 244 | let v5 = new Int64(-1); 245 | expect(v5.toU8a()).toStrictEqual([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]); 246 | expect(v5.encodedLength()).toStrictEqual(8); 247 | 248 | let v6 = new Int64(-16383); 249 | expect(v6.toU8a()).toStrictEqual([0x01, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]); 250 | expect(v6.encodedLength()).toStrictEqual(8); 251 | 252 | let v7 = new Int64(-1073741823); 253 | expect(v7.toU8a()).toStrictEqual([0x01, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff]); 254 | expect(v7.encodedLength()).toStrictEqual(8); 255 | 256 | let v8 = new Int64(-9223372036854775807); 257 | expect(v8.toU8a()).toStrictEqual([0x01, 0, 0, 0, 0, 0, 0, 0x80]); 258 | expect(v8.encodedLength()).toStrictEqual(8); 259 | }); 260 | 261 | it("should decode int64", () => { 262 | expect(Int64.fromU8a([0x01])).toStrictEqual(new Int64(1)); 263 | expect(Int64.fromU8a([0xff, 0x3f])).toStrictEqual(new Int64(16383)); 264 | expect(Int64.fromU8a([0xff, 0xff, 0xff, 0x3f, 0, 0, 0, 0])).toStrictEqual(new Int64(1073741823)); 265 | expect(Int64.fromU8a([0x01, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff])).toStrictEqual(new Int64(-1073741823)); 266 | expect(Int64.fromU8a([0x01, 0, 0, 0, 0, 0, 0, 0x80])).toStrictEqual(new Int64(-9223372036854775807)); 267 | }); 268 | 269 | it("should decode int64 with populate method", () => { 270 | const int64 = new Int64(); 271 | int64.populateFromBytes([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f]) 272 | expect(int64).toStrictEqual(new Int64(9223372036854775807)); 273 | int64.populateFromBytes([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]); 274 | expect(int64).toStrictEqual(new Int64(-1)); 275 | int64.populateFromBytes([0x01, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]); 276 | expect(int64).toStrictEqual(new Int64(-16383)); 277 | }) 278 | 279 | it('should decode only eight bytes', () => { 280 | expect(Int64.fromU8a([0x01, 0x01, 0xff, 0x3f, 0, 0, 0, 0, 0, 0], 2)).toStrictEqual(new Int64(16383)); 281 | expect(Int64.fromU8a([0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0], 3)).toStrictEqual(new Int64(1)); 282 | }); 283 | 284 | itThrows('should throw when empty array is provided', () => { 285 | let v1 = Int64.fromU8a([]); 286 | }); 287 | 288 | itThrows('should throw when index is out of range', () => { 289 | let v1 = Int64.fromU8a([1, 0, 1, 3], 4); 290 | }); 291 | 292 | }); -------------------------------------------------------------------------------- /assembly/__tests__/ScaleMap.spec.ts: -------------------------------------------------------------------------------- 1 | import { u128 } from "as-bignum" 2 | import { BytesReader } from ".." 3 | import { ByteArray } from "../Arrays" 4 | import { Bool } from "../Bool" 5 | import { Hash } from "../Hash" 6 | import { ScaleMap } from "../ScaleMap" 7 | import { ScaleString } from "../ScaleString" 8 | import { UInt128, UInt16, UInt32, UInt64 } from "../UInt" 9 | 10 | describe("String", () => { 11 | it("should encode ScaleMap", () => { 12 | const scaleMap1 = new ScaleMap(); 13 | scaleMap1.set(new ScaleString("scale"), new ByteArray([2, 3, 1, 9, 2, 12])); 14 | scaleMap1.set(new ScaleString("codec"), new ByteArray([12, 23, 12, 59])); 15 | scaleMap1.set(new ScaleString("as"), new ByteArray([12, 23, 52, 59, 92])); 16 | expect(scaleMap1.toU8a()).toStrictEqual([12, 20, 115, 99, 97, 108, 101, 24, 2, 3, 1, 9, 2, 12, 20, 99, 111, 100, 101, 99, 16, 12, 23, 12, 59, 8, 97, 115, 20, 12, 23, 52, 59, 92]); 17 | 18 | const scaleMap2 = new ScaleMap(); 19 | scaleMap2.set(new UInt64(0), new ByteArray([10, 2, 3, 10, 9, 2, 12])); 20 | scaleMap2.set(new UInt64(1), new ByteArray([98, 123, 23, 12, 59])); 21 | scaleMap2.set(new UInt64(2), new ByteArray([12, 23, 52, 59, 92])); 22 | scaleMap2.set(new UInt64(3), new ByteArray([12, 123, 98, 59, 92, 123, 0, 93, 2, 1])); 23 | expect(scaleMap2.toU8a()).toStrictEqual([16, 0, 0, 0, 0, 0, 0, 0, 0, 28, 10, 2, 3, 10, 9, 2, 12, 1, 0, 0, 0, 0, 0, 0, 0, 20, 98, 123, 23, 12, 59, 2, 0, 0, 0, 0, 0, 0, 0, 20, 12, 23, 52, 59, 92, 3, 0, 0, 0, 0, 0, 0, 0, 40, 12, 123, 98, 59, 92, 123, 0, 93, 2, 1]); 24 | }) 25 | 26 | it("should decode ScaleMap", () => { 27 | const mapU8a: u8[] = [16, 0, 0, 0, 0, 28, 10, 2, 3, 10, 9, 2, 12, 1, 0, 0, 0, 32, 1, 0, 98, 123, 23, 12, 59, 1, 2, 0, 0, 0, 12, 12, 23, 52, 3, 0, 0, 0, 44, 0, 12, 123, 98, 59, 92, 123, 0, 93, 2, 1] 28 | const decodedMap = BytesReader.decodeInto>(mapU8a); 29 | const scaleMap = new ScaleMap(); 30 | scaleMap.set(new UInt32(0), new ByteArray([10, 2, 3, 10, 9, 2, 12])); 31 | scaleMap.set(new UInt32(1), new ByteArray([1, 0, 98, 123, 23, 12, 59, 1])); 32 | scaleMap.set(new UInt32(2), new ByteArray([12, 23, 52])); 33 | scaleMap.set(new UInt32(3), new ByteArray([0, 12, 123, 98, 59, 92, 123, 0, 93, 2, 1])); 34 | expect(decodedMap.eq(scaleMap)).toStrictEqual(true); 35 | 36 | const map1U8a: u8[] = [24, 1, 0, 1, 3, 0, 0, 12, 0, 1, 4, 0, 0, 10, 0, 1, 11, 0, 0]; 37 | const decodedMap1 = BytesReader.decodeInto>(map1U8a); 38 | const scaleMap1 = new ScaleMap() 39 | scaleMap1.set(new UInt16(1), new Bool(true)); 40 | scaleMap1.set(new UInt16(3), new Bool(false)); 41 | scaleMap1.set(new UInt16(12), new Bool(true)); 42 | scaleMap1.set(new UInt16(4), new Bool(false)); 43 | scaleMap1.set(new UInt16(10), new Bool(true)); 44 | scaleMap1.set(new UInt16(11), new Bool(false)); 45 | expect(decodedMap1.eq(scaleMap1)).toStrictEqual(true); 46 | 47 | const map2U8a: u8[] = [ 48 | 8, 49 | 1, 12, 12, 12, 1, 1, 1, 0, 0, 0, 1, 12, 123, 123, 11, 123, 33, 121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50 | 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51 | 0xff, 0x00, 0xab, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52 | 64, 226, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 53 | ]; 54 | const decodedMap2 = BytesReader.decodeInto>(map2U8a); 55 | const scaleMap2 = new ScaleMap(); 56 | scaleMap2.set(new Hash([1, 12, 12, 12, 1, 1, 1, 0, 0, 0, 1, 12, 123, 123, 11, 123, 33, 121]), new UInt128(u128.fromU32(1))); 57 | scaleMap2.set(new Hash([0xff, 0x00, 0xab]), new UInt128(u128.fromU32(123456))); 58 | expect(decodedMap2.eq(scaleMap2)).toStrictEqual(true); 59 | }) 60 | }) -------------------------------------------------------------------------------- /assembly/__tests__/ScaleString.spec.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2020 LimeChain Ltd. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { ScaleString } from "../ScaleString"; 16 | 17 | describe("String", () => { 18 | 19 | it("should encode string", () => { 20 | const test1 = new ScaleString("hello_world"); 21 | expect>(test1.toU8a()).toStrictEqual([0x2c, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x5f, 0x77, 0x6f, 0x72, 0x6c, 0x64]); 22 | expect(test1.toU8a().length).toStrictEqual(12); 23 | 24 | const str2 = "A set of words that is complete in itself, typically containing a subject and predicate"; 25 | const test2 = new ScaleString(str2); 26 | expect>(test2.toU8a()).toStrictEqual(append([0x5d, 0x01], str2)); 27 | expect(test2.toU8a().length).toStrictEqual(89); 28 | 29 | const str3 = "™ ± Ã ¿ £ µ"; 30 | const test3 = new ScaleString(str3); 31 | expect>(test3.toU8a()).toStrictEqual([0x48, 0xe2, 0x84, 0xa2, 0x20, 0xc2, 0xb1, 0x20, 0xc3, 0x83, 0x20, 0xc2, 0xbf, 0x20, 0xc2, 0xa3, 0x20, 0xc2, 0xb5]); 32 | expect(test3.toU8a().length).toStrictEqual(19); 33 | 34 | const str4 = "The 1963 Impala featured rectilinear styling with an engine-turned aluminum rear taillight panel surrounded by a chrome border on SS models."; 35 | const test4 = new ScaleString(repeatString(str4, 500)); 36 | expect>(test4.toU8a()).toStrictEqual(append([0xC2, 0x45, 0x04, 0x00], repeatString(str4, 500))); 37 | expect(test4.toU8a().length).toStrictEqual(70004); 38 | }); 39 | 40 | it("should decode string", () => { 41 | const scaleString = ScaleString.fromU8a([0x04, 0x61]); 42 | expect>(scaleString.values).toStrictEqual(([0x61])); 43 | expect(scaleString.toString()).toStrictEqual("a"); 44 | 45 | const scaleString1 = ScaleString.fromU8a([0x08, 0x64, 0x61, 0x62, 0x62]); 46 | expect>(scaleString1.values).toStrictEqual([0x64, 0x61]); 47 | expect(scaleString1.toString()).toStrictEqual("da"); 48 | }); 49 | 50 | it("should encode to hex", () => { 51 | const scaleString = new ScaleString("as-scale-codec"); 52 | expect(scaleString.toHexString()).toStrictEqual("0x61732d7363616c652d636f646563"); 53 | const scaleString1 = new ScaleString("The 1963 Impala featured rectilinear styling with an engine-turned aluminum rear taillight panel surrounded by a chrome border on SS models."); 54 | expect(scaleString1.toHexString()).toStrictEqual("0x546865203139363320496d70616c612066656174757265642072656374696c696e656172207374796c696e67207769746820616e20656e67696e652d7475726e656420616c756d696e756d2072656172207461696c6c696768742070616e656c20737572726f756e6465642062792061206368726f6d6520626f72646572206f6e205353206d6f64656c732e"); 55 | const scaleString2 = new ScaleString("A set of words that is complete in itself, typically containing a subject and predicate"); 56 | expect(scaleString2.toHexString()).toStrictEqual("0x4120736574206f6620776f726473207468617420697320636f6d706c65746520696e20697473656c662c207479706963616c6c7920636f6e7461696e696e672061207375626a65637420616e6420707265646963617465"); 57 | }) 58 | 59 | itThrows("should throw on incorrect encoding", () => { 60 | ScaleString.fromU8a([0x04]); // Encoded length = 1, actual data length = 0 61 | }); 62 | 63 | itThrows('should throw when index is out of range', () => { 64 | ScaleString.fromU8a([8, 0, 1, 12, 0, 1, 3], 8); 65 | }); 66 | }); 67 | 68 | function append (to: Array, from: string): Array { 69 | const strToBytes: ArrayBuffer = String.UTF8.encode(from); 70 | const strArray: Uint8Array = Uint8Array.wrap(strToBytes); 71 | 72 | for (let i = 0; i < strArray.length; i++) { 73 | to.push(strArray[i]); 74 | } 75 | 76 | return to; 77 | } 78 | 79 | function repeatString (str: string, numberOfRepeats: i32): string { 80 | let result: string = str; 81 | for (let i = 1; i < numberOfRepeats; i++) { 82 | result += str; 83 | } 84 | 85 | return result; 86 | } 87 | -------------------------------------------------------------------------------- /assembly/__tests__/UInt.spec.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2020 LimeChain Ltd. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | import { u128 } from "as-bignum"; 15 | import { UInt128 } from "../UInt/UInt128"; 16 | import { UInt16 } from "../UInt/UInt16"; 17 | import { UInt32 } from "../UInt/UInt32"; 18 | import { UInt64 } from "../UInt/UInt64"; 19 | import { UInt8 } from "../UInt/UInt8"; 20 | 21 | describe("UInt8", () => { 22 | 23 | it("should encode uint8", () => { 24 | let v1 = new UInt8(1); 25 | expect(v1.toU8a()).toStrictEqual([0x01]); 26 | expect(v1.encodedLength()).toStrictEqual(1); 27 | 28 | let v2 = new UInt8(15); 29 | expect(v2.toU8a()).toStrictEqual([0xf]); 30 | expect(v2.encodedLength()).toStrictEqual(1); 31 | 32 | let v3 = new UInt8(16); 33 | expect(v3.toU8a()).toStrictEqual([0x10]); 34 | expect(v3.encodedLength()).toStrictEqual(1); 35 | 36 | let v4 = new UInt8(127); 37 | expect(v4.toU8a()).toStrictEqual([0x7f]); 38 | expect(v4.encodedLength()).toStrictEqual(1); 39 | 40 | let v5 = new UInt8(255); 41 | expect(v5.toU8a()).toStrictEqual([0xff]); 42 | expect(v5.encodedLength()).toStrictEqual(1); 43 | 44 | let v6 = new UInt8(241); 45 | expect(v6.toU8a()).toStrictEqual([0xf1]); 46 | expect(v6.encodedLength()).toStrictEqual(1); 47 | 48 | let v7 = new UInt8(129); 49 | expect(v7.toU8a()).toStrictEqual([0x81]); 50 | expect(v7.encodedLength()).toStrictEqual(1); 51 | }); 52 | 53 | it("should decode uint8", () => { 54 | expect(UInt8.fromU8a([0x01])).toStrictEqual(new UInt8(1)); 55 | expect(UInt8.fromU8a([0xf])).toStrictEqual(new UInt8(15)); 56 | expect(UInt8.fromU8a([0x10])).toStrictEqual(new UInt8(16)); 57 | expect(UInt8.fromU8a([0xf1])).toStrictEqual(new UInt8(241)); 58 | expect(UInt8.fromU8a([0x81])).toStrictEqual(new UInt8(129)); 59 | }); 60 | 61 | it("should decode uint8 with populate method", () => { 62 | const uInt8 = new UInt8(); 63 | uInt8.populateFromBytes([0x7f]); 64 | expect(uInt8).toStrictEqual(new UInt8(127)); 65 | uInt8.populateFromBytes([0xff]); 66 | expect(uInt8).toStrictEqual(new UInt8(255)); 67 | uInt8.populateFromBytes([1]); 68 | expect(uInt8).toStrictEqual(new UInt8(1)); 69 | uInt8.populateFromBytes([69]); 70 | expect(uInt8).toStrictEqual(new UInt8(69)); 71 | }); 72 | 73 | it("should decode only first byte", () => { 74 | expect(UInt8.fromU8a([0x05, 0])).toStrictEqual(new UInt8(5)); 75 | expect(UInt8.fromU8a([0x01, 0, 1, 2, 12])).toStrictEqual(new UInt8(1)); 76 | }); 77 | 78 | itThrows('should throw when empty array is provided', () => { 79 | let v1 = UInt8.fromU8a([]); 80 | }); 81 | itThrows('should throw when index is out of range', () => { 82 | let v1 = UInt8.fromU8a([1], 2); 83 | }); 84 | 85 | }); 86 | 87 | describe("UInt16", () => { 88 | 89 | it("should encode uint16", () => { 90 | let v1 = new UInt16(1); 91 | expect(v1.toU8a()).toStrictEqual([0x01, 0]); 92 | expect(v1.encodedLength()).toStrictEqual(2); 93 | 94 | let v2 = new UInt16(15); 95 | expect(v2.toU8a()).toStrictEqual([0xf, 0]); 96 | expect(v2.encodedLength()).toStrictEqual(2); 97 | 98 | let v3 = new UInt16(16); 99 | expect(v3.toU8a()).toStrictEqual([0x10, 0]); 100 | expect(v3.encodedLength()).toStrictEqual(2); 101 | 102 | let v4 = new UInt16(127); 103 | expect(v4.toU8a()).toStrictEqual([0x7f, 0]); 104 | expect(v4.encodedLength()).toStrictEqual(2); 105 | 106 | let v5 = new UInt16(65535); 107 | expect(v5.toU8a()).toStrictEqual([0xff, 0xff]); 108 | expect(v5.encodedLength()).toStrictEqual(2); 109 | 110 | let v6 = new UInt16(65521); 111 | expect(v6.toU8a()).toStrictEqual([0xf1, 0xff]); 112 | expect(v6.encodedLength()).toStrictEqual(2); 113 | 114 | let v7 = new UInt16(65409); 115 | expect(v7.toU8a()).toStrictEqual([0x81, 0xff]); 116 | expect(v7.encodedLength()).toStrictEqual(2); 117 | 118 | let v8 = new UInt16(15000); 119 | expect(v8.toU8a()).toStrictEqual([0x98, 0x3a]); 120 | expect(v8.encodedLength()).toStrictEqual(2); 121 | 122 | let v9 = new UInt16(16383); 123 | expect(v9.toU8a()).toStrictEqual([0xff, 0x3f]); 124 | expect(v9.encodedLength()).toStrictEqual(2); 125 | 126 | let v10 = new UInt16(50536); 127 | expect(v10.toU8a()).toStrictEqual([0x68, 0xc5]); 128 | expect(v10.encodedLength()).toStrictEqual(2); 129 | 130 | let v11 = new UInt16(49153); 131 | expect(v11.toU8a()).toStrictEqual([0x01, 0xc0]); 132 | expect(v11.encodedLength()).toStrictEqual(2); 133 | }); 134 | 135 | it("should decode uint16", () => { 136 | expect(UInt16.fromU8a([0x01, 0])).toStrictEqual(new UInt16(1)); 137 | expect(UInt16.fromU8a([0xf, 0])).toStrictEqual(new UInt16(15)); 138 | expect(UInt16.fromU8a([0x10, 0])).toStrictEqual(new UInt16(16)); 139 | expect(UInt16.fromU8a([0x81, 0xff])).toStrictEqual(new UInt16(65409)); 140 | expect(UInt16.fromU8a([0x98, 0x3a])).toStrictEqual(new UInt16(15000)); 141 | expect(UInt16.fromU8a([0xff, 0x3f])).toStrictEqual(new UInt16(16383)); 142 | expect(UInt16.fromU8a([0x68, 0xc5])).toStrictEqual(new UInt16(50536)); 143 | expect(UInt16.fromU8a([0x01, 0xc0])).toStrictEqual(new UInt16(49153)); 144 | }); 145 | 146 | it("should decode uInt16 with populate method", () => { 147 | const uInt16 = new UInt16(); 148 | uInt16.populateFromBytes([0x7f, 0]); 149 | expect(uInt16).toStrictEqual(new UInt16(127)); 150 | uInt16.populateFromBytes([0xff, 0xff]); 151 | expect(uInt16).toStrictEqual(new UInt16(65535)); 152 | uInt16.populateFromBytes([0xf1, 0xff]); 153 | expect(uInt16).toStrictEqual(new UInt16(65521)); 154 | uInt16.populateFromBytes([1]); 155 | expect(uInt16).toStrictEqual(new UInt16(1)); 156 | uInt16.populateFromBytes([123]); 157 | expect(uInt16).toStrictEqual(new UInt16(123)); 158 | }); 159 | 160 | it('should decode only two bytes', () => { 161 | expect(UInt16.fromU8a([0x01, 0x10, 0x00, 0x01], 1)).toStrictEqual(new UInt16(16)); 162 | }); 163 | 164 | itThrows('should throw when empty array is provided', () => { 165 | let v1 = UInt16.fromU8a([]); 166 | }); 167 | itThrows('should throw when index is out of range', () => { 168 | let v1 = UInt16.fromU8a([1, 0, 1, 223], 4); 169 | }); 170 | }); 171 | 172 | describe("UInt32", () => { 173 | it("should encode uint32", () => { 174 | let v1 = new UInt32(1); 175 | expect(v1.toU8a()).toStrictEqual([0x01, 0, 0, 0]); 176 | expect(v1.encodedLength()).toStrictEqual(4); 177 | 178 | let v2 = new UInt32(16383); 179 | expect(v2.toU8a()).toStrictEqual([0xff, 0x3f, 0, 0]); 180 | expect(v2.encodedLength()).toStrictEqual(4); 181 | 182 | let v3 = new UInt32(1073741823); 183 | expect(v3.toU8a()).toStrictEqual([0xff, 0xff, 0xff, 0x3f]); 184 | expect(v3.encodedLength()).toStrictEqual(4); 185 | 186 | let v4 = new UInt32(4294967295); 187 | expect(v4.toU8a()).toStrictEqual([0xff, 0xff, 0xff, 0xff]); 188 | expect(v4.encodedLength()).toStrictEqual(4); 189 | 190 | let v5 = new UInt32(4294950913); 191 | expect(v5.toU8a()).toStrictEqual([0x01, 0xc0, 0xff, 0xff]); 192 | expect(v5.encodedLength()).toStrictEqual(4); 193 | 194 | let v6 = new UInt32(3221225473); 195 | expect(v6.toU8a()).toStrictEqual([0x01, 0x00, 0x00, 0xc0]); 196 | expect(v6.encodedLength()).toStrictEqual(4); 197 | }); 198 | 199 | it("should decode uint32", () => { 200 | expect(UInt32.fromU8a([0x01, 0, 0, 0])).toStrictEqual(new UInt32(1)); 201 | expect(UInt32.fromU8a([0xff, 0xff, 0xff, 0x3f])).toStrictEqual(new UInt32(1073741823)); 202 | expect(UInt32.fromU8a([0x01, 0xc0, 0xff, 0xff])).toStrictEqual(new UInt32(4294950913)); 203 | expect(UInt32.fromU8a([0x01, 0x00, 0x00, 0xc0])).toStrictEqual(new UInt32(3221225473)); 204 | }); 205 | 206 | it("should decode uInt32 with populate method", () => { 207 | const uInt32 = new UInt32(); 208 | uInt32.populateFromBytes([0xff, 0x3f, 0, 0]); 209 | expect(uInt32).toStrictEqual(new UInt32(16383)); 210 | uInt32.populateFromBytes([0xff, 0xff, 0xff, 0x3f]); 211 | expect(uInt32).toStrictEqual(new UInt32(1073741823)); 212 | uInt32.populateFromBytes([0xff, 0xff, 0xff, 0xff]); 213 | expect(uInt32).toStrictEqual(new UInt32(4294967295)); 214 | uInt32.populateFromBytes([1, 0, 0, 0]); 215 | expect(uInt32).toStrictEqual(new UInt32(1)); 216 | uInt32.populateFromBytes([123, 0, 0, 0]); 217 | expect(uInt32).toStrictEqual(new UInt32(123)); 218 | }) 219 | 220 | it('should decode only four bytes', () => { 221 | expect(UInt32.fromU8a([0x01, 0x01, 0x00, 0x00, 0xc0], 1)).toStrictEqual(new UInt32(3221225473)); 222 | expect(UInt32.fromU8a([0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00], 3)).toStrictEqual(new UInt32(1)); 223 | }); 224 | 225 | itThrows('should throw when empty array is provided', () => { 226 | let v1 = UInt32.fromU8a([]); 227 | }); 228 | itThrows('should throw when index is out of range', () => { 229 | let v1 = UInt32.fromU8a([1, 0, 1, 3, 123, 123, 12, 0], 9); 230 | }); 231 | 232 | 233 | }); 234 | 235 | describe("UInt64", () => { 236 | 237 | it("should encode uint64", () => { 238 | let v1 = new UInt64(1); 239 | expect(v1.toU8a()).toStrictEqual([0x01, 0, 0, 0, 0, 0, 0, 0]); 240 | expect(v1.encodedLength()).toStrictEqual(8); 241 | 242 | let v2 = new UInt64(16383); 243 | expect(v2.toU8a()).toStrictEqual([0xff, 0x3f, 0, 0, 0, 0, 0, 0]); 244 | expect(v2.encodedLength()).toStrictEqual(8); 245 | 246 | let v3 = new UInt64(1073741823); 247 | expect(v3.toU8a()).toStrictEqual([0xff, 0xff, 0xff, 0x3f, 0, 0, 0, 0]); 248 | expect(v3.encodedLength()).toStrictEqual(8); 249 | 250 | let v4 = new UInt64(9223372036854775807); 251 | expect(v4.toU8a()).toStrictEqual([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f]); 252 | expect(v4.encodedLength()).toStrictEqual(8); 253 | 254 | let v5 = new UInt64(18446744073709551615); 255 | expect(v5.toU8a()).toStrictEqual([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]); 256 | expect(v5.encodedLength()).toStrictEqual(8) 257 | 258 | }); 259 | 260 | it("should decode uint64", () => { 261 | expect(UInt64.fromU8a([0x01, 0, 0, 0, 0, 0, 0, 0])).toStrictEqual(new UInt64(1)); 262 | expect(UInt64.fromU8a([0xff, 0x3f, 0, 0, 0, 0, 0, 0])).toStrictEqual(new UInt64(16383)); 263 | expect(UInt64.fromU8a([0xff, 0xff, 0xff, 0x3f, 0, 0, 0, 0])).toStrictEqual(new UInt64(1073741823)); 264 | expect(UInt64.fromU8a([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f])).toStrictEqual(new UInt64(9223372036854775807)); 265 | expect(UInt64.fromU8a([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff])).toStrictEqual(new UInt64(18446744073709551615)); 266 | }); 267 | 268 | it("should decode uint64 with populate method", () => { 269 | const uInt64 = new UInt64(); 270 | uInt64.populateFromBytes([0xff, 0xff, 0xff, 0x3f, 0, 0, 0, 0]); 271 | expect(uInt64).toStrictEqual(new UInt64(1073741823)); 272 | uInt64.populateFromBytes([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f]); 273 | expect(uInt64).toStrictEqual(new UInt64(9223372036854775807)); 274 | uInt64.populateFromBytes([1, 0, 0, 0, 0, 0, 0, 0]); 275 | expect(uInt64).toStrictEqual(new UInt64(1)); 276 | uInt64.populateFromBytes([123, 0, 0, 0, 0, 0, 0, 0]); 277 | expect(uInt64).toStrictEqual(new UInt64(123)); 278 | }) 279 | 280 | it('should decode only eight bytes', () => { 281 | expect(UInt64.fromU8a([0x01, 0x01, 0xff, 0x3f, 0, 0, 0, 0, 0, 0], 2)).toStrictEqual(new UInt64(16383)); 282 | expect(UInt64.fromU8a([0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0], 3)).toStrictEqual(new UInt64(1)); 283 | }); 284 | 285 | itThrows('should throw when empty array is provided', () => { 286 | let v1 = UInt64.fromU8a([]); 287 | }); 288 | 289 | itThrows('should throw when index is out of range', () => { 290 | let v1 = UInt64.fromU8a([1, 0, 1, 3], 13); 291 | }); 292 | 293 | }); 294 | 295 | describe("UInt128", () => { 296 | 297 | it("should encode uint128", () => { 298 | const v0 = new UInt128(u128.fromU32(1)); 299 | expect(v0.toU8a()).toStrictEqual([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); 300 | 301 | const v1 = new UInt128(u128.fromU32(20001)); 302 | expect(v1.toU8a()).toStrictEqual([33, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); 303 | 304 | const v2 = new UInt128(u128.fromU32(123456)); 305 | expect(v2.toU8a()).toStrictEqual([64, 226, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); 306 | 307 | const v3 = new UInt128(u128.fromU64(123456789)); 308 | expect(v3.toU8a()).toStrictEqual([21, 205, 91, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); 309 | 310 | const v4 = new UInt128(u128.fromString('123456789012345')); 311 | expect(v4.toU8a()).toStrictEqual([121, 223, 13, 134, 72, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); 312 | 313 | const v5 = new UInt128(u128.fromString('12345678901234567890')); 314 | expect(v5.toU8a()).toStrictEqual([210, 10, 31, 235, 140, 169, 84, 171, 0, 0, 0, 0, 0, 0, 0, 0]); 315 | 316 | const v6 = new UInt128(u128.fromString('1234567890123456789012345')); 317 | expect(v6.toU8a()).toStrictEqual([121, 223, 226, 61, 68, 166, 54, 15, 110, 5, 1, 0, 0, 0, 0, 0]); 318 | 319 | const v7 = new UInt128(u128.fromU64(u64.MAX_VALUE)); 320 | expect(v7.toU8a()).toStrictEqual([255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0]); 321 | 322 | const v8 = new UInt128(u128.Max); 323 | expect(v8.toU8a()).toStrictEqual([255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]); 324 | 325 | //@ts-ignore 326 | const v9 = new UInt128(u128.Max - u128.fromU64(u64.MAX_VALUE)); 327 | expect(v9.toU8a()).toStrictEqual([0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255]); 328 | }); 329 | 330 | it("should decode uint128", () => { 331 | const v0 = UInt128.fromU8a([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); 332 | expect(v0.toString()).toStrictEqual("1"); 333 | 334 | const v1 = UInt128.fromU8a([49, 212, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); 335 | expect(v1.toString()).toStrictEqual("54321"); 336 | 337 | const v2 = UInt128.fromU8a([21, 205, 91, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); 338 | expect(v2.toString()).toStrictEqual("123456789"); 339 | 340 | const v3 = UInt128.fromU8a([121, 223, 13, 134, 72, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); 341 | expect(v3.toString()).toStrictEqual("123456789012345"); 342 | 343 | const v4 = UInt128.fromU8a([210, 10, 31, 235, 140, 169, 84, 171, 0, 0, 0, 0, 0, 0, 0, 0]); 344 | expect(v4.toString()).toStrictEqual("12345678901234567890"); 345 | 346 | const v5 = UInt128.fromU8a([121, 223, 226, 61, 68, 166, 54, 15, 110, 5, 1, 0, 0, 0, 0, 0]); 347 | expect(v5.toString()).toStrictEqual("1234567890123456789012345"); 348 | 349 | const v6 = UInt128.fromU8a([255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0]); 350 | expect(v6.toString()).toStrictEqual(u64.MAX_VALUE.toString()); 351 | 352 | const v7 = UInt128.fromU8a([255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]); 353 | expect(v7.toString()).toStrictEqual(u128.Max.toString()); 354 | }); 355 | 356 | it("should decode uint128 with populate method", () => { 357 | const v0 = new UInt128(); 358 | v0.populateFromBytes([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); 359 | expect(v0.toString()).toStrictEqual("1"); 360 | 361 | const v1 = new UInt128(); 362 | v1.populateFromBytes([49, 212, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); 363 | expect(v1.toString()).toStrictEqual("54321"); 364 | 365 | const v2 = new UInt128(); 366 | v2.populateFromBytes([21, 205, 91, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); 367 | expect(v2.toString()).toStrictEqual("123456789"); 368 | 369 | const v3 = new UInt128(); 370 | v3.populateFromBytes([121, 223, 13, 134, 72, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); 371 | expect(v3.toString()).toStrictEqual("123456789012345"); 372 | 373 | const v4 = new UInt128(); 374 | v4.populateFromBytes([210, 10, 31, 235, 140, 169, 84, 171, 0, 0, 0, 0, 0, 0, 0, 0]); 375 | expect(v4.toString()).toStrictEqual("12345678901234567890"); 376 | 377 | const v5 = new UInt128(); 378 | v5.populateFromBytes([121, 223, 226, 61, 68, 166, 54, 15, 110, 5, 1, 0, 0, 0, 0, 0]); 379 | expect(v5.toString()).toStrictEqual("1234567890123456789012345"); 380 | 381 | const v6 = new UInt128(); 382 | v6.populateFromBytes([255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0]); 383 | expect(v6.toString()).toStrictEqual(u64.MAX_VALUE.toString()); 384 | 385 | const v7 = new UInt128(); 386 | v7.populateFromBytes([255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]); 387 | expect(v7.toString()).toStrictEqual(u128.Max.toString()); 388 | }); 389 | 390 | itThrows('should throw when decoding empty array', () => { 391 | const v1 = UInt128.fromU8a([]); 392 | }) 393 | 394 | }); -------------------------------------------------------------------------------- /assembly/__tests__/as-pect.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /assembly/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./Arrays"; 2 | export * from "./Bool"; 3 | export * from "./Byte"; 4 | export * from "./BytesReader"; 5 | export * from "./Hash"; 6 | export * from "./Int"; 7 | export * from "./interfaces"; 8 | export * from "./ScaleMap"; 9 | export * from "./ScaleString"; 10 | export * from "./UInt"; 11 | export * from "./utils/Bytes"; 12 | 13 | -------------------------------------------------------------------------------- /assembly/interfaces/Codec.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2020 LimeChain Ltd. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | /** 16 | * @name Codec 17 | * @description 18 | * The base Codec interface. All supported types by the library must implement this interface. 19 | * This interface represents the base functions required by every encoding/decoding of types 20 | */ 21 | export interface Codec { 22 | 23 | /** 24 | * @description Encodes the value as a Uint8Array as per the SCALE specification 25 | */ 26 | toU8a(): u8[]; 27 | 28 | /** 29 | * @description The length of Uint8Array when the value is encoded 30 | */ 31 | encodedLength(): i32; 32 | /** 33 | * @description Non-static constructor method used to populate defined properties of the model 34 | * @param bytes SCALE encoded bytes 35 | * @param index index to start decoding the bytes from 36 | */ 37 | populateFromBytes(bytes: u8[], index: i32): void; 38 | 39 | /** 40 | * Checks if an instance is equal with other instance 41 | * @param other other instance 42 | */ 43 | eq(other: Codec): bool; 44 | 45 | /** 46 | * Checks if an instance is not equal with other instance 47 | * @param other other instance 48 | */ 49 | notEq(other: Codec): bool; 50 | } -------------------------------------------------------------------------------- /assembly/interfaces/DecodedData.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2020 LimeChain Ltd. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | /** 16 | * @name DecodedData 17 | * @description 18 | * DecodedData is used in Scale arrays as a standard output 19 | * each element should return after decoding 20 | * @param 21 | * value - Decoded value 22 | * decBytes - Number of decoded bytes 23 | */ 24 | 25 | export class DecodedData { 26 | constructor (public readonly value: T, public readonly decBytes: i32) { } 27 | } -------------------------------------------------------------------------------- /assembly/interfaces/UnwrappableCodec.ts: -------------------------------------------------------------------------------- 1 | import { Codec } from ".."; 2 | 3 | /** 4 | * @description Interface for types that could be unwrapped 5 | */ 6 | export interface UnwrappableCodec extends Codec { 7 | /** 8 | * Returns the inner native value of the SCALE type 9 | */ 10 | unwrap(): T; 11 | } -------------------------------------------------------------------------------- /assembly/interfaces/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Codec'; 2 | export * from './DecodedData'; 3 | export * from './UnwrappableCodec'; 4 | -------------------------------------------------------------------------------- /assembly/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../node_modules/assemblyscript/std/assembly.json", 3 | "include": [ 4 | "./**/*.ts" 5 | ] 6 | } -------------------------------------------------------------------------------- /assembly/utils/Arrays.ts: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Array Utility functions 4 | */ 5 | export namespace ArrayUtils { 6 | 7 | /** 8 | * By given 2 arrays, checks whether their values are equal (strict equal by index) 9 | */ 10 | export function areArraysEqual(a: Array, b: Array): bool { 11 | if (a.length != b.length) { 12 | return false; 13 | } 14 | 15 | for (let i = 0; i < a.length; i++) { 16 | if (a[i] != b[i]) { 17 | return false; 18 | } 19 | } 20 | return true; 21 | } 22 | 23 | /** 24 | * Returns new Array from Uint8 Typed array 25 | * @param typedArr 26 | */ 27 | export function toU8Array(typedArr: Uint8Array): u8[] { 28 | let res: u8[] = []; 29 | for (let i = 0; i < typedArr.length; i++) { 30 | res.push(typedArr[i]); 31 | } 32 | return res; 33 | } 34 | } -------------------------------------------------------------------------------- /assembly/utils/Bytes.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2020 LimeChain Ltd. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { DecodedData } from "./../interfaces/DecodedData"; 16 | 17 | export const enum BIT_LENGTH { 18 | INT_8 = 1, 19 | INT_16 = 2, 20 | INT_32 = 4, 21 | INT_64 = 8, 22 | INT_128 = 16 23 | } 24 | 25 | export class Bytes { 26 | 27 | static putUint (b: u8[], v: T, bitLength: number): void { 28 | b[0] = u8(v); 29 | 30 | for (let i: u8 = 1; i < bitLength; i++) { 31 | b[i] = u8(v >> i * 8); 32 | } 33 | } 34 | 35 | static toUint (b: u8[], bitLength: i32, index: i32 = 0): T { 36 | const buf = new Array(bitLength); 37 | Bytes.copy(b, buf, 0, index); 38 | 39 | let result: T = buf[0]; 40 | for (let i: i32 = 1; i < bitLength; i++) { 41 | result |= (buf[i] as T) << 8 * u8(i); 42 | } 43 | 44 | return result; 45 | } 46 | 47 | static appendUint (b: Array, v: T, bitLength: number): void { 48 | b.push(u8(v)); 49 | for (let i: u8 = 1; i < bitLength; i++) { 50 | b.push(u8(v >> i * 8)); 51 | } 52 | } 53 | 54 | 55 | /** 56 | * @description Copy u8[] src elements in u8[] dst at provided position. 57 | */ 58 | static copy (src: T[], dst: Array, dstStart: i32 = 0, srcStart: i32 = 0): void { 59 | for (let i = 0; i < dst.length; i++) { 60 | if (src.length - srcStart <= i) { 61 | break; 62 | } 63 | dst[dstStart + i] = src[srcStart + i]; 64 | } 65 | } 66 | 67 | /** 68 | * @description Copy u8[] src elements in Uint8Array dst at provided position. 69 | */ 70 | static copyToTyped (src: u8[], dst: Uint8Array, dstStart: i32 = 0, srcStart: i32 = 0): void { 71 | for (let i = 0; i < dst.length; i++) { 72 | if (src.length - srcStart <= i) { 73 | break; 74 | } 75 | dst[dstStart + i] = src[srcStart + i]; 76 | } 77 | } 78 | 79 | 80 | // Decode compact int from u8[] input 81 | static decodeCompactInt (input: u8[], index: i32 = 0): DecodedData { 82 | assert(input.length - index != 0, "Invalid input: Byte array should not be empty"); 83 | 84 | const mode = input[index] & 3; 85 | if (i32(mode) <= BIT_LENGTH.INT_16) { 86 | return Bytes.decodeSmallInt(input, mode, index); 87 | } 88 | 89 | const topSixBits = input[index] >> 2; 90 | const byteLen = u8(topSixBits) + 4; 91 | 92 | const buf = new Array(byteLen); 93 | Bytes.copy(input, buf, 0, index); 94 | 95 | if (i32(byteLen) == BIT_LENGTH.INT_32) { 96 | return new DecodedData(u64(Bytes.toUint(buf, BIT_LENGTH.INT_32)), BIT_LENGTH.INT_32); 97 | } 98 | 99 | if (i32(byteLen) > BIT_LENGTH.INT_32 && i32(byteLen) < BIT_LENGTH.INT_64) { 100 | const tmp = new Array(8); 101 | Bytes.copy(buf, tmp); 102 | return new DecodedData(Bytes.toUint(tmp, BIT_LENGTH.INT_64), BIT_LENGTH.INT_64); 103 | } 104 | 105 | throw new Error('CompactInt: Invalid encoding of compact int provided'); 106 | } 107 | 108 | static decodeSmallInt (input: u8[], mode: u8, index: i32 = 0): DecodedData { 109 | assert(mode == 0 || mode == 1 || mode == 2, 'Small Int: mode is invalid'); 110 | if (mode == 0) { 111 | return new DecodedData(u64(Bytes.decodeByte(input[index])), BIT_LENGTH.INT_8); 112 | } else if (mode == 1) { 113 | assert(i32(input.length - index) >= BIT_LENGTH.INT_16, "Invalid input: expected 2 bytes array"); 114 | return new DecodedData(u64(Bytes.decode2Bytes([input[index], input[index+1]])), BIT_LENGTH.INT_16); 115 | } else { 116 | assert(i32(input.length - index) >= BIT_LENGTH.INT_32, "Invalid input: expected 4 bytes array"); 117 | return new DecodedData(u64(Bytes.decode4Bytes([input[index], input[index+1], input[index+2], input[index+3]])), BIT_LENGTH.INT_32); 118 | } 119 | } 120 | 121 | static decodeByte (byte: u8): i64 { 122 | return i64(byte >> 2); 123 | } 124 | 125 | static decode2Bytes (bytes: u8[]): i64 { 126 | return i64(Bytes.toUint(bytes, BIT_LENGTH.INT_16) >> 2) 127 | } 128 | 129 | static decode4Bytes (bytes: u8[]): i64 { 130 | return i64(Bytes.toUint(bytes, BIT_LENGTH.INT_32) >> 2); 131 | } 132 | 133 | /** 134 | * Removes the last ZERO bytes of an Array 135 | * @param bytes 136 | */ 137 | static trimEmptyBytes (bytes: u8[]): void { 138 | for (let i = bytes.length - 1; i > 0; i--) { 139 | if (bytes[i] === 0) { 140 | bytes.pop(); 141 | } else { 142 | break; 143 | } 144 | } 145 | } 146 | 147 | /** 148 | * Appends Empty Bytes to the provided bytes array 149 | * @param bytes - the array of bytes to which it will add empty bytes 150 | * @param targetLength - number of empty bytes to add 151 | */ 152 | static appendZeroBytes (bytes: u8[], targetLength: i32): void { 153 | assert(targetLength >= bytes.length, "invalid padding provided"); 154 | const numberOfZeros = targetLength - bytes.length; 155 | for (let i = 0; i < numberOfZeros; i++) { 156 | bytes.push(0); 157 | } 158 | } 159 | } 160 | 161 | -------------------------------------------------------------------------------- /assembly/utils/BytesBuffer.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2020 LimeChain Ltd. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { BIT_LENGTH, Bytes } from "./Bytes"; 16 | 17 | export class BytesBuffer { 18 | 19 | public bytes: Array; 20 | 21 | constructor () { 22 | this.bytes = new Array(); 23 | } 24 | 25 | /** 26 | * @description Encodes array length 27 | */ 28 | encodeCompactInt (i: i64): void { 29 | if (i < 1 << 6) { 30 | Bytes.appendUint(this.bytes, u8(i) << 2, BIT_LENGTH.INT_8); 31 | } else if (i < 1 << 14) { 32 | Bytes.appendUint(this.bytes, u16(i << 2) + 1, BIT_LENGTH.INT_16); 33 | } else if (i < 1 << 30) { 34 | Bytes.appendUint(this.bytes, u32(i << 2) + 2, BIT_LENGTH.INT_32); 35 | } else { 36 | const o = new Array(8); 37 | let m = i; 38 | 39 | let numBytes = 0; 40 | for (; numBytes < 256 && m != 0; numBytes++) { 41 | m = m >> 8; 42 | } 43 | 44 | const topSixBits: u8 = u8(numBytes - 4); 45 | const lengthByte: u8 = (topSixBits << 2) + 3; 46 | 47 | Bytes.putUint(this.bytes, lengthByte, BIT_LENGTH.INT_8); 48 | Bytes.putUint(o, i64(i), BIT_LENGTH.INT_64); 49 | 50 | Bytes.copy(o.slice(0, numBytes), this.bytes, 1); 51 | } 52 | } 53 | 54 | /** 55 | * @description Push input in this.bytes 56 | */ 57 | write (input: u8[]): void { 58 | Bytes.copy(input, this.bytes, this.bytes.length); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 |

AssemblyScript SCALE Codec Example

2 | 3 | The purpose of the example is to demonstrates 4 | * How AssemblyScript SCALE Codec implementation could be used from another AS project 5 | * How one could interact with the library from JS 6 | 7 | # Installation & Usage 8 | 1. Installation 9 | ``` 10 | npm install 11 | ``` 12 | 2. Build 13 | ``` 14 | npm run build 15 | ``` 16 | 3. Start the example 17 | For demonstration execute the following command: 18 | ``` 19 | npm run start 20 | ``` 21 | -------------------------------------------------------------------------------- /example/as-pect.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | /** 3 | * A set of globs passed to the glob package that qualify typescript files for testing. 4 | */ 5 | include: ["assembly/__tests__/**/*.spec.ts"], 6 | /** 7 | * A set of globs passed to the glob package that quality files to be added to each test. 8 | */ 9 | add: ["assembly/__tests__/**/*.include.ts"], 10 | /** 11 | * All the compiler flags needed for this test suite. Make sure that a binary file is output. 12 | */ 13 | flags: { 14 | /** To output a wat file, uncomment the following line. */ 15 | // "--textFile": ["output.wat"], 16 | /** A runtime must be provided here. */ 17 | "--runtime": ["stub"], // Acceptable values are: full, half, stub (arena), and none 18 | }, 19 | /** 20 | * A set of regexp that will disclude source files from testing. 21 | */ 22 | disclude: [/node_modules/], 23 | /** 24 | * Add your required AssemblyScript imports here. 25 | */ 26 | imports (memory, createImports, instantiateSync, binary) { 27 | let instance; // Imports can reference this 28 | const myImports = { 29 | // put your web assembly imports here, and return the module 30 | }; 31 | instance = instantiateSync(binary, createImports(myImports)); 32 | return instance; 33 | }, 34 | /** 35 | * Add a custom reporter here if you want one. The following example is in typescript. 36 | * 37 | * @example 38 | * import { TestReporter, TestGroup, TestResult, TestContext } from "as-pect"; 39 | * 40 | * export class CustomReporter extends TestReporter { 41 | * // implement each abstract method here 42 | * public abstract onStart(suite: TestContext): void; 43 | * public abstract onGroupStart(group: TestGroup): void; 44 | * public abstract onGroupFinish(group: TestGroup): void; 45 | * public abstract onTestStart(group: TestGroup, result: TestResult): void; 46 | * public abstract onTestFinish(group: TestGroup, result: TestResult): void; 47 | * public abstract onFinish(suite: TestContext): void; 48 | * } 49 | */ 50 | // reporter: new CustomReporter(), 51 | /** 52 | * Specify if the binary wasm file should be written to the file system. 53 | */ 54 | outputBinary: false, 55 | }; 56 | -------------------------------------------------------------------------------- /example/assembly/__tests__/as-pect.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /example/assembly/index.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2020 LimeChain Ltd. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { u128 } from "as-bignum"; 16 | import { Bool, Byte, BytesReader, CompactInt, Hash, Int16, Int32, Int64, Int8, ScaleMap, ScaleString, UInt128, UInt128Array, UInt16, UInt32, UInt64, UInt8 } from "as-scale-codec"; 17 | 18 | export function demonstrate(): void { 19 | 20 | trace(`Encoding examples:`) 21 | 22 | // Bool 23 | const scaleBool = new Bool(true); 24 | trace("bool(true) -> " + scaleBool.toU8a().toString()); 25 | 26 | // Byte 27 | const scaleByte = new Byte(0x01); 28 | trace("Byte(0x01) -> " + scaleByte.toU8a().toString()); 29 | 30 | // String 31 | const scaleString = new ScaleString("a"); 32 | trace("String(a) -> " + scaleString.toU8a().toString()) 33 | 34 | // ScaleMap 35 | const scaleMap = new ScaleMap(); 36 | scaleMap.set(new Int32(1), new Bool(false)); 37 | trace("ScaleMap(new Map([[1, false]])" + scaleMap.toU8a().toString()); // => [4, 1, 0, 0, 0, 0]; 38 | 39 | // Hash 40 | const scaleHash = new Hash([0xff, 0x00, 0xab]); 41 | trace("Hash([0xff, 0x00, 0xab]) -> " + scaleHash.toU8a().toString()); // => [0xff, 0x00, 0xab, 0x00, ... 0x00] (32 bytes long) 42 | 43 | // Compact Int 44 | const scaleCompactInt = new CompactInt(1); 45 | trace("CompactInt(1) -> " + scaleCompactInt.toU8a().toString()); // => [0x04] 46 | 47 | // Int 48 | const scaleInt8 = new Int8(-1); 49 | trace("Int8(-1) -> " + scaleInt8.toU8a().toString()); // => [0xff] 50 | 51 | const scaleInt16 = new Int16(-1); 52 | trace("Int16(-1) -> " + scaleInt16.toU8a().toString()) // => [0xff, 0xff] 53 | 54 | const scaleInt32 = new Int32(-1); 55 | trace("Int32(-1) -> " + scaleInt32.toU8a().toString()) // => [0xff, 0xff, 0xff, 0xff] 56 | 57 | const scaleInt64 = new Int64(-1); 58 | trace("Int64(-1) -> " + scaleInt64.toU8a().toString()) // => [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] 59 | 60 | const scaleUInt8 = new UInt8(1); 61 | trace("UInt8(1) -> " + scaleUInt8.toU8a().toString()) // => [0x01] 62 | 63 | const scaleUInt16 = new UInt16(1); 64 | trace("Uint16(1) -> " + scaleUInt16.toU8a().toString()) // => [0x01, 0x00] 65 | 66 | const scaleUInt32 = new UInt32(1); 67 | trace("Uint32(1) -> " + scaleUInt32.toU8a().toString()) // => [0x01, 0x00, 0x00, 0x00] 68 | 69 | const scaleUInt64 = new UInt64(1); 70 | trace("Uint64(1) -> " + scaleUInt64.toU8a().toString()); // => [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] 71 | 72 | const scaleUInt128 = new UInt128(u128.fromU64(18446744073709551615)); 73 | trace("Uint128(18446744073709551615) -> " + scaleUInt128.toU8a().toString()); // => [0x13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] 74 | 75 | trace("Bool [0x01] -> " + Bool.fromU8a([0x01]).value.toString()); 76 | trace("Byte [0x01] -> " + Byte.fromU8a([0x01]).value.toString()); 77 | 78 | const decodeStr = ScaleString.fromU8a([0x04, 0x61]); 79 | trace("String [0x04, 0x61] -> " + decodeStr.valueStr.toString()); 80 | const decodeHash = Hash.fromU8a([0xff, 0x00, 0xab]); 81 | trace("Hash [0xff, 0x00, 0xab] -> " + decodeHash.toString()) 82 | trace("CompactInt [0x04] -> " + CompactInt.fromU8a([0x04]).value.toString()); 83 | trace("Int8 [0xff] -> " + Int8.fromU8a([0xff]).value.toString()); 84 | trace("Int16 [0xff, 0xff] -> " + Int16.fromU8a([0xff, 0xff]).value.toString()); 85 | trace("Int32 [0xff, 0xff, 0xff, 0xff] -> " + Int32.fromU8a([0xff, 0xff, 0xff, 0xff]).toString()); 86 | trace("Int64 [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] -> " + Int64.fromU8a([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]).value.toString()) 87 | 88 | trace("UInt8 [0x01] -> " + UInt8.fromU8a([0x01]).value.toString()); 89 | trace("UInt16 [0x01, 0x00] -> " + UInt16.fromU8a([0x01, 0x00]).value.toString()); 90 | trace("UInt32 [0x01, 0x00, 0x00, 0x00] -> " + UInt32.fromU8a([0x01, 0x00, 0x00, 0x00]).toString()); 91 | trace("UInt64 [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] -> " + UInt64.fromU8a([0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]).value.toString()) 92 | trace("UInt128 [0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] -> " + UInt128.fromU8a([0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]).toString()); 93 | 94 | trace("Decoding using popualateFromBytes Codec method"); 95 | const hash = new Hash(); 96 | hash.populateFromBytes([12, 123, 123, 12, 12, 12, 3, 31, 12, 12, 123, 3, 5, 1, 2, 34, 6, 8, 9, 12, 12, 32, 21, 53, 0, 0, 0, 0, 0, 0, 0, 0]); 97 | trace("Hash [12, 123, 123, 12, 12, 12, 3, 31, 12, 12, 123, 3, 5, 1, 2, 34, 6, 8, 9, 12, 12, 32, 21, 53, 0, 0, 0, 0, 0, 0, 0, 0] -> " + hash.toString()); 98 | const int64 = new Int64(); 99 | int64.populateFromBytes([255, 255, 255, 1]); 100 | trace("Int64 [21, 21, 2, 1] -> " + int64.value.toString()); 101 | const cmpInt = new CompactInt(); 102 | cmpInt.populateFromBytes([145, 2]); 103 | trace("CompactInt [145, 2] -> " + cmpInt.value.toString()); 104 | const uInt64 = new UInt64(); 105 | uInt64.populateFromBytes([1, 1, 1, 1]); 106 | trace("UInt64 [1, 1, 1, 1] -> " + uInt64.value.toString()); 107 | const scaleString1 = new ScaleString(); 108 | scaleString1.populateFromBytes([20, 99, 99, 100, 112, 103]); 109 | trace("ScaleString [97, 99, 99, 100, 112, 103] -> " + scaleString1.valueStr); 110 | const byte = new Byte(); 111 | byte.populateFromBytes([8]); 112 | trace("Byte [8] -> " + byte.toU8a().toString()); 113 | const int32 = new Int32(); 114 | int32.populateFromBytes([255, 0, 0, 0]); 115 | trace("Int32 [255, 0, 0, 0] -> " + int32.value.toString()); 116 | 117 | 118 | 119 | trace("Decoding using BytesReader"); 120 | const bytes: u8[] = [ 121 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 122 | 69, 0, 0, 0, 123 | 110, 125, 239, 2, 124 | 56, 97, 115, 45, 115, 99, 97, 108, 101, 45, 99, 111, 100, 101, 99, 125 | 128, 1, 10, 0, 0, 0, 2, 2, 1, 123, 33, 3, 1, 35, 34, 5, 8, 22, 52, 1, 0, 0, 0, 1, 1, 1, 56, 21, 142, 13, 13, 1, 126 | 0 127 | ]; 128 | 129 | const bytesReader = new BytesReader(bytes); 130 | trace("Int64 [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] -> " + bytesReader.readInto().value.toString()); 131 | trace("UInt32 [69, 0, 0, 0] -> " + bytesReader.readInto().value.toString()); 132 | trace("CompactInt [110, 125, 239, 2] -> " + bytesReader.readInto().value.toString()); 133 | trace("ScaleString [56, 97, 115, 45, 115, 99, 97, 108, 101, 45, 99, 111, 100, 101, 99] -> " + bytesReader.readInto().valueStr); 134 | trace("Hash [128, 1, 10, 0, 0, 0, 2, 2, 1, 123, 33, 3, 1, 35, 34, 5, 8, 22, 52, 1, 0, 0, 0, 1, 1, 1, 56, 21, 142, 13, 13, 1] -> " + bytesReader.readInto().toString()); 135 | trace("Bool [0] -> " + bytesReader.readInto().toString()); 136 | trace("CompactInt [169, 2] -> " + BytesReader.decodeInto([169, 2]).toString()); 137 | trace("Int8 [0xff] -> " + BytesReader.decodeInto([0xff]).toString()); 138 | trace("UInt8 [123] -> " + BytesReader.decodeInto([123]).toString()); 139 | trace("UInt128Array [0x10, 0x04, 0x0c, 0x0c, 0x10] -> " + BytesReader.decodeInto([0x10, 0x04, 0x0c, 0x0c, 0x10]).values.toString()); 140 | trace("ScaleMap(new Map([[1, false]] -> " + BytesReader.decodeInto>([4, 1, 0, 0, 0, 0]).toU8a().toString()); 141 | } -------------------------------------------------------------------------------- /example/assembly/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "assemblyscript/std/assembly.json", 3 | "include": [ 4 | "./*.ts" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /example/index.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const loader = require("@assemblyscript/loader"); 3 | 4 | const imports = { 5 | env: { 6 | abort (_msg, _file, line, column) { 7 | console.error("abort called at index.ts:" + line + ":" + column); 8 | } 9 | } 10 | }; 11 | const instance = loader.instantiateSync(fs.readFileSync(__dirname + "/build/example.wasm"), imports).exports; 12 | console.log('Demonstrating SCALE Codec...'); 13 | instance.demonstrate(); 14 | -------------------------------------------------------------------------------- /example/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "as-scale-example", 3 | "version": "0.0.1", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@as-pect/assembly": { 8 | "version": "4.0.0", 9 | "resolved": "https://registry.npmjs.org/@as-pect/assembly/-/assembly-4.0.0.tgz", 10 | "integrity": "sha512-xkyyWlpOnD7n01bJQivKAePAvg7D4eygp72BgzRfvZxTTTtGDfLU1jwB5gZr8XX5bFkpF/+W5lk/Uqt5LLchWA==" 11 | }, 12 | "@as-pect/cli": { 13 | "version": "4.0.0", 14 | "resolved": "https://registry.npmjs.org/@as-pect/cli/-/cli-4.0.0.tgz", 15 | "integrity": "sha512-OT0iFPmSzmygrLm4lpDgUgbG3KVdE2XoatbNKav0VM7yIIXozc3vwUeDgEwB9NBxnZC/pnp0pZmpM4rXi5IUpw==", 16 | "requires": { 17 | "@as-pect/assembly": "^4.0.0", 18 | "@as-pect/core": "^4.0.0", 19 | "@as-pect/csv-reporter": "^4.0.0", 20 | "@as-pect/json-reporter": "^4.0.0", 21 | "chalk": "^4.1.0", 22 | "glob": "^7.1.6" 23 | } 24 | }, 25 | "@as-pect/core": { 26 | "version": "4.0.0", 27 | "resolved": "https://registry.npmjs.org/@as-pect/core/-/core-4.0.0.tgz", 28 | "integrity": "sha512-NQhf52uumBuQkqSvfmlMDHPhP/jR+2kkXt5BWQ0LnifWyBIsP4GUIe43VjW5brou2WVk+bDxlyo7lEtqideOKA==", 29 | "requires": { 30 | "@as-pect/assembly": "^4.0.0", 31 | "@as-pect/snapshots": "^4.0.0", 32 | "chalk": "^4.1.0", 33 | "long": "^4.0.0" 34 | } 35 | }, 36 | "@as-pect/csv-reporter": { 37 | "version": "4.0.0", 38 | "resolved": "https://registry.npmjs.org/@as-pect/csv-reporter/-/csv-reporter-4.0.0.tgz", 39 | "integrity": "sha512-5M4btRHhUZtcdIf4jeaRzwG0+OgTGvIWoUsNyedeuV5HDIjRM8kb9k+IKjfZqD3dU8TD/C2Ca7Gr4zkbAlswkw==", 40 | "optional": true, 41 | "requires": { 42 | "@as-pect/core": "^4.0.0" 43 | } 44 | }, 45 | "@as-pect/json-reporter": { 46 | "version": "4.0.0", 47 | "resolved": "https://registry.npmjs.org/@as-pect/json-reporter/-/json-reporter-4.0.0.tgz", 48 | "integrity": "sha512-1ekBZlAXOqeN6f5abwBtMiRaH6/6UciepArC7O0wkuI+3nAoj6XUSkRonl8kb/j7zmYbjlsD5UqTNILL+kl+Tg==", 49 | "optional": true, 50 | "requires": { 51 | "@as-pect/core": "^4.0.0" 52 | } 53 | }, 54 | "@as-pect/snapshots": { 55 | "version": "4.0.0", 56 | "resolved": "https://registry.npmjs.org/@as-pect/snapshots/-/snapshots-4.0.0.tgz", 57 | "integrity": "sha512-RBSGTVyBdbpabj/FTp8k3XUTnCSeutmLVgfjVbzzLLZVeNV2i7sVp5acau//qq884ZnXv/gd/g9fleHPYtBxkQ==", 58 | "requires": { 59 | "diff": "^4.0.2", 60 | "nearley": "^2.19.3" 61 | } 62 | }, 63 | "@assemblyscript/loader": { 64 | "version": "0.0.0", 65 | "resolved": "https://registry.npmjs.org/@assemblyscript/loader/-/loader-0.0.0.tgz", 66 | "integrity": "sha512-k5KVk+FNMXuoEToF94JwMbnFBef9Pa808EeJ/RNnEPzMS1E5XjQu0uENyZODK+jTy/iFzksYWxGXmsB7Kb/QLA==" 67 | }, 68 | "@types/color-name": { 69 | "version": "1.1.1", 70 | "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", 71 | "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==" 72 | }, 73 | "ansi-styles": { 74 | "version": "4.2.1", 75 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", 76 | "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", 77 | "requires": { 78 | "@types/color-name": "^1.1.1", 79 | "color-convert": "^2.0.1" 80 | } 81 | }, 82 | "as-bignum": { 83 | "version": "0.2.6", 84 | "resolved": "https://registry.npmjs.org/as-bignum/-/as-bignum-0.2.6.tgz", 85 | "integrity": "sha512-3FNvNp23mmfkhxDJekO8hcjC49jKkvCD1MKYjr/wk7tTiCgdpM+oSfzeFk+Ce8iZtIKXGWARbDjcs4XGmtnyAA==" 86 | }, 87 | "as-scale-codec": { 88 | "version": "file:..", 89 | "requires": { 90 | "@as-pect/assembly": "^4.0.0", 91 | "@as-pect/cli": "^4.0.0", 92 | "@as-pect/core": "^4.0.0", 93 | "@assemblyscript/loader": "^0.16.1", 94 | "as-bignum": "^0.2.6", 95 | "assemblyscript": "^0.16.1" 96 | }, 97 | "dependencies": { 98 | "@assemblyscript/loader": { 99 | "version": "0.16.1", 100 | "resolved": "https://registry.npmjs.org/@assemblyscript/loader/-/loader-0.16.1.tgz", 101 | "integrity": "sha512-fx6wEDH/NgvNYYrkGZnHaguFa73KUD2Pt42UCIlWNumHr9Vp2gnKH2+neOKNlTBFVrwIrMs9KlUYqDC6v/kh1A==" 102 | }, 103 | "assemblyscript": { 104 | "version": "0.16.1", 105 | "resolved": "https://registry.npmjs.org/assemblyscript/-/assemblyscript-0.16.1.tgz", 106 | "integrity": "sha512-btb/Q2cs42O7NaVRLDpUIb4fF+o4H4id0kjOOOzS25KCOx0voiyGBeWYqfnrOeufMQacvDNqGkjJuGkdTJIrQQ==", 107 | "requires": { 108 | "binaryen": "97.0.0-nightly.20201008", 109 | "long": "^4.0.0" 110 | } 111 | }, 112 | "binaryen": { 113 | "version": "97.0.0-nightly.20201008", 114 | "resolved": "https://registry.npmjs.org/binaryen/-/binaryen-97.0.0-nightly.20201008.tgz", 115 | "integrity": "sha512-GWV30FOQqz+vBIZRbc7GSasLNhh8BNLKH+2u2j5BjqM0WOEqqaP5iSj0mq72We2aVYqpBajJPI/CORY6o2RBxA==" 116 | } 117 | } 118 | }, 119 | "assemblyscript": { 120 | "version": "0.13.1", 121 | "resolved": "https://registry.npmjs.org/assemblyscript/-/assemblyscript-0.13.1.tgz", 122 | "integrity": "sha512-ffNfEsNQ62XoruHQHlpn3MdPTva/dX1E6YKoAtl9D2laSThALEKrKzJhD4fq0GI9ui8sHih+ovjYJe5Xr09rdw==", 123 | "requires": { 124 | "binaryen": "93.0.0-nightly.20200609", 125 | "long": "^4.0.0" 126 | } 127 | }, 128 | "balanced-match": { 129 | "version": "1.0.0", 130 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 131 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" 132 | }, 133 | "binaryen": { 134 | "version": "93.0.0-nightly.20200609", 135 | "resolved": "https://registry.npmjs.org/binaryen/-/binaryen-93.0.0-nightly.20200609.tgz", 136 | "integrity": "sha512-CIaeav05u+fWRN2h1ecwIoSaOF/Mk6U85M/G6eg1nOHAXYYmOuh9TztF9Fu8krRWnl98J3W+VfDClApMV5zCtw==" 137 | }, 138 | "brace-expansion": { 139 | "version": "1.1.11", 140 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 141 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 142 | "requires": { 143 | "balanced-match": "^1.0.0", 144 | "concat-map": "0.0.1" 145 | } 146 | }, 147 | "chalk": { 148 | "version": "4.1.0", 149 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", 150 | "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", 151 | "requires": { 152 | "ansi-styles": "^4.1.0", 153 | "supports-color": "^7.1.0" 154 | } 155 | }, 156 | "color-convert": { 157 | "version": "2.0.1", 158 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 159 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 160 | "requires": { 161 | "color-name": "~1.1.4" 162 | } 163 | }, 164 | "color-name": { 165 | "version": "1.1.4", 166 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 167 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" 168 | }, 169 | "commander": { 170 | "version": "2.20.3", 171 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", 172 | "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" 173 | }, 174 | "concat-map": { 175 | "version": "0.0.1", 176 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 177 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" 178 | }, 179 | "diff": { 180 | "version": "4.0.2", 181 | "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", 182 | "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" 183 | }, 184 | "discontinuous-range": { 185 | "version": "1.0.0", 186 | "resolved": "https://registry.npmjs.org/discontinuous-range/-/discontinuous-range-1.0.0.tgz", 187 | "integrity": "sha1-44Mx8IRLukm5qctxx3FYWqsbxlo=" 188 | }, 189 | "fs.realpath": { 190 | "version": "1.0.0", 191 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 192 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" 193 | }, 194 | "glob": { 195 | "version": "7.1.6", 196 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", 197 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", 198 | "requires": { 199 | "fs.realpath": "^1.0.0", 200 | "inflight": "^1.0.4", 201 | "inherits": "2", 202 | "minimatch": "^3.0.4", 203 | "once": "^1.3.0", 204 | "path-is-absolute": "^1.0.0" 205 | } 206 | }, 207 | "has-flag": { 208 | "version": "4.0.0", 209 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 210 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" 211 | }, 212 | "inflight": { 213 | "version": "1.0.6", 214 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 215 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 216 | "requires": { 217 | "once": "^1.3.0", 218 | "wrappy": "1" 219 | } 220 | }, 221 | "inherits": { 222 | "version": "2.0.4", 223 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 224 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 225 | }, 226 | "long": { 227 | "version": "4.0.0", 228 | "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", 229 | "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" 230 | }, 231 | "minimatch": { 232 | "version": "3.0.4", 233 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 234 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 235 | "requires": { 236 | "brace-expansion": "^1.1.7" 237 | } 238 | }, 239 | "moo": { 240 | "version": "0.5.1", 241 | "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.1.tgz", 242 | "integrity": "sha512-I1mnb5xn4fO80BH9BLcF0yLypy2UKl+Cb01Fu0hJRkJjlCRtxZMWkTdAtDd5ZqCOxtCkhmRwyI57vWT+1iZ67w==" 243 | }, 244 | "nearley": { 245 | "version": "2.19.4", 246 | "resolved": "https://registry.npmjs.org/nearley/-/nearley-2.19.4.tgz", 247 | "integrity": "sha512-oqj3m4oqwKsN77pETa9IPvxHHHLW68KrDc2KYoWMUOhDlrNUo7finubwffQMBRnwNCOXc4kRxCZO0Rvx4L6Zrw==", 248 | "requires": { 249 | "commander": "^2.19.0", 250 | "moo": "^0.5.0", 251 | "railroad-diagrams": "^1.0.0", 252 | "randexp": "0.4.6", 253 | "semver": "^5.4.1" 254 | } 255 | }, 256 | "once": { 257 | "version": "1.4.0", 258 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 259 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 260 | "requires": { 261 | "wrappy": "1" 262 | } 263 | }, 264 | "path-is-absolute": { 265 | "version": "1.0.1", 266 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 267 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" 268 | }, 269 | "railroad-diagrams": { 270 | "version": "1.0.0", 271 | "resolved": "https://registry.npmjs.org/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz", 272 | "integrity": "sha1-635iZ1SN3t+4mcG5Dlc3RVnN234=" 273 | }, 274 | "randexp": { 275 | "version": "0.4.6", 276 | "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.4.6.tgz", 277 | "integrity": "sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ==", 278 | "requires": { 279 | "discontinuous-range": "1.0.0", 280 | "ret": "~0.1.10" 281 | } 282 | }, 283 | "ret": { 284 | "version": "0.1.15", 285 | "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", 286 | "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" 287 | }, 288 | "semver": { 289 | "version": "5.7.1", 290 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", 291 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" 292 | }, 293 | "supports-color": { 294 | "version": "7.1.0", 295 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", 296 | "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", 297 | "requires": { 298 | "has-flag": "^4.0.0" 299 | } 300 | }, 301 | "wrappy": { 302 | "version": "1.0.2", 303 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 304 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 305 | } 306 | } 307 | } 308 | -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "as-scale-example", 3 | "version": "0.0.1", 4 | "description": "Example of AssemblyScript SCALE codec", 5 | "main": "./assembly/index.ts", 6 | "contributors": [ 7 | "Daniel Ivanov ", 8 | "Lyubomir Kiprov " 9 | ], 10 | "scripts": { 11 | "start": "node index.js", 12 | "test": "asp --verbose", 13 | "build": "npx asc assembly/index.ts -b build/example.wasm -t build/example.wat --sourceMap --runtime full --optimize", 14 | "build:debug": "npm run build -- --debug" 15 | }, 16 | "repository": { 17 | "type": "git", 18 | "url": "git+https://github.com/LimeChain/assemblyscript-scale-codec.git" 19 | }, 20 | "keywords": [ 21 | "assembly-script", 22 | "SCALE", 23 | "Polkadot", 24 | "Substrate" 25 | ], 26 | "license": "Apache-2.0", 27 | "bugs": { 28 | "url": "https://github.com/LimeChain/assemblyscript-scale-codec/issues" 29 | }, 30 | "homepage": "https://github.com/LimeChain/assemblyscript-scale-codec#readme", 31 | "dependencies": { 32 | "@as-pect/cli": "^4.0.0", 33 | "@assemblyscript/loader": "0.0.0", 34 | "as-scale-codec": "file:../", 35 | "assemblyscript": "^0.13.1" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const loader = require("@assemblyscript/loader"); 3 | module.exports = loader.instantiateSync(fs.readFileSync(__dirname + "/build/release/as-scale-codec.wasm"), { /* imports */ }) -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "as-scale-codec", 3 | "version": "0.2.1", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@as-pect/assembly": { 8 | "version": "4.0.0", 9 | "resolved": "https://registry.npmjs.org/@as-pect/assembly/-/assembly-4.0.0.tgz", 10 | "integrity": "sha512-xkyyWlpOnD7n01bJQivKAePAvg7D4eygp72BgzRfvZxTTTtGDfLU1jwB5gZr8XX5bFkpF/+W5lk/Uqt5LLchWA==" 11 | }, 12 | "@as-pect/cli": { 13 | "version": "4.0.0", 14 | "resolved": "https://registry.npmjs.org/@as-pect/cli/-/cli-4.0.0.tgz", 15 | "integrity": "sha512-OT0iFPmSzmygrLm4lpDgUgbG3KVdE2XoatbNKav0VM7yIIXozc3vwUeDgEwB9NBxnZC/pnp0pZmpM4rXi5IUpw==", 16 | "requires": { 17 | "@as-pect/assembly": "^4.0.0", 18 | "@as-pect/core": "^4.0.0", 19 | "@as-pect/csv-reporter": "^4.0.0", 20 | "@as-pect/json-reporter": "^4.0.0", 21 | "chalk": "^4.1.0", 22 | "glob": "^7.1.6" 23 | } 24 | }, 25 | "@as-pect/core": { 26 | "version": "4.0.0", 27 | "resolved": "https://registry.npmjs.org/@as-pect/core/-/core-4.0.0.tgz", 28 | "integrity": "sha512-NQhf52uumBuQkqSvfmlMDHPhP/jR+2kkXt5BWQ0LnifWyBIsP4GUIe43VjW5brou2WVk+bDxlyo7lEtqideOKA==", 29 | "requires": { 30 | "@as-pect/assembly": "^4.0.0", 31 | "@as-pect/snapshots": "^4.0.0", 32 | "chalk": "^4.1.0", 33 | "long": "^4.0.0" 34 | } 35 | }, 36 | "@as-pect/csv-reporter": { 37 | "version": "4.0.0", 38 | "resolved": "https://registry.npmjs.org/@as-pect/csv-reporter/-/csv-reporter-4.0.0.tgz", 39 | "integrity": "sha512-5M4btRHhUZtcdIf4jeaRzwG0+OgTGvIWoUsNyedeuV5HDIjRM8kb9k+IKjfZqD3dU8TD/C2Ca7Gr4zkbAlswkw==", 40 | "optional": true, 41 | "requires": { 42 | "@as-pect/core": "^4.0.0" 43 | } 44 | }, 45 | "@as-pect/json-reporter": { 46 | "version": "4.0.0", 47 | "resolved": "https://registry.npmjs.org/@as-pect/json-reporter/-/json-reporter-4.0.0.tgz", 48 | "integrity": "sha512-1ekBZlAXOqeN6f5abwBtMiRaH6/6UciepArC7O0wkuI+3nAoj6XUSkRonl8kb/j7zmYbjlsD5UqTNILL+kl+Tg==", 49 | "optional": true, 50 | "requires": { 51 | "@as-pect/core": "^4.0.0" 52 | } 53 | }, 54 | "@as-pect/snapshots": { 55 | "version": "4.0.0", 56 | "resolved": "https://registry.npmjs.org/@as-pect/snapshots/-/snapshots-4.0.0.tgz", 57 | "integrity": "sha512-RBSGTVyBdbpabj/FTp8k3XUTnCSeutmLVgfjVbzzLLZVeNV2i7sVp5acau//qq884ZnXv/gd/g9fleHPYtBxkQ==", 58 | "requires": { 59 | "diff": "^4.0.2", 60 | "nearley": "^2.19.3" 61 | } 62 | }, 63 | "@assemblyscript/loader": { 64 | "version": "0.16.1", 65 | "resolved": "https://registry.npmjs.org/@assemblyscript/loader/-/loader-0.16.1.tgz", 66 | "integrity": "sha512-fx6wEDH/NgvNYYrkGZnHaguFa73KUD2Pt42UCIlWNumHr9Vp2gnKH2+neOKNlTBFVrwIrMs9KlUYqDC6v/kh1A==" 67 | }, 68 | "ansi-styles": { 69 | "version": "4.3.0", 70 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 71 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 72 | "requires": { 73 | "color-convert": "^2.0.1" 74 | } 75 | }, 76 | "as-bignum": { 77 | "version": "0.2.6", 78 | "resolved": "https://registry.npmjs.org/as-bignum/-/as-bignum-0.2.6.tgz", 79 | "integrity": "sha512-3FNvNp23mmfkhxDJekO8hcjC49jKkvCD1MKYjr/wk7tTiCgdpM+oSfzeFk+Ce8iZtIKXGWARbDjcs4XGmtnyAA==" 80 | }, 81 | "assemblyscript": { 82 | "version": "0.16.1", 83 | "resolved": "https://registry.npmjs.org/assemblyscript/-/assemblyscript-0.16.1.tgz", 84 | "integrity": "sha512-btb/Q2cs42O7NaVRLDpUIb4fF+o4H4id0kjOOOzS25KCOx0voiyGBeWYqfnrOeufMQacvDNqGkjJuGkdTJIrQQ==", 85 | "requires": { 86 | "binaryen": "97.0.0-nightly.20201008", 87 | "long": "^4.0.0" 88 | } 89 | }, 90 | "balanced-match": { 91 | "version": "1.0.0", 92 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 93 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" 94 | }, 95 | "binaryen": { 96 | "version": "97.0.0-nightly.20201008", 97 | "resolved": "https://registry.npmjs.org/binaryen/-/binaryen-97.0.0-nightly.20201008.tgz", 98 | "integrity": "sha512-GWV30FOQqz+vBIZRbc7GSasLNhh8BNLKH+2u2j5BjqM0WOEqqaP5iSj0mq72We2aVYqpBajJPI/CORY6o2RBxA==" 99 | }, 100 | "brace-expansion": { 101 | "version": "1.1.11", 102 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 103 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 104 | "requires": { 105 | "balanced-match": "^1.0.0", 106 | "concat-map": "0.0.1" 107 | } 108 | }, 109 | "chalk": { 110 | "version": "4.1.0", 111 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", 112 | "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", 113 | "requires": { 114 | "ansi-styles": "^4.1.0", 115 | "supports-color": "^7.1.0" 116 | } 117 | }, 118 | "color-convert": { 119 | "version": "2.0.1", 120 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 121 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 122 | "requires": { 123 | "color-name": "~1.1.4" 124 | } 125 | }, 126 | "color-name": { 127 | "version": "1.1.4", 128 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 129 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" 130 | }, 131 | "commander": { 132 | "version": "2.20.3", 133 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", 134 | "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" 135 | }, 136 | "concat-map": { 137 | "version": "0.0.1", 138 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 139 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" 140 | }, 141 | "diff": { 142 | "version": "4.0.2", 143 | "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", 144 | "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" 145 | }, 146 | "discontinuous-range": { 147 | "version": "1.0.0", 148 | "resolved": "https://registry.npmjs.org/discontinuous-range/-/discontinuous-range-1.0.0.tgz", 149 | "integrity": "sha1-44Mx8IRLukm5qctxx3FYWqsbxlo=" 150 | }, 151 | "fs.realpath": { 152 | "version": "1.0.0", 153 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 154 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" 155 | }, 156 | "glob": { 157 | "version": "7.1.6", 158 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", 159 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", 160 | "requires": { 161 | "fs.realpath": "^1.0.0", 162 | "inflight": "^1.0.4", 163 | "inherits": "2", 164 | "minimatch": "^3.0.4", 165 | "once": "^1.3.0", 166 | "path-is-absolute": "^1.0.0" 167 | } 168 | }, 169 | "has-flag": { 170 | "version": "4.0.0", 171 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 172 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" 173 | }, 174 | "inflight": { 175 | "version": "1.0.6", 176 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 177 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 178 | "requires": { 179 | "once": "^1.3.0", 180 | "wrappy": "1" 181 | } 182 | }, 183 | "inherits": { 184 | "version": "2.0.4", 185 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 186 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 187 | }, 188 | "long": { 189 | "version": "4.0.0", 190 | "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", 191 | "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" 192 | }, 193 | "minimatch": { 194 | "version": "3.0.4", 195 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 196 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 197 | "requires": { 198 | "brace-expansion": "^1.1.7" 199 | } 200 | }, 201 | "moo": { 202 | "version": "0.5.1", 203 | "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.1.tgz", 204 | "integrity": "sha512-I1mnb5xn4fO80BH9BLcF0yLypy2UKl+Cb01Fu0hJRkJjlCRtxZMWkTdAtDd5ZqCOxtCkhmRwyI57vWT+1iZ67w==" 205 | }, 206 | "nearley": { 207 | "version": "2.19.7", 208 | "resolved": "https://registry.npmjs.org/nearley/-/nearley-2.19.7.tgz", 209 | "integrity": "sha512-Y+KNwhBPcSJKeyQCFjn8B/MIe+DDlhaaDgjVldhy5xtFewIbiQgcbZV8k2gCVwkI1ZsKCnjIYZbR+0Fim5QYgg==", 210 | "requires": { 211 | "commander": "^2.19.0", 212 | "moo": "^0.5.0", 213 | "railroad-diagrams": "^1.0.0", 214 | "randexp": "0.4.6", 215 | "semver": "^5.4.1" 216 | } 217 | }, 218 | "once": { 219 | "version": "1.4.0", 220 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 221 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 222 | "requires": { 223 | "wrappy": "1" 224 | } 225 | }, 226 | "path-is-absolute": { 227 | "version": "1.0.1", 228 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 229 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" 230 | }, 231 | "railroad-diagrams": { 232 | "version": "1.0.0", 233 | "resolved": "https://registry.npmjs.org/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz", 234 | "integrity": "sha1-635iZ1SN3t+4mcG5Dlc3RVnN234=" 235 | }, 236 | "randexp": { 237 | "version": "0.4.6", 238 | "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.4.6.tgz", 239 | "integrity": "sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ==", 240 | "requires": { 241 | "discontinuous-range": "1.0.0", 242 | "ret": "~0.1.10" 243 | } 244 | }, 245 | "ret": { 246 | "version": "0.1.15", 247 | "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", 248 | "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" 249 | }, 250 | "semver": { 251 | "version": "5.7.1", 252 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", 253 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" 254 | }, 255 | "supports-color": { 256 | "version": "7.2.0", 257 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 258 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 259 | "requires": { 260 | "has-flag": "^4.0.0" 261 | } 262 | }, 263 | "wrappy": { 264 | "version": "1.0.2", 265 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 266 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 267 | } 268 | } 269 | } 270 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "as-scale-codec", 3 | "version": "0.2.1", 4 | "description": "AssemblyScript implementation of the SCALE codec used in the Parity Substrate framework", 5 | "main": "./assembly/index.ts", 6 | "contributors": [ 7 | "Daniel Ivanov ", 8 | "Lyubomir Kiprov " 9 | ], 10 | "scripts": { 11 | "asbuild": "npx asc assembly/index.ts -b build/release/as-scale-codec.wasm -t build/release/as-scale-codec.wat --sourceMap --runtime full --optimize", 12 | "test:js": "npm run asbuild && node tests", 13 | "test": "asp --verbose", 14 | "test:ci": "asp --summary" 15 | }, 16 | "repository": { 17 | "type": "git", 18 | "url": "git+https://github.com/LimeChain/assemblyscript-scale-codec.git" 19 | }, 20 | "keywords": [ 21 | "assembly-script", 22 | "SCALE", 23 | "Polkadot", 24 | "Substrate" 25 | ], 26 | "license": "Apache-2.0", 27 | "bugs": { 28 | "url": "https://github.com/LimeChain/assemblyscript-scale-codec/issues" 29 | }, 30 | "homepage": "https://github.com/LimeChain/assemblyscript-scale-codec#readme", 31 | "dependencies": { 32 | "@as-pect/assembly": "^4.0.0", 33 | "@as-pect/cli": "^4.0.0", 34 | "@as-pect/core": "^4.0.0", 35 | "@assemblyscript/loader": "^0.16.1", 36 | "as-bignum": "^0.2.6", 37 | "assemblyscript": "^0.16.1" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /web3_badge_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LimeChain/as-scale-codec/9982786da2f97f7aea5900643c05d112dc0ae32d/web3_badge_black.png --------------------------------------------------------------------------------