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
-
+
@@ -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: