Skip to content

Commit

Permalink
Merge pull request #48 from tinymanorg/v2-updates
Browse files Browse the repository at this point in the history
Tinyman V2
  • Loading branch information
fergalwalsh authored Dec 20, 2022
2 parents cd1a7db + ddf1e01 commit 5e3ba82
Show file tree
Hide file tree
Showing 76 changed files with 6,259 additions and 416 deletions.
2 changes: 2 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[flake8]
ignore = E501,F403,F405,E126,E121,W503,E203
34 changes: 34 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Lint & Tests

on: [push, pull_request]

jobs:
build:

runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.10", "3.9", "3.8"]
py-algorand-sdk-version: ["1.18", "1.17", "1.16", "1.15", "1.14", "1.13"]

steps:
- uses: actions/checkout@v3

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install flake8 black py-algorand-sdk==${{ matrix.py-algorand-sdk-version }}
- name: Run flake8
run: flake8 ${{ github.workspace }} --ignore=E501,F403,F405,E126,E121,W503,E203

- name: Run Black
run: black ${{ github.workspace }} --check

- name: Run Unit tests
run: python -m unittest
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.DS_Store
.idea

# Byte-compiled / optimized / DLL files
__pycache__/
Expand Down Expand Up @@ -129,3 +130,7 @@ dmypy.json

# Pyre type checker
.pyre/

# Tutorials
account*.json
assets*.json
14 changes: 14 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
repos:
- repo: https://github.com/pycqa/flake8
rev: '3.9.2' # pick a git hash / tag to point to
hooks:
- id: flake8
args: ['--ignore=E501,F403,F405,E126,E121,W503,E203', '.']
exclude: ^(env|venv)

- repo: https://github.com/psf/black
rev: 22.8.0
hooks:
- id: black
args: ['.', '--check']
exclude: ^(env|venv)
25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Change Log

## 2.0.0

### Added

* Added Tinyman V2 support (`tinyman.v2`).
* Added Staking support (`tinyman.staking`).
- It allows creating commitment transaction by `prepare_commit_transaction` and tracking commitments by `parse_commit_transaction`.
* Added `calculate_price_impact` function to `tinyman.utils`.
* Improved `TransactionGroup` class.
- Added `+` operator support for composability, it allows creating a new transaction group (`txn_group_1 + txn_group_2`).
- Added `id` property, it returns the transactions group id.
- Added `TransactionGroup.sign_with_logicsig` function and deprecated `TransactionGroup.sign_with_logicisg` because of the typo.

### Changed

* `get_program` (V1) is moved from `tinyman.utils` to `tinyman.v1.contracts`.
* `get_state_from_account_info` (V1) is moved from `tinyman.utils` to `tinyman.v1.utils`.

### Removed

