diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..ee100cb --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,12 @@ +### Description + +> _Please explain the changes you made here_ + +### Checklist + +> _Please, make sure to comply with the checklist below before expecting review_ + +- [ ] Code compiles correctly +- [ ] Created tests which fail without the change (if possible) +- [ ] All tests passing +- [ ] Extended the README / documentation, if necessary diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..76974d5 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,36 @@ +name: CI + +on: + pull_request: + branches: + - '*' + push: + branches: + - 'main' + +jobs: + run-ci: + + name: Run Type Check & Linters + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: 3.10.8 + + - name: Set up Poetry + uses: abatilo/actions-poetry@v2.1.6 + with: + poetry-version: 1.1.13 + + - name: Install python dependencies + run: poetry install + + - uses: pre-commit/action@v3.0.0 + name: "Linters and formatters check" + with: + extra_args: --all-files --show-diff-on-failure diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..5f35867 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,36 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.1.0 + hooks: + - id: check-yaml + - id: end-of-file-fixer + - id: trailing-whitespace + + - repo: https://github.com/psf/black + rev: 22.6.0 + hooks: + - id: black + + - repo: https://github.com/pycqa/isort + rev: 5.10.1 + hooks: + - id: isort + args: ["--profile", "black"] + + - repo: https://github.com/myint/autoflake + rev: v1.4 + hooks: + - id: autoflake + args: + - --in-place + - --remove-unused-variables + - --remove-all-unused-imports + - --expand-star-imports + - --ignore-init-module-imports + + - repo: https://github.com/myint/eradicate + rev: v2.0.0 + hooks: + - id: eradicate + args: + - --in-place diff --git a/README.md b/README.md index c132742..3d27fab 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,10 @@ -``` - __ __ ___ __ __ - \*) \*) \*/ (*/ (*/ - \*\_\*\_|O|_/*/_/*/ - \_______________/ - _ __ _______ __ - / \ [ | |_ __ \ [ | - / _ \ | | .--./) .--. | |__) | .---. ,--. | | _ .--..--. - / ___ \ | | / /'`\;/ .'`\ \ | __ / / /__\\`'_\ : | | [ `.-. .-. | - _/ / \ \_ | | \ \._//| \__. |_| | \ \_| \__.,// | |, | | | | | | | | -|____| |____|[___].',__` '.__.'|____| |___|'.__.'\'-;__/[___][___||__||__] - ( ( __)) - by cusma -``` +

+ +

+ + + +

