diff --git a/.github/mark-dark.svg b/.github/mark-dark.svg new file mode 100644 index 0000000..4fb9b26 --- /dev/null +++ b/.github/mark-dark.svg @@ -0,0 +1,4 @@ + + + + diff --git a/.github/mark-light.svg b/.github/mark-light.svg new file mode 100644 index 0000000..01cb677 --- /dev/null +++ b/.github/mark-light.svg @@ -0,0 +1,4 @@ + + + + diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 0000000..6bb3a9d --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,27 @@ +name: CI + +on: + push: + pull_request: +env: + DEPLOY_RPC_URL: https://katana1.0xmssp.xyz + TARGET_NAME: mssp + +jobs: + sozo-test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - run: curl -L https://install.dojoengine.org | bash + - run: /home/runner/.config/.dojo/bin/dojoup + - run: echo $PATH + - run: cp /home/runner/.config/.dojo/bin/sozo /usr/local/bin/sozo + - run: sozo build + - run: sozo test + - run: sozo --profile ${{ env.TARGET_NAME }} migrate + - run: ls target + - uses: actions/upload-artifact@v4 + with: + name: manifest.json + path: target/${{ env.TARGET_NAME }}/manifest.json + - run: bash scripts/default_auth.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8b043ae --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +target +local +.venv +node_modules +.pdm-python +__pycache__ diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..d41e224 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "cairo1.enableLanguageServer": true, + "cairo1.enableScarb": false, + "cairo1.languageServerPath": "${userHome}/.dojo/bin/dojo-language-server" +} diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d29b859 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Dojo + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..fba13f5 --- /dev/null +++ b/README.md @@ -0,0 +1,44 @@ + + + Dojo logo + + + + + + + + + +[![discord](https://img.shields.io/badge/join-dojo-green?logo=discord&logoColor=white)](https://discord.gg/PwDa2mKhR4) +[![Telegram Chat][tg-badge]][tg-url] + +[tg-badge]: https://img.shields.io/endpoint?color=neon&logo=telegram&label=chat&style=flat-square&url=https%3A%2F%2Ftg.sumanjay.workers.dev%2Fdojoengine +[tg-url]: https://t.me/dojoengine + +# Dojo Starter: Official Guide + +The official Dojo Starter guide, the quickest and most streamlined way to get your Dojo Autonomous World up and running. This guide will assist you with the initial setup, from cloning the repository to deploying your world. + +Read the full tutorial [here](https://book.dojoengine.org/cairo/hello-dojo.html) + +--- + +## Contribution + +This starter project is a constant work in progress and contributions are greatly appreciated! + +1. **Report a Bug** + + - If you think you have encountered a bug, and we should know about it, feel free to report it [here](https://github.com/dojoengine/dojo-starter/issues) and we will take care of it. + +2. **Request a Feature** + + - You can also request for a feature [here](https://github.com/dojoengine/dojo-starter/issues), and if it's viable, it will be picked for development. + +3. **Create a Pull Request** + - It can't get better then this, your pull request will be appreciated by the community. + +For any other questions, feel free to reach out to us [here](https://dojoengine.org/contact). + +Happy coding! diff --git a/Scarb.lock b/Scarb.lock new file mode 100644 index 0000000..bc01496 --- /dev/null +++ b/Scarb.lock @@ -0,0 +1,28 @@ +# Code generated by scarb DO NOT EDIT. +version = 1 + +[[package]] +name = "dojo" +version = "0.5.1" +source = "git+https://github.com/dojoengine/dojo#118ed84f7b5cb9e4e0c1963fca88b71a222ae50d" +dependencies = [ + "dojo_plugin", +] + +[[package]] +name = "dojo_plugin" +version = "0.3.11" +source = "git+https://github.com/dojoengine/dojo?tag=v0.3.11#1e651b5d4d3b79b14a7d8aa29a92062fcb9e6659" + +[[package]] +name = "kingdom_lord" +version = "0.5.0" +dependencies = [ + "dojo", + "openzeppelin", +] + +[[package]] +name = "openzeppelin" +version = "0.8.0" +source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.8.0#c23e8e96de60e6e3159b1ff8591a1187269c0eb7" diff --git a/Scarb.toml b/Scarb.toml new file mode 100644 index 0000000..0ee7df9 --- /dev/null +++ b/Scarb.toml @@ -0,0 +1,43 @@ +[package] +cairo-version = "2.4.0" +name = "kingdom_lord" +version = "0.5.0" + +[cairo] +sierra-replace-ids = true + +[dependencies] +dojo = { git = "https://github.com/dojoengine/dojo", version = "0.5.1" } +openzeppelin = { git = "https://github.com/OpenZeppelin/cairo-contracts.git", tag = "v0.8.0" } +# alexandria_math = { git = "https://github.com/keep-starknet-strange/alexandria.git", rev = "01a7690dc25d19a086f525b8ce66aa505c8e7527"} + +[[target.dojo]] +build-external-contracts = ["openzeppelin::presets::erc20::ERC20"] + +[tool.dojo] +initializer_class_hash = "0xbeef" + +[tool.dojo.env] +rpc_url = "http://localhost:5050/" +# Default account for katana with seed = 0 +account_address = "0x6162896d1d7ab204c7ccac6dd5f8e9e7c25ecd5ae4fcb4ad32e57786bb46e03" +private_key = "0x1800000000300000180000000000030000000000003006001800006600" + +[profile.mssp.tool.dojo.env] +rpc_url = "https://katana1.0xmssp.xyz/" +# Default account for katana with seed = 0 +account_address = "0x6162896d1d7ab204c7ccac6dd5f8e9e7c25ecd5ae4fcb4ad32e57786bb46e03" +private_key = "0x1800000000300000180000000000030000000000003006001800006600" + + +[tool.dojo.world] +name = "Dojo starter" +description = "The official Dojo Starter guide, the quickest and most streamlined way to get your Dojo Autonomous World up and running. This guide will assist you with the initial setup, from cloning the repository to deploying your world." +cover_uri = "file://assets/cover.png" +icon_uri = "file://assets/icon.png" +website = "https://github.com/dojoengine/dojo-starter" + +[tool.dojo.world.socials] +x = "https://x.com/ohayo_dojo" +discord = "https://discord.gg/FB2wR6uF" +github = "https://github.com/dojoengine/dojo-starter" diff --git a/assets/cover.png b/assets/cover.png new file mode 100644 index 0000000..8ac043f Binary files /dev/null and b/assets/cover.png differ diff --git a/assets/icon.png b/assets/icon.png new file mode 100644 index 0000000..2169b56 Binary files /dev/null and b/assets/icon.png differ diff --git a/deploy_mssp.sh b/deploy_mssp.sh new file mode 100644 index 0000000..6fdc4fa --- /dev/null +++ b/deploy_mssp.sh @@ -0,0 +1,3 @@ +sozo --profile mssp build +sozo --profile mssp migrate +DEPLOY_RPC_URL="https://katana1.0xmssp.xyz" TARGET_NAME=mssp bash ./scripts/default_auth.sh \ No newline at end of file diff --git a/index.js b/index.js new file mode 100644 index 0000000..ae7c48e --- /dev/null +++ b/index.js @@ -0,0 +1,208 @@ +const { hash, num, merkle } = require('starknet'); + + +function hash_posei (data) { + return hash.computePoseidonHashOnElements(data); +} +const a = hash_posei([1, 2, 3, 4]); + +console.log(a) + +const wood = [[1, 1, 40, 100, 50, 60, 2, 260, 7], +[1, 2, 65, 165, 85, 100, 1, 620, 13], +[1, 3, 110, 280, 140, 165, 1, 1190, 21], +[1, 4, 185, 465, 235, 280, 1, 2100, 31], +[1, 5, 310, 780, 390, 465, 1, 3560, 46], +[1, 6, 520, 1300, 650, 780, 2, 5890, 70], +[1, 7, 870, 2170, 1085, 1300, 2, 9620, 98], +[1, 8, 1450, 3625, 1810, 2175, 2, 15590, 140], +[1, 9, 2420, 6050, 3025, 3630, 2, 25150, 203], +[1, 10, 4040, 10105, 5050, 6060, 2, 40440, 280], +[1, 11, 6750, 16870, 8435, 10125, 2, 64900, 392], +[1, 12, 11270, 28175, 14090, 16905, 2, 17650, 525], +[1, 13, 18820, 47055, 23525, 28230, 2, 80280, 693], +[1, 14, 31430, 78580, 39290, 47150, 2, 7680, 889], +[1, 15, 52490, 131230, 65615, 78740, 2, 81610, 1120], +[1, 16, 87660, 219155, 109575, 131490, 3, 78930, 1400], +[1, 17, 146395, 365985, 182995, 219590, 3, 57370, 1820], +[1, 18, 244480, 611195, 305600, 366715, 3, 22880, 2240], +[1, 19, 408280, 1020695, 510350, 612420, 3, 36800, 2800], +[1, 20, 681825, 1704565, 852280, 1022740, 3, 76370, 3430], +]; +const brick = [[2, 1, 80, 40, 80, 50, 2, 220, 7], +[2, 2, 135, 65, 135, 85, 1, 550, 13], +[2, 3, 225, 110, 225, 140, 1, 1080, 21], +[2, 4, 375, 185, 375, 235, 1, 1930, 31], +[2, 5, 620, 310, 620, 390, 1, 3290, 46], +[2, 6, 1040, 520, 1040, 650, 2, 5470, 70], +[2, 7, 1735, 870, 1735, 1085, 2, 8950, 98], +[2, 8, 2900, 1450, 2900, 1810, 2, 14520, 140], +[2, 9, 4840, 2420, 4840, 3025, 2, 23430, 203], +[2, 10, 8080, 4040, 8080, 5050, 2, 37690, 280], +[2, 11, 13500, 6750, 13500, 8435, 2, 60510, 392], +[2, 12, 22540, 11270, 22540, 14090, 2, 10610, 525], +[2, 13, 37645, 18820, 37645, 23525, 2, 69020, 693], +[2, 14, 62865, 31430, 62865, 39290, 2, 76070, 889], +[2, 15, 104985, 52490, 104985, 65615, 2, 52790, 1120], +[2, 16, 175320, 87660, 175320, 109575, 3, 32820, 1400], +[2, 17, 292790, 146395, 292790, 182995, 3, 69990, 1820], +[2, 18, 488955, 244480, 488955, 305600, 3, 77620, 2240], +[2, 19, 816555, 408280, 816555, 510350, 3, 20710, 2800], +[2, 20, 1363650, 681825, 1363650, 852280, 3, 33340, 3430], +]; +const steel = [[3, 1, 100, 80, 30, 60, 3, 450, 7], +[3, 2, 165, 135, 50, 100, 2, 920, 13], +[3, 3, 280, 225, 85, 165, 2, 1670, 21], +[3, 4, 465, 375, 140, 280, 2, 2880, 31], +[3, 5, 780, 620, 235, 465, 2, 4800, 46], +[3, 6, 1300, 1040, 390, 780, 2, 7880, 70], +[3, 7, 2170, 1735, 650, 1300, 2, 12810, 98], +[3, 8, 3625, 2900, 1085, 2175, 2, 20690, 140], +[3, 9, 6050, 4840, 1815, 3630, 2, 33310, 203], +[3, 10, 10105, 8080, 3030, 6060, 2, 53500, 280], +[3, 11, 16870, 13500, 5060, 10125, 3, 85800, 392], +[3, 12, 28175, 22540, 8455, 16905, 3, 51070, 525], +[3, 13, 47055, 37645, 14115, 28230, 3, 47360, 693], +[3, 14, 78580, 62865, 23575, 47150, 3, 6850, 889], +[3, 15, 131230, 104985, 39370, 78740, 3, 45720, 1120], +[3, 16, 219155, 175320, 65745, 131490, 3, 38790, 1400], +[3, 17, 365985, 292790, 109795, 219590, 3, 62260, 1820], +[3, 18, 611195, 488955, 183360, 366715, 3, 65260, 2240], +[3, 19, 1020695, 816555, 306210, 612420, 3, 70050, 2800], +[3, 20, 1704565, 1363650, 511370, 1022740, 3, 43170, 3430], +]; +const food = [[4, 1, 70, 90, 70, 20, 0, 150, 7], +[4, 2, 115, 150, 115, 35, 0, 440, 13], +[4, 3, 195, 250, 195, 55, 0, 900, 21], +[4, 4, 325, 420, 325, 95, 0, 1650, 31], +[4, 5, 545, 700, 545, 155, 0, 2830, 46], +[4, 6, 910, 1170, 910, 260, 1, 4730, 70], +[4, 7, 1520, 1950, 1520, 435, 1, 7780, 98], +[4, 8, 2535, 3260, 2535, 725, 1, 12640, 140], +[4, 9, 4235, 5445, 4235, 1210, 1, 20430, 203], +[4, 10, 7070, 9095, 7070, 2020, 1, 32880, 280], +[4, 11, 11810, 15185, 11810, 3375, 1, 52810, 392], +[4, 12, 19725, 25360, 19725, 5635, 1, 84700, 525], +[4, 13, 32940, 42350, 32940, 9410, 1, 49310, 693], +[4, 14, 55005, 70720, 55005, 15715, 1, 44540, 889], +[4, 15, 91860, 118105, 91860, 26245, 1, 2350, 1120], +[4, 16, 153405, 197240, 153405, 43830, 2, 38510, 1400], +[4, 17, 256190, 329385, 256190, 73195, 2, 27260, 1820], +[4, 18, 427835, 550075, 427835, 122240, 2, 43810, 2240], +[4, 19, 714485, 918625, 714485, 204140, 2, 35740, 2800], +[4, 20, 1193195, 1534105, 1193195, 340915, 2, 22830, 3430], +]; +const cityhall = [[5, 1, 70, 40, 60, 20, 2, 2500, 100], +[5, 2, 90, 50, 75, 25, 1, 2620, 104], +[5, 3, 115, 65, 100, 35, 1, 3220, 108], +[5, 4, 145, 85, 125, 40, 1, 3880, 112], +[5, 5, 190, 105, 160, 55, 1, 4610, 116], +[5, 6, 240, 135, 205, 70, 2, 5410, 120], +[5, 7, 310, 175, 265, 90, 2, 6300, 125], +[5, 8, 395, 225, 340, 115, 2, 7280, 129], +[5, 9, 505, 290, 430, 145, 2, 8380, 134], +[5, 10, 645, 370, 555, 185, 2, 9590, 139], +[5, 11, 825, 470, 710, 235, 2, 10940, 144], +[5, 12, 1060, 605, 905, 300, 2, 12440, 150], +[5, 13, 1355, 775, 1160, 385, 2, 14120, 155], +[5, 14, 1735, 990, 1485, 495, 2, 15980, 161], +[5, 15, 2220, 1270, 1900, 635, 2, 18050, 167], +[5, 16, 2840, 1625, 2435, 810, 3, 20370, 173], +[5, 17, 3635, 2075, 3115, 1040, 3, 22950, 180], +[5, 18, 4650, 2660, 3990, 1330, 3, 25830, 187], +[5, 19, 5955, 3405, 5105, 1700, 3, 29040, 193], +[5, 20, 7620, 4355, 6535, 2180, 3, 32630, 201], +]; +const warehouse = [[6, 1, 130, 160, 90, 40, 1, 2000, 1200], +[6, 2, 165, 205, 115, 50, 1, 2620, 1700], +[6, 3, 215, 260, 145, 65, 1, 3340, 2300], +[6, 4, 275, 335, 190, 85, 1, 4170, 3100], +[6, 5, 350, 430, 240, 105, 1, 5140, 4000], +[6, 6, 445, 550, 310, 135, 1, 6260, 5000], +[6, 7, 570, 705, 395, 175, 1, 7570, 6300], +[6, 8, 730, 900, 505, 225, 1, 9080, 7800], +[6, 9, 935, 1155, 650, 290, 1, 10830, 9600], +[6, 10, 1200, 1475, 830, 370, 1, 12860, 11800], +[6, 11, 1535, 1890, 1065, 470, 2, 15220, 14400], +[6, 12, 1965, 2420, 1360, 605, 2, 17950, 17600], +[6, 13, 2515, 3095, 1740, 775, 2, 21130, 21400], +[6, 14, 3220, 3960, 2230, 990, 2, 24810, 25900], +[6, 15, 4120, 5070, 2850, 1270, 2, 29080, 31300], +[6, 16, 5275, 6490, 3650, 1625, 2, 34030, 37900], +[6, 17, 6750, 8310, 4675, 2075, 2, 39770, 45700], +[6, 18, 8640, 10635, 5980, 2660, 2, 46440, 55100], +[6, 19, 11060, 13610, 7655, 3405, 2, 54170, 66400], +[6, 20, 14155, 17420, 9800, 4355, 2, 63130, 80000], +]; +const barn = [[7, 1, 80, 100, 70, 20, 1, 1600, 1200], +[7, 2, 100, 130, 90, 25, 1, 2160, 1700], +[7, 3, 130, 165, 115, 35, 1, 2800, 2300], +[7, 4, 170, 210, 145, 40, 1, 3550, 3100], +[7, 5, 215, 270, 190, 55, 1, 4420, 4000], +[7, 6, 275, 345, 240, 70, 1, 5420, 5000], +[7, 7, 350, 440, 310, 90, 1, 6590, 6300], +[7, 8, 450, 565, 395, 115, 1, 7950, 7800], +[7, 9, 575, 720, 505, 145, 1, 9520, 9600], +[7, 10, 740, 920, 645, 185, 1, 11340, 11800], +[7, 11, 945, 1180, 825, 235, 2, 13450, 14400], +[7, 12, 1210, 1510, 1060, 300, 2, 15910, 17600], +[7, 13, 1545, 1935, 1355, 385, 2, 18750, 21400], +[7, 14, 1980, 2475, 1735, 495, 2, 22050, 25900], +[7, 15, 2535, 3170, 2220, 635, 2, 25880, 31300], +[7, 16, 3245, 4055, 2840, 810, 2, 30320, 37900], +[7, 17, 4155, 5190, 3635, 1040, 2, 35470, 45700], +[7, 18, 5315, 6645, 4650, 1330, 2, 41450, 55100], +[7, 19, 6805, 8505, 5955, 1700, 2, 48380, 66400], +[7, 20, 8710, 10890, 7620, 2180, 2, 56420, 80000], +]; + +const barracks = [[8, 1, 210, 140, 260, 120, 4, 2000, 100], +[8, 2, 270, 180, 335, 155, 2, 2620, 90], +[8, 3, 345, 230, 425, 195, 2, 3340, 83], +[8, 4, 440, 295, 545, 250, 2, 4170, 71], +[8, 5, 565, 375, 700, 320, 2, 5140, 66], +[8, 6, 720, 480, 895, 410, 3, 6260, 58], +[8, 7, 925, 615, 1145, 530, 3, 7570, 52], +[8, 8, 1180, 790, 1465, 675, 3, 9080, 47], +[8, 9, 1515, 1010, 1875, 865, 3, 10830, 43], +[8, 10, 1935, 1290, 2400, 1105, 3, 12860, 38], +[8, 11, 2480, 1655, 3070, 1415, 3, 15220, 34], +[8, 12, 3175, 2115, 3930, 1815, 3, 17950, 31], +[8, 13, 4060, 2710, 5030, 2320, 3, 21130, 28], +[8, 14, 5200, 3465, 6435, 2970, 3, 24810, 25], +[8, 15, 6655, 4435, 8240, 3805, 3, 29080, 22], +[8, 16, 8520, 5680, 10545, 4870, 4, 34030, 20], +[8, 17, 10905, 7270, 13500, 6230, 4, 39770, 18], +[8, 18, 13955, 9305, 17280, 7975, 4, 46440, 16], +[8, 19, 17865, 11910, 22120, 10210, 4, 54170, 14], +[8, 20, 22865, 15245, 28310, 13065, 4, 63130, 13]] +//the last param is the percentage of building time of the soldier, the building time is in the list below +let soldiers = [[40, 35, 6, 50, 120, 100, 150, 30, 1, 1600], +[30, 65, 5, 20, 100, 130, 160, 70, 1, 1760], +[70, 40, 7, 50, 150, 160, 210, 80, 1, 1920], +[0, 20, 16, 0, 140, 160, 20, 40, 2, 1360], +[120, 65, 14, 100, 550, 440, 320, 100, 3, 2640], +[180, 80, 10, 70, 550, 640, 800, 180, 4, 3520], +[60, 30, 4, 0, 900, 360, 500, 70, 3, 4600], +[75, 60, 3, 0, 950, 1350, 600, 90, 6, 9000], +[50, 40, 4, 0, 30750, 27200, 45000, 37500, 5, 4300], +[0, 80, 5, 3000, 4600, 4200, 5800, 4400, 1, 26900]] + +// the first 6 soldier build info is for Militia, Guard, Heavy Infantry, Scouts, Knights, Heavy Knights +// The information in the list is: attack power, defense power, movement speed, load capacity, wood, bricks, steel, food, population occupied by soldiers, and time required to build. + +// chain wood, brick, stell, food, cityhall, warehouse, barn into a big list +const data = wood.concat(brick, steel, food, cityhall, warehouse, barn, barracks); + + +const leaves = data.map((d) => + hash_posei(d) +); + +const tree = new merkle.MerkleTree(leaves, hash.computePoseidonHash); +console.log("root: ", tree.root) + +const h = hash_posei([5, 3, 115, 65, 100, 35, 1, 3220, 108]) +console.log("h: ", h) +const proof = tree.getProof(h); +console.log("proof: ", proof) diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..004c4ed --- /dev/null +++ b/package-lock.json @@ -0,0 +1,696 @@ +{ + "name": "merkle_generate", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "merkle_generate", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "merkletreejs": "^0.3.11", + "starknet": "6.4.0" + } + }, + "node_modules/@ethereumjs/rlp": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-4.0.1.tgz", + "integrity": "sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==", + "bin": { + "rlp": "bin/rlp" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@ethereumjs/util": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/util/-/util-8.1.0.tgz", + "integrity": "sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==", + "dependencies": { + "@ethereumjs/rlp": "^4.0.1", + "ethereum-cryptography": "^2.0.0", + "micro-ftch": "^0.3.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@noble/curves": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.3.0.tgz", + "integrity": "sha512-t01iSXPuN+Eqzb4eBX0S5oubSqXbK/xXa1Ne18Hj8f9pStxztHCE2gfboSp/dZRLSqfuLpRK2nDXDK+W9puocA==", + "dependencies": { + "@noble/hashes": "1.3.3" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz", + "integrity": "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/base": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.5.tgz", + "integrity": "sha512-Brj9FiG2W1MRQSTB212YVPRrcbjkv48FoZi/u4l/zds/ieRrqsh7aUf6CLwkAq61oKXr/ZlTzlY66gLIj3TFTQ==", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.3.3.tgz", + "integrity": "sha512-LJaN3HwRbfQK0X1xFSi0Q9amqOgzQnnDngIt+ZlsBC3Bm7/nE7K0kwshZHyaru79yIVRv/e1mQAjZyuZG6jOFQ==", + "dependencies": { + "@noble/curves": "~1.3.0", + "@noble/hashes": "~1.3.2", + "@scure/base": "~1.1.4" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip39": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.2.2.tgz", + "integrity": "sha512-HYf9TUXG80beW+hGAt3TRM8wU6pQoYur9iNypTROm42dorCGmLnFe3eWjz3gOq6G62H2WRh0FCzAR1PI+29zIA==", + "dependencies": { + "@noble/hashes": "~1.3.2", + "@scure/base": "~1.1.4" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/starknet": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@scure/starknet/-/starknet-1.0.0.tgz", + "integrity": "sha512-o5J57zY0f+2IL/mq8+AYJJ4Xpc1fOtDhr+mFQKbHnYFmm3WQrC+8zj2HEgxak1a+x86mhmBC1Kq305KUpVf0wg==", + "dependencies": { + "@noble/curves": "~1.3.0", + "@noble/hashes": "~1.3.3" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/abi-wan-kanabi": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/abi-wan-kanabi/-/abi-wan-kanabi-2.2.1.tgz", + "integrity": "sha512-W3RNuu2tG10W4AY63uq89JX/MsZSOxvpmsitQ3pbdVn3e8RxXR2oegN0QmGpgfyT0KlPdreydHsqq/u+2Pt2PQ==", + "dependencies": { + "ansicolors": "^0.3.2", + "cardinal": "^2.1.1", + "fs-extra": "^10.0.0", + "yargs": "^17.7.2" + }, + "bin": { + "generate": "dist/generate.js" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ansicolors": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", + "integrity": "sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==" + }, + "node_modules/bignumber.js": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "engines": { + "node": "*" + } + }, + "node_modules/bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" + }, + "node_modules/buffer-reverse": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-reverse/-/buffer-reverse-1.0.1.tgz", + "integrity": "sha512-M87YIUBsZ6N924W57vDwT/aOu8hw7ZgdByz6ijksLjmHJELBASmYTTlNHRgjE+pTsT9oJXGaDSgqqwfdHotDUg==" + }, + "node_modules/cardinal": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", + "integrity": "sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==", + "dependencies": { + "ansicolors": "~0.3.2", + "redeyed": "~2.1.0" + }, + "bin": { + "cdl": "bin/cdl.js" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/crypto-js": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", + "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ethereum-bloom-filters": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz", + "integrity": "sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA==", + "dependencies": { + "js-sha3": "^0.8.0" + } + }, + "node_modules/ethereum-cryptography": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.1.3.tgz", + "integrity": "sha512-BlwbIL7/P45W8FGW2r7LGuvoEZ+7PWsniMvQ4p5s2xCyw9tmaDlpfsN9HjAucbF+t/qpVHwZUisgfK24TCW8aA==", + "dependencies": { + "@noble/curves": "1.3.0", + "@noble/hashes": "1.3.3", + "@scure/bip32": "1.3.3", + "@scure/bip39": "1.2.2" + } + }, + "node_modules/ethjs-unit": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", + "integrity": "sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==", + "dependencies": { + "bn.js": "4.11.6", + "number-to-bn": "1.7.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/ethjs-unit/node_modules/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==" + }, + "node_modules/fetch-cookie": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fetch-cookie/-/fetch-cookie-3.0.1.tgz", + "integrity": "sha512-ZGXe8Y5Z/1FWqQ9q/CrJhkUD73DyBU9VF0hBQmEO/wPHe4A9PKTjplFDLeFX8aOsYypZUcX5Ji/eByn3VCVO3Q==", + "dependencies": { + "set-cookie-parser": "^2.4.8", + "tough-cookie": "^4.0.0" + } + }, + "node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-hex-prefixed": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", + "integrity": "sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==", + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/isomorphic-fetch": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", + "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", + "dependencies": { + "node-fetch": "^2.6.1", + "whatwg-fetch": "^3.4.1" + } + }, + "node_modules/js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/lossless-json": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lossless-json/-/lossless-json-4.0.1.tgz", + "integrity": "sha512-l0L+ppmgPDnb+JGxNLndPtJZGNf6+ZmVaQzoxQm3u6TXmhdnsA+YtdVR8DjzZd/em58686CQhOFDPewfJ4l7MA==" + }, + "node_modules/merkletreejs": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/merkletreejs/-/merkletreejs-0.3.11.tgz", + "integrity": "sha512-LJKTl4iVNTndhL+3Uz/tfkjD0klIWsHlUzgtuNnNrsf7bAlXR30m+xYB7lHr5Z/l6e/yAIsr26Dabx6Buo4VGQ==", + "dependencies": { + "bignumber.js": "^9.0.1", + "buffer-reverse": "^1.0.1", + "crypto-js": "^4.2.0", + "treeify": "^1.1.0", + "web3-utils": "^1.3.4" + }, + "engines": { + "node": ">= 7.6.0" + } + }, + "node_modules/micro-ftch": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/micro-ftch/-/micro-ftch-0.3.1.tgz", + "integrity": "sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg==" + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/number-to-bn": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", + "integrity": "sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==", + "dependencies": { + "bn.js": "4.11.6", + "strip-hex-prefix": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/number-to-bn/node_modules/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==" + }, + "node_modules/pako": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", + "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==" + }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/redeyed": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", + "integrity": "sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==", + "dependencies": { + "esprima": "~4.0.0" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/set-cookie-parser": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.6.0.tgz", + "integrity": "sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==" + }, + "node_modules/starknet": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/starknet/-/starknet-6.4.0.tgz", + "integrity": "sha512-sJb7Q02kUAf0Rmxc+adWQXdcSnJ08ngqEicYxNqSV5R56ndpnqRRPiLCGmTflBzGYuI6QFsHb7uF5ZEi602WQQ==", + "dependencies": { + "@noble/curves": "~1.3.0", + "@scure/base": "~1.1.3", + "@scure/starknet": "~1.0.0", + "abi-wan-kanabi": "^2.2.1", + "fetch-cookie": "^3.0.0", + "isomorphic-fetch": "^3.0.0", + "lossless-json": "^4.0.1", + "pako": "^2.0.4", + "ts-mixer": "^6.0.3", + "url-join": "^4.0.1" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-hex-prefix": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", + "integrity": "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==", + "dependencies": { + "is-hex-prefixed": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/tough-cookie": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", + "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tough-cookie/node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/treeify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/treeify/-/treeify-1.1.0.tgz", + "integrity": "sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/ts-mixer": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.4.tgz", + "integrity": "sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==" + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==" + }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "node_modules/utf8": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", + "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==" + }, + "node_modules/web3-utils": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.10.4.tgz", + "integrity": "sha512-tsu8FiKJLk2PzhDl9fXbGUWTkkVXYhtTA+SmEFkKft+9BgwLxfCRpU96sWv7ICC8zixBNd3JURVoiR3dUXgP8A==", + "dependencies": { + "@ethereumjs/util": "^8.1.0", + "bn.js": "^5.2.1", + "ethereum-bloom-filters": "^1.0.6", + "ethereum-cryptography": "^2.1.2", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-fetch": { + "version": "3.6.20", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", + "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "engines": { + "node": ">=12" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..cb9a26f --- /dev/null +++ b/package.json @@ -0,0 +1,17 @@ +{ + "name": "merkle_generate", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "node index.js", + "debug": "node inspect index.js" + }, + "author": "", + "license": "ISC", + "dependencies": { + "merkletreejs": "^0.3.11", + "starknet": "6.4.0" + } + } + \ No newline at end of file diff --git a/pdm.lock b/pdm.lock new file mode 100644 index 0000000..348296b --- /dev/null +++ b/pdm.lock @@ -0,0 +1,609 @@ +# This file is @generated by PDM. +# It is not intended for manual editing. + +[metadata] +groups = ["default"] +strategy = ["cross_platform"] +lock_version = "4.4" +content_hash = "sha256:d6dea52641c6e8f5db8db28cc562ed94d7132df9999aad41d8344aa433f2d7ce" + +[[package]] +name = "aiohttp" +version = "3.9.3" +requires_python = ">=3.8" +summary = "Async http client/server framework (asyncio)" +dependencies = [ + "aiosignal>=1.1.2", + "async-timeout<5.0,>=4.0; python_version < \"3.11\"", + "attrs>=17.3.0", + "frozenlist>=1.1.1", + "multidict<7.0,>=4.5", + "yarl<2.0,>=1.0", +] +files = [ + {file = "aiohttp-3.9.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:939677b61f9d72a4fa2a042a5eee2a99a24001a67c13da113b2e30396567db54"}, + {file = "aiohttp-3.9.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1f5cd333fcf7590a18334c90f8c9147c837a6ec8a178e88d90a9b96ea03194cc"}, + {file = "aiohttp-3.9.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:82e6aa28dd46374f72093eda8bcd142f7771ee1eb9d1e223ff0fa7177a96b4a5"}, + {file = "aiohttp-3.9.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f56455b0c2c7cc3b0c584815264461d07b177f903a04481dfc33e08a89f0c26b"}, + {file = "aiohttp-3.9.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bca77a198bb6e69795ef2f09a5f4c12758487f83f33d63acde5f0d4919815768"}, + {file = "aiohttp-3.9.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e083c285857b78ee21a96ba1eb1b5339733c3563f72980728ca2b08b53826ca5"}, + {file = "aiohttp-3.9.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab40e6251c3873d86ea9b30a1ac6d7478c09277b32e14745d0d3c6e76e3c7e29"}, + {file = "aiohttp-3.9.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:df822ee7feaaeffb99c1a9e5e608800bd8eda6e5f18f5cfb0dc7eeb2eaa6bbec"}, + {file = "aiohttp-3.9.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:acef0899fea7492145d2bbaaaec7b345c87753168589cc7faf0afec9afe9b747"}, + {file = "aiohttp-3.9.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:cd73265a9e5ea618014802ab01babf1940cecb90c9762d8b9e7d2cc1e1969ec6"}, + {file = "aiohttp-3.9.3-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:a78ed8a53a1221393d9637c01870248a6f4ea5b214a59a92a36f18151739452c"}, + {file = "aiohttp-3.9.3-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:6b0e029353361f1746bac2e4cc19b32f972ec03f0f943b390c4ab3371840aabf"}, + {file = "aiohttp-3.9.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7cf5c9458e1e90e3c390c2639f1017a0379a99a94fdfad3a1fd966a2874bba52"}, + {file = "aiohttp-3.9.3-cp310-cp310-win32.whl", hash = "sha256:3e59c23c52765951b69ec45ddbbc9403a8761ee6f57253250c6e1536cacc758b"}, + {file = "aiohttp-3.9.3-cp310-cp310-win_amd64.whl", hash = "sha256:055ce4f74b82551678291473f66dc9fb9048a50d8324278751926ff0ae7715e5"}, + {file = "aiohttp-3.9.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6b88f9386ff1ad91ace19d2a1c0225896e28815ee09fc6a8932fded8cda97c3d"}, + {file = "aiohttp-3.9.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c46956ed82961e31557b6857a5ca153c67e5476972e5f7190015018760938da2"}, + {file = "aiohttp-3.9.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07b837ef0d2f252f96009e9b8435ec1fef68ef8b1461933253d318748ec1acdc"}, + {file = "aiohttp-3.9.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad46e6f620574b3b4801c68255492e0159d1712271cc99d8bdf35f2043ec266"}, + {file = "aiohttp-3.9.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ed3e046ea7b14938112ccd53d91c1539af3e6679b222f9469981e3dac7ba1ce"}, + {file = "aiohttp-3.9.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:039df344b45ae0b34ac885ab5b53940b174530d4dd8a14ed8b0e2155b9dddccb"}, + {file = "aiohttp-3.9.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7943c414d3a8d9235f5f15c22ace69787c140c80b718dcd57caaade95f7cd93b"}, + {file = "aiohttp-3.9.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:84871a243359bb42c12728f04d181a389718710129b36b6aad0fc4655a7647d4"}, + {file = "aiohttp-3.9.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:5eafe2c065df5401ba06821b9a054d9cb2848867f3c59801b5d07a0be3a380ae"}, + {file = "aiohttp-3.9.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9d3c9b50f19704552f23b4eaea1fc082fdd82c63429a6506446cbd8737823da3"}, + {file = "aiohttp-3.9.3-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:f033d80bc6283092613882dfe40419c6a6a1527e04fc69350e87a9df02bbc283"}, + {file = "aiohttp-3.9.3-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:2c895a656dd7e061b2fd6bb77d971cc38f2afc277229ce7dd3552de8313a483e"}, + {file = "aiohttp-3.9.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1f5a71d25cd8106eab05f8704cd9167b6e5187bcdf8f090a66c6d88b634802b4"}, + {file = "aiohttp-3.9.3-cp311-cp311-win32.whl", hash = "sha256:50fca156d718f8ced687a373f9e140c1bb765ca16e3d6f4fe116e3df7c05b2c5"}, + {file = "aiohttp-3.9.3-cp311-cp311-win_amd64.whl", hash = "sha256:5fe9ce6c09668063b8447f85d43b8d1c4e5d3d7e92c63173e6180b2ac5d46dd8"}, + {file = "aiohttp-3.9.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:38a19bc3b686ad55804ae931012f78f7a534cce165d089a2059f658f6c91fa60"}, + {file = "aiohttp-3.9.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:770d015888c2a598b377bd2f663adfd947d78c0124cfe7b959e1ef39f5b13869"}, + {file = "aiohttp-3.9.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ee43080e75fc92bf36219926c8e6de497f9b247301bbf88c5c7593d931426679"}, + {file = "aiohttp-3.9.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:52df73f14ed99cee84865b95a3d9e044f226320a87af208f068ecc33e0c35b96"}, + {file = "aiohttp-3.9.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc9b311743a78043b26ffaeeb9715dc360335e5517832f5a8e339f8a43581e4d"}, + {file = "aiohttp-3.9.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b955ed993491f1a5da7f92e98d5dad3c1e14dc175f74517c4e610b1f2456fb11"}, + {file = "aiohttp-3.9.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:504b6981675ace64c28bf4a05a508af5cde526e36492c98916127f5a02354d53"}, + {file = "aiohttp-3.9.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a6fe5571784af92b6bc2fda8d1925cccdf24642d49546d3144948a6a1ed58ca5"}, + {file = "aiohttp-3.9.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ba39e9c8627edc56544c8628cc180d88605df3892beeb2b94c9bc857774848ca"}, + {file = "aiohttp-3.9.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:e5e46b578c0e9db71d04c4b506a2121c0cb371dd89af17a0586ff6769d4c58c1"}, + {file = "aiohttp-3.9.3-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:938a9653e1e0c592053f815f7028e41a3062e902095e5a7dc84617c87267ebd5"}, + {file = "aiohttp-3.9.3-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:c3452ea726c76e92f3b9fae4b34a151981a9ec0a4847a627c43d71a15ac32aa6"}, + {file = "aiohttp-3.9.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ff30218887e62209942f91ac1be902cc80cddb86bf00fbc6783b7a43b2bea26f"}, + {file = "aiohttp-3.9.3-cp312-cp312-win32.whl", hash = "sha256:38f307b41e0bea3294a9a2a87833191e4bcf89bb0365e83a8be3a58b31fb7f38"}, + {file = "aiohttp-3.9.3-cp312-cp312-win_amd64.whl", hash = "sha256:b791a3143681a520c0a17e26ae7465f1b6f99461a28019d1a2f425236e6eedb5"}, + {file = "aiohttp-3.9.3.tar.gz", hash = "sha256:90842933e5d1ff760fae6caca4b2b3edba53ba8f4b71e95dacf2818a2aca06f7"}, +] + +[[package]] +name = "aiosignal" +version = "1.3.1" +requires_python = ">=3.7" +summary = "aiosignal: a list of registered asynchronous callbacks" +dependencies = [ + "frozenlist>=1.1.0", +] +files = [ + {file = "aiosignal-1.3.1-py3-none-any.whl", hash = "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17"}, + {file = "aiosignal-1.3.1.tar.gz", hash = "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc"}, +] + +[[package]] +name = "asgiref" +version = "3.7.2" +requires_python = ">=3.7" +summary = "ASGI specs, helper code, and adapters" +dependencies = [ + "typing-extensions>=4; python_version < \"3.11\"", +] +files = [ + {file = "asgiref-3.7.2-py3-none-any.whl", hash = "sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e"}, + {file = "asgiref-3.7.2.tar.gz", hash = "sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed"}, +] + +[[package]] +name = "async-timeout" +version = "4.0.3" +requires_python = ">=3.7" +summary = "Timeout context manager for asyncio programs" +files = [ + {file = "async-timeout-4.0.3.tar.gz", hash = "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f"}, + {file = "async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028"}, +] + +[[package]] +name = "asyncio" +version = "3.4.3" +summary = "reference implementation of PEP 3156" +files = [ + {file = "asyncio-3.4.3-py3-none-any.whl", hash = "sha256:c4d18b22701821de07bd6aea8b53d21449ec0ec5680645e5317062ea21817d2d"}, + {file = "asyncio-3.4.3.tar.gz", hash = "sha256:83360ff8bc97980e4ff25c964c7bd3923d333d177aa4f7fb736b019f26c7cb41"}, +] + +[[package]] +name = "attrs" +version = "23.2.0" +requires_python = ">=3.7" +summary = "Classes Without Boilerplate" +files = [ + {file = "attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"}, + {file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"}, +] + +[[package]] +name = "crypto-cpp-py" +version = "1.4.4" +requires_python = ">=3.8" +summary = "This is a packaged crypto-cpp program" +dependencies = [ + "ecdsa==0.18.0", + "pywin32==306; os_name == \"nt\"", + "sympy==1.11.1", +] +files = [ + {file = "crypto_cpp_py-1.4.4-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:613f49be26ea4e08f4e92516a0882af9f5aca2d2ced7367cd2e1a1dd4aecb92d"}, + {file = "crypto_cpp_py-1.4.4-cp310-cp310-macosx_13_0_universal2.whl", hash = "sha256:5dc432c4270c7008ac28af2363f699951ba85ef762b3e4feb2c28357e407a622"}, + {file = "crypto_cpp_py-1.4.4-cp310-cp310-macosx_14_0_universal2.whl", hash = "sha256:0af8af590f6050a528e50800c474925c1681237972151c27a688f6c0276aa478"}, + {file = "crypto_cpp_py-1.4.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:90e5a951a4ea88f865151165de527945c85b92229aa2f8aef32b2ef0b8ed712d"}, + {file = "crypto_cpp_py-1.4.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:182d30b77a92f41f56a5088e58da80fd4fdc6885668127bddb7951c2acacbb00"}, + {file = "crypto_cpp_py-1.4.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f31394a93d257eb73b7c29f772d6295ae29d43fc7235be51332c1f5692c8739b"}, + {file = "crypto_cpp_py-1.4.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b1a3bfe9e764931fe3656b25a486609b77326f1f3f2518661eb7a34d372e3ff"}, + {file = "crypto_cpp_py-1.4.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:032d5c3ef782638def9e450c6cb3b975744fa320cf66560bb970f9b9ac3dbb4d"}, + {file = "crypto_cpp_py-1.4.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:3047cb99044ca6d707b7a6ec3d32b445cba1917707226513f455c5d8405d4216"}, + {file = "crypto_cpp_py-1.4.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:e0ce59b92ecafb47defd39c104405ccb9651367bc74ac54e1a228265e9a9be97"}, + {file = "crypto_cpp_py-1.4.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:36cc5b597f40d354c9e340c73266d10017dc44f010cd3711379db98b7450898b"}, + {file = "crypto_cpp_py-1.4.4-cp310-cp310-win32.whl", hash = "sha256:c4d8799a1cc45744d98bdb65c2f730ab29fc46fc2471805678bebb6c90343309"}, + {file = "crypto_cpp_py-1.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:28ea4a25a72e66605ec2a7698d159179ac4aa9f3a07fb96901a3a0555a46e0a0"}, + {file = "crypto_cpp_py-1.4.4-cp311-cp311-macosx_12_0_universal2.whl", hash = "sha256:ce8b39e4e2f88cf540ef6b3f71251ba7efbd98462ec3500b0f572e3aed6b0386"}, + {file = "crypto_cpp_py-1.4.4-cp311-cp311-macosx_13_0_universal2.whl", hash = "sha256:44cb0ce6d336d53396b387dcf6cb781264e558d8b925cb1f9208d4b2eb5d5d6b"}, + {file = "crypto_cpp_py-1.4.4-cp311-cp311-macosx_14_0_universal2.whl", hash = "sha256:0a5006dbfe233de71206c36ab08cbe50e619599bca6e076b0219542c105632c3"}, + {file = "crypto_cpp_py-1.4.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e737d0928c4433e241b22fde873522fcc9b6118f9d2899f05a3324e42dbeccc2"}, + {file = "crypto_cpp_py-1.4.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b769f82e86dca3aaf14cd79a34ed5212f3704c5bdaa04cd22b0d5fe079a809c5"}, + {file = "crypto_cpp_py-1.4.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eb6efbd96f5c81fb0de3deaf5d44ea7487fa51c2c5585fba3192b8cac991d7a8"}, + {file = "crypto_cpp_py-1.4.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93782e704fe4b76ec29f4b425fdb7cf0838b1cdd4a97a03e9e8a9a4b7af0a6fa"}, + {file = "crypto_cpp_py-1.4.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:cc92b30b671fd69e741b9f0660a64c410d4aa6a5dc6272dc2d2492061aadddba"}, + {file = "crypto_cpp_py-1.4.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:c3339a3632e2f531e5649168f1f8d2df7385abee79153b994ec2ec6adbd1a20d"}, + {file = "crypto_cpp_py-1.4.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:a9a6541ed402b0b92cbb4a2cfba7e271c098ecc806d5b46219ed9a6cee80f559"}, + {file = "crypto_cpp_py-1.4.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:45420471e54306ded080e1ca0e2832859840d4d0473e273580fcc00b4fcd0610"}, + {file = "crypto_cpp_py-1.4.4-cp311-cp311-win32.whl", hash = "sha256:54317921d79296222dc9991441bd94d7b5888b03e78cc856b253587a05376889"}, + {file = "crypto_cpp_py-1.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:51721a9d7f0351db2b62df6979ec618c3a62b066618a018c7534f6ccd25d3eeb"}, + {file = "crypto_cpp_py-1.4.4-cp312-cp312-macosx_12_0_universal2.whl", hash = "sha256:d2a187cd4906d46724c36a8e35840d26cc61bbaa9386cc544610cf75260a321c"}, + {file = "crypto_cpp_py-1.4.4-cp312-cp312-macosx_13_0_universal2.whl", hash = "sha256:6948b922618c8cebf05d419ae9bafb95fce414322adeac28ccf41ec5d95b25ab"}, + {file = "crypto_cpp_py-1.4.4-cp312-cp312-macosx_14_0_universal2.whl", hash = "sha256:2be5f48f0182825022bfd89c46355c79a2d40c90cd06f519e857e5b28e668bbb"}, + {file = "crypto_cpp_py-1.4.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:93e1ef7cbeadc69f34b92ae8a0090bedf19b689cad6da105108bf199947d6e13"}, + {file = "crypto_cpp_py-1.4.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a8039d0c7ec1628845eedf77305545e62d52348afdc8135abc76980b3f98c531"}, + {file = "crypto_cpp_py-1.4.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dda5f34608b218a55fbf6e56216e96c4b468b405b49b0ca37a754998ab714720"}, + {file = "crypto_cpp_py-1.4.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fbf9c7d5f6ee987f352b3e8c099d3e18bfc02995c85a6bbeeb004f900e9c0c6f"}, + {file = "crypto_cpp_py-1.4.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1362576bfac17d5ac7b64dca73f7a5b22b49a11bab1ee3289c1bcbc48f2a50eb"}, + {file = "crypto_cpp_py-1.4.4-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:e7ebea14c80751a0c75a2b9d4daf6fff889367415c1a1c694c6d19b834885fdf"}, + {file = "crypto_cpp_py-1.4.4-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:6b59041620c816ce6c3bcfcb7aa8673dba07e720d2f48613f7065b3a6a6a58d5"}, + {file = "crypto_cpp_py-1.4.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:380e84cdccf59dae2a190eb0dc38570c546c5d91558a06972257121c30b6025f"}, + {file = "crypto_cpp_py-1.4.4-cp312-cp312-win32.whl", hash = "sha256:50f7f35c8d17892abd6a510a1df6a585a9e5c0a2c820634488ed2391a822e953"}, + {file = "crypto_cpp_py-1.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:c7671c32209063141aca9e7fc158bd3221893f9184231599c01eea194c062fa2"}, + {file = "crypto_cpp_py-1.4.4.tar.gz", hash = "sha256:cac53078972562759455b6ef8168341bacbe61c41f69f2068718d3d82917a19b"}, +] + +[[package]] +name = "ecdsa" +version = "0.18.0" +requires_python = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +summary = "ECDSA cryptographic signature library (pure python)" +dependencies = [ + "six>=1.9.0", +] +files = [ + {file = "ecdsa-0.18.0-py2.py3-none-any.whl", hash = "sha256:80600258e7ed2f16b9aa1d7c295bd70194109ad5a30fdee0eaeefef1d4c559dd"}, + {file = "ecdsa-0.18.0.tar.gz", hash = "sha256:190348041559e21b22a1d65cee485282ca11a6f81d503fddb84d5017e9ed1e49"}, +] + +[[package]] +name = "frozenlist" +version = "1.4.1" +requires_python = ">=3.8" +summary = "A list-like structure which implements collections.abc.MutableSequence" +files = [ + {file = "frozenlist-1.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f9aa1878d1083b276b0196f2dfbe00c9b7e752475ed3b682025ff20c1c1f51ac"}, + {file = "frozenlist-1.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:29acab3f66f0f24674b7dc4736477bcd4bc3ad4b896f5f45379a67bce8b96868"}, + {file = "frozenlist-1.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:74fb4bee6880b529a0c6560885fce4dc95936920f9f20f53d99a213f7bf66776"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:590344787a90ae57d62511dd7c736ed56b428f04cd8c161fcc5e7232c130c69a"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:068b63f23b17df8569b7fdca5517edef76171cf3897eb68beb01341131fbd2ad"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c849d495bf5154cd8da18a9eb15db127d4dba2968d88831aff6f0331ea9bd4c"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9750cc7fe1ae3b1611bb8cfc3f9ec11d532244235d75901fb6b8e42ce9229dfe"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9b2de4cf0cdd5bd2dee4c4f63a653c61d2408055ab77b151c1957f221cabf2a"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0633c8d5337cb5c77acbccc6357ac49a1770b8c487e5b3505c57b949b4b82e98"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:27657df69e8801be6c3638054e202a135c7f299267f1a55ed3a598934f6c0d75"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:f9a3ea26252bd92f570600098783d1371354d89d5f6b7dfd87359d669f2109b5"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:4f57dab5fe3407b6c0c1cc907ac98e8a189f9e418f3b6e54d65a718aaafe3950"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e02a0e11cf6597299b9f3bbd3f93d79217cb90cfd1411aec33848b13f5c656cc"}, + {file = "frozenlist-1.4.1-cp310-cp310-win32.whl", hash = "sha256:a828c57f00f729620a442881cc60e57cfcec6842ba38e1b19fd3e47ac0ff8dc1"}, + {file = "frozenlist-1.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:f56e2333dda1fe0f909e7cc59f021eba0d2307bc6f012a1ccf2beca6ba362439"}, + {file = "frozenlist-1.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a0cb6f11204443f27a1628b0e460f37fb30f624be6051d490fa7d7e26d4af3d0"}, + {file = "frozenlist-1.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b46c8ae3a8f1f41a0d2ef350c0b6e65822d80772fe46b653ab6b6274f61d4a49"}, + {file = "frozenlist-1.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fde5bd59ab5357e3853313127f4d3565fc7dad314a74d7b5d43c22c6a5ed2ced"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:722e1124aec435320ae01ee3ac7bec11a5d47f25d0ed6328f2273d287bc3abb0"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2471c201b70d58a0f0c1f91261542a03d9a5e088ed3dc6c160d614c01649c106"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c757a9dd70d72b076d6f68efdbb9bc943665ae954dad2801b874c8c69e185068"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f146e0911cb2f1da549fc58fc7bcd2b836a44b79ef871980d605ec392ff6b0d2"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f9c515e7914626b2a2e1e311794b4c35720a0be87af52b79ff8e1429fc25f19"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c302220494f5c1ebeb0912ea782bcd5e2f8308037b3c7553fad0e48ebad6ad82"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:442acde1e068288a4ba7acfe05f5f343e19fac87bfc96d89eb886b0363e977ec"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:1b280e6507ea8a4fa0c0a7150b4e526a8d113989e28eaaef946cc77ffd7efc0a"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:fe1a06da377e3a1062ae5fe0926e12b84eceb8a50b350ddca72dc85015873f74"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:db9e724bebd621d9beca794f2a4ff1d26eed5965b004a97f1f1685a173b869c2"}, + {file = "frozenlist-1.4.1-cp311-cp311-win32.whl", hash = "sha256:e774d53b1a477a67838a904131c4b0eef6b3d8a651f8b138b04f748fccfefe17"}, + {file = "frozenlist-1.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:fb3c2db03683b5767dedb5769b8a40ebb47d6f7f45b1b3e3b4b51ec8ad9d9825"}, + {file = "frozenlist-1.4.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:1979bc0aeb89b33b588c51c54ab0161791149f2461ea7c7c946d95d5f93b56ae"}, + {file = "frozenlist-1.4.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:cc7b01b3754ea68a62bd77ce6020afaffb44a590c2289089289363472d13aedb"}, + {file = "frozenlist-1.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c9c92be9fd329ac801cc420e08452b70e7aeab94ea4233a4804f0915c14eba9b"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c3894db91f5a489fc8fa6a9991820f368f0b3cbdb9cd8849547ccfab3392d86"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ba60bb19387e13597fb059f32cd4d59445d7b18b69a745b8f8e5db0346f33480"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8aefbba5f69d42246543407ed2461db31006b0f76c4e32dfd6f42215a2c41d09"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:780d3a35680ced9ce682fbcf4cb9c2bad3136eeff760ab33707b71db84664e3a"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9acbb16f06fe7f52f441bb6f413ebae6c37baa6ef9edd49cdd567216da8600cd"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:23b701e65c7b36e4bf15546a89279bd4d8675faabc287d06bbcfac7d3c33e1e6"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3e0153a805a98f5ada7e09826255ba99fb4f7524bb81bf6b47fb702666484ae1"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:dd9b1baec094d91bf36ec729445f7769d0d0cf6b64d04d86e45baf89e2b9059b"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:1a4471094e146b6790f61b98616ab8e44f72661879cc63fa1049d13ef711e71e"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5667ed53d68d91920defdf4035d1cdaa3c3121dc0b113255124bcfada1cfa1b8"}, + {file = "frozenlist-1.4.1-cp312-cp312-win32.whl", hash = "sha256:beee944ae828747fd7cb216a70f120767fc9f4f00bacae8543c14a6831673f89"}, + {file = "frozenlist-1.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:64536573d0a2cb6e625cf309984e2d873979709f2cf22839bf2d61790b448ad5"}, + {file = "frozenlist-1.4.1-py3-none-any.whl", hash = "sha256:04ced3e6a46b4cfffe20f9ae482818e34eba9b5fb0ce4056e4cc9b6e212d09b7"}, + {file = "frozenlist-1.4.1.tar.gz", hash = "sha256:c037a86e8513059a2613aaba4d817bb90b9d9b6b69aace3ce9c877e8c8ed402b"}, +] + +[[package]] +name = "idna" +version = "3.6" +requires_python = ">=3.5" +summary = "Internationalized Domain Names in Applications (IDNA)" +files = [ + {file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"}, + {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"}, +] + +[[package]] +name = "lark" +version = "1.1.9" +requires_python = ">=3.6" +summary = "a modern parsing library" +files = [ + {file = "lark-1.1.9-py3-none-any.whl", hash = "sha256:a0dd3a87289f8ccbb325901e4222e723e7d745dbfc1803eaf5f3d2ace19cf2db"}, + {file = "lark-1.1.9.tar.gz", hash = "sha256:15fa5236490824c2c4aba0e22d2d6d823575dcaf4cdd1848e34b6ad836240fba"}, +] + +[[package]] +name = "marshmallow" +version = "3.21.1" +requires_python = ">=3.8" +summary = "A lightweight library for converting complex datatypes to and from native Python datatypes." +dependencies = [ + "packaging>=17.0", +] +files = [ + {file = "marshmallow-3.21.1-py3-none-any.whl", hash = "sha256:f085493f79efb0644f270a9bf2892843142d80d7174bbbd2f3713f2a589dc633"}, + {file = "marshmallow-3.21.1.tar.gz", hash = "sha256:4e65e9e0d80fc9e609574b9983cf32579f305c718afb30d7233ab818571768c3"}, +] + +[[package]] +name = "marshmallow-dataclass" +version = "8.6.0" +requires_python = ">=3.6" +summary = "Python library to convert dataclasses into marshmallow schemas." +dependencies = [ + "marshmallow<4.0,>=3.13.0", + "typing-extensions>=4.2.0; python_version < \"3.11\" and python_version >= \"3.7\"", + "typing-inspect<1.0,>=0.8.0", +] +files = [ + {file = "marshmallow_dataclass-8.6.0-py3-none-any.whl", hash = "sha256:7885e9b5f5287b64573b174d69334fd20de1628001a4fa2adc8e75be5196755e"}, + {file = "marshmallow_dataclass-8.6.0.tar.gz", hash = "sha256:a21f4d050a1d24249fd43aa56c7e4aea4b6454e049dc2c5f1496f479e30bf5d7"}, +] + +[[package]] +name = "marshmallow-oneofschema" +version = "3.0.1" +requires_python = ">=3.6" +summary = "marshmallow multiplexing schema" +dependencies = [ + "marshmallow<4.0.0,>=3.0.0", +] +files = [ + {file = "marshmallow-oneofschema-3.0.1.tar.gz", hash = "sha256:62cd2099b29188c92493c2940ee79d1bf2f2619a71721664e5a98ec2faa58237"}, + {file = "marshmallow_oneofschema-3.0.1-py2.py3-none-any.whl", hash = "sha256:bd29410a9f2f7457a2b428286e2a80ef76b8ddc3701527dc1f935a88914b02f2"}, +] + +[[package]] +name = "mpmath" +version = "1.3.0" +summary = "Python library for arbitrary-precision floating-point arithmetic" +files = [ + {file = "mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c"}, + {file = "mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f"}, +] + +[[package]] +name = "multidict" +version = "6.0.5" +requires_python = ">=3.7" +summary = "multidict implementation" +files = [ + {file = "multidict-6.0.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:228b644ae063c10e7f324ab1ab6b548bdf6f8b47f3ec234fef1093bc2735e5f9"}, + {file = "multidict-6.0.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:896ebdcf62683551312c30e20614305f53125750803b614e9e6ce74a96232604"}, + {file = "multidict-6.0.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:411bf8515f3be9813d06004cac41ccf7d1cd46dfe233705933dd163b60e37600"}, + {file = "multidict-6.0.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d147090048129ce3c453f0292e7697d333db95e52616b3793922945804a433c"}, + {file = "multidict-6.0.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:215ed703caf15f578dca76ee6f6b21b7603791ae090fbf1ef9d865571039ade5"}, + {file = "multidict-6.0.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c6390cf87ff6234643428991b7359b5f59cc15155695deb4eda5c777d2b880f"}, + {file = "multidict-6.0.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21fd81c4ebdb4f214161be351eb5bcf385426bf023041da2fd9e60681f3cebae"}, + {file = "multidict-6.0.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3cc2ad10255f903656017363cd59436f2111443a76f996584d1077e43ee51182"}, + {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6939c95381e003f54cd4c5516740faba40cf5ad3eeff460c3ad1d3e0ea2549bf"}, + {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:220dd781e3f7af2c2c1053da9fa96d9cf3072ca58f057f4c5adaaa1cab8fc442"}, + {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:766c8f7511df26d9f11cd3a8be623e59cca73d44643abab3f8c8c07620524e4a"}, + {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:fe5d7785250541f7f5019ab9cba2c71169dc7d74d0f45253f8313f436458a4ef"}, + {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c1c1496e73051918fcd4f58ff2e0f2f3066d1c76a0c6aeffd9b45d53243702cc"}, + {file = "multidict-6.0.5-cp310-cp310-win32.whl", hash = "sha256:7afcdd1fc07befad18ec4523a782cde4e93e0a2bf71239894b8d61ee578c1319"}, + {file = "multidict-6.0.5-cp310-cp310-win_amd64.whl", hash = "sha256:99f60d34c048c5c2fabc766108c103612344c46e35d4ed9ae0673d33c8fb26e8"}, + {file = "multidict-6.0.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f285e862d2f153a70586579c15c44656f888806ed0e5b56b64489afe4a2dbfba"}, + {file = "multidict-6.0.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:53689bb4e102200a4fafa9de9c7c3c212ab40a7ab2c8e474491914d2305f187e"}, + {file = "multidict-6.0.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:612d1156111ae11d14afaf3a0669ebf6c170dbb735e510a7438ffe2369a847fd"}, + {file = "multidict-6.0.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7be7047bd08accdb7487737631d25735c9a04327911de89ff1b26b81745bd4e3"}, + {file = "multidict-6.0.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de170c7b4fe6859beb8926e84f7d7d6c693dfe8e27372ce3b76f01c46e489fcf"}, + {file = "multidict-6.0.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:04bde7a7b3de05732a4eb39c94574db1ec99abb56162d6c520ad26f83267de29"}, + {file = "multidict-6.0.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85f67aed7bb647f93e7520633d8f51d3cbc6ab96957c71272b286b2f30dc70ed"}, + {file = "multidict-6.0.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425bf820055005bfc8aa9a0b99ccb52cc2f4070153e34b701acc98d201693733"}, + {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d3eb1ceec286eba8220c26f3b0096cf189aea7057b6e7b7a2e60ed36b373b77f"}, + {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:7901c05ead4b3fb75113fb1dd33eb1253c6d3ee37ce93305acd9d38e0b5f21a4"}, + {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:e0e79d91e71b9867c73323a3444724d496c037e578a0e1755ae159ba14f4f3d1"}, + {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:29bfeb0dff5cb5fdab2023a7a9947b3b4af63e9c47cae2a10ad58394b517fddc"}, + {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e030047e85cbcedbfc073f71836d62dd5dadfbe7531cae27789ff66bc551bd5e"}, + {file = "multidict-6.0.5-cp311-cp311-win32.whl", hash = "sha256:2f4848aa3baa109e6ab81fe2006c77ed4d3cd1e0ac2c1fbddb7b1277c168788c"}, + {file = "multidict-6.0.5-cp311-cp311-win_amd64.whl", hash = "sha256:2faa5ae9376faba05f630d7e5e6be05be22913782b927b19d12b8145968a85ea"}, + {file = "multidict-6.0.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:51d035609b86722963404f711db441cf7134f1889107fb171a970c9701f92e1e"}, + {file = "multidict-6.0.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:cbebcd5bcaf1eaf302617c114aa67569dd3f090dd0ce8ba9e35e9985b41ac35b"}, + {file = "multidict-6.0.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2ffc42c922dbfddb4a4c3b438eb056828719f07608af27d163191cb3e3aa6cc5"}, + {file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ceb3b7e6a0135e092de86110c5a74e46bda4bd4fbfeeb3a3bcec79c0f861e450"}, + {file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:79660376075cfd4b2c80f295528aa6beb2058fd289f4c9252f986751a4cd0496"}, + {file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4428b29611e989719874670fd152b6625500ad6c686d464e99f5aaeeaca175a"}, + {file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d84a5c3a5f7ce6db1f999fb9438f686bc2e09d38143f2d93d8406ed2dd6b9226"}, + {file = "multidict-6.0.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:76c0de87358b192de7ea9649beb392f107dcad9ad27276324c24c91774ca5271"}, + {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:79a6d2ba910adb2cbafc95dad936f8b9386e77c84c35bc0add315b856d7c3abb"}, + {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:92d16a3e275e38293623ebf639c471d3e03bb20b8ebb845237e0d3664914caef"}, + {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:fb616be3538599e797a2017cccca78e354c767165e8858ab5116813146041a24"}, + {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:14c2976aa9038c2629efa2c148022ed5eb4cb939e15ec7aace7ca932f48f9ba6"}, + {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:435a0984199d81ca178b9ae2c26ec3d49692d20ee29bc4c11a2a8d4514c67eda"}, + {file = "multidict-6.0.5-cp312-cp312-win32.whl", hash = "sha256:9fe7b0653ba3d9d65cbe7698cca585bf0f8c83dbbcc710db9c90f478e175f2d5"}, + {file = "multidict-6.0.5-cp312-cp312-win_amd64.whl", hash = "sha256:01265f5e40f5a17f8241d52656ed27192be03bfa8764d88e8220141d1e4b3556"}, + {file = "multidict-6.0.5-py3-none-any.whl", hash = "sha256:0d63c74e3d7ab26de115c49bffc92cc77ed23395303d496eae515d4204a625e7"}, + {file = "multidict-6.0.5.tar.gz", hash = "sha256:f7e301075edaf50500f0b341543c41194d8df3ae5caf4702f2095f3ca73dd8da"}, +] + +[[package]] +name = "mypy-extensions" +version = "1.0.0" +requires_python = ">=3.5" +summary = "Type system extensions for programs checked with the mypy type checker." +files = [ + {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, + {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, +] + +[[package]] +name = "packaging" +version = "24.0" +requires_python = ">=3.7" +summary = "Core utilities for Python packages" +files = [ + {file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"}, + {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"}, +] + +[[package]] +name = "poseidon-py" +version = "0.1.4" +requires_python = ">=3.8" +summary = "Python implementation of Poseidon hash" +files = [ + {file = "poseidon_py-0.1.4-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:8c2c81636b8389168181425f214da0e75f0b58df89241719373fcbba45c7b061"}, + {file = "poseidon_py-0.1.4-cp310-cp310-macosx_13_0_universal2.whl", hash = "sha256:6103971eb4c4e6f6a8b8d6d83a1e722771dbc04b29e94da7c202bc904efd1aed"}, + {file = "poseidon_py-0.1.4-cp310-cp310-macosx_14_0_universal2.whl", hash = "sha256:f1d269ef1dfaec4fe41226158cd914e8f74b75e937428d2c3de6c7c0cad8ab74"}, + {file = "poseidon_py-0.1.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:195a3b8acb9a3cb27c8a822619663f25f075057471f392ea18098ed83e920e10"}, + {file = "poseidon_py-0.1.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee3f2995b0023dec31dee06cc5d9c12f5aa1d0e8d7cca7fba7b005145c04afcc"}, + {file = "poseidon_py-0.1.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a08ce457a4a01a3f0c83a5556c21e2e95f86fd7ec594f73f72704c239a489b23"}, + {file = "poseidon_py-0.1.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:71423bc1a8e422a1c82a5a786a0c01b8a024a00fc7cba883e01e85410d5bf275"}, + {file = "poseidon_py-0.1.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3c8c4e54a616451c3420cdce1a8e52b5ffcdc604f431a9c6a0f3cd50ef2e1292"}, + {file = "poseidon_py-0.1.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:1ab0d2d10cdb23be125a918e553bcc7cdd27c48c30339d8d8822757e918706b5"}, + {file = "poseidon_py-0.1.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:e57cbdf75398a4faf7b71b2c2b7462975e81047c3a592a2654e0d020aab184e4"}, + {file = "poseidon_py-0.1.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:64bff7984b02a79d4f6864a2d9276ad52d96a933483293bdf5eb2e1558e0994d"}, + {file = "poseidon_py-0.1.4-cp310-cp310-win32.whl", hash = "sha256:0b5fe9eb6e21a8478ea739d3316b28bf2e8de49dc2d2305768b2f14be04bc143"}, + {file = "poseidon_py-0.1.4-cp310-cp310-win_amd64.whl", hash = "sha256:fdabee5ffceb74836979a4497402dd0dd351ec387d3ecad5c627df8da8cf0f04"}, + {file = "poseidon_py-0.1.4-cp311-cp311-macosx_12_0_universal2.whl", hash = "sha256:c1b8778a8b51d980b6780daf3fb11357942d941465f55ebf9eb0702638396b61"}, + {file = "poseidon_py-0.1.4-cp311-cp311-macosx_13_0_universal2.whl", hash = "sha256:89694d6ebaee6086f1d3e6223707acaeb4e9b32c61faf20c6c2685baaeba6326"}, + {file = "poseidon_py-0.1.4-cp311-cp311-macosx_14_0_universal2.whl", hash = "sha256:7cc93c044a03d7067d37c79a697a81562ae5899bd0150bf496520d418a4a774e"}, + {file = "poseidon_py-0.1.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f36dc34704540f2a2bbe18e2f195bcd0fa504b93962bd72f535e37578f264385"}, + {file = "poseidon_py-0.1.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:24a3b643f7e071883686bcb8422558fc1cf485b61a26a028554d60713cdd9aea"}, + {file = "poseidon_py-0.1.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:12237601c95127c0cb8875e81c04f26720069aed544dfff499a473e86a63f14f"}, + {file = "poseidon_py-0.1.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b421fa3e01e0a072622dcc770635dd1aeb2d8a77d334d5af40ae54033587a1df"}, + {file = "poseidon_py-0.1.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:947164c40ef49b47e366b3b838edab9efb42e598a7f95483880e1b3b84536131"}, + {file = "poseidon_py-0.1.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:95724cc0f6708a097521f7193af20e62ee63b2927b9775bcbf42ed1ada0653ae"}, + {file = "poseidon_py-0.1.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:790a44a2858dc8bab9d80d9527a67232823c3fda2216cc4fb8e37775904b103b"}, + {file = "poseidon_py-0.1.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f658750b779ebd09b30c047d671e4e18e90cbc4ab7bb006dfb5c4468fd5b9f61"}, + {file = "poseidon_py-0.1.4-cp311-cp311-win32.whl", hash = "sha256:48e689782cefd5237fac1001df34c2750e707721d309d9811e0095d3139a47d2"}, + {file = "poseidon_py-0.1.4-cp311-cp311-win_amd64.whl", hash = "sha256:5ecc75a778740fff3d4a3bc374fa9fe6868c08091ac199c43ef7f1d9e40c737c"}, + {file = "poseidon_py-0.1.4-cp312-cp312-macosx_12_0_universal2.whl", hash = "sha256:0eef537ac31cbf195a170e696c9f5b6d2d13ce3a0da98f37cf03f0d855ae2be1"}, + {file = "poseidon_py-0.1.4-cp312-cp312-macosx_13_0_universal2.whl", hash = "sha256:446048c88e8ee97c569032171c7cb057b9c739d2985109c55eb234ce66cd2d16"}, + {file = "poseidon_py-0.1.4-cp312-cp312-macosx_14_0_universal2.whl", hash = "sha256:91c259f85cd1b3a5f2d450a481d90bdd4b911d05bd6bcc51fd290d2fd7d66613"}, + {file = "poseidon_py-0.1.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b53d6eaecac2c7a37a66f7a55a451fe5abed0e317ebb26022e9937b43a54f8c9"}, + {file = "poseidon_py-0.1.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ac18854c6305d80f0ccb270b261eb278bbc21f055b43737a8b55726d4caee3a"}, + {file = "poseidon_py-0.1.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:53edc8142cca4fe56eb2e2451eb77165925e2d7df25186fd5ab5b7d813555381"}, + {file = "poseidon_py-0.1.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6880dc2461a2c7336abb7f4774971a053bc04169dbfce5e08feecefad4fd49c2"}, + {file = "poseidon_py-0.1.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:514bc3df634a4ca5621bc0ea60e253257f8cc7773e1d3701e5e8f36a35f4d0f3"}, + {file = "poseidon_py-0.1.4-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:76d7cdb3c4a744573627f8170f659236737218245d04a7ead00e74bfb48ab28a"}, + {file = "poseidon_py-0.1.4-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:8fa27f2797abdec641a26abb05fee82194ebb40fd4ded3fa385b8b143bef4d7f"}, + {file = "poseidon_py-0.1.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:53a78d0fcd1a7742f1d72ce9a2871790c0ae862dec62b18f58982c0ca07a3e79"}, + {file = "poseidon_py-0.1.4-cp312-cp312-win32.whl", hash = "sha256:1176e308c18ff878cc8763cb0dc03541d56775a75b8128f5da6d55ad041a6bd8"}, + {file = "poseidon_py-0.1.4-cp312-cp312-win_amd64.whl", hash = "sha256:9efac87f378ceb64c2b2bad5a2bf8678459ce7ae7947c12326effc4a700fe9e5"}, + {file = "poseidon_py-0.1.4.tar.gz", hash = "sha256:416139d80931c85fd117cbc5b47d2eb1daf25e52acd77b6dd889c4820592a479"}, +] + +[[package]] +name = "pycryptodome" +version = "3.20.0" +requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +summary = "Cryptographic library for Python" +files = [ + {file = "pycryptodome-3.20.0-cp35-abi3-macosx_10_9_universal2.whl", hash = "sha256:ac1c7c0624a862f2e53438a15c9259d1655325fc2ec4392e66dc46cdae24d044"}, + {file = "pycryptodome-3.20.0-cp35-abi3-macosx_10_9_x86_64.whl", hash = "sha256:76658f0d942051d12a9bd08ca1b6b34fd762a8ee4240984f7c06ddfb55eaf15a"}, + {file = "pycryptodome-3.20.0-cp35-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f35d6cee81fa145333137009d9c8ba90951d7d77b67c79cbe5f03c7eb74d8fe2"}, + {file = "pycryptodome-3.20.0-cp35-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76cb39afede7055127e35a444c1c041d2e8d2f1f9c121ecef573757ba4cd2c3c"}, + {file = "pycryptodome-3.20.0-cp35-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49a4c4dc60b78ec41d2afa392491d788c2e06edf48580fbfb0dd0f828af49d25"}, + {file = "pycryptodome-3.20.0-cp35-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fb3b87461fa35afa19c971b0a2b7456a7b1db7b4eba9a8424666104925b78128"}, + {file = "pycryptodome-3.20.0-cp35-abi3-musllinux_1_1_i686.whl", hash = "sha256:acc2614e2e5346a4a4eab6e199203034924313626f9620b7b4b38e9ad74b7e0c"}, + {file = "pycryptodome-3.20.0-cp35-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:210ba1b647837bfc42dd5a813cdecb5b86193ae11a3f5d972b9a0ae2c7e9e4b4"}, + {file = "pycryptodome-3.20.0-cp35-abi3-win32.whl", hash = "sha256:8d6b98d0d83d21fb757a182d52940d028564efe8147baa9ce0f38d057104ae72"}, + {file = "pycryptodome-3.20.0-cp35-abi3-win_amd64.whl", hash = "sha256:9b3ae153c89a480a0ec402e23db8d8d84a3833b65fa4b15b81b83be9d637aab9"}, + {file = "pycryptodome-3.20.0-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:4401564ebf37dfde45d096974c7a159b52eeabd9969135f0426907db367a652a"}, + {file = "pycryptodome-3.20.0-pp27-pypy_73-win32.whl", hash = "sha256:ec1f93feb3bb93380ab0ebf8b859e8e5678c0f010d2d78367cf6bc30bfeb148e"}, + {file = "pycryptodome-3.20.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:acae12b9ede49f38eb0ef76fdec2df2e94aad85ae46ec85be3648a57f0a7db04"}, + {file = "pycryptodome-3.20.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f47888542a0633baff535a04726948e876bf1ed880fddb7c10a736fa99146ab3"}, + {file = "pycryptodome-3.20.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e0e4a987d38cfc2e71b4a1b591bae4891eeabe5fa0f56154f576e26287bfdea"}, + {file = "pycryptodome-3.20.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:c18b381553638414b38705f07d1ef0a7cf301bc78a5f9bc17a957eb19446834b"}, + {file = "pycryptodome-3.20.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a60fedd2b37b4cb11ccb5d0399efe26db9e0dd149016c1cc6c8161974ceac2d6"}, + {file = "pycryptodome-3.20.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:405002eafad114a2f9a930f5db65feef7b53c4784495dd8758069b89baf68eab"}, + {file = "pycryptodome-3.20.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2ab6ab0cb755154ad14e507d1df72de9897e99fd2d4922851a276ccc14f4f1a5"}, + {file = "pycryptodome-3.20.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:acf6e43fa75aca2d33e93409f2dafe386fe051818ee79ee8a3e21de9caa2ac9e"}, + {file = "pycryptodome-3.20.0.tar.gz", hash = "sha256:09609209ed7de61c2b560cc5c8c4fbf892f8b15b1faf7e4cbffac97db1fffda7"}, +] + +[[package]] +name = "pywin32" +version = "306" +summary = "Python for Window Extensions" +files = [ + {file = "pywin32-306-cp310-cp310-win32.whl", hash = "sha256:06d3420a5155ba65f0b72f2699b5bacf3109f36acbe8923765c22938a69dfc8d"}, + {file = "pywin32-306-cp310-cp310-win_amd64.whl", hash = "sha256:84f4471dbca1887ea3803d8848a1616429ac94a4a8d05f4bc9c5dcfd42ca99c8"}, + {file = "pywin32-306-cp311-cp311-win32.whl", hash = "sha256:e65028133d15b64d2ed8f06dd9fbc268352478d4f9289e69c190ecd6818b6407"}, + {file = "pywin32-306-cp311-cp311-win_amd64.whl", hash = "sha256:a7639f51c184c0272e93f244eb24dafca9b1855707d94c192d4a0b4c01e1100e"}, + {file = "pywin32-306-cp311-cp311-win_arm64.whl", hash = "sha256:70dba0c913d19f942a2db25217d9a1b726c278f483a919f1abfed79c9cf64d3a"}, + {file = "pywin32-306-cp312-cp312-win32.whl", hash = "sha256:383229d515657f4e3ed1343da8be101000562bf514591ff383ae940cad65458b"}, + {file = "pywin32-306-cp312-cp312-win_amd64.whl", hash = "sha256:37257794c1ad39ee9be652da0462dc2e394c8159dfd913a8a4e8eb6fd346da0e"}, + {file = "pywin32-306-cp312-cp312-win_arm64.whl", hash = "sha256:5821ec52f6d321aa59e2db7e0a35b997de60c201943557d108af9d4ae1ec7040"}, +] + +[[package]] +name = "six" +version = "1.16.0" +requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +summary = "Python 2 and 3 compatibility utilities" +files = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] + +[[package]] +name = "starknet-py" +version = "0.20.0" +requires_python = ">=3.8,<3.13" +summary = "A python SDK for Starknet" +dependencies = [ + "aiohttp<4.0.0,>=3.8.4", + "asgiref<4.0.0,>=3.4.1", + "crypto-cpp-py==1.4.4", + "lark<2.0.0,>=1.1.5", + "marshmallow-dataclass<8.7.0", + "marshmallow-oneofschema==3.0.1", + "marshmallow<4.0.0,>=3.15.0", + "poseidon-py==0.1.4", + "pycryptodome<4.0,>=3.17", + "typing-extensions<5.0.0,>=4.3.0", +] +files = [ + {file = "starknet_py-0.20.0.tar.gz", hash = "sha256:b144775e5ba175f66e404a990bbcec73c4e24ce8c8d6e434a393d20aa7386c0b"}, +] + +[[package]] +name = "sympy" +version = "1.11.1" +requires_python = ">=3.8" +summary = "Computer algebra system (CAS) in Python" +dependencies = [ + "mpmath>=0.19", +] +files = [ + {file = "sympy-1.11.1-py3-none-any.whl", hash = "sha256:938f984ee2b1e8eae8a07b884c8b7a1146010040fccddc6539c54f401c8f6fcf"}, + {file = "sympy-1.11.1.tar.gz", hash = "sha256:e32380dce63cb7c0108ed525570092fd45168bdae2faa17e528221ef72e88658"}, +] + +[[package]] +name = "typing-extensions" +version = "4.10.0" +requires_python = ">=3.8" +summary = "Backported and Experimental Type Hints for Python 3.8+" +files = [ + {file = "typing_extensions-4.10.0-py3-none-any.whl", hash = "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475"}, + {file = "typing_extensions-4.10.0.tar.gz", hash = "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb"}, +] + +[[package]] +name = "typing-inspect" +version = "0.9.0" +summary = "Runtime inspection utilities for typing module." +dependencies = [ + "mypy-extensions>=0.3.0", + "typing-extensions>=3.7.4", +] +files = [ + {file = "typing_inspect-0.9.0-py3-none-any.whl", hash = "sha256:9ee6fc59062311ef8547596ab6b955e1b8aa46242d854bfc78f4f6b0eff35f9f"}, + {file = "typing_inspect-0.9.0.tar.gz", hash = "sha256:b23fc42ff6f6ef6954e4852c1fb512cdd18dbea03134f91f856a95ccc9461f78"}, +] + +[[package]] +name = "yarl" +version = "1.9.4" +requires_python = ">=3.7" +summary = "Yet another URL library" +dependencies = [ + "idna>=2.0", + "multidict>=4.0", +] +files = [ + {file = "yarl-1.9.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a8c1df72eb746f4136fe9a2e72b0c9dc1da1cbd23b5372f94b5820ff8ae30e0e"}, + {file = "yarl-1.9.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a3a6ed1d525bfb91b3fc9b690c5a21bb52de28c018530ad85093cc488bee2dd2"}, + {file = "yarl-1.9.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c38c9ddb6103ceae4e4498f9c08fac9b590c5c71b0370f98714768e22ac6fa66"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9e09c9d74f4566e905a0b8fa668c58109f7624db96a2171f21747abc7524234"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8477c1ee4bd47c57d49621a062121c3023609f7a13b8a46953eb6c9716ca392"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5ff2c858f5f6a42c2a8e751100f237c5e869cbde669a724f2062d4c4ef93551"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:357495293086c5b6d34ca9616a43d329317feab7917518bc97a08f9e55648455"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54525ae423d7b7a8ee81ba189f131054defdb122cde31ff17477951464c1691c"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:801e9264d19643548651b9db361ce3287176671fb0117f96b5ac0ee1c3530d53"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e516dc8baf7b380e6c1c26792610230f37147bb754d6426462ab115a02944385"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:7d5aaac37d19b2904bb9dfe12cdb08c8443e7ba7d2852894ad448d4b8f442863"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:54beabb809ffcacbd9d28ac57b0db46e42a6e341a030293fb3185c409e626b8b"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bac8d525a8dbc2a1507ec731d2867025d11ceadcb4dd421423a5d42c56818541"}, + {file = "yarl-1.9.4-cp310-cp310-win32.whl", hash = "sha256:7855426dfbddac81896b6e533ebefc0af2f132d4a47340cee6d22cac7190022d"}, + {file = "yarl-1.9.4-cp310-cp310-win_amd64.whl", hash = "sha256:848cd2a1df56ddbffeb375535fb62c9d1645dde33ca4d51341378b3f5954429b"}, + {file = "yarl-1.9.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:35a2b9396879ce32754bd457d31a51ff0a9d426fd9e0e3c33394bf4b9036b099"}, + {file = "yarl-1.9.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c7d56b293cc071e82532f70adcbd8b61909eec973ae9d2d1f9b233f3d943f2c"}, + {file = "yarl-1.9.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d8a1c6c0be645c745a081c192e747c5de06e944a0d21245f4cf7c05e457c36e0"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b3c1ffe10069f655ea2d731808e76e0f452fc6c749bea04781daf18e6039525"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:549d19c84c55d11687ddbd47eeb348a89df9cb30e1993f1b128f4685cd0ebbf8"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7409f968456111140c1c95301cadf071bd30a81cbd7ab829169fb9e3d72eae9"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e23a6d84d9d1738dbc6e38167776107e63307dfc8ad108e580548d1f2c587f42"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d8b889777de69897406c9fb0b76cdf2fd0f31267861ae7501d93003d55f54fbe"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:03caa9507d3d3c83bca08650678e25364e1843b484f19986a527630ca376ecce"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4e9035df8d0880b2f1c7f5031f33f69e071dfe72ee9310cfc76f7b605958ceb9"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:c0ec0ed476f77db9fb29bca17f0a8fcc7bc97ad4c6c1d8959c507decb22e8572"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:ee04010f26d5102399bd17f8df8bc38dc7ccd7701dc77f4a68c5b8d733406958"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:49a180c2e0743d5d6e0b4d1a9e5f633c62eca3f8a86ba5dd3c471060e352ca98"}, + {file = "yarl-1.9.4-cp311-cp311-win32.whl", hash = "sha256:81eb57278deb6098a5b62e88ad8281b2ba09f2f1147c4767522353eaa6260b31"}, + {file = "yarl-1.9.4-cp311-cp311-win_amd64.whl", hash = "sha256:d1d2532b340b692880261c15aee4dc94dd22ca5d61b9db9a8a361953d36410b1"}, + {file = "yarl-1.9.4-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0d2454f0aef65ea81037759be5ca9947539667eecebca092733b2eb43c965a81"}, + {file = "yarl-1.9.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:44d8ffbb9c06e5a7f529f38f53eda23e50d1ed33c6c869e01481d3fafa6b8142"}, + {file = "yarl-1.9.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aaaea1e536f98754a6e5c56091baa1b6ce2f2700cc4a00b0d49eca8dea471074"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3777ce5536d17989c91696db1d459574e9a9bd37660ea7ee4d3344579bb6f129"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fc5fc1eeb029757349ad26bbc5880557389a03fa6ada41703db5e068881e5f2"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea65804b5dc88dacd4a40279af0cdadcfe74b3e5b4c897aa0d81cf86927fee78"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa102d6d280a5455ad6a0f9e6d769989638718e938a6a0a2ff3f4a7ff8c62cc4"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09efe4615ada057ba2d30df871d2f668af661e971dfeedf0c159927d48bbeff0"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:008d3e808d03ef28542372d01057fd09168419cdc8f848efe2804f894ae03e51"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6f5cb257bc2ec58f437da2b37a8cd48f666db96d47b8a3115c29f316313654ff"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:992f18e0ea248ee03b5a6e8b3b4738850ae7dbb172cc41c966462801cbf62cf7"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:0e9d124c191d5b881060a9e5060627694c3bdd1fe24c5eecc8d5d7d0eb6faabc"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3986b6f41ad22988e53d5778f91855dc0399b043fc8946d4f2e68af22ee9ff10"}, + {file = "yarl-1.9.4-cp312-cp312-win32.whl", hash = "sha256:4b21516d181cd77ebd06ce160ef8cc2a5e9ad35fb1c5930882baff5ac865eee7"}, + {file = "yarl-1.9.4-cp312-cp312-win_amd64.whl", hash = "sha256:a9bd00dc3bc395a662900f33f74feb3e757429e545d831eef5bb280252631984"}, + {file = "yarl-1.9.4-py3-none-any.whl", hash = "sha256:928cecb0ef9d5a7946eb6ff58417ad2fe9375762382f1bf5c55e61645f2c43ad"}, + {file = "yarl-1.9.4.tar.gz", hash = "sha256:566db86717cf8080b99b58b083b773a908ae40f06681e87e589a976faf8246bf"}, +] diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..76892cd --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,15 @@ +[project] +name = "kl" +version = "0.1.0" +description = "" +authors = [ + {name = "mssp", email = "mssp@mssp.com"}, +] +dependencies = [ + "starknet-py>=0.20.0", + "asyncio>=3.4.3", +] +requires-python = ">=3.10,<3.13" +readme = "README.md" +license = {text = "MIT"} + diff --git a/pyutils/main.py b/pyutils/main.py new file mode 100644 index 0000000..2110d8e --- /dev/null +++ b/pyutils/main.py @@ -0,0 +1,43 @@ +from starknet_py.hash.address import compute_address +from starknet_py.net.account.account import Account +from starknet_py.net.full_node_client import FullNodeClient +from starknet_py.net.models import StarknetChainId +from starknet_py.net.signer.stark_curve_signer import KeyPair +from starknet_py.net.full_node_client import FullNodeClient +import asyncio +from starknet_py.contract import Contract +from starknet_py.common import create_casm_class, create_compiled_contract +from starknet_py.hash.casm_class_hash import compute_casm_class_hash + +with open("target/dev/kingdom_lord_ERC20.contract_class.json", encoding="utf-8") as f: + compiled_contract = f.read() + +with open("target/dev/kingdom_lord_ERC20.compiled_contract_class.json", encoding="utf-8") as f: + casm = f.read() + +async def main(): + node_url = "http://localhost:5050" + client = FullNodeClient(node_url=node_url) + chain_id = await client.get_chain_id() + chain_id = int(chain_id, 16) + print(chain_id) + key_pair = KeyPair.from_private_key("0x1c9053c053edf324aec366a34c6901b1095b07af69495bffec7d7fe21effb1b") + address =int("0x6b86e40118f29ebe393a75469b4d926c7a44c2e2681b6d319520b7c1156d114", 16) + account = Account(address=address, client=client, key_pair=key_pair, chain=chain_id) + balance = await account.get_balance("0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7") + print(balance) + compiled_class_hash= compute_casm_class_hash(create_casm_class(casm)) + + declare_tx = await account.sign_declare_v2(compiled_contract,compiled_class_hash=compiled_class_hash, max_fee=int(1e20)) + print(declare_tx) + result = await account.client.declare(declare_tx) + print(result) + # deploy_result = await Contract.deploy_contract_v3( + # account=account, + # class_hash="0x02a8846878b6ad1f54f6ba46f5f40e11cee755c677f130b2c4b60566c9003f1f", + # abi=[], + # constructor_args=[], + # max_fee=int(1e16), + # ) + +asyncio.run(main()) \ No newline at end of file diff --git a/scripts/default_auth.sh b/scripts/default_auth.sh new file mode 100644 index 0000000..e4f30dd --- /dev/null +++ b/scripts/default_auth.sh @@ -0,0 +1,43 @@ +#!/bin/bash +set -xo pipefail +pushd $(dirname "$0")/.. + +if [[ -z "${DEPLOY_RPC_URL+x}" ]] +then + export RPC_URL="http://localhost:5050" +else + export RPC_URL="$DEPLOY_RPC_URL" +fi + +if [[ -z "${TARGET_NAME+x}" ]] +then + export TARGET_NAME="dev" +else + echo "profile target is $TARGET_NAME" +fi + +export WORLD_ADDRESS=$(cat ./target/$TARGET_NAME/manifest.json | jq -r '.world.address') + +export ACTIONS_ADDRESS=$(cat ./target/$TARGET_NAME/manifest.json | jq -r '.contracts[] | select(.name == "kingdom_lord::actions::kingdom_lord_controller" ).address') + +echo "---------------------------------------------------------------------------" +echo world : $WORLD_ADDRESS +echo " " +echo actions : $ACTIONS_ADDRESS +echo "---------------------------------------------------------------------------" + +# enable system -> component authorizations +COMPONENTS=("Barn" "OuterCity" "Warehouse" "CityBuilding" "SpawnStatus" "UnderUpgrading" "CityHall", "BuildingAreaInfo" "Barrack" "Troops" "UnderTraining") + +for component in ${COMPONENTS[@]}; do + sozo auth writer $component $ACTIONS_ADDRESS --world $WORLD_ADDRESS --rpc-url $RPC_URL + # time out for 1 second to avoid rate limiting + sleep 1 +done + +echo "Default authorizations have been successfully set." + +echo "Setting pay address for upgrading" +export ADMIN_ADDRESS=$(cat ./target/$TARGET_NAME/manifest.json | jq -r '.contracts[] | select(.name == "kingdom_lord::admin::kingdom_lord_admin" ).address') +sozo execute 0x17acb0793d3bfdf9b8058d6ba25215bed0df3949007d0b7676ad335736e444f set_config --calldata 0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7,0,100,0x6162896d1d7ab204c7ccac6dd5f8e9e7c25ecd5ae4fcb4ad32e57786bb46e03 +echo "Setting pay address for upgrading done" \ No newline at end of file diff --git a/scripts/local_env.sh b/scripts/local_env.sh new file mode 100644 index 0000000..0abe7ca --- /dev/null +++ b/scripts/local_env.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +SCRIPT_DIR="$(dirname "$(readlink -f "$0")")" +# echo "dir: $SCRIPT_DIR" +export STARKNET_RPC="http://localhost:5050" +export STARKNET_KEYSTORE="$SCRIPT_DIR/../account.key" diff --git a/src/actions.cairo b/src/actions.cairo new file mode 100644 index 0000000..359b005 --- /dev/null +++ b/src/actions.cairo @@ -0,0 +1,568 @@ +#[dojo::contract] +mod kingdom_lord_controller { + use kingdom_lord::components::barn::{barn_component, Barn}; + use kingdom_lord::components::barn::barn_component::BarnInternalImpl; + use kingdom_lord::components::warehouse::{warehouse_component, Warehouse}; + use kingdom_lord::components::outer_city::{outer_city_component, OuterCity}; + use kingdom_lord::components::outer_city::outer_city_component::{OuterCityInternalImpl}; + use kingdom_lord::helpers::contract_address::FmtContractAddr; + use kingdom_lord::components::city_hall::{ + city_hall_component, UnderUpgrading, new_under_upgrading, CityHall, CityHallGetLevel + }; + use kingdom_lord::components::city_building::{ + CityBuilding, new_city_building, CityBuildingGetLevelImpl + }; + use kingdom_lord::components::universal::{universal_component, BuildingAreaInfo}; + use kingdom_lord::components::barrack::{ + barrack_component, Barrack, Troops, UnderTraining, SoldierKind, new_under_training, + soldier_info + }; + use kingdom_lord::components::barrack::barrack_component::BarrackInternalImpl; + use kingdom_lord::components::universal::universal_component::UniversalInternalImpl; + use kingdom_lord::models::building::{BuildingUpgradeResource, BuildingUpgradeInfo}; + use kingdom_lord::events::{ + NewPlayerSpawnEvent, StartUpgradeEvent, UpgradeNotEnoughResourceEvent, UpgradeCompleteEvent, + UpgradeNotFinishedEvent, AlreadySpawnedEvent, PayToFinishedUpgradeEvent, + TrainingFinishedEvent, StartTrainingEvent + }; + use starknet::ContractAddress; + use kingdom_lord::interface::{IKingdomLord, Error}; + use kingdom_lord::models::resource::{Wood, Brick, Steel, Food, Resource}; + use kingdom_lord::models::level::{Level, LevelExtentionTraitsImpl}; + use kingdom_lord::models::growth::GrowthRate; + use kingdom_lord::models::building_kind::BuildingKind; + use kingdom_lord::components::config::{Config, verify_proof}; + use kingdom_lord::constants::{ + WOOD_BUILDING_COUNT, BRICK_BUILDING_COUNT, STEEL_BUILDING_COUNT, FOOD_BUILDING_COUNT, + BASE_GROW_RATE, INITIAL_MAX_STORAGE, UNDER_UPGRADING_COUNT, CITY_HALL_START_INDEX, + WAREHOUSE_START_INDEX, BARN_START_INDEX, CONFIG_ID, BRICK_BUILDING_START_INDEX, + STEEL_BUILDING_START_INDEX, FOOD_BUILDING_START_INDEX, BARRACK_START_INDEX, UNDER_TRAINING_COUNT + }; + use starknet::get_caller_address; + use kingdom_lord::models::time::get_current_time; + use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherImpl}; + + component!(path: barn_component, storage: barn, event: BarnEvent); + component!(path: warehouse_component, storage: warehouse, event: WarehouseEvent); + component!(path: outer_city_component, storage: outer_city, event: OuterCityEvent); + component!(path: city_hall_component, storage: city_hall, event: CityHallEvent); + component!(path: universal_component, storage: universal, event: UniversalEvent); + component!(path: barrack_component, storage: barrack, event: BarrackEvent); + + #[derive(Model, Serde, Drop)] + struct SpawnStatus { + #[key] + player: ContractAddress, + already_spawned: bool + } + + #[storage] + struct Storage { + #[substorage(v0)] + barn: barn_component::Storage, + #[substorage(v0)] + warehouse: warehouse_component::Storage, + #[substorage(v0)] + outer_city: outer_city_component::Storage, + #[substorage(v0)] + city_hall: city_hall_component::Storage, + #[substorage(v0)] + universal: universal_component::Storage, + #[substorage(v0)] + barrack: barrack_component::Storage, + } + + + #[event] + #[derive(Copy, Drop, starknet::Event)] + enum Event { + BarnEvent: barn_component::Event, + WarehouseEvent: warehouse_component::Event, + OuterCityEvent: outer_city_component::Event, + CityHallEvent: city_hall_component::Event, + UniversalEvent: universal_component::Event, + BarrackEvent: barrack_component::Event, + // custom + NewPlayerSpawnEvent: NewPlayerSpawnEvent, + StartUpgradeEvent: StartUpgradeEvent, + UpgradeNotEnoughResourceEvent: UpgradeNotEnoughResourceEvent, + UpgradeCompleteEvent: UpgradeCompleteEvent, + UpgradeNotFinishedEvent: UpgradeNotFinishedEvent, + AlreadySpawnedEvent: AlreadySpawnedEvent, + PayToFinishedUpgradeEvent: PayToFinishedUpgradeEvent, + StartTrainingEvent: StartTrainingEvent, + TrainingFinisedEvent: TrainingFinishedEvent, + } + + impl KLBarnImpl = barn_component::BarnInternalImpl; + + impl KLWarehouseImpl = warehouse_component::WarehouseInternalImpl; + + #[abi(embed_v0)] + impl KLOuterCityImpl = outer_city_component::OuterCityTraitImpl; + + impl KLCityHallImpl = city_hall_component::CityHallInternalImpl; + + impl KLBarrackImpl = barrack_component::BarrackInternalImpl; + + #[abi(embed_v0)] + impl KingdomLordImpl of IKingdomLord { + fn spawn(ref self: ContractState) -> Result<(), Error> { + let world = self.world_dispatcher.read(); + + let player = get_caller_address(); + let spawn_status = get!(world, (player), (SpawnStatus)); + if spawn_status.already_spawned { + self.emit(AlreadySpawnedEvent { player }); + return Result::Err(Error::AlreadySpawned); + } + let time = get_current_time(); + set!( + world, + ( + Warehouse { + player, + building_id: WAREHOUSE_START_INDEX, + level: 0_u64.into(), + wood: 0_u64.into(), + steel: 0_u64.into(), + bricks: 0_u64.into(), + max_storage: INITIAL_MAX_STORAGE, + food_consume_rate: 0_u64.into() + }, + BuildingAreaInfo { + player, + building_id: WAREHOUSE_START_INDEX, + building_kind: BuildingKind::Warehouse.into() + }, + Barn { + player, + building_id: BARN_START_INDEX, + level: 0_u64.into(), + food: 0_u64.into(), + max_storage: INITIAL_MAX_STORAGE, + food_consume_rate: 0_u64.into() + }, + BuildingAreaInfo { + player, + building_id: BARN_START_INDEX, + building_kind: BuildingKind::Barn.into() + }, + OuterCity { player, last_mined_time: time }, + ) + ); + + // initialize outer city buildings + let mut index = 0; + let max_index = WOOD_BUILDING_COUNT + + BRICK_BUILDING_COUNT + + STEEL_BUILDING_COUNT + + FOOD_BUILDING_COUNT; + loop { + if index == max_index { + break; + } + if index < BRICK_BUILDING_START_INDEX { + set!( + world, + (new_city_building( + player, BuildingKind::WoodBuilding, BASE_GROW_RATE, 0_u64.into(), index + )) + ); + set!( + world, + (BuildingAreaInfo { + player, + building_id: index, + building_kind: BuildingKind::WoodBuilding.into() + }) + ); + } else if index >= BRICK_BUILDING_START_INDEX + && index < STEEL_BUILDING_START_INDEX { + set!( + world, + (new_city_building( + player, BuildingKind::BrickBuilding, BASE_GROW_RATE, 0_u64.into(), index + )) + ); + set!( + world, + (BuildingAreaInfo { + player, + building_id: index, + building_kind: BuildingKind::BrickBuilding.into() + }) + ); + } else if index >= STEEL_BUILDING_START_INDEX && index < FOOD_BUILDING_START_INDEX { + set!( + world, + (new_city_building( + player, BuildingKind::SteelBuilding, BASE_GROW_RATE, 0_u64.into(), index + )) + ); + set!( + world, + (BuildingAreaInfo { + player, + building_id: index, + building_kind: BuildingKind::SteelBuilding.into() + }) + ); + } else if index < max_index { + set!( + world, + (new_city_building( + player, BuildingKind::FoodBuilding, BASE_GROW_RATE, 0_u64.into(), index + )) + ); + set!( + world, + (BuildingAreaInfo { + player, + building_id: index, + building_kind: BuildingKind::FoodBuilding.into() + }) + ); + } else { + panic!("index not valid") + } + index += 1 + }; + + // initialize upgrading list + index = 0; + loop { + set!(world, (new_under_upgrading(player, index))); + if index == UNDER_UPGRADING_COUNT { + break; + } + index += 1 + }; + let city_hall = CityHall { + player, building_id: CITY_HALL_START_INDEX, level: 1_u64.into(), bonus: 0_u64, food_consume_rate: 0_u64 + }; + set!(world, (city_hall)); + set!( + world, + (BuildingAreaInfo { + player, + building_id: CITY_HALL_START_INDEX, + building_kind: BuildingKind::CityHall.into() + }) + ); + + // initialize barrack + set!( + world, + (Barrack { + player, building_id: BARRACK_START_INDEX, level: 0_u64.into(), bonus: 100_u64, food_consume_rate: 0_u64 + }) + ); + set!( + world, + (Troops { + player, + millitia: 0, + guard: 0, + heavy_infantry: 0, + scouts: 0, + knights: 0, + heavy_knights: 0 + }) + ); + + // initialize upgrading list + index = 0; + loop { + set!(world, (new_under_training(player, index))); + if index == UNDER_TRAINING_COUNT { + break; + } + index += 1 + }; + + set!(world, (SpawnStatus { player, already_spawned: true })); + self.emit(NewPlayerSpawnEvent { player, time }); + Result::Ok(()) + } + + fn get_food_consume_rate(self: @ContractState, player: ContractAddress) -> u64{ + 0 + } + + fn get_resource( + self: @ContractState, player: ContractAddress, + ) -> (Resource, Resource, Resource, Resource) { + let (wood, brick, steel, food) = self.outer_city.get_minable_resource(player); + let remain_food = self.barn.get_food(player); + let (remain_wood, remain_brick, remain_steel) = self.warehouse.get_resource(player); + let warehouse_max_storage = self.warehouse.get_max_storage(player); + let barn_max_storage = self.barn.get_max_storage(player); + + let mut wood_sum = wood + remain_wood; + if wood_sum > warehouse_max_storage.into() { + wood_sum = warehouse_max_storage.into(); + } + + let mut brick_sum = brick + remain_brick; + if brick_sum > warehouse_max_storage.into() { + brick_sum = warehouse_max_storage.into(); + } + + let mut steel_sum = steel + remain_steel; + if steel_sum > warehouse_max_storage.into() { + steel_sum = warehouse_max_storage.into(); + } + + let mut food_sum = food + remain_food; + if food_sum > barn_max_storage.into() { + food_sum = barn_max_storage.into(); + } + + (wood_sum, brick_sum, steel_sum, food_sum) + } + + fn get_growth_rate( + self: @ContractState, player: ContractAddress, + ) -> (GrowthRate, GrowthRate, GrowthRate, GrowthRate) { + self.outer_city.get_growth_rate(player) + } + + fn start_upgrade( + ref self: ContractState, + building_id: u64, + building_kind: u64, + next_level: u64, + req_wood: u64, + req_brick: u64, + req_steel: u64, + req_food: u64, + food_consume_rate: u64, + required_time: u64, + value: u64, + proof: Array + ) -> Result { + let caller_address = get_caller_address(); + let data: Array = array![ + building_kind.into(), + next_level.into(), + req_wood.into(), + req_brick.into(), + req_steel.into(), + req_food.into(), + food_consume_rate.into(), + required_time.into(), + value.into() + ]; + + let building_kind: BuildingKind = building_kind.into(); + let next_level: Level = next_level.into(); + let building_kind = self.universal.building_kind(building_id); + + if building_kind != building_kind && building_kind != BuildingKind::None { + return Result::Err(Error::UnknownedError('invalid building kind')); + } + + if !self.universal.is_next_level_valid(building_id, building_kind, next_level) { + return Result::Err(Error::UnknownedError('next level is not valid')); + } + + let req_wood = req_wood.into(); + let req_brick = req_brick.into(); + let req_steel = req_steel.into(); + let req_food = req_food.into(); + let (wood, brick, steel, food) = self.get_resource(caller_address); + if wood < req_wood || brick < req_brick || steel < req_steel || food < req_food { + self.emit(UpgradeNotEnoughResourceEvent { player: caller_address, building_id }); + return Result::Err(Error::ResourceNotEnough); + } + + let world = self.world_dispatcher.read(); + let config = get!(world, (CONFIG_ID), (Config)); + if !verify_proof(config, data.span(), proof.span()) { + return Result::Err(Error::InvalidProof); + } + + let res = self + .city_hall + .start_upgrade(building_id, next_level.into(), required_time, value, food_consume_rate); + match res { + Result::Ok(under_upgrading) => { + self.mine(); + self.warehouse.remove_resource(req_wood, req_brick, req_steel); + self.barn.remove_food(req_food); + self + .emit( + StartUpgradeEvent { + player: caller_address, + upgrade_id: under_upgrading.upgrade_id, + building_id: under_upgrading.building_id, + level: under_upgrading.target_level, + start_time: under_upgrading.start_time, + end_time: under_upgrading.end_time, + } + ); + Result::Ok(under_upgrading.upgrade_id) + }, + Result::Err(err) => Result::Err(err) + } + } + + fn finish_upgrade( + ref self: ContractState, upgrade_id: u64 + ) -> Result { + let res = self.city_hall.finish_upgrade(upgrade_id); + let player = get_caller_address(); + match res { + Result::Ok(under_upgrade) => { + let world = self.world_dispatcher.read(); + let building_id: u64 = under_upgrade.building_id; + let building_kind = self.universal.building_kind(building_id); + self.universal.level_up(building_id, building_kind, (under_upgrade.value, under_upgrade.food_consume_rate)); + self.mine(); + self + .emit( + UpgradeCompleteEvent { + player, upgrade_id, building_id, level: under_upgrade.target_level + } + ); + }, + Result::Err(err) => { self.emit(UpgradeNotFinishedEvent { player, upgrade_id }) } + } + res + } + + fn pay_to_finish_upgrade(ref self: ContractState, upgrade_id: u64) -> Result<(), Error> { + let caller = starknet::get_caller_address(); + + let world = self.world_dispatcher.read(); + let config = get!(world, (CONFIG_ID), (Config)); + let erc20_dispatcher = IERC20Dispatcher { contract_address: config.erc20_addr }; + let res = erc20_dispatcher.transfer_from(caller, config.receiver, config.amount); + if res { + let result = self.city_hall.pay_to_finish_upgrade(upgrade_id); + match result { + Result::Ok(under_upgrade) => { + let caller = get_caller_address(); + self + .emit( + PayToFinishedUpgradeEvent { + player: caller, + upgrade_id, + building_id: under_upgrade.building_id, + level: under_upgrade.target_level + } + ); + Result::Ok(()) + }, + Result::Err(_) => { panic!("pay to finish upgrade error") } + } + } else { + Result::Err(Error::PayToUpgradeError) + } + } + + fn get_under_upgrading( + self: @ContractState, player: ContractAddress, + ) -> Array { + self.city_hall.get_under_upgrading(player) + } + + fn get_complete_upgrading( + self: @ContractState, player: ContractAddress, + ) -> Array { + self.city_hall.get_complete_upgrading(player) + } + fn get_troops(self: @ContractState, player: ContractAddress) -> Troops { + self.barrack.get_troops(player) + } + + fn start_training(ref self: ContractState, barrack_kind: u64,) -> Result { + let caller_address = get_caller_address(); + let soldier_info = soldier_info(barrack_kind.into()); + let req_wood = soldier_info.req_wood.into(); + let req_brick = soldier_info.req_brick.into(); + let req_steel = soldier_info.req_steel.into(); + let req_food = soldier_info.req_food.into(); + let (wood, brick, steel, food) = self.get_resource(caller_address); + if wood < req_wood || brick < req_brick || steel < req_steel || food < req_food { + return Result::Err(Error::ResourceNotEnough); + } + + self.mine(); + self.warehouse.remove_resource(req_wood, req_brick, req_steel); + self.barn.remove_food(req_food); + let soldier_kind: SoldierKind = barrack_kind.into(); + let res = self.barrack.start_training(soldier_kind, soldier_info.required_time); + match res { + Result::Ok(under_training) => { + self + .emit( + StartTrainingEvent { + player: caller_address, + training_id: under_training.training_id, + soldier_kind: under_training.soldier_kind, + start_time: under_training.start_time, + end_time: under_training.end_time, + } + ); + Result::Ok(under_training.training_id) + }, + Result::Err(err) => Result::Err(err) + } + } + + fn finish_training( + ref self: ContractState, training_id: u64 + ) -> Result { + let res = self.barrack.finish_training(training_id); + match res { + Result::Ok(traning_res) => { + self.mine(); + let player = get_caller_address(); + self.emit(TrainingFinishedEvent { player, training_id }); + }, + Result::Err(err) => {} + } + res + } + + fn get_under_training( + self: @ContractState, player: ContractAddress, + ) -> Array { + self.barrack.get_under_training(player) + } + + fn get_complete_training( + self: @ContractState, player: ContractAddress, + ) -> Array { + self.barrack.get_complete_training(player) + } + + fn get_buildings_levels(self: @ContractState, player: ContractAddress) -> Array { + let world = self.world_dispatcher.read(); + let mut res = array![]; + let mut index = 0_u64; + loop { + if index == 18 { + break; + } + let building = get!(world, (player, index), (CityBuilding)); + res.append(building.get_level()); + index += 1; + }; + let city_hall = get!(world, (player, CITY_HALL_START_INDEX), (CityHall)); + res.append(city_hall.get_level()); + res + } + } + + #[generate_trait] + impl InternalImpl of InternalTrait { + fn mine(self: @ContractState) { + let (mined_wood, mined_brick, mined_steel, mined_food) = self.outer_city.mine(); + self.warehouse.add_resource(mined_wood, mined_brick, mined_steel); + self.barn.add_food(mined_food); + } + } +} diff --git a/src/admin.cairo b/src/admin.cairo new file mode 100644 index 0000000..d6000a5 --- /dev/null +++ b/src/admin.cairo @@ -0,0 +1,78 @@ +#[dojo::contract] +mod kingdom_lord_admin { + use kingdom_lord::interface::IKingdomLordAdmin; + use kingdom_lord::components::config::Config; + use kingdom_lord::components::barn::{barn_component, Barn}; + use kingdom_lord::components::warehouse::{warehouse_component, Warehouse}; + use kingdom_lord::components::outer_city::{outer_city_component, OuterCity}; + use starknet::{get_contract_address, ContractAddress}; + use kingdom_lord::components::outer_city::outer_city_component::{OuterCityInternalImpl}; + use kingdom_lord::constants::{ + WOOD_BUILDING_COUNT, BRICK_BUILDING_COUNT, STEEL_BUILDING_COUNT, FOOD_BUILDING_COUNT, + BASE_GROW_RATE, UNDER_UPGRADING_COUNT, CITY_HALL_START_INDEX, + WAREHOUSE_START_INDEX, BARN_START_INDEX, CONFIG_ID + }; + component!(path: barn_component, storage: barn, event: BarnEvent); + component!(path: warehouse_component, storage: warehouse, event: WarehouseEvent); + component!(path: outer_city_component, storage: outer_city, event: OuterCityEvent); + + #[storage] + struct Storage { + #[substorage(v0)] + barn: barn_component::Storage, + #[substorage(v0)] + warehouse: warehouse_component::Storage, + #[substorage(v0)] + outer_city: outer_city_component::Storage, + } + #[event] + #[derive(Copy, Drop, starknet::Event)] + enum Event { + BarnEvent: barn_component::Event, + WarehouseEvent: warehouse_component::Event, + OuterCityEvent: outer_city_component::Event, + } + impl KLBarnImpl = barn_component::BarnInternalImpl; + + impl KLWarehouseImpl = warehouse_component::WarehouseInternalImpl; + + #[abi(embed_v0)] + impl KLOuterCityImpl = outer_city_component::OuterCityTraitImpl; + + #[abi(embed_v0)] + impl KindomLordAdminImpl of IKingdomLordAdmin{ + fn set_config(self: @ContractState, erc20_addr: ContractAddress, amount: u256, receiver: ContractAddress, level_root_merkle: felt252){ + let world = self.world_dispatcher.read(); + let mut config = get!(world, (CONFIG_ID), (Config)); + config.erc20_addr = erc20_addr; + config.amount = amount; + config.receiver = receiver; + config.merkle_root = level_root_merkle; + set!(world, (config)) + } + + fn set_barn_max_storage(self: @ContractState, addr: ContractAddress, max_storage: u64){ + let world = self.world_dispatcher.read(); + let mut barn = get!(world, (addr, BARN_START_INDEX), (Barn)); + barn.max_storage = max_storage; + set!(world, (barn)) + } + + fn set_warehouse_max_storage(self: @ContractState, addr: ContractAddress, max_storage: u64){ + let world = self.world_dispatcher.read(); + let mut warehouse = get!(world, (addr, WAREHOUSE_START_INDEX), (Warehouse)); + warehouse.max_storage = max_storage; + set!(world, (warehouse)) + } + } + + #[generate_trait] + impl InternalImpl of InternalTrait { + fn mine(self: @ContractState) { + let (mined_wood, mined_brick, mined_steel, mined_food) = self.outer_city.mine(); + self.warehouse.add_resource(mined_wood, mined_brick, mined_steel); + self.barn.add_food(mined_food); + } + + } +} \ No newline at end of file diff --git a/src/components/barn.cairo b/src/components/barn.cairo new file mode 100644 index 0000000..929e3ae --- /dev/null +++ b/src/components/barn.cairo @@ -0,0 +1,98 @@ +use core::traits::Into; +use starknet::ContractAddress; +use super::super::models::resource::{Food, Resource}; +use kingdom_lord::models::level::Level; +use kingdom_lord::models::building::{BuildingUpgradeResource}; +use kingdom_lord::models::level::{LevelTrait, LevelUpTrait}; +#[derive(Model, Copy, Drop, Serde)] +struct Barn{ + #[key] + player: ContractAddress, + #[key] + building_id: u64, + level: Level, + food: Resource, + max_storage: u64, + food_consume_rate: u64 +} + +#[generate_trait] +impl BarnTraitImpl of BarnExtension{ + fn get_food(self: @Barn) -> Resource{ + self.food.clone() + } + + fn add_food(ref self: Barn, food: Resource){ + let new_amount = self.food + food; + if new_amount > self.max_storage.into(){ + self.food = self.max_storage.into(); + } else { + self.food = new_amount; + } + } + + fn remove_food(ref self: Barn, food: Resource){ + self.food -= food; + } +} + + +impl WarehouseLeveTrait of LevelUpTrait{ + fn level_up(ref self: Barn, value: (u64, u64)){ + self.level.level_up(()); + let (max_storage, food_consume_rate) = value; + self.max_storage = max_storage; + self.food_consume_rate = food_consume_rate; + } +} + +impl WarehouseGetLevel of LevelTrait{ + fn get_level(self: @Barn) -> Level{ + self.level.get_level() + } +} + + +#[starknet::component] +mod barn_component{ + use starknet::{get_caller_address, ContractAddress}; + use dojo::world::{ + IWorldProvider, IWorldProviderDispatcher, IWorldDispatcher, IWorldDispatcherTrait + }; + use super::{Barn, Food, Resource, BarnExtension}; + use kingdom_lord::constants::BARN_START_INDEX; + + #[storage] + struct Storage {} + + #[generate_trait] + impl BarnInternalImpl< + TContractState, +HasComponent, +IWorldProvider + > of BarnInternalTrait { + fn add_food(self: @ComponentState, food: Resource){ + let world = self.get_contract().world(); + let player = get_caller_address(); + let mut barn = get!(world, (player, BARN_START_INDEX), (Barn)); + barn.add_food(food); + set!(world, (barn)) + } + + fn remove_food(self: @ComponentState, food: Resource){ + let world = self.get_contract().world(); + let player = get_caller_address(); + let mut barn = get!(world, (player, BARN_START_INDEX), (Barn)); + barn.remove_food(food); + set!(world, (barn)) + } + + fn get_food(self: @ComponentState, player: ContractAddress) -> Resource{ + let barn = get!(self.get_contract().world(), (player, BARN_START_INDEX), (Barn)); + barn.get_food() + } + + fn get_max_storage(self: @ComponentState, player: ContractAddress) -> u64{ + let barn = get!(self.get_contract().world(), (player, BARN_START_INDEX), (Barn)); + barn.max_storage + } + } +} \ No newline at end of file diff --git a/src/components/barrack.cairo b/src/components/barrack.cairo new file mode 100644 index 0000000..8eb4d9c --- /dev/null +++ b/src/components/barrack.cairo @@ -0,0 +1,348 @@ +use core::traits::Into; +use starknet::ContractAddress; +use super::super::models::resource::{Food, Resource}; +use kingdom_lord::models::level::Level; +use kingdom_lord::models::building::{BuildingUpgradeResource}; +use kingdom_lord::models::level::{LevelTrait, LevelUpTrait, LevelImpl}; + + +#[derive(Model, Copy, Drop, Serde)] +struct Barrack{ + #[key] + player: ContractAddress, + #[key] + building_id: u64, + level: Level, + bonus: u64, + food_consume_rate:u64 +} + +#[derive(Model, Copy, Drop, Serde)] +struct Troops{ + #[key] + player: ContractAddress, + millitia: u64, + guard: u64, + heavy_infantry: u64, + scouts: u64, + knights: u64, + heavy_knights: u64 +} + +#[derive(Model, Copy, Drop, Serde)] +struct UnderTraining{ + #[key] + address: ContractAddress, + #[key] + training_id: u64, + soldier_kind: u64, + start_time: u64, + end_time: u64, + is_finished: bool, +} + + +#[derive(Copy, Drop, Serde)] +struct SoldierInfo{ + attack_power: u64, + defense_power: u64, + movement_speed: u64, + load_capacity: u64, + req_wood: u64, + req_brick: u64, + req_steel: u64, + req_food: u64, + food_consume_rate: u64, + required_time: u64, +} + + + +#[derive(Copy, Drop, Serde)] +enum SoldierKind{ + Millitia, + Guard, + HeavyInfantry, + Scouts, + Knights, + HeavyKnights +} + +impl SoldierKindIntou64 of Into{ + fn into(self: u64) -> SoldierKind{ + let self:felt252 = self.into(); + match self{ + 0 => SoldierKind::Millitia, + 1 => SoldierKind::Guard, + 2 => SoldierKind::HeavyInfantry, + 3 => SoldierKind::Scouts, + 4 => SoldierKind::Knights, + 5 => SoldierKind::HeavyKnights, + _ => panic!("Invalid SoldierKind") + } + } +} + +impl IntoSoldierKind of Into{ + fn into(self: SoldierKind) -> u64{ + match self{ + SoldierKind::Millitia => 0, + SoldierKind::Guard => 1, + SoldierKind::HeavyInfantry => 2, + SoldierKind::Scouts => 3, + SoldierKind::Knights => 4, + SoldierKind::HeavyKnights => 5, + } + } +} + +fn new_under_training(address: ContractAddress, training_id: u64) -> UnderTraining{ + UnderTraining{ + address: address, + training_id: training_id, + soldier_kind: 0, + start_time: 0, + end_time: 0, + is_finished: true + } +} + +fn soldier_info(soldier_kind: SoldierKind) -> SoldierInfo{ + match soldier_kind{ + SoldierKind::Millitia => { + SoldierInfo{ + attack_power: 40, + defense_power: 35, + movement_speed: 6, + load_capacity: 50, + req_wood: 120, + req_brick: 100, + req_steel: 150, + req_food: 30, + food_consume_rate: 1, + required_time: 1600 + } + }, + SoldierKind::Guard => { + SoldierInfo{ + attack_power: 30, + defense_power: 65, + movement_speed: 5, + load_capacity: 20, + req_wood: 100, + req_brick: 130, + req_steel: 160, + req_food: 70, + food_consume_rate: 1, + required_time: 1760 + } + }, + SoldierKind::HeavyInfantry => { + SoldierInfo{ + attack_power: 70, + defense_power: 40, + movement_speed: 7, + load_capacity: 50, + req_wood: 150, + req_brick: 160, + req_steel: 210, + req_food: 80, + food_consume_rate: 1, + required_time: 1920 + } + }, + SoldierKind::Scouts => { + SoldierInfo{ + attack_power: 0, + defense_power: 20, + movement_speed: 16, + load_capacity: 0, + req_wood: 140, + req_brick: 160, + req_steel: 20, + req_food: 40, + food_consume_rate: 2, + required_time: 1360 + } + }, + SoldierKind::Knights => { + SoldierInfo{ + attack_power: 120, + defense_power: 65, + movement_speed: 14, + load_capacity: 100, + req_wood: 550, + req_brick: 440, + req_steel: 320, + req_food: 100, + food_consume_rate: 3, + required_time: 2640 + } + }, + SoldierKind::HeavyKnights => { + SoldierInfo{ + attack_power: 180, + defense_power: 80, + movement_speed: 10, + load_capacity: 70, + req_wood: 550, + req_brick: 640, + req_steel: 800, + req_food: 180, + food_consume_rate: 4, + required_time: 3520 + } + } + } +} + + + +impl BarrackLevelTrait of LevelUpTrait{ + fn level_up(ref self: Barrack, value: (u64, u64)){ + self.level.level_up(()); + let (bonus, food_consume_rate) = value; + self.food_consume_rate = food_consume_rate; + self.bonus = bonus; + } +} + +impl BarrackGetLevel of LevelTrait{ + fn get_level(self: @Barrack) -> Level{ + self.level.get_level() + } +} + +#[starknet::component] +mod barrack_component{ + use starknet::{get_caller_address, ContractAddress}; + use dojo::world::{ + IWorldProvider, IWorldProviderDispatcher, IWorldDispatcher, IWorldDispatcherTrait + }; + use super::{BarrackLevelTrait, BarrackGetLevel, Barrack, UnderTraining, SoldierKind, Troops}; + use kingdom_lord::constants::{UNDER_TRAINING_COUNT,BARRACK_START_INDEX}; + use kingdom_lord::interface::Error; + use kingdom_lord::models::time::get_current_time; + + #[storage] + struct Storage {} + + #[generate_trait] + impl BarrackInternalImpl< + TContractState, +HasComponent, +IWorldProvider + > of BarrackInternalTrait { + + fn get_troops(self: @ComponentState, player:ContractAddress) -> Troops{ + let world = self.get_contract().world(); + get!(world, (player), (Troops)) + } + fn get_under_training(self: @ComponentState, player: ContractAddress) -> Array { + let current_block_time = get_current_time(); + let world = self.get_contract().world(); + let mut trainings = array![]; + let mut index = 0; + loop { + if index == UNDER_TRAINING_COUNT { + break; + } + let training: UnderTraining = get!(world, (player, index), (UnderTraining)); + if !training.is_finished && training.end_time > current_block_time { + trainings.append(training); + } + index += 1; + }; + + trainings + } + + fn get_complete_training(self: @ComponentState, player: ContractAddress) -> Array { + let current_block_time = get_current_time(); + let world = self.get_contract().world(); + let mut trainings = array![]; + let mut index = 0; + loop { + if index == UNDER_TRAINING_COUNT { + break; + } + let training: UnderTraining = get!(world, (player, index), (UnderTraining)); + if !training.is_finished && training.end_time <= current_block_time { + trainings.append(training); + } + index += 1; + }; + + trainings + } + fn start_training(self: @ComponentState, + soldier_kind: SoldierKind, + required_time: u64 + )-> Result{ + let world = self.get_contract().world(); + let current_time = get_current_time(); + let player = get_caller_address(); + let barrack = get!(world, (player, BARRACK_START_INDEX), (Barrack)); + let required_time = barrack.bonus * required_time / 100; + let mut index = 0; + let mut res: Result = Result::Err(Error::UnknownedError('start upgrading failed')); + loop { + if index == UNDER_TRAINING_COUNT { + res = Result::Err(Error::TrainingListFull); + break; + } + let mut training: UnderTraining = get!(world, (player, index), (UnderTraining)); + if training.is_finished { + training.soldier_kind = soldier_kind.into(); + training.is_finished = false; + training.start_time = current_time; + training.end_time = current_time + required_time; + + set!(world, (training)); + res = Result::Ok(training); + break; + } + index += 1; + }; + res + } + + fn finish_training(self: @ComponentState, training_id: u64) -> Result{ + let world = self.get_contract().world(); + let current_time = get_current_time(); + let player = get_caller_address(); + let mut training = get!(world, (player, training_id), (UnderTraining)); + if training.is_finished{ + return Result::Err(Error::UnknownedError('Training is already finished')); + } + if training.end_time <= current_time{ + training.is_finished = true; + let mut troops: Troops = get!(world, (player), (Troops)); + let soldier_kind: SoldierKind = training.soldier_kind.into(); + match soldier_kind{ + SoldierKind::Millitia => { + troops.millitia += 1; + }, + SoldierKind::Guard => { + troops.guard += 1; + }, + SoldierKind::HeavyInfantry => { + troops.heavy_infantry += 1; + }, + SoldierKind::Scouts => { + troops.scouts += 1; + }, + SoldierKind::Knights => { + troops.knights += 1; + }, + SoldierKind::HeavyKnights => { + troops.heavy_knights += 1; + } + } + set!(world, (troops)); + set!(world, (training)); + return Result::Ok(training); + } else { + return Result::Err(Error::TrainingNotFinished); + } + } + } +} \ No newline at end of file diff --git a/src/components/city_building.cairo b/src/components/city_building.cairo new file mode 100644 index 0000000..83ad422 --- /dev/null +++ b/src/components/city_building.cairo @@ -0,0 +1,65 @@ +use core::clone::Clone; +use starknet::ContractAddress; +use kingdom_lord::models::level::{Level, LevelTrait, LevelUpTrait, LevelExtentionTraitsImpl, LevelImpl, LevelUpTraitImpl}; +use kingdom_lord::models::resource::{Resource, Wood, Brick, Steel, Food}; +use kingdom_lord::models::growth::{Growth, GrowthRate}; +use kingdom_lord::models::building::{ Minable, BuildingUpgradeResource}; +use kingdom_lord::models::building_kind::BuildingKind; + +#[derive(Model, Copy, Drop, Serde)] +struct CityBuilding { + #[key] + player: ContractAddress, + #[key] + building_id: u64, + building_kind: u64, + level: Level, + growth_rate: u64, + food_consume_rate: u64, +} + +fn new_city_building( + player: ContractAddress, building_kind: BuildingKind, growth_rate: u64, level: Level, index: u64 +) -> CityBuilding { + CityBuilding { + player, + building_id: index, + building_kind: building_kind.into(), + level, + growth_rate, + food_consume_rate: 0, + } +} +impl CityBuildingGetLevelImpl of LevelTrait { + fn get_level(self: @CityBuilding) -> Level { + self.level.clone() + } +} + +impl CityBuildingGrowthRate of Growth { + fn get_growth_rate(self: @CityBuilding) -> GrowthRate { + GrowthRate{ amount: *self.growth_rate } + } +} + +impl CityBuildingLevelImpl of LevelUpTrait { + fn level_up(ref self: CityBuilding, value:(u64, u64)) { + self.level.level_up(()); + let (growth_rate, food_consume_rate) = value; + self.growth_rate = growth_rate; + self.food_consume_rate = food_consume_rate; + } +} + +impl CityBuildingMinableImpl of Minable> { + fn get_minable( + self: @CityBuilding, last_time: u64, current_time: u64 + ) -> Resource { + (*self.growth_rate * (current_time - last_time)).into() + } + + fn mine(self: @CityBuilding, last_time: u64, current_time: u64) -> Resource { + self.get_minable(last_time, current_time) + } +} + diff --git a/src/components/city_hall.cairo b/src/components/city_hall.cairo new file mode 100644 index 0000000..076715c --- /dev/null +++ b/src/components/city_hall.cairo @@ -0,0 +1,218 @@ +use starknet::ContractAddress; +use kingdom_lord::models::resource::{Food, Resource}; +use super::city_building::{CityBuilding, CityBuildingLevelImpl}; +use kingdom_lord::models::level::Level; +use kingdom_lord::models::building::{BuildingUpgradeResource}; +use kingdom_lord::models::level::{LevelTrait, LevelUpTrait}; + +#[derive(Model, Drop, Copy, Serde)] +struct UnderUpgrading { + #[key] + address: ContractAddress, + #[key] + upgrade_id: u64, + building_id: u64, + target_level: Level, + start_time: u64, + end_time: u64, + is_finished: bool, + value: u64, + food_consume_rate:u64, +} + + +fn new_under_upgrading( player: ContractAddress, upgrade_id:u64) -> UnderUpgrading{ + UnderUpgrading{ + address: player, + upgrade_id, + building_id: 0_u64, + target_level: 0_u64.into(), + start_time: 0_u64, + end_time: 0_u64, + is_finished: true, + value: 0_u64, + food_consume_rate: 0_u64, + } +} + + +#[derive(Model, Drop, Copy, Serde)] +struct CityHall { + #[key] + player: ContractAddress, + #[key] + building_id: u64, + level: Level, + bonus: u64, + food_consume_rate:u64, +} + + +impl CityHallLevelTrait of LevelUpTrait{ + + fn level_up(ref self: CityHall, value: (u64, u64)){ + self.level.level_up(()); + let (bonus, food_consume_rate) = value; + self.bonus = bonus; + self.food_consume_rate = food_consume_rate; + } +} + + +impl CityHallGetLevel of LevelTrait{ + fn get_level(self: @CityHall) -> Level{ + self.level.get_level() + } +} + + +#[starknet::component] +mod city_hall_component { + use core::traits::Into; + use core::array::ArrayTrait; + use starknet::{get_caller_address, ContractAddress, get_contract_address}; + use kingdom_lord::models::time::get_current_time; + use dojo::world::{ + IWorldProvider, IWorldProviderDispatcher, IWorldDispatcher, IWorldDispatcherTrait + }; + use kingdom_lord::constants::{UNDER_UPGRADING_COUNT, CITY_HALL_START_INDEX}; + use super::{UnderUpgrading, Level, CityBuilding, CityBuildingLevelImpl, CityHall}; + use kingdom_lord::interface::Error; + + #[storage] + struct Storage {} + + #[generate_trait] + impl CityHallInternalImpl< + TContractState, +HasComponent, +IWorldProvider + > of CityHallInternalTrait { + fn get_under_upgrading(self: @ComponentState, player: ContractAddress) -> Array { + let current_block_time = get_current_time(); + let world = self.get_contract().world(); + let mut upgradings = array![]; + let mut index = 0; + loop { + if index == UNDER_UPGRADING_COUNT { + break; + } + let upgrading: UnderUpgrading = get!(world, (player, index), (UnderUpgrading)); + if !upgrading.is_finished && upgrading.end_time > current_block_time { + upgradings.append(upgrading); + } + index += 1; + }; + + upgradings + } + + fn get_complete_upgrading(self: @ComponentState, player: ContractAddress) -> Array { + let current_block_time = get_current_time(); + let world = self.get_contract().world(); + let mut upgradings = array![]; + let mut index = 0; + loop { + if index == UNDER_UPGRADING_COUNT { + break; + } + let upgrading: UnderUpgrading = get!(world, (player, index), (UnderUpgrading)); + if !upgrading.is_finished && upgrading.end_time <= current_block_time { + upgradings.append(upgrading); + } + index += 1; + }; + + upgradings + } + + fn start_upgrade( + ref self: ComponentState, + building_id: u64, + next_level: Level, + required_time: u64, + value: u64, + food_consume_rate: u64 + ) -> Result { + let world = self.get_contract().world(); + let current_time = get_current_time(); + let player = get_caller_address(); + let city_hall = get!(world, (player, CITY_HALL_START_INDEX), (CityHall)); + let required_time = required_time - city_hall.bonus * required_time / 10000; + let mut index = 0; + let mut res: Result = Result::Err(Error::UnknownedError('start upgrading failed')); + loop { + if index == UNDER_UPGRADING_COUNT { + res = Result::Err(Error::UpgradingListFull); + break; + } + let mut upgrading: UnderUpgrading = get!(world, (player, index), (UnderUpgrading)); + if upgrading.is_finished { + upgrading.building_id = building_id; + upgrading.is_finished = false; + upgrading.start_time = current_time; + upgrading.end_time = current_time + required_time; + upgrading.target_level = next_level; + upgrading.value = value; + upgrading.food_consume_rate = food_consume_rate; + set!(world, (upgrading)); + res = Result::Ok(upgrading); + break; + } + index += 1; + }; + res + } + + fn finish_upgrade( + ref self: ComponentState, upgrade_id: u64 + ) -> Result { + let world = self.get_contract().world(); + let current_time = get_current_time(); + let player = get_caller_address(); + let mut upgrading = get!(world, (player, upgrade_id), (UnderUpgrading)); + if upgrading.end_time <= current_time && !upgrading.is_finished{ + upgrading.is_finished = true; + set!(world, (upgrading)); + return Result::Ok(upgrading); + } else { + return Result::Err(Error::UpgradeNotFinished); + } + } + + fn pay_to_finish_upgrade( + ref self: ComponentState, upgrade_id: u64 + ) -> Result { + let world = self.get_contract().world(); + let current_time = get_current_time(); + let player = get_caller_address(); + let mut upgrading = get!(world, (player, upgrade_id), (UnderUpgrading)); + if !upgrading.is_finished{ + upgrading.is_finished = true; + upgrading.end_time = current_time; + set!(world, (upgrading)); + return Result::Ok(upgrading); + } else { + return Result::Err(Error::PayToUpgradeError); + } + } + + // use for pay to finshed upgrade + fn finish_all_upgrade(ref self: ComponentState){ + let mut index = 0; + let player = get_caller_address(); + let current_time = get_current_time(); + let world = self.get_contract().world(); + loop { + if index == UNDER_UPGRADING_COUNT { + break; + } + let mut upgrading: UnderUpgrading = get!(world, (player, index), (UnderUpgrading)); + if !upgrading.is_finished { + upgrading.is_finished = true; + upgrading.end_time = current_time; + set!(world, (upgrading)); + } + index += 1; + }; + } + } +} diff --git a/src/components/config.cairo b/src/components/config.cairo new file mode 100644 index 0000000..560a180 --- /dev/null +++ b/src/components/config.cairo @@ -0,0 +1,22 @@ +use starknet::ContractAddress; +use kingdom_lord::merkle::merkle_tree::{MerkleTreeImpl, MerkleTree, Hasher}; +use kingdom_lord::merkle::merkle_tree::poseidon::PoseidonHasherImpl; + +#[derive(Model, Copy, Drop, Serde)] +struct Config { + #[key] + id_config: u64, + erc20_addr: ContractAddress, + amount: u256, + receiver: ContractAddress, + merkle_root: felt252 +} + +fn verify_proof(config: Config, data: Span, proof: Span) -> bool{ + + let mut merkle_tree: MerkleTree = MerkleTreeImpl::<_, PoseidonHasherImpl>::new(); + let leaf = core::poseidon::poseidon_hash_span(data); + MerkleTreeImpl::< + _, PoseidonHasherImpl + >::verify(ref merkle_tree, config.merkle_root, leaf, proof) +} \ No newline at end of file diff --git a/src/components/outer_city.cairo b/src/components/outer_city.cairo new file mode 100644 index 0000000..78cd451 --- /dev/null +++ b/src/components/outer_city.cairo @@ -0,0 +1,167 @@ +use starknet::ContractAddress; +use starknet::get_caller_address; +use super::city_building::CityBuilding; +use super::super::models::resource::{Resource, Wood, Brick, Steel, Food}; +use super::super::models::growth::{GrowthRate}; +use super::super::models::level::Level; +use core::Serde; + +#[starknet::interface] +trait OuterCityTrait { + fn get_minable_resource( + self: @TState, player: ContractAddress + ) -> (Resource, Resource, Resource, Resource); + fn get_last_mined_time(self: @TState, player: ContractAddress) -> u64; +} + +#[derive(Model, Copy, Drop, Serde)] +struct OuterCity { + #[key] + player: ContractAddress, + last_mined_time: u64 +} + +#[starknet::component] +mod outer_city_component { + use starknet::{get_caller_address, ContractAddress}; + use kingdom_lord::models::time::get_current_time; + use dojo::world::{ + IWorldProvider, IWorldProviderDispatcher, IWorldDispatcher, IWorldDispatcherTrait + }; + use super::{CityBuilding, Level}; + use super::{Resource, Wood, Brick, Steel, Food}; + use super::super::super::models::building::{Minable}; + use kingdom_lord::constants::{ + WOOD_BUILDING_START_INDEX, STEEL_BUILDING_START_INDEX, BRICK_BUILDING_START_INDEX, + FOOD_BUILDING_START_INDEX, WOOD_BUILDING_COUNT, BRICK_BUILDING_COUNT, + STEEL_BUILDING_COUNT, FOOD_BUILDING_COUNT + }; + use super::super::super::models::growth::Growth; + use super::{OuterCityTrait, OuterCity}; + use super::{GrowthRate}; + use kingdom_lord::helpers::array::{MinableArrayImpl, GrowthArrayImpl}; + + #[storage] + struct Storage {} + + + #[embeddable_as(OuterCityTraitImpl)] + impl OuterCityImpl< + TContractState, +HasComponent, +IWorldProvider + > of OuterCityTrait> { + fn get_minable_resource( + self: @ComponentState, player: ContractAddress + ) -> (Resource, Resource, Resource, Resource) { + let outer_city = get!(self.get_contract().world(), player, (OuterCity)); + let current_block_time = get_current_time(); + let wood: Resource = self + .get_wood_building(player) + .get_minable(outer_city.last_mined_time, current_block_time); + let brick: Resource = self + .get_brick_building(player) + .get_minable(outer_city.last_mined_time, current_block_time); + let steel: Resource = self + .get_steel_building(player) + .get_minable(outer_city.last_mined_time, current_block_time); + let food: Resource = self + .get_food_building(player) + .get_minable(outer_city.last_mined_time, current_block_time); + (wood, brick, steel, food) + } + + fn get_last_mined_time( + self: @ComponentState, player: ContractAddress + ) -> u64 { + get!(self.get_contract().world(), player, (OuterCity)).last_mined_time + } + } + + #[generate_trait] + impl OuterCityInternalImpl< + TContractState, +HasComponent, +IWorldProvider + > of OuterCityInternalTrait { + fn get_build_with_index_range( + self: @ComponentState, start: u64, count: u64, player: ContractAddress + ) -> Array { + let mut res = array![]; + let mut index = start; + let end_index = start + count; + loop { + if end_index == index { + break; + } + let building = get!(self.get_contract().world(), (player, index), (CityBuilding)); + res.append(building); + index += 1; + }; + res + } + + fn get_wood_building( + self: @ComponentState, player: ContractAddress + ) -> Array { + self.get_build_with_index_range(WOOD_BUILDING_START_INDEX, WOOD_BUILDING_COUNT, player) + } + + fn get_steel_building( + self: @ComponentState, player: ContractAddress + ) -> Array { + self.get_build_with_index_range(STEEL_BUILDING_START_INDEX, STEEL_BUILDING_COUNT, player) + } + + fn get_brick_building( + self: @ComponentState, player: ContractAddress + ) -> Array { + self.get_build_with_index_range(BRICK_BUILDING_START_INDEX, BRICK_BUILDING_COUNT, player) + } + + fn get_food_building( + self: @ComponentState, player: ContractAddress + ) -> Array { + self.get_build_with_index_range(FOOD_BUILDING_START_INDEX, FOOD_BUILDING_COUNT, player) + } + + fn get_growth_rate( + self: @ComponentState, player: ContractAddress, + ) -> (GrowthRate, GrowthRate, GrowthRate, GrowthRate) { + let outer_city = get!(self.get_contract().world(), player, (OuterCity)); + let wood_growth_rate: GrowthRate = self + .get_wood_building(player) + .get_growth_rate(); + let brick_growth_rate: GrowthRate = self + .get_brick_building(player) + .get_growth_rate(); + let steel_growth_rate: GrowthRate = self + .get_steel_building(player) + .get_growth_rate(); + let food_growth_rate: GrowthRate = self + .get_food_building(player) + .get_growth_rate(); + (wood_growth_rate, brick_growth_rate, steel_growth_rate, food_growth_rate) + } + + fn mine( + self: @ComponentState + ) -> (Resource, Resource, Resource, Resource) { + let world = self.get_contract().world(); + let caller = get_caller_address(); + let mut outer_city = get!(world, caller, (OuterCity)); + let current_block_time = get_current_time(); + let wood = self + .get_wood_building(caller) + .mine(outer_city.last_mined_time, current_block_time); + let brick = self + .get_brick_building(caller) + .mine(outer_city.last_mined_time, current_block_time); + let steel = self + .get_steel_building(caller) + .mine(outer_city.last_mined_time, current_block_time); + let food = self + .get_food_building(caller) + .mine(outer_city.last_mined_time, current_block_time); + outer_city.last_mined_time = current_block_time; + set!(world, (outer_city)); + (wood, brick, steel, food) + } + } +} diff --git a/src/components/universal.cairo b/src/components/universal.cairo new file mode 100644 index 0000000..4ea5040 --- /dev/null +++ b/src/components/universal.cairo @@ -0,0 +1,144 @@ +use kingdom_lord::models::building_kind::BuildingKind; +use starknet::ContractAddress; + +#[derive(Model, Copy, Drop, Serde)] +struct BuildingAreaInfo { + #[key] + player: ContractAddress, + #[key] + building_id: u64, + building_kind: u64, +} + + +#[starknet::component] +mod universal_component { + use starknet::{get_caller_address, ContractAddress}; + use dojo::world::{ + IWorldProvider, IWorldProviderDispatcher, IWorldDispatcher, IWorldDispatcherTrait + }; + use super::BuildingAreaInfo; + use kingdom_lord::constants::{CITY_HALL_START_INDEX, WAREHOUSE_START_INDEX, BARN_START_INDEX}; + use kingdom_lord::models::building::BuildingUpgradeInfo; + use kingdom_lord::models::building_kind::BuildingKind; + use kingdom_lord::components::city_hall::{CityHall}; + use kingdom_lord::components::city_building::{CityBuilding}; + use kingdom_lord::components::warehouse::{Warehouse}; + use kingdom_lord::components::barn::{Barn}; + use kingdom_lord::components::barrack::{Barrack, BarrackLevelTrait, BarrackGetLevel}; + use kingdom_lord::models::level::{LevelTrait, LevelUpTrait, Level, LevelExtentionTraitsImpl}; + + #[storage] + struct Storage {} + + + #[generate_trait] + impl UniversalInternalImpl< + TContractState, +HasComponent, +IWorldProvider + > of UniversalInternalTrait { + fn building_kind(self: @ComponentState, building_id: u64) -> BuildingKind { + let world = self.get_contract().world(); + let player = get_caller_address(); + let info: BuildingAreaInfo = get!(world, (player, building_id), (BuildingAreaInfo)); + info.building_kind.into() + } + + + fn is_next_level_valid( + self: @ComponentState, + building_id: u64, + building_kind: BuildingKind, + next_level: Level + ) -> bool { + let world = self.get_contract().world(); + let player = get_caller_address(); + match building_kind { + BuildingKind::None => panic!("None building could be found"), + BuildingKind::WoodBuilding => { + let city_building = get!(world, (player, building_id), (CityBuilding)); + return city_building.is_next_level_valid(next_level); + }, + BuildingKind::BrickBuilding => { + let city_building = get!(world, (player, building_id), (CityBuilding)); + return city_building.is_next_level_valid(next_level); + }, + BuildingKind::SteelBuilding => { + let city_building = get!(world, (player, building_id), (CityBuilding)); + return city_building.is_next_level_valid(next_level); + }, + BuildingKind::FoodBuilding => { + let city_building = get!(world, (player, building_id), (CityBuilding)); + return city_building.is_next_level_valid(next_level); + }, + BuildingKind::CityHall => { + let city_hall = get!(world, (player, building_id), (CityHall)); + return city_hall.is_next_level_valid(next_level); + }, + BuildingKind::Warehouse => { + let warehouse = get!(world, (player, building_id), (Warehouse)); + return warehouse.is_next_level_valid(next_level); + }, + BuildingKind::Barn => { + let barn = get!(world, (player, building_id), (Barn)); + return barn.is_next_level_valid(next_level); + }, + BuildingKind::Barrack => { + let barrack = get!(world, (player, building_id), (Barrack)); + return barrack.is_next_level_valid(next_level); + }, + } + } + + fn level_up(self: @ComponentState, building_id: u64, building_kind: BuildingKind, value: (u64, u64)) { + let world = self.get_contract().world(); + let player = get_caller_address(); + match building_kind { + BuildingKind::None => panic!("None building could be found"), + BuildingKind::WoodBuilding => { + let mut city_building = get!(world, (player, building_id), (CityBuilding)); + city_building.level_up(value); + set!(world, (city_building)); + }, + BuildingKind::BrickBuilding => { + let mut city_building = get!(world, (player, building_id), (CityBuilding)); + city_building.level_up(value); + set!(world, (city_building)); + }, + BuildingKind::SteelBuilding => { + let mut city_building = get!(world, (player, building_id), (CityBuilding)); + city_building.level_up(value); + set!(world, (city_building)); + }, + BuildingKind::FoodBuilding => { + let mut city_building = get!(world, (player, building_id), (CityBuilding)); + city_building.level_up(value); + set!(world, (city_building)); + }, + BuildingKind::CityHall => { + let mut city_hall = get!(world, (player, building_id), (CityHall)); + city_hall.level_up(value); + set!(world, (city_hall)); + }, + BuildingKind::Warehouse => { + let mut warehouse = get!(world, (player, building_id), (Warehouse)); + warehouse.level_up(value); + set!(world, (warehouse)); + }, + BuildingKind::Barn => { + let mut barn = get!(world, (player, building_id), (Barn)); + barn.level_up(value); + set!(world, (barn)); + }, + BuildingKind::Barrack => { + let mut barrack = get!(world, (player, building_id), (Barrack)); + barrack.level_up(value); + set!(world, (barrack)); + }, + } + } + + fn get_total_food_consume_rate(self: @ComponentState, player: ContractAddress){ + + } + } +} diff --git a/src/components/warehouse.cairo b/src/components/warehouse.cairo new file mode 100644 index 0000000..7103620 --- /dev/null +++ b/src/components/warehouse.cairo @@ -0,0 +1,114 @@ +use starknet::ContractAddress; +use kingdom_lord::models::resource::{Brick, Wood, Steel, Resource}; +use kingdom_lord::models::level::Level; +use kingdom_lord::models::building::{BuildingUpgradeResource}; +use kingdom_lord::models::level::{LevelTrait, LevelUpTrait}; + +#[derive(Model, Copy, Drop, Serde)] +struct Warehouse { + #[key] + player: ContractAddress, + #[key] + building_id: u64, + level: Level, + wood: Resource, + bricks: Resource, + steel: Resource, + max_storage: u64, + food_consume_rate: u64, +} + +#[generate_trait] +impl WarehouseExtensionImpl of WarehouseExtension{ + fn get_resource(self:@Warehouse) -> (Resource, Resource, Resource) { + (self.wood.clone(), self.bricks.clone(), self.steel.clone()) + } + + fn add_resource(ref self:Warehouse, wood: Resource, bricks: Resource, steel: Resource) { + let new_wood_amount = self.wood + wood; + if new_wood_amount.amount > self.max_storage { + self.wood = self.max_storage.into(); + } else { + self.wood = new_wood_amount; + } + let new_brick_amount = self.bricks + bricks; + if new_brick_amount > self.max_storage.into() { + self.bricks = self.max_storage.into(); + } else { + self.bricks = new_brick_amount; + } + let new_steel_amount = self.steel + steel; + if new_steel_amount > self.max_storage.into() { + self.steel = self.max_storage.into(); + } else { + self.steel = new_steel_amount; + } + } + + fn remove_resource(ref self: Warehouse, wood: Resource, bricks: Resource, steel: Resource) { + self.wood -= wood; + self.bricks -= bricks; + self.steel -= steel; + } +} + +impl WarehouseLeveTrait of LevelUpTrait{ + fn level_up(ref self: Warehouse, value: (u64, u64)){ + self.level.level_up(()); + let (max_storage, food_consume_rate) = value; + self.max_storage = max_storage; + self.food_consume_rate = food_consume_rate; + } +} + +impl WarehouseGetLevel of LevelTrait{ + fn get_level(self: @Warehouse) -> Level{ + self.level.get_level() + } +} + + +#[starknet::component] +mod warehouse_component{ + use starknet::{get_caller_address, ContractAddress}; + use dojo::world::{ + IWorldProvider, IWorldProviderDispatcher, IWorldDispatcher, IWorldDispatcherTrait + }; + use super::{Warehouse, Brick, Wood, Steel, Resource, WarehouseExtension}; + use kingdom_lord::constants::WAREHOUSE_START_INDEX; + + #[storage] + struct Storage {} + + #[generate_trait] + impl WarehouseInternalImpl< + TContractState, +HasComponent, +IWorldProvider + > of WarehouseInternalTrait { + fn add_resource(self:@ComponentState, wood: Resource, bricks: Resource, steel: Resource){ + let world = self.get_contract().world(); + let player = get_caller_address(); + let mut warehouse: Warehouse = get!(world, (player, WAREHOUSE_START_INDEX), (Warehouse)); + warehouse.add_resource(wood, bricks, steel); + set!(world, (warehouse)) + } + + fn remove_resource(self:@ComponentState, wood: Resource, bricks: Resource, steel: Resource){ + let world = self.get_contract().world(); + let player = get_caller_address(); + let mut warehouse: Warehouse = get!(world, (player, WAREHOUSE_START_INDEX), (Warehouse)); + warehouse.remove_resource(wood, bricks, steel); + set!(world, (warehouse)) + } + + fn get_resource(self:@ComponentState, player: ContractAddress) -> (Resource, Resource, Resource){ + let warehouse = get!(self.get_contract().world(), (player, WAREHOUSE_START_INDEX), (Warehouse)); + warehouse.get_resource() + } + + fn get_max_storage(self: @ComponentState, player: ContractAddress) -> u64{ + let warehouse = get!(self.get_contract().world(), (player, WAREHOUSE_START_INDEX), (Warehouse)); + warehouse.max_storage + } + } +} + diff --git a/src/constants.cairo b/src/constants.cairo new file mode 100644 index 0000000..5fbf636 --- /dev/null +++ b/src/constants.cairo @@ -0,0 +1,29 @@ +const WOOD_BUILDING_COUNT: u64 = 4; +const BRICK_BUILDING_COUNT: u64 = 4; +const STEEL_BUILDING_COUNT: u64 = 4; +const FOOD_BUILDING_COUNT:u64 = 6; +const CITY_HALL_COUNT:u64 = 1; +const WAREHOUSE_COUNT:u64 = 1; +const BARN_COUNT:u64 = 1; + +const WOOD_BUILDING_START_INDEX: u64 = 0; +const BRICK_BUILDING_START_INDEX: u64 = 4; +const STEEL_BUILDING_START_INDEX: u64 = 8; +const FOOD_BUILDING_START_INDEX: u64 = 12; +const CITY_HALL_START_INDEX:u64 = 18; +const WAREHOUSE_START_INDEX:u64 = 19; +const BARN_START_INDEX:u64 = 20; +const BARRACK_START_INDEX: u64 = 21; + +const BASE_GROW_RATE: u64 = 4; +// const WOOD_BASE_GROW_RATE:u64 = 10; +// const BRICK_BASE_GROW_RATE:u64 = 10; +// const STEEL_BASE_GROW_RATE:u64 = 10; +// const FOOD_BASE_GROW_RATE:u64 = 10; + +const INITIAL_MAX_STORAGE: u64 = 600; + +const UNDER_UPGRADING_COUNT: u64 = 6; +const UNDER_TRAINING_COUNT: u64 = 20; + +const CONFIG_ID: u64 = 1; diff --git a/src/events.cairo b/src/events.cairo new file mode 100644 index 0000000..3865524 --- /dev/null +++ b/src/events.cairo @@ -0,0 +1,86 @@ + +use starknet::ContractAddress; +use kingdom_lord::models::level::Level; + +#[derive(Drop, starknet::Event)] +struct NewPlayerSpawnEvent{ + #[key] + player: ContractAddress, + time: u64 +} + +#[derive(Drop, starknet::Event)] +struct StartUpgradeEvent{ + #[key] + player: ContractAddress, + #[key] + building_id: u64, + upgrade_id: u64, + level: Level, + start_time: u64, + end_time: u64 +} + +#[derive(Drop, starknet::Event)] +struct UpgradeNotEnoughResourceEvent{ + #[key] + player: ContractAddress, + #[key] + building_id: u64, +} + +#[derive(Drop, starknet::Event)] +struct UpgradeCompleteEvent{ + #[key] + player: ContractAddress, + upgrade_id: u64, + #[key] + building_id: u64, + level: Level +} + +#[derive(Drop, starknet::Event)] +struct UpgradeNotFinishedEvent{ + #[key] + player: ContractAddress, + #[key] + upgrade_id: u64, +} + +#[derive(Drop, starknet::Event)] +struct AlreadySpawnedEvent{ + #[key] + player: ContractAddress +} + + +#[derive(Drop, starknet::Event)] +struct PayToFinishedUpgradeEvent{ + #[key] + player: ContractAddress, + upgrade_id: u64, + #[key] + building_id: u64, + level: Level +} + + +#[derive(Drop, starknet::Event)] +struct StartTrainingEvent{ + #[key] + player: ContractAddress, + training_id: u64, + soldier_kind: u64, + start_time: u64, + end_time:u64 +} + + + +#[derive(Drop, starknet::Event)] +struct TrainingFinishedEvent{ + #[key] + player: ContractAddress, + training_id: u64, +} + diff --git a/src/helpers/array.cairo b/src/helpers/array.cairo new file mode 100644 index 0000000..f2a35de --- /dev/null +++ b/src/helpers/array.cairo @@ -0,0 +1,64 @@ +use core::serde::Serde; +use super::super::models::building::{Minable}; +use super::super::models::growth::{Growth, GrowthRate}; +use super::super::models::level::{Level}; +use super::super::models::resource::Resource; + +impl MinableArrayImpl>, +Drop> of Minable, Resource> { + fn get_minable( + self: @Array, last_time: u64, current_time: u64 + ) -> Resource { + let mut amount: Resource = 0_u64.into(); + let mut index = self.len() - 1; + loop { + amount += self.at(index).get_minable(last_time, current_time); + if index == 0 { + break; + } + index -= 1 + }; + amount + } + fn mine(self: @Array, last_time: u64, current_time: u64) -> Resource { + let mut amount: Resource = 0_u64.into(); + let mut index = self.len() - 1; + loop { + amount += self.at(index).mine(last_time, current_time); + if index == 0 { + break; + } + index -= 1 + }; + amount + } +} + +impl GrowthArrayImpl, +Drop, +Drop> of Growth, R> { + fn get_growth_rate(self: @Array) -> GrowthRate { + let mut amount: GrowthRate = 0_u64.into(); + let mut index = self.len() - 1; + loop { + amount += self.at(index).get_growth_rate(); + if index == 0 { + break; + } + index -= 1 + }; + amount + } +} + +// impl GetLevelArrayImpl> of GetLevel, Array> { +// fn get_level(self: @Array) -> Array { +// let mut res = array![]; +// let mut index = self.len() - 1; +// loop { +// res.append(self.at(index).get_level()); +// if index == 0 { +// break; +// } +// index -= 1 +// }; +// res +// } +// } diff --git a/src/helpers/contract_address.cairo b/src/helpers/contract_address.cairo new file mode 100644 index 0000000..6c641f3 --- /dev/null +++ b/src/helpers/contract_address.cairo @@ -0,0 +1,9 @@ +use core::fmt::{Debug, Formatter, Error}; +use starknet::ContractAddress; +impl FmtContractAddr of Debug{ + fn fmt(self: @ContractAddress, ref f: Formatter) -> Result<(), Error>{ + let felt: felt252 = self.clone().into(); + write!(f, "ContractAddress({:})", felt); + Result::Ok(()) + } +} diff --git a/src/interface.cairo b/src/interface.cairo new file mode 100644 index 0000000..a8cc229 --- /dev/null +++ b/src/interface.cairo @@ -0,0 +1,65 @@ +use kingdom_lord::models::building::BuildingUpgradeInfo; +use kingdom_lord::models::resource::{ Brick, Wood, Steel,Food, Resource}; +use kingdom_lord::models::growth::{GrowthRate}; +use kingdom_lord::models::level::Level; +use kingdom_lord::components::city_hall::city_hall_component::{UnderUpgrading}; +use kingdom_lord::components::barrack::{UnderTraining, Troops}; +use starknet::ContractAddress; + +#[derive(Debug, Serde, Drop, Copy, PartialEq)] +enum Error{ + ResourceNotEnough, + UpgradeNotFinished, + AlreadySpawned, + UpgradingListFull, + UnknownedError: felt252, + PayToUpgradeError, + InvalidProof, + TrainingNotFinished, + TrainingListFull, +} +#[starknet::interface] +trait IKingdomLord{ + // read function + fn get_resource(self: @TState, player: ContractAddress) -> (Resource, Resource, Resource, Resource); + fn get_growth_rate(self: @TState, player: ContractAddress) -> (GrowthRate, GrowthRate, GrowthRate, GrowthRate); + fn get_under_upgrading(self: @TState, player: ContractAddress) -> Array; + fn get_complete_upgrading(self: @TState, player: ContractAddress) -> Array; + fn get_buildings_levels(self: @TState, player: ContractAddress) -> Array; + fn get_under_training(self: @TState, player: ContractAddress) -> Array; + fn get_complete_training(self: @TState, player: ContractAddress) -> Array; + fn get_troops(self: @TState, player: ContractAddress) -> Troops; + fn get_food_consume_rate(self: @TState, player: ContractAddress) -> u64; + + // write function + fn spawn(ref self: TState) -> Result<(), Error>; + fn start_upgrade( + ref self: TState, + building_id: u64, + building_kind: u64, + next_level: u64, + req_wood: u64, + req_brick: u64, + req_steel: u64, + req_food: u64, + food_consume_rate: u64, + required_time: u64, + value: u64, + proof: Array + ) -> Result; + fn finish_upgrade(ref self: TState, upgrade_id: u64) -> Result; + fn start_training( + ref self: TState, + barrack_kind: u64, + ) -> Result; + fn finish_training(ref self: TState, training_id: u64) -> Result; + fn pay_to_finish_upgrade(ref self: TState, upgrade_id: u64) -> Result<(), Error>; +} + +#[starknet::interface] +trait IKingdomLordAdmin{ + fn set_config(self: @TState, erc20_addr: ContractAddress, amount: u256, receiver: ContractAddress, level_root_merkle: felt252) ; + fn set_barn_max_storage(self: @TState, addr: ContractAddress, max_storage: u64); + fn set_warehouse_max_storage(self: @TState, addr: ContractAddress, max_storage: u64); + +} \ No newline at end of file diff --git a/src/lib.cairo b/src/lib.cairo new file mode 100644 index 0000000..2d86295 --- /dev/null +++ b/src/lib.cairo @@ -0,0 +1,45 @@ +mod actions; +mod interface; +mod constants; +mod events; +mod admin; + +mod models { + mod resource; + mod building; + mod level; + mod growth; + mod time; + mod building_kind; +} + +mod components { + mod outer_city; + mod warehouse; + mod barn; + mod city_hall; + mod city_building; + mod universal; + mod config; + mod barrack; +} + +mod helpers { + mod array; + mod contract_address; +} + +mod tests { + mod test_spawn; + mod test_storage; + mod test_upgrade; + mod test_city_hall; + mod test_barrack; + mod test_pay_upgrade; + mod utils; +} + +mod merkle{ + mod merkle_tree; + mod merkle_tree_tests; +} \ No newline at end of file diff --git a/src/merkle/merkle_tree.cairo b/src/merkle/merkle_tree.cairo new file mode 100644 index 0000000..ba31fa6 --- /dev/null +++ b/src/merkle/merkle_tree.cairo @@ -0,0 +1,236 @@ +//! MerkleTree implementation. +//! +//! # Examples +//! +//! ``` +//! // This version uses the pedersen hash method because the PedersenHasherImpl is in the scope. +//! use alexandria_data_structures::merkle_tree::{Hasher, MerkleTree, pedersen::PedersenHasherImpl, MerkleTreeTrait}; +//! +//! // Create a new merkle tree instance. +//! let mut merkle_tree: MerkleTree = MerkleTreeTrait::new(); +//! let mut proof = array![element_1, element_2]; +//! // Compute the merkle root. +//! let root = merkle_tree.compute_root(leaf, proof); +//! ``` +//! +//! ``` +//! // This version uses the poseidon hash method because the PoseidonHasherImpl is in the scope. +//! use alexandria_data_structures::merkle_tree::{ Hasher, MerkleTree, poseidon::PoseidonHasherImpl, MerkleTreeTrait }; +//! +//! // Create a new merkle tree instance. +//! let mut merkle_tree: MerkleTree = MerkleTreeTrait::new(); +//! let mut proof = array![element_1, element_2]; +//! // Compute the merkle root. +//! let root = merkle_tree.compute_root(leaf, proof); +//! ``` + +/// Hasher trait. + +trait HasherTrait { + fn new() -> T; + fn hash(ref self: T, data1: felt252, data2: felt252) -> felt252; +} + + +// Hasher representations. + +#[derive(Drop, Copy)] +struct Hasher {} + +/// Hasher impls. + +mod pedersen { + use hash::HashStateTrait; + use super::{Hasher, HasherTrait}; + + impl PedersenHasherImpl of HasherTrait { + fn new() -> Hasher { + Hasher {} + } + fn hash(ref self: Hasher, data1: felt252, data2: felt252) -> felt252 { + pedersen::pedersen(data1, data2) + } + } +} + +mod poseidon { + use hash::HashStateTrait; + use poseidon::hades_permutation; + use super::{Hasher, HasherTrait}; + + impl PoseidonHasherImpl of HasherTrait { + fn new() -> Hasher { + Hasher {} + } + fn hash(ref self: Hasher, data1: felt252, data2: felt252) -> felt252 { + let (hash, _, _) = hades_permutation(data1, data2, 2); + hash + } + } +} + +/// MerkleTree representation. + +#[derive(Drop)] +struct MerkleTree { + hasher: T +} + +/// MerkleTree trait. +trait MerkleTreeTrait { + /// Create a new merkle tree instance. + fn new() -> MerkleTree; + /// Compute the merkle root of a given proof. + fn compute_root( + ref self: MerkleTree, current_node: felt252, proof: Span + ) -> felt252; + /// Verify a merkle proof. + fn verify(ref self: MerkleTree, root: felt252, leaf: felt252, proof: Span) -> bool; + /// Compute a merkle proof of given leaves and at a given index. + fn compute_proof(ref self: MerkleTree, leaves: Array, index: u32) -> Span; +} + +/// MerkleTree Legacy implementation. +impl MerkleTreeImpl, +Copy, +Drop> of MerkleTreeTrait { + /// Create a new merkle tree instance. + fn new() -> MerkleTree { + MerkleTree { hasher: HasherTrait::new() } + } + + /// Compute the merkle root of a given proof using the generic T hasher. + /// # Arguments + /// * `current_node` - The current node of the proof. + /// * `proof` - The proof. + /// # Returns + /// The merkle root. + fn compute_root( + ref self: MerkleTree, mut current_node: felt252, mut proof: Span + ) -> felt252 { + loop{ + let item = proof.pop_front(); + match item{ + Option::Some(proof_element) => { + current_node = + if Into::::into(current_node) < (*proof_element).into() { + self.hasher.hash(current_node, *proof_element) + } else { + self.hasher.hash(*proof_element, current_node) + } + }, + Option::None => {break;} + } + }; + + current_node + } + + /// Verify a merkle proof using the generic T hasher. + /// # Arguments + /// * `root` - The merkle root. + /// * `leaf` - The leaf to verify. + /// * `proof` - The proof. + /// # Returns + /// True if the proof is valid, false otherwise. + fn verify( + ref self: MerkleTree, root: felt252, mut leaf: felt252, mut proof: Span + ) -> bool { + loop{ + let item = proof.pop_front(); + match item{ + Option::Some(proof_element) => { + leaf = + if Into::::into(leaf) < (*proof_element).into() { + self.hasher.hash(leaf, *proof_element) + } else { + self.hasher.hash(*proof_element, leaf) + }; + }, + Option::None => {break;} + } + }; + leaf == root + } + + /// Compute a merkle proof of given leaves and at a given index using the generic T hasher. + /// # Arguments + /// * `leaves` - The sorted leaves. + /// * `index` - The index of the given. + /// # Returns + /// The merkle proof. + fn compute_proof( + ref self: MerkleTree, mut leaves: Array, index: u32 + ) -> Span { + let mut proof: Array = array![]; + compute_proof(leaves, self.hasher, index, ref proof); + proof.span() + } +} + +/// Helper function to compute a merkle proof of given leaves and at a given index. +/// # Arguments +/// * `nodes` - The sorted nodes. +/// * `index` - The index of the given. +/// * `hasher` - The hasher to use. +/// * `proof` - The proof array to fill. +fn compute_proof, +Drop>( + mut nodes: Array, mut hasher: T, index: u32, ref proof: Array +) { + // Break if we have reached the top of the tree + if nodes.len() == 1 { + return; + } + + // If odd number of nodes, add a null virtual leaf + if nodes.len() % 2 != 0 { + nodes.append(0); + } + + // Compute next level + let next_level: Array = get_next_level(nodes.span(), ref hasher); + + // Find neighbor node + let mut index_parent = 0; + let mut i = 0; + loop { + if i == index { + index_parent = i / 2; + if i % 2 == 0 { + proof.append(*nodes.at(i + 1)); + } else { + proof.append(*nodes.at(i - 1)); + } + break; + } + i += 1; + }; + + compute_proof(next_level, hasher, index_parent, ref proof) +} + +/// Helper function to compute the next layer of a merkle tree providing a layer of nodes. +/// # Arguments +/// * `nodes` - The sorted nodes. +/// * `hasher` - The hasher to use. +/// # Returns +/// The next layer of nodes. +fn get_next_level, +Drop>( + mut nodes: Span, ref hasher: T +) -> Array { + let mut next_level: Array = array![]; + loop{ + let item = nodes.pop_front(); + match item{ + Option::Some(left) => { + let right = *nodes.pop_front().expect('Index out of bounds'); + let node = if Into::::into(*left) < right.into() { + hasher.hash(*left, right) + } else { + hasher.hash(right, *left) + }; + next_level.append(node); + }, + Option::None => {break;} + } + }; + next_level +} diff --git a/src/merkle/merkle_tree_tests.cairo b/src/merkle/merkle_tree_tests.cairo new file mode 100644 index 0000000..8fbd0c9 --- /dev/null +++ b/src/merkle/merkle_tree_tests.cairo @@ -0,0 +1,157 @@ +// Internal imports +use super::merkle_tree::{ + Hasher, MerkleTree, pedersen::PedersenHasherImpl, poseidon::PoseidonHasherImpl, MerkleTreeTrait, + MerkleTreeImpl +}; +use core::fmt::{Debug, Formatter, Error}; +impl FmtArrayFelt252 of Debug>{ + fn fmt(self: @Span, ref f: Formatter) -> Result<(), Error>{ + Result::Ok(()) + } +} + + +mod regular_call_merkle_tree_pedersen { + // Internal imports + use super::{ + Hasher, MerkleTree, PedersenHasherImpl, MerkleTreeTrait,FmtArrayFelt252 + }; + #[test] + #[available_gas(2000000)] + fn regular_call_merkle_tree_pedersen_test() { + // [Setup] Merkle tree. + let mut merkle_tree: MerkleTree = MerkleTreeTrait::new(); + let root = 0x15ac9e457789ef0c56e5d559809e7336a909c14ee2511503fa7af69be1ba639; + let leaf = 0x1; + let valid_proof = array![ + 0x2, 0x68ba2a188dd231112c1cb5aaa5d18be6d84f6c8683e5c3a6638dee83e727acc + ] + .span(); + let leaves = array![0x1, 0x2, 0x3]; + + // [Assert] Compute merkle root. + let computed_root = merkle_tree.compute_root(leaf, valid_proof); + assert_eq!(computed_root, root, "compute valid root failed"); + + // [Assert] Compute merkle proof. + let mut input_leaves = leaves; + let index = 0; + let computed_proof = merkle_tree.compute_proof(input_leaves, index); + assert_eq!(computed_proof, valid_proof, "compute valid proof failed"); + + // [Assert] Verify a valid proof. + let result = merkle_tree.verify(root, leaf, valid_proof); + assert!(result, "verify valid proof failed"); + + // [Assert] Verify an invalid proof. + let invalid_proof = array![ + 0x2 + 1, 0x68ba2a188dd231112c1cb5aaa5d18be6d84f6c8683e5c3a6638dee83e727acc + ] + .span(); + let result = merkle_tree.verify(root, leaf, invalid_proof); + assert!(!result, "verify invalid proof failed"); + + // [Assert] Verify a valid proof with an invalid leaf. + let invalid_leaf = 0x1 + 1; + let result = merkle_tree.verify(root, invalid_leaf, valid_proof); + assert!(!result, "wrong result"); + } +} + +#[test] +#[available_gas(2000000)] +fn merkle_tree_pedersen_test() { + // [Setup] Merkle tree. + let mut merkle_tree: MerkleTree = MerkleTreeImpl::<_, PedersenHasherImpl>::new(); + let root = 0x15ac9e457789ef0c56e5d559809e7336a909c14ee2511503fa7af69be1ba639; + let leaf = 0x1; + let valid_proof = array![0x2, 0x68ba2a188dd231112c1cb5aaa5d18be6d84f6c8683e5c3a6638dee83e727acc] + .span(); + let leaves = array![0x1, 0x2, 0x3]; + + // [Assert] Compute merkle root. + let computed_root = MerkleTreeImpl::< + _, PedersenHasherImpl + >::compute_root(ref merkle_tree, leaf, valid_proof); + assert_eq!(computed_root, root, "compute valid root failed"); + + // [Assert] Compute merkle proof. + let mut input_leaves = leaves; + let index = 0; + let computed_proof = MerkleTreeImpl::< + _, PedersenHasherImpl + >::compute_proof(ref merkle_tree, input_leaves, index); + assert_eq!(computed_proof, valid_proof, "compute valid proof failed"); + + // [Assert] Verify a valid proof. + let result = MerkleTreeImpl::< + _, PedersenHasherImpl + >::verify(ref merkle_tree, root, leaf, valid_proof); + assert!(result, "verify valid proof failed"); + + // [Assert] Verify an invalid proof. + let invalid_proof = array![ + 0x2 + 1, 0x68ba2a188dd231112c1cb5aaa5d18be6d84f6c8683e5c3a6638dee83e727acc + ] + .span(); + let result = MerkleTreeImpl::< + _, PedersenHasherImpl + >::verify(ref merkle_tree, root, leaf, invalid_proof); + assert!(!result, "verify invalid proof failed"); + + // [Assert] Verify a valid proof with an invalid leaf. + let invalid_leaf = 0x1 + 1; + let result = MerkleTreeImpl::< + _, PedersenHasherImpl + >::verify(ref merkle_tree, root, invalid_leaf, valid_proof); + assert!(!result, "wrong result"); +} + +#[test] +#[available_gas(50000000000)] +fn merkle_tree_poseidon_test() { + // [Setup] Merkle tree. + let mut merkle_tree: MerkleTree = MerkleTreeImpl::<_, PoseidonHasherImpl>::new(); + let root = 0x48924a3b2a7a7b7cc1c9371357e95e322899880a6534bdfe24e96a828b9d780; + let leaf = 0x1; + let valid_proof = array![0x2, 0x338eb608d7e48306d01f5a8d4275dd85a52ba79aaf7a1a7b35808ba573c3669] + .span(); + let leaves = array![0x1, 0x2, 0x3]; + + // [Assert] Compute merkle root. + let computed_root = MerkleTreeImpl::< + _, PoseidonHasherImpl + >::compute_root(ref merkle_tree, leaf, valid_proof); + assert_eq!(computed_root, root, "compute valid root failed"); + + // [Assert] Compute merkle proof. + let mut input_leaves = leaves; + let index = 0; + let computed_proof = MerkleTreeImpl::< + _, PoseidonHasherImpl + >::compute_proof(ref merkle_tree, input_leaves, index); + assert_eq!(computed_proof, valid_proof, "compute valid proof failed"); + + // [Assert] Verify a valid proof. + let result = MerkleTreeImpl::< + _, PoseidonHasherImpl + >::verify(ref merkle_tree, root, leaf, valid_proof); + assert!(result, "verify valid proof failed"); + + // [Assert] Verify an invalid proof. + let invalid_proof = array![ + 0x2 + 1, 0x68ba2a188dd231112c1cb5aaa5d18be6d84f6c8683e5c3a6638dee83e727acc + ] + .span(); + let result = MerkleTreeImpl::< + _, PoseidonHasherImpl + >::verify(ref merkle_tree, root, leaf, invalid_proof); + assert!(!result, "verify invalid proof failed"); + + // [Assert] Verify a valid proof with an invalid leaf. + let invalid_leaf = 0x1 + 1; + let result = MerkleTreeImpl::< + _, PoseidonHasherImpl + >::verify(ref merkle_tree, root, invalid_leaf, valid_proof); + assert!(!result, "wrong result"); +} diff --git a/src/models/building.cairo b/src/models/building.cairo new file mode 100644 index 0000000..5a4d59c --- /dev/null +++ b/src/models/building.cairo @@ -0,0 +1,28 @@ +use core::clone::Clone; +use starknet::ContractAddress; +use super::level::Level; +use super::resource::{Resource, Wood, Brick, Steel, Food}; +use super::growth::{Growth, GrowthRate}; +use kingdom_lord::constants::BASE_GROW_RATE; + +trait Minable { + fn get_minable(self: @T, last_time: u64, current_time: u64) -> R; + fn mine(self: @T, last_time: u64, current_time: u64) -> R; +} + + +#[derive(Drop, Introspect, Copy, Serde, Default)] +struct BuildingUpgradeResource { + wood: Resource, + brick: Resource, + steel: Resource, + food: Resource, +} + +#[derive(Drop, Introspect, Copy, Serde, Default)] +struct BuildingUpgradeInfo { + required_resource: BuildingUpgradeResource, + required_time: u64, + next_level: Level, + building_id: u64, +} diff --git a/src/models/building_kind.cairo b/src/models/building_kind.cairo new file mode 100644 index 0000000..51e852c --- /dev/null +++ b/src/models/building_kind.cairo @@ -0,0 +1,46 @@ +#[derive(Drop, Copy, Serde, Hash, Debug, PartialEq)] +enum BuildingKind { + None, + WoodBuilding, + BrickBuilding, + SteelBuilding, + FoodBuilding, + CityHall, + Warehouse, + Barn, + Barrack +} + +impl IntoBuildingKind of Into { + fn into(self: u64) -> BuildingKind { + let self:felt252 = self.into(); + match self{ + 0 => BuildingKind::None, + 1 => BuildingKind::WoodBuilding, + 2 => BuildingKind::BrickBuilding, + 3 => BuildingKind::SteelBuilding, + 4 => BuildingKind::FoodBuilding, + 5 => BuildingKind::CityHall, + 6 => BuildingKind::Warehouse, + 7 => BuildingKind::Barn, + 8 => BuildingKind::Barrack, + _ => panic!("Invalid building id") + } + } +} + +impl BuildingKindIntou64 of Into { + fn into(self: BuildingKind) -> u64 { + match self { + BuildingKind::None => 0, + BuildingKind::WoodBuilding => 1, + BuildingKind::BrickBuilding => 2, + BuildingKind::SteelBuilding => 3, + BuildingKind::FoodBuilding => 4, + BuildingKind::CityHall => 5, + BuildingKind::Warehouse => 6, + BuildingKind::Barn => 7, + BuildingKind::Barrack => 8, + } + } +} diff --git a/src/models/growth.cairo b/src/models/growth.cairo new file mode 100644 index 0000000..deebb75 --- /dev/null +++ b/src/models/growth.cairo @@ -0,0 +1,40 @@ +use super::resource::{Wood, Brick, Steel, Food}; +use core::traits::{Add, Into}; + +trait Growth { + fn get_growth_rate(self: @T) -> GrowthRate; +} + +#[derive(Copy, Drop, Serde, PartialEq, Debug)] +struct GrowthRate { + amount: u64 +} + +impl LevelInto of Into> { + fn into(self: u64) -> GrowthRate { + GrowthRate { amount: self } + } +} + +impl GrowthRateIntou64 of Into, u64> { + fn into(self: GrowthRate) -> u64 { + self.amount + } +} + +impl GrowthRateAdd of Add> { + fn add(lhs: GrowthRate, rhs: GrowthRate) -> GrowthRate { + GrowthRate { amount: lhs.amount + rhs.amount } + } +} + +impl GrowthRateAddEq of AddEq> { + fn add_eq(ref self: GrowthRate, other: GrowthRate) { + self.amount += other.amount; + } +} + +type WoodGrowthRate = GrowthRate; +type BrickGrowthRate = GrowthRate; +type SteelGrowthRate = GrowthRate; +type FoodGrowthRate = GrowthRate; diff --git a/src/models/level.cairo b/src/models/level.cairo new file mode 100644 index 0000000..f4da73a --- /dev/null +++ b/src/models/level.cairo @@ -0,0 +1,48 @@ +#[derive(Drop, Serde, Introspect, Copy, Default, Debug, starknet::Store, PartialEq)] +struct Level{ + level: u64, +} + +trait LevelTrait{ + fn get_level(self: @T) -> Level; +} + +trait LevelUpTrait{ + fn level_up(ref self: T, value: V); +} + +trait LevelExtentionTraits{ + fn get_next_level(self: @T) -> Level; + fn is_next_level_valid(self: @T, target_next_level: Level) -> bool; +} + + + +impl LevelImpl of LevelTrait{ + fn get_level(self: @Level) -> Level{ + *self + } +} +impl LevelUpTraitImpl> of LevelUpTrait{ + fn level_up(ref self: Level, value: T){ + self.level +=1; + } + +} + +impl LevelExtentionTraitsImpl> of LevelExtentionTraits{ + fn is_next_level_valid(self: @T, target_next_level: Level) -> bool{ + self.get_next_level() == target_next_level + } + + fn get_next_level(self: @T) -> Level{ + Level { level: self.get_level().level + 1 } + } +} + +impl LevelInto of Into{ + fn into(self: u64) -> Level{ + Level{ level: self } + } +} + diff --git a/src/models/resource.cairo b/src/models/resource.cairo new file mode 100644 index 0000000..4164743 --- /dev/null +++ b/src/models/resource.cairo @@ -0,0 +1,85 @@ +#[derive(Drop, Introspect, Copy, Serde, Default)] +struct Resource{ + amount: u64 +} + +impl ResourceAdd of Add>{ + fn add(lhs: Resource, rhs: Resource) -> Resource { + Resource { amount: lhs.amount + rhs.amount } + } +} + +impl ResourceAddEq of AddEq>{ + fn add_eq(ref self: Resource, other: Resource) { + self.amount += other.amount; + } +} + +impl ResourceSub of Sub>{ + fn sub(lhs: Resource, rhs: Resource) -> Resource { + Resource { amount: lhs.amount - rhs.amount } + } +} + +impl ResourceSubEq of SubEq>{ + fn sub_eq(ref self: Resource, other: Resource) { + self.amount -= other.amount; + } +} + +impl ResourceFrom of Into>{ + fn into(self: u64) -> Resource { + Resource{ amount: self} + } +} + +impl ResourceInto of Into, u64>{ + fn into(self: Resource) -> u64 { + self.amount + } +} + +impl ResourcePartialEq of PartialEq>{ + fn eq(lhs: @Resource, rhs: @Resource) -> bool{ + lhs.amount == rhs.amount + } + fn ne(lhs: @Resource, rhs: @Resource) -> bool{ + !(lhs.amount == rhs.amount) + } +} +impl ResourcePartialOrd of PartialOrd>{ + fn le(lhs: Resource, rhs: Resource) -> bool{ + lhs.amount <= rhs.amount + } + fn ge(lhs: Resource, rhs: Resource) -> bool{ + lhs.amount >= rhs.amount + } + fn lt(lhs: Resource, rhs: Resource) -> bool{ + lhs.amount < rhs.amount + } + fn gt(lhs:Resource, rhs: Resource) -> bool{ + lhs.amount > rhs.amount + + } +} + + +#[derive(Drop, Introspect, Copy, Serde, Default, Debug)] +struct Steel{} +#[derive(Drop, Introspect, Copy, Serde, Default, Debug)] +struct Wood{} +#[derive(Drop, Introspect, Copy, Serde, Default, Debug)] +struct Food{} +#[derive(Drop, Introspect, Copy, Serde, Default, Debug)] +struct Brick{} + +trait Minable { + fn mine(growth_rate: u64, last_block_number:u64, current_block_number: u64) -> T; +} + +impl MinableImpl> of Minable{ + fn mine(growth_rate: u64, last_block_number:u64, current_block_number: u64) -> T{ + let amount = growth_rate * (current_block_number - last_block_number); + amount.into() + } +} \ No newline at end of file diff --git a/src/models/time.cairo b/src/models/time.cairo new file mode 100644 index 0000000..e301c41 --- /dev/null +++ b/src/models/time.cairo @@ -0,0 +1,4 @@ +use core::starknet::info::get_block_number; +fn get_current_time() -> u64{ + get_block_number() +} \ No newline at end of file diff --git a/src/tests/test_barrack.cairo b/src/tests/test_barrack.cairo new file mode 100644 index 0000000..36d15ad --- /dev/null +++ b/src/tests/test_barrack.cairo @@ -0,0 +1,57 @@ +#[cfg(test)] +mod tests { + use core::result::ResultTrait; + use kingdom_lord::interface::IKingdomLordDispatcherTrait; + use starknet::class_hash::Felt252TryIntoClassHash; + use starknet::get_caller_address; + use starknet::testing::{set_caller_address, set_block_number, set_block_timestamp}; + + // import world dispatcher + use dojo::world::{IWorldDispatcher, IWorldDispatcherTrait}; + + // import test utils + use dojo::test_utils::{spawn_test_world, deploy_contract}; + use kingdom_lord::tests::utils::{setup_world, assert_troop, city_hall_level2_proof, city_hall_level3_proof, assert_resource}; + use kingdom_lord::interface::{ + IKingdomLord, IKingdomLordDispatcher, IKingdomLordLibraryDispatcherImpl, Error + }; + + #[test] + #[available_gas(300000000000)] + fn test_barrack() { + // deploy world with models + let context = setup_world(); + + context.kingdom_lord.spawn(); + let caller = get_caller_address(); + + let err = context + .kingdom_lord + .start_training(0) + .unwrap_err(); + assert(err == Error::ResourceNotEnough, 'not enough resource'); + set_block_number(50); + assert_resource(context, caller, 600,600,600,600); + let training_id1 = context.kingdom_lord.start_training(0).unwrap(); + assert_resource(context, caller, 480,500,450,570); + let training_id2 = context.kingdom_lord.start_training(0).unwrap(); + assert_resource(context, caller, 360,400,300,540); + let training_id3 = context.kingdom_lord.start_training(1).unwrap(); + assert_resource(context, caller, 260,270,140,470); + + set_block_number(100); + let err = context.kingdom_lord.finish_training(training_id1).unwrap_err(); + assert_eq!(err, Error::TrainingNotFinished, "training not finished"); + set_block_number(1650); + context.kingdom_lord.finish_training(training_id1).unwrap(); + assert_troop(context, caller, 1,0,0,0,0,0); + + context.kingdom_lord.finish_training(training_id2).unwrap(); + assert_troop(context, caller, 2,0,0,0,0,0); + let err = context.kingdom_lord.finish_training(training_id3).unwrap_err(); + assert_eq!(err, Error::TrainingNotFinished, "training not finished"); + set_block_number(1810); + let res = context.kingdom_lord.finish_training(training_id3).unwrap(); + assert_troop(context, caller, 2,1,0,0,0,0); + } +} diff --git a/src/tests/test_city_hall.cairo b/src/tests/test_city_hall.cairo new file mode 100644 index 0000000..8de8918 --- /dev/null +++ b/src/tests/test_city_hall.cairo @@ -0,0 +1,61 @@ +#[cfg(test)] +mod tests { + use core::result::ResultTrait; + use kingdom_lord::interface::IKingdomLordDispatcherTrait; + use starknet::class_hash::Felt252TryIntoClassHash; + use starknet::get_caller_address; + use starknet::testing::{set_caller_address, set_block_number, set_block_timestamp}; + + // import world dispatcher + use dojo::world::{IWorldDispatcher, IWorldDispatcherTrait}; + + // import test utils + use dojo::test_utils::{spawn_test_world, deploy_contract}; + use kingdom_lord::tests::utils::{setup_world, city_hall_level2_proof, city_hall_level3_proof}; + use kingdom_lord::interface::{ + IKingdomLord, IKingdomLordDispatcher, IKingdomLordLibraryDispatcherImpl, Error + }; + + #[test] + #[available_gas(300000000000)] + fn test_city_hall() { + // deploy world with models + let context = setup_world(); + + context.kingdom_lord.spawn(); + let caller = get_caller_address(); + + let err = context + .kingdom_lord + .start_upgrade(18, 5, 2, 90, 50, 75, 25, 1, 2620, 104, city_hall_level2_proof()) + .unwrap_err(); + assert(err == Error::ResourceNotEnough, 'not enough resource'); + set_block_number(50); + + let res = context + .kingdom_lord + .start_upgrade(18, 5, 2, 90, 50, 75, 25, 1, 2620, 104, city_hall_level2_proof()); + let upgrade_id = res.unwrap(); + assert(upgrade_id == 0, 'first upgrade id is 0'); + + set_block_number(2670); + + let finishe_upgrade = context.kingdom_lord.get_complete_upgrading(caller); + assert(finishe_upgrade.len() == 1, 'finished should be 1'); + + let upgrade = finishe_upgrade.at(0); + assert(*upgrade.upgrade_id == 0, 'upgrade id should be 0'); + // city hall should be level up + context.kingdom_lord.finish_upgrade(0_u64).unwrap(); + + let res = context + .kingdom_lord + .start_upgrade(18, 5, 3, 115, 65, 100, 35, 1, 3220, 108, city_hall_level3_proof()); + let under_upgrade = context.kingdom_lord.get_under_upgrading(caller); + + let upgrade = under_upgrade.at(0); + // 3220 - 3220 * 104 /10000 + 2670 + // let compute: u64 = 3220_u64 - 3220_u64 * 104_u64 /10000_u64 + 2670_u64; + assert(*upgrade.end_time == 5857, 'end block should be 5857'); + } +} diff --git a/src/tests/test_food_consume.cairo b/src/tests/test_food_consume.cairo new file mode 100644 index 0000000..e69de29 diff --git a/src/tests/test_pay_upgrade.cairo b/src/tests/test_pay_upgrade.cairo new file mode 100644 index 0000000..c3c8ab5 --- /dev/null +++ b/src/tests/test_pay_upgrade.cairo @@ -0,0 +1,103 @@ +#[cfg(test)] +mod tests { + use core::result::ResultTrait; + use kingdom_lord::interface::IKingdomLordDispatcherTrait; + use starknet::class_hash::Felt252TryIntoClassHash; + use starknet::get_caller_address; + use starknet::testing::{set_caller_address, set_block_number, set_block_timestamp, set_contract_address}; + use kingdom_lord::helpers::contract_address::FmtContractAddr; + // import world dispatcher + use dojo::world::{IWorldDispatcher, IWorldDispatcherTrait}; + + // import test utils + use dojo::test_utils::{spawn_test_world, deploy_contract}; + use kingdom_lord::tests::utils::{setup_world, OWNER, PLAYER, wood_level_1_proof}; + use kingdom_lord::interface::{IKingdomLord, IKingdomLordDispatcher, IKingdomLordLibraryDispatcherImpl, Error}; + use kingdom_lord::components::city_hall::UnderUpgrading; + use openzeppelin::token::erc20::interface::IERC20DispatcherImpl; + + #[test] + #[available_gas(300000000000)] + fn test_pay_to_upgrade() { + // deploy world with models + let context = setup_world(); + let owner = OWNER(); + let player = PLAYER(); + set_contract_address(owner); + + let res = context.erc20_dispatcher.transfer(player, 2000); + + set_contract_address(player); + set_caller_address(player); + + context.erc20_dispatcher.approve(context.kingdom_lord.contract_address, 200_u256); + context.kingdom_lord.spawn(); + let caller = get_caller_address(); + + let err = context.kingdom_lord.start_upgrade(0, 1, 1, 40, 100, 50, 60, 2, 260, 7, wood_level_1_proof()).unwrap_err(); + assert(err == Error::ResourceNotEnough, 'not enough resource'); + set_block_number(25); + let res = context.kingdom_lord.start_upgrade(0, 1, 1, 40, 100, 50, 60, 2, 260, 7, wood_level_1_proof()); + let upgrade_id = res.unwrap(); + assert(upgrade_id == 0, 'first upgrade id is 0'); + + set_block_number(29); + let under_upgrade = context.kingdom_lord.get_under_upgrading(caller); + let upgrade = under_upgrade.at(0); + assert(under_upgrade.len() == 1, 'under_upgrade should be 1'); + assert(*upgrade.upgrade_id == 0, 'upgrade id should be 0'); + assert(*upgrade.start_time == 25, 'end block should be 25'); + assert(*upgrade.end_time == 285, 'end block should be 285'); + let finishe_upgrade = context.kingdom_lord.get_complete_upgrading(caller); + assert(finishe_upgrade.len() == 0, 'finished should be 0'); + + context.kingdom_lord.pay_to_finish_upgrade(0_u64).unwrap(); + + let under_upgrade = context.kingdom_lord.get_under_upgrading(caller); + assert(under_upgrade.len() == 0, 'under_upgrade should be 0 '); + let finishe_upgrade = context.kingdom_lord.get_complete_upgrading(caller); + assert(finishe_upgrade.len() == 0, 'finished should be 0'); + + let levels = context.kingdom_lord.get_buildings_levels(caller); + assert(*levels.at(0) == 0_u64.into(), '1 should be 1'); + + + + } + + + #[test] + #[available_gas(300000000000)] + #[should_panic(expected: ('u256_sub Overflow', 'ENTRYPOINT_FAILED', 'ENTRYPOINT_FAILED'))] + fn test_pay_to_upgrade_not_enough() { + // deploy world with models + let context = setup_world(); + let owner = OWNER(); + let player = PLAYER(); + + set_caller_address(player); + set_contract_address(player); + context.kingdom_lord.spawn(); + + let err = context.kingdom_lord.start_upgrade(0, 1, 1, 40, 100, 50, 60, 2, 260, 7, wood_level_1_proof()).unwrap_err(); + assert(err == Error::ResourceNotEnough, 'not enough resource'); + set_block_number(25); + let res = context.kingdom_lord.start_upgrade(0, 1, 1, 40, 100, 50, 60, 2, 260, 7, wood_level_1_proof()); + let upgrade_id = res.unwrap(); + assert(upgrade_id == 0, 'first upgrade id is 0'); + + set_block_number(29); + let under_upgrade = context.kingdom_lord.get_under_upgrading(player); + assert(under_upgrade.len() == 1, 'under_upgrade should be 1'); + + let upgrade = under_upgrade.at(0); + assert(*upgrade.upgrade_id == 0, 'upgrade id should be 0'); + assert(*upgrade.start_time == 25, 'end block should be 25'); + assert(*upgrade.end_time == 285, 'end block should be 285'); + + let finishe_upgrade = context.kingdom_lord.get_complete_upgrading(player); + assert(finishe_upgrade.len() == 0, 'finished should be 0'); + context.kingdom_lord.pay_to_finish_upgrade(0_u64); + + } +} diff --git a/src/tests/test_spawn.cairo b/src/tests/test_spawn.cairo new file mode 100644 index 0000000..1fdf786 --- /dev/null +++ b/src/tests/test_spawn.cairo @@ -0,0 +1,73 @@ +#[cfg(test)] +mod tests { + use kingdom_lord::interface::{IKingdomLordDispatcherTrait, Error}; + use starknet::class_hash::Felt252TryIntoClassHash; + use starknet::get_caller_address; + use starknet::testing::{set_caller_address, set_block_number}; + + // import world dispatcher + use dojo::world::{IWorldDispatcher, IWorldDispatcherTrait}; + + // import test utils + use dojo::test_utils::{spawn_test_world, deploy_contract}; + use kingdom_lord::tests::utils::{setup_world, assert_resource}; + use kingdom_lord::interface::{IKingdomLord, IKingdomLordDispatcher, IKingdomLordLibraryDispatcherImpl}; + + #[test] + #[available_gas(300000000000)] + fn test_spawn() { + // deploy world with models + let context = setup_world(); + let caller = get_caller_address(); + set_block_number(1_u64); + context.kingdom_lord.spawn(); + assert_resource(context, caller, 0, 0, 0, 0); + + // building levels 4446 + let levels = context.kingdom_lord.get_buildings_levels(caller); + assert(*levels.at(0) == 0_u64.into(), '0 should be 0'); + assert(*levels.at(1) == 0_u64.into(), '1 should be 0'); + assert(*levels.at(2) == 0_u64.into(), '2 should be 0'); + assert(*levels.at(3) == 0_u64.into(), '3 should be 0'); + assert(*levels.at(4) == 0_u64.into(), '4 should be 0'); + assert(*levels.at(5) == 0_u64.into(), '5 should be 0'); + assert(*levels.at(6) == 0_u64.into(), '6 should be 0'); + assert(*levels.at(7) == 0_u64.into(), '7 should be 0'); + assert(*levels.at(8) == 0_u64.into(), '8 should be 0'); + assert(*levels.at(9) == 0_u64.into(), '9 should be 0'); + assert(*levels.at(10) == 0_u64.into(), '10 should be 0'); + assert(*levels.at(11) == 0_u64.into(), '11 should be 0'); + assert(*levels.at(12) == 0_u64.into(), '12 should be 0'); + assert(*levels.at(13) == 0_u64.into(), '13 should be 0'); + assert(*levels.at(14) == 0_u64.into(), '14 should be 0'); + assert(*levels.at(15) == 0_u64.into(), '15 should be 0'); + assert(*levels.at(16) == 0_u64.into(), '16 should be 0'); + assert(*levels.at(17) == 0_u64.into(), '17 should be 0'); + + + let (wood_growth_rate, steel_growth_rate, brick_growth_rate, food_growth_rate) = context.kingdom_lord.get_growth_rate(caller); + assert(wood_growth_rate.into() == 16_u64, 'wood growth rate should be 16'); + assert(steel_growth_rate.into() == 16_u64, 'steel growth rate should be 16'); + assert(brick_growth_rate.into() == 16_u64, 'brick growth rate should be 16'); + assert(food_growth_rate.into() == 24_u64, 'food growth rate should be 24'); + + let under_upgrade = context.kingdom_lord.get_under_upgrading(caller); + assert(under_upgrade.len() == 0_u32, 'under_upgrade should be 0'); + + let complete_upgrade = context.kingdom_lord.get_complete_upgrading(caller); + assert(complete_upgrade.len() == 0_u32, 'complete_upgrade should be 0'); + + + } + + #[test] + fn test_dup_spawn() { + // deploy world with models + let context = setup_world(); + let caller = get_caller_address(); + context.kingdom_lord.spawn(); + + let res = context.kingdom_lord.spawn().unwrap_err(); + assert(res == Error::AlreadySpawned, 'dup spawned should be error') + } +} diff --git a/src/tests/test_storage.cairo b/src/tests/test_storage.cairo new file mode 100644 index 0000000..cc70d06 --- /dev/null +++ b/src/tests/test_storage.cairo @@ -0,0 +1,63 @@ +#[cfg(test)] +mod tests { + use core::result::ResultTrait; + use kingdom_lord::interface::IKingdomLordDispatcherTrait; + use starknet::class_hash::Felt252TryIntoClassHash; + use starknet::get_caller_address; + use starknet::testing::{set_caller_address, set_block_number, set_block_timestamp}; + + // import world dispatcher + use dojo::world::{IWorldDispatcher, IWorldDispatcherTrait}; + + // import test utils + use dojo::test_utils::{spawn_test_world, deploy_contract}; + use kingdom_lord::tests::utils::{setup_world, city_hall_level2_proof, assert_resource}; + use kingdom_lord::interface::{ + IKingdomLord, IKingdomLordDispatcher, IKingdomLordLibraryDispatcherImpl, Error + }; + + #[test] + #[available_gas(300000000000)] + fn test_storage() { + // deploy world with models + let context = setup_world(); + + context.kingdom_lord.spawn(); + let caller = get_caller_address(); + + assert_resource(context, caller, 0, 0, 0, 0); + + let err = context + .kingdom_lord + .start_upgrade(18, 5, 2, 90, 50, 75, 25, 1, 2620, 104, city_hall_level2_proof()) + .unwrap_err(); + assert(err == Error::ResourceNotEnough, 'not enough resource'); + set_block_number(1000); + assert_resource(context, caller, 600, 600, 600, 600); + } + + #[test] + #[available_gas(300000000000)] + fn test_upgrade_at_max_storage() { + // deploy world with models + let context = setup_world(); + + context.kingdom_lord.spawn(); + let caller = get_caller_address(); + + assert_resource(context, caller, 0, 0, 0, 0); + + let err = context + .kingdom_lord + .start_upgrade(18, 5, 2, 90, 50, 75, 25, 1, 2620, 104, city_hall_level2_proof()) + .unwrap_err(); + assert(err == Error::ResourceNotEnough, 'not enough resource'); + set_block_number(1000); + + let err = context + .kingdom_lord + .start_upgrade(18, 5, 2, 90, 50, 75, 25, 1, 2620, 104, city_hall_level2_proof()) + .unwrap(); + assert_resource(context, caller, 510, 550, 525, 575); + } +} diff --git a/src/tests/test_upgrade.cairo b/src/tests/test_upgrade.cairo new file mode 100644 index 0000000..f090bd9 --- /dev/null +++ b/src/tests/test_upgrade.cairo @@ -0,0 +1,85 @@ +#[cfg(test)] +mod tests { + use core::result::ResultTrait; + use kingdom_lord::interface::IKingdomLordDispatcherTrait; + use starknet::class_hash::Felt252TryIntoClassHash; + use starknet::get_caller_address; + use starknet::testing::{set_caller_address, set_block_number, set_block_timestamp}; + + // import world dispatcher + use dojo::world::{IWorldDispatcher, IWorldDispatcherTrait}; + + // import test utils + use dojo::test_utils::{spawn_test_world, deploy_contract}; + use kingdom_lord::tests::utils::{setup_world, wood_level_1_proof}; + use kingdom_lord::interface::{ + IKingdomLord, IKingdomLordDispatcher, IKingdomLordLibraryDispatcherImpl, Error + }; + + #[test] + #[available_gas(300000000000)] + fn test_upgrade() { + // deploy world with models + let context = setup_world(); + + context.kingdom_lord.spawn(); + let caller = get_caller_address(); + let err = context + .kingdom_lord + .start_upgrade(0, 1, 1, 40, 100, 50, 60, 2, 260, 7, wood_level_1_proof()) + .unwrap_err(); + assert(err == Error::ResourceNotEnough, 'not enough resource'); + set_block_number(25); + let res = context.kingdom_lord.start_upgrade(0, 1, 1, 40, 100, 50, 60, 2, 260, 7, wood_level_1_proof()); + let upgrade_id = res.unwrap(); + assert(upgrade_id == 0, 'first upgrade id is 0'); + + set_block_number(29); + let under_upgrade = context.kingdom_lord.get_under_upgrading(caller); + + let upgrade = under_upgrade.at(0); + assert(under_upgrade.len() == 1, 'under_upgrade should be 1'); + assert(*upgrade.upgrade_id == 0, 'upgrade id should be 0'); + assert(*upgrade.start_time == 25, 'end block should be 25'); + assert(*upgrade.end_time == 285, 'end block should be 285'); + + let finishe_upgrade = context.kingdom_lord.get_complete_upgrading(caller); + assert(finishe_upgrade.len() == 0, 'finished should be 0'); + + set_block_number(285); + + let finishe_upgrade = context.kingdom_lord.get_complete_upgrading(caller); + assert(finishe_upgrade.len() == 1, 'finished should be 1'); + + let upgrade = under_upgrade.at(0); + assert(*upgrade.upgrade_id == 0, 'upgrade id should be 0'); + context.kingdom_lord.finish_upgrade(0_u64).unwrap(); + + // double finish should failed + context.kingdom_lord.finish_upgrade(0_u64).unwrap_err(); + + let (wood_growth_rate, steel_growth_rate, brick_growth_rate, food_growth_rate) = context + .kingdom_lord + .get_growth_rate(caller); + let w:u64 = wood_growth_rate.into(); + assert(wood_growth_rate.into() == 19_u64, 'wood growth rate should be 19'); + let levels = context.kingdom_lord.get_buildings_levels(caller); + assert(*levels.at(0) == 1_u64.into(), '0 should be 1'); + } + + + #[test] + #[available_gas(300000000000)] + fn test_upgrade_invalid_proof() { + // deploy world with models + let context = setup_world(); + + context.kingdom_lord.spawn(); + let caller = get_caller_address(); + + set_block_number(25); + let res = context.kingdom_lord.start_upgrade(0, 1, 1, 40, 100, 50, 60, 2, 260, 7,array![0x1]); + let err = res.unwrap_err(); + assert(err == Error::InvalidProof, 'not enough resource'); + } +} diff --git a/src/tests/utils.cairo b/src/tests/utils.cairo new file mode 100644 index 0000000..af30e78 --- /dev/null +++ b/src/tests/utils.cairo @@ -0,0 +1,167 @@ +#[cfg(test)] +use dojo::test_utils::{spawn_test_world, deploy_contract}; +use kingdom_lord::components::barn::barn; +use starknet::ContractAddress; +use kingdom_lord::components::outer_city::outer_city; +use kingdom_lord::components::warehouse::warehouse; +use kingdom_lord::components::city_building::city_building; +use dojo::world::{IWorldDispatcher, IWorldDispatcherTrait}; +use kingdom_lord::actions::{kingdom_lord_controller}; +use kingdom_lord::interface::{ + IKingdomLordDispatcher, IKingdomLordAdminDispatcher, IKingdomLordAdmin, + IKingdomLordLibraryDispatcherImpl, IKingdomLordAdminDispatcherImpl, + IKingdomLordDispatcherTrait +}; + use openzeppelin::token::erc20::interface::IERC20DispatcherImpl; + use kingdom_lord::helpers::contract_address::FmtContractAddr; +use kingdom_lord::actions::kingdom_lord_controller::world_dispatcherContractMemberStateTrait; +use kingdom_lord::admin::kingdom_lord_admin; +use kingdom_lord::components::outer_city::OuterCityTraitDispatcher; +use starknet::contract_address_const; +use openzeppelin::presets::erc20::ERC20; +use openzeppelin::token::erc20::interface::IERC20Dispatcher; +trait SerializedAppend { + fn append_serde(ref self: Array, value: T); +} + +impl SerializedAppendImpl, impl TDrop: Drop> of SerializedAppend { + fn append_serde(ref self: Array, value: T) { + value.serialize(ref self); + } +} + +#[derive(Drop, Clone, Copy)] +struct TestContext { + world: IWorldDispatcher, + contract_address: ContractAddress, + kingdom_lord: IKingdomLordDispatcher, + kingdom_lord_admin: IKingdomLordAdminDispatcher, + erc20_dispatcher: IERC20Dispatcher, + erc20_address: ContractAddress +} + + +const NAME: felt252 = 'test'; +const SYNBOL: felt252 = 'test'; +const SUPPLY: u256 = 2000000; + +fn OWNER() -> ContractAddress { + contract_address_const::<'OWNER'>() +} + +fn PLAYER() -> ContractAddress { + contract_address_const::<'PLAYER'>() +} + +fn wood_level_1_proof() -> Array { + array![ + 0x5bd703a76bfe8b2261ff982e1896c88a6d6e2452bc696278f2a5c19f653e0c4, + 0xbbafcb4a5708030baa205ce47a23e2590c83d319fe625bdf662b99e510ab8c, + 0x7311928e7a8f9bcc86d715a6a7d4028f125daf5b5bf841de4ebdd288f6e4368, + 0x4bd1dbe10d1ef0faa8a2a9d79e269fccb754465edae46c66e440254d6a1e8ab, + 0x2ca45d555302aaf1dd30099b789063b0b293e9282c7cf0d50072a69e748e2e, + 0x58ea808ed1dd6d4eb8c2412089e406fd565973ae11f097a8ef1cd395484fff3, + 0x30a686f921ae094fb5747465a4390f70c1d521603c8a1da5799450feeb567fb, + 0x6f083eb9dc40b555e9f8c6ed4529c2c5bfd33087c0f80701992b254230a0c32 + ] +} + +fn city_hall_level2_proof() -> Array { + array![ + 0x56221680bf3d6661ba394e3c97541cd07fe77d832a713572201b3bee1604735, + 0x575978c19ae8821f17dcb09f2865515b661bb72486a758da18853b0208c5081, + 0x751fea1cdd1b21696ae357f83c2b96fbd0a7891b053cdc652807c88320c942c, + 0x352510f1269cea2ac10dab006a027dee2dcc6fc82676fbb5b862269d99528ee, + 0x660a74333a6082be847d98d1779c25ab498eaf93ea998125db323a1bc0c8cc7, + 0x53292aa62ac71f440a6c19786b359d3242844aed9effad78c0e7972ef409a1b, + 0x59dc966df9f4d4b5a02fa4d584ce7280cc0c8633e411a3f92f558abe1ecc464, + 0x6f083eb9dc40b555e9f8c6ed4529c2c5bfd33087c0f80701992b254230a0c32 + ] +} +fn city_hall_level3_proof() -> Array { + array![ + 0x7992d75be0dceda3f95c46f87060d97d2a9831d171cff7c2cd8e85fc3b15b4, + 0x261c187877e5bb8dab0505f0461fdd4f3020fc9aaee3a350bedf511a139be6a, + 0x751fea1cdd1b21696ae357f83c2b96fbd0a7891b053cdc652807c88320c942c, + 0x352510f1269cea2ac10dab006a027dee2dcc6fc82676fbb5b862269d99528ee, + 0x660a74333a6082be847d98d1779c25ab498eaf93ea998125db323a1bc0c8cc7, + 0x53292aa62ac71f440a6c19786b359d3242844aed9effad78c0e7972ef409a1b, + 0x59dc966df9f4d4b5a02fa4d584ce7280cc0c8633e411a3f92f558abe1ecc464, + 0x6f083eb9dc40b555e9f8c6ed4529c2c5bfd33087c0f80701992b254230a0c32 + ] +} + +fn assert_resource( + context: TestContext, player: ContractAddress, wood: u64, brick: u64, steel: u64, food: u64 +) { + let (actual_wood, actual_brick, actual_steel, actual_food) = context.kingdom_lord.get_resource(player); + let actual_wood: u64 = actual_wood.into(); + let actual_brick: u64 = actual_brick.into(); + let actual_steel: u64 = actual_steel.into(); + let actual_food: u64 = actual_food.into(); + assert_eq!(actual_wood, wood, "resource wood should be {} but got {}", wood, actual_wood); + assert_eq!(actual_brick, brick, "resource brick should be {} but got {}", brick, actual_brick); + assert_eq!(actual_steel, steel, "resource steel should be {} but got {}", steel, actual_steel); + assert_eq!(actual_food, food, "resource food should be {} but got {}", food, actual_food); +} + +fn assert_troop( + context: TestContext, player: ContractAddress, millitia: u64, guard: u64, heavy_infantry: u64, scouts: u64, knights: u64, heavy_knights: u64 +) { + let troop = context.kingdom_lord.get_troops(player); + assert_eq!(troop.millitia, millitia, "millititia should be {} but got {}", troop.millitia, millitia); + assert_eq!(troop.guard, guard, "guard should be {} but got {}", troop.guard, guard); + assert_eq!(troop.heavy_infantry, heavy_infantry, "heavy_infantry should be {} but got {}", troop.heavy_infantry, heavy_infantry); + assert_eq!(troop.scouts, scouts, "scouts should be {} but got {}", troop.scouts, scouts); + assert_eq!(troop.knights, knights, "knights should be {} but got {}", troop.knights, knights); + assert_eq!(troop.heavy_knights, heavy_knights, "heavy_knights should be {} but got {}", troop.heavy_knights, heavy_knights); +} + + +#[cfg(test)] +fn setup_world() -> TestContext { + let mut models = array![ + barn::TEST_CLASS_HASH, + warehouse::TEST_CLASS_HASH, + city_building::TEST_CLASS_HASH, + outer_city::TEST_CLASS_HASH + ]; + // deploy world with models + let world = spawn_test_world(models); + // deploy systems contract + let contract_address = world + .deploy_contract('salt1', kingdom_lord_controller::TEST_CLASS_HASH.try_into().unwrap()); + let admin_contract_address = world + .deploy_contract('salt2', kingdom_lord_admin::TEST_CLASS_HASH.try_into().unwrap()); + + // deploy erc20 contract + let mut calldata: Array = array![]; + let owner = OWNER(); + NAME.serialize(ref calldata); + SYNBOL.serialize(ref calldata); + SUPPLY.serialize(ref calldata); + owner.serialize(ref calldata); + let (erc20_contract_address, _) = starknet::deploy_syscall( + ERC20::TEST_CLASS_HASH.try_into().unwrap(), 0, calldata.span(), false + ) + .unwrap(); + + let admin_dispatcher = IKingdomLordAdminDispatcher { contract_address: admin_contract_address }; + let erc20_dispatcher = IERC20Dispatcher { contract_address: erc20_contract_address }; + + admin_dispatcher + .set_config( + erc20_contract_address, + 200_u256, + owner, + 0x2e3aa949c5d014218a1194b9d5c84c7457a027fc34826547b8dfe5b52d72220 + ); + TestContext { + world, + contract_address, + kingdom_lord: IKingdomLordDispatcher { contract_address }, + kingdom_lord_admin: admin_dispatcher, + erc20_dispatcher, + erc20_address: erc20_contract_address + } +} diff --git a/src/traits.cairo b/src/traits.cairo new file mode 100644 index 0000000..e69de29