{"id":13772747,"url":"https://github.com/PyWaves/PyWaves","last_synced_at":"2025-05-11T05:33:30.459Z","repository":{"id":14497066,"uuid":"76631764","full_name":"PyWaves/PyWaves","owner":"PyWaves","description":"Object-oriented library for the Waves blockchain platform","archived":false,"fork":false,"pushed_at":"2024-07-31T12:03:03.000Z","size":358,"stargazers_count":119,"open_issues_count":32,"forks_count":91,"subscribers_count":17,"default_branch":"master","last_synced_at":"2025-04-11T02:54:29.304Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/PyWaves.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2016-12-16T07:26:33.000Z","updated_at":"2025-01-28T23:46:22.000Z","dependencies_parsed_at":"2023-02-18T05:45:49.494Z","dependency_job_id":"54073459-4ba1-4bdc-8b63-67e1711c5b64","html_url":"https://github.com/PyWaves/PyWaves","commit_stats":{"total_commits":182,"total_committers":25,"mean_commits":7.28,"dds":0.5054945054945055,"last_synced_commit":"969213ff67425ec42aca28baedf7474fe8be76a5"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PyWaves%2FPyWaves","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PyWaves%2FPyWaves/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PyWaves%2FPyWaves/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PyWaves%2FPyWaves/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PyWaves","download_url":"https://codeload.github.com/PyWaves/PyWaves/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253523690,"owners_count":21921815,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-03T17:01:07.465Z","updated_at":"2025-05-11T05:33:30.267Z","avatar_url":"https://github.com/PyWaves.png","language":"Python","funding_links":[],"categories":["Frameworks and tools"],"sub_categories":["Client libraries"],"readme":"# PyWaves\nPyWaves is an object-oriented Python interface to the Waves blockchain platform.\n\n## Getting Started\n\nYou can install PyWaves using:\n\n    pip install pywaves\n\n## Documentation\n\nThe library utilizes classes to represent various Waves data structures:\n\n- pywaves.Address\n- pywaves.Asset\n- pywaves.AssetPair\n- pywaves.Order\n\n#### Code Example\n```python\nimport pywaves as pw\n\nmyAddress = pw.Address(privateKey='CtMQWJZqfc7PRzSWiMKaGmWFm4q2VN5fMcYyKDBPDx6S')\notherAddress = pw.Address('3PNTcNiUzppQXDL9RZrK3BcftbujiFqrAfM')\nmyAddress.sendWaves(otherAddress, 10000000)\nmyToken = myAddress.issueAsset('Token1', 'My Token', 1000, 0)\nwhile not myToken.status():\n\tpass\nmyAddress.sendAsset(otherAddress, myToken, 50)\n\n```\n\n### Address Class\n__pywaves.Address(address, publicKey, privateKey, seed)__ _Creates a new Address object_\n\n#### attributes:\n- _address_\n- _publicKey_\n- _privateKey_\n- _seed_\n\n#### methods:\n\n`balance(assetId='', confirmations=0)` returns balance of Waves or other assets\n\n`assets()` returns a list of assets owned by the address\n\n`issueAsset(name, description, quantity, decimals=0, reissuable=False, txFee=DEFAULT_ASSET_FEE, timestamp=0)` issue a new asset\n\n`reissueAsset(Asset, quantity, reissuable=False, txFee=DEFAULT_ASSET_FEE, timestamp=0)` reissue an asset\n\n`burnAsset(Asset, quantity, txFee=DEFAULT_ASSET_FEE, timestamp=0)` burn the specified quantity of an asset\n\n`sendWaves(recipient, amount, attachment='', txFee=DEFAULT_TX_FEE, timestamp=0)` send specified amount of Waves to recipient\n\n`massTransferWaves(transfers, attachment='', timestamp=0)` sending Waves tokens via a mass transfer\n\n`sendAsset(recipient, asset, amount, attachment='', txFee=DEFAULT_TX_FEE, timestamp=0)` send specified amount of an asset to recipient\n\n`massTransferWaves(self, transfers, attachment='', timestamp=0)` sending an asset via mass transfer\n\n`cancelOrder(assetPair, order)` cancel an order\n\n`buy(assetPair, amount price, maxLifetime=30*86400, matcherFee=DEFAULT_MATCHER_FEE, timestamp=0)` post a buy order\n\n`tradableBalance(assetPair)` get tradable balance for the specified asset pair\n\n`sell(assetPair, amount, price, maxLifetime=30*86400, matcherFee=DEFAULT_MATCHER_FEE, timestamp=0)` post a sell order\n\n`lease(recipient, amount, txFee=DEFAULT_LEASE_FEE, timestamp=0)` post a lease transaction\n\n`leaseCancel(leaseId, txFee=DEFAULT_LEASE_FEE, timestamp=0)` cancel a lease\n\n`getOrderHistory(assetPair)` get order history for the specified asset pair\n\n`cancelOpenOrders(assetPair)` cancel all open orders for the specified asset pair\n\n`deleteOrderHistory(assetPair)` delete order history for the specified asset pair\n\n`createAlias(alias, txFee=DEFAULT_ALIAS_FEE, timestamp=0)` create alias\n\n`sponsorAsset(assetId, minimalFeeInAssets, txFee=pywaves.DEFAULT_SPONSOR_FEE, timestamp=0)` sponsoring assets\n\n`setScript(script, txFee=pywaves.DEFAULT_SCRIPT_FEE, timestamp=0)` sets a script for this address\n\n`dataTransaction(data, timestamp=0)` sets data for the account. data should be a json array with entries including type (bool, binary, int, string), key and value\n\n`deleteDataEntry(key)` deletes a given data entry, identified by key, from the data storage of the account\n\n`setScript(scriptSource, txFee=pywaves.DEFAULT_SCRIPT_FEE, timestamp=0)` issue a smart asset\n\n`setAssetScript(asset, scriptSource, txFee=pywaves.DEFAULT_ASSET_SCRIPT_FEE, timestamp=0)` set a new script for a smart asset\n\n`invokeScript(dappAddress, functionName, params, payments, feeAsset = None, txFee=pywaves.DEFAULT_INVOKE_SCRIPT_FEE)` invoke a script on a given dapp address\n\n### Asset Class\n__pywaves.Asset(assetId)__ _Creates a new Asset object_\n\n#### attributes:\n- _status_\n- _assetId_\t\n- _issuer_\n- _name_\n- _description_\t\n- _quantity_\n- _decimals_ = 0\n- _reissuable = False_\n\n#### methods:\n`status()` returns 'Issued' if the asset exists\n\n\n### AssetPair Class\n__pywaves.AssetPair(asset1, asset2)__ _Creates a new AssetPair object with 2 Asset objects_\n\n#### attributes:\n- _asset1_\n- _asset2_\n\n#### methods:\n`orderbook()` get order book\n\n`ticker()` get ticker with 24h ohlcv data  \n\n`last()` get traded price  \n\n`open()` get 24h open price  \n\n`high()` get 24h high price  \n\n`low()` get 24h low price  \n\n`close()` get 24h close price (same as last())  \n\n`vwap()` get 24h vwap price  \n\n`volume()` get 24h volume  \n\n`priceVolume()` get 24h price volume  \n\n`trades(n)` get the last n trades  \n\n`trades(from, to)` get the trades in from/to interval  \n\n`candles(timeframe, n)` get the last n candles in the specified timeframe  \n\n`candles(timeframe, from, to)` get the candles in from/to interval in the specified timeframe \n\n### Order Class\n__pywaves.Order(orderId, assetPair, address='')__ Creates a new Order object\n\n#### attributes:\n- _status_\n- _orderId_\n- _assetPair_\n- _address_\n- _matcher_\n- _matcherPublicKey_\n\n#### methods:\n`status()` returns current order status\n`cancel()` cancel the order\n\n### WXFeeCalculator Class\nThis class is meant to provide the necessary functionality to calculate fees according to the new WX fee structure\n\nAll values here for price and amounts of tokens are always in the smallest unit of the token (\"satoshis\").\n#### Methods:\n`calculateDynamicFee()` calculates the dynamic fee for a trade\n\n`calculateDynamicDiscountFee()` calculates the dynamic discounted fee for a trade\n\n`calculatePercentSellingFee(priceAssetId, amountAssetId, amountToSell)` calculates the percentage selling fee for a trade\n\n`calculatePercentDiscountedSellingFee(priceAssetId, amountAssetId, amountToSell)` calculates the discounted percentage selling fee for a trade\n\n`calculatePercentBuyingFee(priceAssetId, price, amountToBuy)` calculates the percentage buying fee for a trade\n\n`calculatePercentDiscountedBuyingFee(priceAssetId, price, amountToBuy)` calculates the discounted percentage buying fee for a trade\n\n\n#### Example:\n```\nimport pywaves as pw\n\nconfig = {\n    'amountAsset': 'WAVES',\n    'priceAsset': '25FEqEjRkqK6yCkiT7Lz6SAYz7gUFCtxfCChnrVFD5AT',\n    'privateKey': 'xxx'\n}\n\npw.setNode('https://nodes-testnet.wavesnodes.com/', chain='testnet')\npw.setMatcher('http://matcher-testnet.waves.exchange')\n\nwxFeeCalculator = pw.WXFeeCalculator()\naddress = pw.Address(privateKey=config['privateKey'])\ntradingPair = pw.AssetPair(pw.Asset(config['amountAsset']), pw.Asset(config['priceAsset']))\nprice = 5\namountToBuy = 1000000000\nmatcherFee = wxFeeCalculator.calculatePercentDiscountedBuyingFee(config['priceAsset'], price, amountToBuy)\ntx = address.buy(tradingPair, amountToBuy, price, matcherFee = matcherFee, matcherFeeAssetId = 'EMAMLxDnv3xiz8RXg8Btj33jcEw3wLczL3JKYYmuubpc')\nprint (tx)\n```\n\n## Other functions\n`pywaves.setNode(node, chain, chain_id)`  set node URL ('http://ip-address:port') and chain (either 'mainnet' or 'testnet', or any other chain, if you also define the chain id)\n\n`pywaves.setChain(chain, chain_id)`  set chain (either 'mainnet' or 'testnet', or any other chain if you also supply the chain id)\n\n`pywaves.setOffline()`  switch to offline mode; sign tx locally without broadcasting to network\n\n`pywaves.setOnline()`  switch to online mode; sign tx locally a broadcast to network\n\n`pywaves.validateAddress(address)`  checks if the provided address is a valid Waves address\n\n`pywaves.setMatcher(node)`  set matcher URL ('http://ip-address:port')\n\n`pywaves.setDatafeed(node)`  set datafeed URL ('http://ip-address:port')\n\n`pywaves.height()` get blockchain height\n\n`pywaves.lastblock()` get last block\n\n`pywaves.block(n)` get block at specified height\n\n`pywaves.tx(id)` get transaction details\n\n`pywaves.stateChangeForTx(id):` get the state changes for the given tx by id\n\n`pywaves.stateChangesForAddress(address, limit = 1000):` get the last \u003climit\u003e (with a default of 1000) state changes for the given address\n\n`pywaves.symbols()` get list of symbol-asset mapping\n\n`pywaves.markets()` get all traded markets with tickers\n\n`pywaves.{SYMBOL_NAME}` get predefined asset for the specified symbol (pywaves.WAVES, pywaves.BTC, pywaves.USD,...)\n\n\n### Default Fees\nThe fees for waves/asset transfers, asset issue/reissue/burn and matcher transactions are set by default as follows:\n* DEFAULT_TX_FEE = 100000\n* DEFAULT_ASSET_FEE = 100000000\n* DEFAULT_MATCHER_FEE = 1000000\n* DEFAULT_LEASE_FEE = 100000\n* DEFAULT_ALIAS_FEE = 100000\n* DEFAULT_SPONSOR_FEE = 100000000\n* DEFAULT_SCRIPT_FEE = 100000\n\n## More Examples\n\n#### Playing with addresses:\n\n```python\nimport pywaves as pw\n\n# generate a new address\nmyAddress = pw.Address(\"\u003csome address\u003e\")\nmyAddress._generate()\n\n# set an address with an address\nmyAddress = pw.Address('3P6WfA4qYtkgwVAsWiiB6yaea2X8zyXncJh')\n\n# get an existing address from seed\nmyAddress = pw.Address(seed='seven wrist bargain hope pattern banner plastic maple student chaos grit next space visa answer')\n\n# get an existing address from privateKey\nmyAddress = pw.Address(privateKey='CtMQWJZqfc7PRzSWiMKaGmWFm4q2VN5fMcYyKDBPDx6S')\n\n# get an existing address from a publicKey\naddress = pw.Address(publicKey=“EYNuSmW4Adtcc6AMCZyxkiHMPmF2BZ2XxvjpBip3UFZL”)\n\n# get an address from a seed with a different nonce (This is especially useful for accessing addresses generated by nodes)\nmyAddress = pw.Address(seed='seven wrist bargain hope pattern banner plastic maple student chaos grit next space visa answer', nonce=1)\n```\n\n#### Balances:\n```python\nimport pywaves as pw\n\nmyAddress = pw.Address('3P6WfA4qYtkgwVAsWiiB6yaea2X8zyXncJh')\n\n# get Waves balance\nprint(\"Your balance is %18d\" % myAddress.balance())\n\n# get Waves balance after 20 confirmations \nprint(\"Your balance is %18d\" % myAddress.balance(confirmations = 20))\n\n# get an asset balance\nprint(\"Your asset balance is %18d\" % myAddress.balance('DHgwrRvVyqJsepd32YbBqUeDH4GJ1N984X8QoekjgH8J'))\n```\n\n#### Waves and asset transfers:\n```python\nimport pywaves as pw\n\nmyAddress = pw.Address(privateKey='CtMQWJZqfc7PRzSWiMKaGmWFm4q2VN5fMcYyKDBPDx6S')\n\n# send Waves to another address\nmyAddress.sendWaves(recipient = pw.Address('3PNTcNiUzppQXDL9RZrK3BcftbujiFqrAfM'),\n                    amount = 100000000)\n\n# send asset to another address\nmyToken = pw.Asset('4ZzED8WJXsvuo2MEm2BmZ87Azw8Sx7TVC6ufSUA5LyTV')\nmyAddress.sendAsset(recipient = pw.Address('3PNTcNiUzppQXDL9RZrK3BcftbujiFqrAfM'),\n                    asset = myToken,\n                    amount = 1000)\n```\n\n#### Issuing an asset:\n```python\nimport pywaves as pw\n\nmyToken = myAddress.issueAsset( name = \"MyToken\",\n                                description = \"This is my first token\",\n                                quantity = 1000000,\n                                decimals = 2 )\n```\n\n#### Create an alias:\n```python\nimport pywaves as pw\n\npw.setNode(node = 'http://127.0.0.1:6869', chain = 'testnet')\n\nmyAddress = pw.Address(privateKey='CtMQWJZqfc7PRzSWiMKaGmWFm4q2VN5fMcYyKDBPDx6S')\nmyAddress.createAlias(\"MYALIAS1\")\n```\n\n#### Mass payment:\n```python\nimport pywaves as pw\n\nrecipients =   ['3PBbp6bg2YEnHfdJtYM7jzzXYQeb7sx5oFg',\n                '3P4A27aCd3skNja46pcgrLYEnK36TkSzgUp',\n                '3P81U3ujotNUwZMWALdcJQLzBVbrAuUQMfs',\n                '3PGcKEMwQcEbmeL8Jhe9nZQRBNCNdcHCoZP',\n                '3PKjtzZ4FhKrJUikbQ1hRk5xbwVKDyTyvkn']\n\nmyAddress = pw.Address(privateKey = \"CtMQWJZqfc7PRzSWiMKaGmWFm4q2VN5fMcYyKDBPDx6S\")\n\nfor address in recipients:\n\tmyAddress.sendWaves(pw.Address(address), 1000000)\n```\n\n#### Mass transfer of Waves (feature 11)\n```python\nimport pywaves as pw\n\ntransfers = [\n\t{ 'recipient': '3N1xca2DY8AEwqRDAJpzUgY99eq8J9h4rB3', 'amount': 1 },\n\t{ 'recipient': '3N3YWbQ27NnK7tek6ASFh38Bj93guLxxSi1', 'amount': 2 },\n\t{ 'recipient': '3MwiB5UkWxt4X1qJ8DQpP2LpM3m48V1z5rC', 'amount': 3 }\n]\n\naddress = pw.Address(privateKey = \"CtMQWJZqfc7PRzSWiMKaGmWFm4q2VN5fMcYyKDBPDx6S\")\naddress.massTransferWaves(transfers)\n```\n\n#### Mass transfer of Assets (feature 11)\n```python\nimport pywaves as pw\n\ntransfers = [\n\t{ 'recipient': '3N1xca2DY8AEwqRDAJpzUgY99eq8J9h4rB3', 'amount': 1 },\n\t{ 'recipient': '3N3YWbQ27NnK7tek6ASFh38Bj93guLxxSi1', 'amount': 2 },\n\t{ 'recipient': '3MwiB5UkWxt4X1qJ8DQpP2LpM3m48V1z5rC', 'amount': 3 }\n]\n\naddress = pw.Address(privateKey = \"CtMQWJZqfc7PRzSWiMKaGmWFm4q2VN5fMcYyKDBPDx6S\")\naddress.massTransferAssets(transfers, pw.Asset('9DtBNdyBCyViLZHptyF1HbQk73F6s7nQ5dXhNHubtBhd'))\n```\n#### Data Transaction: \n```python\nimport pywaves as py\n\nmyAddress = py.Address(privateKey='CtMQWJZqfc7PRzSWiMKaGmWFm4q2VN5fMcYyKDBPDx6S')\n\ndata = [{\n        'type':'string', \n        'key': 'test', \n        'value':'testval'\n        }]\n\nmyAddress.dataTransaction(data)\n\n```\n#### Token airdrop:\n```python\nimport pywaves as pw\n\nmyAddress = pw.Address(privateKey = '`')\nmyToken = pw.Asset('4ZzED8WJXsvuo2MEm2BmZ87Azw8Sx7TVC6ufSUA5LyTV')\namount = 1000\n\nwith open('recipients.txt') as f:\n\tlines = f.readlines()\nfor address in lines:\n\tmyAddress.sendAsset(pw.Address(address.strip()), myToken, amount)\n```\n\n#### Add a script to an account:\n```python\nimport pywaves as pw\nimport base64\n\npw.setNode(node='\u003cnode\u003e', chain='testnet')\n\nscript = 'match tx { \\n' + \\\n'  case _ =\u003e true\\n' + \\\n'}'\naddress = pw.Address(privateKey = \"\u003cprivate key\u003e\")\ntx = address.setScript(script, txFee=1000000)\n```\n\n#### Issue a Smart Asset\n```python\nimort pywaves as pw\nimport base64\n\npw.setNode(node='\u003cnode\u003e', chain='testnet')\n\nscript = 'match tx { \\n' + \\\n'  case _ =\u003e true\\n' + \\\n'}'\naddress = pw.Address(privateKey = '\u003cprivate key\u003e')\ntx = address.issueSmartAsset('smartTestAsset', 'an asset for testingsmart assets', 1000, script, 2)\n```\n\n#### Set a new script for a Smart Asset\n```python\nimport pywaves as pw\nimport base64\n\npw.setNode(node='\u003cnode\u003e', chain='testnet')\n\nscript = 'match tx { \\n' + \\\n'  case _ =\u003e true\\n' + \\\n'}'\naddress = pw.Address(privateKey = '\u003cprivate key\u003e')\ntx = address.setAssetScript(pw.Asset('\u003casset id\u003e'), script)\n```\n\n#### Invoking a script on a dapp address\n```python\nimport pywaves as pw\n\npw.setNode(node='\u003cnode\u003e', chain='testnet')\n\naddress = pw.Address(privateKey = '\u003cprivate key\u003e')\ntx = address.invokeScript('3N5Wq22bLSf3gt5VwHTCRbRnETeSwpuT8kK', 'fundRecipient', [{\"type\": \"integer\", \"value\": 100, }, { \"type\": \"string\", \"value\": \"test\" }, { \"type\": \"boolean\", \"value\": True }], [ { \"amount\": 100, \"assetId\": \"BGNVLgPKLwiBiZ7vWLcy3r92MzpPCU2DuUb4tv9W6gMi\" } ])\n```\n\n#### Working with contracts\n```python\nimport pywaves as pw\n\npw.setNode(node = '\u003cnode\u003e', 'T')\n\ncontract = pw.Contract('3N7XfieeJ8dHyMJfs7amukzxKB1PfMXzHzi', '\u003cseed\u003e')\ncontract.faucet()\n```\n\n#### Working with oracles\nQuerrying oracles:\n```python\nimport pywaves as pw\n\noracle = pw.Oracle(oracleAddress = '3P4PCxsJqMzQBALo8zANHtBDZRRquobHQp7')\n# getting all data entries for an oracle\nprint(oracle.getData())\n# getting data for a specific key of an oracle\nprint(oracle.getData('order_total_EeH5DRjdMnoYDhNbtkLsRNZq95etJUqWtvMDBCXojBoy'))\n# getting all data entries of an oracle filtered by a regular expression\nprint(oracle.getData(regex = '^order_total_.*$'))\n```\nStoring data in an oracle:\n```python\nimport pywaves as pw\n\npw.setNode('https://testnode1.wavesnodes.com', 'T')\n\noracle = pw.Oracle(seed='\u003cyour seed here\u003e')\nprint(oracle.storeData('oracle_test', 'string', 'test entry from oracle class'))\n```\n\n#### Working with more than one network\n```python\nimport pywaves as pw\n\nconfig = pw.ParallelPyWaves()\nconfig.setNode('https://testnode1.wavesnodes.com', 'testnet')\n\ntAddress = pw.Address(seed = \"test test test\", pywaves = config)\n\naddress = pw.Address(seed = \"test test test\")\nprint(tAddress.address)\nprint(address.address)\nprint(tAddress.address)\n```\n\n#### Playing with Waves Matcher node (DEX):\n```python\t\nimport pywaves as pw\n\n# set Matcher node to use\npw.setMatcher(node = 'http://127.0.0.1:6886')\n\n# post a buy order\nBTC = pw.Asset('4ZzED8WJXsvuo2MEm2BmZ87Azw8Sx7TVC6ufSUA5LyTV')\nUSD = pw.Asset('6wuo2hTaDyPQVceETj1fc5p4WoMVCGMYNASN8ym4BGiL')\nBTC_USD = pw.AssetPair(BTC, USD)\nmyOrder = myAddress.buy(assetPair = BTC_USD, amount = 15e8, price = 95075)\n\n# post a sell order\nWCT = pw.Asset('6wuo2hTaDyPQVceETj1fc5p4WoMVCGMYNASN8ym4BGiL')\nIncent = pw.Asset('FLbGXzrpqkvucZqsHDcNxePTkh2ChmEi4GdBfDRRJVof')\nWCT_Incent = pw.AssetPair(WCT, Incent)\nmyOrder = myAddress.sell(assetPair = WCT_Incent, amount = 100e8, price = 25e8)\n\n# post a buy order using Waves as price asset\nBTC = pw.Asset('4ZzED8WJXsvuo2MEm2BmZ87Azw8Sx7TVC6ufSUA5LyTV')\nBTC_WAVES = pw.AssetPair(BTC, pw.WAVES)\nmyOrder = myAddress.buy(assetPair = BTC_WAVES, amount = 1e8, price = 50e8)\n\n# cancel an order\nmyOrder.cancel()\n# or\nmyAddress.cancelOrder(assetPair, myOrder)\n\n```\n\n#### Getting Market Data from Waves Data Feed (WDF):\n```python\t\nimport pywaves as pw\n\n# set the asset pair\nWAVES_BTC = pw.AssetPair(pw.WAVES, pw.BTC)\n\n# get last price and volume\nprint(\"%s %s\" % (WAVES_BTC.last(), WAVES_BTC.volume()))\n\n# get ticker\nticker = WAVES_BTC.ticker()\nprint(ticker['24h_open'])\nprint(ticker['24h_vwap'])\n\n# get last 10 trades\ntrades = WAVES_BTC.trades(10)\nfor t in trades:\n\tprint(\"%s %s %s %s\" % (t['buyer'], t['seller'], t['price'], t['amount']))\n\t\n# get last 10 daily OHLCV candles\nohlcv = WAVES_BTC.candles(1440, 10)\nfor t in ohlcv:\n\tprint(\"%s %s %s %s %s\" % (t['open'], t['high'], t['low'], t['close'], t['volume']))\n```\n\n#### LPOS\n```python\nimport pywaves as pw\n\n# connect to a local testnet node\npw.setNode(node = 'http://127.0.0.1:6869', chain = 'testnet')\n\nmyAddress = pw.Address(privateKey = 'CsBpQpNE3Z1THNMS9vJPaXqYwN9Hgmhd9AsAPrM3tiuJ')\nminerAddress = pw.Address('3NBThmVJmcexzJ9itP9KiiC2K6qnGQwpqMq')\n\n# lease 1000 Waves to minerAddress\nleaseId = myAddress.lease(minerAddress, 100000000000)\n\n# revoke the lease\nmyAddress.leaseCancel(leaseId)\n\n```\n\n#### Doing simple multisig\nThanks to the new functionality of the TxSigner and TxGenerator classes, new functionality like multisig is possible:\n````python\npw.setNode('https://nodes-testnet.wavesnodes.com', 'T')\nfirstAddress = address.Address(seed = 'this is just a simple test seed one')\nsecondAddress = address.Address(seed = 'this is just a simple test seed two')\n\ngenerator = txGenerator.TxGenerator()\nsigner = txSigner.TxSigner()\ntx = generator.generateSendWaves(secondAddress, 1, firstAddress.publicKey, txFee=500000)\nsigner.signTx(tx, firstAddress.privateKey)\nsigner.signTx(tx, secondAddress.privateKey)\n\nres = firstAddress.broadcastTx(tx)\n````\n\n### Using PyWaves in a Python shell\n\n#### Check an address balance:\n```\n\u003e\u003e\u003e import pywaves as pw\n\u003e\u003e\u003e pw.Address('3P31zvGdh6ai6JK6zZ18TjYzJsa1B83YPoj')\naddress = 3P31zvGdh6ai6JK6zZ18TjYzJsa1B83YPoj\npublicKey = \nprivateKey = \nseed = \nbalances:\n  Waves = 1186077288304570\n  BDMRyZsmDZpgKhdM7fUTknKcUbVVkDpMcqEj31PUzjMy (Tokes) = 43570656915\n  RRBqh2XxcwAdLYEdSickM589Vb4RCemBCPH5mJaWhU9 (Ripto Bux) = 4938300000000\n  4rmhfoscYcjz1imNDvtz45doouvrQqDpbX7xdfLB4guF (incentCoffee) = 7\n  Ftim86CXM6hANxArJXZs2Fq7XLs3nJvgBzzEwQWwQn6N (Waves) = 2117290600000000\n  E4ip4jzTc4PCvebYn1818T4LNoYBVL3Y4Y4dMPatGwa9 (BitCoin) = 500000000000\n  FLbGXzrpqkvucZqsHDcNxePTkh2ChmEi4GdBfDRRJVof (Incent) = 12302659925430\n  GQr2fpkfmWjMaZCbqMxefbiwgvpcNgYdev7xpuX6xqcE (KISS) = 1000\n  DxG3PLganyNzajHGzvWLjc4P3T2CpkBGxY4J9eJAAUPw (UltraCoin) = 200000000000000\n  4eWBPyY4XNPsFLoQK3iuVUfamqKLDu5o6zQCYyp9d8Ae (LIKE) = 1000\n\u003e\u003e\u003e \n```\n\n#### Generate a new address:\n```\n\u003e\u003e\u003e import pywaves as pw\n\u003e\u003e\u003e newAddress = pw.Address('\u003csome address\u003e')\n\u003e\u003e\u003e newAddress._generate()\naddress = 3P6WfA4qYtkgwVAsWiiB6yaea2X8zyXncJh\npublicKey = EYNuSmW4Adtcc6AMCZyxkiHMPmF2BZ2XxvjpBip3UFZL\nprivateKey = CtMQWJZqfc7PRzSWiMKaGmWFm4q2VN5fMcYyKDBPDx6S\nseed = seven wrist bargain hope pattern banner plastic maple student chaos grit next space visa answer\nbalances:\n  Waves = 0\n\u003e\u003e\u003e \n```\n\n#### Check an asset:\n```\n\u003e\u003e\u003e import pywaves as pw\n\u003e\u003e\u003e pw.Asset('DHgwrRvVyqJsepd32YbBqUeDH4GJ1N984X8QoekjgH8J')\nstatus = Issued\nassetId = DHgwrRvVyqJsepd32YbBqUeDH4GJ1N984X8QoekjgH8J\nissuer = 3PPKF2pH4KMYgsDixjrhnWrPycVHr1Ye37V\nname = WavesCommunity\ndescription = Waves community token.\nquantity = 1000000000\ndecimals = 2\nreissuable = False\n```\n\n#### Post an order and check its status:\n```\n\u003e\u003e\u003e myOrder = myAddress.buy(pw.AssetPair(token1, token2), 1, 25)\n\u003e\u003e\u003e myOrder\nstatus = Accepted\nid = ARZdYgfXz3ksRMvhnGeLLJnn3CQnz7RCa7U6dVw3zert\nasset1 = AFzL992FQbhcgSZGKDKAiRWcjtthM55yVCE99hwbHf88\nasset2 = 49Aha2RR2eunR3KZFwedfdi7K9v5MLQbLYcmVdp2QkZT\nsender.address = 3P6WfA4qYtkgwVAsWiiB6yaea2X8zyXncJh\nsender.publicKey = EYNuSmW4Adtcc6AMCZyxkiHMPmF2BZ2XxvjpBip3UFZL\nmatcher = http://127.0.0.1:6886\n```\n\n#### Cancel the order\n```\n\u003e\u003e\u003e myOrder.cancel()\n\u003e\u003e\u003e myOrder\nstatus = Cancelled\nid = ARZdYgfXz3ksRMvhnGeLLJnn3CQnz7RCa7U6dVw3zert\nasset1 = AFzL992FQbhcgSZGKDKAiRWcjtthM55yVCE99hwbHf88\nasset2 = 49Aha2RR2eunR3KZFwedfdi7K9v5MLQbLYcmVdp2QkZT\nsender.address = 3P6WfA4qYtkgwVAsWiiB6yaea2X8zyXncJh\nsender.publicKey = EYNuSmW4Adtcc6AMCZyxkiHMPmF2BZ2XxvjpBip3UFZL\nmatcher = http://127.0.0.1:6886\n```\n\n### Offline signing and custom timestamps\n\n#### Offline signing a future transaction:\n```\n\u003e\u003e\u003e import pywaves as pw\n\u003e\u003e\u003e pw.setOffline()\n\u003e\u003e\u003e myAddress=pw.Address(privateKey=\"F2jVbjrKzjUsZ1AQRdnd8MmxFc85NQz5jwvZX4BXswXv\")\n\u003e\u003e\u003e recipient=pw.Address(\"3P8Ya6Ary5gzwnzbBXDp3xjeNG97JEiPcdA\")\n# sign a future tx to transfer 100 WAVES to recipient\n# the tx is valid on Jan 1st, 2020 12:00pm\n\u003e\u003e\u003e myAddress.sendWaves(recipient, amount=100e8, timestamp=1577880000000)\n{'api-endpoint': '/assets/broadcast/transfer',\n 'api-type': 'POST',\n 'api-data': '{\"fee\": 100000,\n\t\t\t   \"timestamp\": 1577880000000,\n\t\t\t   \"senderPublicKey\": \"27zdzBa1q46RCMamZ8gw2xrTGypZnbzXs5J1Y2HbUmEv\",\n\t\t\t   \"amount\": 10000000000,\n\t\t\t   \"attachment\": \"\",\n\t\t\t   \"recipient\": \"3P8Ya6Ary5gzwnzbBXDp3xjeNG97JEiPcdA\"\n\t\t\t   \"signature\": \"YetPopTJWC4WBPXbneWv9g6YEp6J9g9rquZWjewjdQnFbmaxtXjrRsUu69NZzHebVzUGLrhQiFFoguXJwdUn8BH\"}'}\n```\n\n#### Offline signing time lock/unlock transactions:\n```\n\u003e\u003e\u003e import pywaves as pw\n\u003e\u003e\u003e pw.setOffline()\n\u003e\u003e\u003e myAddress=pw.Address(privateKey=\"F2jVbjrKzjUsZ1AQRdnd8MmxFc85NQz5jwvZX4BXswXv\")\n# generate a lockbox address\n\u003e\u003e\u003e lockAddress=pw.Address('\u003csome address\u003e')\n\u003e\u003e\u003e lockAddress._generate()\n# sign the 'lock' tx to send 100e8 to the lockbox (valid on Nov 1st, 2017)\n\u003e\u003e\u003e myAddress.sendWaves(lockAddress, 100e8, timestamp=1509537600000)\n{'api-endpoint': '/assets/broadcast/transfer',\n 'api-type': 'POST',\n 'api-data': '{\"fee\": 100000,\n               \"timestamp\": 1509537600000,\n               \"senderPublicKey\": \"27zdzBa1q46RCMamZ8gw2xrTGypZnbzXs5J1Y2HbUmEv\",\n               \"amount\": 10000000000,\n               \"attachment\": \"\",\n               \"recipient\": \"3P3UbyQM9W7WzTgjYkLuBrPZZeWsiUtCcpv\",\n               \"signature\": \"5VgT6qWxJwxEyrxFNfsi67QqbyUiGq9Ka7HVzgovRTTDT8nLRyuQv2wBAJQhRiXDkTTV6zsQmHnBkh8keCaFPoNT\"}'}\n# sign the 'unlock' tx to send funds back to myAddress (valid on Jan 1st, 2020)\n\u003e\u003e\u003e lockAddress.sendWaves(myAddress, 100e8-200000, txFee=200000, timestamp=1577880000000)\n{'api-endpoint': '/assets/broadcast/transfer',\n 'api-type': 'POST',\n 'api-data': '{\"fee\": 200000,\n               \"timestamp\": 1577880000000,\n\t\t\t   \"senderPublicKey\": \"52XnBGnAVZmw1CHo9aJPiMsVMiTWeNGSNN9aYJ7cDtx4\",\n\t\t\t   \"amount\": 9999800000,\n\t\t\t   \"attachment\": \"\",\n\t\t\t   \"recipient\": \"3P7tfdCaTyYCfg5ojxNahEJDSS4MZ7ybXBY\",\n\t\t\t   \"signature\": \"3beyz1sqKefP96LaXWT3CxdPRW86DAxcj6wgWPyyKq3SgdotVqnKyWXDyeHnBzCq1nC7JA9CChTmo1c1iVAv6C4T\"}'}\n# delete lockbox address and private key\n\u003e\u003e\u003e del lockAddress\n```\n\n## Connecting to a different node or chain\n\nPyWaves supports both mainnet and testnet chains. By default, PyWaves connects to the mainnet RPC server at https://nodes.wavesnodes.com. It's possible to specify a different server and chain with the setNode() function\n\n```python\nimport pywaves as pw\n\n# connects to a local testnet node\npw.setNode(node = 'http://127.0.0.1:6869', chain = 'testnet')\n\n# connects to a local mainnet node\npw.setNode(node = 'http://127.0.0.1:6869', chain = 'mainnet')\n\n```\n\n\n## License\nCode released under the [MIT License](https://github.com/PyWaves/PyWaves/blob/master/LICENSE).\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FPyWaves%2FPyWaves","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FPyWaves%2FPyWaves","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FPyWaves%2FPyWaves/lists"}