## Incipit @@ -39,19 +32,20 @@ Join [AlgoRealm channel](https://t.me/algorealm)! ## Play with AlgoRealm CLI -### 1. Setup -1. Download the [`algorealm.py`](https://github.com/cusma/algorealm/blob/main/algorealm.py) script -2. Install the following dependencies: +### 0. Prerequisites + +- [poetry](https://python-poetry.org/) +- [python >= 3.10](https://www.python.org/) + +### 1. Setup ```shell -$ pip3 install docopt --upgrade -$ pip3 install msgpack --upgrade -$ pip3 install py-algorand-sdk --upgrade +$ poetry install # install dependencies +$ poetry shell # activate virtual environment +$ cd src # cd into source directory, to be replaced with UI webapp in future ``` -3. Create an account on PureStake and [get your API token](https://developer.purestake.io/login) - ### 2. How to play Playing **AlgoRealm** from your CLI is pretty easy, just ask for help: @@ -65,13 +59,13 @@ AlgoRealm, only generous heart will ever rule over Algorand. (by cusma) Usage: algorealm.py poem - algorealm.py dynasty - algorealm.py verify-order - algorealm.py claim-crown - algorealm.py claim-sceptre - algorealm.py claim-card - algorealm.py buy-order [--notify] - algorealm.py sell-card + algorealm.py dynasty + algorealm.py verify-order + algorealm.py claim-crown + algorealm.py claim-sceptre + algorealm.py claim-card + algorealm.py buy-order [--notify] + algorealm.py sell-card algorealm.py [--help] Commands: @@ -104,24 +98,24 @@ $ ./goal app read --app-id 137491307 --global 3. Discover it with the AlgoRealm CLI: ```shell -$ python3 algorealm.py dynasty +$ python3 algorealm.py dynasty ``` ``` - __ __ ___ __ __ - \*) \*) \*/ (*/ (*/ - \*\_\*\_|O|_/*/_/*/ - \_______________/ - _ __ _______ __ - / \ [ | |_ __ \ [ | - / _ \ | | .--./) .--. | |__) | .---. ,--. | | _ .--..--. - / ___ \ | | / /'`\;/ .'`\ \ | __ / / /__\\`'_\ : | | [ `.-. .-. | - _/ / \ \_ | | \ \._//| \__. |_| | \ \_| \__.,// | |, | | | | | | | | + __ __ ___ __ __ + \*) \*) \*/ (*/ (*/ + \*\_\*\_|O|_/*/_/*/ + \_______________/ + _ __ _______ __ + / \ [ | |_ __ \ [ | + / _ \ | | .--./) .--. | |__) | .---. ,--. | | _ .--..--. + / ___ \ | | / /'`\;/ .'`\ \ | __ / / /__\\`'_\ : | | [ `.-. .-. | + _/ / \ \_ | | \ \._//| \__. |_| | \ \_| \__.,// | |, | | | | | | | | |____| |____|[___].',__` '.__.'|____| |___|'.__.'\'-;__/[___][___||__||__] - ( ( __)) - *** DYNASTY *** - - + ( ( __)) + *** DYNASTY *** + + šŸ‘‘ jkbishbish claimed the Crown of Entropy on Block: 13578171 donating: 2 microALGOs to the Rewards Pool. @@ -146,11 +140,11 @@ on Block: 14989913 donating: 4 microALGOs to the Rewards Pool. Chose your `` and become part of the Dynasty! Remember that to dethrone the current Majesties you must donate to the Algorand's Rewards Pool more `` than the last donation. ```shell -$ python3 algorealm.py claim-crown +$ python3 algorealm.py claim-crown ``` ```shell -$ python3 algorealm.py claim-sceptre +$ python3 algorealm.py claim-sceptre ``` āš ļø Enter the the `` formatting it as: `"word_1 word_2 word_3 ... word_25"` and keep it safe! @@ -168,7 +162,7 @@ Only the generous heart of the [Great Majesty of Algorand](https://github.com/cu The AlgoRealm Card can be claimed **starting from block 16,250,000** using the command `claim-card`: hold strong both the Crown and the Sceptre and keep the throne until there! ```shell -$ python3 algorealm.py claim-card +$ python3 algorealm.py claim-card ``` āš ļø Enter the the `` formatting it as: `"word_1 word_2 word_3 ... word_25"` and keep it safe! @@ -180,7 +174,7 @@ As a **Buyer** you can easily place a **buy-order** proposal to the **Seller** u Using the `--notify` option the **Seller** will receive a notification on-chain, being acknowledge about the new buy-order proposal. ```shell -$ python3 algorealm.py buy-order [--notify] +$ python3 algorealm.py buy-order [--notify] ``` āš ļø Enter the the `` formatting it as: `"word_1 word_2 word_3 ... word_25"` and keep it safe! @@ -194,21 +188,21 @@ As a **Seller** you can review and verify the buy-order proposal, validating the The `verify-order` command requires your `` as argument. ```shell -$ python3 algorealm.py verify-order +$ python3 algorealm.py verify-order ``` Some compliancy checks are performed over the `trade.gtx` file before displaying the buy-order summary: ```shell * =========================== ORDER SUMMARY =========================== * - + BUYER: SELLER: AMOUNT: 1.0 ALGO ROYALTY: 0.1 ALGO - + LAST VALID BLOCK: 13184621 - + * ===================================================================== * ``` @@ -219,7 +213,7 @@ If you agree with the buy-order proposal you can sell the AlgoRealm Special Card As a **Seller**, if you agree with the buy-order proposal, you can sell your AlgoRealm Special Card using the command `sell-card`. ```shell -$ python3 algorealm.py sell-card +$ python3 algorealm.py sell-card ``` āš ļø Enter the the `` formatting it as: `"word_1 word_2 word_3 ... word_25"` and keep it safe! @@ -360,3 +354,12 @@ If you enjoyed AlgoRealm or find it useful as free and open source learning exam Here you find the [AlgoRealm slide deck](https://docs.google.com/presentation/d/1pkE_VWuq_zPOtkc8tK8MYKPzdBwUQA8r5UgACpBpmvk/edit?usp=sharing) presented at Algorand's Office Hours! Join [AlgoRealm channel](https://t.me/algorealm)! + + +## ā­ļø Stargazers + +Special thanks to everyone who forked or starred the repository ā¤ļø + +[![Stargazers repo roster for @AlgoWorldNFT/algoworld-contracts](https://reporoster.com/stars/dark/cusma/algorealm)](https://github.com/cusma/algorealm/stargazers) + +[![Forkers repo roster for @AlgoWorldNFT/algoworld-contracts](https://reporoster.com/forks/dark/cusma/algorealm)](https://github.com/cusma/algorealm/network/members) diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 0000000..1ab4377 --- /dev/null +++ b/poetry.lock @@ -0,0 +1,167 @@ +[[package]] +name = "black" +version = "22.10.0" +description = "The uncompromising code formatter." +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +click = ">=8.0.0" +mypy-extensions = ">=0.4.3" +pathspec = ">=0.9.0" +platformdirs = ">=2" +tomli = {version = ">=1.1.0", markers = "python_full_version < \"3.11.0a7\""} + +[package.extras] +colorama = ["colorama (>=0.4.3)"] +d = ["aiohttp (>=3.7.4)"] +jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] +uvloop = ["uvloop (>=0.15.2)"] + +[[package]] +name = "cffi" +version = "1.15.1" +description = "Foreign Function Interface for Python calling C code." +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +pycparser = "*" + +[[package]] +name = "click" +version = "8.1.3" +description = "Composable command line interface toolkit" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +category = "dev" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" + +[[package]] +name = "docopt" +version = "0.6.2" +description = "Pythonic argument parser, that will make you smile" +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "msgpack" +version = "1.0.4" +description = "MessagePack serializer" +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "mypy-extensions" +version = "0.4.3" +description = "Experimental type system extensions for programs checked with the mypy typechecker." +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "pathspec" +version = "0.10.2" +description = "Utility library for gitignore style pattern matching of file paths." +category = "dev" +optional = false +python-versions = ">=3.7" + +[[package]] +name = "platformdirs" +version = "2.5.4" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.extras] +docs = ["furo (>=2022.9.29)", "proselint (>=0.13)", "sphinx-autodoc-typehints (>=1.19.4)", "sphinx (>=5.3)"] +test = ["appdirs (==1.4.4)", "pytest-cov (>=4)", "pytest-mock (>=3.10)", "pytest (>=7.2)"] + +[[package]] +name = "py-algorand-sdk" +version = "1.20.1" +description = "Algorand SDK in Python" +category = "main" +optional = false +python-versions = ">=3.8" + +[package.dependencies] +msgpack = ">=1.0.0,<2" +pycryptodomex = ">=3.6.0,<4" +pynacl = ">=1.4.0,<2" + +[[package]] +name = "pycparser" +version = "2.21" +description = "C parser in Python" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "pycryptodomex" +version = "3.16.0" +description = "Cryptographic library for Python" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "pynacl" +version = "1.5.0" +description = "Python binding to the Networking and Cryptography (NaCl) library" +category = "main" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +cffi = ">=1.4.1" + +[package.extras] +docs = ["sphinx (>=1.6.5)", "sphinx-rtd-theme"] +tests = ["pytest (>=3.2.1,!=3.3.0)", "hypothesis (>=3.27.0)"] + +[[package]] +name = "tomli" +version = "2.0.1" +description = "A lil' TOML parser" +category = "dev" +optional = false +python-versions = ">=3.7" + +[metadata] +lock-version = "1.1" +python-versions = "^3.10" +content-hash = "05926e82d4f7483312cd284ec6467857bdd935dbdd66ff52b5a3573867adae85" + +[metadata.files] +black = [] +cffi = [] +click = [] +colorama = [] +docopt = [] +msgpack = [] +mypy-extensions = [] +pathspec = [] +platformdirs = [] +py-algorand-sdk = [] +pycparser = [] +pycryptodomex = [] +pynacl = [] +tomli = [] diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..bbc29d2 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,19 @@ +[tool.poetry] +name = "algorealm-cli" +version = "0.2.0" +description = "An interactive game of randomness powered by Algorand blockchain (by cusma)" +authors = ["cosimo.bassi@algorand.com"] +license = "MIT" + +[tool.poetry.dependencies] +python = "^3.10" +docopt = "^0.6.2" +msgpack = "^1.0.4" +py-algorand-sdk = "^1.20.1" + +[tool.poetry.dev-dependencies] +black = "^22.10.0" + +[build-system] +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api" diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000..5d4107a --- /dev/null +++ b/renovate.json @@ -0,0 +1,28 @@ +{ + "extends": ["config:base"], + "semanticCommits": true, + "ignoreDeps": [], + "schedule": "before 3am on the first day of the month", + "assignees": ["cusma"], + "baseBranches": ["main"], + "separateMajorMinor": true, + "rebaseStalePrs": true, + "lockFileMaintenance": { + "enabled": true, + "extends": "schedule:monthly" + }, + "packageRules": [ + { + "matchPackagePatterns": ["*"], + "matchUpdateTypes": ["minor", "patch"], + "groupName": "all non-major dependencies", + "groupSlug": "all-minor-patch" + } + ], + "docker": { + "enabled": true + }, + "python": { + "enabled": false + } +} diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/algorealm.py b/src/algorealm.py similarity index 64% rename from algorealm.py rename to src/algorealm.py index aa00644..ab32fc1 100644 --- a/algorealm.py +++ b/src/algorealm.py @@ -3,13 +3,13 @@ Usage: algorealm.py poem - algorealm.py dynasty - algorealm.py verify-order - algorealm.py claim-crown - algorealm.py claim-sceptre - algorealm.py claim-card - algorealm.py buy-order [--notify] - algorealm.py sell-card + algorealm.py dynasty + algorealm.py verify-order + algorealm.py claim-crown + algorealm.py claim-sceptre + algorealm.py claim-card + algorealm.py buy-order [--notify] + algorealm.py sell-card algorealm.py [--help] Commands: @@ -27,20 +27,19 @@ -h --help """ +import base64 +import dataclasses import math import sys import time -import base64 -import msgpack import traceback -import dataclasses -from docopt import docopt - -from algosdk.v2client import algod, indexer +import msgpack +from algosdk import account, mnemonic, util from algosdk.error import AlgodHTTPError, IndexerHTTPError from algosdk.future import transaction -from algosdk import mnemonic, account, util +from algosdk.v2client import algod, indexer +from docopt import docopt @dataclasses.dataclass @@ -65,20 +64,21 @@ def create_account(cls): MAX_CONNECTION_ATTEMPTS = 10 CONNECTION_ATTEMPT_DELAY_SEC = 2 -INDEXER_ADDRESS = "https://mainnet-algorand.api.purestake.io/idx2" -ALGOD_ADDRESS = "https://mainnet-algorand.api.purestake.io/ps2" +INDEXER_ADDRESS = "https://mainnet-idx.algonode.cloud" +ALGOD_ADDRESS = "https://mainnet-api.algonode.cloud" -REWARDS_POOL = '737777777777777777777777777777777777777777777777777UFEJ2CI' +REWARDS_POOL = "737777777777777777777777777777777777777777777777777UFEJ2CI" ALGOREALM_FIRST_BLOCK = 13578170 ALGOREALM_APP_ID = 137491307 CROWN_ID = 137493252 SCEPTRE_ID = 137494385 -ALGOREALM_LAW_BYTECODE = \ - 'AiAIAwbr5sdBAQSE9sdB8f7HQegHJgEg/v////////////////////////////////////' \ - '////8yBCISMwAQIxIzABgkEhAQMwEQJRIzAQAzAAASEDMBBygSEBAzAhAhBBIzAhQzAQAS' \ - 'EDMCESEFEjMCESEGEhEQMwISJRIQMwIBIQcOEDMCFTIDEhAzAiAyAxIQEA==' +ALGOREALM_LAW_BYTECODE = ( + "AiAIAwbr5sdBAQSE9sdB8f7HQegHJgEg/v////////////////////////////////////" + "////8yBCISMwAQIxIzABgkEhAQMwEQJRIzAQAzAAASEDMBBygSEBAzAhAhBBIzAhQzAQAS" + "EDMCESEFEjMCESEGEhEQMwISJRIQMwIBIQcOEDMCFTIDEhAzAiAyAxIQEA==" +) ALGOREALM_LAW_LSIG = transaction.LogicSig( base64.decodebytes(ALGOREALM_LAW_BYTECODE.encode()) @@ -93,28 +93,27 @@ def create_account(cls): ALGOREALM_CARD_FIRST_BLOCK = 16250000 ROYALTY_PERC = 5 ROYALTY_COLLECTOR_1 = Account( - address='H7N65NZIWBOKFDSRNPLLDGN72HVFKXT4RRSY7M66B6Y2PFLQFKLPLHU5JU', - private_key='' + address="H7N65NZIWBOKFDSRNPLLDGN72HVFKXT4RRSY7M66B6Y2PFLQFKLPLHU5JU", private_key="" ) ROYALTY_COLLECTOR_2 = Account( - address='2PDM3E7WLVPMEKCCMNTHM3FCZNZM4CSJQUOC4SWHMFPAR3N4NXBLCQKHPE', - private_key='' + address="2PDM3E7WLVPMEKCCMNTHM3FCZNZM4CSJQUOC4SWHMFPAR3N4NXBLCQKHPE", private_key="" ) ASA_STATE_OBSERVER_APP_ID = 321230622 CARD_ID = 321172366 -CARD_CONTRACT_BYTECODE = \ - 'AyAOAQMGBOgHnq6WmQGE9sdB8f7HQQVkjueSmQGQ6d8HAM7i0wcmAwtBc2FBbW91bnRFcS' \ - 'A/2+63KLBcoo5Ra9axmb/R6lVefIxlj7PeD7GnlXAqliDTxs2T9l1ewihCY2Z2bKLLcs4K' \ - 'SYUcLkrHYV4I7bxtwjIEIhJAAaIyBCMSQAD4MgQkEkAAAQAzABAkEjMBECQSEDMCECISED' \ - 'MDECISEDMEECISEDMFECUSEDMFASEEDhAzBSAyAxIQMwUVMgMSEDMAGCEFEjcAGgAoEhA3' \ - 'ABwBMwAAEhA3ADAAIQYSEDcAGgEiFhIQEDMBGCEFEjcBGgAoEhA3ARwBMwEAEhA3ATAAIQ' \ - 'cSEDcBGgEiFhIQEDMAADMCBxIQMwEAMwIHEhAzAgAzBRQSEDMDADMCBxIQMwMHKRIQMwQA' \ - 'MwIHEhAzBAcqEhAzAwgzBAgSEDMDCDMCCCEICyEJCg8QMwURIQoSEDMFEiISEDMFEzMCBx' \ - 'IQMwUUMwIAEhBCANczABAkEjMBECQSEDMCECUSEDMCASEEDhAzAiAyAxIQMwIVMgMSEDMA' \ - 'GCEFEjcAGgAoEhA3ABwBMwAAEhA3ADAAIQYSEDcAGgEiFhIQEDMBGCEFEjcBGgAoEhA3AR' \ - 'wBMwEAEhA3ATAAIQcSEDcBGgEiFhIQEDMAADMCFBIQMwEAMwIUEhAzAgIhCw0QMwIRIQoS' \ - 'EDMCEiISEDMCADMCExIQQgA0MRAlEjEBIQQOEDETMgMSEDEVMgMSEDEgMgMSEDERIQoSED' \ - 'ESIQwSEDEAMRQSEDEEIQ0MEA==' +CARD_CONTRACT_BYTECODE = ( + "AyAOAQMGBOgHnq6WmQGE9sdB8f7HQQVkjueSmQGQ6d8HAM7i0wcmAwtBc2FBbW91bnRFcS" + "A/2+63KLBcoo5Ra9axmb/R6lVefIxlj7PeD7GnlXAqliDTxs2T9l1ewihCY2Z2bKLLcs4K" + "SYUcLkrHYV4I7bxtwjIEIhJAAaIyBCMSQAD4MgQkEkAAAQAzABAkEjMBECQSEDMCECISED" + "MDECISEDMEECISEDMFECUSEDMFASEEDhAzBSAyAxIQMwUVMgMSEDMAGCEFEjcAGgAoEhA3" + "ABwBMwAAEhA3ADAAIQYSEDcAGgEiFhIQEDMBGCEFEjcBGgAoEhA3ARwBMwEAEhA3ATAAIQ" + "cSEDcBGgEiFhIQEDMAADMCBxIQMwEAMwIHEhAzAgAzBRQSEDMDADMCBxIQMwMHKRIQMwQA" + "MwIHEhAzBAcqEhAzAwgzBAgSEDMDCDMCCCEICyEJCg8QMwURIQoSEDMFEiISEDMFEzMCBx" + "IQMwUUMwIAEhBCANczABAkEjMBECQSEDMCECUSEDMCASEEDhAzAiAyAxIQMwIVMgMSEDMA" + "GCEFEjcAGgAoEhA3ABwBMwAAEhA3ADAAIQYSEDcAGgEiFhIQEDMBGCEFEjcBGgAoEhA3AR" + "wBMwEAEhA3ATAAIQcSEDcBGgEiFhIQEDMAADMCFBIQMwEAMwIUEhAzAgIhCw0QMwIRIQoS" + "EDMCEiISEDMCADMCExIQQgA0MRAlEjEBIQQOEDETMgMSEDEVMgMSEDEgMgMSEDERIQoSED" + "ESIQwSEDEAMRQSEDEEIQ0MEA==" +) CARD_CONTRACT_LSIG = transaction.LogicSig( base64.decodebytes(CARD_CONTRACT_BYTECODE.encode()) @@ -141,8 +140,7 @@ def wait_for_confirmation(client: algod.AlgodClient, txid: str): client.status_after_block(last_round) txinfo = client.pending_transaction_info(txid) - print( - f"Transaction {txid} confirmed in round {txinfo.get('confirmed-round')}.") + print(f"Transaction {txid} confirmed in round {txinfo.get('confirmed-round')}.") return txinfo @@ -154,10 +152,7 @@ def sign(account: Account, txn: transaction.Transaction): return txn.sign(account.private_key) -def sign_send_wait( - algod_client: algod.AlgodClient, - account: Account, - txn): +def sign_send_wait(algod_client: algod.AlgodClient, account: Account, txn): """Sign a transaction, submit it, and wait for its confirmation.""" signed_txn = sign(account, txn) tx_id = signed_txn.transaction.get_txid() @@ -190,18 +185,15 @@ def search_algorelm_calls(indexer_client: indexer.IndexerClient): application_id=ALGOREALM_APP_ID, min_round=ALGOREALM_FIRST_BLOCK, ) - calls += result['transactions'] - numtx = len(result['transactions']) + calls += result["transactions"] + numtx = len(result["transactions"]) if numtx > 0: # pointer to the next chunk of requests - nexttoken = result['next-token'] + nexttoken = result["next-token"] return calls -def search_algorelm_nft_txns( - indexer_client: indexer.IndexerClient, - nft_id: int -): +def search_algorelm_nft_txns(indexer_client: indexer.IndexerClient, nft_id: int): nexttoken = "" numtx = 1 txns = [] @@ -210,14 +202,14 @@ def search_algorelm_nft_txns( asset_id=nft_id, limit=1000, next_page=nexttoken, - txn_type='axfer', + txn_type="axfer", min_round=ALGOREALM_FIRST_BLOCK, ) - txns += result['transactions'] - numtx = len(result['transactions']) + txns += result["transactions"] + numtx = len(result["transactions"]) if numtx > 0: # pointer to the next chunk of requests - nexttoken = result['next-token'] + nexttoken = result["next-token"] return txns @@ -229,9 +221,11 @@ def history(indexer_client: indexer.IndexerClient): algorealm_calls = search_algorelm_calls(indexer_client) break except IndexerHTTPError: - print(f'Indexer Client connection attempt ' - f'{attempts}/{MAX_CONNECTION_ATTEMPTS}') - print('Trying to contact Indexer Client again...') + print( + f"Indexer Client connection attempt " + f"{attempts}/{MAX_CONNECTION_ATTEMPTS}" + ) + print("Trying to contact Indexer Client again...") time.sleep(CONNECTION_ATTEMPT_DELAY_SEC) finally: attempts += 1 @@ -239,27 +233,32 @@ def history(indexer_client: indexer.IndexerClient): quit("āŒ Unable to connect to Indexer Client. Check your API token!") claims_history = [] - name = '' - claim = '' + name = "" + claim = "" for call in algorealm_calls: - call_args = call['application-transaction']['application-args'] + call_args = call["application-transaction"]["application-args"] # Check is an NFT claim call if len(call_args) == 2: - block = call['confirmed-round'] + block = call["confirmed-round"] nft = call_args[0].encode() - donation = call['global-state-delta'][0]['value']['uint'] + donation = call["global-state-delta"][0]["value"]["uint"] # Check is a different claimer (2 elements in the state delta) - if len(call['global-state-delta']) == 2: + if len(call["global-state-delta"]) == 2: name = base64.b64decode( - call['global-state-delta'][1]['value']['bytes']).decode() + call["global-state-delta"][1]["value"]["bytes"] + ).decode() if nft == base64.b64encode(b"Crown"): - claim = f"šŸ‘‘ {name} claimed the Crown of Entropy\n" \ - f"on Block: {block} donating: {donation} microALGOs " \ - f"to the Rewards Pool.\n\n" + claim = ( + f"šŸ‘‘ {name} claimed the Crown of Entropy\n" + f"on Block: {block} donating: {donation} microALGOs " + f"to the Rewards Pool.\n\n" + ) elif nft == base64.b64encode(b"Sceptre"): - claim = f"šŸŖ„ {name} claimed the Sceptre of Proof\n" \ - f"on Block: {block} donating: {donation} microALGOs " \ - f"to the Rewards Pool.\n\n" + claim = ( + f"šŸŖ„ {name} claimed the Sceptre of Proof\n" + f"on Block: {block} donating: {donation} microALGOs " + f"to the Rewards Pool.\n\n" + ) else: pass @@ -279,9 +278,11 @@ def current_owner(indexer_client: indexer.IndexerClient, nft_id: int): nft_txns = search_algorelm_nft_txns(indexer_client, nft_id) break except IndexerHTTPError: - print(f'Indexer Client connection attempt ' - f'{attempts}/{MAX_CONNECTION_ATTEMPTS}') - print('Trying to contact Indexer Client again...') + print( + f"Indexer Client connection attempt " + f"{attempts}/{MAX_CONNECTION_ATTEMPTS}" + ) + print("Trying to contact Indexer Client again...") time.sleep(CONNECTION_ATTEMPT_DELAY_SEC) finally: attempts += 1 @@ -290,23 +291,23 @@ def current_owner(indexer_client: indexer.IndexerClient, nft_id: int): nft_txns.reverse() for txn in nft_txns: - if txn['asset-transfer-transaction']['amount'] == 1: - return txn['asset-transfer-transaction']['receiver'] + if txn["asset-transfer-transaction"]["amount"] == 1: + return txn["asset-transfer-transaction"]["receiver"] def opt_in( - algod_client: algod.AlgodClient, - user: Account, - nft_id: int, + algod_client: algod.AlgodClient, + user: Account, + nft_id: int, ): - nft_name = algod_client.asset_info(nft_id)['params']['name'] - optin = '' + nft_name = algod_client.asset_info(nft_id)["params"]["name"] + optin = "" while not optin: - optin = str(input( - f"Do you want to opt-in the {nft_name} (ID: {nft_id})? (Y/n) " - )) + optin = str( + input(f"Do you want to opt-in the {nft_name} (ID: {nft_id})? (Y/n) ") + ) print("") - if optin.lower() == 'y': + if optin.lower() == "y": params = algod_client.suggested_params() opt_in_txn = transaction.AssetOptInTxn( @@ -316,20 +317,20 @@ def opt_in( ) return sign_send_wait(algod_client, user, opt_in_txn) - elif optin.lower() == 'n': + elif optin.lower() == "n": return else: - optin = '' + optin = "" def claim_nft( - algod_client: algod.AlgodClient, - indexer_client: indexer.IndexerClient, - claimer: Account, - claim_arg: str, - new_majesty: str, - donation_amount: int, - nft_id: int, + algod_client: algod.AlgodClient, + indexer_client: indexer.IndexerClient, + claimer: Account, + claim_arg: str, + new_majesty: str, + donation_amount: int, + nft_id: int, ): params = algod_client.suggested_params() @@ -337,7 +338,7 @@ def claim_nft( sender=claimer.address, sp=params, index=ALGOREALM_APP_ID, - app_args=[claim_arg.encode(), new_majesty.encode()] + app_args=[claim_arg.encode(), new_majesty.encode()], ) donation_txn = transaction.PaymentTxn( @@ -361,23 +362,27 @@ def claim_nft( [claim_txn, donation_txn, nft_transfer], ) - nft_name = algod_client.asset_info(nft_id)['params']['name'] + nft_name = algod_client.asset_info(nft_id)["params"]["name"] - print(f"Claiming the {nft_name} as {new_majesty}, " - f"donating {donation_amount / 10 ** 6} ALGO...\n") + print( + f"Claiming the {nft_name} as {new_majesty}, " + f"donating {donation_amount / 10 ** 6} ALGO...\n" + ) try: gtxn_id = algod_client.send_transactions(signed_group) wait_for_confirmation(algod_client, gtxn_id) except AlgodHTTPError: - quit("\nā˜¹ļø Were you too stingy? Only generous hearts will rule over " - "Algorand Realm!\nļø") + quit( + "\nā˜¹ļø Were you too stingy? Only generous hearts will rule over " + "Algorand Realm!\nļø" + ) def proof_asa_amount_eq_txn( - algod_client: algod.AlgodClient, - sender: Account, - asa_id: int, - asa_amount: int, + algod_client: algod.AlgodClient, + sender: Account, + asa_id: int, + asa_amount: int, ): params = algod_client.suggested_params() @@ -427,17 +432,19 @@ def claim_card(algod_client: algod.AlgodClient, claimer: Account): gtxn_id = algod_client.send_transactions(signed_group) wait_for_confirmation(algod_client, gtxn_id) except AlgodHTTPError: - quit("\nOnly the generous heart of the Great Majesty of Algorand " - "can break the spell!\n" - "Conquer both the šŸ‘‘ Crown of Entropy and the šŸŖ„ Sceptre " - "of Proof first!\n") + quit( + "\nOnly the generous heart of the Great Majesty of Algorand " + "can break the spell!\n" + "Conquer both the šŸ‘‘ Crown of Entropy and the šŸŖ„ Sceptre " + "of Proof first!\n" + ) def card_order( - algod_client: algod.AlgodClient, - buyer: Account, - seller: Account, - price: int, + algod_client: algod.AlgodClient, + buyer: Account, + seller: Account, + price: int, ): params = algod_client.suggested_params() @@ -493,36 +500,31 @@ def card_order( nft_card_payment, royalty_1_payment, royalty_2_payment, - nft_card_xfer + nft_card_xfer, ] transaction.assign_group_id(trade_gtxn) signed_nft_card_payment = trade_gtxn[2].sign(buyer.private_key) trade_gtxn[2] = signed_nft_card_payment - trade_gtxn[5] = transaction.LogicSigTransaction(trade_gtxn[5], - CARD_CONTRACT.lsig) - transaction.write_to_file(trade_gtxn, 'trade_raw.gtxn', overwrite=True) + trade_gtxn[5] = transaction.LogicSigTransaction(trade_gtxn[5], CARD_CONTRACT.lsig) + transaction.write_to_file(trade_gtxn, "trade_raw.gtxn", overwrite=True) - print( - "šŸ“ Partially signed trade group transaction saved as: 'trade.gtxn'\n") + print("šŸ“ Partially signed trade group transaction saved as: 'trade.gtxn'\n") return trade_gtxn def notify( - algod_client: algod.AlgodClient, - user: Account, - seller: Account, - trade_gtxn: list + algod_client: algod.AlgodClient, user: Account, seller: Account, trade_gtxn: list ): params = algod_client.suggested_params() note = { - 'buy_order': 'AlgoRealm Special Card', - 'asset_id': CARD_ID, - 'algo_amount': trade_gtxn[2].transaction.amt / 10 ** 6, - 'algo_royalty': (trade_gtxn[3].amt + trade_gtxn[4].amt) / 10 ** 6, - 'last_valid_block': trade_gtxn[2].transaction.last_valid_round + "buy_order": "AlgoRealm Special Card", + "asset_id": CARD_ID, + "algo_amount": trade_gtxn[2].transaction.amt / 10**6, + "algo_royalty": (trade_gtxn[3].amt + trade_gtxn[4].amt) / 10**6, + "last_valid_block": trade_gtxn[2].transaction.last_valid_round, } bytes_note = msgpack.packb(note) @@ -540,19 +542,18 @@ def notify( print("āœ‰ļø Sending buy order notification to the Seller...\n") algod_client.send_transactions([signed_txn]) wait_for_confirmation(algod_client, tx_id) - print("\nšŸ“„ Buy order notification:\n" - "https://algoexplorer.io/tx/" + tx_id) + print("\nšŸ“„ Buy order notification:\n" "https://algoexplorer.io/tx/" + tx_id) def verify_buy_order(seller_address: str): - trade_gtxn = transaction.retrieve_from_file('trade_raw.gtxn') + trade_gtxn = transaction.retrieve_from_file("trade_raw.gtxn") # Check TXN 0: Crown Proof of Ownership try: - assert trade_gtxn[0].type == 'appl' + assert trade_gtxn[0].type == "appl" assert trade_gtxn[0].index == ASA_STATE_OBSERVER_APP_ID - assert trade_gtxn[0].app_args[0] == b'AsaAmountEq' - assert trade_gtxn[0].app_args[1] == b'\x00\x00\x00\x00\x00\x00\x00\x01' + assert trade_gtxn[0].app_args[0] == b"AsaAmountEq" + assert trade_gtxn[0].app_args[1] == b"\x00\x00\x00\x00\x00\x00\x00\x01" assert trade_gtxn[0].foreign_assets[0] == CROWN_ID assert trade_gtxn[0].accounts[0] == seller_address assert trade_gtxn[0].sender == seller_address @@ -562,15 +563,14 @@ def verify_buy_order(seller_address: str): _, _, tb = sys.exc_info() tb_info = traceback.extract_tb(tb) filename, line, func, text = tb_info[-1] - quit("Transaction 0 - Crown Proof of Ownership is invalid: {}".format( - text)) + quit("Transaction 0 - Crown Proof of Ownership is invalid: {}".format(text)) # Check TXN 1: Sceptre Proof of Ownership try: - assert trade_gtxn[1].type == 'appl' + assert trade_gtxn[1].type == "appl" assert trade_gtxn[1].index == ASA_STATE_OBSERVER_APP_ID - assert trade_gtxn[1].app_args[0] == b'AsaAmountEq' - assert trade_gtxn[1].app_args[1] == b'\x00\x00\x00\x00\x00\x00\x00\x01' + assert trade_gtxn[1].app_args[0] == b"AsaAmountEq" + assert trade_gtxn[1].app_args[1] == b"\x00\x00\x00\x00\x00\x00\x00\x01" assert trade_gtxn[1].foreign_assets[0] == SCEPTRE_ID assert trade_gtxn[1].accounts[0] == seller_address assert trade_gtxn[1].sender == seller_address @@ -580,13 +580,11 @@ def verify_buy_order(seller_address: str): _, _, tb = sys.exc_info() tb_info = traceback.extract_tb(tb) filename, line, func, text = tb_info[-1] - quit( - "Transaction 1 - Sceptre Proof of Ownership is invalid: {}".format( - text)) + quit("Transaction 1 - Sceptre Proof of Ownership is invalid: {}".format(text)) # Check TXN 2: Card Payment try: - assert trade_gtxn[2].transaction.type == 'pay' + assert trade_gtxn[2].transaction.type == "pay" assert trade_gtxn[2].transaction.receiver == seller_address except AssertionError: _, _, tb = sys.exc_info() @@ -596,7 +594,7 @@ def verify_buy_order(seller_address: str): # Check TXN 3: Royalty 1 Payment try: - assert trade_gtxn[3].type == 'pay' + assert trade_gtxn[3].type == "pay" assert trade_gtxn[3].sender == seller_address assert trade_gtxn[3].receiver == ROYALTY_COLLECTOR_1.address assert trade_gtxn[3].fee <= 1000 @@ -609,7 +607,7 @@ def verify_buy_order(seller_address: str): # Check TXN 4: Royalty 3 Payment try: - assert trade_gtxn[4].type == 'pay' + assert trade_gtxn[4].type == "pay" assert trade_gtxn[4].sender == seller_address assert trade_gtxn[4].receiver == ROYALTY_COLLECTOR_2.address assert trade_gtxn[4].fee <= 1000 @@ -622,12 +620,11 @@ def verify_buy_order(seller_address: str): # Check TXN 5: Card Transfer try: - assert trade_gtxn[5].transaction.type == 'axfer' + assert trade_gtxn[5].transaction.type == "axfer" assert trade_gtxn[5].transaction.index == CARD_ID assert trade_gtxn[5].transaction.amount == 1 assert trade_gtxn[5].transaction.sender == CARD_CONTRACT.address - assert trade_gtxn[5].transaction.receiver == trade_gtxn[ - 2].transaction.sender + assert trade_gtxn[5].transaction.receiver == trade_gtxn[2].transaction.sender assert trade_gtxn[5].transaction.revocation_target == seller_address assert trade_gtxn[5].transaction.fee <= 1000 assert trade_gtxn[5].transaction.rekey_to is None @@ -646,7 +643,7 @@ def order_summary(algod_client: algod.AlgodClient, trade_gtxn: list): last_valid_round = trade_gtxn[2].transaction.last_valid_round remaning_rounds = last_valid_round - current_round if remaning_rounds <= 0: - remaning_rounds = 'Buy order expired!' + remaning_rounds = "Buy order expired!" return f""" * =========================== ORDER SUMMARY =========================== * @@ -663,7 +660,7 @@ def order_summary(algod_client: algod.AlgodClient, trade_gtxn: list): def sell_card(algod_client: algod.AlgodClient, user: Account): - trade_gtxn = transaction.retrieve_from_file('trade_raw.gtxn') + trade_gtxn = transaction.retrieve_from_file("trade_raw.gtxn") signed_crown_proof = trade_gtxn[0].sign(user.private_key) signed_sceptre_proof = trade_gtxn[1].sign(user.private_key) @@ -675,38 +672,39 @@ def sell_card(algod_client: algod.AlgodClient, user: Account): trade_gtxn[3] = signed_royalty_1 trade_gtxn[4] = signed_royalty_2 - print(f"šŸ¤ Selling the AlgoRealm Special Card for " - f"{trade_gtxn[2].transaction.amt / 10 ** 6} ALGO:\n") + print( + f"šŸ¤ Selling the AlgoRealm Special Card for " + f"{trade_gtxn[2].transaction.amt / 10 ** 6} ALGO:\n" + ) try: gtxn_id = algod_client.send_transactions(trade_gtxn) except AlgodHTTPError: - quit( - "You must hold the šŸ‘‘ Crown and the šŸŖ„ Scepter to sell the Card!\n") + quit("You must hold the šŸ‘‘ Crown and the šŸŖ„ Scepter to sell the Card!\n") else: return wait_for_confirmation(algod_client, gtxn_id) def title(): return r""" - __ __ ___ __ __ - \*) \*) \*/ (*/ (*/ - \*\_\*\_|O|_/*/_/*/ - \_______________/ - _ __ _______ __ - / \ [ | |_ __ \ [ | - / _ \ | | .--./) .--. | |__) | .---. ,--. | | _ .--..--. - / ___ \ | | / /'`\;/ .'`\ \ | __ / / /__\\`'_\ : | | [ `.-. .-. | - _/ / \ \_ | | \ \._//| \__. |_| | \ \_| \__.,// | |, | | | | | | | | + __ __ ___ __ __ + \*) \*) \*/ (*/ (*/ + \*\_\*\_|O|_/*/_/*/ + \_______________/ + _ __ _______ __ + / \ [ | |_ __ \ [ | + / _ \ | | .--./) .--. | |__) | .---. ,--. | | _ .--..--. + / ___ \ | | / /'`\;/ .'`\ \ | __ / / /__\\`'_\ : | | [ `.-. .-. | + _/ / \ \_ | | \ \._//| \__. |_| | \ \_| \__.,// | |, | | | | | | | | |____| |____|[___].',__` '.__.'|____| |___|'.__.'\'-;__/[___][___||__||__] ( ( __)) - by cusma + by cusma """ def poem(): return r""" - ,-----------------------------------------. - (_\ \ + ,-----------------------------------------. + (_\ \ | There was a time | | When nothing but Entropy was there. | | Then came the cryptographic Proof, | @@ -718,9 +716,9 @@ def poem(): | So Algorand never fork. | _| | (_/___________________(*)___________________/ - \\ - )) - ^ + \\ + )) + ^ """ @@ -728,148 +726,134 @@ def main(): if len(sys.argv) == 1: # Display help if no arguments, see: # https://github.com/docopt/docopt/issues/420#issuecomment-405018014 - sys.argv.append('--help') + sys.argv.append("--help") args = docopt(__doc__) print(title()) - if args['poem']: + if args["poem"]: return print(poem()) # Clients - token = args[''] - header = {'X-Api-key': token} + header = {"User-Agent": "algosdk"} algod_client = algod.AlgodClient( - algod_token=token, - algod_address=ALGOD_ADDRESS, - headers=header + algod_token="", algod_address=ALGOD_ADDRESS, headers=header ) indexer_client = indexer.IndexerClient( - indexer_token=token, - indexer_address=INDEXER_ADDRESS, - headers=header + indexer_token="", indexer_address=INDEXER_ADDRESS, headers=header ) - if args['verify-order']: + if args["verify-order"]: summary = order_summary( - algod_client, verify_buy_order(args['']) + algod_client, verify_buy_order(args[""]) ) return print(summary) - if args['dynasty']: + if args["dynasty"]: print( r""" *** DYNASTY *** """ ) - return print(*['\n', *history(indexer_client)]) + return print(*["\n", *history(indexer_client)]) # Checking mnemonic format try: - assert len(args[''].split()) == 25 + assert len(args[""].split()) == 25 except AssertionError: - quit('The mnemonic phrase must contain 25 words, ' - 'formatted as: "word_1 word_2 ... word_25"\n') + quit( + "The mnemonic phrase must contain 25 words, " + 'formatted as: "word_1 word_2 ... word_25"\n' + ) - private_key = mnemonic.to_private_key(args['']) + private_key = mnemonic.to_private_key(args[""]) - user = Account( - account.address_from_private_key(private_key), - private_key - ) + user = Account(account.address_from_private_key(private_key), private_key) - if args['claim-crown']: + if args["claim-crown"]: opt_in(algod_client, user, CROWN_ID) - name = args[''] + name = args[""] claim_nft( algod_client=algod_client, indexer_client=indexer_client, claimer=user, - claim_arg='Crown', + claim_arg="Crown", new_majesty=name, - donation_amount=int(args['']), + donation_amount=int(args[""]), nft_id=CROWN_ID, ) print(f"\nšŸ‘‘ Glory to {name}, the Randomic Majesty of Algorand! šŸŽ‰\n") - elif args['claim-sceptre']: + elif args["claim-sceptre"]: opt_in(algod_client, user, SCEPTRE_ID) - name = args[''] + name = args[""] claim_nft( algod_client=algod_client, indexer_client=indexer_client, claimer=user, - claim_arg='Sceptre', + claim_arg="Sceptre", new_majesty=name, - donation_amount=int(args['']), + donation_amount=int(args[""]), nft_id=SCEPTRE_ID, ) - print( - f"\nšŸŖ„ Glory to {name}, the Verifiable Majesty of Algorand! šŸŽ‰\n") + print(f"\nšŸŖ„ Glory to {name}, the Verifiable Majesty of Algorand! šŸŽ‰\n") - elif args['claim-card']: + elif args["claim-card"]: if algod_client.status()["last-round"] <= ALGOREALM_CARD_FIRST_BLOCK: - return print("šŸ” The spell can be broken starting from the block " - f"{ALGOREALM_CARD_FIRST_BLOCK}... ā³\n") + return print( + "šŸ” The spell can be broken starting from the block " + f"{ALGOREALM_CARD_FIRST_BLOCK}... ā³\n" + ) - algorelm_card_contract = algod_client.account_info( - CARD_CONTRACT.address - ) + algorelm_card_contract = algod_client.account_info(CARD_CONTRACT.address) - assets = algorelm_card_contract['assets'] + assets = algorelm_card_contract["assets"] - card_nft = list(filter( - lambda asset: asset['asset-id'] == CARD_ID, assets))[0] + card_nft = list(filter(lambda asset: asset["asset-id"] == CARD_ID, assets))[0] - if card_nft['amount'] == 0: - return print("šŸ”“ The enchanted coffer is empty! " - "The AlgoRealm Special Card has been claimed!\n") + if card_nft["amount"] == 0: + return print( + "šŸ”“ The enchanted coffer is empty! " + "The AlgoRealm Special Card has been claimed!\n" + ) opt_in(algod_client, user, CARD_ID) print("\nāœØ Whispering words of wisdom...") - claim_card( - algod_client=algod_client, - claimer=user + claim_card(algod_client=algod_client, claimer=user) + print( + f"\n ļæ½ The spell has been broken! " + f"The AlgoRealm Special Card is yours! šŸŽ‰\n" ) - print(f"\n šŸ“œ The spell has been broken! " - f"The AlgoRealm Special Card is yours! šŸŽ‰\n") - if args['buy-order']: + if args["buy-order"]: opt_in(algod_client, user, CARD_ID) - amount = int(args['']) + amount = int(args[""]) - print( - f"āœļø Placing order of: {util.microalgos_to_algos(amount)} ALGO\n") + print(f"āœļø Placing order of: {util.microalgos_to_algos(amount)} ALGO\n") - seller = Account( - address=current_owner(indexer_client, CARD_ID), - private_key='' - ) + seller = Account(address=current_owner(indexer_client, CARD_ID), private_key="") trade_gtxn = card_order( - algod_client=algod_client, - buyer=user, - seller=seller, - price=amount + algod_client=algod_client, buyer=user, seller=seller, price=amount ) - if args['--notify']: + if args["--notify"]: notify(algod_client, user, seller, trade_gtxn) return print( "\nšŸ“¦ Send `trade.gtxn` file to the Seller to finalize the trade!\n" ) - if args['sell-card']: + if args["sell-card"]: sell_card(algod_client, user) else: diff --git a/algorealm_approval.teal b/src/contracts/algorealm_approval.teal similarity index 100% rename from algorealm_approval.teal rename to src/contracts/algorealm_approval.teal diff --git a/algorealm_clear.teal b/src/contracts/algorealm_clear.teal similarity index 100% rename from algorealm_clear.teal rename to src/contracts/algorealm_clear.teal diff --git a/algorealm_law.teal b/src/contracts/algorealm_law.teal similarity index 99% rename from algorealm_law.teal rename to src/contracts/algorealm_law.teal index 0edb7ba..6343343 100644 --- a/algorealm_law.teal +++ b/src/contracts/algorealm_law.teal @@ -53,4 +53,4 @@ gtxn 2 RekeyTo global ZeroAddress == && -&& \ No newline at end of file +&& diff --git a/card/README.md b/src/contracts/card/README.md similarity index 99% rename from card/README.md rename to src/contracts/card/README.md index 34347e9..81da0be 100644 --- a/card/README.md +++ b/src/contracts/card/README.md @@ -4,7 +4,7 @@ The [AlgoRealm Card](https://algoexplorer.io/asset/321172366) is a unique [AlgoW
- + algorealm_card
@@ -230,7 +230,7 @@ Note that you have no counterparty risk, since `trade-2.stxn` can only be approv ### Trading role: Seller -As **Seller**, you review the buy order proposal placed by the **Buyer** as *Unsigned Trade Group Transaction*. If you agree on the buy order proposal, you sign the AlgoRealm Card *Unsigned Trade Group Transaction* and submit it to the blockchain. +As **Seller**, you review the buy order proposal placed by the **Buyer** as *Unsigned Trade Group Transaction*. If you agree on the buy order proposal, you sign the AlgoRealm Card *Unsigned Trade Group Transaction* and submit it to the blockchain. Remember that, in doing so, there is no counterparty risk for both parties. @@ -278,4 +278,3 @@ cat trade-0.stxn trade-1.stxn trade-2.stxn trade-3.stxn trade-4.stxn trade-5.stx ```shell ./goal clerk rawsend -f trade.sgtxn ``` - diff --git a/card/algorealm_card_contract.teal b/src/contracts/card/algorealm_card_contract.teal similarity index 99% rename from card/algorealm_card_contract.teal rename to src/contracts/card/algorealm_card_contract.teal index c44e35f..b6d0d0e 100755 --- a/card/algorealm_card_contract.teal +++ b/src/contracts/card/algorealm_card_contract.teal @@ -274,4 +274,4 @@ txn LastValid int 16052558 < && -l7: \ No newline at end of file +l7: