From 43ffb174f0030f6a7907c6e634aa8f0612cb4b65 Mon Sep 17 00:00:00 2001 From: D3stinn3 Date: Thu, 24 Apr 2025 15:07:19 +0300 Subject: [PATCH 1/2] Workshop submission with GitHub box and deployment --- .../PersonalBank.approval.puya.map | 487 +++++++++++++----- .../personal_bank/PersonalBank.approval.teal | 103 ++-- .../personal_bank/PersonalBank.arc56.json | 62 ++- .../personal_bank/personal_bank_client.py | 127 ++++- .../smart_contracts/personal_bank/contract.py | 15 +- 5 files changed, 583 insertions(+), 211 deletions(-) diff --git a/projects/algorand-python-workshop/smart_contracts/artifacts/personal_bank/PersonalBank.approval.puya.map b/projects/algorand-python-workshop/smart_contracts/artifacts/personal_bank/PersonalBank.approval.puya.map index 083cebc..d6139b5 100644 --- a/projects/algorand-python-workshop/smart_contracts/artifacts/personal_bank/PersonalBank.approval.puya.map +++ b/projects/algorand-python-workshop/smart_contracts/artifacts/personal_bank/PersonalBank.approval.puya.map @@ -3,7 +3,7 @@ "sources": [ "../../personal_bank/contract.py" ], - "mappings": ";;;;;;;;;;;;AAIA;;AAAA;;;AAAA;;;;;;;;;;;;AAAA;;;AAAA;;;;;;AAAA;;AAqCK;;AAAA;AAAA;AAAA;;AAAA;AAAA;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AA3BA;;AAAA;AAAA;AAAA;;AAAA;AAVL;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAUK;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAVL;;AAAA;;;;;;;;;AAUA;;;AAcY;;AAAA;;AAAoB;;AAApB;AADJ;AAGO;;AAAA;;AAAA;AAAP;AAE+C;;AAAA;;AAAA;AAAtB;AAAA;;AAEjC;;;AACY;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAIG;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAP;;AAAA;AAFI;;AAAA;AAAA;;AAAA;AAAA;;;;AAc2C;;AAAtB;AAAA;AAAA;AACzB;AAAA;AAES;AACI;;;;;;AADJ;;;AAGD;;;AAHC;;;AAMO;;AAAc;AAA9B;AAAA;AAEA", + "mappings": ";;;;;;;;;;;;;;;;;;;AAIA;;AAAA;;;AAAA;;;;;;;;;;;;;;;;;AAAA;;;AAAA;;;;;;;;AAAA;;AAmEK;;AAAA;AAAA;AAAA;;AAAA;AAAA;;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAvBA;;AAAA;AAAA;AAAA;;AAAA;AAAA;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AA7BA;;AAAA;AAAA;AAAA;;AAAA;AAfL;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;;AAeK;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAfL;;AAAA;;;;;;;;;AAeA;;;AAcY;;AAAA;;AAAoB;;AAApB;AADJ;AAGO;;AAAA;;AAAA;AAAP;AAE+C;;AAAA;;AAAA;AAAtB;AAAA;;AAEjC;;;AACY;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAIJ;AAAA;;AAAA;AAAA;;AAAA;AAEO;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAP;;AAAA;AAJI;;AAAA;AAAA;;AAAA;AAAA;;;;AAgB2C;;AAAtB;AAAA;AAAA;AACzB;AAAA;AAES;AACI;;;;;;AADJ;;;AAGD;;;AAHC;;;AAMO;;AAAc;AAA9B;AAAA;AAEA;AAIO;AAAA;AAAA;AAAP", "op_pc_offset": 0, "pc_events": { "1": { @@ -14,9 +14,9 @@ "op": "intcblock 1 0" }, "5": { - "op": "bytecblock 0x151f7c75" + "op": "bytecblock 0x151f7c75 0x676974687562" }, - "12": { + "19": { "op": "txn NumAppArgs", "defined_out": [ "tmp%0#2" @@ -25,40 +25,44 @@ "tmp%0#2" ] }, - "14": { - "op": "bz main_bare_routing@7", + "21": { + "op": "bz main_bare_routing@8", "stack_out": [] }, - "17": { - "op": "pushbytess 0x3298e7c0 0x3a395f2b // method \"deposit(pay)uint64\", method \"withdraw()uint64\"", + "24": { + "op": "pushbytess 0xd822ffef 0x3a395f2b 0x62b8318d // method \"deposit(pay,string)uint64\", method \"withdraw()uint64\", method \"get_box()string\"", "defined_out": [ - "Method(deposit(pay)uint64)", + "Method(deposit(pay,string)uint64)", + "Method(get_box()string)", "Method(withdraw()uint64)" ], "stack_out": [ - "Method(deposit(pay)uint64)", - "Method(withdraw()uint64)" + "Method(deposit(pay,string)uint64)", + "Method(withdraw()uint64)", + "Method(get_box()string)" ] }, - "29": { + "41": { "op": "txna ApplicationArgs 0", "defined_out": [ - "Method(deposit(pay)uint64)", + "Method(deposit(pay,string)uint64)", + "Method(get_box()string)", "Method(withdraw()uint64)", "tmp%2#0" ], "stack_out": [ - "Method(deposit(pay)uint64)", + "Method(deposit(pay,string)uint64)", "Method(withdraw()uint64)", + "Method(get_box()string)", "tmp%2#0" ] }, - "32": { - "op": "match main_deposit_route@5 main_withdraw_route@6", + "44": { + "op": "match main_deposit_route@5 main_withdraw_route@6 main_get_box_route@7", "stack_out": [] }, - "38": { - "block": "main_after_if_else@9", + "52": { + "block": "main_after_if_else@10", "stack_in": [], "op": "intc_1 // 0", "defined_out": [ @@ -68,37 +72,116 @@ "tmp%0#1" ] }, - "39": { + "53": { "op": "return", "stack_out": [] }, - "40": { - "block": "main_withdraw_route@6", + "54": { + "block": "main_get_box_route@7", "stack_in": [], "op": "txn OnCompletion", "defined_out": [ - "tmp%9#0" + "tmp%15#0" ], "stack_out": [ - "tmp%9#0" + "tmp%15#0" ] }, - "42": { + "56": { "op": "!", "defined_out": [ - "tmp%10#0" + "tmp%16#0" ], "stack_out": [ - "tmp%10#0" + "tmp%16#0" ] }, - "43": { + "57": { "error": "OnCompletion is not NoOp", "op": "assert // OnCompletion is not NoOp", "stack_out": [] }, - "44": { + "58": { "op": "txn ApplicationID", + "defined_out": [ + "tmp%17#0" + ], + "stack_out": [ + "tmp%17#0" + ] + }, + "60": { + "error": "can only call when not creating", + "op": "assert // can only call when not creating", + "stack_out": [] + }, + "61": { + "callsub": "smart_contracts.personal_bank.contract.PersonalBank.get_box", + "op": "callsub get_box", + "defined_out": [ + "tmp%19#0" + ], + "stack_out": [ + "tmp%19#0" + ] + }, + "64": { + "op": "bytec_0 // 0x151f7c75", + "defined_out": [ + "0x151f7c75", + "tmp%19#0" + ], + "stack_out": [ + "tmp%19#0", + "0x151f7c75" + ] + }, + "65": { + "op": "swap", + "stack_out": [ + "0x151f7c75", + "tmp%19#0" + ] + }, + "66": { + "op": "concat", + "defined_out": [ + "tmp%20#0" + ], + "stack_out": [ + "tmp%20#0" + ] + }, + "67": { + "op": "log", + "stack_out": [] + }, + "68": { + "op": "intc_0 // 1", + "defined_out": [ + "tmp%0#1" + ], + "stack_out": [ + "tmp%0#1" + ] + }, + "69": { + "op": "return", + "stack_out": [] + }, + "70": { + "block": "main_withdraw_route@6", + "stack_in": [], + "op": "txn OnCompletion", + "defined_out": [ + "tmp%10#0" + ], + "stack_out": [ + "tmp%10#0" + ] + }, + "72": { + "op": "!", "defined_out": [ "tmp%11#0" ], @@ -106,12 +189,26 @@ "tmp%11#0" ] }, - "46": { + "73": { + "error": "OnCompletion is not NoOp", + "op": "assert // OnCompletion is not NoOp", + "stack_out": [] + }, + "74": { + "op": "txn ApplicationID", + "defined_out": [ + "tmp%12#0" + ], + "stack_out": [ + "tmp%12#0" + ] + }, + "76": { "error": "can only call when not creating", "op": "assert // can only call when not creating", "stack_out": [] }, - "47": { + "77": { "callsub": "smart_contracts.personal_bank.contract.PersonalBank.withdraw", "op": "callsub withdraw", "defined_out": [ @@ -121,7 +218,7 @@ "to_encode%1#0" ] }, - "50": { + "80": { "op": "itob", "defined_out": [ "val_as_bytes%1#0" @@ -130,7 +227,7 @@ "val_as_bytes%1#0" ] }, - "51": { + "81": { "op": "bytec_0 // 0x151f7c75", "defined_out": [ "0x151f7c75", @@ -141,27 +238,27 @@ "0x151f7c75" ] }, - "52": { + "82": { "op": "swap", "stack_out": [ "0x151f7c75", "val_as_bytes%1#0" ] }, - "53": { + "83": { "op": "concat", "defined_out": [ - "tmp%13#0" + "tmp%14#0" ], "stack_out": [ - "tmp%13#0" + "tmp%14#0" ] }, - "54": { + "84": { "op": "log", "stack_out": [] }, - "55": { + "85": { "op": "intc_0 // 1", "defined_out": [ "tmp%0#1" @@ -170,11 +267,11 @@ "tmp%0#1" ] }, - "56": { + "86": { "op": "return", "stack_out": [] }, - "57": { + "87": { "block": "main_deposit_route@5", "stack_in": [], "op": "txn OnCompletion", @@ -185,7 +282,7 @@ "tmp%3#0" ] }, - "59": { + "89": { "op": "!", "defined_out": [ "tmp%4#0" @@ -194,12 +291,12 @@ "tmp%4#0" ] }, - "60": { + "90": { "error": "OnCompletion is not NoOp", "op": "assert // OnCompletion is not NoOp", "stack_out": [] }, - "61": { + "91": { "op": "txn ApplicationID", "defined_out": [ "tmp%5#0" @@ -208,12 +305,12 @@ "tmp%5#0" ] }, - "63": { + "93": { "error": "can only call when not creating", "op": "assert // can only call when not creating", "stack_out": [] }, - "64": { + "94": { "op": "txn GroupIndex", "defined_out": [ "tmp%7#0" @@ -222,7 +319,7 @@ "tmp%7#0" ] }, - "66": { + "96": { "op": "intc_0 // 1", "defined_out": [ "1", @@ -233,7 +330,7 @@ "1" ] }, - "67": { + "97": { "op": "-", "defined_out": [ "gtxn_idx%0#0" @@ -242,7 +339,7 @@ "gtxn_idx%0#0" ] }, - "68": { + "98": { "op": "dup", "defined_out": [ "gtxn_idx%0#0", @@ -253,7 +350,7 @@ "gtxn_idx%0#0 (copy)" ] }, - "69": { + "99": { "op": "gtxns TypeEnum", "defined_out": [ "gtxn_idx%0#0", @@ -264,7 +361,7 @@ "gtxn_type%0#0" ] }, - "71": { + "101": { "op": "intc_0 // pay", "defined_out": [ "gtxn_idx%0#0", @@ -277,7 +374,7 @@ "pay" ] }, - "72": { + "102": { "op": "==", "defined_out": [ "gtxn_idx%0#0", @@ -288,14 +385,25 @@ "gtxn_type_matches%0#0" ] }, - "73": { + "103": { "error": "transaction type is pay", "op": "assert // transaction type is pay", "stack_out": [ "gtxn_idx%0#0" ] }, - "74": { + "104": { + "op": "txna ApplicationArgs 1", + "defined_out": [ + "gtxn_idx%0#0", + "tmp%8#0" + ], + "stack_out": [ + "gtxn_idx%0#0", + "tmp%8#0" + ] + }, + "107": { "callsub": "smart_contracts.personal_bank.contract.PersonalBank.deposit", "op": "callsub deposit", "defined_out": [ @@ -305,7 +413,7 @@ "to_encode%0#0" ] }, - "77": { + "110": { "op": "itob", "defined_out": [ "val_as_bytes%0#0" @@ -314,7 +422,7 @@ "val_as_bytes%0#0" ] }, - "78": { + "111": { "op": "bytec_0 // 0x151f7c75", "defined_out": [ "0x151f7c75", @@ -325,27 +433,27 @@ "0x151f7c75" ] }, - "79": { + "112": { "op": "swap", "stack_out": [ "0x151f7c75", "val_as_bytes%0#0" ] }, - "80": { + "113": { "op": "concat", "defined_out": [ - "tmp%8#0" + "tmp%9#0" ], "stack_out": [ - "tmp%8#0" + "tmp%9#0" ] }, - "81": { + "114": { "op": "log", "stack_out": [] }, - "82": { + "115": { "op": "intc_0 // 1", "defined_out": [ "tmp%0#1" @@ -354,49 +462,49 @@ "tmp%0#1" ] }, - "83": { + "116": { "op": "return", "stack_out": [] }, - "84": { - "block": "main_bare_routing@7", + "117": { + "block": "main_bare_routing@8", "stack_in": [], "op": "txn OnCompletion", "defined_out": [ - "tmp%14#0" + "tmp%21#0" ], "stack_out": [ - "tmp%14#0" + "tmp%21#0" ] }, - "86": { - "op": "bnz main_after_if_else@9", + "119": { + "op": "bnz main_after_if_else@10", "stack_out": [] }, - "89": { + "122": { "op": "txn ApplicationID", "defined_out": [ - "tmp%15#0" + "tmp%22#0" ], "stack_out": [ - "tmp%15#0" + "tmp%22#0" ] }, - "91": { + "124": { "op": "!", "defined_out": [ - "tmp%16#0" + "tmp%23#0" ], "stack_out": [ - "tmp%16#0" + "tmp%23#0" ] }, - "92": { + "125": { "error": "can only call when creating", "op": "assert // can only call when creating", "stack_out": [] }, - "93": { + "126": { "op": "intc_0 // 1", "defined_out": [ "tmp%0#1" @@ -405,21 +513,22 @@ "tmp%0#1" ] }, - "94": { + "127": { "op": "return", "stack_out": [] }, - "95": { + "128": { "subroutine": "smart_contracts.personal_bank.contract.PersonalBank.deposit", "params": { - "pay_txn#0": "uint64" + "pay_txn#0": "uint64", + "github_handle#0": "bytes" }, "block": "deposit", "stack_in": [], - "op": "proto 1 1" + "op": "proto 2 1" }, - "98": { - "op": "frame_dig -1", + "131": { + "op": "frame_dig -2", "defined_out": [ "pay_txn#0 (copy)" ], @@ -427,7 +536,7 @@ "pay_txn#0 (copy)" ] }, - "100": { + "133": { "op": "gtxns Receiver", "defined_out": [ "tmp%0#0" @@ -436,7 +545,7 @@ "tmp%0#0" ] }, - "102": { + "135": { "op": "global CurrentApplicationAddress", "defined_out": [ "tmp%0#0", @@ -447,7 +556,7 @@ "tmp%1#0" ] }, - "104": { + "137": { "op": "==", "defined_out": [ "tmp%2#0" @@ -456,18 +565,18 @@ "tmp%2#0" ] }, - "105": { + "138": { "error": "Receiver must be the contract address", "op": "assert // Receiver must be the contract address", "stack_out": [] }, - "106": { - "op": "frame_dig -1", + "139": { + "op": "frame_dig -2", "stack_out": [ "pay_txn#0 (copy)" ] }, - "108": { + "141": { "op": "gtxns Amount", "defined_out": [ "tmp%3#0" @@ -476,7 +585,7 @@ "tmp%3#0" ] }, - "110": { + "143": { "op": "dup", "defined_out": [ "tmp%3#0" @@ -486,21 +595,21 @@ "tmp%3#0" ] }, - "111": { + "144": { "error": "Deposit amount must be greater than zero", "op": "assert // Deposit amount must be greater than zero", "stack_out": [ "tmp%3#0" ] }, - "112": { - "op": "frame_dig -1", + "145": { + "op": "frame_dig -2", "stack_out": [ "tmp%3#0", "pay_txn#0 (copy)" ] }, - "114": { + "147": { "op": "gtxns Sender", "defined_out": [ "tmp%3#0", @@ -511,7 +620,7 @@ "tmp%5#0" ] }, - "116": { + "149": { "op": "dup", "defined_out": [ "tmp%3#0", @@ -523,7 +632,7 @@ "tmp%5#0" ] }, - "117": { + "150": { "op": "box_get", "defined_out": [ "deposited#0", @@ -538,7 +647,7 @@ "deposited#0" ] }, - "118": { + "151": { "op": "bury 1", "stack_out": [ "tmp%3#0", @@ -546,14 +655,14 @@ "deposited#0" ] }, - "120": { + "153": { "op": "bz deposit_else_body@2", "stack_out": [ "tmp%3#0", "tmp%5#0" ] }, - "123": { + "156": { "op": "frame_dig 1", "stack_out": [ "tmp%3#0", @@ -561,7 +670,7 @@ "tmp%5#0" ] }, - "125": { + "158": { "op": "dup", "defined_out": [ "tmp%3#0", @@ -575,7 +684,7 @@ "tmp%5#0 (copy)" ] }, - "126": { + "159": { "op": "box_get", "defined_out": [ "maybe_exists%1#0", @@ -591,7 +700,7 @@ "maybe_exists%1#0" ] }, - "127": { + "160": { "op": "swap", "stack_out": [ "tmp%3#0", @@ -601,7 +710,7 @@ "maybe_value%1#0" ] }, - "128": { + "161": { "op": "btoi", "defined_out": [ "maybe_exists%1#0", @@ -617,7 +726,7 @@ "maybe_value_converted%1#0" ] }, - "129": { + "162": { "op": "swap", "stack_out": [ "tmp%3#0", @@ -627,7 +736,7 @@ "maybe_exists%1#0" ] }, - "130": { + "163": { "error": "check self.depositors entry exists", "op": "assert // check self.depositors entry exists", "stack_out": [ @@ -637,7 +746,7 @@ "maybe_value_converted%1#0" ] }, - "131": { + "164": { "op": "frame_dig 0", "stack_out": [ "tmp%3#0", @@ -647,7 +756,7 @@ "tmp%3#0" ] }, - "133": { + "166": { "op": "+", "defined_out": [ "new_box_value%0#0", @@ -661,7 +770,7 @@ "new_box_value%0#0" ] }, - "134": { + "167": { "op": "itob", "defined_out": [ "new_box_value%1#0", @@ -675,19 +784,76 @@ "new_box_value%1#0" ] }, - "135": { + "168": { "op": "box_put", "stack_out": [ "tmp%3#0", "tmp%5#0" ] }, - "136": { + "169": { "block": "deposit_after_if_else@3", "stack_in": [ "tmp%3#0", "tmp%5#0" ], + "op": "bytec_1 // 0x676974687562", + "defined_out": [ + "0x676974687562" + ], + "stack_out": [ + "tmp%3#0", + "tmp%5#0", + "0x676974687562" + ] + }, + "170": { + "op": "box_del", + "defined_out": [ + "{box_del}" + ], + "stack_out": [ + "tmp%3#0", + "tmp%5#0", + "{box_del}" + ] + }, + "171": { + "op": "pop", + "stack_out": [ + "tmp%3#0", + "tmp%5#0" + ] + }, + "172": { + "op": "bytec_1 // 0x676974687562", + "stack_out": [ + "tmp%3#0", + "tmp%5#0", + "0x676974687562" + ] + }, + "173": { + "op": "frame_dig -1", + "defined_out": [ + "0x676974687562", + "github_handle#0 (copy)" + ], + "stack_out": [ + "tmp%3#0", + "tmp%5#0", + "0x676974687562", + "github_handle#0 (copy)" + ] + }, + "175": { + "op": "box_put", + "stack_out": [ + "tmp%3#0", + "tmp%5#0" + ] + }, + "176": { "op": "frame_dig 1", "defined_out": [ "tmp%5#0" @@ -698,7 +864,7 @@ "tmp%5#0" ] }, - "138": { + "178": { "op": "box_get", "defined_out": [ "maybe_exists%2#0", @@ -712,7 +878,7 @@ "maybe_exists%2#0" ] }, - "139": { + "179": { "op": "swap", "stack_out": [ "tmp%3#0", @@ -721,7 +887,7 @@ "maybe_value%2#0" ] }, - "140": { + "180": { "op": "btoi", "defined_out": [ "maybe_exists%2#0", @@ -735,7 +901,7 @@ "maybe_value_converted%2#0" ] }, - "141": { + "181": { "op": "swap", "stack_out": [ "tmp%3#0", @@ -744,7 +910,7 @@ "maybe_exists%2#0" ] }, - "142": { + "182": { "error": "check self.depositors entry exists", "op": "assert // check self.depositors entry exists", "stack_out": [ @@ -753,14 +919,14 @@ "maybe_value_converted%2#0" ] }, - "143": { + "183": { "op": "frame_bury 0" }, - "145": { + "185": { "retsub": true, "op": "retsub" }, - "146": { + "186": { "block": "deposit_else_body@2", "stack_in": [ "tmp%3#0", @@ -776,7 +942,7 @@ "tmp%3#0" ] }, - "148": { + "188": { "op": "itob", "defined_out": [ "new_box_value%3#0", @@ -788,7 +954,7 @@ "new_box_value%3#0" ] }, - "149": { + "189": { "op": "frame_dig 1", "defined_out": [ "new_box_value%3#0", @@ -802,7 +968,7 @@ "tmp%5#0" ] }, - "151": { + "191": { "op": "swap", "stack_out": [ "tmp%3#0", @@ -811,17 +977,17 @@ "new_box_value%3#0" ] }, - "152": { + "192": { "op": "box_put", "stack_out": [ "tmp%3#0", "tmp%5#0" ] }, - "153": { + "193": { "op": "b deposit_after_if_else@3" }, - "156": { + "196": { "subroutine": "smart_contracts.personal_bank.contract.PersonalBank.withdraw", "params": {}, "block": "withdraw", @@ -834,7 +1000,7 @@ "tmp%0#0" ] }, - "158": { + "198": { "op": "box_get", "defined_out": [ "deposited#0", @@ -845,14 +1011,14 @@ "deposited#0" ] }, - "159": { + "199": { "op": "swap", "stack_out": [ "deposited#0", "maybe_value%0#0" ] }, - "160": { + "200": { "op": "btoi", "defined_out": [ "deposit_amt#0", @@ -863,24 +1029,24 @@ "deposit_amt#0" ] }, - "161": { + "201": { "op": "swap", "stack_out": [ "deposit_amt#0", "deposited#0" ] }, - "162": { + "202": { "error": "No deposits found for this account", "op": "assert // No deposits found for this account", "stack_out": [ "deposit_amt#0" ] }, - "163": { + "203": { "op": "itxn_begin" }, - "164": { + "204": { "op": "txn Sender", "defined_out": [ "deposit_amt#0", @@ -891,14 +1057,14 @@ "inner_txn_params%0%%param_Receiver_idx_0#0" ] }, - "166": { + "206": { "op": "itxn_field Receiver" }, - "168": { + "208": { "op": "itxn_field Amount", "stack_out": [] }, - "170": { + "210": { "op": "intc_0 // pay", "defined_out": [ "pay" @@ -907,11 +1073,11 @@ "pay" ] }, - "171": { + "211": { "op": "itxn_field TypeEnum", "stack_out": [] }, - "173": { + "213": { "op": "intc_1 // 0", "defined_out": [ "0" @@ -920,14 +1086,14 @@ "0" ] }, - "174": { + "214": { "op": "itxn_field Fee", "stack_out": [] }, - "176": { + "216": { "op": "itxn_submit" }, - "177": { + "217": { "op": "itxn Amount", "defined_out": [ "result.Amount#0" @@ -936,7 +1102,7 @@ "result.Amount#0" ] }, - "179": { + "219": { "op": "txn Sender", "defined_out": [ "result.Amount#0", @@ -947,7 +1113,7 @@ "tmp%2#0" ] }, - "181": { + "221": { "op": "intc_1 // 0", "stack_out": [ "result.Amount#0", @@ -955,7 +1121,7 @@ "0" ] }, - "182": { + "222": { "op": "itob", "defined_out": [ "new_box_value%0#0", @@ -968,13 +1134,48 @@ "new_box_value%0#0" ] }, - "183": { + "223": { "op": "box_put", "stack_out": [ "result.Amount#0" ] }, - "184": { + "224": { + "retsub": true, + "op": "retsub" + }, + "225": { + "subroutine": "smart_contracts.personal_bank.contract.PersonalBank.get_box", + "params": {}, + "block": "get_box", + "stack_in": [], + "op": "bytec_1 // 0x676974687562", + "defined_out": [ + "0x676974687562" + ], + "stack_out": [ + "0x676974687562" + ] + }, + "226": { + "op": "box_get", + "defined_out": [ + "maybe_exists%0#0", + "maybe_value%0#0" + ], + "stack_out": [ + "maybe_value%0#0", + "maybe_exists%0#0" + ] + }, + "227": { + "error": "check self.github exists", + "op": "assert // check self.github exists", + "stack_out": [ + "maybe_value%0#0" + ] + }, + "228": { "retsub": true, "op": "retsub" } diff --git a/projects/algorand-python-workshop/smart_contracts/artifacts/personal_bank/PersonalBank.approval.teal b/projects/algorand-python-workshop/smart_contracts/artifacts/personal_bank/PersonalBank.approval.teal index 8ae7993..b6d0319 100644 --- a/projects/algorand-python-workshop/smart_contracts/artifacts/personal_bank/PersonalBank.approval.teal +++ b/projects/algorand-python-workshop/smart_contracts/artifacts/personal_bank/PersonalBank.approval.teal @@ -4,23 +4,39 @@ // smart_contracts.personal_bank.contract.PersonalBank.__algopy_entrypoint_with_init() -> uint64: main: intcblock 1 0 - bytecblock 0x151f7c75 + bytecblock 0x151f7c75 0x676974687562 // smart_contracts/personal_bank/contract.py:5 // class PersonalBank(ARC4Contract): txn NumAppArgs - bz main_bare_routing@7 - pushbytess 0x3298e7c0 0x3a395f2b // method "deposit(pay)uint64", method "withdraw()uint64" + bz main_bare_routing@8 + pushbytess 0xd822ffef 0x3a395f2b 0x62b8318d // method "deposit(pay,string)uint64", method "withdraw()uint64", method "get_box()string" txna ApplicationArgs 0 - match main_deposit_route@5 main_withdraw_route@6 + match main_deposit_route@5 main_withdraw_route@6 main_get_box_route@7 -main_after_if_else@9: +main_after_if_else@10: // smart_contracts/personal_bank/contract.py:5 // class PersonalBank(ARC4Contract): intc_1 // 0 return +main_get_box_route@7: + // smart_contracts/personal_bank/contract.py:72 + // @abimethod() + txn OnCompletion + ! + assert // OnCompletion is not NoOp + txn ApplicationID + assert // can only call when not creating + callsub get_box + bytec_0 // 0x151f7c75 + swap + concat + log + intc_0 // 1 + return + main_withdraw_route@6: - // smart_contracts/personal_bank/contract.py:42 + // smart_contracts/personal_bank/contract.py:49 // @abimethod() txn OnCompletion ! @@ -37,7 +53,7 @@ main_withdraw_route@6: return main_deposit_route@5: - // smart_contracts/personal_bank/contract.py:15 + // smart_contracts/personal_bank/contract.py:20 // @abimethod() txn OnCompletion ! @@ -54,7 +70,8 @@ main_deposit_route@5: intc_0 // pay == assert // transaction type is pay - // smart_contracts/personal_bank/contract.py:15 + txna ApplicationArgs 1 + // smart_contracts/personal_bank/contract.py:20 // @abimethod() callsub deposit itob @@ -65,11 +82,11 @@ main_deposit_route@5: intc_0 // 1 return -main_bare_routing@7: +main_bare_routing@8: // smart_contracts/personal_bank/contract.py:5 // class PersonalBank(ARC4Contract): txn OnCompletion - bnz main_after_if_else@9 + bnz main_after_if_else@10 txn ApplicationID ! assert // can only call when creating @@ -77,40 +94,40 @@ main_bare_routing@7: return -// smart_contracts.personal_bank.contract.PersonalBank.deposit(pay_txn: uint64) -> uint64: +// smart_contracts.personal_bank.contract.PersonalBank.deposit(pay_txn: uint64, github_handle: bytes) -> uint64: deposit: - // smart_contracts/personal_bank/contract.py:15-16 + // smart_contracts/personal_bank/contract.py:20-21 // @abimethod() - // def deposit(self, pay_txn: gtxn.PaymentTransaction) -> UInt64: - proto 1 1 - // smart_contracts/personal_bank/contract.py:29 + // def deposit(self, pay_txn: gtxn.PaymentTransaction, github_handle: arc4.String) -> UInt64: + proto 2 1 + // smart_contracts/personal_bank/contract.py:34 // pay_txn.receiver == Global.current_application_address - frame_dig -1 + frame_dig -2 gtxns Receiver global CurrentApplicationAddress == - // smart_contracts/personal_bank/contract.py:28-30 + // smart_contracts/personal_bank/contract.py:33-35 // assert ( // pay_txn.receiver == Global.current_application_address // ), "Receiver must be the contract address" assert // Receiver must be the contract address - // smart_contracts/personal_bank/contract.py:31 + // smart_contracts/personal_bank/contract.py:36 // assert pay_txn.amount > 0, "Deposit amount must be greater than zero" - frame_dig -1 + frame_dig -2 gtxns Amount dup assert // Deposit amount must be greater than zero - // smart_contracts/personal_bank/contract.py:33 + // smart_contracts/personal_bank/contract.py:38 // deposit_amt, deposited = self.depositors.maybe(pay_txn.sender) - frame_dig -1 + frame_dig -2 gtxns Sender dup box_get bury 1 - // smart_contracts/personal_bank/contract.py:35 + // smart_contracts/personal_bank/contract.py:40 // if deposited: bz deposit_else_body@2 - // smart_contracts/personal_bank/contract.py:36 + // smart_contracts/personal_bank/contract.py:41 // self.depositors[pay_txn.sender] += pay_txn.amount frame_dig 1 dup @@ -125,7 +142,15 @@ deposit: box_put deposit_after_if_else@3: - // smart_contracts/personal_bank/contract.py:40 + // smart_contracts/personal_bank/contract.py:45 + // self.github.value = github_handle + bytec_1 // 0x676974687562 + box_del + pop + bytec_1 // 0x676974687562 + frame_dig -1 + box_put + // smart_contracts/personal_bank/contract.py:47 // return self.depositors[pay_txn.sender] frame_dig 1 box_get @@ -137,7 +162,7 @@ deposit_after_if_else@3: retsub deposit_else_body@2: - // smart_contracts/personal_bank/contract.py:38 + // smart_contracts/personal_bank/contract.py:43 // self.depositors[pay_txn.sender] = pay_txn.amount frame_dig 0 itob @@ -149,37 +174,37 @@ deposit_else_body@2: // smart_contracts.personal_bank.contract.PersonalBank.withdraw() -> uint64: withdraw: - // smart_contracts/personal_bank/contract.py:52 + // smart_contracts/personal_bank/contract.py:59 // deposit_amt, deposited = self.depositors.maybe(Txn.sender) txn Sender box_get swap btoi - // smart_contracts/personal_bank/contract.py:53 + // smart_contracts/personal_bank/contract.py:60 // assert deposited, "No deposits found for this account" swap assert // No deposits found for this account - // smart_contracts/personal_bank/contract.py:55-59 + // smart_contracts/personal_bank/contract.py:62-66 // result = itxn.Payment( // receiver=Txn.sender, // amount=deposit_amt, // fee=0, // ).submit() itxn_begin - // smart_contracts/personal_bank/contract.py:56 + // smart_contracts/personal_bank/contract.py:63 // receiver=Txn.sender, txn Sender itxn_field Receiver itxn_field Amount - // smart_contracts/personal_bank/contract.py:55 + // smart_contracts/personal_bank/contract.py:62 // result = itxn.Payment( intc_0 // pay itxn_field TypeEnum - // smart_contracts/personal_bank/contract.py:58 + // smart_contracts/personal_bank/contract.py:65 // fee=0, intc_1 // 0 itxn_field Fee - // smart_contracts/personal_bank/contract.py:55-59 + // smart_contracts/personal_bank/contract.py:62-66 // result = itxn.Payment( // receiver=Txn.sender, // amount=deposit_amt, @@ -187,12 +212,22 @@ withdraw: // ).submit() itxn_submit itxn Amount - // smart_contracts/personal_bank/contract.py:61 + // smart_contracts/personal_bank/contract.py:68 // self.depositors[Txn.sender] = UInt64(0) txn Sender intc_1 // 0 itob box_put - // smart_contracts/personal_bank/contract.py:63 + // smart_contracts/personal_bank/contract.py:70 // return result.amount retsub + + +// smart_contracts.personal_bank.contract.PersonalBank.get_box() -> bytes: +get_box: + // smart_contracts/personal_bank/contract.py:74 + // return self.github.value + bytec_1 // 0x676974687562 + box_get + assert // check self.github exists + retsub diff --git a/projects/algorand-python-workshop/smart_contracts/artifacts/personal_bank/PersonalBank.arc56.json b/projects/algorand-python-workshop/smart_contracts/artifacts/personal_bank/PersonalBank.arc56.json index dfee262..cf54b6c 100644 --- a/projects/algorand-python-workshop/smart_contracts/artifacts/personal_bank/PersonalBank.arc56.json +++ b/projects/algorand-python-workshop/smart_contracts/artifacts/personal_bank/PersonalBank.arc56.json @@ -9,6 +9,10 @@ "type": "pay", "name": "pay_txn", "desc": "The payment transaction containing deposit information" + }, + { + "type": "string", + "name": "github_handle" } ], "returns": { @@ -43,6 +47,22 @@ "desc": "Withdraws all funds from the sender's account\nThis method transfers the entire balance of the sender's account back to them, and resets their balance to zero. The sender must have a deposit to withdraw.", "events": [], "recommendations": {} + }, + { + "name": "get_box", + "args": [], + "returns": { + "type": "string" + }, + "actions": { + "create": [], + "call": [ + "NoOp" + ] + }, + "readonly": false, + "events": [], + "recommendations": {} } ], "arcs": [ @@ -64,7 +84,13 @@ "keys": { "global": {}, "local": {}, - "box": {} + "box": { + "github": { + "keyType": "AVMBytes", + "valueType": "string", + "key": "Z2l0aHVi" + } + } }, "maps": { "global": {}, @@ -89,52 +115,60 @@ "sourceInfo": [ { "pc": [ - 111 + 144 ], "errorMessage": "Deposit amount must be greater than zero" }, { "pc": [ - 162 + 202 ], "errorMessage": "No deposits found for this account" }, { "pc": [ - 43, - 60 + 57, + 73, + 90 ], "errorMessage": "OnCompletion is not NoOp" }, { "pc": [ - 105 + 138 ], "errorMessage": "Receiver must be the contract address" }, { "pc": [ - 92 + 125 ], "errorMessage": "can only call when creating" }, { "pc": [ - 46, - 63 + 60, + 76, + 93 ], "errorMessage": "can only call when not creating" }, { "pc": [ - 130, - 142 + 163, + 182 ], "errorMessage": "check self.depositors entry exists" }, { "pc": [ - 73 + 227 + ], + "errorMessage": "check self.github exists" + }, + { + "pc": [ + 103 ], "errorMessage": "transaction type is pay" } @@ -147,11 +181,11 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCiNwcmFnbWEgdHlwZXRyYWNrIGZhbHNlCgovLyBzbWFydF9jb250cmFjdHMucGVyc29uYWxfYmFuay5jb250cmFjdC5QZXJzb25hbEJhbmsuX19hbGdvcHlfZW50cnlwb2ludF93aXRoX2luaXQoKSAtPiB1aW50NjQ6Cm1haW46CiAgICBpbnRjYmxvY2sgMSAwCiAgICBieXRlY2Jsb2NrIDB4MTUxZjdjNzUKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjUKICAgIC8vIGNsYXNzIFBlcnNvbmFsQmFuayhBUkM0Q29udHJhY3QpOgogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IG1haW5fYmFyZV9yb3V0aW5nQDcKICAgIHB1c2hieXRlc3MgMHgzMjk4ZTdjMCAweDNhMzk1ZjJiIC8vIG1ldGhvZCAiZGVwb3NpdChwYXkpdWludDY0IiwgbWV0aG9kICJ3aXRoZHJhdygpdWludDY0IgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggbWFpbl9kZXBvc2l0X3JvdXRlQDUgbWFpbl93aXRoZHJhd19yb3V0ZUA2CgptYWluX2FmdGVyX2lmX2Vsc2VAOToKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjUKICAgIC8vIGNsYXNzIFBlcnNvbmFsQmFuayhBUkM0Q29udHJhY3QpOgogICAgaW50Y18xIC8vIDAKICAgIHJldHVybgoKbWFpbl93aXRoZHJhd19yb3V0ZUA2OgogICAgLy8gc21hcnRfY29udHJhY3RzL3BlcnNvbmFsX2JhbmsvY29udHJhY3QucHk6NDIKICAgIC8vIEBhYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIHdpdGhkcmF3CiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX2RlcG9zaXRfcm91dGVANToKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjE1CiAgICAvLyBAYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gc21hcnRfY29udHJhY3RzL3BlcnNvbmFsX2JhbmsvY29udHJhY3QucHk6NQogICAgLy8gY2xhc3MgUGVyc29uYWxCYW5rKEFSQzRDb250cmFjdCk6CiAgICB0eG4gR3JvdXBJbmRleAogICAgaW50Y18wIC8vIDEKICAgIC0KICAgIGR1cAogICAgZ3R4bnMgVHlwZUVudW0KICAgIGludGNfMCAvLyBwYXkKICAgID09CiAgICBhc3NlcnQgLy8gdHJhbnNhY3Rpb24gdHlwZSBpcyBwYXkKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjE1CiAgICAvLyBAYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgZGVwb3NpdAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl9iYXJlX3JvdXRpbmdANzoKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjUKICAgIC8vIGNsYXNzIFBlcnNvbmFsQmFuayhBUkM0Q29udHJhY3QpOgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgYm56IG1haW5fYWZ0ZXJfaWZfZWxzZUA5CiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBjcmVhdGluZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5wZXJzb25hbF9iYW5rLmNvbnRyYWN0LlBlcnNvbmFsQmFuay5kZXBvc2l0KHBheV90eG46IHVpbnQ2NCkgLT4gdWludDY0OgpkZXBvc2l0OgogICAgLy8gc21hcnRfY29udHJhY3RzL3BlcnNvbmFsX2JhbmsvY29udHJhY3QucHk6MTUtMTYKICAgIC8vIEBhYmltZXRob2QoKQogICAgLy8gZGVmIGRlcG9zaXQoc2VsZiwgcGF5X3R4bjogZ3R4bi5QYXltZW50VHJhbnNhY3Rpb24pIC0+IFVJbnQ2NDoKICAgIHByb3RvIDEgMQogICAgLy8gc21hcnRfY29udHJhY3RzL3BlcnNvbmFsX2JhbmsvY29udHJhY3QucHk6MjkKICAgIC8vIHBheV90eG4ucmVjZWl2ZXIgPT0gR2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcwogICAgZnJhbWVfZGlnIC0xCiAgICBndHhucyBSZWNlaXZlcgogICAgZ2xvYmFsIEN1cnJlbnRBcHBsaWNhdGlvbkFkZHJlc3MKICAgID09CiAgICAvLyBzbWFydF9jb250cmFjdHMvcGVyc29uYWxfYmFuay9jb250cmFjdC5weToyOC0zMAogICAgLy8gYXNzZXJ0ICgKICAgIC8vICAgICBwYXlfdHhuLnJlY2VpdmVyID09IEdsb2JhbC5jdXJyZW50X2FwcGxpY2F0aW9uX2FkZHJlc3MKICAgIC8vICksICJSZWNlaXZlciBtdXN0IGJlIHRoZSBjb250cmFjdCBhZGRyZXNzIgogICAgYXNzZXJ0IC8vIFJlY2VpdmVyIG11c3QgYmUgdGhlIGNvbnRyYWN0IGFkZHJlc3MKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjMxCiAgICAvLyBhc3NlcnQgcGF5X3R4bi5hbW91bnQgPiAwLCAiRGVwb3NpdCBhbW91bnQgbXVzdCBiZSBncmVhdGVyIHRoYW4gemVybyIKICAgIGZyYW1lX2RpZyAtMQogICAgZ3R4bnMgQW1vdW50CiAgICBkdXAKICAgIGFzc2VydCAvLyBEZXBvc2l0IGFtb3VudCBtdXN0IGJlIGdyZWF0ZXIgdGhhbiB6ZXJvCiAgICAvLyBzbWFydF9jb250cmFjdHMvcGVyc29uYWxfYmFuay9jb250cmFjdC5weTozMwogICAgLy8gZGVwb3NpdF9hbXQsIGRlcG9zaXRlZCA9IHNlbGYuZGVwb3NpdG9ycy5tYXliZShwYXlfdHhuLnNlbmRlcikKICAgIGZyYW1lX2RpZyAtMQogICAgZ3R4bnMgU2VuZGVyCiAgICBkdXAKICAgIGJveF9nZXQKICAgIGJ1cnkgMQogICAgLy8gc21hcnRfY29udHJhY3RzL3BlcnNvbmFsX2JhbmsvY29udHJhY3QucHk6MzUKICAgIC8vIGlmIGRlcG9zaXRlZDoKICAgIGJ6IGRlcG9zaXRfZWxzZV9ib2R5QDIKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjM2CiAgICAvLyBzZWxmLmRlcG9zaXRvcnNbcGF5X3R4bi5zZW5kZXJdICs9IHBheV90eG4uYW1vdW50CiAgICBmcmFtZV9kaWcgMQogICAgZHVwCiAgICBib3hfZ2V0CiAgICBzd2FwCiAgICBidG9pCiAgICBzd2FwCiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5kZXBvc2l0b3JzIGVudHJ5IGV4aXN0cwogICAgZnJhbWVfZGlnIDAKICAgICsKICAgIGl0b2IKICAgIGJveF9wdXQKCmRlcG9zaXRfYWZ0ZXJfaWZfZWxzZUAzOgogICAgLy8gc21hcnRfY29udHJhY3RzL3BlcnNvbmFsX2JhbmsvY29udHJhY3QucHk6NDAKICAgIC8vIHJldHVybiBzZWxmLmRlcG9zaXRvcnNbcGF5X3R4bi5zZW5kZXJdCiAgICBmcmFtZV9kaWcgMQogICAgYm94X2dldAogICAgc3dhcAogICAgYnRvaQogICAgc3dhcAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuZGVwb3NpdG9ycyBlbnRyeSBleGlzdHMKICAgIGZyYW1lX2J1cnkgMAogICAgcmV0c3ViCgpkZXBvc2l0X2Vsc2VfYm9keUAyOgogICAgLy8gc21hcnRfY29udHJhY3RzL3BlcnNvbmFsX2JhbmsvY29udHJhY3QucHk6MzgKICAgIC8vIHNlbGYuZGVwb3NpdG9yc1twYXlfdHhuLnNlbmRlcl0gPSBwYXlfdHhuLmFtb3VudAogICAgZnJhbWVfZGlnIDAKICAgIGl0b2IKICAgIGZyYW1lX2RpZyAxCiAgICBzd2FwCiAgICBib3hfcHV0CiAgICBiIGRlcG9zaXRfYWZ0ZXJfaWZfZWxzZUAzCgoKLy8gc21hcnRfY29udHJhY3RzLnBlcnNvbmFsX2JhbmsuY29udHJhY3QuUGVyc29uYWxCYW5rLndpdGhkcmF3KCkgLT4gdWludDY0Ogp3aXRoZHJhdzoKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjUyCiAgICAvLyBkZXBvc2l0X2FtdCwgZGVwb3NpdGVkID0gc2VsZi5kZXBvc2l0b3JzLm1heWJlKFR4bi5zZW5kZXIpCiAgICB0eG4gU2VuZGVyCiAgICBib3hfZ2V0CiAgICBzd2FwCiAgICBidG9pCiAgICAvLyBzbWFydF9jb250cmFjdHMvcGVyc29uYWxfYmFuay9jb250cmFjdC5weTo1MwogICAgLy8gYXNzZXJ0IGRlcG9zaXRlZCwgIk5vIGRlcG9zaXRzIGZvdW5kIGZvciB0aGlzIGFjY291bnQiCiAgICBzd2FwCiAgICBhc3NlcnQgLy8gTm8gZGVwb3NpdHMgZm91bmQgZm9yIHRoaXMgYWNjb3VudAogICAgLy8gc21hcnRfY29udHJhY3RzL3BlcnNvbmFsX2JhbmsvY29udHJhY3QucHk6NTUtNTkKICAgIC8vIHJlc3VsdCA9IGl0eG4uUGF5bWVudCgKICAgIC8vICAgICByZWNlaXZlcj1UeG4uc2VuZGVyLAogICAgLy8gICAgIGFtb3VudD1kZXBvc2l0X2FtdCwKICAgIC8vICAgICBmZWU9MCwKICAgIC8vICkuc3VibWl0KCkKICAgIGl0eG5fYmVnaW4KICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjU2CiAgICAvLyByZWNlaXZlcj1UeG4uc2VuZGVyLAogICAgdHhuIFNlbmRlcgogICAgaXR4bl9maWVsZCBSZWNlaXZlcgogICAgaXR4bl9maWVsZCBBbW91bnQKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjU1CiAgICAvLyByZXN1bHQgPSBpdHhuLlBheW1lbnQoCiAgICBpbnRjXzAgLy8gcGF5CiAgICBpdHhuX2ZpZWxkIFR5cGVFbnVtCiAgICAvLyBzbWFydF9jb250cmFjdHMvcGVyc29uYWxfYmFuay9jb250cmFjdC5weTo1OAogICAgLy8gZmVlPTAsCiAgICBpbnRjXzEgLy8gMAogICAgaXR4bl9maWVsZCBGZWUKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjU1LTU5CiAgICAvLyByZXN1bHQgPSBpdHhuLlBheW1lbnQoCiAgICAvLyAgICAgcmVjZWl2ZXI9VHhuLnNlbmRlciwKICAgIC8vICAgICBhbW91bnQ9ZGVwb3NpdF9hbXQsCiAgICAvLyAgICAgZmVlPTAsCiAgICAvLyApLnN1Ym1pdCgpCiAgICBpdHhuX3N1Ym1pdAogICAgaXR4biBBbW91bnQKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjYxCiAgICAvLyBzZWxmLmRlcG9zaXRvcnNbVHhuLnNlbmRlcl0gPSBVSW50NjQoMCkKICAgIHR4biBTZW5kZXIKICAgIGludGNfMSAvLyAwCiAgICBpdG9iCiAgICBib3hfcHV0CiAgICAvLyBzbWFydF9jb250cmFjdHMvcGVyc29uYWxfYmFuay9jb250cmFjdC5weTo2MwogICAgLy8gcmV0dXJuIHJlc3VsdC5hbW91bnQKICAgIHJldHN1Ygo=", + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCiNwcmFnbWEgdHlwZXRyYWNrIGZhbHNlCgovLyBzbWFydF9jb250cmFjdHMucGVyc29uYWxfYmFuay5jb250cmFjdC5QZXJzb25hbEJhbmsuX19hbGdvcHlfZW50cnlwb2ludF93aXRoX2luaXQoKSAtPiB1aW50NjQ6Cm1haW46CiAgICBpbnRjYmxvY2sgMSAwCiAgICBieXRlY2Jsb2NrIDB4MTUxZjdjNzUgMHg2NzY5NzQ2ODc1NjIKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjUKICAgIC8vIGNsYXNzIFBlcnNvbmFsQmFuayhBUkM0Q29udHJhY3QpOgogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IG1haW5fYmFyZV9yb3V0aW5nQDgKICAgIHB1c2hieXRlc3MgMHhkODIyZmZlZiAweDNhMzk1ZjJiIDB4NjJiODMxOGQgLy8gbWV0aG9kICJkZXBvc2l0KHBheSxzdHJpbmcpdWludDY0IiwgbWV0aG9kICJ3aXRoZHJhdygpdWludDY0IiwgbWV0aG9kICJnZXRfYm94KClzdHJpbmciCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBtYWluX2RlcG9zaXRfcm91dGVANSBtYWluX3dpdGhkcmF3X3JvdXRlQDYgbWFpbl9nZXRfYm94X3JvdXRlQDcKCm1haW5fYWZ0ZXJfaWZfZWxzZUAxMDoKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjUKICAgIC8vIGNsYXNzIFBlcnNvbmFsQmFuayhBUkM0Q29udHJhY3QpOgogICAgaW50Y18xIC8vIDAKICAgIHJldHVybgoKbWFpbl9nZXRfYm94X3JvdXRlQDc6CiAgICAvLyBzbWFydF9jb250cmFjdHMvcGVyc29uYWxfYmFuay9jb250cmFjdC5weTo3MgogICAgLy8gQGFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgZ2V0X2JveAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl93aXRoZHJhd19yb3V0ZUA2OgogICAgLy8gc21hcnRfY29udHJhY3RzL3BlcnNvbmFsX2JhbmsvY29udHJhY3QucHk6NDkKICAgIC8vIEBhYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIHdpdGhkcmF3CiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX2RlcG9zaXRfcm91dGVANToKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjIwCiAgICAvLyBAYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gc21hcnRfY29udHJhY3RzL3BlcnNvbmFsX2JhbmsvY29udHJhY3QucHk6NQogICAgLy8gY2xhc3MgUGVyc29uYWxCYW5rKEFSQzRDb250cmFjdCk6CiAgICB0eG4gR3JvdXBJbmRleAogICAgaW50Y18wIC8vIDEKICAgIC0KICAgIGR1cAogICAgZ3R4bnMgVHlwZUVudW0KICAgIGludGNfMCAvLyBwYXkKICAgID09CiAgICBhc3NlcnQgLy8gdHJhbnNhY3Rpb24gdHlwZSBpcyBwYXkKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjIwCiAgICAvLyBAYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgZGVwb3NpdAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl9iYXJlX3JvdXRpbmdAODoKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjUKICAgIC8vIGNsYXNzIFBlcnNvbmFsQmFuayhBUkM0Q29udHJhY3QpOgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgYm56IG1haW5fYWZ0ZXJfaWZfZWxzZUAxMAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gY3JlYXRpbmcKICAgIGludGNfMCAvLyAxCiAgICByZXR1cm4KCgovLyBzbWFydF9jb250cmFjdHMucGVyc29uYWxfYmFuay5jb250cmFjdC5QZXJzb25hbEJhbmsuZGVwb3NpdChwYXlfdHhuOiB1aW50NjQsIGdpdGh1Yl9oYW5kbGU6IGJ5dGVzKSAtPiB1aW50NjQ6CmRlcG9zaXQ6CiAgICAvLyBzbWFydF9jb250cmFjdHMvcGVyc29uYWxfYmFuay9jb250cmFjdC5weToyMC0yMQogICAgLy8gQGFiaW1ldGhvZCgpCiAgICAvLyBkZWYgZGVwb3NpdChzZWxmLCBwYXlfdHhuOiBndHhuLlBheW1lbnRUcmFuc2FjdGlvbiwgZ2l0aHViX2hhbmRsZTogYXJjNC5TdHJpbmcpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDIgMQogICAgLy8gc21hcnRfY29udHJhY3RzL3BlcnNvbmFsX2JhbmsvY29udHJhY3QucHk6MzQKICAgIC8vIHBheV90eG4ucmVjZWl2ZXIgPT0gR2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcwogICAgZnJhbWVfZGlnIC0yCiAgICBndHhucyBSZWNlaXZlcgogICAgZ2xvYmFsIEN1cnJlbnRBcHBsaWNhdGlvbkFkZHJlc3MKICAgID09CiAgICAvLyBzbWFydF9jb250cmFjdHMvcGVyc29uYWxfYmFuay9jb250cmFjdC5weTozMy0zNQogICAgLy8gYXNzZXJ0ICgKICAgIC8vICAgICBwYXlfdHhuLnJlY2VpdmVyID09IEdsb2JhbC5jdXJyZW50X2FwcGxpY2F0aW9uX2FkZHJlc3MKICAgIC8vICksICJSZWNlaXZlciBtdXN0IGJlIHRoZSBjb250cmFjdCBhZGRyZXNzIgogICAgYXNzZXJ0IC8vIFJlY2VpdmVyIG11c3QgYmUgdGhlIGNvbnRyYWN0IGFkZHJlc3MKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjM2CiAgICAvLyBhc3NlcnQgcGF5X3R4bi5hbW91bnQgPiAwLCAiRGVwb3NpdCBhbW91bnQgbXVzdCBiZSBncmVhdGVyIHRoYW4gemVybyIKICAgIGZyYW1lX2RpZyAtMgogICAgZ3R4bnMgQW1vdW50CiAgICBkdXAKICAgIGFzc2VydCAvLyBEZXBvc2l0IGFtb3VudCBtdXN0IGJlIGdyZWF0ZXIgdGhhbiB6ZXJvCiAgICAvLyBzbWFydF9jb250cmFjdHMvcGVyc29uYWxfYmFuay9jb250cmFjdC5weTozOAogICAgLy8gZGVwb3NpdF9hbXQsIGRlcG9zaXRlZCA9IHNlbGYuZGVwb3NpdG9ycy5tYXliZShwYXlfdHhuLnNlbmRlcikKICAgIGZyYW1lX2RpZyAtMgogICAgZ3R4bnMgU2VuZGVyCiAgICBkdXAKICAgIGJveF9nZXQKICAgIGJ1cnkgMQogICAgLy8gc21hcnRfY29udHJhY3RzL3BlcnNvbmFsX2JhbmsvY29udHJhY3QucHk6NDAKICAgIC8vIGlmIGRlcG9zaXRlZDoKICAgIGJ6IGRlcG9zaXRfZWxzZV9ib2R5QDIKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjQxCiAgICAvLyBzZWxmLmRlcG9zaXRvcnNbcGF5X3R4bi5zZW5kZXJdICs9IHBheV90eG4uYW1vdW50CiAgICBmcmFtZV9kaWcgMQogICAgZHVwCiAgICBib3hfZ2V0CiAgICBzd2FwCiAgICBidG9pCiAgICBzd2FwCiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5kZXBvc2l0b3JzIGVudHJ5IGV4aXN0cwogICAgZnJhbWVfZGlnIDAKICAgICsKICAgIGl0b2IKICAgIGJveF9wdXQKCmRlcG9zaXRfYWZ0ZXJfaWZfZWxzZUAzOgogICAgLy8gc21hcnRfY29udHJhY3RzL3BlcnNvbmFsX2JhbmsvY29udHJhY3QucHk6NDUKICAgIC8vIHNlbGYuZ2l0aHViLnZhbHVlID0gZ2l0aHViX2hhbmRsZQogICAgYnl0ZWNfMSAvLyAweDY3Njk3NDY4NzU2MgogICAgYm94X2RlbAogICAgcG9wCiAgICBieXRlY18xIC8vIDB4Njc2OTc0Njg3NTYyCiAgICBmcmFtZV9kaWcgLTEKICAgIGJveF9wdXQKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjQ3CiAgICAvLyByZXR1cm4gc2VsZi5kZXBvc2l0b3JzW3BheV90eG4uc2VuZGVyXQogICAgZnJhbWVfZGlnIDEKICAgIGJveF9nZXQKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmRlcG9zaXRvcnMgZW50cnkgZXhpc3RzCiAgICBmcmFtZV9idXJ5IDAKICAgIHJldHN1YgoKZGVwb3NpdF9lbHNlX2JvZHlAMjoKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjQzCiAgICAvLyBzZWxmLmRlcG9zaXRvcnNbcGF5X3R4bi5zZW5kZXJdID0gcGF5X3R4bi5hbW91bnQKICAgIGZyYW1lX2RpZyAwCiAgICBpdG9iCiAgICBmcmFtZV9kaWcgMQogICAgc3dhcAogICAgYm94X3B1dAogICAgYiBkZXBvc2l0X2FmdGVyX2lmX2Vsc2VAMwoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5wZXJzb25hbF9iYW5rLmNvbnRyYWN0LlBlcnNvbmFsQmFuay53aXRoZHJhdygpIC0+IHVpbnQ2NDoKd2l0aGRyYXc6CiAgICAvLyBzbWFydF9jb250cmFjdHMvcGVyc29uYWxfYmFuay9jb250cmFjdC5weTo1OQogICAgLy8gZGVwb3NpdF9hbXQsIGRlcG9zaXRlZCA9IHNlbGYuZGVwb3NpdG9ycy5tYXliZShUeG4uc2VuZGVyKQogICAgdHhuIFNlbmRlcgogICAgYm94X2dldAogICAgc3dhcAogICAgYnRvaQogICAgLy8gc21hcnRfY29udHJhY3RzL3BlcnNvbmFsX2JhbmsvY29udHJhY3QucHk6NjAKICAgIC8vIGFzc2VydCBkZXBvc2l0ZWQsICJObyBkZXBvc2l0cyBmb3VuZCBmb3IgdGhpcyBhY2NvdW50IgogICAgc3dhcAogICAgYXNzZXJ0IC8vIE5vIGRlcG9zaXRzIGZvdW5kIGZvciB0aGlzIGFjY291bnQKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjYyLTY2CiAgICAvLyByZXN1bHQgPSBpdHhuLlBheW1lbnQoCiAgICAvLyAgICAgcmVjZWl2ZXI9VHhuLnNlbmRlciwKICAgIC8vICAgICBhbW91bnQ9ZGVwb3NpdF9hbXQsCiAgICAvLyAgICAgZmVlPTAsCiAgICAvLyApLnN1Ym1pdCgpCiAgICBpdHhuX2JlZ2luCiAgICAvLyBzbWFydF9jb250cmFjdHMvcGVyc29uYWxfYmFuay9jb250cmFjdC5weTo2MwogICAgLy8gcmVjZWl2ZXI9VHhuLnNlbmRlciwKICAgIHR4biBTZW5kZXIKICAgIGl0eG5fZmllbGQgUmVjZWl2ZXIKICAgIGl0eG5fZmllbGQgQW1vdW50CiAgICAvLyBzbWFydF9jb250cmFjdHMvcGVyc29uYWxfYmFuay9jb250cmFjdC5weTo2MgogICAgLy8gcmVzdWx0ID0gaXR4bi5QYXltZW50KAogICAgaW50Y18wIC8vIHBheQogICAgaXR4bl9maWVsZCBUeXBlRW51bQogICAgLy8gc21hcnRfY29udHJhY3RzL3BlcnNvbmFsX2JhbmsvY29udHJhY3QucHk6NjUKICAgIC8vIGZlZT0wLAogICAgaW50Y18xIC8vIDAKICAgIGl0eG5fZmllbGQgRmVlCiAgICAvLyBzbWFydF9jb250cmFjdHMvcGVyc29uYWxfYmFuay9jb250cmFjdC5weTo2Mi02NgogICAgLy8gcmVzdWx0ID0gaXR4bi5QYXltZW50KAogICAgLy8gICAgIHJlY2VpdmVyPVR4bi5zZW5kZXIsCiAgICAvLyAgICAgYW1vdW50PWRlcG9zaXRfYW10LAogICAgLy8gICAgIGZlZT0wLAogICAgLy8gKS5zdWJtaXQoKQogICAgaXR4bl9zdWJtaXQKICAgIGl0eG4gQW1vdW50CiAgICAvLyBzbWFydF9jb250cmFjdHMvcGVyc29uYWxfYmFuay9jb250cmFjdC5weTo2OAogICAgLy8gc2VsZi5kZXBvc2l0b3JzW1R4bi5zZW5kZXJdID0gVUludDY0KDApCiAgICB0eG4gU2VuZGVyCiAgICBpbnRjXzEgLy8gMAogICAgaXRvYgogICAgYm94X3B1dAogICAgLy8gc21hcnRfY29udHJhY3RzL3BlcnNvbmFsX2JhbmsvY29udHJhY3QucHk6NzAKICAgIC8vIHJldHVybiByZXN1bHQuYW1vdW50CiAgICByZXRzdWIKCgovLyBzbWFydF9jb250cmFjdHMucGVyc29uYWxfYmFuay5jb250cmFjdC5QZXJzb25hbEJhbmsuZ2V0X2JveCgpIC0+IGJ5dGVzOgpnZXRfYm94OgogICAgLy8gc21hcnRfY29udHJhY3RzL3BlcnNvbmFsX2JhbmsvY29udHJhY3QucHk6NzQKICAgIC8vIHJldHVybiBzZWxmLmdpdGh1Yi52YWx1ZQogICAgYnl0ZWNfMSAvLyAweDY3Njk3NDY4NzU2MgogICAgYm94X2dldAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuZ2l0aHViIGV4aXN0cwogICAgcmV0c3ViCg==", "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCiNwcmFnbWEgdHlwZXRyYWNrIGZhbHNlCgovLyBhbGdvcHkuYXJjNC5BUkM0Q29udHJhY3QuY2xlYXJfc3RhdGVfcHJvZ3JhbSgpIC0+IHVpbnQ2NDoKbWFpbjoKICAgIHB1c2hpbnQgMSAvLyAxCiAgICByZXR1cm4K" }, "byteCode": { - "approval": "CiACAQAmAQQVH3x1MRtBAEOCAgQymOfABDo5Xys2GgCOAgATAAIjQzEZFEQxGESIAGoWKExQsCJDMRkURDEYRDEWIglJOBAiEkSIABIWKExQsCJDMRlA/80xGBREIkOKAQGL/zgHMgoSRIv/OAhJRIv/OABJvkUBQQAXiwFJvkwXTESLAAgWv4sBvkwXTESMAImLABaLAUy/Qv/sMQC+TBdMRLExALIHsggishAjsgGztAgxACMWv4k=", + "approval": "CiACAQAmAgQVH3x1BmdpdGh1YjEbQQBdggME2CL/7wQ6OV8rBGK4MY02GgCOAwAjABIAAiNDMRkURDEYRIgAoShMULAiQzEZFEQxGESIAHQWKExQsCJDMRkURDEYRDEWIglJOBAiEkQ2GgGIABIWKExQsCJDMRlA/7oxGBREIkOKAgGL/jgHMgoSRIv+OAhJRIv+OABJvkUBQQAeiwFJvkwXTESLAAgWvym8SCmL/7+LAb5MF0xEjACJiwAWiwFMv0L/5TEAvkwXTESxMQCyB7IIIrIQI7IBs7QIMQAjFr+JKb5EiQ==", "clear": "CoEBQw==" }, "compilerInfo": { diff --git a/projects/algorand-python-workshop/smart_contracts/artifacts/personal_bank/personal_bank_client.py b/projects/algorand-python-workshop/smart_contracts/artifacts/personal_bank/personal_bank_client.py index 1e67562..05be60a 100644 --- a/projects/algorand-python-workshop/smart_contracts/artifacts/personal_bank/personal_bank_client.py +++ b/projects/algorand-python-workshop/smart_contracts/artifacts/personal_bank/personal_bank_client.py @@ -19,7 +19,7 @@ import algokit_utils from algokit_utils import AlgorandClient as _AlgoKitAlgorandClient -_APP_SPEC_JSON = r"""{"arcs": [22, 28], "bareActions": {"call": [], "create": ["NoOp"]}, "methods": [{"actions": {"call": ["NoOp"], "create": []}, "args": [{"type": "pay", "desc": "The payment transaction containing deposit information", "name": "pay_txn"}], "name": "deposit", "returns": {"type": "uint64", "desc": "The total amount deposited by the sender after this transaction (as UInt64)"}, "desc": "Deposits funds into the personal bank\nThis method accepts a payment transaction and records the deposit amount in the sender's BoxMap. If the sender already has a deposit, the amount is added to their existing balance.", "events": [], "readonly": false, "recommendations": {}}, {"actions": {"call": ["NoOp"], "create": []}, "args": [], "name": "withdraw", "returns": {"type": "uint64", "desc": "The amount withdrawn (as UInt64)"}, "desc": "Withdraws all funds from the sender's account\nThis method transfers the entire balance of the sender's account back to them, and resets their balance to zero. The sender must have a deposit to withdraw.", "events": [], "readonly": false, "recommendations": {}}], "name": "PersonalBank", "state": {"keys": {"box": {}, "global": {}, "local": {}}, "maps": {"box": {"depositors": {"keyType": "address", "valueType": "uint64", "prefix": ""}}, "global": {}, "local": {}}, "schema": {"global": {"bytes": 0, "ints": 0}, "local": {"bytes": 0, "ints": 0}}}, "structs": {}, "byteCode": {"approval": "CiACAQAmAQQVH3x1MRtBAEOCAgQymOfABDo5Xys2GgCOAgATAAIjQzEZFEQxGESIAGoWKExQsCJDMRkURDEYRDEWIglJOBAiEkSIABIWKExQsCJDMRlA/80xGBREIkOKAQGL/zgHMgoSRIv/OAhJRIv/OABJvkUBQQAXiwFJvkwXTESLAAgWv4sBvkwXTESMAImLABaLAUy/Qv/sMQC+TBdMRLExALIHsggishAjsgGztAgxACMWv4k=", "clear": "CoEBQw=="}, "compilerInfo": {"compiler": "puya", "compilerVersion": {"major": 4, "minor": 7, "patch": 0}}, "events": [], "networks": {}, "source": {"approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCiNwcmFnbWEgdHlwZXRyYWNrIGZhbHNlCgovLyBzbWFydF9jb250cmFjdHMucGVyc29uYWxfYmFuay5jb250cmFjdC5QZXJzb25hbEJhbmsuX19hbGdvcHlfZW50cnlwb2ludF93aXRoX2luaXQoKSAtPiB1aW50NjQ6Cm1haW46CiAgICBpbnRjYmxvY2sgMSAwCiAgICBieXRlY2Jsb2NrIDB4MTUxZjdjNzUKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjUKICAgIC8vIGNsYXNzIFBlcnNvbmFsQmFuayhBUkM0Q29udHJhY3QpOgogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IG1haW5fYmFyZV9yb3V0aW5nQDcKICAgIHB1c2hieXRlc3MgMHgzMjk4ZTdjMCAweDNhMzk1ZjJiIC8vIG1ldGhvZCAiZGVwb3NpdChwYXkpdWludDY0IiwgbWV0aG9kICJ3aXRoZHJhdygpdWludDY0IgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggbWFpbl9kZXBvc2l0X3JvdXRlQDUgbWFpbl93aXRoZHJhd19yb3V0ZUA2CgptYWluX2FmdGVyX2lmX2Vsc2VAOToKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjUKICAgIC8vIGNsYXNzIFBlcnNvbmFsQmFuayhBUkM0Q29udHJhY3QpOgogICAgaW50Y18xIC8vIDAKICAgIHJldHVybgoKbWFpbl93aXRoZHJhd19yb3V0ZUA2OgogICAgLy8gc21hcnRfY29udHJhY3RzL3BlcnNvbmFsX2JhbmsvY29udHJhY3QucHk6NDIKICAgIC8vIEBhYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIHdpdGhkcmF3CiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX2RlcG9zaXRfcm91dGVANToKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjE1CiAgICAvLyBAYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gc21hcnRfY29udHJhY3RzL3BlcnNvbmFsX2JhbmsvY29udHJhY3QucHk6NQogICAgLy8gY2xhc3MgUGVyc29uYWxCYW5rKEFSQzRDb250cmFjdCk6CiAgICB0eG4gR3JvdXBJbmRleAogICAgaW50Y18wIC8vIDEKICAgIC0KICAgIGR1cAogICAgZ3R4bnMgVHlwZUVudW0KICAgIGludGNfMCAvLyBwYXkKICAgID09CiAgICBhc3NlcnQgLy8gdHJhbnNhY3Rpb24gdHlwZSBpcyBwYXkKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjE1CiAgICAvLyBAYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgZGVwb3NpdAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl9iYXJlX3JvdXRpbmdANzoKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjUKICAgIC8vIGNsYXNzIFBlcnNvbmFsQmFuayhBUkM0Q29udHJhY3QpOgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgYm56IG1haW5fYWZ0ZXJfaWZfZWxzZUA5CiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBjcmVhdGluZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5wZXJzb25hbF9iYW5rLmNvbnRyYWN0LlBlcnNvbmFsQmFuay5kZXBvc2l0KHBheV90eG46IHVpbnQ2NCkgLT4gdWludDY0OgpkZXBvc2l0OgogICAgLy8gc21hcnRfY29udHJhY3RzL3BlcnNvbmFsX2JhbmsvY29udHJhY3QucHk6MTUtMTYKICAgIC8vIEBhYmltZXRob2QoKQogICAgLy8gZGVmIGRlcG9zaXQoc2VsZiwgcGF5X3R4bjogZ3R4bi5QYXltZW50VHJhbnNhY3Rpb24pIC0+IFVJbnQ2NDoKICAgIHByb3RvIDEgMQogICAgLy8gc21hcnRfY29udHJhY3RzL3BlcnNvbmFsX2JhbmsvY29udHJhY3QucHk6MjkKICAgIC8vIHBheV90eG4ucmVjZWl2ZXIgPT0gR2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcwogICAgZnJhbWVfZGlnIC0xCiAgICBndHhucyBSZWNlaXZlcgogICAgZ2xvYmFsIEN1cnJlbnRBcHBsaWNhdGlvbkFkZHJlc3MKICAgID09CiAgICAvLyBzbWFydF9jb250cmFjdHMvcGVyc29uYWxfYmFuay9jb250cmFjdC5weToyOC0zMAogICAgLy8gYXNzZXJ0ICgKICAgIC8vICAgICBwYXlfdHhuLnJlY2VpdmVyID09IEdsb2JhbC5jdXJyZW50X2FwcGxpY2F0aW9uX2FkZHJlc3MKICAgIC8vICksICJSZWNlaXZlciBtdXN0IGJlIHRoZSBjb250cmFjdCBhZGRyZXNzIgogICAgYXNzZXJ0IC8vIFJlY2VpdmVyIG11c3QgYmUgdGhlIGNvbnRyYWN0IGFkZHJlc3MKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjMxCiAgICAvLyBhc3NlcnQgcGF5X3R4bi5hbW91bnQgPiAwLCAiRGVwb3NpdCBhbW91bnQgbXVzdCBiZSBncmVhdGVyIHRoYW4gemVybyIKICAgIGZyYW1lX2RpZyAtMQogICAgZ3R4bnMgQW1vdW50CiAgICBkdXAKICAgIGFzc2VydCAvLyBEZXBvc2l0IGFtb3VudCBtdXN0IGJlIGdyZWF0ZXIgdGhhbiB6ZXJvCiAgICAvLyBzbWFydF9jb250cmFjdHMvcGVyc29uYWxfYmFuay9jb250cmFjdC5weTozMwogICAgLy8gZGVwb3NpdF9hbXQsIGRlcG9zaXRlZCA9IHNlbGYuZGVwb3NpdG9ycy5tYXliZShwYXlfdHhuLnNlbmRlcikKICAgIGZyYW1lX2RpZyAtMQogICAgZ3R4bnMgU2VuZGVyCiAgICBkdXAKICAgIGJveF9nZXQKICAgIGJ1cnkgMQogICAgLy8gc21hcnRfY29udHJhY3RzL3BlcnNvbmFsX2JhbmsvY29udHJhY3QucHk6MzUKICAgIC8vIGlmIGRlcG9zaXRlZDoKICAgIGJ6IGRlcG9zaXRfZWxzZV9ib2R5QDIKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjM2CiAgICAvLyBzZWxmLmRlcG9zaXRvcnNbcGF5X3R4bi5zZW5kZXJdICs9IHBheV90eG4uYW1vdW50CiAgICBmcmFtZV9kaWcgMQogICAgZHVwCiAgICBib3hfZ2V0CiAgICBzd2FwCiAgICBidG9pCiAgICBzd2FwCiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5kZXBvc2l0b3JzIGVudHJ5IGV4aXN0cwogICAgZnJhbWVfZGlnIDAKICAgICsKICAgIGl0b2IKICAgIGJveF9wdXQKCmRlcG9zaXRfYWZ0ZXJfaWZfZWxzZUAzOgogICAgLy8gc21hcnRfY29udHJhY3RzL3BlcnNvbmFsX2JhbmsvY29udHJhY3QucHk6NDAKICAgIC8vIHJldHVybiBzZWxmLmRlcG9zaXRvcnNbcGF5X3R4bi5zZW5kZXJdCiAgICBmcmFtZV9kaWcgMQogICAgYm94X2dldAogICAgc3dhcAogICAgYnRvaQogICAgc3dhcAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuZGVwb3NpdG9ycyBlbnRyeSBleGlzdHMKICAgIGZyYW1lX2J1cnkgMAogICAgcmV0c3ViCgpkZXBvc2l0X2Vsc2VfYm9keUAyOgogICAgLy8gc21hcnRfY29udHJhY3RzL3BlcnNvbmFsX2JhbmsvY29udHJhY3QucHk6MzgKICAgIC8vIHNlbGYuZGVwb3NpdG9yc1twYXlfdHhuLnNlbmRlcl0gPSBwYXlfdHhuLmFtb3VudAogICAgZnJhbWVfZGlnIDAKICAgIGl0b2IKICAgIGZyYW1lX2RpZyAxCiAgICBzd2FwCiAgICBib3hfcHV0CiAgICBiIGRlcG9zaXRfYWZ0ZXJfaWZfZWxzZUAzCgoKLy8gc21hcnRfY29udHJhY3RzLnBlcnNvbmFsX2JhbmsuY29udHJhY3QuUGVyc29uYWxCYW5rLndpdGhkcmF3KCkgLT4gdWludDY0Ogp3aXRoZHJhdzoKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjUyCiAgICAvLyBkZXBvc2l0X2FtdCwgZGVwb3NpdGVkID0gc2VsZi5kZXBvc2l0b3JzLm1heWJlKFR4bi5zZW5kZXIpCiAgICB0eG4gU2VuZGVyCiAgICBib3hfZ2V0CiAgICBzd2FwCiAgICBidG9pCiAgICAvLyBzbWFydF9jb250cmFjdHMvcGVyc29uYWxfYmFuay9jb250cmFjdC5weTo1MwogICAgLy8gYXNzZXJ0IGRlcG9zaXRlZCwgIk5vIGRlcG9zaXRzIGZvdW5kIGZvciB0aGlzIGFjY291bnQiCiAgICBzd2FwCiAgICBhc3NlcnQgLy8gTm8gZGVwb3NpdHMgZm91bmQgZm9yIHRoaXMgYWNjb3VudAogICAgLy8gc21hcnRfY29udHJhY3RzL3BlcnNvbmFsX2JhbmsvY29udHJhY3QucHk6NTUtNTkKICAgIC8vIHJlc3VsdCA9IGl0eG4uUGF5bWVudCgKICAgIC8vICAgICByZWNlaXZlcj1UeG4uc2VuZGVyLAogICAgLy8gICAgIGFtb3VudD1kZXBvc2l0X2FtdCwKICAgIC8vICAgICBmZWU9MCwKICAgIC8vICkuc3VibWl0KCkKICAgIGl0eG5fYmVnaW4KICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjU2CiAgICAvLyByZWNlaXZlcj1UeG4uc2VuZGVyLAogICAgdHhuIFNlbmRlcgogICAgaXR4bl9maWVsZCBSZWNlaXZlcgogICAgaXR4bl9maWVsZCBBbW91bnQKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjU1CiAgICAvLyByZXN1bHQgPSBpdHhuLlBheW1lbnQoCiAgICBpbnRjXzAgLy8gcGF5CiAgICBpdHhuX2ZpZWxkIFR5cGVFbnVtCiAgICAvLyBzbWFydF9jb250cmFjdHMvcGVyc29uYWxfYmFuay9jb250cmFjdC5weTo1OAogICAgLy8gZmVlPTAsCiAgICBpbnRjXzEgLy8gMAogICAgaXR4bl9maWVsZCBGZWUKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjU1LTU5CiAgICAvLyByZXN1bHQgPSBpdHhuLlBheW1lbnQoCiAgICAvLyAgICAgcmVjZWl2ZXI9VHhuLnNlbmRlciwKICAgIC8vICAgICBhbW91bnQ9ZGVwb3NpdF9hbXQsCiAgICAvLyAgICAgZmVlPTAsCiAgICAvLyApLnN1Ym1pdCgpCiAgICBpdHhuX3N1Ym1pdAogICAgaXR4biBBbW91bnQKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjYxCiAgICAvLyBzZWxmLmRlcG9zaXRvcnNbVHhuLnNlbmRlcl0gPSBVSW50NjQoMCkKICAgIHR4biBTZW5kZXIKICAgIGludGNfMSAvLyAwCiAgICBpdG9iCiAgICBib3hfcHV0CiAgICAvLyBzbWFydF9jb250cmFjdHMvcGVyc29uYWxfYmFuay9jb250cmFjdC5weTo2MwogICAgLy8gcmV0dXJuIHJlc3VsdC5hbW91bnQKICAgIHJldHN1Ygo=", "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCiNwcmFnbWEgdHlwZXRyYWNrIGZhbHNlCgovLyBhbGdvcHkuYXJjNC5BUkM0Q29udHJhY3QuY2xlYXJfc3RhdGVfcHJvZ3JhbSgpIC0+IHVpbnQ2NDoKbWFpbjoKICAgIHB1c2hpbnQgMSAvLyAxCiAgICByZXR1cm4K"}, "sourceInfo": {"approval": {"pcOffsetMethod": "none", "sourceInfo": [{"pc": [111], "errorMessage": "Deposit amount must be greater than zero"}, {"pc": [162], "errorMessage": "No deposits found for this account"}, {"pc": [43, 60], "errorMessage": "OnCompletion is not NoOp"}, {"pc": [105], "errorMessage": "Receiver must be the contract address"}, {"pc": [92], "errorMessage": "can only call when creating"}, {"pc": [46, 63], "errorMessage": "can only call when not creating"}, {"pc": [130, 142], "errorMessage": "check self.depositors entry exists"}, {"pc": [73], "errorMessage": "transaction type is pay"}]}, "clear": {"pcOffsetMethod": "none", "sourceInfo": []}}, "templateVariables": {}}""" +_APP_SPEC_JSON = r"""{"arcs": [22, 28], "bareActions": {"call": [], "create": ["NoOp"]}, "methods": [{"actions": {"call": ["NoOp"], "create": []}, "args": [{"type": "pay", "desc": "The payment transaction containing deposit information", "name": "pay_txn"}, {"type": "string", "name": "github_handle"}], "name": "deposit", "returns": {"type": "uint64", "desc": "The total amount deposited by the sender after this transaction (as UInt64)"}, "desc": "Deposits funds into the personal bank\nThis method accepts a payment transaction and records the deposit amount in the sender's BoxMap. If the sender already has a deposit, the amount is added to their existing balance.", "events": [], "readonly": false, "recommendations": {}}, {"actions": {"call": ["NoOp"], "create": []}, "args": [], "name": "withdraw", "returns": {"type": "uint64", "desc": "The amount withdrawn (as UInt64)"}, "desc": "Withdraws all funds from the sender's account\nThis method transfers the entire balance of the sender's account back to them, and resets their balance to zero. The sender must have a deposit to withdraw.", "events": [], "readonly": false, "recommendations": {}}, {"actions": {"call": ["NoOp"], "create": []}, "args": [], "name": "get_box", "returns": {"type": "string"}, "events": [], "readonly": false, "recommendations": {}}], "name": "PersonalBank", "state": {"keys": {"box": {"github": {"key": "Z2l0aHVi", "keyType": "AVMBytes", "valueType": "string"}}, "global": {}, "local": {}}, "maps": {"box": {"depositors": {"keyType": "address", "valueType": "uint64", "prefix": ""}}, "global": {}, "local": {}}, "schema": {"global": {"bytes": 0, "ints": 0}, "local": {"bytes": 0, "ints": 0}}}, "structs": {}, "byteCode": {"approval": "CiACAQAmAgQVH3x1BmdpdGh1YjEbQQBdggME2CL/7wQ6OV8rBGK4MY02GgCOAwAjABIAAiNDMRkURDEYRIgAoShMULAiQzEZFEQxGESIAHQWKExQsCJDMRkURDEYRDEWIglJOBAiEkQ2GgGIABIWKExQsCJDMRlA/7oxGBREIkOKAgGL/jgHMgoSRIv+OAhJRIv+OABJvkUBQQAeiwFJvkwXTESLAAgWvym8SCmL/7+LAb5MF0xEjACJiwAWiwFMv0L/5TEAvkwXTESxMQCyB7IIIrIQI7IBs7QIMQAjFr+JKb5EiQ==", "clear": "CoEBQw=="}, "compilerInfo": {"compiler": "puya", "compilerVersion": {"major": 4, "minor": 7, "patch": 0}}, "events": [], "networks": {}, "source": {"approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCiNwcmFnbWEgdHlwZXRyYWNrIGZhbHNlCgovLyBzbWFydF9jb250cmFjdHMucGVyc29uYWxfYmFuay5jb250cmFjdC5QZXJzb25hbEJhbmsuX19hbGdvcHlfZW50cnlwb2ludF93aXRoX2luaXQoKSAtPiB1aW50NjQ6Cm1haW46CiAgICBpbnRjYmxvY2sgMSAwCiAgICBieXRlY2Jsb2NrIDB4MTUxZjdjNzUgMHg2NzY5NzQ2ODc1NjIKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjUKICAgIC8vIGNsYXNzIFBlcnNvbmFsQmFuayhBUkM0Q29udHJhY3QpOgogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IG1haW5fYmFyZV9yb3V0aW5nQDgKICAgIHB1c2hieXRlc3MgMHhkODIyZmZlZiAweDNhMzk1ZjJiIDB4NjJiODMxOGQgLy8gbWV0aG9kICJkZXBvc2l0KHBheSxzdHJpbmcpdWludDY0IiwgbWV0aG9kICJ3aXRoZHJhdygpdWludDY0IiwgbWV0aG9kICJnZXRfYm94KClzdHJpbmciCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBtYWluX2RlcG9zaXRfcm91dGVANSBtYWluX3dpdGhkcmF3X3JvdXRlQDYgbWFpbl9nZXRfYm94X3JvdXRlQDcKCm1haW5fYWZ0ZXJfaWZfZWxzZUAxMDoKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjUKICAgIC8vIGNsYXNzIFBlcnNvbmFsQmFuayhBUkM0Q29udHJhY3QpOgogICAgaW50Y18xIC8vIDAKICAgIHJldHVybgoKbWFpbl9nZXRfYm94X3JvdXRlQDc6CiAgICAvLyBzbWFydF9jb250cmFjdHMvcGVyc29uYWxfYmFuay9jb250cmFjdC5weTo3MgogICAgLy8gQGFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgZ2V0X2JveAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl93aXRoZHJhd19yb3V0ZUA2OgogICAgLy8gc21hcnRfY29udHJhY3RzL3BlcnNvbmFsX2JhbmsvY29udHJhY3QucHk6NDkKICAgIC8vIEBhYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIHdpdGhkcmF3CiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX2RlcG9zaXRfcm91dGVANToKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjIwCiAgICAvLyBAYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gc21hcnRfY29udHJhY3RzL3BlcnNvbmFsX2JhbmsvY29udHJhY3QucHk6NQogICAgLy8gY2xhc3MgUGVyc29uYWxCYW5rKEFSQzRDb250cmFjdCk6CiAgICB0eG4gR3JvdXBJbmRleAogICAgaW50Y18wIC8vIDEKICAgIC0KICAgIGR1cAogICAgZ3R4bnMgVHlwZUVudW0KICAgIGludGNfMCAvLyBwYXkKICAgID09CiAgICBhc3NlcnQgLy8gdHJhbnNhY3Rpb24gdHlwZSBpcyBwYXkKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjIwCiAgICAvLyBAYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgZGVwb3NpdAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl9iYXJlX3JvdXRpbmdAODoKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjUKICAgIC8vIGNsYXNzIFBlcnNvbmFsQmFuayhBUkM0Q29udHJhY3QpOgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgYm56IG1haW5fYWZ0ZXJfaWZfZWxzZUAxMAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gY3JlYXRpbmcKICAgIGludGNfMCAvLyAxCiAgICByZXR1cm4KCgovLyBzbWFydF9jb250cmFjdHMucGVyc29uYWxfYmFuay5jb250cmFjdC5QZXJzb25hbEJhbmsuZGVwb3NpdChwYXlfdHhuOiB1aW50NjQsIGdpdGh1Yl9oYW5kbGU6IGJ5dGVzKSAtPiB1aW50NjQ6CmRlcG9zaXQ6CiAgICAvLyBzbWFydF9jb250cmFjdHMvcGVyc29uYWxfYmFuay9jb250cmFjdC5weToyMC0yMQogICAgLy8gQGFiaW1ldGhvZCgpCiAgICAvLyBkZWYgZGVwb3NpdChzZWxmLCBwYXlfdHhuOiBndHhuLlBheW1lbnRUcmFuc2FjdGlvbiwgZ2l0aHViX2hhbmRsZTogYXJjNC5TdHJpbmcpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDIgMQogICAgLy8gc21hcnRfY29udHJhY3RzL3BlcnNvbmFsX2JhbmsvY29udHJhY3QucHk6MzQKICAgIC8vIHBheV90eG4ucmVjZWl2ZXIgPT0gR2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcwogICAgZnJhbWVfZGlnIC0yCiAgICBndHhucyBSZWNlaXZlcgogICAgZ2xvYmFsIEN1cnJlbnRBcHBsaWNhdGlvbkFkZHJlc3MKICAgID09CiAgICAvLyBzbWFydF9jb250cmFjdHMvcGVyc29uYWxfYmFuay9jb250cmFjdC5weTozMy0zNQogICAgLy8gYXNzZXJ0ICgKICAgIC8vICAgICBwYXlfdHhuLnJlY2VpdmVyID09IEdsb2JhbC5jdXJyZW50X2FwcGxpY2F0aW9uX2FkZHJlc3MKICAgIC8vICksICJSZWNlaXZlciBtdXN0IGJlIHRoZSBjb250cmFjdCBhZGRyZXNzIgogICAgYXNzZXJ0IC8vIFJlY2VpdmVyIG11c3QgYmUgdGhlIGNvbnRyYWN0IGFkZHJlc3MKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjM2CiAgICAvLyBhc3NlcnQgcGF5X3R4bi5hbW91bnQgPiAwLCAiRGVwb3NpdCBhbW91bnQgbXVzdCBiZSBncmVhdGVyIHRoYW4gemVybyIKICAgIGZyYW1lX2RpZyAtMgogICAgZ3R4bnMgQW1vdW50CiAgICBkdXAKICAgIGFzc2VydCAvLyBEZXBvc2l0IGFtb3VudCBtdXN0IGJlIGdyZWF0ZXIgdGhhbiB6ZXJvCiAgICAvLyBzbWFydF9jb250cmFjdHMvcGVyc29uYWxfYmFuay9jb250cmFjdC5weTozOAogICAgLy8gZGVwb3NpdF9hbXQsIGRlcG9zaXRlZCA9IHNlbGYuZGVwb3NpdG9ycy5tYXliZShwYXlfdHhuLnNlbmRlcikKICAgIGZyYW1lX2RpZyAtMgogICAgZ3R4bnMgU2VuZGVyCiAgICBkdXAKICAgIGJveF9nZXQKICAgIGJ1cnkgMQogICAgLy8gc21hcnRfY29udHJhY3RzL3BlcnNvbmFsX2JhbmsvY29udHJhY3QucHk6NDAKICAgIC8vIGlmIGRlcG9zaXRlZDoKICAgIGJ6IGRlcG9zaXRfZWxzZV9ib2R5QDIKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjQxCiAgICAvLyBzZWxmLmRlcG9zaXRvcnNbcGF5X3R4bi5zZW5kZXJdICs9IHBheV90eG4uYW1vdW50CiAgICBmcmFtZV9kaWcgMQogICAgZHVwCiAgICBib3hfZ2V0CiAgICBzd2FwCiAgICBidG9pCiAgICBzd2FwCiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5kZXBvc2l0b3JzIGVudHJ5IGV4aXN0cwogICAgZnJhbWVfZGlnIDAKICAgICsKICAgIGl0b2IKICAgIGJveF9wdXQKCmRlcG9zaXRfYWZ0ZXJfaWZfZWxzZUAzOgogICAgLy8gc21hcnRfY29udHJhY3RzL3BlcnNvbmFsX2JhbmsvY29udHJhY3QucHk6NDUKICAgIC8vIHNlbGYuZ2l0aHViLnZhbHVlID0gZ2l0aHViX2hhbmRsZQogICAgYnl0ZWNfMSAvLyAweDY3Njk3NDY4NzU2MgogICAgYm94X2RlbAogICAgcG9wCiAgICBieXRlY18xIC8vIDB4Njc2OTc0Njg3NTYyCiAgICBmcmFtZV9kaWcgLTEKICAgIGJveF9wdXQKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjQ3CiAgICAvLyByZXR1cm4gc2VsZi5kZXBvc2l0b3JzW3BheV90eG4uc2VuZGVyXQogICAgZnJhbWVfZGlnIDEKICAgIGJveF9nZXQKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmRlcG9zaXRvcnMgZW50cnkgZXhpc3RzCiAgICBmcmFtZV9idXJ5IDAKICAgIHJldHN1YgoKZGVwb3NpdF9lbHNlX2JvZHlAMjoKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjQzCiAgICAvLyBzZWxmLmRlcG9zaXRvcnNbcGF5X3R4bi5zZW5kZXJdID0gcGF5X3R4bi5hbW91bnQKICAgIGZyYW1lX2RpZyAwCiAgICBpdG9iCiAgICBmcmFtZV9kaWcgMQogICAgc3dhcAogICAgYm94X3B1dAogICAgYiBkZXBvc2l0X2FmdGVyX2lmX2Vsc2VAMwoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5wZXJzb25hbF9iYW5rLmNvbnRyYWN0LlBlcnNvbmFsQmFuay53aXRoZHJhdygpIC0+IHVpbnQ2NDoKd2l0aGRyYXc6CiAgICAvLyBzbWFydF9jb250cmFjdHMvcGVyc29uYWxfYmFuay9jb250cmFjdC5weTo1OQogICAgLy8gZGVwb3NpdF9hbXQsIGRlcG9zaXRlZCA9IHNlbGYuZGVwb3NpdG9ycy5tYXliZShUeG4uc2VuZGVyKQogICAgdHhuIFNlbmRlcgogICAgYm94X2dldAogICAgc3dhcAogICAgYnRvaQogICAgLy8gc21hcnRfY29udHJhY3RzL3BlcnNvbmFsX2JhbmsvY29udHJhY3QucHk6NjAKICAgIC8vIGFzc2VydCBkZXBvc2l0ZWQsICJObyBkZXBvc2l0cyBmb3VuZCBmb3IgdGhpcyBhY2NvdW50IgogICAgc3dhcAogICAgYXNzZXJ0IC8vIE5vIGRlcG9zaXRzIGZvdW5kIGZvciB0aGlzIGFjY291bnQKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9wZXJzb25hbF9iYW5rL2NvbnRyYWN0LnB5OjYyLTY2CiAgICAvLyByZXN1bHQgPSBpdHhuLlBheW1lbnQoCiAgICAvLyAgICAgcmVjZWl2ZXI9VHhuLnNlbmRlciwKICAgIC8vICAgICBhbW91bnQ9ZGVwb3NpdF9hbXQsCiAgICAvLyAgICAgZmVlPTAsCiAgICAvLyApLnN1Ym1pdCgpCiAgICBpdHhuX2JlZ2luCiAgICAvLyBzbWFydF9jb250cmFjdHMvcGVyc29uYWxfYmFuay9jb250cmFjdC5weTo2MwogICAgLy8gcmVjZWl2ZXI9VHhuLnNlbmRlciwKICAgIHR4biBTZW5kZXIKICAgIGl0eG5fZmllbGQgUmVjZWl2ZXIKICAgIGl0eG5fZmllbGQgQW1vdW50CiAgICAvLyBzbWFydF9jb250cmFjdHMvcGVyc29uYWxfYmFuay9jb250cmFjdC5weTo2MgogICAgLy8gcmVzdWx0ID0gaXR4bi5QYXltZW50KAogICAgaW50Y18wIC8vIHBheQogICAgaXR4bl9maWVsZCBUeXBlRW51bQogICAgLy8gc21hcnRfY29udHJhY3RzL3BlcnNvbmFsX2JhbmsvY29udHJhY3QucHk6NjUKICAgIC8vIGZlZT0wLAogICAgaW50Y18xIC8vIDAKICAgIGl0eG5fZmllbGQgRmVlCiAgICAvLyBzbWFydF9jb250cmFjdHMvcGVyc29uYWxfYmFuay9jb250cmFjdC5weTo2Mi02NgogICAgLy8gcmVzdWx0ID0gaXR4bi5QYXltZW50KAogICAgLy8gICAgIHJlY2VpdmVyPVR4bi5zZW5kZXIsCiAgICAvLyAgICAgYW1vdW50PWRlcG9zaXRfYW10LAogICAgLy8gICAgIGZlZT0wLAogICAgLy8gKS5zdWJtaXQoKQogICAgaXR4bl9zdWJtaXQKICAgIGl0eG4gQW1vdW50CiAgICAvLyBzbWFydF9jb250cmFjdHMvcGVyc29uYWxfYmFuay9jb250cmFjdC5weTo2OAogICAgLy8gc2VsZi5kZXBvc2l0b3JzW1R4bi5zZW5kZXJdID0gVUludDY0KDApCiAgICB0eG4gU2VuZGVyCiAgICBpbnRjXzEgLy8gMAogICAgaXRvYgogICAgYm94X3B1dAogICAgLy8gc21hcnRfY29udHJhY3RzL3BlcnNvbmFsX2JhbmsvY29udHJhY3QucHk6NzAKICAgIC8vIHJldHVybiByZXN1bHQuYW1vdW50CiAgICByZXRzdWIKCgovLyBzbWFydF9jb250cmFjdHMucGVyc29uYWxfYmFuay5jb250cmFjdC5QZXJzb25hbEJhbmsuZ2V0X2JveCgpIC0+IGJ5dGVzOgpnZXRfYm94OgogICAgLy8gc21hcnRfY29udHJhY3RzL3BlcnNvbmFsX2JhbmsvY29udHJhY3QucHk6NzQKICAgIC8vIHJldHVybiBzZWxmLmdpdGh1Yi52YWx1ZQogICAgYnl0ZWNfMSAvLyAweDY3Njk3NDY4NzU2MgogICAgYm94X2dldAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuZ2l0aHViIGV4aXN0cwogICAgcmV0c3ViCg==", "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCiNwcmFnbWEgdHlwZXRyYWNrIGZhbHNlCgovLyBhbGdvcHkuYXJjNC5BUkM0Q29udHJhY3QuY2xlYXJfc3RhdGVfcHJvZ3JhbSgpIC0+IHVpbnQ2NDoKbWFpbjoKICAgIHB1c2hpbnQgMSAvLyAxCiAgICByZXR1cm4K"}, "sourceInfo": {"approval": {"pcOffsetMethod": "none", "sourceInfo": [{"pc": [144], "errorMessage": "Deposit amount must be greater than zero"}, {"pc": [202], "errorMessage": "No deposits found for this account"}, {"pc": [57, 73, 90], "errorMessage": "OnCompletion is not NoOp"}, {"pc": [138], "errorMessage": "Receiver must be the contract address"}, {"pc": [125], "errorMessage": "can only call when creating"}, {"pc": [60, 76, 93], "errorMessage": "can only call when not creating"}, {"pc": [163, 182], "errorMessage": "check self.depositors entry exists"}, {"pc": [227], "errorMessage": "check self.github exists"}, {"pc": [103], "errorMessage": "transaction type is pay"}]}, "clear": {"pcOffsetMethod": "none", "sourceInfo": []}}, "templateVariables": {}}""" APP_SPEC = algokit_utils.Arc56Contract.from_json(_APP_SPEC_JSON) def _parse_abi_args(args: object | None = None) -> list[object] | None: @@ -68,10 +68,11 @@ def _init_dataclass(cls: type, data: dict) -> object: class DepositArgs: """Dataclass for deposit arguments""" pay_txn: algokit_utils.AppMethodCallTransactionArgument + github_handle: str @property def abi_method_signature(self) -> str: - return "deposit(pay)uint64" + return "deposit(pay,string)uint64" class PersonalBankParams: @@ -80,14 +81,14 @@ def __init__(self, app_client: algokit_utils.AppClient): def deposit( self, - args: tuple[algokit_utils.AppMethodCallTransactionArgument] | DepositArgs, + args: tuple[algokit_utils.AppMethodCallTransactionArgument, str] | DepositArgs, params: algokit_utils.CommonAppCallParams | None = None ) -> algokit_utils.AppCallMethodCallParams: method_args = _parse_abi_args(args) params = params or algokit_utils.CommonAppCallParams() return self.app_client.params.call(algokit_utils.AppClientMethodCallParams(**{ **dataclasses.asdict(params), - "method": "deposit(pay)uint64", + "method": "deposit(pay,string)uint64", "args": method_args, })) @@ -102,6 +103,17 @@ def withdraw( "method": "withdraw()uint64", })) + def get_box( + self, + params: algokit_utils.CommonAppCallParams | None = None + ) -> algokit_utils.AppCallMethodCallParams: + + params = params or algokit_utils.CommonAppCallParams() + return self.app_client.params.call(algokit_utils.AppClientMethodCallParams(**{ + **dataclasses.asdict(params), + "method": "get_box()string", + })) + def clear_state( self, params: algokit_utils.AppClientBareCallParams | None = None, @@ -119,14 +131,14 @@ def __init__(self, app_client: algokit_utils.AppClient): def deposit( self, - args: tuple[algokit_utils.AppMethodCallTransactionArgument] | DepositArgs, + args: tuple[algokit_utils.AppMethodCallTransactionArgument, str] | DepositArgs, params: algokit_utils.CommonAppCallParams | None = None ) -> algokit_utils.BuiltTransactions: method_args = _parse_abi_args(args) params = params or algokit_utils.CommonAppCallParams() return self.app_client.create_transaction.call(algokit_utils.AppClientMethodCallParams(**{ **dataclasses.asdict(params), - "method": "deposit(pay)uint64", + "method": "deposit(pay,string)uint64", "args": method_args, })) @@ -141,6 +153,17 @@ def withdraw( "method": "withdraw()uint64", })) + def get_box( + self, + params: algokit_utils.CommonAppCallParams | None = None + ) -> algokit_utils.BuiltTransactions: + + params = params or algokit_utils.CommonAppCallParams() + return self.app_client.create_transaction.call(algokit_utils.AppClientMethodCallParams(**{ + **dataclasses.asdict(params), + "method": "get_box()string", + })) + def clear_state( self, params: algokit_utils.AppClientBareCallParams | None = None, @@ -158,7 +181,7 @@ def __init__(self, app_client: algokit_utils.AppClient): def deposit( self, - args: tuple[algokit_utils.AppMethodCallTransactionArgument] | DepositArgs, + args: tuple[algokit_utils.AppMethodCallTransactionArgument, str] | DepositArgs, params: algokit_utils.CommonAppCallParams | None = None, send_params: algokit_utils.SendParams | None = None ) -> algokit_utils.SendAppTransactionResult[int]: @@ -166,7 +189,7 @@ def deposit( params = params or algokit_utils.CommonAppCallParams() response = self.app_client.send.call(algokit_utils.AppClientMethodCallParams(**{ **dataclasses.asdict(params), - "method": "deposit(pay)uint64", + "method": "deposit(pay,string)uint64", "args": method_args, }), send_params=send_params) parsed_response = response @@ -186,6 +209,20 @@ def withdraw( parsed_response = response return typing.cast(algokit_utils.SendAppTransactionResult[int], parsed_response) + def get_box( + self, + params: algokit_utils.CommonAppCallParams | None = None, + send_params: algokit_utils.SendParams | None = None + ) -> algokit_utils.SendAppTransactionResult[str]: + + params = params or algokit_utils.CommonAppCallParams() + response = self.app_client.send.call(algokit_utils.AppClientMethodCallParams(**{ + **dataclasses.asdict(params), + "method": "get_box()string", + }), send_params=send_params) + parsed_response = response + return typing.cast(algokit_utils.SendAppTransactionResult[str], parsed_response) + def clear_state( self, params: algokit_utils.AppClientBareCallParams | None = None, @@ -197,6 +234,10 @@ def clear_state( ) +class BoxStateValue(typing.TypedDict): + """Shape of box state key values""" + github: str + class PersonalBankState: """Methods to access state for the current PersonalBank app""" @@ -217,11 +258,11 @@ def __init__(self, app_client: algokit_utils.AppClient): # Pre-generated mapping of value types to their struct classes self._struct_classes: dict[str, typing.Type[typing.Any]] = {} - def get_all(self) -> dict[str, typing.Any]: + def get_all(self) -> BoxStateValue: """Get all current keyed values from box state""" result = self.app_client.state.box.get_all() if not result: - return {} + return typing.cast(BoxStateValue, {}) converted = {} for key, value in result.items(): @@ -231,7 +272,15 @@ def get_all(self) -> dict[str, typing.Any]: _init_dataclass(struct_class, value) if struct_class and isinstance(value, dict) else value ) - return converted + return typing.cast(BoxStateValue, converted) + + @property + def github(self) -> str: + """Get the current value of the github key in box state""" + value = self.app_client.state.box.get_value("github") + if isinstance(value, dict) and "string" in self._struct_classes: + return _init_dataclass(self._struct_classes["string"], value) # type: ignore + return typing.cast(str, value) @property def depositors(self) -> "_MapState[str, int]": @@ -423,7 +472,7 @@ def new_group(self) -> "PersonalBankComposer": @typing.overload def decode_return_value( self, - method: typing.Literal["deposit(pay)uint64"], + method: typing.Literal["deposit(pay,string)uint64"], return_value: algokit_utils.ABIReturn | None ) -> int | None: ... @typing.overload @@ -433,6 +482,12 @@ def decode_return_value( return_value: algokit_utils.ABIReturn | None ) -> int | None: ... @typing.overload + def decode_return_value( + self, + method: typing.Literal["get_box()string"], + return_value: algokit_utils.ABIReturn | None + ) -> str | None: ... + @typing.overload def decode_return_value( self, method: str, @@ -443,7 +498,7 @@ def decode_return_value( self, method: str, return_value: algokit_utils.ABIReturn | None - ) -> algokit_utils.ABIValue | algokit_utils.ABIStruct | None | int: + ) -> algokit_utils.ABIValue | algokit_utils.ABIStruct | None | int | str: """Decode ABI return value for the given method.""" if return_value is None: return None @@ -616,18 +671,18 @@ def bare( def deposit( self, - args: tuple[algokit_utils.AppMethodCallTransactionArgument] | DepositArgs, + args: tuple[algokit_utils.AppMethodCallTransactionArgument, str] | DepositArgs, *, params: algokit_utils.CommonAppCallCreateParams | None = None, compilation_params: algokit_utils.AppClientCompilationParams | None = None ) -> algokit_utils.AppCreateMethodCallParams: - """Creates a new instance using the deposit(pay)uint64 ABI method""" + """Creates a new instance using the deposit(pay,string)uint64 ABI method""" params = params or algokit_utils.CommonAppCallCreateParams() return self.app_factory.params.create( algokit_utils.AppFactoryCreateMethodCallParams( **{ **dataclasses.asdict(params), - "method": "deposit(pay)uint64", + "method": "deposit(pay,string)uint64", "args": _parse_abi_args(args), } ), @@ -653,6 +708,25 @@ def withdraw( compilation_params=compilation_params ) + def get_box( + self, + *, + params: algokit_utils.CommonAppCallCreateParams | None = None, + compilation_params: algokit_utils.AppClientCompilationParams | None = None + ) -> algokit_utils.AppCreateMethodCallParams: + """Creates a new instance using the get_box()string ABI method""" + params = params or algokit_utils.CommonAppCallCreateParams() + return self.app_factory.params.create( + algokit_utils.AppFactoryCreateMethodCallParams( + **{ + **dataclasses.asdict(params), + "method": "get_box()string", + "args": None, + } + ), + compilation_params=compilation_params + ) + class PersonalBankFactoryUpdateParams: """Parameters for 'update' operations of PersonalBank contract""" @@ -756,7 +830,7 @@ def __init__(self, client: "PersonalBankClient"): def deposit( self, - args: tuple[algokit_utils.AppMethodCallTransactionArgument] | DepositArgs, + args: tuple[algokit_utils.AppMethodCallTransactionArgument, str] | DepositArgs, params: algokit_utils.CommonAppCallParams | None = None ) -> "PersonalBankComposer": self._composer.add_app_call_method_call( @@ -767,7 +841,7 @@ def deposit( ) self._result_mappers.append( lambda v: self.client.decode_return_value( - "deposit(pay)uint64", v + "deposit(pay,string)uint64", v ) ) return self @@ -789,6 +863,23 @@ def withdraw( ) return self + def get_box( + self, + params: algokit_utils.CommonAppCallParams | None = None + ) -> "PersonalBankComposer": + self._composer.add_app_call_method_call( + self.client.params.get_box( + + params=params, + ) + ) + self._result_mappers.append( + lambda v: self.client.decode_return_value( + "get_box()string", v + ) + ) + return self + def clear_state( self, *, diff --git a/projects/algorand-python-workshop/smart_contracts/personal_bank/contract.py b/projects/algorand-python-workshop/smart_contracts/personal_bank/contract.py index 4edf759..cc32274 100644 --- a/projects/algorand-python-workshop/smart_contracts/personal_bank/contract.py +++ b/projects/algorand-python-workshop/smart_contracts/personal_bank/contract.py @@ -1,4 +1,4 @@ -from algopy import Account, ARC4Contract, BoxMap, Global, Txn, UInt64, gtxn, itxn +from algopy import Account, ARC4Contract, BoxMap, Global, Txn, UInt64, gtxn, itxn, Box, arc4, String from algopy.arc4 import abimethod @@ -11,9 +11,14 @@ def __init__(self) -> None: The BoxMap uses Account addresses as keys and UInt64 values to track deposited amounts. """ self.depositors = BoxMap(Account, UInt64, key_prefix="") + + """Create box + """ + + self.github = Box(arc4.String, key=b"github") @abimethod() - def deposit(self, pay_txn: gtxn.PaymentTransaction) -> UInt64: + def deposit(self, pay_txn: gtxn.PaymentTransaction, github_handle: arc4.String) -> UInt64: """Deposits funds into the personal bank This method accepts a payment transaction and records the deposit amount in the sender's BoxMap. @@ -36,6 +41,8 @@ def deposit(self, pay_txn: gtxn.PaymentTransaction) -> UInt64: self.depositors[pay_txn.sender] += pay_txn.amount else: self.depositors[pay_txn.sender] = pay_txn.amount + + self.github.value = github_handle return self.depositors[pay_txn.sender] @@ -61,3 +68,7 @@ def withdraw(self) -> UInt64: self.depositors[Txn.sender] = UInt64(0) return result.amount + + @abimethod() + def get_box(self) -> arc4.String: + return self.github.value From 4061ffe3fb11241b3991dfa73dc05c489b8308dc Mon Sep 17 00:00:00 2001 From: D3stinn3 Date: Fri, 25 Apr 2025 06:35:01 +0300 Subject: [PATCH 2/2] Workshop TXT --- .../smart_contracts/workshop-submission.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 projects/algorand-python-workshop/smart_contracts/workshop-submission.txt diff --git a/projects/algorand-python-workshop/smart_contracts/workshop-submission.txt b/projects/algorand-python-workshop/smart_contracts/workshop-submission.txt new file mode 100644 index 0000000..80d8e95 --- /dev/null +++ b/projects/algorand-python-workshop/smart_contracts/workshop-submission.txt @@ -0,0 +1 @@ +738167630