Tinyman Python SDK

Overview

tinyman-py-sdk

Tinyman Python SDK

Design Goal

This SDK is designed for automated interaction with the Tinyman AMM. It will be most useful for developers who wish to create automated trading programs/bots. It may also be useful to create an alternative UI but that is not a design goal of this library. It is designed to be reasonably low level so that pieces can be used in isolation.

Status

This SDK is currently under active early development and should not be considered stable.

Installation

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

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

Sneak Preview

from tinyman.v1.client import TinymanTestnetClient

client = TinymanTestnetClient()

# 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)

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

# See the examples for the rest...

Examples

Basic Swapping

swapping1.py This example demonstrates basic functionality including:

  • retrieving Pool details
  • getting a swap quote
  • preparing swap transactions
  • signing transactions
  • submitting transactions
  • checking excess amounts
  • preparing redeem transactions

swapping1_less_convenience.py This example has exactly the same functionality as swapping1.py but is purposely more verbose, using less convenience functions.

Basic Pooling

pooling1.py This example demonstrates retrieving the current pool position/share for an address.

Basic Add Liquidity (Minting)

add_liquidity1.py This example demonstrates add liquidity to an existing pool.

Basic Burning

TODO

Conventions

  • Methods starting with fetch_ all make network requests to fetch current balances/state.
  • Methods of the form prepare_X_transactions all return TransactionGroup objects (see below).
  • All asset amounts are returned as AssetAmount objects which contain an Asset and amount (int).
  • All asset amount inputs are expected as micro units e.g. 1 Algo = 1_000_000 micro units.

Signing & Submission

The SDk separates transaction preparation from signing and submission to leave the developer in full control of how transactions are signed and submitted to the network.

Preparation

The prepare_X_transactions methods all return a TransactionGroup object. This is a container object containing a list of transaction objects (.transactions) and a list for signed transactions (.signed_transactions).

transaction_group = client.prepare_app_optin_transactions(account['address'])

Signing

In most cases some of the transactions have a corresponding entry in .signed_transactions because they have been signed by the Pool LogicSig. The remaining transactions should be signed by the 'user'.

The TransactionGroup includes a method to do this when signing with a private key:

transaction_group.sign_with_private_key(account['address'], account['private_key'])

This helper method is equivalent to the following:

for i, txn in enumerate(transaction_group.transactions):
    if txn.sender == account['address']:
        transaction_group.signed_transactions[i] = txn.sign(account['private_key'])

Any alternative method of signing can be used here following the same pattern. For example using KMD:

kmd = algosdk.kmd.KMDClient(KMD_TOKEN, KMD_ADDRESS)
handle = kmd.init_wallet_handle(KMD_WALLET_ID, KMD_WALLET_PASSWORD)
for i, txn in enumerate(transaction_group.transactions):
    if txn.sender == account['address']:
        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:

transaction_group.sign_with_logicisg(logicsig)

Submission

A TransactionGroup containing fully signed transactions can be submitted to the network in either of two ways:

Using an Algod client:

algod = AlgodClient(TOKEN, ADDRESS, headers={'User-Agent': 'algosdk'})
txid = algod.send_transactions(transaction_group.signed_transactions)

Or, using the convenience method of the TinymanClient:

result = client.submit(transaction_group, wait=True)

This method submits the signed transactions and optionally waits for confirmation.

License

tinyman-py-sdk is licensed under a MIT license except for the exceptions listed below. See the LICENSE file for details.

Exceptions

tinyman/v1/asc.json is currently unlicensed. It may be used by this SDK but may not be used in any other way or be distributed separately without the express permission of Tinyman.

