Metadata-Version: 2.1
Name: patract-interface
Version: 0.1.0
Summary: Substrate Contract SDK for Python As a part of Himalia
Home-page: https://github.com/patractlabs/py-patract
Author: patractlabs
Author-email: polkadev@protonmail.com
License: UNKNOWN
Keywords: contract interface polkascan polkadot substrate blockchain rpc kusama
Platform: UNKNOWN
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Topic :: Software Development
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3 :: Only
Requires-Python: >=3.6, <4
Description-Content-Type: text/markdown
Requires-Dist: websocket-client (>=0.57.0)
Requires-Dist: base58 (>=2.0.1)
Requires-Dist: certifi (>=2020.11.8)
Requires-Dist: idna (>=2.8)
Requires-Dist: requests (>=2.25.0)
Requires-Dist: xxhash (>=1.3.0)
Requires-Dist: scalecodec (>=0.10.41)
Requires-Dist: py-sr25519-bindings (>=0.1.2)
Requires-Dist: py-ed25519-bindings (>=0.1.2)
Requires-Dist: py-bip39-bindings (>=0.1.6)
Requires-Dist: executor (>=23.2)
Requires-Dist: scalecodec (>=0.10.42)
Requires-Dist: substrate-interface (>=0.11.8)
Provides-Extra: test
Requires-Dist: coverage ; extra == 'test'
Requires-Dist: pytest ; extra == 'test'

# Himalia PatractPy

Substrate Contract SDK for Python As a part of Himalia

----------

PatractPy is a contract SDK to support the development of Python scripts that interact with contracts, including automated scripts to support testing. Unlike PatractGo, PatractPy is mainly for script development, so PatractPy mainly completes contract-related RPC interfaces, and completes contract deployment and instantiation-related operations.

PatractPy will provide support for [europa](https://github.com/patractlabs/europa) env, which is a good environment for contract exec sandbox,
With PatractPy, we can write contract unittest by python, which is more friendly to developer and can easy use other test tools.

PatractPy will be based on [polkascan's Python Substrate Interface](https://github.com/polkascan/py-substrate-interface), which is a Python sdk for Substrate.

Element Group for disscusion: https://app.element.io/#/room/#PatractLabsDev:matrix.org

PatractPy will achieve the following support:

- Some support that missing in [polkascan's Python Substrate Interface](https://github.com/polkascan/py-substrate-interface), which is needed for contracts
- Provide Scanning and monitoring support for contract to do statistics and analysis
- Provide a SDK development example for ERC20 contract
- Support For unittest to canvas or [europa](https://github.com/patractlabs/europa) env.

For Unittest, should install [europa](https://github.com/patractlabs/europa) at first.

```bash
europa --version
europa 0.1.0-3f71403-x86_64-linux-gnu
```

All of test pased by europa environment.

## Basic Apis For Contracts

As [polkascan's Python Substrate Interface](https://github.com/polkascan/py-substrate-interface) has provide some support to contract api, so we not need to important the api for contract calls, but there is some api to add:

- `SubstrateSubscriber` is a subscriber support to subscribe data changes in chain, for example, the events in chain.
- `get_contract_event_type` add event decode support for contracts.

## ContractObserver

ContractObserver can observer events for a contract:

```python
substrate=SubstrateInterface(url="ws://127.0.0.1:9944", type_registry_preset='canvas')
contract_metadata = ContractMetadata.create_from_file(
    metadata_file=os.path.join(os.path.dirname(__file__), 'constracts', 'ink', 'erc20.json'),
    substrate=substrate
)
observer = ContractObserver("0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48", contract_metadata, substrate)

# for some handlers
observer.scanEvents()
```

The handler function can take the erc20 support as a example.

## ERC20 API

ERC20 api provide a wapper to erc20 contract exec, read and observer events, it can be a example for contracts api calling.

```python

# init api
substrate=SubstrateInterface(url="ws://127.0.0.1:9944", type_registry_preset='canvas')

contract_metadata = ContractMetadata.create_from_file(
    metadata_file=os.path.join(os.path.dirname(__file__), 'constracts', 'ink', 'erc20.json'),
    substrate=substrate
)

alice = Keypair.create_from_uri('//Alice')
bob = Keypair.create_from_uri('//Bob')

# erc20 api
erc20 = ERC20.create_from_contracts(
    substrate= substrate, 
    contract_file= os.path.join(os.path.dirname(__file__), 'constracts', 'ink', 'erc20.wasm'),
    metadata_file= os.path.join(os.path.dirname(__file__), 'constracts', 'ink', 'erc20.json')
)

# deplay a erc20 contract
erc20.putAndDeploy(alice, 1000000 * (10 ** 15))

# read total supply
total_supply = erc20.totalSupply()

# transfer
erc20.transferFrom(alice,
    fromAcc=alice.ss58_address, 
    toAcc=bob.ss58_address, 
    amt=10000)

erc20.transfer(alice, bob.ss58_address, 10000)

# get balance
alice_balance = erc20.balanceOf(alice.ss58_address)

# approve
erc20.approve(alice, spender=bob.ss58_address, amt=10000)

# get allowance
alice_allowance = erc20.allowance(alice.ss58_address, bob.ss58_address)

```

`ERC20Observer` is a event observer for erc20 contract:

```python
observer = ERC20Observer.create_from_address(
    substrate = substrate, 
    contract_address = contract_address,
    metadata_file= os.path.join(os.path.dirname(__file__), 'constracts', 'ink', 'erc20.json')
)

def on_transfer(num, fromAcc, toAcc, amt):
    logging.info("on_transfer in block[{}] : {} {} {}".format(num, fromAcc, toAcc, amt))

def on_approval(num, owner, spender, amt):
    logging.info("on_approval in block[{}] : {} {} {}".format(num, owner, spender, amt))

observer.scanEvents(on_transfer = on_transfer, on_approval = on_approval)
```

## Unittest Node Environment

PatractPy can support write contract unittest by node environment.

At First We need install [europa](https://github.com/patractlabs/europa).

```python
from patractinterface.contracts.erc20 import ERC20
from patractinterface.unittest.env import SubstrateTestEnv

class UnittestEnvTest(unittest.TestCase):
    @classmethod
    def setUp(cls):
        # start env or use canvas for a 6s block
        cls.env = SubstrateTestEnv.create_europa(port=39944)
        cls.env.startNode()

        cls.api = SubstrateInterface(url=cls.env.url(), type_registry_preset=cls.env.typ())
        cls.alice = Keypair.create_from_uri('//Alice')
        cls.bob = Keypair.create_from_uri('//Bob')

        cls.erc20 = ERC20.create_from_contracts(
            substrate= cls.substrate, 
            contract_file= os.path.join(os.path.dirname(__file__), 'constracts', 'ink', 'erc20.wasm'),
            metadata_file= os.path.join(os.path.dirname(__file__), 'constracts', 'ink', 'erc20.json')
        )
        cls.erc20.putAndDeploy(alice, 1000000 * (10 ** 15))

        return

    def tearDown(cls):
        cls.env.stopNode()

    def test_transfer(self):
        self.erc20.transferFrom(alice,
            fromAcc=alice.ss58_address, 
            toAcc=bob.ss58_address, 
            amt=10000)
        # some more test case

if __name__ == '__main__':
    unittest.main()
```

By example, we can use python to write testcase for some complex logics, by [europa](https://github.com/patractlabs/europa), we can test the contracts for python scripts.

