Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FOR REVIEW ONLY - py-algorand-sdk v1.9.0b2 #270

Merged
merged 8 commits into from
Jan 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Changelog

## 1.9.0b2
### Added

- Support Foreign objects as ABI arguments and address ARC-4 changes (#251)
- Add requirement to fetch behave source code and update readme (#262)
- Fix wait for confirmation function (#263)
- Add a default User-Agent header to the v2 algod client (#260)

## 1.9.0b1
### Added

Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ WORKDIR $HOME/py-algorand-sdk

# SDK dependencies, and source version of behave with tag expression support
RUN pip install . -q \
&& pip install git+https://github.com/behave/behave -q
&& pip install -r requirements.txt -q

# Run integration tests
CMD ["/bin/bash", "-c", "make unit && make integration"]
Expand Down
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,14 @@ Alternatively, choose a [distribution file](https://pypi.org/project/py-algorand

## SDK Development

Run tests with `make docker-test`
Install dependencies
* `pip install -r requirements.txt`

Run tests
* `make docker-test`

Format code:
* `black .`

## Quick start

Expand Down
12 changes: 9 additions & 3 deletions algosdk/abi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,14 @@
from algosdk.abi.array_dynamic_type import ArrayDynamicType
from algosdk.abi.array_static_type import ArrayStaticType
from algosdk.abi.tuple_type import TupleType
from .method import Method, Argument, Returns
from .interface import Interface
from .contract import Contract
from algosdk.abi.method import Method, Argument, Returns
from algosdk.abi.interface import Interface
from algosdk.abi.contract import Contract, NetworkInfo
from algosdk.abi.transaction import (
ABITransactionType,
is_abi_transaction_type,
check_abi_transaction_type,
)
from algosdk.abi.reference import ABIReferenceType, is_abi_reference_type

name = "abi"
56 changes: 48 additions & 8 deletions algosdk/abi/contract.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import json
from typing import List, Union
from typing import Dict, List, Union

from algosdk.abi.method import Method

Expand All @@ -10,22 +10,32 @@ class Contract:

Args:
name (string): name of the contract
app_id (int): application id associated with the contract
methods (list): list of Method objects
desc (string, optional): description of the contract
networks (dict, optional): information about the contract in a
particular network, such as an app-id.
"""

def __init__(self, name: str, app_id: int, methods: List[Method]) -> None:
def __init__(
self,
name: str,
methods: List[Method],
desc: str = None,
networks: Dict[str, "NetworkInfo"] = None,
) -> None:
self.name = name
self.app_id = int(app_id)
self.methods = methods
self.desc = desc
self.networks = networks if networks else {}

def __eq__(self, o: object) -> bool:
if not isinstance(o, Contract):
return False
return (
self.name == o.name
and self.app_id == o.app_id
and self.methods == o.methods
and self.desc == o.desc
and self.networks == o.networks
)

@staticmethod
Expand All @@ -36,13 +46,43 @@ def from_json(resp: Union[str, bytes, bytearray]) -> "Contract":
def dictify(self) -> dict:
d = {}
d["name"] = self.name
d["appId"] = self.app_id
d["methods"] = [m.dictify() for m in self.methods]
d["desc"] = self.desc
d["networks"] = {k: v.dictify() for k, v in self.networks.items()}
return d

@staticmethod
def undictify(d: dict) -> "Contract":
name = d["name"]
app_id = d["appId"]
method_list = [Method.undictify(method) for method in d["methods"]]
return Contract(name=name, app_id=app_id, methods=method_list)
desc = d["desc"] if "desc" in d else None
networks = d["networks"] if "networks" in d else {}
for k, v in networks.items():
networks[k] = NetworkInfo.undictify(v)
return Contract(
name=name, desc=desc, networks=networks, methods=method_list
)


class NetworkInfo:
"""
Represents network information.

Args:
app_id (int): application ID on a particular network
"""

def __init__(self, app_id: int) -> None:
self.app_id = app_id

def __eq__(self, o: object) -> bool:
if not isinstance(o, NetworkInfo):
return False
return self.app_id == o.app_id

def dictify(self) -> dict:
return {"appID": self.app_id}

@staticmethod
def undictify(d: dict) -> "NetworkInfo":
return NetworkInfo(app_id=d["appID"])
17 changes: 14 additions & 3 deletions algosdk/abi/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,24 @@ class Interface:
Args:
name (string): name of the interface
methods (list): list of Method objects
desc (string, optional): description of the interface
"""

def __init__(self, name: str, methods: List[Method]) -> None:
def __init__(
self, name: str, methods: List[Method], desc: str = None
) -> None:
self.name = name
self.methods = methods
self.desc = desc

def __eq__(self, o: object) -> bool:
if not isinstance(o, Interface):
return False
return self.name == o.name and self.methods == o.methods
return (
self.name == o.name
and self.methods == o.methods
and self.desc == o.desc
)

@staticmethod
def from_json(resp: Union[str, bytes, bytearray]) -> "Interface":
Expand All @@ -31,10 +39,13 @@ def dictify(self) -> dict:
d = {}
d["name"] = self.name
d["methods"] = [m.dictify() for m in self.methods]
if self.desc:
d["desc"] = self.desc
return d

@staticmethod
def undictify(d: dict) -> "Interface":
name = d["name"]
method_list = [Method.undictify(method) for method in d["methods"]]
return Interface(name=name, methods=method_list)
desc = d["desc"] if "desc" in d else None
return Interface(name=name, desc=desc, methods=method_list)
17 changes: 4 additions & 13 deletions algosdk/abi/method.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,6 @@
from algosdk import abi, constants, error


TRANSACTION_ARGS = (
"txn", # Denotes a placeholder for any of the six transaction types below
constants.PAYMENT_TXN,
constants.KEYREG_TXN,
constants.ASSETCONFIG_TXN,
constants.ASSETTRANSFER_TXN,
constants.ASSETFREEZE_TXN,
constants.APPCALL_TXN,
)


class Method:
"""
Represents a ABI method description.
Expand Down Expand Up @@ -44,7 +33,7 @@ def __init__(
# add one for this method call itself.
txn_count = 1
for arg in self.args:
if arg.type in TRANSACTION_ARGS:
if abi.is_abi_transaction_type(arg.type):
txn_count += 1
self.txn_calls = txn_count

Expand Down Expand Up @@ -150,7 +139,9 @@ class Argument:
def __init__(
self, arg_type: str, name: str = None, desc: str = None
) -> None:
if arg_type in TRANSACTION_ARGS:
if abi.is_abi_transaction_type(arg_type) or abi.is_abi_reference_type(
arg_type
):
self.type = arg_type
else:
# If the type cannot be parsed into an ABI type, it will error
Expand Down
20 changes: 20 additions & 0 deletions algosdk/abi/reference.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from typing import Any


class ABIReferenceType:
# Account reference type
ACCOUNT = "account"

# Application reference type
APPLICATION = "application"

# Asset reference type
ASSET = "asset"


def is_abi_reference_type(t: Any) -> bool:
return t in (
ABIReferenceType.ACCOUNT,
ABIReferenceType.APPLICATION,
ABIReferenceType.ASSET,
)
45 changes: 45 additions & 0 deletions algosdk/abi/transaction.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from typing import Any

from algosdk import constants
from algosdk.future.transaction import Transaction


class ABITransactionType:
# Any transaction type
ANY = "txn"

# Payment transaction type
PAY = constants.PAYMENT_TXN

# Key registration transaction type
KEYREG = constants.KEYREG_TXN

# Asset configuration transaction type
ACFG = constants.ASSETCONFIG_TXN

# Asset transfer transaction type
AXFER = constants.ASSETTRANSFER_TXN

# Asset freeze transaction type
AFRZ = constants.ASSETFREEZE_TXN

# Application transaction type
APPL = constants.APPCALL_TXN


def is_abi_transaction_type(t: Any) -> bool:
return t in (
ABITransactionType.ANY,
ABITransactionType.PAY,
ABITransactionType.KEYREG,
ABITransactionType.ACFG,
ABITransactionType.AXFER,
ABITransactionType.AFRZ,
ABITransactionType.APPL,
)


def check_abi_transaction_type(t: Any, txn: Transaction) -> bool:
if t == ABITransactionType.ANY:
return True
return txn.type and txn.type == t
Loading