* Deprecated `wait_for_confirmation` function is removed. `wait_for_confirmation` is added to [Algorand SDK](https://github.com/algorand/py-algorand-sdk).
* Drop Python 3.7 support.

156 changes: 148 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,150 @@ The SDK has been updated for Tinyman V1.1.


## Installation
tinyman-py-sdk is not yet released on PYPI. It can be installed directly from this repository with pip:
tinyman-py-sdk is not released on PYPI. It can be installed directly from this repository with pip:

`pip install git+https://github.com/tinymanorg/tinyman-py-sdk.git`

## V2

## Sneak Preview

```python
# examples/v2/sneak_preview.py

from examples.v2.utils import get_algod
from tinyman.v2.client import TinymanV2TestnetClient

algod = get_algod()
client = TinymanV2TestnetClient(algod_client=algod)

# Fetch our two assets of interest
USDC = client.fetch_asset(10458941)
ALGO = client.fetch_asset(0)

# Fetch the pool we will work with
pool = client.fetch_pool(USDC, ALGO)
print(f"Pool Info: {pool.info()}")

# Get a quote for a swap of 1 ALGO to USDC with 1% slippage tolerance
quote = pool.fetch_fixed_input_swap_quote(amount_in=ALGO(1_000_000), slippage=0.01)
print(quote)
print(f"USDC per ALGO: {quote.price}")
print(f"USDC per ALGO (worst case): {quote.price_with_slippage}")
```

## Tutorial

You can find a tutorial under the `examples/v2/tutorial` folder.

To run a step use `python <file_name>` such as `python 01_generate_account.py`.

#### Prerequisites
1. [Generating an account](examples/v2/01_generate_account.py)
2. [Creating assets](examples/v2/02_create_assets.by)

#### Steps

3. [Bootstrapping a pool](examples/v2/03_bootstrap_pool.py)
4. [Adding initial liquidity to the pool](examples/v2/04_add_initial_liquidity.py)
5. [Adding flexible (add two asset with a flexible rate) liquidity to the pool](examples/v2/05_add_flexible_liquidity.py)
6. [Adding single asset (add only one asset) liquidity to the pool](examples/v2/06_add_single_asset_liquidity.py)
7. [Removing liquidity to the pool](examples/v2/07_remove_liquidity.py)
8. [Removing single asset(receive single asset) liquidity to the pool](examples/v2/08_single_asset_remove_liquidity.py)
9. [Swapping fixed-input](examples/v2/09_fixed_input_swap.py)
10. [Swapping fixed-output](examples/v2/10_fixed_output_swap.py)

## Example Operations

### Bootstrap

```python
txn_group = pool.prepare_bootstrap_transactions()
txn_group.sign_with_private_key(<ADDRESS>, <PRIVATE_KEY>)
txn_info = txn_group.submit(algod, wait=True)
```

### Add Liquidity

#### Initial Add Liquidity

```python
quote = pool.fetch_initial_add_liquidity_quote(
amount_a=<AssetAmount>,
amount_b=<AssetAmount>,
)
txn_group = pool.prepare_add_liquidity_transactions_from_quote(quote)
txn_group.sign_with_private_key(<ADDRESS>, <PRIVATE_KEY>)
txn_info = txn_group.submit(algod, wait=True)
```

#### Flexible Add Liquidity

```python
quote = pool.fetch_flexible_add_liquidity_quote(
amount_a=<AssetAmount>,
amount_b=<AssetAmount>,
)
txn_group = pool.prepare_add_liquidity_transactions_from_quote(quote=quote)
txn_group.sign_with_private_key(<ADDRESS>, <PRIVATE_KEY>)
txn_info = txn_group.submit(algod, wait=True)
```

#### Single Asset Add Liquidity

```python
quote = pool.fetch_single_asset_add_liquidity_quote(amount_a=<AssetAmount>)
txn_group = pool.prepare_add_liquidity_transactions_from_quote(quote=quote)
txn_group.sign_with_private_key(<ADDRESS>, <PRIVATE_KEY>)
txn_info = txn_group.submit(algod, wait=True)
```

### Remove Liquidity

#### Remove Liquidity

```python
quote = pool.fetch_remove_liquidity_quote(
pool_token_asset_in=<AssetAmount>,
)
txn_group = pool.prepare_remove_liquidity_transactions_from_quote(quote=quote)
txn_group.sign_with_private_key(<ADDRESS>, <PRIVATE_KEY>)
txn_info = txn_group.submit(algod, wait=True)
```

#### Single Asset Remove Liquidity

```python
quote = pool.fetch_single_asset_remove_liquidity_quote(
pool_token_asset_in=<AssetAmount>,
output_asset=<Asset>,
)
txn_group = pool.prepare_remove_liquidity_transactions_from_quote(quote=quote)
txn_group.sign_with_private_key(<ADDRESS>, <PRIVATE_KEY>)
txn_info = txn_group.submit(algod, wait=True)
```

### Swap

#### Fixed Input Swap

```python
quote = pool.fetch_fixed_input_swap_quote(amount_in=<AssetAmount>)
txn_group = pool.prepare_swap_transactions_from_quote(quote=quote)
txn_group.sign_with_private_key(<ADDRESS>, <PRIVATE_KEY>)
txn_info = txn_group.submit(algod, wait=True)
```

#### Fixed Output Swap

```python
quote = pool.fetch_fixed_output_swap_quote(amount_in=<AssetAmount>)
txn_group = pool.prepare_swap_transactions_from_quote(quote=quote)
txn_group.sign_with_private_key(<ADDRESS>, <PRIVATE_KEY>)
txn_info = txn_group.submit(algod, wait=True)
```

## V1.1

## Sneak Preview

Expand Down Expand Up @@ -48,7 +188,7 @@ print(f'TINYUSDC per ALGO (worst case): {quote.price_with_slippage}')
## Examples

### Basic Swapping
[swapping1.py](examples/swapping1.py)
[swapping1.py](examples/v1/swapping1.py)
This example demonstrates basic functionality including:
* retrieving Pool details
* getting a swap quote
Expand All @@ -58,16 +198,16 @@ This example demonstrates basic functionality including:
* checking excess amounts
* preparing redeem transactions

[swapping1_less_convenience.py](examples/swapping1_less_convenience.py)
This example has exactly the same functionality as [swapping1.py](examples/swapping1.py) but is purposely more verbose, using less convenience functions.
[swapping1_less_convenience.py](examples/v1/swapping1_less_convenience.py)
This example has exactly the same functionality as [swapping1.py](examples/v1/swapping1.py) but is purposely more verbose, using less convenience functions.


### Basic Pooling
[pooling1.py](examples/pooling1.py)
[pooling1.py](examples/v1/pooling1.py)
This example demonstrates retrieving the current pool position/share for an address.

### Basic Add Liquidity (Minting)
[add_liquidity1.py](examples/add_liquidity1.py)
[add_liquidity1.py](examples/v1/add_liquidity1.py)
This example demonstrates add liquidity to an existing pool.

### Basic Burning
Expand Down Expand Up @@ -119,9 +259,9 @@ for i, txn in enumerate(transaction_group.transactions):
transaction_group.signed_transactions[i] = kmd.sign_transaction(handle, KMD_WALLET_PASSWORD, txn)
```

A User account LogicSig can also be used in a similar way or using the `sign_with_logicisg` convenience method:
A User account LogicSig can also be used in a similar way or using the `sign_with_logicsig` convenience method:
```python
transaction_group.sign_with_logicisg(logicsig)
transaction_group.sign_with_logicsig(logicsig)
```

### Submission
Expand Down
32 changes: 32 additions & 0 deletions asc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"repo": "https://github.com/tinymanorg/tinyman-staking",
"ref": "main",
"contracts": {
"staking_app": {
"type": "app",
"approval_program": {
"bytecode": "BSADAAEIJgcIZW5kX3RpbWUGYXNzZXRzBG1pbnMMdmVyaWZpY2F0aW9uCGJhbGFuY2UgAmlkD3Byb2dyYW1fY291bnRlcjEZIhJAAC8xGSMSQAAZMRmBAhJAAicxGYEEEkACITEZgQUSQAIfADYaAIAFc2V0dXASQAGZADYaAIAGY3JlYXRlEkAAijYaAIAGY29tbWl0EkAAfTYaAIAFY2xhaW0SQAEDNhoAgAZ1cGRhdGUSQAE8NhoAgA51cGRhdGVfcmV3YXJkcxJAAN82GgCADXVwZGF0ZV9hc3NldHMSQAD4NhoAgAtlbmRfcHJvZ3JhbRJAAPI2GgArEkAA9TYaAIALbG9nX2JhbGFuY2USQADvACNDIyhiMgcNRCMpYiJKJAtbNjAAEkAACiMISYEODERC/+tMSDUBIypiNAEkC1s1AjYaARdBAAg2GgEXNAIPRCI2MABwAERJFicETFCwNhoBFw9EgBN0aW55bWFuU3Rha2luZy92MTpiMQVRABMSRDEFVxMANQE0ASJbIycFYhJENAEkWzYwABJENAGBEFs2GgEXEkQjQyNDIoACcjE2GgFmIoACcjI2GgJmIoACcjM2GgNmIoACcjQ2GgRmIoACcjU2GgVmI0MiKTYaAWYiKjYaAmYjQyIoNhoBF2YjQyNDMgkxABJEIis2GgFmI0MiNjAAcABESUQWJwRMULAjQycGZCMINQEnBjQBZyInBTQBZiKAA3VybDYaAWYigA9yZXdhcmRfYXNzZXRfaWQ2GgIXZiKADXJld2FyZF9wZXJpb2Q2GgMXZiKACnN0YXJ0X3RpbWU2GgQXZiIoNhoFF2YiKTYaBmYiKjYaB2YjQyNDMgkxABJDMgkxABJDAA==",
"address": "KJ3W4IB66Q4ZITCNVABJXAV4I4HKWSZIJMD6BTFATQAWO5AKOV5VMZ6OFI",
"size": 658,
"variables": [],
"source": "https://github.com/tinymanorg/tinyman-staking/tree/main/contracts/staking.teal"
},
"clear_program": {
"bytecode": "BIEB",
"address": "P7GEWDXXW5IONRW6XRIRVPJCT2XXEQGOBGG65VJPBUOYZEJCBZWTPHS3VQ",
"size": 3,
"variables": [],
"source": "https://github.com/tinymanorg/tinyman-staking/tree/main/contracts/clear_state.teal"
},
"global_state_schema": {
"num_uints": 2,
"num_byte_slices": 2
},
"local_state_schema": {
"num_uints": 5,
"num_byte_slices": 11
},
"name": "staking_app"
}
}
}
Empty file added examples/__init__.py
Empty file.
13 changes: 13 additions & 0 deletions examples/staking/commitments.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import requests
from tinyman.staking import parse_commit_transaction
from tinyman.staking.constants import TESTNET_STAKING_APP_ID

app_id = TESTNET_STAKING_APP_ID
result = requests.get(
f"https://indexer.testnet.algoexplorerapi.io/v2/transactions?application-id={app_id}&latest=50"
).json()
for txn in result["transactions"]:
commit = parse_commit_transaction(txn, app_id)
if commit:
print(commit)
print()
40 changes: 40 additions & 0 deletions examples/staking/make_commitment.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# This sample is provided for demonstration purposes only.
# It is not intended for production use.
# This example does not constitute trading advice.

from tinyman.v1.client import TinymanTestnetClient

from tinyman.staking import prepare_commit_transaction

# Hardcoding account keys is not a great practice. This is for demonstration purposes only.
# See the README & Docs for alternative signing methods.
account = {
"address": "ALGORAND_ADDRESS_HERE",
"private_key": "base64_private_key_here", # Use algosdk.mnemonic.to_private_key(mnemonic) if necessary
}

client = TinymanTestnetClient(user_address=account["address"])

# Fetch our two assets of interest
TINYUSDC = client.fetch_asset(21582668)
ALGO = client.fetch_asset(0)

# Fetch the pool we will work with
pool = client.fetch_pool(TINYUSDC, ALGO)


sp = client.algod.suggested_params()

txn_group = prepare_commit_transaction(
app_id=client.staking_app_id,
program_id=1,
program_account="B4XVZ226UPFEIQBPIY6H454YA4B7HYXGEM7UDQR2RJP66HVLOARZTUTS6Q",
pool_asset_id=pool.liquidity_asset.id,
amount=600_000_000,
sender=account["address"],
suggested_params=sp,
)

txn_group.sign_with_private_key(account["address"], account["private_key"])
result = client.submit(txn_group, wait=True)
print(result)
Loading

0 comments on commit 5e3ba82

Please sign in to comment.