From ea43a48a1e21a9e1d96a321bfd3376577a457d49 Mon Sep 17 00:00:00 2001 From: Astha Yadav <75947851+Asthay97@users.noreply.github.com> Date: Thu, 12 Dec 2024 19:11:18 +0530 Subject: [PATCH 1/3] Adding code for local storage examples --- .../smart_contracts/local_storage/contract.py | 133 ++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 projects/python-contract-examples/smart_contracts/local_storage/contract.py diff --git a/projects/python-contract-examples/smart_contracts/local_storage/contract.py b/projects/python-contract-examples/smart_contracts/local_storage/contract.py new file mode 100644 index 0000000..1f12478 --- /dev/null +++ b/projects/python-contract-examples/smart_contracts/local_storage/contract.py @@ -0,0 +1,133 @@ +from algopy import ARC4Contract, LocalState, Bytes, UInt64, arc4, Account, Application, Asset + +# example: LOCAL_STORAGE +class LocalStorage(ARC4Contract): + def __init__(self) -> None: + ## Initialise local storages + self.local_int = LocalState(UInt64) # Uint64 + self.local_bytes = LocalState(Bytes) # Bytes + self.local_bool = LocalState(bool) #Bool + self.local_asset = LocalState(Asset) # Asset + self.local_application = LocalState(Application) # Application + self.local_account = LocalState(Account) # Account + + @arc4.abimethod + def contains_local_data(self, for_account: Account) -> bool: + assert for_account in self.local_int # Uint64 + return True + + @arc4.abimethod + def contains_local_data_example(self, for_account: Account) -> bool: + assert for_account in self.local_int # Uint64 + assert for_account in self.local_bytes # Bytes + assert for_account in self.local_bool # Bool + assert for_account in self.local_asset # Asset + assert for_account in self.local_application # Application + assert for_account in self.local_account # Account + return True + + # delete local data + @arc4.abimethod + def delete_local_data(self, for_account: Account) -> None: + del self.local_account[for_account] # Uint64 + + @arc4.abimethod + def delete_local_data_example(self, for_account: Account) -> bool: + del self.local_int[for_account] # Uint64 + del self.local_bytes[for_account] # Bytes + del self.local_bool[for_account] # Bool + del self.local_asset[for_account] # Asset + del self.local_application[for_account] # Application + del self.local_account[for_account] # Account + return True + + # get item + @arc4.abimethod + def get_item_local_data(self, for_account: Account)-> UInt64: + return self.local_int[for_account] + + @arc4.abimethod + def get_item_local_data_example(self, for_account: Account) -> bool: + assert self.local_int[for_account] == UInt64(10) # Uint64 - returns guranteed data + assert self.local_bytes[for_account] == b"Hello" # Bytes + assert self.local_bool[for_account] == True # Bool + assert self.local_asset[for_account] == Asset(UInt64(10)) # Asset + assert self.local_application[for_account] == Application(UInt64(10)) # Application + assert self.local_account[for_account] == Account(Bytes(b"Hello")) # Account + return True + + # set item + @arc4.abimethod + def set_local_int(self, for_account: Account, value: UInt64) -> None: + self.local_int[for_account] = value # Uint64 + + @arc4.abimethod + def set_local_data_example(self, for_account: Account, value_byte: Bytes, value_bool: bool, value_asset: Asset, value_account: Account, value_appln: Application) -> bool: + self.local_bytes[for_account] = value_byte # Bytes + assert self.local_bytes[for_account] == value_byte + + self.local_bool[for_account] = value_bool # Bool + assert self.local_bool[for_account] == value_bool + + self.local_asset[for_account] = value_asset # Asset + assert self.local_asset[for_account] == value_asset + + self.local_application[for_account] = value_appln # Application + assert self.local_application[for_account] == value_appln + + self.local_account[for_account] = value_account # Account + assert self.local_account[for_account] == value_account + return True + + # get function + @arc4.abimethod + def get_local_data_with_default_int(self, for_account: Account) -> UInt64: + return self.local_int.get(for_account, default=UInt64(0)) # Uint64 + + @arc4.abimethod + def get_local_data_with_default(self, for_account: Account) -> bool: + assert self.local_int.get(for_account, default=UInt64(0)) == UInt64(10) # Uint64 + assert self.local_bytes.get(for_account, default=Bytes(b"Default Value")) == Bytes(b"Hello") # Bytes + assert self.local_bool.get(for_account, default=False) == True # Bool + + assert self.local_asset.get(for_account, default=Asset(UInt64(0))) == Asset(UInt64(10)) # Asset + assert self.local_application.get(for_account, default=Application(UInt64(0))) == Application(UInt64(10)) # Application + assert self.local_account.get(for_account, default=Account(Bytes(b"Default Value"))) == Account(Bytes(b"Hello")) # Account + + return True + + # maybe function + @arc4.abimethod + def maybe_local_data(self, for_account: Account) -> tuple[UInt64, bool]: + # used to get data or assert int + result, exists = self.local_int.maybe(for_account) # Uint64 + if not exists: + result = UInt64(0) + return result, exists + + @arc4.abimethod + def maybe_local_data_example(self, for_account: Account) -> bool: + result, exists = self.local_int.maybe(for_account) # Uint64 + assert exists, "no data for account" + assert result == UInt64(10) + + resultBytes, exists = self.local_bytes.maybe(for_account) # Bytes + assert exists, "no data for account" + assert resultBytes == b"Hello" + + resultBool, exists = self.local_bool.maybe(for_account) # Bool + assert exists, "no data for account" + assert resultBool == True + + resultAsset, exists = self.local_asset.maybe(for_account) # Asset + assert exists, "no data for account" + assert resultAsset == Asset(UInt64(10)) + + resultAppln, exists = self.local_application.maybe(for_account) # Application + assert exists, "no data for account" + assert resultAppln == Application(UInt64(10)) + + resultAccount, exists = self.local_account.maybe(for_account) # Account + assert exists, "no data for account" + assert resultAccount == Account(Bytes(b"Hello")) + return True From 2dc3befee62d4fb325920ea06d062b1c7db9f53b Mon Sep 17 00:00:00 2001 From: Astha Yadav <75947851+Asthay97@users.noreply.github.com> Date: Fri, 13 Dec 2024 19:52:27 +0530 Subject: [PATCH 2/3] Fixed lint for local storage --- .../smart_contracts/local_storage/contract.py | 171 +++++++++++------- 1 file changed, 105 insertions(+), 66 deletions(-) diff --git a/projects/python-contract-examples/smart_contracts/local_storage/contract.py b/projects/python-contract-examples/smart_contracts/local_storage/contract.py index 1f12478..c398e8e 100644 --- a/projects/python-contract-examples/smart_contracts/local_storage/contract.py +++ b/projects/python-contract-examples/smart_contracts/local_storage/contract.py @@ -1,133 +1,172 @@ -from algopy import ARC4Contract, LocalState, Bytes, UInt64, arc4, Account, Application, Asset +from algopy import ( + Account, + Application, + ARC4Contract, + Asset, + Bytes, + LocalState, + UInt64, + arc4, +) + # example: LOCAL_STORAGE class LocalStorage(ARC4Contract): def __init__(self) -> None: ## Initialise local storages - self.local_int = LocalState(UInt64) # Uint64 - self.local_bytes = LocalState(Bytes) # Bytes - self.local_bool = LocalState(bool) #Bool - self.local_asset = LocalState(Asset) # Asset - self.local_application = LocalState(Application) # Application - self.local_account = LocalState(Account) # Account + self.local_int = LocalState(UInt64) # Uint64 + self.local_bytes = LocalState(Bytes) # Bytes + self.local_bool = LocalState(bool) # Bool + self.local_asset = LocalState(Asset) # Asset + self.local_application = LocalState(Application) # Application + self.local_account = LocalState(Account) # Account @arc4.abimethod - def contains_local_data(self, for_account: Account) -> bool: - assert for_account in self.local_int # Uint64 + def contains_local_data(self, for_account: Account) -> bool: + assert for_account in self.local_int # Uint64 return True - + @arc4.abimethod - def contains_local_data_example(self, for_account: Account) -> bool: - assert for_account in self.local_int # Uint64 - assert for_account in self.local_bytes # Bytes - assert for_account in self.local_bool # Bool - assert for_account in self.local_asset # Asset - assert for_account in self.local_application # Application - assert for_account in self.local_account # Account + def contains_local_data_example(self, for_account: Account) -> bool: + assert for_account in self.local_int # Uint64 + assert for_account in self.local_bytes # Bytes + assert for_account in self.local_bool # Bool + assert for_account in self.local_asset # Asset + assert for_account in self.local_application # Application + assert for_account in self.local_account # Account return True - + # delete local data @arc4.abimethod def delete_local_data(self, for_account: Account) -> None: - del self.local_account[for_account] # Uint64 - + del self.local_account[for_account] # Uint64 + @arc4.abimethod def delete_local_data_example(self, for_account: Account) -> bool: - del self.local_int[for_account] # Uint64 - del self.local_bytes[for_account] # Bytes - del self.local_bool[for_account] # Bool - del self.local_asset[for_account] # Asset - del self.local_application[for_account] # Application - del self.local_account[for_account] # Account + del self.local_int[for_account] # Uint64 + del self.local_bytes[for_account] # Bytes + del self.local_bool[for_account] # Bool + del self.local_asset[for_account] # Asset + del self.local_application[for_account] # Application + del self.local_account[for_account] # Account return True # get item @arc4.abimethod - def get_item_local_data(self, for_account: Account)-> UInt64: + def get_item_local_data(self, for_account: Account) -> UInt64: return self.local_int[for_account] @arc4.abimethod def get_item_local_data_example(self, for_account: Account) -> bool: - assert self.local_int[for_account] == UInt64(10) # Uint64 - returns guranteed data - assert self.local_bytes[for_account] == b"Hello" # Bytes - assert self.local_bool[for_account] == True # Bool - assert self.local_asset[for_account] == Asset(UInt64(10)) # Asset - assert self.local_application[for_account] == Application(UInt64(10)) # Application - assert self.local_account[for_account] == Account(Bytes(b"Hello")) # Account + assert self.local_int[for_account] == UInt64( + 10 + ) # Uint64 - returns guranteed data + assert self.local_bytes[for_account] == b"Hello" # Bytes + assert bool(self.local_bool[for_account]) # Bool + assert self.local_asset[for_account] == Asset(UInt64(10)) # Asset + assert self.local_application[for_account] == Application( + UInt64(10) + ) # Application + assert self.local_account[for_account] == Account(Bytes(b"Hello")) # Account return True - + # set item @arc4.abimethod - def set_local_int(self, for_account: Account, value: UInt64) -> None: - self.local_int[for_account] = value # Uint64 - + def set_local_int(self, for_account: Account, value: UInt64) -> None: + self.local_int[for_account] = value # Uint64 + @arc4.abimethod - def set_local_data_example(self, for_account: Account, value_byte: Bytes, value_bool: bool, value_asset: Asset, value_account: Account, value_appln: Application) -> bool: - self.local_bytes[for_account] = value_byte # Bytes + def set_local_data_example( + self, + for_account: Account, + value_asset: Asset, + value_account: Account, + value_appln: Application, + value_byte: Bytes, + *, + value_bool: bool, + ) -> bool: + self.local_bytes[for_account] = value_byte # Bytes assert self.local_bytes[for_account] == value_byte - self.local_bool[for_account] = value_bool # Bool + self.local_bool[for_account] = value_bool # Bool assert self.local_bool[for_account] == value_bool - - self.local_asset[for_account] = value_asset # Asset + + self.local_asset[for_account] = value_asset # Asset assert self.local_asset[for_account] == value_asset - self.local_application[for_account] = value_appln # Application + self.local_application[for_account] = value_appln # Application assert self.local_application[for_account] == value_appln - self.local_account[for_account] = value_account # Account + self.local_account[for_account] = value_account # Account assert self.local_account[for_account] == value_account return True # get function @arc4.abimethod def get_local_data_with_default_int(self, for_account: Account) -> UInt64: - return self.local_int.get(for_account, default=UInt64(0)) # Uint64 + return self.local_int.get(for_account, default=UInt64(0)) # Uint64 @arc4.abimethod def get_local_data_with_default(self, for_account: Account) -> bool: - assert self.local_int.get(for_account, default=UInt64(0)) == UInt64(10) # Uint64 - assert self.local_bytes.get(for_account, default=Bytes(b"Default Value")) == Bytes(b"Hello") # Bytes - assert self.local_bool.get(for_account, default=False) == True # Bool - - assert self.local_asset.get(for_account, default=Asset(UInt64(0))) == Asset(UInt64(10)) # Asset - assert self.local_application.get(for_account, default=Application(UInt64(0))) == Application(UInt64(10)) # Application - assert self.local_account.get(for_account, default=Account(Bytes(b"Default Value"))) == Account(Bytes(b"Hello")) # Account - + assert self.local_int.get(for_account, default=UInt64(0)) == UInt64( + 10 + ) # Uint64 + assert self.local_bytes.get( + for_account, default=Bytes(b"Default Value") + ) == Bytes( + b"Hello" + ) # Bytes + assert bool(self.local_bool.get(for_account, default=False)) # Bool + + assert self.local_asset.get(for_account, default=Asset(UInt64(0))) == Asset( + UInt64(10) + ) # Asset + assert self.local_application.get( + for_account, default=Application(UInt64(0)) + ) == Application( + UInt64(10) + ) # Application + assert self.local_account.get( + for_account, default=Account(Bytes(b"Default Value")) + ) == Account( + Bytes(b"Hello") + ) # Account + return True # maybe function @arc4.abimethod def maybe_local_data(self, for_account: Account) -> tuple[UInt64, bool]: # used to get data or assert int - result, exists = self.local_int.maybe(for_account) # Uint64 + result, exists = self.local_int.maybe(for_account) # Uint64 if not exists: result = UInt64(0) return result, exists @arc4.abimethod def maybe_local_data_example(self, for_account: Account) -> bool: - result, exists = self.local_int.maybe(for_account) # Uint64 + result, exists = self.local_int.maybe(for_account) # Uint64 assert exists, "no data for account" assert result == UInt64(10) - resultBytes, exists = self.local_bytes.maybe(for_account) # Bytes + result_bytes, exists = self.local_bytes.maybe(for_account) # Bytes assert exists, "no data for account" - assert resultBytes == b"Hello" + assert result_bytes == b"Hello" - resultBool, exists = self.local_bool.maybe(for_account) # Bool + result_bool, exists = self.local_bool.maybe(for_account) # Bool assert exists, "no data for account" - assert resultBool == True + assert bool(result_bool) - resultAsset, exists = self.local_asset.maybe(for_account) # Asset + result_asset, exists = self.local_asset.maybe(for_account) # Asset assert exists, "no data for account" - assert resultAsset == Asset(UInt64(10)) + assert result_asset == Asset(UInt64(10)) - resultAppln, exists = self.local_application.maybe(for_account) # Application + result_appln, exists = self.local_application.maybe(for_account) # Application assert exists, "no data for account" - assert resultAppln == Application(UInt64(10)) - - resultAccount, exists = self.local_account.maybe(for_account) # Account + assert result_appln == Application(UInt64(10)) + + result_account, exists = self.local_account.maybe(for_account) # Account assert exists, "no data for account" - assert resultAccount == Account(Bytes(b"Hello")) + assert result_account == Account(Bytes(b"Hello")) return True From 00cfdb7b8830f441ef35fa62cf22fffc182acd4c Mon Sep 17 00:00:00 2001 From: Astha Yadav <75947851+Asthay97@users.noreply.github.com> Date: Fri, 3 Jan 2025 14:10:30 +0530 Subject: [PATCH 3/3] Added artifacts for local storage contract --- .../local_storage/LocalStorage.approval.teal | 680 ++++++++ .../local_storage/LocalStorage.arc32.json | 302 ++++ .../local_storage/LocalStorage.clear.teal | 5 + .../local_storage/local_storage_client.py | 1401 +++++++++++++++++ 4 files changed, 2388 insertions(+) create mode 100644 projects/python-contract-examples/smart_contracts/artifacts/local_storage/LocalStorage.approval.teal create mode 100644 projects/python-contract-examples/smart_contracts/artifacts/local_storage/LocalStorage.arc32.json create mode 100644 projects/python-contract-examples/smart_contracts/artifacts/local_storage/LocalStorage.clear.teal create mode 100644 projects/python-contract-examples/smart_contracts/artifacts/local_storage/local_storage_client.py diff --git a/projects/python-contract-examples/smart_contracts/artifacts/local_storage/LocalStorage.approval.teal b/projects/python-contract-examples/smart_contracts/artifacts/local_storage/LocalStorage.approval.teal new file mode 100644 index 0000000..8528563 --- /dev/null +++ b/projects/python-contract-examples/smart_contracts/artifacts/local_storage/LocalStorage.approval.teal @@ -0,0 +1,680 @@ +#pragma version 10 + +smart_contracts.local_storage.contract.LocalStorage.approval_program: + callsub __puya_arc4_router__ + return + + +// smart_contracts.local_storage.contract.LocalStorage.__puya_arc4_router__() -> uint64: +__puya_arc4_router__: + proto 0 1 + txn NumAppArgs + bz __puya_arc4_router___bare_routing@16 + method "contains_local_data(account)bool" + method "contains_local_data_example(account)bool" + method "delete_local_data(account)void" + method "delete_local_data_example(account)bool" + method "get_item_local_data(account)uint64" + method "get_item_local_data_example(account)bool" + method "set_local_int(account,uint64)void" + method "set_local_data_example(account,asset,account,application,byte[],bool)bool" + method "get_local_data_with_default_int(account)uint64" + method "get_local_data_with_default(account)bool" + method "maybe_local_data(account)(uint64,bool)" + method "maybe_local_data_example(account)bool" + txna ApplicationArgs 0 + match __puya_arc4_router___contains_local_data_route@2 __puya_arc4_router___contains_local_data_example_route@3 __puya_arc4_router___delete_local_data_route@4 __puya_arc4_router___delete_local_data_example_route@5 __puya_arc4_router___get_item_local_data_route@6 __puya_arc4_router___get_item_local_data_example_route@7 __puya_arc4_router___set_local_int_route@8 __puya_arc4_router___set_local_data_example_route@9 __puya_arc4_router___get_local_data_with_default_int_route@10 __puya_arc4_router___get_local_data_with_default_route@11 __puya_arc4_router___maybe_local_data_route@12 __puya_arc4_router___maybe_local_data_example_route@13 + int 0 + retsub + +__puya_arc4_router___contains_local_data_route@2: + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + txna ApplicationArgs 1 + btoi + txnas Accounts + callsub contains_local_data + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + int 1 + retsub + +__puya_arc4_router___contains_local_data_example_route@3: + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + txna ApplicationArgs 1 + btoi + txnas Accounts + callsub contains_local_data_example + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + int 1 + retsub + +__puya_arc4_router___delete_local_data_route@4: + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + txna ApplicationArgs 1 + btoi + txnas Accounts + callsub delete_local_data + int 1 + retsub + +__puya_arc4_router___delete_local_data_example_route@5: + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + txna ApplicationArgs 1 + btoi + txnas Accounts + callsub delete_local_data_example + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + int 1 + retsub + +__puya_arc4_router___get_item_local_data_route@6: + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + txna ApplicationArgs 1 + btoi + txnas Accounts + callsub get_item_local_data + itob + byte 0x151f7c75 + swap + concat + log + int 1 + retsub + +__puya_arc4_router___get_item_local_data_example_route@7: + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + txna ApplicationArgs 1 + btoi + txnas Accounts + callsub get_item_local_data_example + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + int 1 + retsub + +__puya_arc4_router___set_local_int_route@8: + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + txna ApplicationArgs 1 + btoi + txnas Accounts + txna ApplicationArgs 2 + btoi + callsub set_local_int + int 1 + retsub + +__puya_arc4_router___set_local_data_example_route@9: + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + txna ApplicationArgs 1 + btoi + txnas Accounts + txna ApplicationArgs 2 + btoi + txnas Assets + txna ApplicationArgs 3 + btoi + txnas Accounts + txna ApplicationArgs 4 + btoi + txnas Applications + txna ApplicationArgs 5 + extract 2 0 + txna ApplicationArgs 6 + int 0 + getbit + callsub set_local_data_example + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + int 1 + retsub + +__puya_arc4_router___get_local_data_with_default_int_route@10: + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + txna ApplicationArgs 1 + btoi + txnas Accounts + callsub get_local_data_with_default_int + itob + byte 0x151f7c75 + swap + concat + log + int 1 + retsub + +__puya_arc4_router___get_local_data_with_default_route@11: + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + txna ApplicationArgs 1 + btoi + txnas Accounts + callsub get_local_data_with_default + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + int 1 + retsub + +__puya_arc4_router___maybe_local_data_route@12: + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + txna ApplicationArgs 1 + btoi + txnas Accounts + callsub maybe_local_data + swap + itob + byte 0x00 + int 0 + uncover 3 + setbit + concat + byte 0x151f7c75 + swap + concat + log + int 1 + retsub + +__puya_arc4_router___maybe_local_data_example_route@13: + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + txna ApplicationArgs 1 + btoi + txnas Accounts + callsub maybe_local_data_example + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + int 1 + retsub + +__puya_arc4_router___bare_routing@16: + txn OnCompletion + bnz __puya_arc4_router___after_if_else@20 + txn ApplicationID + ! + assert // is creating + int 1 + retsub + +__puya_arc4_router___after_if_else@20: + int 0 + retsub + + +// smart_contracts.local_storage.contract.LocalStorage.contains_local_data(for_account: bytes) -> uint64: +contains_local_data: + proto 1 1 + frame_dig -1 + int 0 + byte "local_int" + app_local_get_ex + bury 1 + assert + int 1 + retsub + + +// smart_contracts.local_storage.contract.LocalStorage.contains_local_data_example(for_account: bytes) -> uint64: +contains_local_data_example: + proto 1 1 + frame_dig -1 + int 0 + byte "local_int" + app_local_get_ex + bury 1 + assert + frame_dig -1 + int 0 + byte "local_bytes" + app_local_get_ex + bury 1 + assert + frame_dig -1 + int 0 + byte "local_bool" + app_local_get_ex + bury 1 + assert + frame_dig -1 + int 0 + byte "local_asset" + app_local_get_ex + bury 1 + assert + frame_dig -1 + int 0 + byte "local_application" + app_local_get_ex + bury 1 + assert + frame_dig -1 + int 0 + byte "local_account" + app_local_get_ex + bury 1 + assert + int 1 + retsub + + +// smart_contracts.local_storage.contract.LocalStorage.delete_local_data(for_account: bytes) -> void: +delete_local_data: + proto 1 0 + frame_dig -1 + byte "local_account" + app_local_del + retsub + + +// smart_contracts.local_storage.contract.LocalStorage.delete_local_data_example(for_account: bytes) -> uint64: +delete_local_data_example: + proto 1 1 + frame_dig -1 + byte "local_int" + app_local_del + frame_dig -1 + byte "local_bytes" + app_local_del + frame_dig -1 + byte "local_bool" + app_local_del + frame_dig -1 + byte "local_asset" + app_local_del + frame_dig -1 + byte "local_application" + app_local_del + frame_dig -1 + byte "local_account" + app_local_del + int 1 + retsub + + +// smart_contracts.local_storage.contract.LocalStorage.get_item_local_data(for_account: bytes) -> uint64: +get_item_local_data: + proto 1 1 + frame_dig -1 + int 0 + byte "local_int" + app_local_get_ex + assert // check self.local_int exists for account + retsub + + +// smart_contracts.local_storage.contract.LocalStorage.get_item_local_data_example(for_account: bytes) -> uint64: +get_item_local_data_example: + proto 1 1 + frame_dig -1 + int 0 + byte "local_int" + app_local_get_ex + assert // check self.local_int exists for account + int 10 + == + assert + frame_dig -1 + int 0 + byte "local_bytes" + app_local_get_ex + assert // check self.local_bytes exists for account + byte 0x48656c6c6f + == + assert + frame_dig -1 + int 0 + byte "local_bool" + app_local_get_ex + assert // check self.local_bool exists for account + assert + frame_dig -1 + int 0 + byte "local_asset" + app_local_get_ex + assert // check self.local_asset exists for account + int 10 + == + assert + frame_dig -1 + int 0 + byte "local_application" + app_local_get_ex + assert // check self.local_application exists for account + int 10 + == + assert + frame_dig -1 + int 0 + byte "local_account" + app_local_get_ex + assert // check self.local_account exists for account + int 0 + assert // Address length is 32 bytes + byte 0x48656c6c6f + == + assert + int 1 + retsub + + +// smart_contracts.local_storage.contract.LocalStorage.set_local_int(for_account: bytes, value: uint64) -> void: +set_local_int: + proto 2 0 + frame_dig -2 + byte "local_int" + frame_dig -1 + app_local_put + retsub + + +// smart_contracts.local_storage.contract.LocalStorage.set_local_data_example(for_account: bytes, value_asset: uint64, value_account: bytes, value_appln: uint64, value_byte: bytes, value_bool: uint64) -> uint64: +set_local_data_example: + proto 6 1 + frame_dig -6 + byte "local_bytes" + frame_dig -2 + app_local_put + frame_dig -6 + int 0 + byte "local_bytes" + app_local_get_ex + assert // check self.local_bytes exists for account + frame_dig -2 + == + assert + frame_dig -6 + byte "local_bool" + frame_dig -1 + app_local_put + frame_dig -6 + int 0 + byte "local_bool" + app_local_get_ex + assert // check self.local_bool exists for account + frame_dig -1 + == + assert + frame_dig -6 + byte "local_asset" + frame_dig -5 + app_local_put + frame_dig -6 + int 0 + byte "local_asset" + app_local_get_ex + assert // check self.local_asset exists for account + frame_dig -5 + == + assert + frame_dig -6 + byte "local_application" + frame_dig -3 + app_local_put + frame_dig -6 + int 0 + byte "local_application" + app_local_get_ex + assert // check self.local_application exists for account + frame_dig -3 + == + assert + frame_dig -6 + byte "local_account" + frame_dig -4 + app_local_put + frame_dig -6 + int 0 + byte "local_account" + app_local_get_ex + assert // check self.local_account exists for account + frame_dig -4 + == + assert + int 1 + retsub + + +// smart_contracts.local_storage.contract.LocalStorage.get_local_data_with_default_int(for_account: bytes) -> uint64: +get_local_data_with_default_int: + proto 1 1 + frame_dig -1 + int 0 + byte "local_int" + app_local_get_ex + int 0 + cover 2 + select + retsub + + +// smart_contracts.local_storage.contract.LocalStorage.get_local_data_with_default(for_account: bytes) -> uint64: +get_local_data_with_default: + proto 1 1 + frame_dig -1 + int 0 + byte "local_int" + app_local_get_ex + int 0 + cover 2 + select + int 10 + == + assert + frame_dig -1 + int 0 + byte "local_bytes" + app_local_get_ex + byte 0x44656661756c742056616c7565 + cover 2 + select + byte 0x48656c6c6f + == + assert + frame_dig -1 + int 0 + byte "local_bool" + app_local_get_ex + int 0 + cover 2 + select + assert + frame_dig -1 + int 0 + byte "local_asset" + app_local_get_ex + int 0 + cover 2 + select + int 10 + == + assert + frame_dig -1 + int 0 + byte "local_application" + app_local_get_ex + int 0 + cover 2 + select + int 10 + == + assert + int 0 + assert // Address length is 32 bytes + frame_dig -1 + int 0 + byte "local_account" + app_local_get_ex + byte 0x44656661756c742056616c7565 + cover 2 + select + byte 0x48656c6c6f + == + assert + int 1 + retsub + + +// smart_contracts.local_storage.contract.LocalStorage.maybe_local_data(for_account: bytes) -> uint64, uint64: +maybe_local_data: + proto 1 2 + frame_dig -1 + int 0 + byte "local_int" + app_local_get_ex + dup + uncover 2 + swap + bnz maybe_local_data_after_if_else@2 + int 0 + frame_bury 1 + +maybe_local_data_after_if_else@2: + frame_dig 1 + frame_dig 0 + uncover 3 + uncover 3 + retsub + + +// smart_contracts.local_storage.contract.LocalStorage.maybe_local_data_example(for_account: bytes) -> uint64: +maybe_local_data_example: + proto 1 1 + frame_dig -1 + int 0 + byte "local_int" + app_local_get_ex + assert // no data for account + int 10 + == + assert + frame_dig -1 + int 0 + byte "local_bytes" + app_local_get_ex + assert // no data for account + byte 0x48656c6c6f + == + assert + frame_dig -1 + int 0 + byte "local_bool" + app_local_get_ex + assert // no data for account + assert + frame_dig -1 + int 0 + byte "local_asset" + app_local_get_ex + assert // no data for account + int 10 + == + assert + frame_dig -1 + int 0 + byte "local_application" + app_local_get_ex + assert // no data for account + int 10 + == + assert + frame_dig -1 + int 0 + byte "local_account" + app_local_get_ex + assert // no data for account + int 0 + assert // Address length is 32 bytes + byte 0x48656c6c6f + == + assert + int 1 + retsub diff --git a/projects/python-contract-examples/smart_contracts/artifacts/local_storage/LocalStorage.arc32.json b/projects/python-contract-examples/smart_contracts/artifacts/local_storage/LocalStorage.arc32.json new file mode 100644 index 0000000..6f7fd23 --- /dev/null +++ b/projects/python-contract-examples/smart_contracts/artifacts/local_storage/LocalStorage.arc32.json @@ -0,0 +1,302 @@ +{ + "hints": { + "contains_local_data(account)bool": { + "call_config": { + "no_op": "CALL" + } + }, + "contains_local_data_example(account)bool": { + "call_config": { + "no_op": "CALL" + } + }, + "delete_local_data(account)void": { + "call_config": { + "no_op": "CALL" + } + }, + "delete_local_data_example(account)bool": { + "call_config": { + "no_op": "CALL" + } + }, + "get_item_local_data(account)uint64": { + "call_config": { + "no_op": "CALL" + } + }, + "get_item_local_data_example(account)bool": { + "call_config": { + "no_op": "CALL" + } + }, + "set_local_int(account,uint64)void": { + "call_config": { + "no_op": "CALL" + } + }, + "set_local_data_example(account,asset,account,application,byte[],bool)bool": { + "call_config": { + "no_op": "CALL" + } + }, + "get_local_data_with_default_int(account)uint64": { + "call_config": { + "no_op": "CALL" + } + }, + "get_local_data_with_default(account)bool": { + "call_config": { + "no_op": "CALL" + } + }, + "maybe_local_data(account)(uint64,bool)": { + "call_config": { + "no_op": "CALL" + } + }, + "maybe_local_data_example(account)bool": { + "call_config": { + "no_op": "CALL" + } + } + }, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpzbWFydF9jb250cmFjdHMubG9jYWxfc3RvcmFnZS5jb250cmFjdC5Mb2NhbFN0b3JhZ2UuYXBwcm92YWxfcHJvZ3JhbToKICAgIGNhbGxzdWIgX19wdXlhX2FyYzRfcm91dGVyX18KICAgIHJldHVybgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5sb2NhbF9zdG9yYWdlLmNvbnRyYWN0LkxvY2FsU3RvcmFnZS5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICBwcm90byAwIDEKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdAMTYKICAgIG1ldGhvZCAiY29udGFpbnNfbG9jYWxfZGF0YShhY2NvdW50KWJvb2wiCiAgICBtZXRob2QgImNvbnRhaW5zX2xvY2FsX2RhdGFfZXhhbXBsZShhY2NvdW50KWJvb2wiCiAgICBtZXRob2QgImRlbGV0ZV9sb2NhbF9kYXRhKGFjY291bnQpdm9pZCIKICAgIG1ldGhvZCAiZGVsZXRlX2xvY2FsX2RhdGFfZXhhbXBsZShhY2NvdW50KWJvb2wiCiAgICBtZXRob2QgImdldF9pdGVtX2xvY2FsX2RhdGEoYWNjb3VudCl1aW50NjQiCiAgICBtZXRob2QgImdldF9pdGVtX2xvY2FsX2RhdGFfZXhhbXBsZShhY2NvdW50KWJvb2wiCiAgICBtZXRob2QgInNldF9sb2NhbF9pbnQoYWNjb3VudCx1aW50NjQpdm9pZCIKICAgIG1ldGhvZCAic2V0X2xvY2FsX2RhdGFfZXhhbXBsZShhY2NvdW50LGFzc2V0LGFjY291bnQsYXBwbGljYXRpb24sYnl0ZVtdLGJvb2wpYm9vbCIKICAgIG1ldGhvZCAiZ2V0X2xvY2FsX2RhdGFfd2l0aF9kZWZhdWx0X2ludChhY2NvdW50KXVpbnQ2NCIKICAgIG1ldGhvZCAiZ2V0X2xvY2FsX2RhdGFfd2l0aF9kZWZhdWx0KGFjY291bnQpYm9vbCIKICAgIG1ldGhvZCAibWF5YmVfbG9jYWxfZGF0YShhY2NvdW50KSh1aW50NjQsYm9vbCkiCiAgICBtZXRob2QgIm1heWJlX2xvY2FsX2RhdGFfZXhhbXBsZShhY2NvdW50KWJvb2wiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19jb250YWluc19sb2NhbF9kYXRhX3JvdXRlQDIgX19wdXlhX2FyYzRfcm91dGVyX19fY29udGFpbnNfbG9jYWxfZGF0YV9leGFtcGxlX3JvdXRlQDMgX19wdXlhX2FyYzRfcm91dGVyX19fZGVsZXRlX2xvY2FsX2RhdGFfcm91dGVANCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19kZWxldGVfbG9jYWxfZGF0YV9leGFtcGxlX3JvdXRlQDUgX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X2l0ZW1fbG9jYWxfZGF0YV9yb3V0ZUA2IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9pdGVtX2xvY2FsX2RhdGFfZXhhbXBsZV9yb3V0ZUA3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3NldF9sb2NhbF9pbnRfcm91dGVAOCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19zZXRfbG9jYWxfZGF0YV9leGFtcGxlX3JvdXRlQDkgX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X2xvY2FsX2RhdGFfd2l0aF9kZWZhdWx0X2ludF9yb3V0ZUAxMCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfbG9jYWxfZGF0YV93aXRoX2RlZmF1bHRfcm91dGVAMTEgX19wdXlhX2FyYzRfcm91dGVyX19fbWF5YmVfbG9jYWxfZGF0YV9yb3V0ZUAxMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19tYXliZV9sb2NhbF9kYXRhX2V4YW1wbGVfcm91dGVAMTMKICAgIGludCAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2NvbnRhaW5zX2xvY2FsX2RhdGFfcm91dGVAMjoKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICBjYWxsc3ViIGNvbnRhaW5zX2xvY2FsX2RhdGEKICAgIGJ5dGUgMHgwMAogICAgaW50IDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19jb250YWluc19sb2NhbF9kYXRhX2V4YW1wbGVfcm91dGVAMzoKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICBjYWxsc3ViIGNvbnRhaW5zX2xvY2FsX2RhdGFfZXhhbXBsZQogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2RlbGV0ZV9sb2NhbF9kYXRhX3JvdXRlQDQ6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgY2FsbHN1YiBkZWxldGVfbG9jYWxfZGF0YQogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fZGVsZXRlX2xvY2FsX2RhdGFfZXhhbXBsZV9yb3V0ZUA1OgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIGNhbGxzdWIgZGVsZXRlX2xvY2FsX2RhdGFfZXhhbXBsZQogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9pdGVtX2xvY2FsX2RhdGFfcm91dGVANjoKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICBjYWxsc3ViIGdldF9pdGVtX2xvY2FsX2RhdGEKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9pdGVtX2xvY2FsX2RhdGFfZXhhbXBsZV9yb3V0ZUA3OgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIGNhbGxzdWIgZ2V0X2l0ZW1fbG9jYWxfZGF0YV9leGFtcGxlCiAgICBieXRlIDB4MDAKICAgIGludCAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fc2V0X2xvY2FsX2ludF9yb3V0ZUA4OgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIGNhbGxzdWIgc2V0X2xvY2FsX2ludAogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fc2V0X2xvY2FsX2RhdGFfZXhhbXBsZV9yb3V0ZUA5OgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDQKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDYKICAgIGludCAwCiAgICBnZXRiaXQKICAgIGNhbGxzdWIgc2V0X2xvY2FsX2RhdGFfZXhhbXBsZQogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9sb2NhbF9kYXRhX3dpdGhfZGVmYXVsdF9pbnRfcm91dGVAMTA6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgY2FsbHN1YiBnZXRfbG9jYWxfZGF0YV93aXRoX2RlZmF1bHRfaW50CiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfbG9jYWxfZGF0YV93aXRoX2RlZmF1bHRfcm91dGVAMTE6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgY2FsbHN1YiBnZXRfbG9jYWxfZGF0YV93aXRoX2RlZmF1bHQKICAgIGJ5dGUgMHgwMAogICAgaW50IDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19tYXliZV9sb2NhbF9kYXRhX3JvdXRlQDEyOgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIGNhbGxzdWIgbWF5YmVfbG9jYWxfZGF0YQogICAgc3dhcAogICAgaXRvYgogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAzCiAgICBzZXRiaXQKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fbWF5YmVfbG9jYWxfZGF0YV9leGFtcGxlX3JvdXRlQDEzOgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIGNhbGxzdWIgbWF5YmVfbG9jYWxfZGF0YV9leGFtcGxlCiAgICBieXRlIDB4MDAKICAgIGludCAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDE2OgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgYm56IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAMjAKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gaXMgY3JlYXRpbmcKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAMjA6CiAgICBpbnQgMAogICAgcmV0c3ViCgoKLy8gc21hcnRfY29udHJhY3RzLmxvY2FsX3N0b3JhZ2UuY29udHJhY3QuTG9jYWxTdG9yYWdlLmNvbnRhaW5zX2xvY2FsX2RhdGEoZm9yX2FjY291bnQ6IGJ5dGVzKSAtPiB1aW50NjQ6CmNvbnRhaW5zX2xvY2FsX2RhdGE6CiAgICBwcm90byAxIDEKICAgIGZyYW1lX2RpZyAtMQogICAgaW50IDAKICAgIGJ5dGUgImxvY2FsX2ludCIKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGJ1cnkgMQogICAgYXNzZXJ0CiAgICBpbnQgMQogICAgcmV0c3ViCgoKLy8gc21hcnRfY29udHJhY3RzLmxvY2FsX3N0b3JhZ2UuY29udHJhY3QuTG9jYWxTdG9yYWdlLmNvbnRhaW5zX2xvY2FsX2RhdGFfZXhhbXBsZShmb3JfYWNjb3VudDogYnl0ZXMpIC0+IHVpbnQ2NDoKY29udGFpbnNfbG9jYWxfZGF0YV9leGFtcGxlOgogICAgcHJvdG8gMSAxCiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAwCiAgICBieXRlICJsb2NhbF9pbnQiCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBidXJ5IDEKICAgIGFzc2VydAogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMAogICAgYnl0ZSAibG9jYWxfYnl0ZXMiCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBidXJ5IDEKICAgIGFzc2VydAogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMAogICAgYnl0ZSAibG9jYWxfYm9vbCIKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGJ1cnkgMQogICAgYXNzZXJ0CiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAwCiAgICBieXRlICJsb2NhbF9hc3NldCIKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGJ1cnkgMQogICAgYXNzZXJ0CiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAwCiAgICBieXRlICJsb2NhbF9hcHBsaWNhdGlvbiIKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGJ1cnkgMQogICAgYXNzZXJ0CiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAwCiAgICBieXRlICJsb2NhbF9hY2NvdW50IgogICAgYXBwX2xvY2FsX2dldF9leAogICAgYnVyeSAxCiAgICBhc3NlcnQKICAgIGludCAxCiAgICByZXRzdWIKCgovLyBzbWFydF9jb250cmFjdHMubG9jYWxfc3RvcmFnZS5jb250cmFjdC5Mb2NhbFN0b3JhZ2UuZGVsZXRlX2xvY2FsX2RhdGEoZm9yX2FjY291bnQ6IGJ5dGVzKSAtPiB2b2lkOgpkZWxldGVfbG9jYWxfZGF0YToKICAgIHByb3RvIDEgMAogICAgZnJhbWVfZGlnIC0xCiAgICBieXRlICJsb2NhbF9hY2NvdW50IgogICAgYXBwX2xvY2FsX2RlbAogICAgcmV0c3ViCgoKLy8gc21hcnRfY29udHJhY3RzLmxvY2FsX3N0b3JhZ2UuY29udHJhY3QuTG9jYWxTdG9yYWdlLmRlbGV0ZV9sb2NhbF9kYXRhX2V4YW1wbGUoZm9yX2FjY291bnQ6IGJ5dGVzKSAtPiB1aW50NjQ6CmRlbGV0ZV9sb2NhbF9kYXRhX2V4YW1wbGU6CiAgICBwcm90byAxIDEKICAgIGZyYW1lX2RpZyAtMQogICAgYnl0ZSAibG9jYWxfaW50IgogICAgYXBwX2xvY2FsX2RlbAogICAgZnJhbWVfZGlnIC0xCiAgICBieXRlICJsb2NhbF9ieXRlcyIKICAgIGFwcF9sb2NhbF9kZWwKICAgIGZyYW1lX2RpZyAtMQogICAgYnl0ZSAibG9jYWxfYm9vbCIKICAgIGFwcF9sb2NhbF9kZWwKICAgIGZyYW1lX2RpZyAtMQogICAgYnl0ZSAibG9jYWxfYXNzZXQiCiAgICBhcHBfbG9jYWxfZGVsCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ5dGUgImxvY2FsX2FwcGxpY2F0aW9uIgogICAgYXBwX2xvY2FsX2RlbAogICAgZnJhbWVfZGlnIC0xCiAgICBieXRlICJsb2NhbF9hY2NvdW50IgogICAgYXBwX2xvY2FsX2RlbAogICAgaW50IDEKICAgIHJldHN1YgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5sb2NhbF9zdG9yYWdlLmNvbnRyYWN0LkxvY2FsU3RvcmFnZS5nZXRfaXRlbV9sb2NhbF9kYXRhKGZvcl9hY2NvdW50OiBieXRlcykgLT4gdWludDY0OgpnZXRfaXRlbV9sb2NhbF9kYXRhOgogICAgcHJvdG8gMSAxCiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAwCiAgICBieXRlICJsb2NhbF9pbnQiCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5sb2NhbF9pbnQgZXhpc3RzIGZvciBhY2NvdW50CiAgICByZXRzdWIKCgovLyBzbWFydF9jb250cmFjdHMubG9jYWxfc3RvcmFnZS5jb250cmFjdC5Mb2NhbFN0b3JhZ2UuZ2V0X2l0ZW1fbG9jYWxfZGF0YV9leGFtcGxlKGZvcl9hY2NvdW50OiBieXRlcykgLT4gdWludDY0OgpnZXRfaXRlbV9sb2NhbF9kYXRhX2V4YW1wbGU6CiAgICBwcm90byAxIDEKICAgIGZyYW1lX2RpZyAtMQogICAgaW50IDAKICAgIGJ5dGUgImxvY2FsX2ludCIKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmxvY2FsX2ludCBleGlzdHMgZm9yIGFjY291bnQKICAgIGludCAxMAogICAgPT0KICAgIGFzc2VydAogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMAogICAgYnl0ZSAibG9jYWxfYnl0ZXMiCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5sb2NhbF9ieXRlcyBleGlzdHMgZm9yIGFjY291bnQKICAgIGJ5dGUgMHg0ODY1NmM2YzZmCiAgICA9PQogICAgYXNzZXJ0CiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAwCiAgICBieXRlICJsb2NhbF9ib29sIgogICAgYXBwX2xvY2FsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYubG9jYWxfYm9vbCBleGlzdHMgZm9yIGFjY291bnQKICAgIGFzc2VydAogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMAogICAgYnl0ZSAibG9jYWxfYXNzZXQiCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5sb2NhbF9hc3NldCBleGlzdHMgZm9yIGFjY291bnQKICAgIGludCAxMAogICAgPT0KICAgIGFzc2VydAogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMAogICAgYnl0ZSAibG9jYWxfYXBwbGljYXRpb24iCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5sb2NhbF9hcHBsaWNhdGlvbiBleGlzdHMgZm9yIGFjY291bnQKICAgIGludCAxMAogICAgPT0KICAgIGFzc2VydAogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMAogICAgYnl0ZSAibG9jYWxfYWNjb3VudCIKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmxvY2FsX2FjY291bnQgZXhpc3RzIGZvciBhY2NvdW50CiAgICBpbnQgMAogICAgYXNzZXJ0IC8vIEFkZHJlc3MgbGVuZ3RoIGlzIDMyIGJ5dGVzCiAgICBieXRlIDB4NDg2NTZjNmM2ZgogICAgPT0KICAgIGFzc2VydAogICAgaW50IDEKICAgIHJldHN1YgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5sb2NhbF9zdG9yYWdlLmNvbnRyYWN0LkxvY2FsU3RvcmFnZS5zZXRfbG9jYWxfaW50KGZvcl9hY2NvdW50OiBieXRlcywgdmFsdWU6IHVpbnQ2NCkgLT4gdm9pZDoKc2V0X2xvY2FsX2ludDoKICAgIHByb3RvIDIgMAogICAgZnJhbWVfZGlnIC0yCiAgICBieXRlICJsb2NhbF9pbnQiCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9sb2NhbF9wdXQKICAgIHJldHN1YgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5sb2NhbF9zdG9yYWdlLmNvbnRyYWN0LkxvY2FsU3RvcmFnZS5zZXRfbG9jYWxfZGF0YV9leGFtcGxlKGZvcl9hY2NvdW50OiBieXRlcywgdmFsdWVfYXNzZXQ6IHVpbnQ2NCwgdmFsdWVfYWNjb3VudDogYnl0ZXMsIHZhbHVlX2FwcGxuOiB1aW50NjQsIHZhbHVlX2J5dGU6IGJ5dGVzLCB2YWx1ZV9ib29sOiB1aW50NjQpIC0+IHVpbnQ2NDoKc2V0X2xvY2FsX2RhdGFfZXhhbXBsZToKICAgIHByb3RvIDYgMQogICAgZnJhbWVfZGlnIC02CiAgICBieXRlICJsb2NhbF9ieXRlcyIKICAgIGZyYW1lX2RpZyAtMgogICAgYXBwX2xvY2FsX3B1dAogICAgZnJhbWVfZGlnIC02CiAgICBpbnQgMAogICAgYnl0ZSAibG9jYWxfYnl0ZXMiCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5sb2NhbF9ieXRlcyBleGlzdHMgZm9yIGFjY291bnQKICAgIGZyYW1lX2RpZyAtMgogICAgPT0KICAgIGFzc2VydAogICAgZnJhbWVfZGlnIC02CiAgICBieXRlICJsb2NhbF9ib29sIgogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfbG9jYWxfcHV0CiAgICBmcmFtZV9kaWcgLTYKICAgIGludCAwCiAgICBieXRlICJsb2NhbF9ib29sIgogICAgYXBwX2xvY2FsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYubG9jYWxfYm9vbCBleGlzdHMgZm9yIGFjY291bnQKICAgIGZyYW1lX2RpZyAtMQogICAgPT0KICAgIGFzc2VydAogICAgZnJhbWVfZGlnIC02CiAgICBieXRlICJsb2NhbF9hc3NldCIKICAgIGZyYW1lX2RpZyAtNQogICAgYXBwX2xvY2FsX3B1dAogICAgZnJhbWVfZGlnIC02CiAgICBpbnQgMAogICAgYnl0ZSAibG9jYWxfYXNzZXQiCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5sb2NhbF9hc3NldCBleGlzdHMgZm9yIGFjY291bnQKICAgIGZyYW1lX2RpZyAtNQogICAgPT0KICAgIGFzc2VydAogICAgZnJhbWVfZGlnIC02CiAgICBieXRlICJsb2NhbF9hcHBsaWNhdGlvbiIKICAgIGZyYW1lX2RpZyAtMwogICAgYXBwX2xvY2FsX3B1dAogICAgZnJhbWVfZGlnIC02CiAgICBpbnQgMAogICAgYnl0ZSAibG9jYWxfYXBwbGljYXRpb24iCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5sb2NhbF9hcHBsaWNhdGlvbiBleGlzdHMgZm9yIGFjY291bnQKICAgIGZyYW1lX2RpZyAtMwogICAgPT0KICAgIGFzc2VydAogICAgZnJhbWVfZGlnIC02CiAgICBieXRlICJsb2NhbF9hY2NvdW50IgogICAgZnJhbWVfZGlnIC00CiAgICBhcHBfbG9jYWxfcHV0CiAgICBmcmFtZV9kaWcgLTYKICAgIGludCAwCiAgICBieXRlICJsb2NhbF9hY2NvdW50IgogICAgYXBwX2xvY2FsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYubG9jYWxfYWNjb3VudCBleGlzdHMgZm9yIGFjY291bnQKICAgIGZyYW1lX2RpZyAtNAogICAgPT0KICAgIGFzc2VydAogICAgaW50IDEKICAgIHJldHN1YgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5sb2NhbF9zdG9yYWdlLmNvbnRyYWN0LkxvY2FsU3RvcmFnZS5nZXRfbG9jYWxfZGF0YV93aXRoX2RlZmF1bHRfaW50KGZvcl9hY2NvdW50OiBieXRlcykgLT4gdWludDY0OgpnZXRfbG9jYWxfZGF0YV93aXRoX2RlZmF1bHRfaW50OgogICAgcHJvdG8gMSAxCiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAwCiAgICBieXRlICJsb2NhbF9pbnQiCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBpbnQgMAogICAgY292ZXIgMgogICAgc2VsZWN0CiAgICByZXRzdWIKCgovLyBzbWFydF9jb250cmFjdHMubG9jYWxfc3RvcmFnZS5jb250cmFjdC5Mb2NhbFN0b3JhZ2UuZ2V0X2xvY2FsX2RhdGFfd2l0aF9kZWZhdWx0KGZvcl9hY2NvdW50OiBieXRlcykgLT4gdWludDY0OgpnZXRfbG9jYWxfZGF0YV93aXRoX2RlZmF1bHQ6CiAgICBwcm90byAxIDEKICAgIGZyYW1lX2RpZyAtMQogICAgaW50IDAKICAgIGJ5dGUgImxvY2FsX2ludCIKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGludCAwCiAgICBjb3ZlciAyCiAgICBzZWxlY3QKICAgIGludCAxMAogICAgPT0KICAgIGFzc2VydAogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMAogICAgYnl0ZSAibG9jYWxfYnl0ZXMiCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBieXRlIDB4NDQ2NTY2NjE3NTZjNzQyMDU2NjE2Yzc1NjUKICAgIGNvdmVyIDIKICAgIHNlbGVjdAogICAgYnl0ZSAweDQ4NjU2YzZjNmYKICAgID09CiAgICBhc3NlcnQKICAgIGZyYW1lX2RpZyAtMQogICAgaW50IDAKICAgIGJ5dGUgImxvY2FsX2Jvb2wiCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBpbnQgMAogICAgY292ZXIgMgogICAgc2VsZWN0CiAgICBhc3NlcnQKICAgIGZyYW1lX2RpZyAtMQogICAgaW50IDAKICAgIGJ5dGUgImxvY2FsX2Fzc2V0IgogICAgYXBwX2xvY2FsX2dldF9leAogICAgaW50IDAKICAgIGNvdmVyIDIKICAgIHNlbGVjdAogICAgaW50IDEwCiAgICA9PQogICAgYXNzZXJ0CiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAwCiAgICBieXRlICJsb2NhbF9hcHBsaWNhdGlvbiIKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGludCAwCiAgICBjb3ZlciAyCiAgICBzZWxlY3QKICAgIGludCAxMAogICAgPT0KICAgIGFzc2VydAogICAgaW50IDAKICAgIGFzc2VydCAvLyBBZGRyZXNzIGxlbmd0aCBpcyAzMiBieXRlcwogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMAogICAgYnl0ZSAibG9jYWxfYWNjb3VudCIKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGJ5dGUgMHg0NDY1NjY2MTc1NmM3NDIwNTY2MTZjNzU2NQogICAgY292ZXIgMgogICAgc2VsZWN0CiAgICBieXRlIDB4NDg2NTZjNmM2ZgogICAgPT0KICAgIGFzc2VydAogICAgaW50IDEKICAgIHJldHN1YgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5sb2NhbF9zdG9yYWdlLmNvbnRyYWN0LkxvY2FsU3RvcmFnZS5tYXliZV9sb2NhbF9kYXRhKGZvcl9hY2NvdW50OiBieXRlcykgLT4gdWludDY0LCB1aW50NjQ6Cm1heWJlX2xvY2FsX2RhdGE6CiAgICBwcm90byAxIDIKICAgIGZyYW1lX2RpZyAtMQogICAgaW50IDAKICAgIGJ5dGUgImxvY2FsX2ludCIKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGR1cAogICAgdW5jb3ZlciAyCiAgICBzd2FwCiAgICBibnogbWF5YmVfbG9jYWxfZGF0YV9hZnRlcl9pZl9lbHNlQDIKICAgIGludCAwCiAgICBmcmFtZV9idXJ5IDEKCm1heWJlX2xvY2FsX2RhdGFfYWZ0ZXJfaWZfZWxzZUAyOgogICAgZnJhbWVfZGlnIDEKICAgIGZyYW1lX2RpZyAwCiAgICB1bmNvdmVyIDMKICAgIHVuY292ZXIgMwogICAgcmV0c3ViCgoKLy8gc21hcnRfY29udHJhY3RzLmxvY2FsX3N0b3JhZ2UuY29udHJhY3QuTG9jYWxTdG9yYWdlLm1heWJlX2xvY2FsX2RhdGFfZXhhbXBsZShmb3JfYWNjb3VudDogYnl0ZXMpIC0+IHVpbnQ2NDoKbWF5YmVfbG9jYWxfZGF0YV9leGFtcGxlOgogICAgcHJvdG8gMSAxCiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAwCiAgICBieXRlICJsb2NhbF9pbnQiCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gbm8gZGF0YSBmb3IgYWNjb3VudAogICAgaW50IDEwCiAgICA9PQogICAgYXNzZXJ0CiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAwCiAgICBieXRlICJsb2NhbF9ieXRlcyIKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBubyBkYXRhIGZvciBhY2NvdW50CiAgICBieXRlIDB4NDg2NTZjNmM2ZgogICAgPT0KICAgIGFzc2VydAogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMAogICAgYnl0ZSAibG9jYWxfYm9vbCIKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBubyBkYXRhIGZvciBhY2NvdW50CiAgICBhc3NlcnQKICAgIGZyYW1lX2RpZyAtMQogICAgaW50IDAKICAgIGJ5dGUgImxvY2FsX2Fzc2V0IgogICAgYXBwX2xvY2FsX2dldF9leAogICAgYXNzZXJ0IC8vIG5vIGRhdGEgZm9yIGFjY291bnQKICAgIGludCAxMAogICAgPT0KICAgIGFzc2VydAogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMAogICAgYnl0ZSAibG9jYWxfYXBwbGljYXRpb24iCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gbm8gZGF0YSBmb3IgYWNjb3VudAogICAgaW50IDEwCiAgICA9PQogICAgYXNzZXJ0CiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAwCiAgICBieXRlICJsb2NhbF9hY2NvdW50IgogICAgYXBwX2xvY2FsX2dldF9leAogICAgYXNzZXJ0IC8vIG5vIGRhdGEgZm9yIGFjY291bnQKICAgIGludCAwCiAgICBhc3NlcnQgLy8gQWRkcmVzcyBsZW5ndGggaXMgMzIgYnl0ZXMKICAgIGJ5dGUgMHg0ODY1NmM2YzZmCiAgICA9PQogICAgYXNzZXJ0CiAgICBpbnQgMQogICAgcmV0c3ViCg==", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpzbWFydF9jb250cmFjdHMubG9jYWxfc3RvcmFnZS5jb250cmFjdC5Mb2NhbFN0b3JhZ2UuY2xlYXJfc3RhdGVfcHJvZ3JhbToKICAgIGludCAxCiAgICByZXR1cm4K" + }, + "state": { + "global": { + "num_byte_slices": 0, + "num_uints": 0 + }, + "local": { + "num_byte_slices": 2, + "num_uints": 4 + } + }, + "schema": { + "global": { + "declared": {}, + "reserved": {} + }, + "local": { + "declared": { + "local_account": { + "type": "bytes", + "key": "local_account" + }, + "local_application": { + "type": "uint64", + "key": "local_application" + }, + "local_asset": { + "type": "uint64", + "key": "local_asset" + }, + "local_bool": { + "type": "uint64", + "key": "local_bool" + }, + "local_bytes": { + "type": "bytes", + "key": "local_bytes" + }, + "local_int": { + "type": "uint64", + "key": "local_int" + } + }, + "reserved": {} + } + }, + "contract": { + "name": "LocalStorage", + "methods": [ + { + "name": "contains_local_data", + "args": [ + { + "type": "account", + "name": "for_account" + } + ], + "readonly": false, + "returns": { + "type": "bool" + } + }, + { + "name": "contains_local_data_example", + "args": [ + { + "type": "account", + "name": "for_account" + } + ], + "readonly": false, + "returns": { + "type": "bool" + } + }, + { + "name": "delete_local_data", + "args": [ + { + "type": "account", + "name": "for_account" + } + ], + "readonly": false, + "returns": { + "type": "void" + } + }, + { + "name": "delete_local_data_example", + "args": [ + { + "type": "account", + "name": "for_account" + } + ], + "readonly": false, + "returns": { + "type": "bool" + } + }, + { + "name": "get_item_local_data", + "args": [ + { + "type": "account", + "name": "for_account" + } + ], + "readonly": false, + "returns": { + "type": "uint64" + } + }, + { + "name": "get_item_local_data_example", + "args": [ + { + "type": "account", + "name": "for_account" + } + ], + "readonly": false, + "returns": { + "type": "bool" + } + }, + { + "name": "set_local_int", + "args": [ + { + "type": "account", + "name": "for_account" + }, + { + "type": "uint64", + "name": "value" + } + ], + "readonly": false, + "returns": { + "type": "void" + } + }, + { + "name": "set_local_data_example", + "args": [ + { + "type": "account", + "name": "for_account" + }, + { + "type": "asset", + "name": "value_asset" + }, + { + "type": "account", + "name": "value_account" + }, + { + "type": "application", + "name": "value_appln" + }, + { + "type": "byte[]", + "name": "value_byte" + }, + { + "type": "bool", + "name": "value_bool" + } + ], + "readonly": false, + "returns": { + "type": "bool" + } + }, + { + "name": "get_local_data_with_default_int", + "args": [ + { + "type": "account", + "name": "for_account" + } + ], + "readonly": false, + "returns": { + "type": "uint64" + } + }, + { + "name": "get_local_data_with_default", + "args": [ + { + "type": "account", + "name": "for_account" + } + ], + "readonly": false, + "returns": { + "type": "bool" + } + }, + { + "name": "maybe_local_data", + "args": [ + { + "type": "account", + "name": "for_account" + } + ], + "readonly": false, + "returns": { + "type": "(uint64,bool)" + } + }, + { + "name": "maybe_local_data_example", + "args": [ + { + "type": "account", + "name": "for_account" + } + ], + "readonly": false, + "returns": { + "type": "bool" + } + } + ], + "networks": {} + }, + "bare_call_config": { + "no_op": "CREATE" + } +} \ No newline at end of file diff --git a/projects/python-contract-examples/smart_contracts/artifacts/local_storage/LocalStorage.clear.teal b/projects/python-contract-examples/smart_contracts/artifacts/local_storage/LocalStorage.clear.teal new file mode 100644 index 0000000..fd74f14 --- /dev/null +++ b/projects/python-contract-examples/smart_contracts/artifacts/local_storage/LocalStorage.clear.teal @@ -0,0 +1,5 @@ +#pragma version 10 + +smart_contracts.local_storage.contract.LocalStorage.clear_state_program: + int 1 + return diff --git a/projects/python-contract-examples/smart_contracts/artifacts/local_storage/local_storage_client.py b/projects/python-contract-examples/smart_contracts/artifacts/local_storage/local_storage_client.py new file mode 100644 index 0000000..b5fc971 --- /dev/null +++ b/projects/python-contract-examples/smart_contracts/artifacts/local_storage/local_storage_client.py @@ -0,0 +1,1401 @@ +# flake8: noqa +# fmt: off +# mypy: disable-error-code="no-any-return, no-untyped-call, misc, type-arg" +# This file was automatically generated by algokit-client-generator. +# DO NOT MODIFY IT BY HAND. +# requires: algokit-utils@^1.2.0 +import base64 +import dataclasses +import decimal +import typing +from abc import ABC, abstractmethod + +import algokit_utils +import algosdk +from algosdk.v2client import models +from algosdk.atomic_transaction_composer import ( + AtomicTransactionComposer, + AtomicTransactionResponse, + SimulateAtomicTransactionResponse, + TransactionSigner, + TransactionWithSigner +) + +_APP_SPEC_JSON = r"""{ + "hints": { + "contains_local_data(account)bool": { + "call_config": { + "no_op": "CALL" + } + }, + "contains_local_data_example(account)bool": { + "call_config": { + "no_op": "CALL" + } + }, + "delete_local_data(account)void": { + "call_config": { + "no_op": "CALL" + } + }, + "delete_local_data_example(account)bool": { + "call_config": { + "no_op": "CALL" + } + }, + "get_item_local_data(account)uint64": { + "call_config": { + "no_op": "CALL" + } + }, + "get_item_local_data_example(account)bool": { + "call_config": { + "no_op": "CALL" + } + }, + "set_local_int(account,uint64)void": { + "call_config": { + "no_op": "CALL" + } + }, + "set_local_data_example(account,asset,account,application,byte[],bool)bool": { + "call_config": { + "no_op": "CALL" + } + }, + "get_local_data_with_default_int(account)uint64": { + "call_config": { + "no_op": "CALL" + } + }, + "get_local_data_with_default(account)bool": { + "call_config": { + "no_op": "CALL" + } + }, + "maybe_local_data(account)(uint64,bool)": { + "call_config": { + "no_op": "CALL" + } + }, + "maybe_local_data_example(account)bool": { + "call_config": { + "no_op": "CALL" + } + } + }, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpzbWFydF9jb250cmFjdHMubG9jYWxfc3RvcmFnZS5jb250cmFjdC5Mb2NhbFN0b3JhZ2UuYXBwcm92YWxfcHJvZ3JhbToKICAgIGNhbGxzdWIgX19wdXlhX2FyYzRfcm91dGVyX18KICAgIHJldHVybgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5sb2NhbF9zdG9yYWdlLmNvbnRyYWN0LkxvY2FsU3RvcmFnZS5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICBwcm90byAwIDEKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdAMTYKICAgIG1ldGhvZCAiY29udGFpbnNfbG9jYWxfZGF0YShhY2NvdW50KWJvb2wiCiAgICBtZXRob2QgImNvbnRhaW5zX2xvY2FsX2RhdGFfZXhhbXBsZShhY2NvdW50KWJvb2wiCiAgICBtZXRob2QgImRlbGV0ZV9sb2NhbF9kYXRhKGFjY291bnQpdm9pZCIKICAgIG1ldGhvZCAiZGVsZXRlX2xvY2FsX2RhdGFfZXhhbXBsZShhY2NvdW50KWJvb2wiCiAgICBtZXRob2QgImdldF9pdGVtX2xvY2FsX2RhdGEoYWNjb3VudCl1aW50NjQiCiAgICBtZXRob2QgImdldF9pdGVtX2xvY2FsX2RhdGFfZXhhbXBsZShhY2NvdW50KWJvb2wiCiAgICBtZXRob2QgInNldF9sb2NhbF9pbnQoYWNjb3VudCx1aW50NjQpdm9pZCIKICAgIG1ldGhvZCAic2V0X2xvY2FsX2RhdGFfZXhhbXBsZShhY2NvdW50LGFzc2V0LGFjY291bnQsYXBwbGljYXRpb24sYnl0ZVtdLGJvb2wpYm9vbCIKICAgIG1ldGhvZCAiZ2V0X2xvY2FsX2RhdGFfd2l0aF9kZWZhdWx0X2ludChhY2NvdW50KXVpbnQ2NCIKICAgIG1ldGhvZCAiZ2V0X2xvY2FsX2RhdGFfd2l0aF9kZWZhdWx0KGFjY291bnQpYm9vbCIKICAgIG1ldGhvZCAibWF5YmVfbG9jYWxfZGF0YShhY2NvdW50KSh1aW50NjQsYm9vbCkiCiAgICBtZXRob2QgIm1heWJlX2xvY2FsX2RhdGFfZXhhbXBsZShhY2NvdW50KWJvb2wiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19jb250YWluc19sb2NhbF9kYXRhX3JvdXRlQDIgX19wdXlhX2FyYzRfcm91dGVyX19fY29udGFpbnNfbG9jYWxfZGF0YV9leGFtcGxlX3JvdXRlQDMgX19wdXlhX2FyYzRfcm91dGVyX19fZGVsZXRlX2xvY2FsX2RhdGFfcm91dGVANCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19kZWxldGVfbG9jYWxfZGF0YV9leGFtcGxlX3JvdXRlQDUgX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X2l0ZW1fbG9jYWxfZGF0YV9yb3V0ZUA2IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9pdGVtX2xvY2FsX2RhdGFfZXhhbXBsZV9yb3V0ZUA3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3NldF9sb2NhbF9pbnRfcm91dGVAOCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19zZXRfbG9jYWxfZGF0YV9leGFtcGxlX3JvdXRlQDkgX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X2xvY2FsX2RhdGFfd2l0aF9kZWZhdWx0X2ludF9yb3V0ZUAxMCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfbG9jYWxfZGF0YV93aXRoX2RlZmF1bHRfcm91dGVAMTEgX19wdXlhX2FyYzRfcm91dGVyX19fbWF5YmVfbG9jYWxfZGF0YV9yb3V0ZUAxMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19tYXliZV9sb2NhbF9kYXRhX2V4YW1wbGVfcm91dGVAMTMKICAgIGludCAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2NvbnRhaW5zX2xvY2FsX2RhdGFfcm91dGVAMjoKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICBjYWxsc3ViIGNvbnRhaW5zX2xvY2FsX2RhdGEKICAgIGJ5dGUgMHgwMAogICAgaW50IDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19jb250YWluc19sb2NhbF9kYXRhX2V4YW1wbGVfcm91dGVAMzoKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICBjYWxsc3ViIGNvbnRhaW5zX2xvY2FsX2RhdGFfZXhhbXBsZQogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2RlbGV0ZV9sb2NhbF9kYXRhX3JvdXRlQDQ6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgY2FsbHN1YiBkZWxldGVfbG9jYWxfZGF0YQogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fZGVsZXRlX2xvY2FsX2RhdGFfZXhhbXBsZV9yb3V0ZUA1OgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIGNhbGxzdWIgZGVsZXRlX2xvY2FsX2RhdGFfZXhhbXBsZQogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9pdGVtX2xvY2FsX2RhdGFfcm91dGVANjoKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICBjYWxsc3ViIGdldF9pdGVtX2xvY2FsX2RhdGEKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9pdGVtX2xvY2FsX2RhdGFfZXhhbXBsZV9yb3V0ZUA3OgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIGNhbGxzdWIgZ2V0X2l0ZW1fbG9jYWxfZGF0YV9leGFtcGxlCiAgICBieXRlIDB4MDAKICAgIGludCAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fc2V0X2xvY2FsX2ludF9yb3V0ZUA4OgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIGNhbGxzdWIgc2V0X2xvY2FsX2ludAogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fc2V0X2xvY2FsX2RhdGFfZXhhbXBsZV9yb3V0ZUA5OgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDQKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDYKICAgIGludCAwCiAgICBnZXRiaXQKICAgIGNhbGxzdWIgc2V0X2xvY2FsX2RhdGFfZXhhbXBsZQogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9sb2NhbF9kYXRhX3dpdGhfZGVmYXVsdF9pbnRfcm91dGVAMTA6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgY2FsbHN1YiBnZXRfbG9jYWxfZGF0YV93aXRoX2RlZmF1bHRfaW50CiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfbG9jYWxfZGF0YV93aXRoX2RlZmF1bHRfcm91dGVAMTE6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgY2FsbHN1YiBnZXRfbG9jYWxfZGF0YV93aXRoX2RlZmF1bHQKICAgIGJ5dGUgMHgwMAogICAgaW50IDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19tYXliZV9sb2NhbF9kYXRhX3JvdXRlQDEyOgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIGNhbGxzdWIgbWF5YmVfbG9jYWxfZGF0YQogICAgc3dhcAogICAgaXRvYgogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAzCiAgICBzZXRiaXQKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fbWF5YmVfbG9jYWxfZGF0YV9leGFtcGxlX3JvdXRlQDEzOgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIGNhbGxzdWIgbWF5YmVfbG9jYWxfZGF0YV9leGFtcGxlCiAgICBieXRlIDB4MDAKICAgIGludCAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDE2OgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgYm56IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAMjAKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gaXMgY3JlYXRpbmcKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAMjA6CiAgICBpbnQgMAogICAgcmV0c3ViCgoKLy8gc21hcnRfY29udHJhY3RzLmxvY2FsX3N0b3JhZ2UuY29udHJhY3QuTG9jYWxTdG9yYWdlLmNvbnRhaW5zX2xvY2FsX2RhdGEoZm9yX2FjY291bnQ6IGJ5dGVzKSAtPiB1aW50NjQ6CmNvbnRhaW5zX2xvY2FsX2RhdGE6CiAgICBwcm90byAxIDEKICAgIGZyYW1lX2RpZyAtMQogICAgaW50IDAKICAgIGJ5dGUgImxvY2FsX2ludCIKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGJ1cnkgMQogICAgYXNzZXJ0CiAgICBpbnQgMQogICAgcmV0c3ViCgoKLy8gc21hcnRfY29udHJhY3RzLmxvY2FsX3N0b3JhZ2UuY29udHJhY3QuTG9jYWxTdG9yYWdlLmNvbnRhaW5zX2xvY2FsX2RhdGFfZXhhbXBsZShmb3JfYWNjb3VudDogYnl0ZXMpIC0+IHVpbnQ2NDoKY29udGFpbnNfbG9jYWxfZGF0YV9leGFtcGxlOgogICAgcHJvdG8gMSAxCiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAwCiAgICBieXRlICJsb2NhbF9pbnQiCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBidXJ5IDEKICAgIGFzc2VydAogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMAogICAgYnl0ZSAibG9jYWxfYnl0ZXMiCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBidXJ5IDEKICAgIGFzc2VydAogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMAogICAgYnl0ZSAibG9jYWxfYm9vbCIKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGJ1cnkgMQogICAgYXNzZXJ0CiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAwCiAgICBieXRlICJsb2NhbF9hc3NldCIKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGJ1cnkgMQogICAgYXNzZXJ0CiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAwCiAgICBieXRlICJsb2NhbF9hcHBsaWNhdGlvbiIKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGJ1cnkgMQogICAgYXNzZXJ0CiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAwCiAgICBieXRlICJsb2NhbF9hY2NvdW50IgogICAgYXBwX2xvY2FsX2dldF9leAogICAgYnVyeSAxCiAgICBhc3NlcnQKICAgIGludCAxCiAgICByZXRzdWIKCgovLyBzbWFydF9jb250cmFjdHMubG9jYWxfc3RvcmFnZS5jb250cmFjdC5Mb2NhbFN0b3JhZ2UuZGVsZXRlX2xvY2FsX2RhdGEoZm9yX2FjY291bnQ6IGJ5dGVzKSAtPiB2b2lkOgpkZWxldGVfbG9jYWxfZGF0YToKICAgIHByb3RvIDEgMAogICAgZnJhbWVfZGlnIC0xCiAgICBieXRlICJsb2NhbF9hY2NvdW50IgogICAgYXBwX2xvY2FsX2RlbAogICAgcmV0c3ViCgoKLy8gc21hcnRfY29udHJhY3RzLmxvY2FsX3N0b3JhZ2UuY29udHJhY3QuTG9jYWxTdG9yYWdlLmRlbGV0ZV9sb2NhbF9kYXRhX2V4YW1wbGUoZm9yX2FjY291bnQ6IGJ5dGVzKSAtPiB1aW50NjQ6CmRlbGV0ZV9sb2NhbF9kYXRhX2V4YW1wbGU6CiAgICBwcm90byAxIDEKICAgIGZyYW1lX2RpZyAtMQogICAgYnl0ZSAibG9jYWxfaW50IgogICAgYXBwX2xvY2FsX2RlbAogICAgZnJhbWVfZGlnIC0xCiAgICBieXRlICJsb2NhbF9ieXRlcyIKICAgIGFwcF9sb2NhbF9kZWwKICAgIGZyYW1lX2RpZyAtMQogICAgYnl0ZSAibG9jYWxfYm9vbCIKICAgIGFwcF9sb2NhbF9kZWwKICAgIGZyYW1lX2RpZyAtMQogICAgYnl0ZSAibG9jYWxfYXNzZXQiCiAgICBhcHBfbG9jYWxfZGVsCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ5dGUgImxvY2FsX2FwcGxpY2F0aW9uIgogICAgYXBwX2xvY2FsX2RlbAogICAgZnJhbWVfZGlnIC0xCiAgICBieXRlICJsb2NhbF9hY2NvdW50IgogICAgYXBwX2xvY2FsX2RlbAogICAgaW50IDEKICAgIHJldHN1YgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5sb2NhbF9zdG9yYWdlLmNvbnRyYWN0LkxvY2FsU3RvcmFnZS5nZXRfaXRlbV9sb2NhbF9kYXRhKGZvcl9hY2NvdW50OiBieXRlcykgLT4gdWludDY0OgpnZXRfaXRlbV9sb2NhbF9kYXRhOgogICAgcHJvdG8gMSAxCiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAwCiAgICBieXRlICJsb2NhbF9pbnQiCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5sb2NhbF9pbnQgZXhpc3RzIGZvciBhY2NvdW50CiAgICByZXRzdWIKCgovLyBzbWFydF9jb250cmFjdHMubG9jYWxfc3RvcmFnZS5jb250cmFjdC5Mb2NhbFN0b3JhZ2UuZ2V0X2l0ZW1fbG9jYWxfZGF0YV9leGFtcGxlKGZvcl9hY2NvdW50OiBieXRlcykgLT4gdWludDY0OgpnZXRfaXRlbV9sb2NhbF9kYXRhX2V4YW1wbGU6CiAgICBwcm90byAxIDEKICAgIGZyYW1lX2RpZyAtMQogICAgaW50IDAKICAgIGJ5dGUgImxvY2FsX2ludCIKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmxvY2FsX2ludCBleGlzdHMgZm9yIGFjY291bnQKICAgIGludCAxMAogICAgPT0KICAgIGFzc2VydAogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMAogICAgYnl0ZSAibG9jYWxfYnl0ZXMiCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5sb2NhbF9ieXRlcyBleGlzdHMgZm9yIGFjY291bnQKICAgIGJ5dGUgMHg0ODY1NmM2YzZmCiAgICA9PQogICAgYXNzZXJ0CiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAwCiAgICBieXRlICJsb2NhbF9ib29sIgogICAgYXBwX2xvY2FsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYubG9jYWxfYm9vbCBleGlzdHMgZm9yIGFjY291bnQKICAgIGFzc2VydAogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMAogICAgYnl0ZSAibG9jYWxfYXNzZXQiCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5sb2NhbF9hc3NldCBleGlzdHMgZm9yIGFjY291bnQKICAgIGludCAxMAogICAgPT0KICAgIGFzc2VydAogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMAogICAgYnl0ZSAibG9jYWxfYXBwbGljYXRpb24iCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5sb2NhbF9hcHBsaWNhdGlvbiBleGlzdHMgZm9yIGFjY291bnQKICAgIGludCAxMAogICAgPT0KICAgIGFzc2VydAogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMAogICAgYnl0ZSAibG9jYWxfYWNjb3VudCIKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmxvY2FsX2FjY291bnQgZXhpc3RzIGZvciBhY2NvdW50CiAgICBpbnQgMAogICAgYXNzZXJ0IC8vIEFkZHJlc3MgbGVuZ3RoIGlzIDMyIGJ5dGVzCiAgICBieXRlIDB4NDg2NTZjNmM2ZgogICAgPT0KICAgIGFzc2VydAogICAgaW50IDEKICAgIHJldHN1YgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5sb2NhbF9zdG9yYWdlLmNvbnRyYWN0LkxvY2FsU3RvcmFnZS5zZXRfbG9jYWxfaW50KGZvcl9hY2NvdW50OiBieXRlcywgdmFsdWU6IHVpbnQ2NCkgLT4gdm9pZDoKc2V0X2xvY2FsX2ludDoKICAgIHByb3RvIDIgMAogICAgZnJhbWVfZGlnIC0yCiAgICBieXRlICJsb2NhbF9pbnQiCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9sb2NhbF9wdXQKICAgIHJldHN1YgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5sb2NhbF9zdG9yYWdlLmNvbnRyYWN0LkxvY2FsU3RvcmFnZS5zZXRfbG9jYWxfZGF0YV9leGFtcGxlKGZvcl9hY2NvdW50OiBieXRlcywgdmFsdWVfYXNzZXQ6IHVpbnQ2NCwgdmFsdWVfYWNjb3VudDogYnl0ZXMsIHZhbHVlX2FwcGxuOiB1aW50NjQsIHZhbHVlX2J5dGU6IGJ5dGVzLCB2YWx1ZV9ib29sOiB1aW50NjQpIC0+IHVpbnQ2NDoKc2V0X2xvY2FsX2RhdGFfZXhhbXBsZToKICAgIHByb3RvIDYgMQogICAgZnJhbWVfZGlnIC02CiAgICBieXRlICJsb2NhbF9ieXRlcyIKICAgIGZyYW1lX2RpZyAtMgogICAgYXBwX2xvY2FsX3B1dAogICAgZnJhbWVfZGlnIC02CiAgICBpbnQgMAogICAgYnl0ZSAibG9jYWxfYnl0ZXMiCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5sb2NhbF9ieXRlcyBleGlzdHMgZm9yIGFjY291bnQKICAgIGZyYW1lX2RpZyAtMgogICAgPT0KICAgIGFzc2VydAogICAgZnJhbWVfZGlnIC02CiAgICBieXRlICJsb2NhbF9ib29sIgogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfbG9jYWxfcHV0CiAgICBmcmFtZV9kaWcgLTYKICAgIGludCAwCiAgICBieXRlICJsb2NhbF9ib29sIgogICAgYXBwX2xvY2FsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYubG9jYWxfYm9vbCBleGlzdHMgZm9yIGFjY291bnQKICAgIGZyYW1lX2RpZyAtMQogICAgPT0KICAgIGFzc2VydAogICAgZnJhbWVfZGlnIC02CiAgICBieXRlICJsb2NhbF9hc3NldCIKICAgIGZyYW1lX2RpZyAtNQogICAgYXBwX2xvY2FsX3B1dAogICAgZnJhbWVfZGlnIC02CiAgICBpbnQgMAogICAgYnl0ZSAibG9jYWxfYXNzZXQiCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5sb2NhbF9hc3NldCBleGlzdHMgZm9yIGFjY291bnQKICAgIGZyYW1lX2RpZyAtNQogICAgPT0KICAgIGFzc2VydAogICAgZnJhbWVfZGlnIC02CiAgICBieXRlICJsb2NhbF9hcHBsaWNhdGlvbiIKICAgIGZyYW1lX2RpZyAtMwogICAgYXBwX2xvY2FsX3B1dAogICAgZnJhbWVfZGlnIC02CiAgICBpbnQgMAogICAgYnl0ZSAibG9jYWxfYXBwbGljYXRpb24iCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5sb2NhbF9hcHBsaWNhdGlvbiBleGlzdHMgZm9yIGFjY291bnQKICAgIGZyYW1lX2RpZyAtMwogICAgPT0KICAgIGFzc2VydAogICAgZnJhbWVfZGlnIC02CiAgICBieXRlICJsb2NhbF9hY2NvdW50IgogICAgZnJhbWVfZGlnIC00CiAgICBhcHBfbG9jYWxfcHV0CiAgICBmcmFtZV9kaWcgLTYKICAgIGludCAwCiAgICBieXRlICJsb2NhbF9hY2NvdW50IgogICAgYXBwX2xvY2FsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYubG9jYWxfYWNjb3VudCBleGlzdHMgZm9yIGFjY291bnQKICAgIGZyYW1lX2RpZyAtNAogICAgPT0KICAgIGFzc2VydAogICAgaW50IDEKICAgIHJldHN1YgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5sb2NhbF9zdG9yYWdlLmNvbnRyYWN0LkxvY2FsU3RvcmFnZS5nZXRfbG9jYWxfZGF0YV93aXRoX2RlZmF1bHRfaW50KGZvcl9hY2NvdW50OiBieXRlcykgLT4gdWludDY0OgpnZXRfbG9jYWxfZGF0YV93aXRoX2RlZmF1bHRfaW50OgogICAgcHJvdG8gMSAxCiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAwCiAgICBieXRlICJsb2NhbF9pbnQiCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBpbnQgMAogICAgY292ZXIgMgogICAgc2VsZWN0CiAgICByZXRzdWIKCgovLyBzbWFydF9jb250cmFjdHMubG9jYWxfc3RvcmFnZS5jb250cmFjdC5Mb2NhbFN0b3JhZ2UuZ2V0X2xvY2FsX2RhdGFfd2l0aF9kZWZhdWx0KGZvcl9hY2NvdW50OiBieXRlcykgLT4gdWludDY0OgpnZXRfbG9jYWxfZGF0YV93aXRoX2RlZmF1bHQ6CiAgICBwcm90byAxIDEKICAgIGZyYW1lX2RpZyAtMQogICAgaW50IDAKICAgIGJ5dGUgImxvY2FsX2ludCIKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGludCAwCiAgICBjb3ZlciAyCiAgICBzZWxlY3QKICAgIGludCAxMAogICAgPT0KICAgIGFzc2VydAogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMAogICAgYnl0ZSAibG9jYWxfYnl0ZXMiCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBieXRlIDB4NDQ2NTY2NjE3NTZjNzQyMDU2NjE2Yzc1NjUKICAgIGNvdmVyIDIKICAgIHNlbGVjdAogICAgYnl0ZSAweDQ4NjU2YzZjNmYKICAgID09CiAgICBhc3NlcnQKICAgIGZyYW1lX2RpZyAtMQogICAgaW50IDAKICAgIGJ5dGUgImxvY2FsX2Jvb2wiCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBpbnQgMAogICAgY292ZXIgMgogICAgc2VsZWN0CiAgICBhc3NlcnQKICAgIGZyYW1lX2RpZyAtMQogICAgaW50IDAKICAgIGJ5dGUgImxvY2FsX2Fzc2V0IgogICAgYXBwX2xvY2FsX2dldF9leAogICAgaW50IDAKICAgIGNvdmVyIDIKICAgIHNlbGVjdAogICAgaW50IDEwCiAgICA9PQogICAgYXNzZXJ0CiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAwCiAgICBieXRlICJsb2NhbF9hcHBsaWNhdGlvbiIKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGludCAwCiAgICBjb3ZlciAyCiAgICBzZWxlY3QKICAgIGludCAxMAogICAgPT0KICAgIGFzc2VydAogICAgaW50IDAKICAgIGFzc2VydCAvLyBBZGRyZXNzIGxlbmd0aCBpcyAzMiBieXRlcwogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMAogICAgYnl0ZSAibG9jYWxfYWNjb3VudCIKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGJ5dGUgMHg0NDY1NjY2MTc1NmM3NDIwNTY2MTZjNzU2NQogICAgY292ZXIgMgogICAgc2VsZWN0CiAgICBieXRlIDB4NDg2NTZjNmM2ZgogICAgPT0KICAgIGFzc2VydAogICAgaW50IDEKICAgIHJldHN1YgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5sb2NhbF9zdG9yYWdlLmNvbnRyYWN0LkxvY2FsU3RvcmFnZS5tYXliZV9sb2NhbF9kYXRhKGZvcl9hY2NvdW50OiBieXRlcykgLT4gdWludDY0LCB1aW50NjQ6Cm1heWJlX2xvY2FsX2RhdGE6CiAgICBwcm90byAxIDIKICAgIGZyYW1lX2RpZyAtMQogICAgaW50IDAKICAgIGJ5dGUgImxvY2FsX2ludCIKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGR1cAogICAgdW5jb3ZlciAyCiAgICBzd2FwCiAgICBibnogbWF5YmVfbG9jYWxfZGF0YV9hZnRlcl9pZl9lbHNlQDIKICAgIGludCAwCiAgICBmcmFtZV9idXJ5IDEKCm1heWJlX2xvY2FsX2RhdGFfYWZ0ZXJfaWZfZWxzZUAyOgogICAgZnJhbWVfZGlnIDEKICAgIGZyYW1lX2RpZyAwCiAgICB1bmNvdmVyIDMKICAgIHVuY292ZXIgMwogICAgcmV0c3ViCgoKLy8gc21hcnRfY29udHJhY3RzLmxvY2FsX3N0b3JhZ2UuY29udHJhY3QuTG9jYWxTdG9yYWdlLm1heWJlX2xvY2FsX2RhdGFfZXhhbXBsZShmb3JfYWNjb3VudDogYnl0ZXMpIC0+IHVpbnQ2NDoKbWF5YmVfbG9jYWxfZGF0YV9leGFtcGxlOgogICAgcHJvdG8gMSAxCiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAwCiAgICBieXRlICJsb2NhbF9pbnQiCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gbm8gZGF0YSBmb3IgYWNjb3VudAogICAgaW50IDEwCiAgICA9PQogICAgYXNzZXJ0CiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAwCiAgICBieXRlICJsb2NhbF9ieXRlcyIKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBubyBkYXRhIGZvciBhY2NvdW50CiAgICBieXRlIDB4NDg2NTZjNmM2ZgogICAgPT0KICAgIGFzc2VydAogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMAogICAgYnl0ZSAibG9jYWxfYm9vbCIKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBubyBkYXRhIGZvciBhY2NvdW50CiAgICBhc3NlcnQKICAgIGZyYW1lX2RpZyAtMQogICAgaW50IDAKICAgIGJ5dGUgImxvY2FsX2Fzc2V0IgogICAgYXBwX2xvY2FsX2dldF9leAogICAgYXNzZXJ0IC8vIG5vIGRhdGEgZm9yIGFjY291bnQKICAgIGludCAxMAogICAgPT0KICAgIGFzc2VydAogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMAogICAgYnl0ZSAibG9jYWxfYXBwbGljYXRpb24iCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gbm8gZGF0YSBmb3IgYWNjb3VudAogICAgaW50IDEwCiAgICA9PQogICAgYXNzZXJ0CiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAwCiAgICBieXRlICJsb2NhbF9hY2NvdW50IgogICAgYXBwX2xvY2FsX2dldF9leAogICAgYXNzZXJ0IC8vIG5vIGRhdGEgZm9yIGFjY291bnQKICAgIGludCAwCiAgICBhc3NlcnQgLy8gQWRkcmVzcyBsZW5ndGggaXMgMzIgYnl0ZXMKICAgIGJ5dGUgMHg0ODY1NmM2YzZmCiAgICA9PQogICAgYXNzZXJ0CiAgICBpbnQgMQogICAgcmV0c3ViCg==", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpzbWFydF9jb250cmFjdHMubG9jYWxfc3RvcmFnZS5jb250cmFjdC5Mb2NhbFN0b3JhZ2UuY2xlYXJfc3RhdGVfcHJvZ3JhbToKICAgIGludCAxCiAgICByZXR1cm4K" + }, + "state": { + "global": { + "num_byte_slices": 0, + "num_uints": 0 + }, + "local": { + "num_byte_slices": 2, + "num_uints": 4 + } + }, + "schema": { + "global": { + "declared": {}, + "reserved": {} + }, + "local": { + "declared": { + "local_account": { + "type": "bytes", + "key": "local_account" + }, + "local_application": { + "type": "uint64", + "key": "local_application" + }, + "local_asset": { + "type": "uint64", + "key": "local_asset" + }, + "local_bool": { + "type": "uint64", + "key": "local_bool" + }, + "local_bytes": { + "type": "bytes", + "key": "local_bytes" + }, + "local_int": { + "type": "uint64", + "key": "local_int" + } + }, + "reserved": {} + } + }, + "contract": { + "name": "LocalStorage", + "methods": [ + { + "name": "contains_local_data", + "args": [ + { + "type": "account", + "name": "for_account" + } + ], + "returns": { + "type": "bool" + } + }, + { + "name": "contains_local_data_example", + "args": [ + { + "type": "account", + "name": "for_account" + } + ], + "returns": { + "type": "bool" + } + }, + { + "name": "delete_local_data", + "args": [ + { + "type": "account", + "name": "for_account" + } + ], + "returns": { + "type": "void" + } + }, + { + "name": "delete_local_data_example", + "args": [ + { + "type": "account", + "name": "for_account" + } + ], + "returns": { + "type": "bool" + } + }, + { + "name": "get_item_local_data", + "args": [ + { + "type": "account", + "name": "for_account" + } + ], + "returns": { + "type": "uint64" + } + }, + { + "name": "get_item_local_data_example", + "args": [ + { + "type": "account", + "name": "for_account" + } + ], + "returns": { + "type": "bool" + } + }, + { + "name": "set_local_int", + "args": [ + { + "type": "account", + "name": "for_account" + }, + { + "type": "uint64", + "name": "value" + } + ], + "returns": { + "type": "void" + } + }, + { + "name": "set_local_data_example", + "args": [ + { + "type": "account", + "name": "for_account" + }, + { + "type": "asset", + "name": "value_asset" + }, + { + "type": "account", + "name": "value_account" + }, + { + "type": "application", + "name": "value_appln" + }, + { + "type": "byte[]", + "name": "value_byte" + }, + { + "type": "bool", + "name": "value_bool" + } + ], + "returns": { + "type": "bool" + } + }, + { + "name": "get_local_data_with_default_int", + "args": [ + { + "type": "account", + "name": "for_account" + } + ], + "returns": { + "type": "uint64" + } + }, + { + "name": "get_local_data_with_default", + "args": [ + { + "type": "account", + "name": "for_account" + } + ], + "returns": { + "type": "bool" + } + }, + { + "name": "maybe_local_data", + "args": [ + { + "type": "account", + "name": "for_account" + } + ], + "returns": { + "type": "(uint64,bool)" + } + }, + { + "name": "maybe_local_data_example", + "args": [ + { + "type": "account", + "name": "for_account" + } + ], + "returns": { + "type": "bool" + } + } + ], + "networks": {} + }, + "bare_call_config": { + "no_op": "CREATE" + } +}""" +APP_SPEC = algokit_utils.ApplicationSpecification.from_json(_APP_SPEC_JSON) +_TReturn = typing.TypeVar("_TReturn") + + +class _ArgsBase(ABC, typing.Generic[_TReturn]): + @staticmethod + @abstractmethod + def method() -> str: + ... + + +_TArgs = typing.TypeVar("_TArgs", bound=_ArgsBase[typing.Any]) + + +@dataclasses.dataclass(kw_only=True) +class _TArgsHolder(typing.Generic[_TArgs]): + args: _TArgs + + +def _filter_none(value: dict | typing.Any) -> dict | typing.Any: + if isinstance(value, dict): + return {k: _filter_none(v) for k, v in value.items() if v is not None} + return value + + +def _as_dict(data: typing.Any, *, convert_all: bool = True) -> dict[str, typing.Any]: + if data is None: + return {} + if not dataclasses.is_dataclass(data): + raise TypeError(f"{data} must be a dataclass") + if convert_all: + result = dataclasses.asdict(data) # type: ignore[call-overload] + else: + result = {f.name: getattr(data, f.name) for f in dataclasses.fields(data)} + return _filter_none(result) + + +def _convert_transaction_parameters( + transaction_parameters: algokit_utils.TransactionParameters | None, +) -> algokit_utils.TransactionParametersDict: + return typing.cast(algokit_utils.TransactionParametersDict, _as_dict(transaction_parameters)) + + +def _convert_call_transaction_parameters( + transaction_parameters: algokit_utils.TransactionParameters | None, +) -> algokit_utils.OnCompleteCallParametersDict: + return typing.cast(algokit_utils.OnCompleteCallParametersDict, _as_dict(transaction_parameters)) + + +def _convert_create_transaction_parameters( + transaction_parameters: algokit_utils.TransactionParameters | None, + on_complete: algokit_utils.OnCompleteActionName, +) -> algokit_utils.CreateCallParametersDict: + result = typing.cast(algokit_utils.CreateCallParametersDict, _as_dict(transaction_parameters)) + on_complete_enum = on_complete.replace("_", " ").title().replace(" ", "") + "OC" + result["on_complete"] = getattr(algosdk.transaction.OnComplete, on_complete_enum) + return result + + +def _convert_deploy_args( + deploy_args: algokit_utils.DeployCallArgs | None, +) -> algokit_utils.ABICreateCallArgsDict | None: + if deploy_args is None: + return None + + deploy_args_dict = typing.cast(algokit_utils.ABICreateCallArgsDict, _as_dict(deploy_args)) + if isinstance(deploy_args, _TArgsHolder): + deploy_args_dict["args"] = _as_dict(deploy_args.args) + deploy_args_dict["method"] = deploy_args.args.method() + + return deploy_args_dict + + +@dataclasses.dataclass(kw_only=True) +class ContainsLocalDataArgs(_ArgsBase[bool]): + for_account: str | bytes + + @staticmethod + def method() -> str: + return "contains_local_data(account)bool" + + +@dataclasses.dataclass(kw_only=True) +class ContainsLocalDataExampleArgs(_ArgsBase[bool]): + for_account: str | bytes + + @staticmethod + def method() -> str: + return "contains_local_data_example(account)bool" + + +@dataclasses.dataclass(kw_only=True) +class DeleteLocalDataArgs(_ArgsBase[None]): + for_account: str | bytes + + @staticmethod + def method() -> str: + return "delete_local_data(account)void" + + +@dataclasses.dataclass(kw_only=True) +class DeleteLocalDataExampleArgs(_ArgsBase[bool]): + for_account: str | bytes + + @staticmethod + def method() -> str: + return "delete_local_data_example(account)bool" + + +@dataclasses.dataclass(kw_only=True) +class GetItemLocalDataArgs(_ArgsBase[int]): + for_account: str | bytes + + @staticmethod + def method() -> str: + return "get_item_local_data(account)uint64" + + +@dataclasses.dataclass(kw_only=True) +class GetItemLocalDataExampleArgs(_ArgsBase[bool]): + for_account: str | bytes + + @staticmethod + def method() -> str: + return "get_item_local_data_example(account)bool" + + +@dataclasses.dataclass(kw_only=True) +class SetLocalIntArgs(_ArgsBase[None]): + for_account: str | bytes + value: int + + @staticmethod + def method() -> str: + return "set_local_int(account,uint64)void" + + +@dataclasses.dataclass(kw_only=True) +class SetLocalDataExampleArgs(_ArgsBase[bool]): + for_account: str | bytes + value_asset: int + value_account: str | bytes + value_appln: int + value_byte: bytes | bytearray + value_bool: bool + + @staticmethod + def method() -> str: + return "set_local_data_example(account,asset,account,application,byte[],bool)bool" + + +@dataclasses.dataclass(kw_only=True) +class GetLocalDataWithDefaultIntArgs(_ArgsBase[int]): + for_account: str | bytes + + @staticmethod + def method() -> str: + return "get_local_data_with_default_int(account)uint64" + + +@dataclasses.dataclass(kw_only=True) +class GetLocalDataWithDefaultArgs(_ArgsBase[bool]): + for_account: str | bytes + + @staticmethod + def method() -> str: + return "get_local_data_with_default(account)bool" + + +@dataclasses.dataclass(kw_only=True) +class MaybeLocalDataArgs(_ArgsBase[tuple[int, bool]]): + for_account: str | bytes + + @staticmethod + def method() -> str: + return "maybe_local_data(account)(uint64,bool)" + + +@dataclasses.dataclass(kw_only=True) +class MaybeLocalDataExampleArgs(_ArgsBase[bool]): + for_account: str | bytes + + @staticmethod + def method() -> str: + return "maybe_local_data_example(account)bool" + + +class ByteReader: + def __init__(self, data: bytes): + self._data = data + + @property + def as_bytes(self) -> bytes: + return self._data + + @property + def as_str(self) -> str: + return self._data.decode("utf8") + + @property + def as_base64(self) -> str: + return base64.b64encode(self._data).decode("utf8") + + @property + def as_hex(self) -> str: + return self._data.hex() + + +class LocalState: + def __init__(self, data: dict[bytes, bytes | int]): + self.local_account = ByteReader(typing.cast(bytes, data.get(b"local_account"))) + self.local_application = typing.cast(int, data.get(b"local_application")) + self.local_asset = typing.cast(int, data.get(b"local_asset")) + self.local_bool = typing.cast(int, data.get(b"local_bool")) + self.local_bytes = ByteReader(typing.cast(bytes, data.get(b"local_bytes"))) + self.local_int = typing.cast(int, data.get(b"local_int")) + + +@dataclasses.dataclass(kw_only=True) +class SimulateOptions: + allow_more_logs: bool = dataclasses.field(default=False) + allow_empty_signatures: bool = dataclasses.field(default=False) + extra_opcode_budget: int = dataclasses.field(default=0) + exec_trace_config: models.SimulateTraceConfig | None = dataclasses.field(default=None) + + +class Composer: + + def __init__(self, app_client: algokit_utils.ApplicationClient, atc: AtomicTransactionComposer): + self.app_client = app_client + self.atc = atc + + def build(self) -> AtomicTransactionComposer: + return self.atc + + def simulate(self, options: SimulateOptions | None = None) -> SimulateAtomicTransactionResponse: + request = models.SimulateRequest( + allow_more_logs=options.allow_more_logs, + allow_empty_signatures=options.allow_empty_signatures, + extra_opcode_budget=options.extra_opcode_budget, + exec_trace_config=options.exec_trace_config, + txn_groups=[] + ) if options else None + result = self.atc.simulate(self.app_client.algod_client, request) + return result + + def execute(self) -> AtomicTransactionResponse: + return self.app_client.execute_atc(self.atc) + + def contains_local_data( + self, + *, + for_account: str | bytes, + transaction_parameters: algokit_utils.TransactionParameters | None = None, + ) -> "Composer": + """Adds a call to `contains_local_data(account)bool` ABI method + + :param str | bytes for_account: The `for_account` ABI parameter + :param algokit_utils.TransactionParameters transaction_parameters: (optional) Additional transaction parameters + :returns Composer: This Composer instance""" + + args = ContainsLocalDataArgs( + for_account=for_account, + ) + self.app_client.compose_call( + self.atc, + call_abi_method=args.method(), + transaction_parameters=_convert_call_transaction_parameters(transaction_parameters), + **_as_dict(args, convert_all=True), + ) + return self + + def contains_local_data_example( + self, + *, + for_account: str | bytes, + transaction_parameters: algokit_utils.TransactionParameters | None = None, + ) -> "Composer": + """Adds a call to `contains_local_data_example(account)bool` ABI method + + :param str | bytes for_account: The `for_account` ABI parameter + :param algokit_utils.TransactionParameters transaction_parameters: (optional) Additional transaction parameters + :returns Composer: This Composer instance""" + + args = ContainsLocalDataExampleArgs( + for_account=for_account, + ) + self.app_client.compose_call( + self.atc, + call_abi_method=args.method(), + transaction_parameters=_convert_call_transaction_parameters(transaction_parameters), + **_as_dict(args, convert_all=True), + ) + return self + + def delete_local_data( + self, + *, + for_account: str | bytes, + transaction_parameters: algokit_utils.TransactionParameters | None = None, + ) -> "Composer": + """Adds a call to `delete_local_data(account)void` ABI method + + :param str | bytes for_account: The `for_account` ABI parameter + :param algokit_utils.TransactionParameters transaction_parameters: (optional) Additional transaction parameters + :returns Composer: This Composer instance""" + + args = DeleteLocalDataArgs( + for_account=for_account, + ) + self.app_client.compose_call( + self.atc, + call_abi_method=args.method(), + transaction_parameters=_convert_call_transaction_parameters(transaction_parameters), + **_as_dict(args, convert_all=True), + ) + return self + + def delete_local_data_example( + self, + *, + for_account: str | bytes, + transaction_parameters: algokit_utils.TransactionParameters | None = None, + ) -> "Composer": + """Adds a call to `delete_local_data_example(account)bool` ABI method + + :param str | bytes for_account: The `for_account` ABI parameter + :param algokit_utils.TransactionParameters transaction_parameters: (optional) Additional transaction parameters + :returns Composer: This Composer instance""" + + args = DeleteLocalDataExampleArgs( + for_account=for_account, + ) + self.app_client.compose_call( + self.atc, + call_abi_method=args.method(), + transaction_parameters=_convert_call_transaction_parameters(transaction_parameters), + **_as_dict(args, convert_all=True), + ) + return self + + def get_item_local_data( + self, + *, + for_account: str | bytes, + transaction_parameters: algokit_utils.TransactionParameters | None = None, + ) -> "Composer": + """Adds a call to `get_item_local_data(account)uint64` ABI method + + :param str | bytes for_account: The `for_account` ABI parameter + :param algokit_utils.TransactionParameters transaction_parameters: (optional) Additional transaction parameters + :returns Composer: This Composer instance""" + + args = GetItemLocalDataArgs( + for_account=for_account, + ) + self.app_client.compose_call( + self.atc, + call_abi_method=args.method(), + transaction_parameters=_convert_call_transaction_parameters(transaction_parameters), + **_as_dict(args, convert_all=True), + ) + return self + + def get_item_local_data_example( + self, + *, + for_account: str | bytes, + transaction_parameters: algokit_utils.TransactionParameters | None = None, + ) -> "Composer": + """Adds a call to `get_item_local_data_example(account)bool` ABI method + + :param str | bytes for_account: The `for_account` ABI parameter + :param algokit_utils.TransactionParameters transaction_parameters: (optional) Additional transaction parameters + :returns Composer: This Composer instance""" + + args = GetItemLocalDataExampleArgs( + for_account=for_account, + ) + self.app_client.compose_call( + self.atc, + call_abi_method=args.method(), + transaction_parameters=_convert_call_transaction_parameters(transaction_parameters), + **_as_dict(args, convert_all=True), + ) + return self + + def set_local_int( + self, + *, + for_account: str | bytes, + value: int, + transaction_parameters: algokit_utils.TransactionParameters | None = None, + ) -> "Composer": + """Adds a call to `set_local_int(account,uint64)void` ABI method + + :param str | bytes for_account: The `for_account` ABI parameter + :param int value: The `value` ABI parameter + :param algokit_utils.TransactionParameters transaction_parameters: (optional) Additional transaction parameters + :returns Composer: This Composer instance""" + + args = SetLocalIntArgs( + for_account=for_account, + value=value, + ) + self.app_client.compose_call( + self.atc, + call_abi_method=args.method(), + transaction_parameters=_convert_call_transaction_parameters(transaction_parameters), + **_as_dict(args, convert_all=True), + ) + return self + + def set_local_data_example( + self, + *, + for_account: str | bytes, + value_asset: int, + value_account: str | bytes, + value_appln: int, + value_byte: bytes | bytearray, + value_bool: bool, + transaction_parameters: algokit_utils.TransactionParameters | None = None, + ) -> "Composer": + """Adds a call to `set_local_data_example(account,asset,account,application,byte[],bool)bool` ABI method + + :param str | bytes for_account: The `for_account` ABI parameter + :param int value_asset: The `value_asset` ABI parameter + :param str | bytes value_account: The `value_account` ABI parameter + :param int value_appln: The `value_appln` ABI parameter + :param bytes | bytearray value_byte: The `value_byte` ABI parameter + :param bool value_bool: The `value_bool` ABI parameter + :param algokit_utils.TransactionParameters transaction_parameters: (optional) Additional transaction parameters + :returns Composer: This Composer instance""" + + args = SetLocalDataExampleArgs( + for_account=for_account, + value_asset=value_asset, + value_account=value_account, + value_appln=value_appln, + value_byte=value_byte, + value_bool=value_bool, + ) + self.app_client.compose_call( + self.atc, + call_abi_method=args.method(), + transaction_parameters=_convert_call_transaction_parameters(transaction_parameters), + **_as_dict(args, convert_all=True), + ) + return self + + def get_local_data_with_default_int( + self, + *, + for_account: str | bytes, + transaction_parameters: algokit_utils.TransactionParameters | None = None, + ) -> "Composer": + """Adds a call to `get_local_data_with_default_int(account)uint64` ABI method + + :param str | bytes for_account: The `for_account` ABI parameter + :param algokit_utils.TransactionParameters transaction_parameters: (optional) Additional transaction parameters + :returns Composer: This Composer instance""" + + args = GetLocalDataWithDefaultIntArgs( + for_account=for_account, + ) + self.app_client.compose_call( + self.atc, + call_abi_method=args.method(), + transaction_parameters=_convert_call_transaction_parameters(transaction_parameters), + **_as_dict(args, convert_all=True), + ) + return self + + def get_local_data_with_default( + self, + *, + for_account: str | bytes, + transaction_parameters: algokit_utils.TransactionParameters | None = None, + ) -> "Composer": + """Adds a call to `get_local_data_with_default(account)bool` ABI method + + :param str | bytes for_account: The `for_account` ABI parameter + :param algokit_utils.TransactionParameters transaction_parameters: (optional) Additional transaction parameters + :returns Composer: This Composer instance""" + + args = GetLocalDataWithDefaultArgs( + for_account=for_account, + ) + self.app_client.compose_call( + self.atc, + call_abi_method=args.method(), + transaction_parameters=_convert_call_transaction_parameters(transaction_parameters), + **_as_dict(args, convert_all=True), + ) + return self + + def maybe_local_data( + self, + *, + for_account: str | bytes, + transaction_parameters: algokit_utils.TransactionParameters | None = None, + ) -> "Composer": + """Adds a call to `maybe_local_data(account)(uint64,bool)` ABI method + + :param str | bytes for_account: The `for_account` ABI parameter + :param algokit_utils.TransactionParameters transaction_parameters: (optional) Additional transaction parameters + :returns Composer: This Composer instance""" + + args = MaybeLocalDataArgs( + for_account=for_account, + ) + self.app_client.compose_call( + self.atc, + call_abi_method=args.method(), + transaction_parameters=_convert_call_transaction_parameters(transaction_parameters), + **_as_dict(args, convert_all=True), + ) + return self + + def maybe_local_data_example( + self, + *, + for_account: str | bytes, + transaction_parameters: algokit_utils.TransactionParameters | None = None, + ) -> "Composer": + """Adds a call to `maybe_local_data_example(account)bool` ABI method + + :param str | bytes for_account: The `for_account` ABI parameter + :param algokit_utils.TransactionParameters transaction_parameters: (optional) Additional transaction parameters + :returns Composer: This Composer instance""" + + args = MaybeLocalDataExampleArgs( + for_account=for_account, + ) + self.app_client.compose_call( + self.atc, + call_abi_method=args.method(), + transaction_parameters=_convert_call_transaction_parameters(transaction_parameters), + **_as_dict(args, convert_all=True), + ) + return self + + def create_bare( + self, + *, + on_complete: typing.Literal["no_op"] = "no_op", + transaction_parameters: algokit_utils.CreateTransactionParameters | None = None, + ) -> "Composer": + """Adds a call to create an application using the no_op bare method + + :param typing.Literal[no_op] on_complete: On completion type to use + :param algokit_utils.CreateTransactionParameters transaction_parameters: (optional) Additional transaction parameters + :returns Composer: This Composer instance""" + + self.app_client.compose_create( + self.atc, + call_abi_method=False, + transaction_parameters=_convert_create_transaction_parameters(transaction_parameters, on_complete), + ) + return self + + def clear_state( + self, + transaction_parameters: algokit_utils.TransactionParameters | None = None, + app_args: list[bytes] | None = None, + ) -> "Composer": + """Adds a call to the application with on completion set to ClearState + + :param algokit_utils.TransactionParameters transaction_parameters: (optional) Additional transaction parameters + :param list[bytes] | None app_args: (optional) Application args to pass""" + + self.app_client.compose_clear_state(self.atc, _convert_transaction_parameters(transaction_parameters), app_args) + return self + + +class LocalStorageClient: + """A class for interacting with the LocalStorage app providing high productivity and + strongly typed methods to deploy and call the app""" + + @typing.overload + def __init__( + self, + algod_client: algosdk.v2client.algod.AlgodClient, + *, + app_id: int = 0, + signer: TransactionSigner | algokit_utils.Account | None = None, + sender: str | None = None, + suggested_params: algosdk.transaction.SuggestedParams | None = None, + template_values: algokit_utils.TemplateValueMapping | None = None, + app_name: str | None = None, + ) -> None: + ... + + @typing.overload + def __init__( + self, + algod_client: algosdk.v2client.algod.AlgodClient, + *, + creator: str | algokit_utils.Account, + indexer_client: algosdk.v2client.indexer.IndexerClient | None = None, + existing_deployments: algokit_utils.AppLookup | None = None, + signer: TransactionSigner | algokit_utils.Account | None = None, + sender: str | None = None, + suggested_params: algosdk.transaction.SuggestedParams | None = None, + template_values: algokit_utils.TemplateValueMapping | None = None, + app_name: str | None = None, + ) -> None: + ... + + def __init__( + self, + algod_client: algosdk.v2client.algod.AlgodClient, + *, + creator: str | algokit_utils.Account | None = None, + indexer_client: algosdk.v2client.indexer.IndexerClient | None = None, + existing_deployments: algokit_utils.AppLookup | None = None, + app_id: int = 0, + signer: TransactionSigner | algokit_utils.Account | None = None, + sender: str | None = None, + suggested_params: algosdk.transaction.SuggestedParams | None = None, + template_values: algokit_utils.TemplateValueMapping | None = None, + app_name: str | None = None, + ) -> None: + """ + LocalStorageClient can be created with an app_id to interact with an existing application, alternatively + it can be created with a creator and indexer_client specified to find existing applications by name and creator. + + :param AlgodClient algod_client: AlgoSDK algod client + :param int app_id: The app_id of an existing application, to instead find the application by creator and name + use the creator and indexer_client parameters + :param str | Account creator: The address or Account of the app creator to resolve the app_id + :param IndexerClient indexer_client: AlgoSDK indexer client, only required if deploying or finding app_id by + creator and app name + :param AppLookup existing_deployments: + :param TransactionSigner | Account signer: Account or signer to use to sign transactions, if not specified and + creator was passed as an Account will use that. + :param str sender: Address to use as the sender for all transactions, will use the address associated with the + signer if not specified. + :param TemplateValueMapping template_values: Values to use for TMPL_* template variables, dictionary keys should + *NOT* include the TMPL_ prefix + :param str | None app_name: Name of application to use when deploying, defaults to name defined on the + Application Specification + """ + + self.app_spec = APP_SPEC + + # calling full __init__ signature, so ignoring mypy warning about overloads + self.app_client = algokit_utils.ApplicationClient( # type: ignore[call-overload, misc] + algod_client=algod_client, + app_spec=self.app_spec, + app_id=app_id, + creator=creator, + indexer_client=indexer_client, + existing_deployments=existing_deployments, + signer=signer, + sender=sender, + suggested_params=suggested_params, + template_values=template_values, + app_name=app_name, + ) + + @property + def algod_client(self) -> algosdk.v2client.algod.AlgodClient: + return self.app_client.algod_client + + @property + def app_id(self) -> int: + return self.app_client.app_id + + @app_id.setter + def app_id(self, value: int) -> None: + self.app_client.app_id = value + + @property + def app_address(self) -> str: + return self.app_client.app_address + + @property + def sender(self) -> str | None: + return self.app_client.sender + + @sender.setter + def sender(self, value: str) -> None: + self.app_client.sender = value + + @property + def signer(self) -> TransactionSigner | None: + return self.app_client.signer + + @signer.setter + def signer(self, value: TransactionSigner) -> None: + self.app_client.signer = value + + @property + def suggested_params(self) -> algosdk.transaction.SuggestedParams | None: + return self.app_client.suggested_params + + @suggested_params.setter + def suggested_params(self, value: algosdk.transaction.SuggestedParams | None) -> None: + self.app_client.suggested_params = value + + def get_local_state(self, account: str | None = None) -> LocalState: + """Returns the application's local state wrapped in a strongly typed class with options to format the stored value""" + + state = typing.cast(dict[bytes, bytes | int], self.app_client.get_local_state(account, raw=True)) + return LocalState(state) + + def contains_local_data( + self, + *, + for_account: str | bytes, + transaction_parameters: algokit_utils.TransactionParameters | None = None, + ) -> algokit_utils.ABITransactionResponse[bool]: + """Calls `contains_local_data(account)bool` ABI method + + :param str | bytes for_account: The `for_account` ABI parameter + :param algokit_utils.TransactionParameters transaction_parameters: (optional) Additional transaction parameters + :returns algokit_utils.ABITransactionResponse[bool]: The result of the transaction""" + + args = ContainsLocalDataArgs( + for_account=for_account, + ) + result = self.app_client.call( + call_abi_method=args.method(), + transaction_parameters=_convert_call_transaction_parameters(transaction_parameters), + **_as_dict(args, convert_all=True), + ) + return result + + def contains_local_data_example( + self, + *, + for_account: str | bytes, + transaction_parameters: algokit_utils.TransactionParameters | None = None, + ) -> algokit_utils.ABITransactionResponse[bool]: + """Calls `contains_local_data_example(account)bool` ABI method + + :param str | bytes for_account: The `for_account` ABI parameter + :param algokit_utils.TransactionParameters transaction_parameters: (optional) Additional transaction parameters + :returns algokit_utils.ABITransactionResponse[bool]: The result of the transaction""" + + args = ContainsLocalDataExampleArgs( + for_account=for_account, + ) + result = self.app_client.call( + call_abi_method=args.method(), + transaction_parameters=_convert_call_transaction_parameters(transaction_parameters), + **_as_dict(args, convert_all=True), + ) + return result + + def delete_local_data( + self, + *, + for_account: str | bytes, + transaction_parameters: algokit_utils.TransactionParameters | None = None, + ) -> algokit_utils.ABITransactionResponse[None]: + """Calls `delete_local_data(account)void` ABI method + + :param str | bytes for_account: The `for_account` ABI parameter + :param algokit_utils.TransactionParameters transaction_parameters: (optional) Additional transaction parameters + :returns algokit_utils.ABITransactionResponse[None]: The result of the transaction""" + + args = DeleteLocalDataArgs( + for_account=for_account, + ) + result = self.app_client.call( + call_abi_method=args.method(), + transaction_parameters=_convert_call_transaction_parameters(transaction_parameters), + **_as_dict(args, convert_all=True), + ) + return result + + def delete_local_data_example( + self, + *, + for_account: str | bytes, + transaction_parameters: algokit_utils.TransactionParameters | None = None, + ) -> algokit_utils.ABITransactionResponse[bool]: + """Calls `delete_local_data_example(account)bool` ABI method + + :param str | bytes for_account: The `for_account` ABI parameter + :param algokit_utils.TransactionParameters transaction_parameters: (optional) Additional transaction parameters + :returns algokit_utils.ABITransactionResponse[bool]: The result of the transaction""" + + args = DeleteLocalDataExampleArgs( + for_account=for_account, + ) + result = self.app_client.call( + call_abi_method=args.method(), + transaction_parameters=_convert_call_transaction_parameters(transaction_parameters), + **_as_dict(args, convert_all=True), + ) + return result + + def get_item_local_data( + self, + *, + for_account: str | bytes, + transaction_parameters: algokit_utils.TransactionParameters | None = None, + ) -> algokit_utils.ABITransactionResponse[int]: + """Calls `get_item_local_data(account)uint64` ABI method + + :param str | bytes for_account: The `for_account` ABI parameter + :param algokit_utils.TransactionParameters transaction_parameters: (optional) Additional transaction parameters + :returns algokit_utils.ABITransactionResponse[int]: The result of the transaction""" + + args = GetItemLocalDataArgs( + for_account=for_account, + ) + result = self.app_client.call( + call_abi_method=args.method(), + transaction_parameters=_convert_call_transaction_parameters(transaction_parameters), + **_as_dict(args, convert_all=True), + ) + return result + + def get_item_local_data_example( + self, + *, + for_account: str | bytes, + transaction_parameters: algokit_utils.TransactionParameters | None = None, + ) -> algokit_utils.ABITransactionResponse[bool]: + """Calls `get_item_local_data_example(account)bool` ABI method + + :param str | bytes for_account: The `for_account` ABI parameter + :param algokit_utils.TransactionParameters transaction_parameters: (optional) Additional transaction parameters + :returns algokit_utils.ABITransactionResponse[bool]: The result of the transaction""" + + args = GetItemLocalDataExampleArgs( + for_account=for_account, + ) + result = self.app_client.call( + call_abi_method=args.method(), + transaction_parameters=_convert_call_transaction_parameters(transaction_parameters), + **_as_dict(args, convert_all=True), + ) + return result + + def set_local_int( + self, + *, + for_account: str | bytes, + value: int, + transaction_parameters: algokit_utils.TransactionParameters | None = None, + ) -> algokit_utils.ABITransactionResponse[None]: + """Calls `set_local_int(account,uint64)void` ABI method + + :param str | bytes for_account: The `for_account` ABI parameter + :param int value: The `value` ABI parameter + :param algokit_utils.TransactionParameters transaction_parameters: (optional) Additional transaction parameters + :returns algokit_utils.ABITransactionResponse[None]: The result of the transaction""" + + args = SetLocalIntArgs( + for_account=for_account, + value=value, + ) + result = self.app_client.call( + call_abi_method=args.method(), + transaction_parameters=_convert_call_transaction_parameters(transaction_parameters), + **_as_dict(args, convert_all=True), + ) + return result + + def set_local_data_example( + self, + *, + for_account: str | bytes, + value_asset: int, + value_account: str | bytes, + value_appln: int, + value_byte: bytes | bytearray, + value_bool: bool, + transaction_parameters: algokit_utils.TransactionParameters | None = None, + ) -> algokit_utils.ABITransactionResponse[bool]: + """Calls `set_local_data_example(account,asset,account,application,byte[],bool)bool` ABI method + + :param str | bytes for_account: The `for_account` ABI parameter + :param int value_asset: The `value_asset` ABI parameter + :param str | bytes value_account: The `value_account` ABI parameter + :param int value_appln: The `value_appln` ABI parameter + :param bytes | bytearray value_byte: The `value_byte` ABI parameter + :param bool value_bool: The `value_bool` ABI parameter + :param algokit_utils.TransactionParameters transaction_parameters: (optional) Additional transaction parameters + :returns algokit_utils.ABITransactionResponse[bool]: The result of the transaction""" + + args = SetLocalDataExampleArgs( + for_account=for_account, + value_asset=value_asset, + value_account=value_account, + value_appln=value_appln, + value_byte=value_byte, + value_bool=value_bool, + ) + result = self.app_client.call( + call_abi_method=args.method(), + transaction_parameters=_convert_call_transaction_parameters(transaction_parameters), + **_as_dict(args, convert_all=True), + ) + return result + + def get_local_data_with_default_int( + self, + *, + for_account: str | bytes, + transaction_parameters: algokit_utils.TransactionParameters | None = None, + ) -> algokit_utils.ABITransactionResponse[int]: + """Calls `get_local_data_with_default_int(account)uint64` ABI method + + :param str | bytes for_account: The `for_account` ABI parameter + :param algokit_utils.TransactionParameters transaction_parameters: (optional) Additional transaction parameters + :returns algokit_utils.ABITransactionResponse[int]: The result of the transaction""" + + args = GetLocalDataWithDefaultIntArgs( + for_account=for_account, + ) + result = self.app_client.call( + call_abi_method=args.method(), + transaction_parameters=_convert_call_transaction_parameters(transaction_parameters), + **_as_dict(args, convert_all=True), + ) + return result + + def get_local_data_with_default( + self, + *, + for_account: str | bytes, + transaction_parameters: algokit_utils.TransactionParameters | None = None, + ) -> algokit_utils.ABITransactionResponse[bool]: + """Calls `get_local_data_with_default(account)bool` ABI method + + :param str | bytes for_account: The `for_account` ABI parameter + :param algokit_utils.TransactionParameters transaction_parameters: (optional) Additional transaction parameters + :returns algokit_utils.ABITransactionResponse[bool]: The result of the transaction""" + + args = GetLocalDataWithDefaultArgs( + for_account=for_account, + ) + result = self.app_client.call( + call_abi_method=args.method(), + transaction_parameters=_convert_call_transaction_parameters(transaction_parameters), + **_as_dict(args, convert_all=True), + ) + return result + + def maybe_local_data( + self, + *, + for_account: str | bytes, + transaction_parameters: algokit_utils.TransactionParameters | None = None, + ) -> algokit_utils.ABITransactionResponse[tuple[int, bool]]: + """Calls `maybe_local_data(account)(uint64,bool)` ABI method + + :param str | bytes for_account: The `for_account` ABI parameter + :param algokit_utils.TransactionParameters transaction_parameters: (optional) Additional transaction parameters + :returns algokit_utils.ABITransactionResponse[tuple[int, bool]]: The result of the transaction""" + + args = MaybeLocalDataArgs( + for_account=for_account, + ) + result = self.app_client.call( + call_abi_method=args.method(), + transaction_parameters=_convert_call_transaction_parameters(transaction_parameters), + **_as_dict(args, convert_all=True), + ) + return result + + def maybe_local_data_example( + self, + *, + for_account: str | bytes, + transaction_parameters: algokit_utils.TransactionParameters | None = None, + ) -> algokit_utils.ABITransactionResponse[bool]: + """Calls `maybe_local_data_example(account)bool` ABI method + + :param str | bytes for_account: The `for_account` ABI parameter + :param algokit_utils.TransactionParameters transaction_parameters: (optional) Additional transaction parameters + :returns algokit_utils.ABITransactionResponse[bool]: The result of the transaction""" + + args = MaybeLocalDataExampleArgs( + for_account=for_account, + ) + result = self.app_client.call( + call_abi_method=args.method(), + transaction_parameters=_convert_call_transaction_parameters(transaction_parameters), + **_as_dict(args, convert_all=True), + ) + return result + + def create_bare( + self, + *, + on_complete: typing.Literal["no_op"] = "no_op", + transaction_parameters: algokit_utils.CreateTransactionParameters | None = None, + ) -> algokit_utils.TransactionResponse: + """Creates an application using the no_op bare method + + :param typing.Literal[no_op] on_complete: On completion type to use + :param algokit_utils.CreateTransactionParameters transaction_parameters: (optional) Additional transaction parameters + :returns algokit_utils.TransactionResponse: The result of the transaction""" + + result = self.app_client.create( + call_abi_method=False, + transaction_parameters=_convert_create_transaction_parameters(transaction_parameters, on_complete), + ) + return result + + def clear_state( + self, + transaction_parameters: algokit_utils.TransactionParameters | None = None, + app_args: list[bytes] | None = None, + ) -> algokit_utils.TransactionResponse: + """Calls the application with on completion set to ClearState + + :param algokit_utils.TransactionParameters transaction_parameters: (optional) Additional transaction parameters + :param list[bytes] | None app_args: (optional) Application args to pass + :returns algokit_utils.TransactionResponse: The result of the transaction""" + + return self.app_client.clear_state(_convert_transaction_parameters(transaction_parameters), app_args) + + def deploy( + self, + version: str | None = None, + *, + signer: TransactionSigner | None = None, + sender: str | None = None, + allow_update: bool | None = None, + allow_delete: bool | None = None, + on_update: algokit_utils.OnUpdate = algokit_utils.OnUpdate.Fail, + on_schema_break: algokit_utils.OnSchemaBreak = algokit_utils.OnSchemaBreak.Fail, + template_values: algokit_utils.TemplateValueMapping | None = None, + create_args: algokit_utils.DeployCallArgs | None = None, + update_args: algokit_utils.DeployCallArgs | None = None, + delete_args: algokit_utils.DeployCallArgs | None = None, + ) -> algokit_utils.DeployResponse: + """Deploy an application and update client to reference it. + + Idempotently deploy (create, update/delete if changed) an app against the given name via the given creator + account, including deploy-time template placeholder substitutions. + To understand the architecture decisions behind this functionality please see + + + ```{note} + If there is a breaking state schema change to an existing app (and `on_schema_break` is set to + 'ReplaceApp' the existing app will be deleted and re-created. + ``` + + ```{note} + If there is an update (different TEAL code) to an existing app (and `on_update` is set to 'ReplaceApp') + the existing app will be deleted and re-created. + ``` + + :param str version: version to use when creating or updating app, if None version will be auto incremented + :param algosdk.atomic_transaction_composer.TransactionSigner signer: signer to use when deploying app + , if None uses self.signer + :param str sender: sender address to use when deploying app, if None uses self.sender + :param bool allow_delete: Used to set the `TMPL_DELETABLE` template variable to conditionally control if an app + can be deleted + :param bool allow_update: Used to set the `TMPL_UPDATABLE` template variable to conditionally control if an app + can be updated + :param OnUpdate on_update: Determines what action to take if an application update is required + :param OnSchemaBreak on_schema_break: Determines what action to take if an application schema requirements + has increased beyond the current allocation + :param dict[str, int|str|bytes] template_values: Values to use for `TMPL_*` template variables, dictionary keys + should *NOT* include the TMPL_ prefix + :param algokit_utils.DeployCallArgs | None create_args: Arguments used when creating an application + :param algokit_utils.DeployCallArgs | None update_args: Arguments used when updating an application + :param algokit_utils.DeployCallArgs | None delete_args: Arguments used when deleting an application + :return DeployResponse: details action taken and relevant transactions + :raises DeploymentError: If the deployment failed""" + + return self.app_client.deploy( + version, + signer=signer, + sender=sender, + allow_update=allow_update, + allow_delete=allow_delete, + on_update=on_update, + on_schema_break=on_schema_break, + template_values=template_values, + create_args=_convert_deploy_args(create_args), + update_args=_convert_deploy_args(update_args), + delete_args=_convert_deploy_args(delete_args), + ) + + def compose(self, atc: AtomicTransactionComposer | None = None) -> Composer: + return Composer(self.app_client, atc or AtomicTransactionComposer())