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

Support Foreign objects as ABI arguments and address ARC-4 changes #251

Merged
merged 45 commits into from
Dec 28, 2021
Merged
Show file tree
Hide file tree
Changes from 43 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
4cab7a8
Start ABI JSON interaction
algochoi Oct 27, 2021
223b05e
Add static annoation
algochoi Oct 27, 2021
bad480d
Fix Method argument parsing
algochoi Oct 27, 2021
3b6f40c
Add ABI Typing to Method arguments
algochoi Oct 29, 2021
7b732a6
Merge remote-tracking branch 'origin/develop' into algochoi/abi-inter…
algochoi Oct 29, 2021
7cf0608
[WIP] Add AtomicTransactionComposer build functions
algochoi Oct 29, 2021
58cef31
[WIP] Sign and send atomic transaction groups
algochoi Nov 1, 2021
43874b2
Add unit tests for object parsing
algochoi Nov 1, 2021
d3fe73d
Clean up method calls
algochoi Nov 3, 2021
c7f4e14
Address PR comments on JSON objects
algochoi Nov 8, 2021
72d172d
Refactor ABI Type to ABIType so it can be exposed to outside world
algochoi Nov 10, 2021
e96b740
Add cucumber steps for ABI tests and update existing implementation s…
algochoi Nov 10, 2021
e052fa7
Refactor TransactionSigner to Abstract class and merge signatures whe…
algochoi Nov 12, 2021
d55f9a6
Update testing to reflect json unit tests and composer tests
algochoi Nov 16, 2021
a748f7b
Formatting and docstring fixes
algochoi Nov 16, 2021
982d519
Add foreign types for method arguments
algochoi Nov 16, 2021
23f63bb
Clean up imports
algochoi Nov 16, 2021
7daa605
Merge branch 'algochoi/abi-interaction' into algochoi/foreign-types
algochoi Nov 16, 2021
f21ec5d
Fix unit test for appId
algochoi Nov 17, 2021
5a6be1c
Merge branch 'algochoi/abi-interaction' into algochoi/foreign-types
algochoi Nov 17, 2021
cfef0a6
Add unit test for foreign array
algochoi Nov 17, 2021
d63b4d1
Refactor some names and add txn as an arg type
algochoi Nov 18, 2021
5c9d28e
Partially address PR comments
algochoi Nov 19, 2021
5e9ab5a
Merge branch 'algochoi/abi-interaction' into algochoi/foreign-types
algochoi Nov 19, 2021
c024249
Fix encoding args for foreign types
algochoi Nov 19, 2021
9fa591a
Add some additional checks for safety
algochoi Nov 19, 2021
351099a
Fix a step so we check for empty string instead of None
algochoi Nov 19, 2021
c5df38c
Correct foreign app and account indices accounting for the implicit a…
algochoi Nov 22, 2021
8f24033
Merge branch 'algochoi/abi-interaction' into algochoi/foreign-types
algochoi Nov 22, 2021
d664879
Merge branch 'develop' into algochoi/foreign-types
algochoi Nov 30, 2021
34c625c
Resolve formatting
algochoi Nov 30, 2021
b29bdaa
Fix unit tests
algochoi Nov 30, 2021
1239547
Fix foreign objects to compact duplicates and special values
algochoi Dec 13, 2021
c218fdf
Refactor foreign objects, transactions, and address some new ABI changes
algochoi Dec 15, 2021
2fbf11a
ABI composer modifications and test updates
algochoi Dec 18, 2021
2503554
Change Interface and Contract to newest ABI changes
algochoi Dec 21, 2021
eed9935
Fix some integration tests for composer
algochoi Dec 21, 2021
00f550b
Fix remaining composer tests
algochoi Dec 21, 2021
0428abe
Formatting changes
algochoi Dec 21, 2021
ad7a483
Fix method json tests
algochoi Dec 22, 2021
fdddcc7
Address PR Comments, clean up and refactor composer and contract
algochoi Dec 28, 2021
8390be2
Create helper function for populating foreign objects
algochoi Dec 28, 2021
9838025
Change type hints on reference and transaction checks
algochoi Dec 28, 2021
909a54d
Add generics and fix dictifying network info
algochoi Dec 28, 2021
90f1daa
Fix step for cucumber test contract parsing
algochoi Dec 28, 2021
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
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
algochoi marked this conversation as resolved.
Show resolved Hide resolved

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["desc"] = self.desc
d["networks"] = self.networks
algochoi marked this conversation as resolved.
Show resolved Hide resolved
d["methods"] = [m.dictify() for m in self.methods]
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
algochoi marked this conversation as resolved.
Show resolved Hide resolved


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