Skip to content

Commit

Permalink
Merge branch 'release/v1.9.0b2'
Browse files Browse the repository at this point in the history
  • Loading branch information
egieseke committed Jan 3, 2022
2 parents 6785baa + 039f29b commit 6bb2533
Show file tree
Hide file tree
Showing 17 changed files with 606 additions and 148 deletions.
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

0 comments on commit 6bb2533

Please sign in to comment.