diff --git a/.github/workflows/pytests.yml b/.github/workflows/pytests.yml index 0d96c82f..db636017 100644 --- a/.github/workflows/pytests.yml +++ b/.github/workflows/pytests.yml @@ -29,12 +29,13 @@ jobs: runs-on: ubuntu-latest env: # https://www.notion.so/nibiru/Resources-and-Repo-Configs-b31aa8074a2b419d80b0c946ed5efab0 - LCD_ENDPOINT: ${{ secrets.LCD_ENDPOINT }} - GRPC_ENDPOINT: ${{ secrets.GRPC_ENDPOINT }} - TENDERMINT_RPC_ENDPOINT: ${{ secrets.TENDERMINT_RPC_ENDPOINT }} - WEBSOCKET_ENDPOINT: ${{ secrets.WEBSOCKET_ENDPOINT }} - CHAIN_ID: ${{ secrets.CHAIN_ID }} - VALIDATOR_MNEMONIC: ${{ secrets.VALIDATOR_MNEMONIC }} + LCD_ENDPOINT: "http://localhost:1317" + GRPC_ENDPOINT: "localhost:9090" + TENDERMINT_RPC_ENDPOINT: "http://localhost:26657" + USE_LOCALNET: true + WEBSOCKET_ENDPOINT: "ws://localhost:26657/websocket" + CHAIN_ID: "nibiru-localnet-0" + VALIDATOR_MNEMONIC: "guard cream sadness conduct invite crumble clock pudding hole grit liar hotel maid produce squeeze return argue turtle know drive eight casino maze host" DEVNET_NUMBER: ${{ secrets.DEVNET_NUMBER }} steps: # ---------------------------------------------- @@ -97,6 +98,17 @@ jobs: - name: Install dependencies if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true' run: poetry install --no-interaction --no-root + + - name: Run chaosnet + uses: NibiruChain/localnet-action@v1.1 + id: chaosnet + with: + services: nibiru pricefeeder + ghtoken: ${{ secrets.GITHUB_TOKEN }} + ghactor: ${{ github.actor }} + + - name: sleep 30 seconds + run: sleep 30 #---------------------------------------------- # run tests #---------------------------------------------- diff --git a/examples/2- My first transaction.ipynb b/examples/2- My first transaction.ipynb index cdf34ee3..86917f9c 100644 --- a/examples/2- My first transaction.ipynb +++ b/examples/2- My first transaction.ipynb @@ -1,304 +1,304 @@ { - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import nibiru\n", - "import nibiru.msg # Messages package for transactions\n", - "import nibiru.exceptions\n", - "import json\n", - "import os" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "nibiru.__version__" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "network = nibiru.Network.devnet()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Transaction types" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "There are 3 ways to post transactions with the python Sdk, having to do with the synchronization needed by the user.\n", - "\n", - "```python\n", - "class TxType(Enum):\n", - " \"\"\"\n", - " The TxType allows you to chose what type of synchronization you want to use to send transaction\n", - " \"\"\"\n", - "\n", - " SYNC = 1\n", - " \"\"\"\n", - " The CLI waits for a CheckTx execution response only.\n", - " Each full-node that receives a transaction sends a CheckTx to the application layer to check for validity, and\n", - " receives an abci.ResponseCheckTx. If the Tx passes the checks, it is held in the nodes' Mempool , an in-memory pool\n", - " of transactions unique to each node pending inclusion in a block - honest nodes will discard Tx if it is found to\n", - " be invalid.\n", - "\n", - " Prior to consensus, nodes continuously check incoming transactions and gossip them to their peers.\n", - " \"\"\"\n", - "\n", - " ASYNC = 2\n", - " \"\"\"\n", - " The CLI returns immediately (transaction might fail silently).\n", - " If you send a transaction with this option, it is recommended to query the transaction output using the hash of the\n", - " transaction given by the output of the tx call.\n", - " \"\"\"\n", - "\n", - " BLOCK = 3\n", - " \"\"\"\n", - " The tx function will wait unitl the tx is be committed in a block.\n", - " This have the effect of having the full log of the transaction available with the output of the method. These logs\n", - " will include information as to coin sent and received, states changed etc.\n", - " \"\"\"\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can adjust our agent to open positions with any of those options" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tx_config = nibiru.TxConfig(tx_type=nibiru.TxType.BLOCK, gas_multiplier=3)\n", - "trader = nibiru.Sdk.authorize().with_network(network).with_config(tx_config)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Our trader don't have any fund, so if we try to open a position it will fail saying that the address does not exist (never registered with the auth module of the chain)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "pair = \"ubtc:unusd\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "try:\n", - " trader.tx.execute_msgs(\n", - " nibiru.msg.perp.MsgOpenPosition( # we will explain better this below\n", - " sender=trader.address,\n", - " pair=pair,\n", - " side=nibiru.Side.BUY,\n", - " quote_asset_amount=10,\n", - " leverage=10,\n", - " base_asset_amount_limit=0,\n", - " )\n", - ")\n", - "except nibiru.exceptions.SimulationError as exception:\n", - " print(\"Simulation error: \", exception)\n", - "else:\n", - " raise" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "For our example, let's fund our trader with some fund from the validator node of our local tesnet." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "VALIDATOR_MNEMONIC = os.environ.get(\n", - " \"VALIDATOR_MNEMONIC\", \n", - " \"guard cream sadness conduct invite crumble clock pudding hole grit liar hotel maid produce squeeze return argue turtle know drive eight casino maze host\",\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "validator = (\n", - " nibiru.Sdk\n", - " .authorize(VALIDATOR_MNEMONIC) # This allows us to recover the wallet with a mnemonic\n", - " .with_network(network)\n", - " .with_config(tx_config)\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now that we have a validator agent, let's send some fund with a MsgSend transaction" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tx_output = validator.tx.execute_msgs(\n", - " nibiru.msg.bank.MsgSend(\n", - " from_address=validator.address,\n", - " to_address=trader.address,\n", - " coins=[nibiru.Coin(1_000_000, \"unibi\"), nibiru.Coin(10_000_000, \"unusd\")]\n", - " )\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can now query the balance of the trader address using the query we saw in the previous notebook" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print(trader.query.get_bank_balances(trader.address))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Let's try to open again a position" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# New bug found today require us to run this command again.\n", - "# trader = nibiru.Sdk.authorize(trader).with_network(network).with_config(tx_config)\n", - "\n", - "trader = nibiru.Sdk.authorize(trader.mnemonic).with_network(network).with_config(tx_config)\n", - "\n", - "tx_output = trader.tx.execute_msgs(\n", - " nibiru.msg.perp.MsgOpenPosition( # we will explain better this below\n", - " sender=trader.address,\n", - " pair=pair,\n", - " side=nibiru.Side.BUY,\n", - " quote_asset_amount=10,\n", - " leverage=10,\n", - " base_asset_amount_limit=0,\n", - " )\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can take a look at the log of the transaction by reading the txoutput" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print(json.dumps(tx_output[\"rawLog\"], indent=4))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Documentation for msgs can be found there: https://nibiru-py.readthedocs.io/en/latest/nibiru.msg.html" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "trader.query.perp.position(pair=pair, trader=trader.address)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3.10.4 ('nibi')", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.4" - }, - "orig_nbformat": 4, - "vscode": { - "interpreter": { - "hash": "23c82724f6800107d27a1bc097df076b7f523b299f39e774e7f2b8b0c7154a18" - } - } - }, - "nbformat": 4, - "nbformat_minor": 2 + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import nibiru\n", + "import nibiru.msg # Messages package for transactions\n", + "import nibiru.exceptions\n", + "import json\n", + "import os" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "nibiru.__version__" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "network = nibiru.Network.devnet()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Transaction types" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "There are 3 ways to post transactions with the python Sdk, having to do with the synchronization needed by the user.\n", + "\n", + "```python\n", + "class TxType(Enum):\n", + " \"\"\"\n", + " The TxType allows you to chose what type of synchronization you want to use to send transaction\n", + " \"\"\"\n", + "\n", + " SYNC = 1\n", + " \"\"\"\n", + " The CLI waits for a CheckTx execution response only.\n", + " Each full-node that receives a transaction sends a CheckTx to the application layer to check for validity, and\n", + " receives an abci.ResponseCheckTx. If the Tx passes the checks, it is held in the nodes' Mempool , an in-memory pool\n", + " of transactions unique to each node pending inclusion in a block - honest nodes will discard Tx if it is found to\n", + " be invalid.\n", + "\n", + " Prior to consensus, nodes continuously check incoming transactions and gossip them to their peers.\n", + " \"\"\"\n", + "\n", + " ASYNC = 2\n", + " \"\"\"\n", + " The CLI returns immediately (transaction might fail silently).\n", + " If you send a transaction with this option, it is recommended to query the transaction output using the hash of the\n", + " transaction given by the output of the tx call.\n", + " \"\"\"\n", + "\n", + " BLOCK = 3\n", + " \"\"\"\n", + " The tx function will wait unitl the tx is be committed in a block.\n", + " This have the effect of having the full log of the transaction available with the output of the method. These logs\n", + " will include information as to coin sent and received, states changed etc.\n", + " \"\"\"\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can adjust our agent to open positions with any of those options" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tx_config = nibiru.TxConfig(tx_type=nibiru.TxType.BLOCK, gas_multiplier=3)\n", + "trader = nibiru.Sdk.authorize().with_network(network).with_config(tx_config)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Our trader don't have any fund, so if we try to open a position it will fail saying that the address does not exist (never registered with the auth module of the chain)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pair = \"ubtc:unusd\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "try:\n", + " trader.tx.execute_msgs(\n", + " nibiru.msg.perp.MsgOpenPosition( # we will explain better this below\n", + " sender=trader.address,\n", + " pair=pair,\n", + " side=nibiru.Side.BUY,\n", + " quote_asset_amount=10,\n", + " leverage=10,\n", + " base_asset_amount_limit=0,\n", + " )\n", + ")\n", + "except nibiru.exceptions.SimulationError as exception:\n", + " print(\"Simulation error: \", exception)\n", + "else:\n", + " raise" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For our example, let's fund our trader with some fund from the validator node of our local tesnet." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "VALIDATOR_MNEMONIC = os.environ.get(\n", + " \"VALIDATOR_MNEMONIC\", \n", + " \"guard cream sadness conduct invite crumble clock pudding hole grit liar hotel maid produce squeeze return argue turtle know drive eight casino maze host\",\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "validator = (\n", + " nibiru.Sdk\n", + " .authorize(VALIDATOR_MNEMONIC) # This allows us to recover the wallet with a mnemonic\n", + " .with_network(network)\n", + " .with_config(tx_config)\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now that we have a validator agent, let's send some fund with a MsgSend transaction" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tx_output = validator.tx.execute_msgs(\n", + " nibiru.msg.bank.MsgSend(\n", + " from_address=validator.address,\n", + " to_address=trader.address,\n", + " coins=[nibiru.Coin(1_000_000, \"unibi\"), nibiru.Coin(10_000_000, \"unusd\")]\n", + " )\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can now query the balance of the trader address using the query we saw in the previous notebook" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(trader.query.get_bank_balances(trader.address))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's try to open again a position" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# New bug found today require us to run this command again.\n", + "# trader = nibiru.Sdk.authorize(trader).with_network(network).with_config(tx_config)\n", + "\n", + "trader = nibiru.Sdk.authorize(trader.mnemonic).with_network(network).with_config(tx_config)\n", + "\n", + "tx_output = trader.tx.execute_msgs(\n", + " nibiru.msg.perp.MsgOpenPosition( # we will explain better this below\n", + " sender=trader.address,\n", + " pair=pair,\n", + " side=nibiru.Side.BUY,\n", + " quote_asset_amount=10,\n", + " leverage=10,\n", + " base_asset_amount_limit=0,\n", + " )\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can take a look at the log of the transaction by reading the txoutput" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(json.dumps(tx_output[\"rawLog\"], indent=4))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Documentation for msgs can be found there: https://nibiru-py.readthedocs.io/en/latest/nibiru.msg.html" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "trader.query.perp.position(pair=pair, trader=trader.address)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.10.4 ('nibi')", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.4" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "23c82724f6800107d27a1bc097df076b7f523b299f39e774e7f2b8b0c7154a18" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/tests/auth_test.py b/tests/auth_test.py index 291f61be..764a9eeb 100644 --- a/tests/auth_test.py +++ b/tests/auth_test.py @@ -9,9 +9,7 @@ def test_query_auth_account(sdk_val: nibiru.Sdk): query_resp: dict = sdk_val.query.auth.account(sdk_val.address)["account"] - tests.dict_keys_must_match( - query_resp, ['@type', 'address', 'pubKey', 'accountNumber', 'sequence'] - ) + tests.dict_keys_must_match(query_resp, ['@type', 'address', 'pubKey', 'sequence']) def test_query_auth_accounts(sdk_val: nibiru.Sdk):