Comments
  • ASA with Unicode character 🪙 in unit-name raises KeyError in pools.py

    ASA with Unicode character 🪙 in unit-name raises KeyError in pools.py

    pool = {
    ...
        liquidity_asset_name': liquidity_asset['params']['name']
    ...
    

    A workaround for us is just a simple liquidity_asset['params'].get('name'), but you'd probably want a solution/name that includes the other ASA in the pool.

    opened by ipaleka 7
  • Mainnet: OPUL/ALGO Pool Returning Wrong Quote

    Mainnet: OPUL/ALGO Pool Returning Wrong Quote

    Running the following on mainnet:

    ALGO = client.fetch_asset(0)
    OPUL = client.fetch_asset(287867876)
    pool = client.fetch_pool(OPUL, ALGO)
    quote = pool.fetch_fixed_input_swap_quote(ALGO(2500), slippage=0.01)
    

    returns, for example, 2955 as quote.

    In reality, this is actually 0.2955, so the quote is actually is off by exactly 10000 for some reason.

    opened by albertshin 5
  • v1.0 Pools appear irretrievable

    v1.0 Pools appear irretrievable

    Minimum code to reproduce:

    from tinyman.v1.client import TinymanClient
    from algosdk.v2client.algod import AlgodClient
    
    algod = AlgodClient('', 'https://api.algoexplorer.io', headers={'User-Agent': 'algosdk'})
    
    # V1 client
    client_v1 = TinymanClient(algod_client=algod, validator_app_id=350338509)
    # V1.1 client
    client_v2 = TinymanClient(algod_client=algod, validator_app_id=552635992)
    
    # Get two assets
    YLDY = client_v1.fetch_asset(226701642)
    ALGO = client_v1.fetch_asset(0)
    
    # Find pool (which definitely still exists)
    # Actual target address is 
    # Y74RXNAUAZT2U5PD57Y22NVU6UPW5WNLRLHA763EE5IJSLSJXRAX6YY4OE
    pool = client_v1.fetch_pool(YLDY, ALGO)
    pool.address # FNWKQUJCBFEW3OIUFAV5WD5WF6YZ52DKCVVCVTW5G53TOY5RS4AX57SFXU
    
    # Actual target address is 
    # KX6S647W6BEN6XHEJVMXK3UYLVNGT2Q6PHQSF5AA2JSSDFSOX7R4MESXRY
    pool2 = client_v2.fetch_pool(YLDY, ALGO)
    pool2.address # KX6S647W6BEN6XHEJVMXK3UYLVNGT2Q6PHQSF5AA2JSSDFSOX7R4MESXRY
    
    wontfix 
    opened by jmrMOONBOI 4
  • Limit Exceeded

    Limit Exceeded

    I have been trying to keep an updated price of an ASA. It was originally checking at 10 second intervals, I have also tried it at 30 second intervals. It can run happily for anywhere between 2 and 8 hrs, but then I get the 429 error and limit exceeded message. Once banned / blocked, there doesn't seem to be any clue as to when I will be unblocked.

    The error comes directly from calling: pool = client.fetch_pool then quote = pool.fetch_fixed_input_swap_quote I'm using the standard example code for getting the swap quotes

    1. What are the API limits?
    2. Is there any way to catch this before it triggers the block / ban?
    3. Is this something tinyman-py-sdk should handle, or is it an algod issue?

    I haven't been able to find anything about the API rate limit online

    opened by scoobie-bot 4
  • Exception after submitting an order

    Exception after submitting an order

    I have a loop in which I am checking some conditions. Once these conditions verified, I am submitting an order.

    Very few times where the submit function is called without an error but most of the time I have the following exception.

    result = client.submit(transaction_group1, wait=True) File "D:\Programs\lib\site-packages\tinyman\v1\client.py", line 34, in submit raise Exception(json.loads(e.args[0])['message']) from None File "D:\Programs\lib\json_init_.py", line 346, in loads return _default_decoder.decode(s) File "D:\Programs\lib\json\decoder.py", line 337, in decode obj, end = self.raw_decode(s, idx=_w(s, 0).end()) File "D:\Programs\lib\json\decoder.py", line 355, in raw_decode raise JSONDecodeError("Expecting value", s, err.value) from None json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

    Any idea about the root cause of this non deterministic behavior resulting to this exception? Many Thanks

    opened by BrelKsiba 4
  • added asset optin for client

    added asset optin for client

    I have added an opt in transaction for assets in the client, which makes it simpler to resolve the error raised in https://github.com/tinymanorg/tinyman-py-sdk/issues/8

    opened by fdreyer 4
  • Return incorrect information

    Return incorrect information

    I get the price of a token via sdk via the example code For example the price of goETH But there is a problem, the price received via sdk is very different from the price inside the site (I tested it again today, the price difference was about $ 40!)

    duplicate 
    opened by awminux 3
  • wait for confirmation could run into infinite loop

    wait for confirmation could run into infinite loop

    It could happen that the function wait_for_confirmation(client, txid) is running/waiting undefinitely. This happens some times for a reason that I cannot explain.

    Do you know in which case this situation can happen?

    A suggestion could be to define the wait_for_confirmation and submit functions with an additional timeout parameter, for example:

    def wait_for_confirmation(client, txid, timeout)

    and/or

    def submit(transaction_group, wait, timeout): ---> when wait = True, a timeout could be given.

    opened by BrelKsiba 3
  • How to check asset amount in wallet?

    How to check asset amount in wallet?

    thinking i may have to use algod for this? i want to keep purchasing an asset until I spend all ALGO, I don't want to purchase it all at once because slippage will be too high

    opened by majestique 3
  • Swapping on testnet

    Swapping on testnet

    I am encountering the following issue when attempting to exchange two coins on tinyman using testnet.

    Following the steps inhttps://github.com/tinymanorg/tinyman-py-sdk/blob/main/examples/swapping1.py, which work for Mainnet without problem, the code crashes with an AlgodHTTPError. Here is a minimal example:

    from tinyman.v1.client import TinymanTestnetClient
    client=TinymanTestnetClient(user_address=address)
    assert(client.is_opted_in())
    algo=client.fetch_asset(0)
    usdc=client.fetch_asset(10458941)
    pool = client.fetch_pool(usdc, algo)
    quote = pool.fetch_fixed_input_swap_quote(algo(1_000_000), slippage=0.01)
    transaction_group = pool.prepare_swap_transactions_from_quote(quote)
    transaction_group.sign_with_private_key(address, private_key)
    result = client.submit(transaction_group, wait=True)
    

    which fails with the following error

    ---------------------------------------------------------------------------
    JSONDecodeError                           Traceback (most recent call last)
    <ipython-input-10-82e8ae16ad39> in <module>
          5 transaction_group = pool.prepare_swap_transactions_from_quote(quote)
          6 transaction_group.sign_with_private_key(address, private_key)
    ----> 7 result = client.submit(transaction_group, wait=True)
    
    ~/.local/lib/python3.9/site-packages/tinyman/v1/client.py in submit(self, transaction_group, wait)
         32             txid = self.algod.send_transactions(transaction_group.signed_transactions)
         33         except AlgodHTTPError as e:
    ---> 34             raise Exception(json.loads(e.args[0])['message']) from None
         35         if wait:
         36             return wait_for_confirmation(self.algod, txid)
    
    /usr/lib/python3.9/json/__init__.py in loads(s, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw)
        344             parse_int is None and parse_float is None and
        345             parse_constant is None and object_pairs_hook is None and not kw):
    --> 346         return _default_decoder.decode(s)
        347     if cls is None:
        348         cls = JSONDecoder
    
    /usr/lib/python3.9/json/decoder.py in decode(self, s, _w)
        335 
        336         """
    --> 337         obj, end = self.raw_decode(s, idx=_w(s, 0).end())
        338         end = _w(s, end).end()
        339         if end != len(s):
    
    /usr/lib/python3.9/json/decoder.py in raw_decode(self, s, idx)
        353             obj, end = self.scan_once(s, idx)
        354         except StopIteration as err:
    --> 355             raise JSONDecodeError("Expecting value", s, err.value) from None
        356         return obj, end
    
    JSONDecodeError: Expecting value: line 1 column 1 (char 0)
    

    Is there something that needs to be set up differently for a swap on testnet, or perhaps something that changed on the algosdk library which is causing this issue?

    opened by fdreyer 3
  • msgpack decode error [pos 294]: only encoded map or array can be decoded into a struct

    msgpack decode error [pos 294]: only encoded map or array can be decoded into a struct

    Getting err mentioned in the title on submitting the swap group transaction

    Right now i am using node v 14.0 and algosdk version 1.17.0

    Steps to reproduce

    so here is what we are doing we are trying to swap using tinyman sdk we have a backend i send him params req to do swapping there he creates 4 transaction ( a group transaction) 2 of which are meant to be signed by tinyman sdk and two are meant to be signed by the frontend aka the person who is trying to do the swapping ... so what backend does is he signs the txn that needs to be signed by the backend and send me the all 4 txns ... i sign the remaining 2 txns and create a array and submit those ... while submitting that txn i get the msgpack error at pos: 294

    here is the code that i am performing on the frontend

                                 const decoded_txn1 = algosdk.decodeSignedTransaction(
    				Buffer.from(res.data.signed_txn.stxn1, "base64")
    			).lsig?.l;
    			console.log(
    				"the decoded txn is :",
    				algosdk.decodeSignedTransaction(
    					Buffer.from(res.data.signed_txn.stxn1, "base64")
    				)
    			);
    			const decoded_txn2 = algosdk.decodeSignedTransaction(
    				Buffer.from(res.data.signed_txn.stxn2, "base64")
    			).lsig?.l;
    			console.log(
    				"the decoded txn is :",
    				algosdk.decodeSignedTransaction(
    					Buffer.from(res.data.signed_txn.stxn2, "base64")
    				)
    			);
    			// const txnId1 = await myAlgoConnect.signTransaction(res.data[0].txn);
    			const signedTxns: any = await myAlgoConnect.signTransaction(
    				[res.data.unsigned_txn.txn1, res.data.unsigned_txn.txn2].map(
    					(txn: any) => txn
    				)
    			);
    			console.log("the signed txn is :", signedTxns);
    			const signed = [];
    			signed.push(signedTxns[0].blob);
    			signed.push(decoded_txn1);
    			signed.push(signedTxns[1].blob);
    			signed.push(decoded_txn2);
    
    			console.log("the signe array is :", signed);
    
    			let tx = await client.sendRawTransaction(signed).do();
    			console.log("Transaction : " + tx.txId);
    			let confirmedTxn = await algosdk.waitForConfirmation(
    				client,
    				tx.txId,
    				4
    			);
    			console.log("the confirmed txn is :", confirmedTxn);
    		}
    

    -the res.data.signed_txn are the txn that are already signed by the backend -the res.data.unsigned_txn are the txn that needs to be signed by the frontend

    the data that i am getting from backend is { "signed_txn": { "stxn1": "gqRsc2lngaFsxQNcBCAIAQAAva7+BAMEBQYlJA1EMQkyAxJEMRUyAxJEMSAyAxJEMgQiDUQzAQAxABJEMwEQIQcSRDMBGIGs194dEkQzARkiEjMBGyEEEhA3ARoAgAlib290c3RyYXASEEAAXDMBGSMSRDMBG4ECEjcBGgCABHN3YXASEEACOzMBGyISRDcBGgCABG1pbnQSQAE7NwEaAIAEYnVybhJAAZg3ARoAgAZyZWRlZW0SQAJbNwEaAIAEZmVlcxJAAnkAIQYhBSQjEk0yBBJENwEaARclEjcBGgIXJBIQRDMCADEAEkQzAhAhBBJEMwIhIxJEMwIiIxwSRDMCIyEHEkQzAiQjEkQzAiWACFRNUE9PTDExEkQzAiZRAA+AD1RpbnltYW5Qb29sMS4xIBJEMwIngBNodHRwczovL3RpbnltYW4ub3JnEkQzAikyAxJEMwIqMgMSRDMCKzIDEkQzAiwyAxJEMwMAMQASRDMDECEFEkQzAxElEkQzAxQxABJEMwMSIxJEJCMTQAAQMwEBMwIBCDMDAQg1AUIBsTMEADEAEkQzBBAhBRJEMwQRJBJEMwQUMQASRDMEEiMSRDMBATMCAQgzAwEIMwQBCDUBQgF8MgQhBhJENwEcATEAE0Q3ARwBMwQUEkQzAgAxABNEMwIUMQASRDMDADMCABJEMwIRJRJEMwMUMwMHMwMQIhJNMQASRDMDESMzAxAiEk0kEkQzBAAxABJEMwQUMwIAEkQzAQEzBAEINQFCAREyBCEGEkQ3ARwBMQATRDcBHAEzAhQSRDMDFDMDBzMDECISTTcBHAESRDMCADEAEkQzAhQzBAASRDMCESUSRDMDADEAEkQzAxQzAwczAxAiEk0zBAASRDMDESMzAxAiEk0kEkQzBAAxABNEMwQUMQASRDMBATMCAQgzAwEINQFCAJAyBCEFEkQ3ARwBMQATRDMCADcBHAESRDMCADEAE0QzAwAxABJEMwIUMwIHMwIQIhJNMQASRDMDFDMDBzMDECISTTMCABJEMwEBMwMBCDUBQgA+MgQhBBJENwEcATEAE0QzAhQzAgczAhAiEk03ARwBEkQzAQEzAgEINQFCABIyBCEEEkQzAQEzAgEINQFCAAAzAAAxABNEMwAHMQASRDMACDQBD0OjdHhujKRhcGFhksQEc3dhcMQCZmmkYXBhc5LOAJ+XPc4DuCvcpGFwYXSRxCAEzdCClExhS38IXK2Ty2C4ALvYIPveAQnXc4K5GMZ0K6RhcGlkzgO3q6yjZmVlzQPoomZ2zgFSlVujZ2VurHRlc3RuZXQtdjEuMKJnaMQgSGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiKjZ3JwxCASDWuTSLUW+zDJsUot+B3TCItojg+n8oHeoe7ZC2teaKJsds4BUplDo3NuZMQgS4jy0Gb7ZcISjP2zb5geqse5Tl0YxJsqRg6gs6LDLoSkdHlwZaRhcHBs", "stxn2": "gqRsc2lngaFsxQNcBCAIAQAAva7+BAMEBQYlJA1EMQkyAxJEMRUyAxJEMSAyAxJEMgQiDUQzAQAxABJEMwEQIQcSRDMBGIGs194dEkQzARkiEjMBGyEEEhA3ARoAgAlib290c3RyYXASEEAAXDMBGSMSRDMBG4ECEjcBGgCABHN3YXASEEACOzMBGyISRDcBGgCABG1pbnQSQAE7NwEaAIAEYnVybhJAAZg3ARoAgAZyZWRlZW0SQAJbNwEaAIAEZmVlcxJAAnkAIQYhBSQjEk0yBBJENwEaARclEjcBGgIXJBIQRDMCADEAEkQzAhAhBBJEMwIhIxJEMwIiIxwSRDMCIyEHEkQzAiQjEkQzAiWACFRNUE9PTDExEkQzAiZRAA+AD1RpbnltYW5Qb29sMS4xIBJEMwIngBNodHRwczovL3RpbnltYW4ub3JnEkQzAikyAxJEMwIqMgMSRDMCKzIDEkQzAiwyAxJEMwMAMQASRDMDECEFEkQzAxElEkQzAxQxABJEMwMSIxJEJCMTQAAQMwEBMwIBCDMDAQg1AUIBsTMEADEAEkQzBBAhBRJEMwQRJBJEMwQUMQASRDMEEiMSRDMBATMCAQgzAwEIMwQBCDUBQgF8MgQhBhJENwEcATEAE0Q3ARwBMwQUEkQzAgAxABNEMwIUMQASRDMDADMCABJEMwIRJRJEMwMUMwMHMwMQIhJNMQASRDMDESMzAxAiEk0kEkQzBAAxABJEMwQUMwIAEkQzAQEzBAEINQFCAREyBCEGEkQ3ARwBMQATRDcBHAEzAhQSRDMDFDMDBzMDECISTTcBHAESRDMCADEAEkQzAhQzBAASRDMCESUSRDMDADEAEkQzAxQzAwczAxAiEk0zBAASRDMDESMzAxAiEk0kEkQzBAAxABNEMwQUMQASRDMBATMCAQgzAwEINQFCAJAyBCEFEkQ3ARwBMQATRDMCADcBHAESRDMCADEAE0QzAwAxABJEMwIUMwIHMwIQIhJNMQASRDMDFDMDBzMDECISTTMCABJEMwEBMwMBCDUBQgA+MgQhBBJENwEcATEAE0QzAhQzAgczAhAiEk03ARwBEkQzAQEzAgEINQFCABIyBCEEEkQzAQEzAgEINQFCAAAzAAAxABNEMwAHMQASRDMACDQBD0OjdHhui6RhYW10zgGBEjekYXJjdsQgBM3QgpRMYUt/CFytk8tguAC72CD73gEJ13OCuRjGdCujZmVlzQPoomZ2zgFSlVujZ2VurHRlc3RuZXQtdjEuMKJnaMQgSGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiKjZ3JwxCASDWuTSLUW+zDJsUot+B3TCItojg+n8oHeoe7ZC2teaKJsds4BUplDo3NuZMQgS4jy0Gb7ZcISjP2zb5geqse5Tl0YxJsqRg6gs6LDLoSkdHlwZaVheGZlcqR4YWlkzgCflz0=" }, "unsigned_txn": { "txn1": "i6NhbXTNB9CjZmVlzQPoomZ2zgFSlVujZ2VurHRlc3RuZXQtdjEuMKJnaMQgSGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiKjZ3JwxCASDWuTSLUW+zDJsUot+B3TCItojg+n8oHeoe7ZC2teaKJsds4BUplDpG5vdGXEA2ZlZaNyY3bEIEuI8tBm+2XCEoz9s2+YHqrHuU5dGMSbKkYOoLOiwy6Eo3NuZMQgBM3QgpRMYUt/CFytk8tguAC72CD73gEJ13OCuRjGdCukdHlwZaNwYXk=", "txn2": "iqNhbXTOAGrPwKNmZWXNA+iiZnbOAVKVW6NnZW6sdGVzdG5ldC12MS4womdoxCBIY7UYpLPITsgQ8i1PEIHLD3HwWaesIN7GL39w5Qk6IqNncnDEIBINa5NItRb7MMmxSi34HdMIi2iOD6fygd6h7tkLa15oomx2zgFSmUOjcmN2xCBLiPLQZvtlwhKM/bNvmB6qx7lOXRjEmypGDqCzosMuhKNzbmTEIATN0IKUTGFLfwhcrZPLYLgAu9gg+94BCddzgrkYxnQrpHR5cGWjcGF5" } }

    these are encoded txns

    after decoding the signed txn from the backend i get

    Screenshot 2022-06-13 at 1 00 11 PM

    now i am submitting the lsig.l to the submit fuction but getting the error at that time

    Expected behaviour

    the group txn should submit

    Actual behaviour

    gitves back a error msgpack decode error [pos 294]: only encoded map or array can be decoded into a struct

    help wanted question 
    opened by aryanwebmob 2
  • Compatibility issue with py-algorand-sdk 2.0.0

    Compatibility issue with py-algorand-sdk 2.0.0

    https://github.com/algorand/py-algorand-sdk/releases/tag/v2.0.0

    All the code from the algosdk.future package is moved directly under algosdk.

    So, for example

    from algosdk.future.transaction import LogicSigAccount

    becomes

    from algosdk.transaction import LogicSigAccount

    `

    opened by ipaleka 0
  • V1 - Mismatch between minimum received in webapp and SDK

    V1 - Mismatch between minimum received in webapp and SDK

    I noticed a mismatch of minimum price between the webapp and the SDK.

    Here the results of the quote from SDK:

    Here a print of the quote: SwapQuote(swap_type='fixed-input', amount_in=ALGO('700'), amount_out=Planets('30848.706199'), swap_fees=ALGO('2.1'), slippage=0.005, price_impact=0.00644)

    Here the print of amount expected with slippage: print(quote2.amount_out_with_slippage); Planets('30694.462669')

    This is different from what I see in the webapp (since many days) image

    As you can see the amount_out is correct. However, the amount_out_with_slippage seems to be not correct.

    I noticed also that sometimes, even the amount_out does not match. Here I changed th amount_in to 500 ALGO. I am getting the following: SDK: SwapQuote(swap_type='fixed-input', amount_in=ALGO('500'), amount_out=Planets('23341.505158'), swap_fees=ALGO('1.5'), slippage=0.005, price_impact=0.00553)

    webapp: image

    The amount_out in this case is not the same.

    This code was working months agso and I was getting exact results between the webapp and the SDK.

    Best regards, HHA

    wontfix 
    opened by BrelKsiba 2
  • TxnGroup.submit should raise an error if any of the signed_transactions is None

    TxnGroup.submit should raise an error if any of the signed_transactions is None

    https://github.com/tinymanorg/tinyman-py-sdk/blob/40ca5536b7e31d642954ed4e3e9ee773e598c28d/tinyman/utils.py#L108

    If any of the elements of signed_transactions is None we should raise an error to inform the user that not all transactions have been signed.

    The same applies to client.submit: https://github.com/tinymanorg/tinyman-py-sdk/blob/40ca5536b7e31d642954ed4e3e9ee773e598c28d/tinyman/v1/client.py#L30

    enhancement good first issue 
    opened by fergalwalsh 0
  • TxnGroup.sign_with_private_key should raise an error if the address is not one of the senders

    TxnGroup.sign_with_private_key should raise an error if the address is not one of the senders

    https://github.com/tinymanorg/tinyman-py-sdk/blob/40ca5536b7e31d642954ed4e3e9ee773e598c28d/tinyman/utils.py#L103

    If the address is not one of the senders we should raise an error. This has tripped up some people who were passing a different address to the one used to generate the transactions but didn't get any error.

    PS. Don't be tempted to refactor this to require only a private key and derive the address from that - that won't work for rekeyed accounts.

    enhancement good first issue 
    opened by fergalwalsh 0
  • V1 - Swap quote mismatch

    V1 - Swap quote mismatch

    Hi 👋

    I'm trying to get fixed input swap quote and I noticed it's not correct for some pools. In below example PAGO/ALGO pool on the testnet.

    from tinyman.v1.client import TinymanTestnetClient
    
    client = TinymanTestnetClient(algod_client)
    
    asset1 = client.fetch_asset(92772865)
    asset2 = client.fetch_asset(0)
    amount = 80
    asset_in = asset1
    
    pool = client.fetch_pool(asset1, asset2)
    quote = pool.fetch_fixed_input_swap_quote(asset_in(amount * 10 ** asset_in.decimals), slippage=0.05)
    

    I get the following quote for ALGO out amount and min out amount

    image

    while in the Tinyman app I get

    image

    which is almost the same but still slightly different.

    When I make the transaction from the app the value I receive is matching the minimum value from the app but it seems like the total value (min + excess) is matching the value calculated by the SDK https://testnet.algoexplorer.io/tx/group/MEYPju6fy6LvBzph49xU%2BmvYyj3bpdf4A0FlmYTykU0%3D

    image

    image

    image

    Looks like the bug is on the app side not SDK but maybe you can double check it and confirm?

    bug enhancement wontfix 
    opened by kasia-antos 2
  • Can't send two swap transactions in the same round.

    Can't send two swap transactions in the same round.

    Due to the first transaction in all groups being the same (send 0.002 Algo from sender to escrow for the fees), the transaction ID will be the same if you attempt to create two different swaps and send them within the same round.

    The issue is similar to an old bug when you trying to trade 0.002 Algo for any other ASA and the group transaction would fail saying the transaction already exists, The resolution was to add "fee" into the node field. However because when you send two separate swaps each group has its own "fee" transaction with identical parameters, the second group will always fail because the fee transaction already exists in this round (if the round was different and the firstvalid and last valid were shifted by 1 it would be a different txid).

    My temporary solution to this was to dump 8 random bytes of data into the note field instead of "fee".

    bug enhancement 
    opened by nullun 0
Owner
Tinyman
Tinyman
Tinyman Python SDK

tinyman-py-sdk Tinyman Python SDK Design Goal This SDK is designed for automated interaction with the Tinyman AMM. It will be most useful for develope

Tinyman 113 Dec 30, 2022
Graviti-python-sdk - Graviti Data Platform Python SDK

Graviti Python SDK Graviti Python SDK is a python library to access Graviti Data

Graviti 13 Dec 15, 2022
AWS SDK for Python

Boto3 - The AWS SDK for Python Boto3 is the Amazon Web Services (AWS) Software Development Kit (SDK) for Python, which allows Python developers to wri

the boto project 7.8k Jan 8, 2023
Python SDK for Facebook's Graph API

Facebook Python SDK This client library is designed to support the Facebook Graph API and the official Facebook JavaScript SDK, which is the canonical

Mobolic 2.7k Jan 7, 2023
Box SDK for Python

Box Python SDK Installing Getting Started Authorization Server-to-Server Auth with JWT Traditional 3-legged OAuth2 Other Auth Options Usage Documentat

Box 371 Dec 29, 2022
The Official Dropbox API V2 SDK for Python

The offical Dropbox SDK for Python. Documentation can be found on Read The Docs. Installation Create an app via the Developer Console. Install via pip

Dropbox 828 Jan 5, 2023
Evernote SDK for Python

Evernote SDK for Python Evernote API version 1.28 This SDK is intended for use with Python 2.X For Evernote's beta Python 3 SDK see https://github.com

Evernote 612 Dec 30, 2022
Python SDK for IEX Cloud

iexfinance Python SDK for IEX Cloud. Architecture mirrors that of the IEX Cloud API (and its documentation). An easy-to-use toolkit to obtain data for

Addison Lynch 640 Jan 7, 2023
Unofficial Medium Python Flask API and SDK

PyMedium - Unofficial Medium API PyMedium is an unofficial Medium API written in python flask. It provides developers to access to user, post list and

Engine Bai 157 Nov 11, 2022
The Python SDK for the Rackspace Cloud

pyrax Python SDK for OpenStack/Rackspace APIs DEPRECATED: Pyrax is no longer being developed or supported. See openstacksdk and the rackspacesdk plugi

PyContribs 238 Sep 21, 2022
:snake: Python SDK to query Scaleway APIs.

Scaleway SDK Python SDK to query Scaleway's APIs. Stable release: Development: Installation The package is available on pip. To install it in a virtua

Scaleway 114 Dec 11, 2022
Skyscanner Python SDK

Skyscanner Python SDK Important As of May 1st, 2020, the project is deprecated and no longer maintained. The latest update in v1.1.5 includes changing

Skyscanner 118 Sep 23, 2022
WeChat SDK for Python

___ __ _______ ________ ___ ___ ________ _________ ________ ___ ___ |\ \ |\ \|\ ___ \ |\ ____\|\ \|\ \|\ __ \|\___

wechatpy 3.3k Dec 26, 2022
Python SDK for the Buycoins API.

This library provides easy access to the Buycoins API using the Python programming language. It provides all the feature of the API so that you don't need to interact with the API directly. This library can be used with Python 3.6+

Musa Rasheed 48 May 4, 2022
Graviti TensorBay Python SDK

TensorBay Python SDK is a python library to access TensorBay and manage your datasets. It provides: A pythonic way to access your

Graviti 72 Aug 22, 2022
A Python script for rendering glTF files with V-Ray App SDK

V-Ray glTF viewer Overview The V-Ray glTF viewer is a set of Python scripts for the V-Ray App SDK that allow the parsing and rendering of glTF (.gltf

Chaos 24 Dec 5, 2022
qualysclient - a python SDK for interacting with the Qualys API

qualysclient - a python SDK for interacting with the Qualys API

null 5 Oct 28, 2022
A Python SDK for connecting devices to Microsoft Azure IoT services

V2 - We are now GA! This repository contains code for the Azure IoT SDKs for Python. This enables python developers to easily create IoT device soluti

Microsoft Azure 381 Dec 30, 2022