Giter Club home page Giter Club logo

terra.py's Introduction

DEPRECATED

Terra SDK python library will not be maintained any further by TFL officialy. Alternative options to this library can be found here:



py-sdk-logo

The Python SDK for Terra

(Unfamiliar with Terra? Check out the Terra Docs)

GitHub Python pip

Explore the Docs »
PyPI Package · GitHub Repository

The Terra Software Development Kit (SDK) in Python is a simple library toolkit for building software that can interact with the Terra blockchain and provides simple abstractions over core data structures, serialization, key management, and API request generation.

Features

  • Written in Python with extensive support libraries
  • Versatile support for key management solutions
  • Exposes the Terra API through LCDClient

Table of Contents


API Reference

An intricate reference to the APIs on the Terra SDK can be found here.


Getting Started

A walk-through of the steps to get started with the Terra SDK alongside a few use case examples are provided below. Alternatively, a tutorial video is also available here as reference.

Requirements

Terra SDK requires Python v3.7+.

Installation

NOTE: All code starting with a $ is meant to run on your terminal (a bash prompt). All code starting with a >>> is meant to run in a python interpreter, like ipython.

Terra SDK can be installed (preferably in a virtual environment from PyPI using pip) as follows:

$ pip install -U terra_sdk

You might have pip3 installed instead of pip; proceed according to your own setup.

❗ If you want to communicate with Terra Classic, use terra-sdk==2.x

Dependencies

Terra SDK uses Poetry to manage dependencies. To get set up with all the required dependencies, run:

$ pip install poetry
$ poetry install

Tests

Terra SDK provides extensive tests for data classes and functions. To run them, after the steps in Dependencies:

$ make test

Code Quality

Terra SDK uses Black, isort, and Mypy for checking code quality and maintaining style. To reformat, after the steps in Dependencies:

$ make qa && make format

Usage Examples

Terra SDK can help you read block data, sign and send transactions, deploy and interact with contracts, and many more. The following examples are provided to help you get started. Use cases and functionalities of the Terra SDK are not limited to the following examples and can be found in full here.

In order to interact with the Terra blockchain, you'll need a connection to a Terra node. This can be done through setting up an LCDClient (The LCDClient is an object representing an HTTP connection to a Terra LCD node.):

>>> from terra_sdk.client.lcd import LCDClient
>>> terra = LCDClient(chain_id="phoenix-1", url="https://phoenix-lcd.terra.dev")

Getting Blockchain Information

Once properly configured, the LCDClient instance will allow you to interact with the Terra blockchain. Try getting the latest block height:

>>> terra.tendermint.block_info()['block']['header']['height']

'1687543'

Async Usage

If you want to make asynchronous, non-blocking LCD requests, you can use AsyncLCDClient. The interface is similar to LCDClient, except the module and wallet API functions must be awaited.


>>> import asyncio 
>>> from terra_sdk.client.lcd import AsyncLCDClient

>>> async def main():
      terra = AsyncLCDClient("https://phoenix-lcd.terra.dev", "phoenix-1")
      total_supply = await terra.bank.total()
      print(total_supply)
      await terra.session.close # you must close the session

>>> asyncio.get_event_loop().run_until_complete(main())

Building and Signing Transactions

If you wish to perform a state-changing operation on the Terra blockchain such as sending tokens, swapping assets, withdrawing rewards, or even invoking functions on smart contracts, you must create a transaction and broadcast it to the network. Terra SDK provides functions that help create StdTx objects.

Example Using a Wallet (recommended)

A Wallet allows you to create and sign a transaction in a single step by automatically fetching the latest information from the blockchain (chain ID, account number, sequence).

Use LCDClient.wallet() to create a Wallet from any Key instance. The Key provided should correspond to the account you intend to sign the transaction with.

NOTE: If you are using MacOS and got an exception 'bad key length' from MnemonicKey, please check your python implementation. if python3 -c "import ssl; print(ssl.OPENSSL_VERSION)" returns LibreSSL 2.8.3, you need to reinstall python via pyenv or homebrew.

>>> from terra_sdk.client.lcd import LCDClient
>>> from terra_sdk.key.mnemonic import MnemonicKey

>>> mk = MnemonicKey(mnemonic=MNEMONIC)
>>> terra = LCDClient("https://phoenix-lcd.terra.dev", "phoenix-1")
>>> wallet = terra.wallet(mk)

Once you have your Wallet, you can simply create a StdTx using Wallet.create_and_sign_tx.

>>> from terra_sdk.core.fee import Fee
>>> from terra_sdk.core.bank import MsgSend
>>> from terra_sdk.client.lcd.api.tx import CreateTxOptions

>>> tx = wallet.create_and_sign_tx(CreateTxOptions(
        msgs=[MsgSend(
            wallet.key.acc_address,
            RECIPIENT,
            "1000000uluna"    # send 1 luna
        )],
        memo="test transaction!",
        fee=Fee(200000, "120000uluna")
    ))

You should now be able to broadcast your transaction to the network.

>>> result = terra.tx.broadcast(tx)
>>> print(result)

Contributing

Community contribution, whether it's a new feature, correction, bug report, additional documentation, or any other feedback is always welcome. Please read through this section to ensure that your contribution is in the most suitable format for us to effectively process.


Reporting an Issue

First things first: Do NOT report security vulnerabilities in public issues! Please disclose responsibly by submitting your findings to the Terra Bugcrowd submission form. The issue will be assessed as soon as possible. If you encounter a different issue with the Python SDK, check first to see if there is an existing issue on the Issues page, or if there is a pull request on the Pull requests page. Be sure to check both the Open and Closed tabs addressing the issue.

If there isn't a discussion on the topic there, you can file an issue. The ideal report includes:

  • A description of the problem / suggestion.
  • How to recreate the bug.
  • If relevant, including the versions of your:
    • Python interpreter
    • Terra SDK
    • Optionally of the other dependencies involved
  • If possible, create a pull request with a (failing) test case demonstrating what's wrong. This makes the process for fixing bugs quicker & gets issues resolved sooner.

Requesting a Feature

If you wish to request the addition of a feature, please first check out the Issues page and the Pull requests page (both Open and Closed tabs). If you decide to continue with the request, think of the merits of the feature to convince the project's developers, and provide as much detail and context as possible in the form of filing an issue on the Issues page.


Contributing Code

If you wish to contribute to the repository in the form of patches, improvements, new features, etc., first scale the contribution. If it is a major development, like implementing a feature, it is recommended that you consult with the developers of the project before starting the development to avoid duplicating efforts. Once confirmed, you are welcome to submit your pull request.

For new contributors, here is a quick guide:

  1. Fork the repository.
  2. Build the project using the Dependencies and Tests steps.
  3. Install a virtualenv.
  4. Develop your code and test the changes using the Tests and Code Quality steps.
  5. Commit your changes (ideally follow the Angular commit message guidelines).
  6. Push your fork and submit a pull request to the repository's main branch to propose your code.

A good pull request:

  • Is clear and concise.
  • Works across all supported versions of Python. (3.7+)
  • Follows the existing style of the code base (Flake8).
  • Has comments included as needed.
  • Includes a test case that demonstrates the previous flaw that now passes with the included patch, or demonstrates the newly added feature.
  • Must include documentation for changing or adding any public APIs.
  • Must be appropriately licensed (MIT License).

Documentation Contributions

Documentation improvements are always welcome. The documentation files live in the docs directory of the repository and are written in reStructuredText and use Sphinx to create the full suite of documentation.
When contributing documentation, please do your best to follow the style of the documentation files. This means a soft limit of 88 characters wide in your text files and a semi-formal, yet friendly and approachable, prose style. You can propose your improvements by submitting a pull request as explained above.

Need more information on how to contribute?

You can give this guide read for more insight.


License

This software is licensed under the MIT license. See LICENSE for full disclosure.

© 2021 Terraform Labs, PTE.


 

Terra-logo

Powering the innovation of money.

terra.py's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

terra.py's Issues

Fee estimator "fee_denoms" is no longer working on col-5 branch

Hi guys,

I'm testing col5 branch and it seems the way to simulate a fee against the node is no longer working. I'm just passing fee_denoms=["uusd"] as normal and the following error returns:

strconv.ParseFloat: parsing "['uusd']": invalid syntax

Thank you

Error Estimating TX Fee

  • terra_sdk version: 1.01
  • Python version: 3.9
  • Operating System: Windows 10

Description

I am attempting to use the terra.tx.estimate_fee() to provide an estimate of the fee cost for submitting a transaction which requires a the Union of a StdSignMsg and a StdTx. StdSignMsg requires a fee parameter which seems to defeat the purpose of estimating the fee. If you continue along and provide the fee, tx.estimate_fee() requires the Union of two nonhashable objects to form a tx object? I am looking to get a value similar to how Terra Station estimates the fee cost for a transaction. Is this the correct function or should I be looking at something else?

What I Did

try:
    terra = LCDClient(chain_id="bombay-12", url="https://bombay-lcd.terra.dev")
    mk = MnemonicKey(mnemonic="<mnumonic>")
    wallet = terra.wallet(mk)
    tx = wallet.create_and_sign_tx(
        msgs=[MsgSend(wallet.key.acc_address,
                      "terra1fa0trn2nqjc2n6mmz9txta7ky5h5nnp9m6cra3", "1000uluna")],
        memo="test transaction!",
        fee_denoms=["uluna"])
    stdmsg = StdSignMsg(chain_id="bombay-12", account_number=wallet.account_number(), sequence=wallet.sequence(), msgs=[MsgSend(wallet.key.acc_address,
                      "terra1y0acvg6lsla7hugagm2scapqqx5fp59gukptmv", "1000uluna")], memo="Test", fee="20000uluna")
    print(terra.tx.estimate_fee({stdmsg, tx}))
    print(tx)
except LCDResponseError as e:
    print(e)

The Error:

Traceback (most recent call last):
  File "C:/Users/User/git_repos/terra/main.py", line 36, in estimate_fee_bombay
    print(terra.tx.estimate_fee({stdmsg, tx}))
TypeError: unhashable type: 'StdSignMsg'

ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host

terra_sdk version: 2.0.5
Python version: 3.9.4
Operating System: Windows

Description

I am calling my wallets bank in a python console, and received this error. After reading, I dont quite understand it and thought id reach out for some help. when not using async do I need to be closing a previous connection?

What I Did

terra = LCDClient(
"https://lcd.terra.dev", "columbus-5"
)

mk = MnemonicKey(
mnemonic=walletkey
)
wallet = client.wallet(mk)
bank = pd.DataFrame(
client.bank.balance(wallet.key.acc_address)[0].to_data()
).set_index('denom').astype(int)

Exception in callback _ProactorBasePipeTransport._call_connection_lost(None)
handle: <Handle _ProactorBasePipeTransport._call_connection_lost(None)>
Traceback (most recent call last):
  File "C:\Users\rmathews\Desktop\WPy64-3940\python-3.9.4.amd64\lib\asyncio\events.py", line 80, in _run   
    self._context.run(self._callback, *self._args)
  File "C:\Users\rmathews\Desktop\WPy64-3940\python-3.9.4.amd64\lib\asyncio\proactor_events.py", line 162, 
in _call_connection_lost
    self._sock.shutdown(socket.SHUT_RDWR)
ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host

parse_msg() KeyError: '/cosmos.authz.v1beta1.MsgExec'

  • terra_sdk version: 2.0.4
  • Python version: 3.8
  • Operating System: both Win10 or Docker Compose setup

Description

cannot fetch tx_info - KeyError: '/cosmos.authz.v1beta1.MsgExec'
seems like at least this proto class is missed in parse_msg

What I Did

from terra_sdk.client.lcd import LCDClient

terra = LCDClient(chain_id="columbus-5", url="https://lcd.terra.dev")
terra.tx.tx_info('da66fac2c941d3862f743ceac2b343ff47348883e894c00506cdc58a202a5b81')

PyCharm output:

G:\PycharmProjects\cryptology\tera\venv\Scripts\python.exe G:/PycharmProjects/cryptology/tera/tera/fetch_transactions_keyerror.py
Traceback (most recent call last):
  File "G:/PycharmProjects/cryptology/tera/tera/fetch_transactions_keyerror.py", line 4, in <module>
    terra.tx.tx_info('da66fac2c941d3862f743ceac2b343ff47348883e894c00506cdc58a202a5b81')
  File "G:\PycharmProjects\cryptology\tera\venv\lib\site-packages\terra_sdk\client\lcd\api\_base.py", line 29, in decorator
    return instance._run_sync(async_call(instance, *args, **kwargs))
  File "G:\PycharmProjects\cryptology\tera\venv\lib\site-packages\terra_sdk\client\lcd\api\_base.py", line 13, in _run_sync
    return self._c.loop.run_until_complete(coroutine)
  File "G:\PycharmProjects\cryptology\tera\venv\lib\site-packages\nest_asyncio.py", line 81, in run_until_complete
    return f.result()
  File "C:\Python38\lib\asyncio\futures.py", line 178, in result
    raise self._exception
  File "C:\Python38\lib\asyncio\tasks.py", line 280, in __step
    result = coro.send(None)
  File "G:\PycharmProjects\cryptology\tera\venv\lib\site-packages\terra_sdk\client\lcd\api\tx.py", line 132, in tx_info
    return TxInfo.from_data(res["tx_response"])
  File "G:\PycharmProjects\cryptology\tera\venv\lib\site-packages\terra_sdk\core\tx.py", line 441, in from_data
    Tx.from_data(data['tx']),
  File "G:\PycharmProjects\cryptology\tera\venv\lib\site-packages\terra_sdk\core\tx.py", line 83, in from_data
    TxBody.from_data(data["body"]),
  File "G:\PycharmProjects\cryptology\tera\venv\lib\site-packages\terra_sdk\core\tx.py", line 177, in from_data
    [Msg.from_data(m) for m in data["messages"]],
  File "G:\PycharmProjects\cryptology\tera\venv\lib\site-packages\terra_sdk\core\tx.py", line 177, in <listcomp>
    [Msg.from_data(m) for m in data["messages"]],
  File "G:\PycharmProjects\cryptology\tera\venv\lib\site-packages\terra_sdk\core\msg.py", line 21, in from_data
    return parse_msg(data)
  File "G:\PycharmProjects\cryptology\tera\venv\lib\site-packages\terra_sdk\util\base.py", line 27, in from_data
    return table[data["@type"]](data)
KeyError: '/cosmos.authz.v1beta1.MsgExec'

Equivalent for v1 txs API

  • terra_sdk version: Latest columbus-5
  • Python version: 3.7
  • Operating System: Unix (google Collaboratory experiments)

Description

The V1 txs API endpoint allows to search for transactions using account ID, ex:
https://fcd.terra.dev/v1/txs?limit=100&account=terra1hyxq9usxp7fge5lx7qx3k0mqe2u55fv4xptqtc

The non-v1 API seems deprecated:
https://fcd.terra.dev/swagger

Terra-SDK looks to use the same params as the deprecated API for it's txs searches, we can call:
transactions = terra.tx.search({"message.sender":wallet})

But we cannot call:
transactions = terra.tx.search({"account":wallet})

Is there a way or to do this ?
Documentation is unclear about this method options.

Thanks !

Error during validators complete data fetch using SDK

  • terra_sdk version: 0.14.0
  • Python version:3.8
  • Operating System:mac os catalina

Description

I am working on getting all data related to validators for a particular time.To do that I started. using terra sdk and also direct api call using python request.Python request is fine but wee are interested in using sdk feature.

What I Did

I tried simple. sdk module and. call the validators as below however it failed with error and complete traceback is added:

from terra_sdk.client.lcd import LCDClient
client = LCDClient(chain_id="columbus-4", url="https://lcd.terra.dev")
validators = client.staking.validators()#client.staking.validators()#
print(validators)

Error traceback is as below:

Traceback (most recent call last):
  File "/Users/cloudusr/Documents/projects/stader-validators-data-etl-v0/etl/test.py", line 56, in <module>
    data_crawlers()
  File "/Users/cloudusr/Documents/projects/stader-validators-data-etl-v0/etl/test.py", line 38, in data_crawlers
    validators = client.staking.validators()#client.staking.validators()#
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/terra_sdk/client/lcd/api/_base.py", line 29, in decorator
    return instance._run_sync(async_call(instance, *args, **kwargs))
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/terra_sdk/client/lcd/api/_base.py", line 13, in _run_sync
    return self._c.loop.run_until_complete(coroutine)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/nest_asyncio.py", line 70, in run_until_complete
    return f.result()
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/asyncio/futures.py", line 178, in result
    raise self._exception
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/asyncio/tasks.py", line 280, in __step
    result = coro.send(None)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/terra_sdk/client/lcd/api/staking.py", line 173, in validators
    return [Validator.from_data(d) for d in res]
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/terra_sdk/client/lcd/api/staking.py", line 173, in <listcomp>
    return [Validator.from_data(d) for d in res]
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/terra_sdk/core/staking/data/validator.py", line 142, in from_data
    jailed=data["jailed"],
KeyError: 'jailed'

Process finished with exit code 1

Calling StdFee in create_and_sign_tx returns error

terra_sdk version: 1.02
Python version: 3.9.2
Operating System: Windows 10

Description

When calling create_and_sign_tx() using StdFee() to set fee rate I receive the following error message.
terra_sdk.exceptions.LCDResponseError: Status 400 - this transaction cannot be broadcasted via legacy REST endpoints, because it does not support Amino serialization. Please either use CLI, gRPC, gRPC-gateway, or directly query the Tendermint RPC endpoint to broadcast this transaction. The new REST endpoint (via gRPC-gateway) is POST /cosmos/tx/v1beta1/txs. Please also see the REST endpoints migration guide at https://docs.cosmos.network/master/migrations/rest.html for more info
No issues when I set the fee through with gas_prices and gas_adjustment.

What I Did

Broken function:

def execute_contract(msgs,gas_fee,gas_adjustment):
    tx=wallet.create_and_sign_tx(msgs=msgs
                                ,fee=fee=StdFee(1200000, '{}uusd'.format(round(fee * 1000000,0))
                                )
    result = terra.tx.broadcast(tx)
    print(f'RESULTS:{result}')

Working function:

def execute_contract(msgs,gas_fee,gas_adjustment):
    tx=wallet.create_and_sign_tx(msgs=msgs
                                ,gas_prices=gas_fee
                                ,gas_adjustment=gas_adjustment
                                )
    result = terra.tx.broadcast(tx)
    print(f'RESULTS:{result}')

Full Traceback:

Traceback (most recent call last):
  File "C:\Users\19054\Desktop\terraswap_blunaluna\testing_stdfee.py", line 50, in <module>
    test = execute_trade(blunaluna_contract_astro,0.1,'uluna',wallet,terra,0.1)
  File "C:\Users\19054\Desktop\terraswap_blunaluna\testing_stdfee.py", line 42, in execute_trade
    execute_tx_result = terra.tx.broadcast(execute_tx)
  File "C:\Users\19054\AppData\Local\Programs\Python\Python39\lib\site-packages\terra_sdk\client\lcd\api\_base.py", line 29, in decorator
    return instance._run_sync(async_call(instance, *args, **kwargs))
  File "C:\Users\19054\AppData\Local\Programs\Python\Python39\lib\site-packages\terra_sdk\client\lcd\api\_base.py", line 13, in _run_sync
    return self._c.loop.run_until_complete(coroutine)
  File "C:\Users\19054\AppData\Local\Programs\Python\Python39\lib\site-packages\nest_asyncio.py", line 70, in run_until_complete
    return f.result()
  File "C:\Users\19054\AppData\Local\Programs\Python\Python39\lib\asyncio\futures.py", line 201, in result
    raise self._exception
  File "C:\Users\19054\AppData\Local\Programs\Python\Python39\lib\asyncio\tasks.py", line 256, in __step
    result = coro.send(None)
  File "C:\Users\19054\AppData\Local\Programs\Python\Python39\lib\site-packages\terra_sdk\client\lcd\api\tx.py", line 226, in broadcast
    res = await self._broadcast(tx, "block", options)
  File "C:\Users\19054\AppData\Local\Programs\Python\Python39\lib\site-packages\terra_sdk\client\lcd\api\tx.py", line 178, in _broadcast
    return await self._c._post("/txs", data, raw=True)
  File "C:\Users\19054\AppData\Local\Programs\Python\Python39\lib\site-packages\terra_sdk\client\lcd\lcdclient.py", line 255, in _post
    result = await super()._post(*args, **kwargs)
  File "C:\Users\19054\AppData\Local\Programs\Python\Python39\lib\site-packages\terra_sdk\client\lcd\lcdclient.py", line 110, in _post
    raise LCDResponseError(message=result.get("error"), response=response)
terra_sdk.exceptions.LCDResponseError: Status 400 - this transaction cannot be broadcasted via legacy REST endpoints, because it does not support Amino serialization. Please either use CLI, gRPC, gRPC-gateway, or directly query the Tendermint RPC endpoint to broadcast this transaction. The new REST endpoint (via gRPC-gateway) is POST /cosmos/tx/v1beta1/txs. Please also see the REST endpoints migration guide at https://docs.cosmos.network/master/migrations/rest.html for more info

Can't get tx_info for hash from columbus-4

  • terra_sdk version: 1.0.0
  • Python version: 3.9.7
  • Operating System: Ubuntu 18.04.6 LTS

Description

In release 1.0.0, I cannot seem to get transaction info by tx hash when the network is columbus-4. I believe it is not respecting the chain_id value when creating the LCDClient object,

What I Did

I created a columbus-4 chain_id LCDClient object.

I followed the example in the docs here to output the tendermint.node_info network, and it returns "columbus-5" instead of "columbus-4".

I then tried to get tx_info for a transaction. The transaction definitely exists because I can find it in Terra Finder no problem. However, the request returns a 404.

from terra_sdk.client.lcd import LCDClient
terra = LCDClient(url="https://lcd.terra.dev", chain_id="columbus-4")
terra.tendermint.node_info()['node_info']['network']
>>> 'columbus-5'

terra.tx.tx_info(<tx hash>) 
>>> terra_sdk.exceptions.LCDResponseError: Status 404 - tx (<tx hash>) not found

Quart and accessing AsyncLCDClient globally?

I have some experience with other languages so I should be able to find my way through the basics of python but I am really struggling with the added quart and async aspect, which has been recommended to me instead of the sync client with flask when the sync client instantiated globally was generating async errors on POST request. I have completed the Terra SDK basics video tutorial, searched github for code where AsyncLCDClient and @app.before_serving and async def startup() are used, read through the quart tutorials, watched tutorials from the quart dev and on async but I am still stuck trying to get the basic setup of instantiating the async client, and then being able to access it and methods of it in the same function and globally as will be required.

Current code:

from quart import Quart, request
# from terra_sdk.client.lcd import LCDClient
from terra_sdk.client.lcd import AsyncLCDClient
from terra_sdk.key.mnemonic import MnemonicKey
import json, config

from terra_sdk.client.lcd.api.bank import BankAPI

# Sync version which allows global access but generates an *ASync* error on POST.
# terra = LCDClient("https://bombay-lcd.terra.dev", "bombay-12")
# wallet = terra.wallet(mk)

app = Quart(__name__)

# mk = MnemonicKey(mnemonic=config.MNEMONIC) // Production
mk = MnemonicKey()

@app.before_serving
async def startup():
    app.terra = AsyncLCDClient("https://bombay-lcd.terra.dev", "bombay-12")
    
    # Not recognised:
    # wallet = await app.terra.wallet(mk)
    # wallet = await terra.wallet(mk)

@app.route('/webhook', methods=['POST'])
async def webhook():
    data = json.loads(await request.data)

    # Not recognised:
    # info = await terra.tendermint.node_info()
    # info = await app.terra.tendermint.node_info()

    if (data['passphrase']) != config.WEBHOOK_PASSPHRASE: #Upgrade to bcrypt.
        
        return {
            "code": "error",
            "message": "invalid passphrase"
        }
    else:
            # Placeholder for order function call
            return {
             "code": "success",
             "message": "authorised"
         }

# async def order():
    # Not recognised:
    # balance = await terra.bank.balance(mk.acc_address)
    
    # Other order logic to swap tokens using functions from AsyncLCDClient

if __name__ == "__main__":
    app.run()

I was told I should be able instantiate it to app.terra, and that I should then be able to access it but I am not able to either in the same function or globally as I will need to.

Someone else recommended today I instantiate AsyncLCDClient instead in the global scope and then use modules and methods of it in async functions:

terra = AsyncLCDClient("https://bombay-lcd.terra.dev", "bombay-12")

@app.route('/webhook', methods=['POST'])
async def webhook():
    data = json.loads(await request.data)

    info = await terra.tendermint.node_info()
    print(f"Node info {info}")

Although I could then access terra globally this resulted in the following error:

   File "/home/hashewnuts/cloud/code/VisualStudioCode/quart-test/venv/lib/python3.8/site-packages/aiohttp/helpers.py", line 701, in __enter__
    raise RuntimeError(
RuntimeError: Timeout context manager should be used inside a task

I have seen aiohttp referred to as outdated and unmaintained, and as I understand it quart should be used without it. Searching for the error I also found this thread where pgjones recommends using a startup function as I have been.

I would really appreciate if someone could tell me where I am going wrong, and if possible provide me with a very basic template of how to properly instantiate terra Async using quart and access it globally that I can follow as I progress through my project.

Dev confirms using startup: https://terra-money.github.io/terra.py/guides/async.html

Error Getting Validator Rewards

  • terra_sdk version: terra-sdk-1.0.0
  • Python version: 3.9
  • Operating System: Windows 10

Description

Attempting to query the available commissions acrued from a validator using the distribution.validator_rewards(terraveloper) function. Attempted this for multiple validators' terraveloper addresses but every time code errored.

What I Did

Script

terra = LCDClient(chain_id="columbus-5", url="https://lcd.terra.dev")
print(terra.distribution.validator_rewards("terravaloper1259cmu5zyklsdkmgstxhwqpe0utfe5hhyty0at"))

Traceback:

Traceback (most recent call last):
  File "C:\Users\Micha\git_repos\comission\main.py", line 15, in <module>
    check_comission()
  File "C:\Users\Micha\git_repos\comission\main.py", line 9, in check_comission
    print(terra.distribution.validator_rewards("terravaloper1259cmu5zyklsdkmgstxhwqpe0utfe5hhyty0at"))
  File "C:\Users\Micha\git_repos\comission\venv\lib\site-packages\terra_sdk\client\lcd\api\_base.py", line 29, in decorator
    return instance._run_sync(async_call(instance, *args, **kwargs))
  File "C:\Users\Micha\git_repos\comission\venv\lib\site-packages\terra_sdk\client\lcd\api\_base.py", line 13, in _run_sync
    return self._c.loop.run_until_complete(coroutine)
  File "C:\Users\Micha\git_repos\comission\venv\lib\site-packages\nest_asyncio.py", line 70, in run_until_complete
    return f.result()
  File "C:\Users\Micha\AppData\Local\Programs\Python\Python39\lib\asyncio\futures.py", line 201, in result
    raise self._exception
  File "C:\Users\Micha\AppData\Local\Programs\Python\Python39\lib\asyncio\tasks.py", line 256, in __step
    result = coro.send(None)
  File "C:\Users\Micha\git_repos\comission\venv\lib\site-packages\terra_sdk\client\lcd\api\distribution.py", line 61, in validator_rewards
    val_commission=Coins.from_data(res["val_commission"]),
  File "C:\Users\Micha\git_repos\comission\venv\lib\site-packages\terra_sdk\core\coins.py", line 114, in from_data
    return cls(coins)
  File "C:\Users\Micha\git_repos\comission\venv\lib\site-packages\terra_sdk\core\coins.py", line 80, in __init__
    for coin in coins:
  File "C:\Users\Micha\git_repos\comission\venv\lib\site-packages\terra_sdk\core\coin.py", line 213, in from_data
    return cls(data["denom"], data["amount"])
TypeError: string indices must be integers

terra 2.0.3 typo / bug in asyncronous broadcast method

  • terra_sdk version: 2.0.3
  • Python version: 3.9
  • Operating System: Not relevant

Description

in :

terra_sdk/client/lcd/api/tx.py
method _broadcast (line 247)
data = {"tx_bytes": self.encode(tx), "mode": mode}
self.encode (l227) is defined as an asyncronous method and is never awaited, thus failing the Json serialisation.

-> self.encode should not be defined as asyncronous (it does not perform asyncronous operations).
-> self.decode (l231) neither, it may cause another failure later in the execution.

Please patch those issues before using terra 2.0.3 as a deployed service, it may open up unforeseen vulnerabilities.

What I Did

await terra.tx.broadcast(signed_tx)

create_and_sign_tx Error - 'str' object has no attribute 'sequence'

  • terra_sdk version: 2.0.3

Description

I am getting error 'str' object has no attribute 'sequence' with the create_and_sign_tx function with the latest stable release version.

I am using the CreateTxOptions as mentioned in other issues, but am getting this ^ error now.

execute_msg = MsgExecuteContract(wallet.key.acc_address, contract_addr , msg_struct )
tx_opt = CreateTxOptions(msgs=[execute_msg], fee_denoms=['uusd'], memo=".")
tx = await wallet.create_and_sign_tx( tx_opt )
res = await self.terra.tx.broadcast(tx)

Can you please help me get this working. ?

Error: LCDResponseError: Status 401 - chain-id required but not specified

  • terra_sdk version: 0.14.0
  • Python version: 3.9.7
  • Operating System: Ubuntu

Description

Try using MsgSend or MsgSwap fail on:
LCDResponseError: Status 401 - chain-id required but not specified

For example:

from terra_sdk.client.lcd import LCDClient
from terra_sdk.core.bank import MsgSend
terra = LCDClient(chain_id="bombay-12", url="https://bombay-lcd.terra.dev")
print(terra.tendermint.node_info())

from terra_sdk.key.mnemonic import MnemonicKey
mk = MnemonicKey()
# I send some coins to mk address

mk2 = MnemonicKey()
terra.bank.balance(mk.acc_address)

send = MsgSend(mk.acc_address, mk2.acc_address, terra.bank.balance(mk.acc_address)/2)

tx = wallet.create_and_sign_tx(
   msgs=[send],
   memo="Some test",
)

fail on:
LCDResponseError: Status 401 - chain-id required but not specified

Swap create_and_sign_tx error

  • terra_sdk version: newest
  • Python version: newest
  • Operating System: win 10

Description

I'm trying to write a simple swap that converts UST to Luna. Can you please provide a simple swap tx that works?

What I Did

I followed through the steps and when I get to instantiating the tx I get an error.

from terra_sdk.core.market import MsgSwap

swap = MsgSwap(mk.acc_address, '3000000000uusd', 'uluna')

tx = wallet.create_and_sign_tx(
    msgs=[swap],
    gas_prices='2uluna',
    gas_adjustment='1.5',
    fee_denoms=['uusd', 'uluna']
)

Traceback:

---------------------------------------------------------------------------
LCDResponseError                          Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_8636/565227005.py in <module>
      3 swap = MsgSwap(mk.acc_address, '3000000000uusd', 'uluna')
      4 
----> 5 tx = wallet.create_and_sign_tx(
      6     msgs=[swap],
      7     # fee=None,

~\anaconda3\lib\site-packages\terra_sdk\client\lcd\wallet.py in create_and_sign_tx(self, msgs, fee, memo, gas_prices, gas_adjustment, fee_denoms, account_number, sequence)
    135         """
    136         return self.key.sign_tx(
--> 137             self.create_tx(
    138                 msgs,
    139                 fee,

~\anaconda3\lib\site-packages\terra_sdk\client\lcd\wallet.py in create_tx(self, msgs, fee, memo, gas_prices, gas_adjustment, fee_denoms, account_number, sequence)
     91             StdSignMsg: unsigned transaction
     92         """
---> 93         return self.lcd.tx.create(
     94             sender=self.key.acc_address,
     95             msgs=msgs,

~\anaconda3\lib\site-packages\terra_sdk\client\lcd\api\_base.py in decorator(wrapped, instance, args, kwargs)
     27     @wrapt.decorator
     28     def decorator(wrapped, instance, args, kwargs):
---> 29         return instance._run_sync(async_call(instance, *args, **kwargs))
     30 
     31     return decorator

~\anaconda3\lib\site-packages\terra_sdk\client\lcd\api\_base.py in _run_sync(self, coroutine)
     11     def _run_sync(self, coroutine):
     12         """Runs an asynchronous coroutine synchronously."""
---> 13         return self._c.loop.run_until_complete(coroutine)
     14 
     15     @staticmethod

~\anaconda3\lib\site-packages\nest_asyncio.py in run_until_complete(self, future)
     68                 raise RuntimeError(
     69                     'Event loop stopped before Future completed.')
---> 70             return f.result()
     71 
     72     def _run_once(self):

~\anaconda3\lib\asyncio\futures.py in result(self)
    176         self.__log_traceback = False
    177         if self._exception is not None:
--> 178             raise self._exception
    179         return self._result
    180 

~\anaconda3\lib\asyncio\tasks.py in __step(***failed resolving arguments***)
    278                 # We use the `send` method directly, because coroutines
    279                 # don't have `__iter__` and `__next__` methods.
--> 280                 result = coro.send(None)
    281             else:
    282                 result = coro.throw(exc)

~\anaconda3\lib\site-packages\terra_sdk\client\lcd\api\tx.py in create(self, sender, msgs, fee, memo, gas, gas_prices, gas_adjustment, fee_denoms, account_number, sequence)
     70         if fee is None:
     71             fee = await BaseAsyncAPI._try_await(
---> 72                 self.estimate_fee(
     73                     sender, msgs, memo, gas, gas_prices, gas_adjustment, fee_denoms
     74                 )

~\anaconda3\lib\site-packages\terra_sdk\client\lcd\api\_base.py in decorator(wrapped, instance, args, kwargs)
     27     @wrapt.decorator
     28     def decorator(wrapped, instance, args, kwargs):
---> 29         return instance._run_sync(async_call(instance, *args, **kwargs))
     30 
     31     return decorator

~\anaconda3\lib\site-packages\terra_sdk\client\lcd\api\_base.py in _run_sync(self, coroutine)
     11     def _run_sync(self, coroutine):
     12         """Runs an asynchronous coroutine synchronously."""
---> 13         return self._c.loop.run_until_complete(coroutine)
     14 
     15     @staticmethod

~\anaconda3\lib\site-packages\nest_asyncio.py in run_until_complete(self, future)
     68                 raise RuntimeError(
     69                     'Event loop stopped before Future completed.')
---> 70             return f.result()
     71 
     72     def _run_once(self):

~\anaconda3\lib\asyncio\futures.py in result(self)
    176         self.__log_traceback = False
    177         if self._exception is not None:
--> 178             raise self._exception
    179         return self._result
    180 

~\anaconda3\lib\asyncio\tasks.py in __step(***failed resolving arguments***)
    278                 # We use the `send` method directly, because coroutines
    279                 # don't have `__iter__` and `__next__` methods.
--> 280                 result = coro.send(None)
    281             else:
    282                 result = coro.throw(exc)

~\anaconda3\lib\site-packages\terra_sdk\client\lcd\api\tx.py in estimate_fee(self, sender, msgs, memo, gas, gas_prices, gas_adjustment, fee_denoms)
    131         }
    132 
--> 133         res = await self._c._post("/txs/estimate_fee", data)
    134         fee_amount = Coins.from_data(res["fee"]["amount"])
    135 

~\anaconda3\lib\site-packages\terra_sdk\client\lcd\lcdclient.py in _post(self, *args, **kwargs)
    253         )
    254         try:
--> 255             result = await super()._post(*args, **kwargs)
    256         finally:
    257             await self.session.close()

~\anaconda3\lib\site-packages\terra_sdk\client\lcd\lcdclient.py in _post(self, endpoint, data, raw)
    108                 raise LCDResponseError(message=str(response.reason), response=response)
    109             if not 200 <= response.status < 299:
--> 110                 raise LCDResponseError(message=result.get("error"), response=response)
    111         self.last_request_height = result.get("height")
    112         return result if raw else result["result"]

LCDResponseError: Status 400 - rpc error: code = NotFound desc = rpc error: code = NotFound desc = account terra1z5vf42z0s2zkxnzjdxmxwgghqstk8zvft7rxzc not found: key not found

Bad gas calculation for zero-sum uluna >> uusd Terraswaps

  • terra_sdk version: terra-sdk==1.0.2
  • Python version: 3.8.10
  • Operating System: Ubuntu 20.04

Description

I want to process swap transactions reliably exchanging all of the available native coin in exchange for another native coin. I understand this requires estimating or calculating the fees, but sometimes estimating errors so it is better to calculate - please correct me if I am wrong.

Before I was estimating and calculating Joowoon told me I should use 200K on Mainnet, and 300K on testnet for transactions, so I am still using the value for gas. I notice that estimating the fee will return a lower value if I do not provide a gas value to it.

fee_estimate and my fee calculation return different values and I wanted to ask if this is normal and if not if there is something wrong with my code?

What I Did

async def fees( offer_coin, ask_denom ):
    # offer and ask_denom are balance.['uusd'] and 'uluna'

    swap = MsgSwap( account, offer_coin, ask_denom )
    
    gas_prices_request = Request("https://fcd.terra.dev/v1/txs/gas_prices", headers={"User-Agent": "Mozilla/5.0"})
    gas_prices = json.loads(urllib.request.urlopen(gas_prices_request).read().decode())
    
    tx = {
        'msgs' : [swap],
        'gas': 300000,
        'gas_prices' : gas_prices,
        'fee_denoms' : [offer_coin.denom]
    }

    fee_estimate_raw = await app.terra.tx.estimate_fee(account, **tx)
    fee_estimate_data = fee_estimate_raw.to_data()
    fee_estimate = int(fee_estimate_data['gas']) + int(fee_estimate_data['amount'][0]['amount'])

    tax_rate = await app.terra.treasury.tax_rate()
    tax_cap = await app.terra.treasury.tax_cap(offer_coin.denom)
    tax_cap_amount = tax_cap.amount
    tax_fees = min(math.ceil(offer_coin.amount * tax_rate), tax_cap_amount)
    gas_fees = 300000 * float(gas_prices[offer_coin.denom])
    fee_calculation = tax_fees + gas_fees
    
    print(f'offer_coin: {offer_coin}')

    print(f"fee_estimate amount: {int(fee_estimate_data['amount'][0]['amount'])}")
    print (f'fee_estimate: {fee_estimate}')

    print(f'Tax rate: {tax_rate}')
    print(f'Tax cap: {tax_cap.amount}')
    print(f'Tax fees: {tax_fees}')
    print(f'gas fees: {gas_fees}')
    print(f'fee_calculation: {fee_calculation}')

    return True
offer_coin: 26335802384uusd
fee_estimate amount: 45000
fee_estimate: 345000
Tax rate: 0.005045308519999478
Tax cap: 1388167
Tax fees: 1388167
gas fees: 45000.0
fee_calculation: 1433167.0

`estimate_fee()` rounds calculated fee amount down instead of up

estimate_fee() rounds the calculated fee amount down instead of up, so using the calculated estimate directly often causes transactions to be rejected by LCDs with a minimum gas price set:

insufficient fees; got: "261368uusd", required: "331067uaud,331067ucad,243944uchf,1707605ucny,1568209udkk,217807ueur,191670ugbp,2038672uhkd,3798549720uidr,18957900uinr,28523972ujpy,295816416ukrw,19743uluna,746765254umnt,2178068unok,13242651uphp,182850usdr,2178068usek,348491usgd,8050138uthb,261369uusd" = "331067uaud,331067ucad,243944uchf,1707605ucny,1568209udkk,217807ueur,191670ugbp,2038672uhkd,3798549720uidr,18957900uinr,28523972ujpy,295816416ukrw,19743uluna,746765254umnt,2178068unok,13242651uphp,182850usdr,2178068usek,348491usgd,8050138uthb,261369uusd"(gas) +""(stability): insufficient fee

This is for a tx with a gas limit of 1742454, which would require a minimum fee of 0.15uusd * 1742454 = 261368.1uusd ~= 261369uusd on the public Bombay LCD.

estimate_fee() rounds the calculated fee down with to_int_coins() though, so the calculated fee amount is 261368 instead (i.e. gas price is 0.149999943uusd -- below the min price of 0.15uusd)

fee_amount = gas_prices_coins.mul(gas).to_int_coins() if gas_prices_coins else Coins.from_str('0uusd')

How to set slippage maximum for sell swap

  • terra_sdk version: 1.0.0
  • Python version: 3.10
  • Operating System: Windows 11

Description

I'm trying to put in a slippage maximum when selling a contract token (e.g. LOOP) for UST. I know how to do this on the buy side but haven't been able to figure out how to do so when selling. Can anyone point me to documentation that talks about this?

What I Did

I have tried doing a transaction manually through terraswap and using a slippage maximum, looking at the popup box to check the execute message and how it's set up, but still I don't see anything that changes when setting different slippage parameters.

Fetching proposal_id error due key error.

Description

Fetching a proposal_id using terra.gov.proposal() does not work because there is an error in the object that looks for proposal_status where it should be status instead.

proposal_status=data["proposal_status"],

Data sample:

{'id': '175', 'content': {'type': 'distribution/CommunityPoolSpendProposal', 'value': {'title': 'UST Goes Interchain: Degen Strats Part Four', 'description': 'Bring UST to Market.xyz and Themis\nhttps://agora.terra.money/t/ust-goes-interchain-degen-strats-part-four/3599', 'recipient': 'terra1jrhxdtwxrsxw3t2al6t3sga89974juhpccuxct', 'amount': [{'denom': 'uusd', 'amount': '40000000000000'}]}}, 'status': 2, 'final_tally_result': {'yes': '0', 'abstain': '0', 'no': '0', 'no_with_veto': '0'}, 'submit_time': '2022-01-11T19:11:20.807833336Z', 'deposit_end_time': '2022-01-25T19:11:20.807833336Z', 'total_deposit': [{'denom': 'uluna', 'amount': '50000001'}], 'voting_start_time': '2022-01-12T01:26:01.593909182Z', 'voting_end_time': '2022-01-19T01:26:01.593909182Z'}

I'd do a PR but I'm not sure how you wanted to handle this as I believe proto files would need to be updated also ...

Thanks

I am getting error : terra_sdk.exceptions.LCDResponseError: Status 401 - chain-id required but not specified

  • terra_sdk version:
  • Python version: 3.8
  • Operating System: ubuntu

Description

Using LocalTerra , Station connected and all looks OK. Latest Terra and Latest CosmWasm template.

When i try to upload a sample contract it was throwing the error in the create_and_sign_tx method

Status 401 - chain-id required but not specified

test_contract_wasm is the cosmwasm template.

What I Did

terra = LocalTerra()
test1 = terra.wallets["test1"]
contract_file = open("./test_contract.wasm", "rb")
file_bytes = base64.b64encode(contract_file.read()).decode()
store_code = MsgStoreCode(test1.key.acc_address, file_bytes)
store_code_tx = test1.create_and_sign_tx(msgs=[store_code])
store_code_tx_result = terra.tx.broadcast(store_code_tx)
print(store_code_tx_result)

Traceback (most recent call last):
File "contract.py", line 11, in
store_code_tx = test1.create_and_sign_tx(msgs=[store_code])
File "/home/ssenathi/.local/lib/python3.8/site-packages/terra_sdk/client/lcd/wallet.py", line 136, in create_and_sign_tx
self.create_tx(
File "/home/ssenathi/.local/lib/python3.8/site-packages/terra_sdk/client/lcd/wallet.py", line 93, in create_tx
return self.lcd.tx.create(
File "/home/ssenathi/.local/lib/python3.8/site-packages/terra_sdk/client/lcd/api/_base.py", line 29, in decorator
return instance._run_sync(async_call(instance, *args, **kwargs))
File "/home/ssenathi/.local/lib/python3.8/site-packages/terra_sdk/client/lcd/api/_base.py", line 13, in _run_sync
return self._c.loop.run_until_complete(coroutine)
File "/home/ssenathi/.local/lib/python3.8/site-packages/nest_asyncio.py", line 70, in run_until_complete
return f.result()
File "/usr/lib/python3.8/asyncio/futures.py", line 178, in result
raise self._exception
File "/usr/lib/python3.8/asyncio/tasks.py", line 280, in __step
result = coro.send(None)
File "/home/ssenathi/.local/lib/python3.8/site-packages/terra_sdk/client/lcd/api/tx.py", line 67, in create
self.estimate_fee(tx, gas_prices, gas_adjustment, fee_denoms)
File "/home/ssenathi/.local/lib/python3.8/site-packages/terra_sdk/client/lcd/api/_base.py", line 29, in decorator
return instance._run_sync(async_call(instance, *args, **kwargs))
File "/home/ssenathi/.local/lib/python3.8/site-packages/terra_sdk/client/lcd/api/_base.py", line 13, in _run_sync
return self._c.loop.run_until_complete(coroutine)
File "/home/ssenathi/.local/lib/python3.8/site-packages/nest_asyncio.py", line 70, in run_until_complete
return f.result()
File "/usr/lib/python3.8/asyncio/futures.py", line 178, in result
raise self._exception
File "/usr/lib/python3.8/asyncio/tasks.py", line 280, in __step
result = coro.send(None)
File "/home/ssenathi/.local/lib/python3.8/site-packages/terra_sdk/client/lcd/api/tx.py", line 126, in estimate_fee
res = await self._c._post("/txs/estimate_fee", data)
File "/home/ssenathi/.local/lib/python3.8/site-packages/terra_sdk/client/lcd/lcdclient.py", line 255, in _post
result = await super()._post(*args, **kwargs)
File "/home/ssenathi/.local/lib/python3.8/site-packages/terra_sdk/client/lcd/lcdclient.py", line 110, in _post
raise LCDResponseError(message=result.get("error"), response=response)
terra_sdk.exceptions.LCDResponseError: Status 401 - chain-id required but not specified

terra_sdk.exceptions.LCDResponseError: Status 404 'key not found'

  • terra_sdk version: 2.0.3
  • Python version: 3.9.4
  • Operating System: Windows

Description

just following example. I put in my mnemonic and run.

image

Paste the command(s) you ran and the output.
If there was a crash, please include the traceback here.

terra_sdk.exceptions.LCDResponseError: Status 404 - {'code': 5, 'message': 'rpc error: code = NotFound desc = account terra1 not
found: key not found', 'details': []}

any idea why I get that? Its a real mnemonic and it shows my address in the error response so not sure why there is any error if its finding the account. thanks!

terra_sdk.exceptions.LCDResponseError: Status 400 - account sequence mismatch

terra_sdk version: 2.0.3
Python version: 3.9.4
Operating System: Windows

Description

Receiving this error. Happens about 50% of the time after during the second transaction in a pair of rapid succession TXs from the same wallet. Looking for any advice or idea why 1. it seems to happen only sometimes 2. any reason why I cant make 2 TXs back to back. first one never fails, just the second.

terra_sdk.exceptions.LCDResponseError: Status 400 - account sequence mismatch, expected 24, got 23: incorrect account sequence: invalid request

What I Did

image

Not working for Bombay-10

  • terra_sdk version: latest
  • Python version: 3.7
  • Operating System: Linux

Description

I am trying to fetch the total supply to test the API.
Working fine for tequila-0004.
When I change testnet to Bombay-10 it give me 501.

What I Did


import asyncio 
from terra_sdk.client.lcd import AsyncLCDClient

async def main():

	terra = AsyncLCDClient("https://bombay-lcd.terra.dev","bombay-9")
	total_supply = await terra.supply.total()
	print(total_supply)
	#await terra.session.close # you must close the session

asyncio.get_event_loop().run_until_complete(main())


Failed StdFee Import

  • terra_sdk version: 2.0.3
  • Python version: 3.7
  • Operating System: Windows 10 64-bit

Hi everyone,

I'm trying to do the simple tutorials, which can be found in the Terra SDK Documentation.
All imports work fine, but not the StdFee import.
Am I doing something wrong or is there an other way to implement fees?

I used the exact same implementation as in the documentation.
https://terra-money.github.io/terra.py/guides/transactions.html?highlight=fees
https://terra-money.github.io/terra.py/core_modules/auth.html?highlight=fees

image

Dec cannot represent a value smaller than 1e-6

  • terra_sdk version: 0.14.0
  • Python version: 3.9.5
  • Operating System: Windows 10 Pro (build 19043.1110)

Description

Hi there,

I've started to put together my own little python API for Anchor Protocol, and I'm trying to multiply a Dec coin by ~4e-8. Specifically, I'd like to increment the value of a Coin object with denom="uaust" by Anchor Earn's per-block deposit rate. It would be convenient to use Coin's mul() function for this, since I'd like to return a new Coin object.

Unfortunately, I've just discovered that the smallest value that Dec can (accurately) represent is 1e-6 - much higher than I need! See minimal demo below.

Is this by design / expected? Perhaps related to the convention of working in micro currency units?

If this behaviour is expected and difficult/unlikely to change, may I humbly suggest a rewording of the Dec class docstring? Perhaps it could explicitly state this minimum? Also, at the moment, the docstring states that Dec (my emphasis):

[...]Serializes as a string with 18 points of decimal precision.

which I found a little confusing. To me at least, "18 points of decimal precision" implies that 1e-18 (or thereabouts) can be represented.

I'd be happy to work on any agreed-upon changes and submit a pull request :)

[EDIT]

I just discovered that constructing with a decimal string works fine! Not with a scientific notation string though. See second code block below.

What I Did

$ python
>>> from terra_sdk.core import Dec
>>> print(Dec(5e-7))
0.000000000000000000
>>> print(Dec(5e-7 + 1e-20))
0.000001000000000000
>>> print(Dec(5e-7 + 1e-20) == Dec(1e-6))
True

[EDIT] Decimal string okay:

$ python
>>> from terra_sdk.core import Dec
>>> print(Dec(0.000000005))
0.000000000000000000
>>> print(Dec("0.000000005"))
0.000000005000000000
>>> print(Dec(5e-9))
0.000000000000000000
>>> print(Dec("5e-9"))
.....
ValueError: Unable to parse Dec from string: 5e-9

Failed to parse IBC coin

  • terra_sdk version: 1.0.0
  • Python version: 3.10
  • Operating System: Windows 11

Description

I'm trying do a swap of the scrt token to UST and run into an error with my coins line. I'm able to do a swap from UST to scrt.

What I Did

Here are my msgexecutecontract lines. I've tried the two listed coins lines and neither worked resulting in the error below.

swap = MsgExecuteContract(
sender=wallet.key.acc_address,
contract=pair_address_input,
execute_msg=swap_msg,

  coins="denom":"ibc/EB2CED20AB0466F18BE49285E56B31306D4C60438A022EA995BA65D5E3CF7E09", "amount": "100000" }]
        coins='100000ibc/EB2CED20AB0466F18BE49285E56B31306D4C60438A022EA995BA65D5E3CF7E09'

``

Traceback (most recent call last):
File "C:\Users\ryann\AppData\Roaming\JetBrains\PyCharmCE2021.2\scratches\scratch.py", line 55, in
buy_order(.1, contract_addresses.scrt_pair, 10)
File "C:\Users\ryann\AppData\Roaming\JetBrains\PyCharmCE2021.2\scratches\scratch.py", line 33, in buy_order
swap = MsgExecuteContract(
File "", line 6, in init
File "C:\Users\ryann\PycharmProjects\myProject\venv\lib\site-packages\terra_sdk\core\coins.py", line 70, in init
self._coins = Coins.from_str(arg)._coins
File "C:\Users\ryann\PycharmProjects\myProject\venv\lib\site-packages\terra_sdk\core\coins.py", line 50, in from_str
return Coins(Coin.from_str(cs) for cs in coin_strings)
File "C:\Users\ryann\PycharmProjects\myProject\venv\lib\site-packages\terra_sdk\core\coins.py", line 80, in init
for coin in coins:
File "C:\Users\ryann\PycharmProjects\myProject\venv\lib\site-packages\terra_sdk\core\coins.py", line 50, in
return Coins(Coin.from_str(cs) for cs in coin_strings)
File "C:\Users\ryann\PycharmProjects\myProject\venv\lib\site-packages\terra_sdk\core\coin.py", line 94, in from_str
raise ValueError(f"failed to parse Coin: {string}")
ValueError: failed to parse Coin: 100000ibc/EB2CED20AB0466F18BE49285E56B31306D4C60438A022EA995BA65D5E3CF7E09

Error execution examples

  • terra_sdk version:
  • Python version: 3.9
  • Operating System: Windows

Description

when execute:
from terra_sdk.client.lcd import LCDClient
from terra_sdk.key.mnemonic import MnemonicKey
from terra_sdk.core.auth import StdFee
from terra_sdk.core.bank import MsgSend

mk = MnemonicKey(mnemonic="MNEMONIC")
terra = LCDClient(chain_id="columbus-5", url="https://lcd.terra.dev")
wallet = terra.wallet(mk)

tx = wallet.create_and_sign_tx(
msgs=[MsgSend(
wallet.key.acc_address,
"RECIPIENT",
"1000000uluna" # send 1 luna
)],
memo="test transaction!",
fee=StdFee(200000, "120000uluna")
)

result = terra.tx.broadcast(tx)
print(result)

What I Did

Traceback (most recent call last):
File "c:\python-virtual-environments\TestTerraFirst\WalletTerra2.py", line 11, in
tx = wallet.create_and_sign_tx(
File "C:\python-virtual-environments\TestTerraFirst\lib\site-packages\terra_sdk\client\lcd\wallet.py", line 137, in create_and_sign_tx
self.create_tx(
File "C:\python-virtual-environments\TestTerraFirst\lib\site-packages\terra_sdk\client\lcd\wallet.py", line 93, in create_tx
return self.lcd.tx.create(
File "C:\python-virtual-environments\TestTerraFirst\lib\site-packages\terra_sdk\client\lcd\api_base.py", line 29, in decorator
return instance._run_sync(async_call(instance, *args, **kwargs))
File "C:\python-virtual-environments\TestTerraFirst\lib\site-packages\terra_sdk\client\lcd\api_base.py", line 13, in _run_sync
return self._c.loop.run_until_complete(coroutine)
File "C:\python-virtual-environments\TestTerraFirst\lib\site-packages\nest_asyncio.py", line 81, in run_until_complete
return f.result()
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.2800.0_x64__qbz5n2kfra8p0\lib\asyncio\futures.py", line 201, in result
raise self._exception
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.2800.0_x64__qbz5n2kfra8p0\lib\asyncio\tasks.py", line 256, in __step
result = coro.send(None)
File "C:\python-virtual-environments\TestTerraFirst\lib\site-packages\terra_sdk\client\lcd\api\tx.py", line 78, in create
account = await BaseAsyncAPI._try_await(self._c.auth.account_info(sender))
File "C:\python-virtual-environments\TestTerraFirst\lib\site-packages\terra_sdk\client\lcd\api_base.py", line 29, in decorator
return instance._run_sync(async_call(instance, *args, **kwargs))
File "C:\python-virtual-environments\TestTerraFirst\lib\site-packages\terra_sdk\client\lcd\api_base.py", line 13, in _run_sync
return self._c.loop.run_until_complete(coroutine)
File "C:\python-virtual-environments\TestTerraFirst\lib\site-packages\nest_asyncio.py", line 81, in run_until_complete
return f.result()
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.2800.0_x64__qbz5n2kfra8p0\lib\asyncio\futures.py", line 201, in result
raise self._exception
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.2800.0_x64__qbz5n2kfra8p0\lib\asyncio\tasks.py", line 256, in __step
result = coro.send(None)
File "C:\python-virtual-environments\TestTerraFirst\lib\site-packages\terra_sdk\client\lcd\api\auth.py", line 25, in account_info
return Account.from_data(result)
File "C:\python-virtual-environments\TestTerraFirst\lib\site-packages\terra_sdk\core\auth\data\account.py", line 48, in from_data
address=data["address"],
KeyError: 'address'

create_and_sign_tx - AttributeError: 'BlockTxBroadcastResult' object has no attribute 'encode'

  • terra_sdk version: 2.0.4
  • Python version: 3.9.7
  • Operating System: Ubuntu 20.04

Description

I am trying to deploy cw20 token to Local Terra, but when executing contract I get attribute error.

What I Did

from terra_sdk.client.lcd.api.tx import CreateTxOptions
from terra_sdk.client.localterra import LocalTerra
from terra_sdk.util.contract import get_code_id, read_file_as_b64
from terra_sdk.core.wasm import MsgStoreCode, MsgInstantiateContract, MsgExecuteContract
from terra_sdk.core.coins import Coins
from terra_sdk.core.fee import Fee

lt = LocalTerra()
deployer = lt.wallets["test1"]
test_acc = lt.wallets["test2"]


def store_contract(contract_name):
    contract_bytes = read_file_as_b64(f"artifacts/{contract_name}.wasm")
    store_code = MsgStoreCode(deployer.key.acc_address, contract_bytes)
    tx = deployer.create_and_sign_tx(CreateTxOptions(
        msgs=[store_code]
    ))
    result = lt.tx.broadcast(tx)
    code_id = get_code_id(result)
    return code_id


def instantiate_contract(code_id: str, init_msg: dict) -> str:
    instantiate = MsgInstantiateContract(
        sender=deployer.key.acc_address,
        admin=deployer.key.acc_address,
        code_id=code_id,
        init_msg=init_msg,
    )

    tx = deployer.create_and_sign_tx(CreateTxOptions(
        msgs=[instantiate]
    ))

    result = lt.tx.broadcast(tx)
    print(result)
    return result


def execute_contract(sender, contract_addr: str, execute_msg):

    execute = MsgExecuteContract(
        sender=sender.key.acc_address, contract=contract_addr, execute_msg=execute_msg
    )
    # tx = sender.create_and_sign_tx(CreateTxOptions(
    #     msgs=[execute],
    #     fee=Fee(1000000, "1000000uluna")
    # ))
    execute = MsgExecuteContract(
        sender.key.acc_address,
        contract_addr,
        execute_msg,
        {"uluna": 100000},
    )

    execute_tx = sender.create_and_sign_tx(
        CreateTxOptions(msgs=[execute], fee=Fee(1000000, Coins(uluna=1000000)))
    )

    result = lt.tx.broadcast(execute_tx)
    print(result)
    return result


code_id = store_contract("terraswap_token")
contract_address = instantiate_contract(code_id,
                                        {
                                            "name": "Test Terra Token",
                                            "symbol": "TTT",
                                            "decimals": 6,
                                            "initial_balances": [
                                                {"address": deployer.key.acc_address,
                                                    "amount": "1000000000"}
                                            ]
                                        })

execute_contract(deployer, contract_address, {
    "transfer": {
        "recipient": test_acc.key.acc_address,
        "amount": "50000000000"
    }
})

print(lt.wasm.contract_query(contract_address, {
      "balance": {"address": deployer.key.acc_address}}))

print(lt.wasm.contract_query(contract_address, {
      "balance": {"address": test_acc.key.acc_address}}))

error while commit tx/broadcast tx due "isOracleTX".

Due the last Terra Core update to prioritize OracleTx, the broadcast/commit isn't working anymore.

I've attempted to do a PR but I'm unsure how to fix this error. :(

Thank you so much guys,

terra_sdk.exceptions.LCDResponseError: Status 500 - broadcast_tx_commit: error unmarshalling result: unknown field "isOracleTx" in types.ResponseCheckTx

Update ecdsa to 0.17.0

  • terra_sdk version: 1.0.2
  • Python version: 3.10
  • Operating System: MacOS/Linux

Description

Can you please update ecdsa to 0.17.0 or relax the pinning? This library currently has it pinned on ecdsa<0.17.0 and >=0.16.1, which is now in conflict with a bunch of other libraries.

What I Did

Try pip install terra-sdk==1.0.2 substrate-interface==1.1.4 and watch the fireworks

Error while sending a transaction

terra_sdk version: 0.14.0
python version: 3.9

I am currently trying to broadcast a swap transaction on tequila testnet. This is my transaction:

        {
            "swap": {
                "offer_asset": {
                    "info": {"native_token": {"denom": "uusd"}},
                    "amount":  "1000000000",
                }
            }
        },

But I am getting one of the following two errors when I try to send it using the following code:
(This is from @ouiliame youtube stream)

    def execute_contract(self, contract_address, execute_msg, coins=None):
        execute = MsgExecuteContract(
            sender=self.sender.key.acc_address,
            contract=contract_address,
            execute_msg=execute_msg,
            coins=coins,
        )
        tx = self.sender.create_and_sign_tx(
            msgs=[execute], fee=StdFee(4000000, "1000000uluna")
        )
        result = self.client.tx.broadcast(tx)
        return result

Error when connecting to http://tequila-lcd.terra.dev

terra_sdk.exceptions.LCDResponseError: Status 400 - it is not allowed to query txs without tx.height or (tx.maxheight && tx.minheight) options. please refer {URL}/swagger-ui

Error when connecting to https://tequila-lcd.terra.dev

LCDResponseError: Status 500 - broadcast_tx_commit: error unmarshalling: invalid character '<' looking for beginning of value

I can't do a simple swap. Gas_adjustment asks me for coin format

  • Terra_sdk version: terra-sdk-1.0.0b1
  • Python version: 3.8
  • Operating System: Ubuntu 20.04

Description

I'm trying to do a swap, with the following code, it worked perfectly in col-4. Since the upgrade, I can't get it to work. Right now it is giving me the format error in gas_adjustment. It was never a coin format and I think it shouldn't ask for it in that format, I assume it as a bug

What I Did

tx = wallet.create_and_sign_tx(
            msgs=[swap],
            gas_prices= str(gas_prices_live["uusd"]),
            gas_adjustment="1.4"
            )

Error i get

Traceback (most recent call last):
File "/home/rama/eclipse-workspace/Probar_Com_Terra/PruebaGral.py", line 160, in
tx = wallet.create_and_sign_tx(
File "/home/rama/.local/lib/python3.8/site-packages/terra_sdk/client/lcd/wallet.py", line 136, in create_and_sign_tx
self.create_tx(
File "/home/rama/.local/lib/python3.8/site-packages/terra_sdk/client/lcd/wallet.py", line 93, in create_tx
return self.lcd.tx.create(
File "/home/rama/.local/lib/python3.8/site-packages/terra_sdk/client/lcd/api/_base.py", line 29, in decorator
return instance._run_sync(async_call(instance, *args, **kwargs))
File "/home/rama/.local/lib/python3.8/site-packages/terra_sdk/client/lcd/api/_base.py", line 13, in _run_sync
return self._c.loop.run_until_complete(coroutine)
File "/home/rama/.local/lib/python3.8/site-packages/nest_asyncio.py", line 70, in run_until_complete
return f.result()
File "/usr/lib/python3.8/asyncio/futures.py", line 178, in result
raise self._exception
File "/usr/lib/python3.8/asyncio/tasks.py", line 280, in __step
result = coro.send(None)
File "/home/rama/.local/lib/python3.8/site-packages/terra_sdk/client/lcd/api/tx.py", line 64, in create
self.estimate_fee(
File "/home/rama/.local/lib/python3.8/site-packages/terra_sdk/client/lcd/api/_base.py", line 29, in decorator
return instance._run_sync(async_call(instance, *args, **kwargs))
File "/home/rama/.local/lib/python3.8/site-packages/terra_sdk/client/lcd/api/_base.py", line 13, in _run_sync
return self._c.loop.run_until_complete(coroutine)
File "/home/rama/.local/lib/python3.8/site-packages/nest_asyncio.py", line 70, in run_until_complete
return f.result()
File "/usr/lib/python3.8/asyncio/futures.py", line 178, in result
raise self._exception
File "/usr/lib/python3.8/asyncio/tasks.py", line 280, in __step
result = coro.send(None)
File "/home/rama/.local/lib/python3.8/site-packages/terra_sdk/client/lcd/api/tx.py", line 106, in estimate_fee
gas_prices_coins = Coins(gas_prices)
File "/home/rama/.local/lib/python3.8/site-packages/terra_sdk/core/coins.py", line 70, in init
self._coins = Coins.from_str(arg)._coins
File "/home/rama/.local/lib/python3.8/site-packages/terra_sdk/core/coins.py", line 50, in from_str
return Coins(Coin.from_str(cs) for cs in coin_strings)
File "/home/rama/.local/lib/python3.8/site-packages/terra_sdk/core/coins.py", line 80, in init
for coin in coins:
File "/home/rama/.local/lib/python3.8/site-packages/terra_sdk/core/coins.py", line 50, in
return Coins(Coin.from_str(cs) for cs in coin_strings)
File "/home/rama/.local/lib/python3.8/site-packages/terra_sdk/core/coin.py", line 94, in from_str
raise ValueError(f"failed to parse Coin: {string}")
ValueError: failed to parse Coin: 1.4

Error on create and sign tx

Terra sdk version: 0.14.0
Python Version: 3.9
OS: Mac

Hello,
I am trying to follow along @ouiliame videos on youtube (https://youtu.be/xh3pqyTePuk?t=862 in particular). When deploying my first contract on local terra with the following code:

lt = LocalTerra()
deployer = lt.wallets["test2"]


def store_contract(contract_name):
    contract_bytes = read_file_as_b64(f"artifacts/{contract_name}.wasm")
    store_code = MsgStoreCode(
        deployer.key.acc_address,
        contract_bytes,
    )
    tx = deployer.create_and_sign_tx(
        msgs=[store_code], fee=StdFee(4000000, "10000000uluna")
    )
    result = lt.tx.broadcast(tx)

I get the following error:

...
  File "...lib/python3.9/site-packages/terra_sdk/client/lcd/api/auth.py", line 25, in account_info
    return Account.from_data(result)
  File "...lib/python3.9/site-packages/terra_sdk/core/auth/data/account.py", line 53, in from_data
    coins=Coins.from_data(data["coins"]),
KeyError: 'coins'

Error happens at deployer.create_and_sign_tx(...) line.

Thanks.

tx_info no longer working on Mainnet or Testnet post Columbus-5 update

  • terra_sdk version: 0.14.0
  • Python version: 3.9.6
  • Operating System: Win 10 64-bit 21H1
if config.NETWORK == 'MAINNET':
    chain_id = 'columbus-5'
    public_node_url = 'https://lcd.terra.dev'

else:
    chain_id = 'bombay-12'
    public_node_url = 'https://bombay-fcd.terra.dev'

terra = LCDClient(chain_id=chain_id, url=public_node_url)

Mainnet:
terra.tx.tx_info('42DE8348A333613EB013251DE2056EE301019DA8C2505935B24E8596AFD350A1')

Testnet:
terra.tx.tx_info('BC00BDD340F8622679A8746CC0AC3474D87D3189F4F7263A77C873D3A3D9ED17')

Both return the same error_

Traceback (most recent call last):
  File "C:\_Code\Terra One-Stop-Bot\C_Main.py", line 1744, in <module>
    print(terra.tx.tx_info('BC00BDD340F8622679A8746CC0AC3474D87D3189F4F7263A77C873D3A3D9ED17'))
  File "C:\Users\mE\AppData\Local\Programs\Python\Python39\lib\site-packages\wrapt\wrappers.py", line 605, in __call__
    return self._self_wrapper(self.__wrapped__, self._self_instance,
  File "C:\Users\mE\AppData\Local\Programs\Python\Python39\lib\site-packages\terra_sdk\client\lcd\api\_base.py", line 29, in decorator
    return instance._run_sync(async_call(instance, *args, **kwargs))
  File "C:\Users\mE\AppData\Local\Programs\Python\Python39\lib\site-packages\terra_sdk\client\lcd\api\_base.py", line 13, in _run_sync
    return self._c.loop.run_until_complete(coroutine)
  File "C:\Users\mE\AppData\Local\Programs\Python\Python39\lib\site-packages\nest_asyncio.py", line 70, in run_until_complete
    return f.result()
  File "C:\Users\mE\AppData\Local\Programs\Python\Python39\lib\asyncio\futures.py", line 201, in result
    raise self._exception
  File "C:\Users\mE\AppData\Local\Programs\Python\Python39\lib\asyncio\tasks.py", line 256, in __step
    result = coro.send(None)
  File "C:\Users\mE\AppData\Local\Programs\Python\Python39\lib\site-packages\terra_sdk\client\lcd\api\tx.py", line 28, in tx_info
    return TxInfo.from_data(await self._c._get(f"/txs/{tx_hash}", raw=True))
  File "C:\Users\mE\AppData\Local\Programs\Python\Python39\lib\site-packages\terra_sdk\core\auth\data\tx.py", line 276, in from_data
    parse_tx_logs(data.get("logs")),
  File "C:\Users\mE\AppData\Local\Programs\Python\Python39\lib\site-packages\terra_sdk\core\auth\data\tx.py", line 196, in parse_tx_logs
    [
  File "C:\Users\mE\AppData\Local\Programs\Python\Python39\lib\site-packages\terra_sdk\core\auth\data\tx.py", line 197, in <listcomp>
    TxLog(msg_index=log["msg_index"], log=log["log"], events=log["events"])
KeyError: 'msg_index'

Fetch market price of mAssets

Hi, I am new to Terra SDK python and wanted to learn how I can fetch market price of non-native Terra tokens such as mAssets from the SDK. I would be very happy if you could guide me as I could not find much information about non-native assets.

is_tx_error() fails due to code now being 0 instead of None

  • terra_sdk version: 2.0.3
  • Python version: 3.10
  • Operating System: Windows 10

Description

Doing a broadcast now returns result.code = 0 instead of result.code = None so now is_tx_error(result) fails

What I Did

sendtx = self.wallet.create_and_sign_tx(CreateTxOptions(
    msgs=[execute],
    fee_denoms=["uusd"],
))
result = self.terra.tx.broadcast(sendtx)

error = is_tx_error(result)
if error:
    raise Exception(
        f"Transaction failed, TX_ID: {result.txhash}\nError: {result.raw_log}"
    )

this always triggers because is_tx_error always returns true now.

2.0.3
result: ......., code=0, codespace='', info=None, data=None, timestamp=None)

1.0.2
result: ........, code=None, codespace=None)

create_tx is no longer working in the latest release, it works on 1.0.2.

Hi.

I'm not sure if it's only me but due recent updates in terra.py my create_tx I used to simulate fees against the node is no longer working.

This code works below works on 1.0.2 but won't work on the latest. Error message I get is: TypeError: create_and_sign_tx() got an unexpected keyword argument 'msgs' when building tx using create_tx.

    def execute_contract_msg(self, contract_addr):

        mk = MnemonicKey(mnemonic='')
        simulation_wallet = self.terra.wallet(mk)
        msg = {count: {}}  
        try:
            execute = MsgExecuteContract(
                sender=simulation_wallet.key.acc_address,
                contract=contract_addr,
                execute_msg=msg,
                coins=Coins(),
            )

            tx = simulation_wallet.create_tx(
                msgs=[execute],
                fee_denoms=['uusd'],
                memo=".",
            )
            print(tx)

Unrecognized message type "cosmos-sdk/MsgTransfer"

  • terra_sdk version: 1.0.2
  • Python version: 3.9.2
  • Operating System: Debian 11

Description

I am trying to use the LCD client's tx_info method to download mainnet transaction D22FC6E.... The library doesn't seem to be able to parse the transaction after downloading it because it doesn't recognize the message type cosmos-sdk/MsgTransfer.

What I Did

>>> from terra_sdk.client.lcd import LCDClient
>>> client = LCDClient(url="https://lcd.terra.dev", chain_id="columbus-5")
>>> tx_info = client.tx.tx_info("D22FC6EB287D9F099DD8EBADAAC5D9A0F6AA9D6B87F4A35A3FACEF4182706A16")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/path/to/venv/lib/python3.9/site-packages/terra_sdk/client/lcd/api/_base.py", line 29, in decorator
    return instance._run_sync(async_call(instance, *args, **kwargs))
  File "/path/to/venv/lib/python3.9/site-packages/terra_sdk/client/lcd/api/_base.py", line 13, in _run_sync
    return self._c.loop.run_until_complete(coroutine)
  File "/path/to/venv/lib/python3.9/site-packages/nest_asyncio.py", line 81, in run_until_complete
    return f.result()
  File "/usr/lib/python3.9/asyncio/futures.py", line 201, in result
    raise self._exception
  File "/usr/lib/python3.9/asyncio/tasks.py", line 256, in __step
    result = coro.send(None)
  File "/path/to/venv/lib/python3.9/site-packages/terra_sdk/client/lcd/api/tx.py", line 36, in tx_info
    return TxInfo.from_data(await self._c._get(f"/txs/{tx_hash}", raw=True))
  File "/path/to/venv/lib/python3.9/site-packages/terra_sdk/core/auth/data/tx.py", line 279, in from_data
    StdTx.from_data(data["tx"]),
  File "/path/to/venv/lib/python3.9/site-packages/terra_sdk/core/auth/data/tx.py", line 147, in from_data
    [Msg.from_data(m) for m in data["msg"]],
  File "/path/to/venv/lib/python3.9/site-packages/terra_sdk/core/auth/data/tx.py", line 147, in <listcomp>
    [Msg.from_data(m) for m in data["msg"]],
  File "/path/to/venv/lib/python3.9/site-packages/terra_sdk/core/msg.py", line 11, in from_data
    return parse_msg(data)
  File "/path/to/venv/lib/python3.9/site-packages/terra_sdk/util/base.py", line 20, in from_data
    return table[data["type"]](data)
KeyError: 'cosmos-sdk/MsgTransfer'
>>>

supply.total()

  • terra_sdk version: 1.0.2 (and same behavior on 1.0.0)
  • Python version: 3.9.2
  • Operating System: Windows 10 (and similar behavior on Ubuntu WSL on Windows)

Description

I am trying to set-up getting information from Terra. I have imported terra_sdk and I am just trying to get some test set up. I can run terra.node_info() and terra.block_info() for both columbus-4 and columbus-5 but terra.supply.total() fails.

What I Did

Paste the command(s) you ran and the output.
If there was a crash, please include the traceback here.

terra = LCDClient(chain_id="columbus-5", url="https://lcd.terra.dev")
terra.supply.total()
Traceback (most recent call last):
File "", line 1, in
File "C:\Users\jsilverman\AppData\Roaming\Python\Python39\site-packages\terra_sdk\client\lcd\api_base.py", line 29, in decorator
File "C:\Users\jsilverman\AppData\Roaming\Python\Python39\site-packages\terra_sdk\client\lcd\api_base.py", line 13, in _run_sync
File "C:\Python39\lib\site-packages\nest_asyncio.py", line 70, in run_until_complete
return f.result()
File "C:\Python39\lib\asyncio\futures.py", line 201, in result
raise self._exception
File "C:\Python39\lib\asyncio\tasks.py", line 256, in __step
result = coro.send(None)
File "C:\Users\jsilverman\AppData\Roaming\Python\Python39\site-packages\terra_sdk\client\lcd\api\supply.py", line 15, in total
File "C:\Users\jsilverman\AppData\Roaming\Python\Python39\site-packages\terra_sdk\client\lcd\lcdclient.py", line 243, in _get
File "C:\Users\jsilverman\AppData\Roaming\Python\Python39\site-packages\terra_sdk\client\lcd\lcdclient.py", line 95, in _get
terra_sdk.exceptions.LCDResponseError: Status 501

Getting 403 forbidden from any LCDClient queries

  • terra_sdk version: 0.14.0
  • Python version: 3.7.6
  • Operating System: Mac OS Big Sur (11.5.1)

Description

When trying to query the chain like so

from terra_sdk.client.lcd import LCDClient

terra = LCDClient(chain_id="columbus-4", url="https://lcd.terra.dev")
terra.tendermint.node_info()

I am receiving the following error:

LCDResponseError: Status 403 - Forbidden
---------------------------------------------------------------------------
JSONDecodeError                           Traceback (most recent call last)
/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/terra_sdk/client/lcd/lcdclient.py in _get(self, endpoint, params, raw)
     90             try:
---> 91                 result = await response.json(content_type=None)
     92             except JSONDecodeError:

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/aiohttp/client_reqrep.py in json(self, encoding, loads, content_type)
   1112 
-> 1113         return loads(stripped.decode(encoding))
   1114 

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/__init__.py in loads(s, encoding, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw)
    347             parse_constant is None and object_pairs_hook is None and not kw):
--> 348         return _default_decoder.decode(s)
    349     if cls is None:

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/decoder.py in decode(self, s, _w)
    336         """
--> 337         obj, end = self.raw_decode(s, idx=_w(s, 0).end())
    338         end = _w(s, end).end()

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/decoder.py in raw_decode(self, 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)

During handling of the above exception, another exception occurred:

LCDResponseError                          Traceback (most recent call last)
<ipython-input-2-f7edf77fe692> in <module>
      2 
      3 terra = LCDClient(chain_id="columbus-4", url="https://lcd.terra.dev")
----> 4 terra.tendermint.node_info()

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/terra_sdk/client/lcd/api/_base.py in decorator(wrapped, instance, args, kwargs)
     27     @wrapt.decorator
     28     def decorator(wrapped, instance, args, kwargs):
---> 29         return instance._run_sync(async_call(instance, *args, **kwargs))
     30 
     31     return decorator

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/terra_sdk/client/lcd/api/_base.py in _run_sync(self, coroutine)
     11     def _run_sync(self, coroutine):
     12         """Runs an asynchronous coroutine synchronously."""
---> 13         return self._c.loop.run_until_complete(coroutine)
     14 
     15     @staticmethod

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/nest_asyncio.py in run_until_complete(self, future)
     68                 raise RuntimeError(
     69                     'Event loop stopped before Future completed.')
---> 70             return f.result()
     71 
     72     def _run_once(self):

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/futures.py in result(self)
    179         self.__log_traceback = False
    180         if self._exception is not None:
--> 181             raise self._exception
    182         return self._result
    183 

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/tasks.py in __step(***failed resolving arguments***)
    247                 # We use the `send` method directly, because coroutines
    248                 # don't have `__iter__` and `__next__` methods.
--> 249                 result = coro.send(None)
    250             else:
    251                 result = coro.throw(exc)

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/terra_sdk/client/lcd/api/tendermint.py in node_info(self)
     13             dict: node information
     14         """
---> 15         return await self._c._get("/node_info", raw=True)
     16 
     17     async def syncing(self) -> bool:

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/terra_sdk/client/lcd/lcdclient.py in _get(self, *args, **kwargs)
    241         )
    242         try:
--> 243             result = await super()._get(*args, **kwargs)
    244         finally:
    245             await self.session.close()

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/terra_sdk/client/lcd/lcdclient.py in _get(self, endpoint, params, raw)
     91                 result = await response.json(content_type=None)
     92             except JSONDecodeError:
---> 93                 raise LCDResponseError(message=str(response.reason), response=response)
     94             if not 200 <= response.status < 299:
     95                 raise LCDResponseError(message=result.get("error"), response=response)

This is the case for any query I have tried so far - is there some LCDClient config I am missing here? Thanks :)

Error when querying prices from Oracle

Description

Can't get prices from oracle using terra.oracle.exchange_rate('uusd').

What I Did

>>> terra.oracle.exchange_rates()
Coins('13.363899366807197127uaud,12.507059505101729225ucad,9.299427851702487944uchf,66.68376033969933393ucny,8.482260343541582751ueur,7.298704192986536663ugbp,80.525231868325979739uhkd,756.729796676163555129uinr,1126.838181910159832044ujpy,12907.245538546065628807ukrw,29579.640321016654708655umnt,7.182148051564867481usdr,85.923147806798035292usek,13.799548482083606946usgd,325.581339483602357661uthb,10.371857135833388667uusd')
>>> terra.oracle.exchange_rate('uusd')
Traceback (most recent call last):
  File "/snap/pycharm-community/238/plugins/python-ce/helpers/pydev/_pydevd_bundle/pydevd_exec2.py", line 3, in Exec
    exec(exp, global_vars, local_vars)
  File "<input>", line 1, in <module>
  File "/home/v-terra/PycharmProjects/x/venv/lib/python3.8/site-packages/terra_sdk/client/lcd/api/_base.py", line 29, in decorator
    return instance._run_sync(async_call(instance, *args, **kwargs))
  File "/home/v-terra/PycharmProjects/x/venv/lib/python3.8/site-packages/terra_sdk/client/lcd/api/_base.py", line 13, in _run_sync
    return self._c.loop.run_until_complete(coroutine)
  File "/home/v-terra/PycharmProjects/x/venv/lib/python3.8/site-packages/nest_asyncio.py", line 70, in run_until_complete
    return f.result()
  File "/usr/lib/python3.8/asyncio/futures.py", line 178, in result
    raise self._exception
  File "/usr/lib/python3.8/asyncio/tasks.py", line 280, in __step
    result = coro.send(None)
  File "/home/v-terra/PycharmProjects/x/venv/lib/python3.8/site-packages/terra_sdk/client/lcd/api/oracle.py", line 93, in exchange_rate
    rates = await self.exchange_rates()
TypeError: object Coins can't be used in 'await' expression

Cannot swap CW20 on Bombay & safe market price swaps

  • terra_sdk version: terra-sdk==1.0.2
  • Python version: 3.8.10
  • Operating System: Ubuntu 20.04

Description

I am trying to create function on Bombay that will handle CW20 to native and vice versa swaps. I have received some support on Discord, been through the docs, and reference other code on github but I cannot process my test swap of UST to mETH without error.

Describe what you were trying to get done.
I expected to receive confirmation of the swap, as I do when swapping native to native with the same function but instead either the Coins value or something else causes an error.

I am also interested in learning if there is some way I can edit my script so that I can rely on it to execute a swap automatically on POST but also:

  • Minimise fees as much as possible
  • Only sell at or close to the market rate

I want to avoid a situation where my script receives a sell signal when ETH is at 4K but I logon to find it actually sold on Terraswap for 3K due to volatility or any other reason. I can include a market value from Tradingview or somewhere else if necessary. Is there a good way to do this?

What I Did

I have left in some commented out different versions of code I have tried and the generated error messages:

from quart import Quart, request
from terra_sdk.client.lcd import AsyncLCDClient
from terra_sdk.core.coin import Coin
from terra_sdk.core.coins import Coins
from terra_sdk.key.mnemonic import MnemonicKey
from terra_sdk.core.market import MsgSwap
from terra_sdk.core.wasm import MsgExecuteContract
import json, config, asyncio, urllib, re, base64
from urllib.request import Request
import bcrypt
from terra_sdk.client.localterra import LocalTerra

app = Quart(__name__)

meth_ust_lp_testnet = 'terra1j4urgdl38ezrrs59fn403cxgr34u3yd0tv4ypn' # Testnet
meth_contract_testnet = 'terra1ys4dwwzaenjg2gy02mslmc96f267xvpsjat7gx' # Testnet
# beth_contract = 'terra1dzhzukyezv0etz22ud940z7adyv7xgcjkahuun' # Mainnet
# beth_ust_lp_contract = 'terra1c0afrdc5253tkp5wt7rxhuj42xwyf2lcre0s7c' # Mainnet

mk = MnemonicKey(mnemonic=config.MNEMONIC)
account = mk.acc_address

@app.before_serving
async def startup():
    # app.terra = AsyncLCDClient("https://bombay.stakesystems.io/", "bombay-12") # Use when testnet issues
    app.terra = AsyncLCDClient("https://bombay-lcd.terra.dev", "bombay-12") # https://bombay-lcd.terra.dev
    app.wallet = app.terra.wallet(mk)

@app.route('/webhook', methods=['POST'])
async def webhook():

    try:
     data = json.loads(await request.data)
     passphrase = data['passphrase']
    except Exception as e:
     print(e)
     passphrase = 'invalid'
    finally:
     if not bcrypt.checkpw(passphrase.encode('utf8'), config.HASHED):
        return {
                "code": "error",
                "message": "authentication failure"
                }

    balance = await app.terra.bank.balance(account) # remove await for localterra
    coins_human = balance.div(1_000_000)
    denoms = balance.denoms()

    bases = {
        "LUNA": "uluna",
        "ETH": "meth"
    }

    try:
     action = data['strategy']['order_action']  
     ticker = (data['ticker'])
     base = re.match("[A-Z]{3,4}(?=USD|UST|USDT|USDC|BUSD|BTC)", ticker).group(0)
     bar = (data['bar'])
    except Exception as e:
     print(e)
     return {
            "code": "error",
            "message": "malformed JSON"
            }
    
    ubase = bases[base]

    print(ubase)

    if ubase in denoms:
        ubase_coin = balance[ubase]
        ubase_coin_amount = ubase_coin.amount
    else:
        ubase_coin = None
        ubase_coin_amount = 0

    if 'uusd' in denoms:
        uquote_coin = balance['uusd']
        uquote_coin_amount = uquote_coin.amount
    else:
        uquote_coin = None
        uquote_coin_amount = 0

    print(coins_human)

    if ( (action == 'buy' and uquote_coin_amount > 100000000) or (action == 'sell' and ubase_coin_amount > 0) ):
        
        result = await swap( ( ubase_coin, uquote_coin - 100000000)[action == 'buy'], ( 'uusd', ubase)[action == 'buy'] )

        print(f'\n{(await app.terra.bank.balance(account)).div(1000000)}')
        if result:
            print('Swap complete.')
            print(coins_human)
            return {
                "code": "success",
                "message": "swap complete"
            }
        else:
            print('Swap failure.')
            print(coins_human)
            return {
                "code": "error",
                "message": "swap failure"              
                }
    else:
        print('Insufficient funds')
        print(coins_human)
        return {
            "code": "response",
            "message": "insufficient funds"
        }

def to_base64_string(data: dict) -> str:
    data_string = json.dumps(data)
    return base64.b64encode(data_string.encode("utf-8")).decode("utf-8")

async def swap( offer_coin, ask_denom ):
    print (f'Swapping {offer_coin.denom} for {ask_denom}.')
    
    # NATIVE --> NATIVE
    if offer_coin.denom == 'uluna' or ask_denom == 'uluna':
        swap = MsgSwap(mk.acc_address, offer_coin, ask_denom )
    
    # UST --> CW20:
    elif offer_coin.denom == 'uusd':
        print("In UST -->> CW20 block.")
        print (f"account : {account}")
        print (f"offer_coin : {offer_coin}")
        print(f'offer_coin.amount : {offer_coin.amount}')
        print(type(offer_coin))
        
        #print (offer_coin.amount * 1_000_000)
        # offer_coins = Coins([offer_coin])
        #offer_coins = Coins.from_str(f'{offer_coin}')
        #offer_coins = Coins(uusd=offer_coin.amount)
        offer_coins = Coins.from_data([offer_coin.to_data()])
        print(offer_coins)
        print(type(offer_coins))
        swap = MsgExecuteContract(
            sender = account,
            contract = meth_ust_lp_testnet,
            execute_msg = {
                "swap": {
                    "max_spread": "0.01",
                    "offer_asset": {
                        "info": {
                            "native_token": {
                                "denom": "uusd"
                            }
                        },
                        "amount": offer_coin.amount
                    },
                }
            },
            coins = offer_coins

            # coins = Coins(str(offer_coin)) # Error parsing into type
            # coins = Coins(offer_coin) # TypeError: could not create Coins object with argument: 26418195744uusd
            # coins = Coins.from_str(str(offer_coin.amount)) # terra_sdk.exceptions.LCDResponseError: <unprintable LCDResponseError object>
            # coins = Coins(str(offer_coin.amount)) # terra_sdk.exceptions.LCDResponseError: <unprintable LCDResponseError object
            # coins = Coins([Coin(str(offer_coin.denom), int(offer_coin.amount))])
            # coins = Coins([offer_coin])
            # coins = Coins.from_str(offer_coin.amount + 'uusd')
        )

    # CW20 --> UST:
    elif ask_denom == 'uusd':
        swap = MsgExecuteContract(
            sender = account,
            contract = meth_contract_testnet,
            execute_msg = {

                "send": {
                    "contract": meth_ust_lp_testnet,
                    "amount": offer_coin.amount,
                    "msg": to_base64_string({
                        "swap": {
                        "offer_asset": {
                            "info" : {
                                "token": {
                                    "contract_addr": "uusd" 
                                }
                            },
                            "amount": offer_coin.amount
                        },
                    }
                })
                }
            }
        )

    url_request = Request("https://fcd.terra.dev/v1/txs/gas_prices", headers={"User-Agent": "Mozilla/5.0"})
    live_gas_prices = json.loads(urllib.request.urlopen(url_request).read().decode())
    
    tx = await app.wallet.create_and_sign_tx(
        msgs = [swap],
        gas_prices = live_gas_prices,
        gas = 131300,
        fee_denoms = ['uusd']
    )

    tx_error = True

    delay = 1
    count = 0
    while tx_error and count < 100:
            result = await app.terra.tx.broadcast(tx)
            print(result)
            print(result.gas_used)
            tx_error = result.is_tx_error()
            print(f"\nError: {tx_error}")
            count = count + 1
            if tx_error == True:
                print(f"\nCount: {count}")
                await asyncio.sleep(delay)
                if count <= 5:
                    delay = (delay * 2)

    return not tx_error

# async def terraswap( offer_asset, denom ):

#         {
#         "swap": {
#         "offer_asset": {
#             "info" : {
#                 "native_token": {
#                     "denom": "uusd"
#                 }
#             },
#             "amount": AMOUNT * 1_000_000, # AMOUNT YOU WANT TO SWAP
#         },
#         "to": "terra1...", # cw20 contract
#         }
#     }

if __name__ == "__main__":
    app.run()

Output:

Swapping uusd for meth.
In UST -->> CW20 block.
account : terra18y3txnfkmtquwuzz2lqe8w23dsu29hjqxy0er9
offer_coin : 26401115340uusd
offer_coin.amount : 26401115340
<class 'terra_sdk.core.coin.Coin'>
26401115340uusd
<class 'terra_sdk.core.coins.Coins'>
BlockTxBroadcastResult(height=7048459, txhash='9084ABD54E2035FE46096DB3D1C98FB7DFF2D7FD2474A39DBAF6FE16696D9289', raw_log='failed to execute message; message index: 0: Error parsing into type terraswap::pair::ExecuteMsg: Invalid type: execute wasm contract failed', gas_wanted=131300, gas_used=64301, logs=None, code=4, codespace='wasm')

Is there a way to parse the tx information

I got the information of a block through the following link

https://blockdaemon-terra-lcd.api.bdnodes.net:1317/blocks/latest

But the tx in the obtained information is encrypted,

CpsHCqwFCjIvdGVycmEub3JhY2xlLnYxYmV0YTEuTXNnQWdncmVnYXRlRXhjaGFuZ2VSYXRlVm90ZRL1BAoEYTM5NhKJBDEyMi41NjUzOTc1MTQzNjIxMzU5NTd1YXVkLDExMi41NDI0NzA0NjAxMTE0MDM4NzZ1Y2FkLDgxLjE3MTY1NDU4OTYzMjY1OTU4MnVjaGYsNTYzLjM0ODc4NDc0NDI1MjI3NzA4M3VjbnksNTgxLjkwMjU1ODM0NTg2ODE5MjYyOXVka2ssNzguMjM2OTkzODc3MDM3ODYwMTcydWV1ciw2NS42NTE1NDIzMDI5NjQxMzkwODh1Z2JwLDY4OS4wMzk3NzI3MDQzMTc3ODk3NnVoa2QsMTI2NDYwMC4xMDQ5NjE5NzI4MjQwMjU4OTd1aWRyLDY1ODkuMjg1NjI3MTE5ODU5MDk2NzA1dWluciwxMDIzNC4zNjQwNTQ5ODk0ODk5MTc5NjV1anB5LDEwNTUzNi40MDk5NzU3NjYxMDg2NTgxMjZ1a3J3LDI1MTg3NS4yMTEwNjM5OTQ4NTAwNzU1MTJ1bW50LDQ1MzEuOTI5MzU5NDc5OTgwODk1OTQzdXBocCw2My4wOTM3OTEwMjY0Njg4NjQ1MTh1c2RyLDgwNS4wMDM5NTE0ODMyNDA3ODA1Mzh1c2VrLDExOS43NzMwNTAxNjc2NDkxOTI3ODN1c2dkLDI5NDUuMzU2MzEzMzg0Njc4MDQ2Mjk4dXRoYiw4OC4zOTMzOTQ5NTc2NzQ2ODEwMjF1dXNkGix0ZXJyYTFzZm12aHVmd2p2ZzM3dTR0M3ZlOTdwZGxjeTNtNndyd3N4ajl6dCIzdGVycmF2YWxvcGVyMTV6Y2pkdWF2eGM1bWtwOHFjcXM5ZXlod2xxd2Rscnp5NmpsbjNtCscBCjUvdGVycmEub3JhY2xlLnYxYmV0YTEuTXNnQWdncmVnYXRlRXhjaGFuZ2VSYXRlUHJldm90ZRKNAQooOGUxYmMxZjFjMTVkYzYxN2VlOGU0ZWVmM2EyMjQxMjE4ODIyNDJmZBIsdGVycmExc2Ztdmh1ZndqdmczN3U0dDN2ZTk3cGRsY3kzbTZ3cndzeGo5enQaM3RlcnJhdmFsb3BlcjE1emNqZHVhdnhjNW1rcDhxY3FzOWV5aHdscXdkbHJ6eTZqbG4zbRIgQHRlcnJhLW1vbmV5L29yYWNsZS1mZWVkZXJAMi4wLjASWgpSCkYKHy9jb3Ntb3MuY3J5cHRvLnNlY3AyNTZrMS5QdWJLZXkSIwohArxXLIfbrb1zZW75O4zGRGdjBJ1McwCFxnjqf+z8uPHqEgQKAggBGOKvSBIEEPCTCRpAy6hcGdiaHcbO7BW7EE7wN50Y2MK0yadNySu35SutLP8Uv7Q6uGXRye//I9P4PdBXxzdDZLgAbkyBfsI+ShEcbA==

image
Is there any way to parse out the tx information?

Certificate Verify Failed

Description

ClientConnectorCertificateError: Cannot connect to host lcd.terra.dev:443 ssl:True [SSLCertVerificationError: (1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:997)')]

What I Did

I copied code from the readme to test it locally

from terra_sdk.client.lcd import LCDClient
terra = LCDClient(chain_id="columbus-5", url="https://lcd.terra.dev")
terra.tendermint.block_info()['block']['header']['height']

Can't get block info for block height below 4724001

  • terra_sdk version: 1.0.0
  • Python version: 3.7.10
  • Operating System: OSX

Description

I can't get block info for block height below 4724001 even specify chain ID columbus-4.
How can I get all block info for those blocks?

What I Did

terra = LCDClient(chain_id="columbus-4", url="https://lcd.terra.dev")
pprint(terra.tendermint.block_info(1))

it raise error:

terra_sdk.exceptions.LCDResponseError: Status 500 - height 1 is not available, lowest height is 4724001

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.