diff --git a/projects/TokenizeRWATemplate-contracts/smart_contracts/artifacts/hello_world/HelloWorld.approval.puya.map b/projects/TokenizeRWATemplate-contracts/smart_contracts/artifacts/hello_world/HelloWorld.approval.puya.map new file mode 100644 index 0000000..ac885db --- /dev/null +++ b/projects/TokenizeRWATemplate-contracts/smart_contracts/artifacts/hello_world/HelloWorld.approval.puya.map @@ -0,0 +1,416 @@ +{ + "version": 3, + "sources": [ + "../../hello_world/contract.algo.ts" + ], + "mappings": ";AAEA;;AAAA;;;AAAA;;;;;;AAAA;;;AAAA;;;;AAAA;AACE;;AAAA;AAAA;;AAAA;AAAA;AAAA;;;AADF;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AACE;;;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;;AACS;;;;;;;;;AAAA;AAAA;AADT;AAAA;AAAA;AAAA;;;AAAA;AAAA;AAAA;;;;;;AAAA;AAAA;AAAA;AAAA;;AAAA", + "op_pc_offset": 0, + "pc_events": { + "1": { + "subroutine": "@algorandfoundation/algorand-typescript/arc4/index.d.ts::Contract.approvalProgram", + "params": {}, + "block": "main", + "stack_in": [], + "op": "txn NumAppArgs", + "defined_out": [ + "tmp%0#1" + ], + "stack_out": [ + "tmp%0#1" + ] + }, + "3": { + "op": "bz main___algots__.defaultCreate@5", + "stack_out": [] + }, + "6": { + "op": "pushbytes 0x02bece11 // method \"hello(string)string\"", + "defined_out": [ + "Method(hello(string)string)" + ], + "stack_out": [ + "Method(hello(string)string)" + ] + }, + "12": { + "op": "txna ApplicationArgs 0", + "defined_out": [ + "Method(hello(string)string)", + "tmp%2#0" + ], + "stack_out": [ + "Method(hello(string)string)", + "tmp%2#0" + ] + }, + "15": { + "op": "match main_hello_route@3", + "stack_out": [] + }, + "19": { + "op": "err" + }, + "20": { + "block": "main_hello_route@3", + "stack_in": [], + "op": "txn OnCompletion", + "defined_out": [ + "tmp%3#0" + ], + "stack_out": [ + "tmp%3#0" + ] + }, + "22": { + "op": "!", + "defined_out": [ + "tmp%4#0" + ], + "stack_out": [ + "tmp%4#0" + ] + }, + "23": { + "op": "txn ApplicationID", + "defined_out": [ + "tmp%4#0", + "tmp%5#0" + ], + "stack_out": [ + "tmp%4#0", + "tmp%5#0" + ] + }, + "25": { + "op": "&&", + "defined_out": [ + "tmp%7#0" + ], + "stack_out": [ + "tmp%7#0" + ] + }, + "26": { + "error": "OnCompletion must be NoOp && can only call when not creating", + "op": "assert // OnCompletion must be NoOp && can only call when not creating", + "stack_out": [] + }, + "27": { + "op": "b hello" + }, + "30": { + "block": "main___algots__.defaultCreate@5", + "stack_in": [], + "op": "txn OnCompletion", + "defined_out": [ + "tmp%8#0" + ], + "stack_out": [ + "tmp%8#0" + ] + }, + "32": { + "op": "!", + "defined_out": [ + "tmp%9#0" + ], + "stack_out": [ + "tmp%9#0" + ] + }, + "33": { + "op": "txn ApplicationID", + "defined_out": [ + "tmp%10#0", + "tmp%9#0" + ], + "stack_out": [ + "tmp%9#0", + "tmp%10#0" + ] + }, + "35": { + "op": "!", + "defined_out": [ + "tmp%11#0", + "tmp%9#0" + ], + "stack_out": [ + "tmp%9#0", + "tmp%11#0" + ] + }, + "36": { + "op": "&&", + "defined_out": [ + "tmp%12#0" + ], + "stack_out": [ + "tmp%12#0" + ] + }, + "37": { + "error": "OnCompletion must be NoOp && can only call when creating", + "op": "assert // OnCompletion must be NoOp && can only call when creating", + "stack_out": [] + }, + "38": { + "op": "pushint 1 // 1", + "defined_out": [ + "1" + ], + "stack_out": [ + "1" + ] + }, + "40": { + "op": "return", + "stack_out": [] + }, + "41": { + "subroutine": "smart_contracts/hello_world/contract.algo.ts::HelloWorld.hello[routing]", + "params": {}, + "block": "hello", + "stack_in": [], + "op": "txna ApplicationArgs 1", + "defined_out": [ + "tmp%0#0" + ], + "stack_out": [ + "tmp%0#0" + ] + }, + "44": { + "op": "dup", + "defined_out": [ + "tmp%0#0", + "tmp%0#0 (copy)" + ], + "stack_out": [ + "tmp%0#0", + "tmp%0#0 (copy)" + ] + }, + "45": { + "op": "pushint 0 // 0", + "defined_out": [ + "0", + "tmp%0#0", + "tmp%0#0 (copy)" + ], + "stack_out": [ + "tmp%0#0", + "tmp%0#0 (copy)", + "0" + ] + }, + "47": { + "error": "invalid array length header", + "op": "extract_uint16 // on error: invalid array length header", + "defined_out": [ + "aggregate%array_length%0#0", + "tmp%0#0" + ], + "stack_out": [ + "tmp%0#0", + "aggregate%array_length%0#0" + ] + }, + "48": { + "op": "pushint 2 // 2", + "defined_out": [ + "2", + "aggregate%array_length%0#0", + "tmp%0#0" + ], + "stack_out": [ + "tmp%0#0", + "aggregate%array_length%0#0", + "2" + ] + }, + "50": { + "op": "+", + "defined_out": [ + "add%0#0", + "tmp%0#0" + ], + "stack_out": [ + "tmp%0#0", + "add%0#0" + ] + }, + "51": { + "op": "dig 1", + "stack_out": [ + "tmp%0#0", + "add%0#0", + "tmp%0#0 (copy)" + ] + }, + "53": { + "op": "len", + "defined_out": [ + "add%0#0", + "len%0#0", + "tmp%0#0" + ], + "stack_out": [ + "tmp%0#0", + "add%0#0", + "len%0#0" + ] + }, + "54": { + "op": "==", + "defined_out": [ + "eq%0#0", + "tmp%0#0" + ], + "stack_out": [ + "tmp%0#0", + "eq%0#0" + ] + }, + "55": { + "error": "invalid number of bytes for arc4.dynamic_array", + "op": "assert // invalid number of bytes for arc4.dynamic_array", + "stack_out": [ + "tmp%0#0" + ] + }, + "56": { + "op": "extract 2 0", + "defined_out": [ + "name#0" + ], + "stack_out": [ + "name#0" + ] + }, + "59": { + "op": "pushbytes \"Hello, \"", + "defined_out": [ + "\"Hello, \"", + "name#0" + ], + "stack_out": [ + "name#0", + "\"Hello, \"" + ] + }, + "68": { + "op": "swap", + "stack_out": [ + "\"Hello, \"", + "name#0" + ] + }, + "69": { + "op": "concat", + "stack_out": [ + "tmp%0#0" + ] + }, + "70": { + "op": "dup", + "stack_out": [ + "tmp%0#0", + "tmp%0#0 (copy)" + ] + }, + "71": { + "op": "len", + "defined_out": [ + "aggregate%length%0#0", + "tmp%0#0" + ], + "stack_out": [ + "tmp%0#0", + "aggregate%length%0#0" + ] + }, + "72": { + "op": "itob", + "defined_out": [ + "aggregate%as_bytes%0#0", + "tmp%0#0" + ], + "stack_out": [ + "tmp%0#0", + "aggregate%as_bytes%0#0" + ] + }, + "73": { + "op": "extract 6 2", + "defined_out": [ + "aggregate%length_uint16%0#0", + "tmp%0#0" + ], + "stack_out": [ + "tmp%0#0", + "aggregate%length_uint16%0#0" + ] + }, + "76": { + "op": "swap", + "stack_out": [ + "aggregate%length_uint16%0#0", + "tmp%0#0" + ] + }, + "77": { + "op": "concat", + "defined_out": [ + "aggregate%encoded_value%0#0" + ], + "stack_out": [ + "aggregate%encoded_value%0#0" + ] + }, + "78": { + "op": "pushbytes 0x151f7c75", + "defined_out": [ + "0x151f7c75", + "aggregate%encoded_value%0#0" + ], + "stack_out": [ + "aggregate%encoded_value%0#0", + "0x151f7c75" + ] + }, + "84": { + "op": "swap", + "stack_out": [ + "0x151f7c75", + "aggregate%encoded_value%0#0" + ] + }, + "85": { + "op": "concat", + "defined_out": [ + "tmp%4#0" + ], + "stack_out": [ + "tmp%4#0" + ] + }, + "86": { + "op": "log", + "stack_out": [] + }, + "87": { + "op": "pushint 1 // 1", + "defined_out": [ + "1" + ], + "stack_out": [ + "1" + ] + }, + "89": { + "op": "return", + "stack_out": [] + } + } +} \ No newline at end of file diff --git a/projects/TokenizeRWATemplate-contracts/smart_contracts/artifacts/hello_world/HelloWorld.approval.teal b/projects/TokenizeRWATemplate-contracts/smart_contracts/artifacts/hello_world/HelloWorld.approval.teal new file mode 100644 index 0000000..83100f4 --- /dev/null +++ b/projects/TokenizeRWATemplate-contracts/smart_contracts/artifacts/hello_world/HelloWorld.approval.teal @@ -0,0 +1,71 @@ +#pragma version 11 +#pragma typetrack false + +// @algorandfoundation/algorand-typescript/arc4/index.d.ts::Contract.approvalProgram() -> uint64: +main: + // smart_contracts/hello_world/contract.algo.ts:3 + // export class HelloWorld extends Contract { + txn NumAppArgs + bz main___algots__.defaultCreate@5 + pushbytes 0x02bece11 // method "hello(string)string" + txna ApplicationArgs 0 + match main_hello_route@3 + err + +main_hello_route@3: + // smart_contracts/hello_world/contract.algo.ts:4 + // public hello(name: string): string { + txn OnCompletion + ! + txn ApplicationID + && + assert // OnCompletion must be NoOp && can only call when not creating + b hello + +main___algots__.defaultCreate@5: + // smart_contracts/hello_world/contract.algo.ts:3 + // export class HelloWorld extends Contract { + txn OnCompletion + ! + txn ApplicationID + ! + && + assert // OnCompletion must be NoOp && can only call when creating + pushint 1 // 1 + return + + +// smart_contracts/hello_world/contract.algo.ts::HelloWorld.hello[routing]() -> void: +hello: + // smart_contracts/hello_world/contract.algo.ts:4 + // public hello(name: string): string { + txna ApplicationArgs 1 + dup + pushint 0 // 0 + extract_uint16 // on error: invalid array length header + pushint 2 // 2 + + + dig 1 + len + == + assert // invalid number of bytes for arc4.dynamic_array + extract 2 0 + // smart_contracts/hello_world/contract.algo.ts:5 + // return `Hello, ${name}` + pushbytes "Hello, " + swap + concat + // smart_contracts/hello_world/contract.algo.ts:4 + // public hello(name: string): string { + dup + len + itob + extract 6 2 + swap + concat + pushbytes 0x151f7c75 + swap + concat + log + pushint 1 // 1 + return diff --git a/projects/TokenizeRWATemplate-contracts/smart_contracts/artifacts/hello_world/HelloWorld.arc32.json b/projects/TokenizeRWATemplate-contracts/smart_contracts/artifacts/hello_world/HelloWorld.arc32.json new file mode 100644 index 0000000..be7a4a6 --- /dev/null +++ b/projects/TokenizeRWATemplate-contracts/smart_contracts/artifacts/hello_world/HelloWorld.arc32.json @@ -0,0 +1,55 @@ +{ + "hints": { + "hello(string)string": { + "call_config": { + "no_op": "CALL" + } + } + }, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDExCiNwcmFnbWEgdHlwZXRyYWNrIGZhbHNlCgovLyBAYWxnb3JhbmRmb3VuZGF0aW9uL2FsZ29yYW5kLXR5cGVzY3JpcHQvYXJjNC9pbmRleC5kLnRzOjpDb250cmFjdC5hcHByb3ZhbFByb2dyYW0oKSAtPiB1aW50NjQ6Cm1haW46CiAgICAvLyBzbWFydF9jb250cmFjdHMvaGVsbG9fd29ybGQvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgSGVsbG9Xb3JsZCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBtYWluX19fYWxnb3RzX18uZGVmYXVsdENyZWF0ZUA1CiAgICBwdXNoYnl0ZXMgMHgwMmJlY2UxMSAvLyBtZXRob2QgImhlbGxvKHN0cmluZylzdHJpbmciCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBtYWluX2hlbGxvX3JvdXRlQDMKICAgIGVycgoKbWFpbl9oZWxsb19yb3V0ZUAzOgogICAgLy8gc21hcnRfY29udHJhY3RzL2hlbGxvX3dvcmxkL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gcHVibGljIGhlbGxvKG5hbWU6IHN0cmluZyk6IHN0cmluZyB7CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgJiYKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gbXVzdCBiZSBOb09wICYmIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIGIgaGVsbG8KCm1haW5fX19hbGdvdHNfXy5kZWZhdWx0Q3JlYXRlQDU6CiAgICAvLyBzbWFydF9jb250cmFjdHMvaGVsbG9fd29ybGQvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgSGVsbG9Xb3JsZCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICAmJgogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBtdXN0IGJlIE5vT3AgJiYgY2FuIG9ubHkgY2FsbCB3aGVuIGNyZWF0aW5nCiAgICBwdXNoaW50IDEgLy8gMQogICAgcmV0dXJuCgoKLy8gc21hcnRfY29udHJhY3RzL2hlbGxvX3dvcmxkL2NvbnRyYWN0LmFsZ28udHM6OkhlbGxvV29ybGQuaGVsbG9bcm91dGluZ10oKSAtPiB2b2lkOgpoZWxsbzoKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9oZWxsb193b3JsZC9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIHB1YmxpYyBoZWxsbyhuYW1lOiBzdHJpbmcpOiBzdHJpbmcgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZHVwCiAgICBwdXNoaW50IDAgLy8gMAogICAgZXh0cmFjdF91aW50MTYgLy8gb24gZXJyb3I6IGludmFsaWQgYXJyYXkgbGVuZ3RoIGhlYWRlcgogICAgcHVzaGludCAyIC8vIDIKICAgICsKICAgIGRpZyAxCiAgICBsZW4KICAgID09CiAgICBhc3NlcnQgLy8gaW52YWxpZCBudW1iZXIgb2YgYnl0ZXMgZm9yIGFyYzQuZHluYW1pY19hcnJheTxhcmM0LnVpbnQ4PgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9oZWxsb193b3JsZC9jb250cmFjdC5hbGdvLnRzOjUKICAgIC8vIHJldHVybiBgSGVsbG8sICR7bmFtZX1gCiAgICBwdXNoYnl0ZXMgIkhlbGxvLCAiCiAgICBzd2FwCiAgICBjb25jYXQKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9oZWxsb193b3JsZC9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIHB1YmxpYyBoZWxsbyhuYW1lOiBzdHJpbmcpOiBzdHJpbmcgewogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIHB1c2hieXRlcyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgcHVzaGludCAxIC8vIDEKICAgIHJldHVybgo=", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDExCiNwcmFnbWEgdHlwZXRyYWNrIGZhbHNlCgovLyBAYWxnb3JhbmRmb3VuZGF0aW9uL2FsZ29yYW5kLXR5cGVzY3JpcHQvYmFzZS1jb250cmFjdC5kLnRzOjpCYXNlQ29udHJhY3QuY2xlYXJTdGF0ZVByb2dyYW0oKSAtPiB1aW50NjQ6Cm1haW46CiAgICBwdXNoaW50IDEgLy8gMQogICAgcmV0dXJuCg==" + }, + "state": { + "global": { + "num_byte_slices": 0, + "num_uints": 0 + }, + "local": { + "num_byte_slices": 0, + "num_uints": 0 + } + }, + "schema": { + "global": { + "declared": {}, + "reserved": {} + }, + "local": { + "declared": {}, + "reserved": {} + } + }, + "contract": { + "name": "HelloWorld", + "methods": [ + { + "name": "hello", + "args": [ + { + "type": "string", + "name": "name" + } + ], + "readonly": false, + "returns": { + "type": "string" + } + } + ], + "networks": {} + }, + "bare_call_config": { + "no_op": "CREATE" + } +} \ No newline at end of file diff --git a/projects/TokenizeRWATemplate-contracts/smart_contracts/artifacts/hello_world/HelloWorld.arc56.json b/projects/TokenizeRWATemplate-contracts/smart_contracts/artifacts/hello_world/HelloWorld.arc56.json new file mode 100644 index 0000000..50455a9 --- /dev/null +++ b/projects/TokenizeRWATemplate-contracts/smart_contracts/artifacts/hello_world/HelloWorld.arc56.json @@ -0,0 +1,113 @@ +{ + "name": "HelloWorld", + "structs": {}, + "methods": [ + { + "name": "hello", + "args": [ + { + "type": "string", + "name": "name" + } + ], + "returns": { + "type": "string" + }, + "actions": { + "create": [], + "call": [ + "NoOp" + ] + }, + "readonly": false, + "events": [], + "recommendations": {} + } + ], + "arcs": [ + 22, + 28 + ], + "networks": {}, + "state": { + "schema": { + "global": { + "ints": 0, + "bytes": 0 + }, + "local": { + "ints": 0, + "bytes": 0 + } + }, + "keys": { + "global": {}, + "local": {}, + "box": {} + }, + "maps": { + "global": {}, + "local": {}, + "box": {} + } + }, + "bareActions": { + "create": [ + "NoOp" + ], + "call": [] + }, + "sourceInfo": { + "approval": { + "sourceInfo": [ + { + "pc": [ + 37 + ], + "errorMessage": "OnCompletion must be NoOp && can only call when creating" + }, + { + "pc": [ + 26 + ], + "errorMessage": "OnCompletion must be NoOp && can only call when not creating" + }, + { + "pc": [ + 47 + ], + "errorMessage": "invalid array length header" + }, + { + "pc": [ + 55 + ], + "errorMessage": "invalid number of bytes for arc4.dynamic_array" + } + ], + "pcOffsetMethod": "none" + }, + "clear": { + "sourceInfo": [], + "pcOffsetMethod": "none" + } + }, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDExCiNwcmFnbWEgdHlwZXRyYWNrIGZhbHNlCgovLyBAYWxnb3JhbmRmb3VuZGF0aW9uL2FsZ29yYW5kLXR5cGVzY3JpcHQvYXJjNC9pbmRleC5kLnRzOjpDb250cmFjdC5hcHByb3ZhbFByb2dyYW0oKSAtPiB1aW50NjQ6Cm1haW46CiAgICAvLyBzbWFydF9jb250cmFjdHMvaGVsbG9fd29ybGQvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgSGVsbG9Xb3JsZCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBtYWluX19fYWxnb3RzX18uZGVmYXVsdENyZWF0ZUA1CiAgICBwdXNoYnl0ZXMgMHgwMmJlY2UxMSAvLyBtZXRob2QgImhlbGxvKHN0cmluZylzdHJpbmciCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBtYWluX2hlbGxvX3JvdXRlQDMKICAgIGVycgoKbWFpbl9oZWxsb19yb3V0ZUAzOgogICAgLy8gc21hcnRfY29udHJhY3RzL2hlbGxvX3dvcmxkL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gcHVibGljIGhlbGxvKG5hbWU6IHN0cmluZyk6IHN0cmluZyB7CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgJiYKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gbXVzdCBiZSBOb09wICYmIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIGIgaGVsbG8KCm1haW5fX19hbGdvdHNfXy5kZWZhdWx0Q3JlYXRlQDU6CiAgICAvLyBzbWFydF9jb250cmFjdHMvaGVsbG9fd29ybGQvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgSGVsbG9Xb3JsZCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICAmJgogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBtdXN0IGJlIE5vT3AgJiYgY2FuIG9ubHkgY2FsbCB3aGVuIGNyZWF0aW5nCiAgICBwdXNoaW50IDEgLy8gMQogICAgcmV0dXJuCgoKLy8gc21hcnRfY29udHJhY3RzL2hlbGxvX3dvcmxkL2NvbnRyYWN0LmFsZ28udHM6OkhlbGxvV29ybGQuaGVsbG9bcm91dGluZ10oKSAtPiB2b2lkOgpoZWxsbzoKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9oZWxsb193b3JsZC9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIHB1YmxpYyBoZWxsbyhuYW1lOiBzdHJpbmcpOiBzdHJpbmcgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZHVwCiAgICBwdXNoaW50IDAgLy8gMAogICAgZXh0cmFjdF91aW50MTYgLy8gb24gZXJyb3I6IGludmFsaWQgYXJyYXkgbGVuZ3RoIGhlYWRlcgogICAgcHVzaGludCAyIC8vIDIKICAgICsKICAgIGRpZyAxCiAgICBsZW4KICAgID09CiAgICBhc3NlcnQgLy8gaW52YWxpZCBudW1iZXIgb2YgYnl0ZXMgZm9yIGFyYzQuZHluYW1pY19hcnJheTxhcmM0LnVpbnQ4PgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9oZWxsb193b3JsZC9jb250cmFjdC5hbGdvLnRzOjUKICAgIC8vIHJldHVybiBgSGVsbG8sICR7bmFtZX1gCiAgICBwdXNoYnl0ZXMgIkhlbGxvLCAiCiAgICBzd2FwCiAgICBjb25jYXQKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9oZWxsb193b3JsZC9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIHB1YmxpYyBoZWxsbyhuYW1lOiBzdHJpbmcpOiBzdHJpbmcgewogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIHB1c2hieXRlcyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgcHVzaGludCAxIC8vIDEKICAgIHJldHVybgo=", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDExCiNwcmFnbWEgdHlwZXRyYWNrIGZhbHNlCgovLyBAYWxnb3JhbmRmb3VuZGF0aW9uL2FsZ29yYW5kLXR5cGVzY3JpcHQvYmFzZS1jb250cmFjdC5kLnRzOjpCYXNlQ29udHJhY3QuY2xlYXJTdGF0ZVByb2dyYW0oKSAtPiB1aW50NjQ6Cm1haW46CiAgICBwdXNoaW50IDEgLy8gMQogICAgcmV0dXJuCg==" + }, + "byteCode": { + "approval": "CzEbQQAYgAQCvs4RNhoAjgEAAQAxGRQxGBBEQgALMRkUMRgUEESBAUM2GgFJgQBZgQIISwEVEkRXAgCAB0hlbGxvLCBMUEkVFlcGAkxQgAQVH3x1TFCwgQFD", + "clear": "C4EBQw==" + }, + "compilerInfo": { + "compiler": "puya", + "compilerVersion": { + "major": 5, + "minor": 3, + "patch": 2 + } + }, + "events": [], + "templateVariables": {} +} \ No newline at end of file diff --git a/projects/TokenizeRWATemplate-contracts/smart_contracts/artifacts/hello_world/HelloWorld.clear.puya.map b/projects/TokenizeRWATemplate-contracts/smart_contracts/artifacts/hello_world/HelloWorld.clear.puya.map new file mode 100644 index 0000000..bf29998 --- /dev/null +++ b/projects/TokenizeRWATemplate-contracts/smart_contracts/artifacts/hello_world/HelloWorld.clear.puya.map @@ -0,0 +1,25 @@ +{ + "version": 3, + "sources": [], + "mappings": ";;;", + "op_pc_offset": 0, + "pc_events": { + "1": { + "subroutine": "@algorandfoundation/algorand-typescript/base-contract.d.ts::BaseContract.clearStateProgram", + "params": {}, + "block": "main", + "stack_in": [], + "op": "pushint 1 // 1", + "defined_out": [ + "1" + ], + "stack_out": [ + "1" + ] + }, + "3": { + "op": "return", + "stack_out": [] + } + } +} \ No newline at end of file diff --git a/projects/TokenizeRWATemplate-contracts/smart_contracts/artifacts/hello_world/HelloWorld.clear.teal b/projects/TokenizeRWATemplate-contracts/smart_contracts/artifacts/hello_world/HelloWorld.clear.teal new file mode 100644 index 0000000..42f81b0 --- /dev/null +++ b/projects/TokenizeRWATemplate-contracts/smart_contracts/artifacts/hello_world/HelloWorld.clear.teal @@ -0,0 +1,7 @@ +#pragma version 11 +#pragma typetrack false + +// @algorandfoundation/algorand-typescript/base-contract.d.ts::BaseContract.clearStateProgram() -> uint64: +main: + pushint 1 // 1 + return diff --git a/projects/TokenizeRWATemplate-contracts/smart_contracts/artifacts/hello_world/HelloWorldClient.ts b/projects/TokenizeRWATemplate-contracts/smart_contracts/artifacts/hello_world/HelloWorldClient.ts new file mode 100644 index 0000000..34dfd09 --- /dev/null +++ b/projects/TokenizeRWATemplate-contracts/smart_contracts/artifacts/hello_world/HelloWorldClient.ts @@ -0,0 +1,580 @@ +/* eslint-disable */ +/** + * This file was automatically generated by @algorandfoundation/algokit-client-generator. + * DO NOT MODIFY IT BY HAND. + * requires: @algorandfoundation/algokit-utils: ^7 + */ +import { type AlgorandClient } from '@algorandfoundation/algokit-utils/types/algorand-client' +import { ABIReturn, AppReturn, SendAppTransactionResult } from '@algorandfoundation/algokit-utils/types/app' +import { Arc56Contract, getArc56ReturnValue, getABIStructFromABITuple } from '@algorandfoundation/algokit-utils/types/app-arc56' +import { + AppClient as _AppClient, + AppClientMethodCallParams, + AppClientParams, + AppClientBareCallParams, + CallOnComplete, + AppClientCompilationParams, + ResolveAppClientByCreatorAndName, + ResolveAppClientByNetwork, + CloneAppClientParams, +} from '@algorandfoundation/algokit-utils/types/app-client' +import { AppFactory as _AppFactory, AppFactoryAppClientParams, AppFactoryResolveAppClientByCreatorAndNameParams, AppFactoryDeployParams, AppFactoryParams, CreateSchema } from '@algorandfoundation/algokit-utils/types/app-factory' +import { TransactionComposer, AppCallMethodCall, AppMethodCallTransactionArgument, SimulateOptions, RawSimulateOptions, SkipSignaturesSimulateOptions } from '@algorandfoundation/algokit-utils/types/composer' +import { SendParams, SendSingleTransactionResult, SendAtomicTransactionComposerResults } from '@algorandfoundation/algokit-utils/types/transaction' +import { Address, encodeAddress, modelsv2, OnApplicationComplete, Transaction, TransactionSigner } from 'algosdk' + +export const APP_SPEC: Arc56Contract = {"name":"HelloWorld","structs":{},"methods":[{"name":"hello","args":[{"type":"string","name":"name"}],"returns":{"type":"string"},"actions":{"create":[],"call":["NoOp"]},"readonly":false,"events":[],"recommendations":{}}],"arcs":[22,28],"networks":{},"state":{"schema":{"global":{"ints":0,"bytes":0},"local":{"ints":0,"bytes":0}},"keys":{"global":{},"local":{},"box":{}},"maps":{"global":{},"local":{},"box":{}}},"bareActions":{"create":["NoOp"],"call":[]},"sourceInfo":{"approval":{"sourceInfo":[{"pc":[37],"errorMessage":"OnCompletion must be NoOp && can only call when creating"},{"pc":[26],"errorMessage":"OnCompletion must be NoOp && can only call when not creating"},{"pc":[47],"errorMessage":"invalid array length header"},{"pc":[55],"errorMessage":"invalid number of bytes for arc4.dynamic_array"}],"pcOffsetMethod":"none"},"clear":{"sourceInfo":[],"pcOffsetMethod":"none"}},"source":{"approval":"I3ByYWdtYSB2ZXJzaW9uIDExCiNwcmFnbWEgdHlwZXRyYWNrIGZhbHNlCgovLyBAYWxnb3JhbmRmb3VuZGF0aW9uL2FsZ29yYW5kLXR5cGVzY3JpcHQvYXJjNC9pbmRleC5kLnRzOjpDb250cmFjdC5hcHByb3ZhbFByb2dyYW0oKSAtPiB1aW50NjQ6Cm1haW46CiAgICAvLyBzbWFydF9jb250cmFjdHMvaGVsbG9fd29ybGQvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgSGVsbG9Xb3JsZCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBtYWluX19fYWxnb3RzX18uZGVmYXVsdENyZWF0ZUA1CiAgICBwdXNoYnl0ZXMgMHgwMmJlY2UxMSAvLyBtZXRob2QgImhlbGxvKHN0cmluZylzdHJpbmciCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBtYWluX2hlbGxvX3JvdXRlQDMKICAgIGVycgoKbWFpbl9oZWxsb19yb3V0ZUAzOgogICAgLy8gc21hcnRfY29udHJhY3RzL2hlbGxvX3dvcmxkL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gcHVibGljIGhlbGxvKG5hbWU6IHN0cmluZyk6IHN0cmluZyB7CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgJiYKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gbXVzdCBiZSBOb09wICYmIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIGIgaGVsbG8KCm1haW5fX19hbGdvdHNfXy5kZWZhdWx0Q3JlYXRlQDU6CiAgICAvLyBzbWFydF9jb250cmFjdHMvaGVsbG9fd29ybGQvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgSGVsbG9Xb3JsZCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICAmJgogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBtdXN0IGJlIE5vT3AgJiYgY2FuIG9ubHkgY2FsbCB3aGVuIGNyZWF0aW5nCiAgICBwdXNoaW50IDEgLy8gMQogICAgcmV0dXJuCgoKLy8gc21hcnRfY29udHJhY3RzL2hlbGxvX3dvcmxkL2NvbnRyYWN0LmFsZ28udHM6OkhlbGxvV29ybGQuaGVsbG9bcm91dGluZ10oKSAtPiB2b2lkOgpoZWxsbzoKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9oZWxsb193b3JsZC9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIHB1YmxpYyBoZWxsbyhuYW1lOiBzdHJpbmcpOiBzdHJpbmcgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZHVwCiAgICBwdXNoaW50IDAgLy8gMAogICAgZXh0cmFjdF91aW50MTYgLy8gb24gZXJyb3I6IGludmFsaWQgYXJyYXkgbGVuZ3RoIGhlYWRlcgogICAgcHVzaGludCAyIC8vIDIKICAgICsKICAgIGRpZyAxCiAgICBsZW4KICAgID09CiAgICBhc3NlcnQgLy8gaW52YWxpZCBudW1iZXIgb2YgYnl0ZXMgZm9yIGFyYzQuZHluYW1pY19hcnJheTxhcmM0LnVpbnQ4PgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9oZWxsb193b3JsZC9jb250cmFjdC5hbGdvLnRzOjUKICAgIC8vIHJldHVybiBgSGVsbG8sICR7bmFtZX1gCiAgICBwdXNoYnl0ZXMgIkhlbGxvLCAiCiAgICBzd2FwCiAgICBjb25jYXQKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9oZWxsb193b3JsZC9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIHB1YmxpYyBoZWxsbyhuYW1lOiBzdHJpbmcpOiBzdHJpbmcgewogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIHB1c2hieXRlcyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgcHVzaGludCAxIC8vIDEKICAgIHJldHVybgo=","clear":"I3ByYWdtYSB2ZXJzaW9uIDExCiNwcmFnbWEgdHlwZXRyYWNrIGZhbHNlCgovLyBAYWxnb3JhbmRmb3VuZGF0aW9uL2FsZ29yYW5kLXR5cGVzY3JpcHQvYmFzZS1jb250cmFjdC5kLnRzOjpCYXNlQ29udHJhY3QuY2xlYXJTdGF0ZVByb2dyYW0oKSAtPiB1aW50NjQ6Cm1haW46CiAgICBwdXNoaW50IDEgLy8gMQogICAgcmV0dXJuCg=="},"byteCode":{"approval":"CzEbQQAYgAQCvs4RNhoAjgEAAQAxGRQxGBBEQgALMRkUMRgUEESBAUM2GgFJgQBZgQIISwEVEkRXAgCAB0hlbGxvLCBMUEkVFlcGAkxQgAQVH3x1TFCwgQFD","clear":"C4EBQw=="},"events":[],"templateVariables":{}} as unknown as Arc56Contract + +/** + * A state record containing binary data + */ +export interface BinaryState { + /** + * Gets the state value as a Uint8Array + */ + asByteArray(): Uint8Array | undefined + /** + * Gets the state value as a string + */ + asString(): string | undefined +} + +class BinaryStateValue implements BinaryState { + constructor(private value: Uint8Array | undefined) {} + + asByteArray(): Uint8Array | undefined { + return this.value + } + + asString(): string | undefined { + return this.value !== undefined ? Buffer.from(this.value).toString('utf-8') : undefined + } +} + +/** + * Expands types for IntelliSense so they are more human readable + * See https://stackoverflow.com/a/69288824 + */ +export type Expand = T extends (...args: infer A) => infer R + ? (...args: Expand) => Expand + : T extends infer O + ? { [K in keyof O]: O[K] } + : never + + +/** + * The argument types for the HelloWorld contract + */ +export type HelloWorldArgs = { + /** + * The object representation of the arguments for each method + */ + obj: { + 'hello(string)string': { + name: string + } + } + /** + * The tuple representation of the arguments for each method + */ + tuple: { + 'hello(string)string': [name: string] + } +} + +/** + * The return type for each method + */ +export type HelloWorldReturns = { + 'hello(string)string': string +} + +/** + * Defines the types of available calls and state of the HelloWorld smart contract. + */ +export type HelloWorldTypes = { + /** + * Maps method signatures / names to their argument and return types. + */ + methods: + & Record<'hello(string)string' | 'hello', { + argsObj: HelloWorldArgs['obj']['hello(string)string'] + argsTuple: HelloWorldArgs['tuple']['hello(string)string'] + returns: HelloWorldReturns['hello(string)string'] + }> +} + +/** + * Defines the possible abi call signatures. + */ +export type HelloWorldSignatures = keyof HelloWorldTypes['methods'] +/** + * Defines the possible abi call signatures for methods that return a non-void value. + */ +export type HelloWorldNonVoidMethodSignatures = keyof HelloWorldTypes['methods'] extends infer T ? T extends keyof HelloWorldTypes['methods'] ? MethodReturn extends void ? never : T : never : never +/** + * Defines an object containing all relevant parameters for a single call to the contract. + */ +export type CallParams = Expand< + Omit & + { + /** The args for the ABI method call, either as an ordered array or an object */ + args: Expand + } +> +/** + * Maps a method signature from the HelloWorld smart contract to the method's arguments in either tuple or struct form + */ +export type MethodArgs = HelloWorldTypes['methods'][TSignature]['argsObj' | 'argsTuple'] +/** + * Maps a method signature from the HelloWorld smart contract to the method's return type + */ +export type MethodReturn = HelloWorldTypes['methods'][TSignature]['returns'] + + +/** + * Defines supported create method params for this smart contract + */ +export type HelloWorldCreateCallParams = + | Expand +/** + * Defines arguments required for the deploy method. + */ +export type HelloWorldDeployParams = Expand & { + /** + * Create transaction parameters to use if a create needs to be issued as part of deployment; use `method` to define ABI call (if available) or leave out for a bare call (if available) + */ + createParams?: HelloWorldCreateCallParams +}> + + +/** + * Exposes methods for constructing `AppClient` params objects for ABI calls to the HelloWorld smart contract + */ +export abstract class HelloWorldParamsFactory { + /** + * Constructs a no op call for the hello(string)string ABI method + * + * @param params Parameters for the call + * @returns An `AppClientMethodCallParams` object for the call + */ + static hello(params: CallParams & CallOnComplete): AppClientMethodCallParams & CallOnComplete { + return { + ...params, + method: 'hello(string)string' as const, + args: Array.isArray(params.args) ? params.args : [params.args.name], + } + } +} + +/** + * A factory to create and deploy one or more instance of the HelloWorld smart contract and to create one or more app clients to interact with those (or other) app instances + */ +export class HelloWorldFactory { + /** + * The underlying `AppFactory` for when you want to have more flexibility + */ + public readonly appFactory: _AppFactory + + /** + * Creates a new instance of `HelloWorldFactory` + * + * @param params The parameters to initialise the app factory with + */ + constructor(params: Omit) { + this.appFactory = new _AppFactory({ + ...params, + appSpec: APP_SPEC, + }) + } + + /** The name of the app (from the ARC-32 / ARC-56 app spec or override). */ + public get appName() { + return this.appFactory.appName + } + + /** The ARC-56 app spec being used */ + get appSpec() { + return APP_SPEC + } + + /** A reference to the underlying `AlgorandClient` this app factory is using. */ + public get algorand(): AlgorandClient { + return this.appFactory.algorand + } + + /** + * Returns a new `AppClient` client for an app instance of the given ID. + * + * Automatically populates appName, defaultSender and source maps from the factory + * if not specified in the params. + * @param params The parameters to create the app client + * @returns The `AppClient` + */ + public getAppClientById(params: AppFactoryAppClientParams) { + return new HelloWorldClient(this.appFactory.getAppClientById(params)) + } + + /** + * Returns a new `AppClient` client, resolving the app by creator address and name + * using AlgoKit app deployment semantics (i.e. looking for the app creation transaction note). + * + * Automatically populates appName, defaultSender and source maps from the factory + * if not specified in the params. + * @param params The parameters to create the app client + * @returns The `AppClient` + */ + public async getAppClientByCreatorAndName( + params: AppFactoryResolveAppClientByCreatorAndNameParams, + ) { + return new HelloWorldClient(await this.appFactory.getAppClientByCreatorAndName(params)) + } + + /** + * Idempotently deploys the HelloWorld smart contract. + * + * @param params The arguments for the contract calls and any additional parameters for the call + * @returns The deployment result + */ + public async deploy(params: HelloWorldDeployParams = {}) { + const result = await this.appFactory.deploy({ + ...params, + }) + return { result: result.result, appClient: new HelloWorldClient(result.appClient) } + } + + /** + * Get parameters to create transactions (create and deploy related calls) for the current app. A good mental model for this is that these parameters represent a deferred transaction creation. + */ + readonly params = { + /** + * Gets available create methods + */ + create: { + /** + * Creates a new instance of the HelloWorld smart contract using a bare call. + * + * @param params The params for the bare (raw) call + * @returns The params for a create call + */ + bare: (params?: Expand) => { + return this.appFactory.params.bare.create(params) + }, + }, + + } + + /** + * Create transactions for the current app + */ + readonly createTransaction = { + /** + * Gets available create methods + */ + create: { + /** + * Creates a new instance of the HelloWorld smart contract using a bare call. + * + * @param params The params for the bare (raw) call + * @returns The transaction for a create call + */ + bare: (params?: Expand) => { + return this.appFactory.createTransaction.bare.create(params) + }, + }, + + } + + /** + * Send calls to the current app + */ + readonly send = { + /** + * Gets available create methods + */ + create: { + /** + * Creates a new instance of the HelloWorld smart contract using a bare call. + * + * @param params The params for the bare (raw) call + * @returns The create result + */ + bare: async (params?: Expand) => { + const result = await this.appFactory.send.bare.create(params) + return { result: result.result, appClient: new HelloWorldClient(result.appClient) } + }, + }, + + } + +} +/** + * A client to make calls to the HelloWorld smart contract + */ +export class HelloWorldClient { + /** + * The underlying `AppClient` for when you want to have more flexibility + */ + public readonly appClient: _AppClient + + /** + * Creates a new instance of `HelloWorldClient` + * + * @param appClient An `AppClient` instance which has been created with the HelloWorld app spec + */ + constructor(appClient: _AppClient) + /** + * Creates a new instance of `HelloWorldClient` + * + * @param params The parameters to initialise the app client with + */ + constructor(params: Omit) + constructor(appClientOrParams: _AppClient | Omit) { + this.appClient = appClientOrParams instanceof _AppClient ? appClientOrParams : new _AppClient({ + ...appClientOrParams, + appSpec: APP_SPEC, + }) + } + + /** + * Checks for decode errors on the given return value and maps the return value to the return type for the given method + * @returns The typed return value or undefined if there was no value + */ + decodeReturnValue(method: TSignature, returnValue: ABIReturn | undefined) { + return returnValue !== undefined ? getArc56ReturnValue>(returnValue, this.appClient.getABIMethod(method), APP_SPEC.structs) : undefined + } + + /** + * Returns a new `HelloWorldClient` client, resolving the app by creator address and name + * using AlgoKit app deployment semantics (i.e. looking for the app creation transaction note). + * @param params The parameters to create the app client + */ + public static async fromCreatorAndName(params: Omit): Promise { + return new HelloWorldClient(await _AppClient.fromCreatorAndName({...params, appSpec: APP_SPEC})) + } + + /** + * Returns an `HelloWorldClient` instance for the current network based on + * pre-determined network-specific app IDs specified in the ARC-56 app spec. + * + * If no IDs are in the app spec or the network isn't recognised, an error is thrown. + * @param params The parameters to create the app client + */ + static async fromNetwork( + params: Omit + ): Promise { + return new HelloWorldClient(await _AppClient.fromNetwork({...params, appSpec: APP_SPEC})) + } + + /** The ID of the app instance this client is linked to. */ + public get appId() { + return this.appClient.appId + } + + /** The app address of the app instance this client is linked to. */ + public get appAddress() { + return this.appClient.appAddress + } + + /** The name of the app. */ + public get appName() { + return this.appClient.appName + } + + /** The ARC-56 app spec being used */ + public get appSpec() { + return this.appClient.appSpec + } + + /** A reference to the underlying `AlgorandClient` this app client is using. */ + public get algorand(): AlgorandClient { + return this.appClient.algorand + } + + /** + * Get parameters to create transactions for the current app. A good mental model for this is that these parameters represent a deferred transaction creation. + */ + readonly params = { + /** + * Makes a clear_state call to an existing instance of the HelloWorld smart contract. + * + * @param params The params for the bare (raw) call + * @returns The clearState result + */ + clearState: (params?: Expand) => { + return this.appClient.params.bare.clearState(params) + }, + + /** + * Makes a call to the HelloWorld smart contract using the `hello(string)string` ABI method. + * + * @param params The params for the smart contract call + * @returns The call params + */ + hello: (params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC}) => { + return this.appClient.params.call(HelloWorldParamsFactory.hello(params)) + }, + + } + + /** + * Create transactions for the current app + */ + readonly createTransaction = { + /** + * Makes a clear_state call to an existing instance of the HelloWorld smart contract. + * + * @param params The params for the bare (raw) call + * @returns The clearState result + */ + clearState: (params?: Expand) => { + return this.appClient.createTransaction.bare.clearState(params) + }, + + /** + * Makes a call to the HelloWorld smart contract using the `hello(string)string` ABI method. + * + * @param params The params for the smart contract call + * @returns The call transaction + */ + hello: (params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC}) => { + return this.appClient.createTransaction.call(HelloWorldParamsFactory.hello(params)) + }, + + } + + /** + * Send calls to the current app + */ + readonly send = { + /** + * Makes a clear_state call to an existing instance of the HelloWorld smart contract. + * + * @param params The params for the bare (raw) call + * @returns The clearState result + */ + clearState: (params?: Expand) => { + return this.appClient.send.bare.clearState(params) + }, + + /** + * Makes a call to the HelloWorld smart contract using the `hello(string)string` ABI method. + * + * @param params The params for the smart contract call + * @returns The call result + */ + hello: async (params: CallParams & SendParams & {onComplete?: OnApplicationComplete.NoOpOC}) => { + const result = await this.appClient.send.call(HelloWorldParamsFactory.hello(params)) + return {...result, return: result.return as unknown as (undefined | HelloWorldReturns['hello(string)string'])} + }, + + } + + /** + * Clone this app client with different params + * + * @param params The params to use for the the cloned app client. Omit a param to keep the original value. Set a param to override the original value. Setting to undefined will clear the original value. + * @returns A new app client with the altered params + */ + public clone(params: CloneAppClientParams) { + return new HelloWorldClient(this.appClient.clone(params)) + } + + /** + * Methods to access state for the current HelloWorld app + */ + state = { + } + + public newGroup(): HelloWorldComposer { + const client = this + const composer = this.algorand.newGroup() + let promiseChain:Promise = Promise.resolve() + const resultMappers: Array any)> = [] + return { + /** + * Add a hello(string)string method call against the HelloWorld contract + */ + hello(params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC}) { + promiseChain = promiseChain.then(async () => composer.addAppCallMethodCall(await client.params.hello(params))) + resultMappers.push((v) => client.decodeReturnValue('hello(string)string', v)) + return this + }, + /** + * Add a clear state call to the HelloWorld contract + */ + clearState(params: AppClientBareCallParams) { + promiseChain = promiseChain.then(() => composer.addAppCall(client.params.clearState(params))) + return this + }, + addTransaction(txn: Transaction, signer?: TransactionSigner) { + promiseChain = promiseChain.then(() => composer.addTransaction(txn, signer)) + return this + }, + async composer() { + await promiseChain + return composer + }, + async simulate(options?: SimulateOptions) { + await promiseChain + const result = await (!options ? composer.simulate() : composer.simulate(options)) + return { + ...result, + returns: result.returns?.map((val, i) => resultMappers[i] !== undefined ? resultMappers[i]!(val) : val.returnValue) + } + }, + async send(params?: SendParams) { + await promiseChain + const result = await composer.send(params) + return { + ...result, + returns: result.returns?.map((val, i) => resultMappers[i] !== undefined ? resultMappers[i]!(val) : val.returnValue) + } + } + } as unknown as HelloWorldComposer + } +} +export type HelloWorldComposer = { + /** + * Calls the hello(string)string ABI method. + * + * @param args The arguments for the contract call + * @param params Any additional parameters for the call + * @returns The typed transaction composer so you can fluently chain multiple calls or call execute to execute all queued up transactions + */ + hello(params?: CallParams): HelloWorldComposer<[...TReturns, HelloWorldReturns['hello(string)string'] | undefined]> + + /** + * Makes a clear_state call to an existing instance of the HelloWorld smart contract. + * + * @param args The arguments for the bare call + * @returns The typed transaction composer so you can fluently chain multiple calls or call execute to execute all queued up transactions + */ + clearState(params?: AppClientBareCallParams): HelloWorldComposer<[...TReturns, undefined]> + + /** + * Adds a transaction to the composer + * + * @param txn A transaction to add to the transaction group + * @param signer The optional signer to use when signing this transaction. + */ + addTransaction(txn: Transaction, signer?: TransactionSigner): HelloWorldComposer + /** + * Returns the underlying AtomicTransactionComposer instance + */ + composer(): Promise + /** + * Simulates the transaction group and returns the result + */ + simulate(): Promise & { simulateResponse: modelsv2.SimulateResponse }> + simulate(options: SkipSignaturesSimulateOptions): Promise & { simulateResponse: modelsv2.SimulateResponse }> + simulate(options: RawSimulateOptions): Promise & { simulateResponse: modelsv2.SimulateResponse }> + /** + * Sends the transaction group to the network and returns the results + */ + send(params?: SendParams): Promise> +} +export type HelloWorldComposerResults = Expand + diff --git a/projects/TokenizeRWATemplate-frontend/package.json b/projects/TokenizeRWATemplate-frontend/package.json index de5533a..db91571 100644 --- a/projects/TokenizeRWATemplate-frontend/package.json +++ b/projects/TokenizeRWATemplate-frontend/package.json @@ -61,10 +61,10 @@ }, "scripts": { "dev": "vite", - "generate:app-clients": "algokit project link --all", - "build:dev": "npm run generate:app-clients && tsc && vite build", - "build": "tsc && vite build", - "preview": "vite preview" + "preview": "vite preview", + "typecheck": "tsc --noEmit", + "generate:app-clients": "sh -c 'command -v algokit >/dev/null 2>&1 && algokit project link --all || echo \"algokit not found; skipping client generation\"'", + "build": "npm run generate:app-clients && tsc && vite build" }, "eslintConfig": { "extends": [ diff --git a/projects/TokenizeRWATemplate-frontend/src/Layout.tsx b/projects/TokenizeRWATemplate-frontend/src/Layout.tsx index a9fa693..884db6f 100644 --- a/projects/TokenizeRWATemplate-frontend/src/Layout.tsx +++ b/projects/TokenizeRWATemplate-frontend/src/Layout.tsx @@ -7,7 +7,7 @@ import { ellipseAddress } from './utils/ellipseAddress' export default function Layout() { const [openWalletModal, setOpenWalletModal] = useState(false) - const { activeAddress, isActive } = useWallet() + const { activeAddress } = useWallet() const toggleWalletModal = () => setOpenWalletModal(!openWalletModal) diff --git a/projects/TokenizeRWATemplate-frontend/src/components/AppCalls.tsx b/projects/TokenizeRWATemplate-frontend/src/components/AppCalls.tsx index 1268994..0d80f46 100644 --- a/projects/TokenizeRWATemplate-frontend/src/components/AppCalls.tsx +++ b/projects/TokenizeRWATemplate-frontend/src/components/AppCalls.tsx @@ -1,10 +1,10 @@ +import { AlgorandClient } from '@algorandfoundation/algokit-utils' +import { OnSchemaBreak, OnUpdate } from '@algorandfoundation/algokit-utils/types/app' import { useWallet } from '@txnlab/use-wallet-react' import { useSnackbar } from 'notistack' import { useState } from 'react' -import { HelloWorldFactory } from '../contracts/HelloWorld' -import { OnSchemaBreak, OnUpdate } from '@algorandfoundation/algokit-utils/types/app' +import { HelloWorldFactory } from '../../TokenizeRWATemplate-contracts/smart_contracts/artifacts/hello_world/HelloWorldClient' import { getAlgodConfigFromViteEnvironment, getIndexerConfigFromViteEnvironment } from '../utils/network/getAlgoClientConfigs' -import { AlgorandClient } from '@algorandfoundation/algokit-utils' interface AppCallsInterface { openModal: boolean @@ -23,11 +23,20 @@ const AppCalls = ({ openModal, setModalState }: AppCallsInterface) => { algodConfig, indexerConfig, }) - algorand.setDefaultSigner(transactionSigner) + if (transactionSigner) { + // @ts-expect-error - optional API depending on algokit-utils version + algorand.setDefaultSigner?.(transactionSigner) + } const sendAppCall = async () => { setLoading(true) + if (!activeAddress || !transactionSigner) { + enqueueSnackbar('Please connect a wallet first.', { variant: 'warning' }) + setLoading(false) + return + } + // Please note, in typical production scenarios, // you wouldn't want to use deploy directly from your frontend. // Instead, you would deploy your contract on your backend and reference it by id. diff --git a/projects/TokenizeRWATemplate-frontend/src/components/ConnectWallet.tsx b/projects/TokenizeRWATemplate-frontend/src/components/ConnectWallet.tsx index 80109ff..453018f 100644 --- a/projects/TokenizeRWATemplate-frontend/src/components/ConnectWallet.tsx +++ b/projects/TokenizeRWATemplate-frontend/src/components/ConnectWallet.tsx @@ -1,4 +1,4 @@ -import { useWallet, WalletId, type BaseWallet } from '@txnlab/use-wallet-react' +import { useWallet, WalletId } from '@txnlab/use-wallet-react' import { useMemo, useState } from 'react' import { ellipseAddress } from '../utils/ellipseAddress' import { getAlgodConfigFromViteEnvironment } from '../utils/network/getAlgoClientConfigs' @@ -17,7 +17,10 @@ const ConnectWallet = ({ openModal, closeModal }: ConnectWalletProps) => { // Get network config for Lora link const algoConfig = getAlgodConfigFromViteEnvironment() - const networkName = useMemo(() => (algoConfig.network === '' ? 'localnet' : algoConfig.network.toLowerCase()), [algoConfig.network]) + const networkName = useMemo(() => { + const n = (algoConfig.network ?? '').toString() + return n === '' ? 'localnet' : n.toLowerCase() + }, [algoConfig.network]) const visibleWallets = useMemo(() => (wallets ?? []).filter(Boolean), [wallets]) @@ -31,7 +34,7 @@ const ConnectWallet = ({ openModal, closeModal }: ConnectWalletProps) => { // Capture wallet ID for logout (before disconnect clears it) const activeWalletId = activeWallet?.id - const connectWallet = async (wallet: BaseWallet) => { + const connectWallet = async (wallet: any) => { setLastError('') setConnectingKey(wallet.id) diff --git a/projects/TokenizeRWATemplate-frontend/src/components/TokenizeAsset.tsx b/projects/TokenizeRWATemplate-frontend/src/components/TokenizeAsset.tsx index 310b38b..0a39822 100644 --- a/projects/TokenizeRWATemplate-frontend/src/components/TokenizeAsset.tsx +++ b/projects/TokenizeRWATemplate-frontend/src/components/TokenizeAsset.tsx @@ -1,11 +1,11 @@ import { AlgorandClient } from '@algorandfoundation/algokit-utils' +import { useWallet } from '@txnlab/use-wallet-react' import { sha512_256 } from 'js-sha512' import { useSnackbar } from 'notistack' import { ChangeEvent, useCallback, useEffect, useMemo, useRef, useState } from 'react' import { AiOutlineCloudUpload, AiOutlineInfoCircle, AiOutlineLoading3Quarters } from 'react-icons/ai' import { BsCoin } from 'react-icons/bs' import { getAlgodConfigFromViteEnvironment } from '../utils/network/getAlgoClientConfigs' -import { useWallet } from '@txnlab/use-wallet-react' /** * Type for created assets stored in browser localStorage @@ -178,7 +178,7 @@ export default function TokenizeAsset() { // ===== use-wallet (Web3Auth OR WalletConnect) ===== // Use transactionSigner (not signer) - this is the correct property name from use-wallet const { transactionSigner, activeAddress } = useWallet() - + // Alias for backward compatibility in the code const signer = transactionSigner @@ -227,10 +227,7 @@ export default function TokenizeAsset() { let apiCallSucceeded = false try { - holding = await algorand.asset.getAccountInformation( - activeAddress, - BigInt(TESTNET_USDC_ASSET_ID), - ) + holding = await algorand.asset.getAccountInformation(activeAddress, BigInt(TESTNET_USDC_ASSET_ID)) apiCallSucceeded = true } catch (assetApiError: unknown) { // API call failed - account is likely not opted in @@ -343,12 +340,7 @@ export default function TokenizeAsset() { // 1. Actually switching TO usdc mode (not just re-render) // 2. Blockchain check is complete (status confirmed) // 3. Warning hasn't been shown already - if ( - modeChanged && - hasCheckedUsdcOnChain && - !hasShownUsdcWarningRef.current && - usdcStatus === 'not-opted-in' - ) { + if (modeChanged && hasCheckedUsdcOnChain && !hasShownUsdcWarningRef.current && usdcStatus === 'not-opted-in') { enqueueSnackbar('You are not opted in to USDC yet. Please opt in before receiving or sending USDC.', { variant: 'info', }) @@ -394,7 +386,7 @@ export default function TokenizeAsset() { enqueueSnackbar('Please connect a wallet or continue with Google first.', { variant: 'warning' }) return } - + if (!signer) { enqueueSnackbar('Wallet signer not available. Please try reconnecting your wallet.', { variant: 'error' }) return @@ -529,7 +521,7 @@ export default function TokenizeAsset() { enqueueSnackbar('Please connect a wallet or continue with Google first.', { variant: 'warning' }) return } - + if (!signer) { enqueueSnackbar('Wallet signer not available. Please try reconnecting your wallet.', { variant: 'error' }) return @@ -627,7 +619,7 @@ export default function TokenizeAsset() { enqueueSnackbar('Please connect a wallet or continue with Google first.', { variant: 'warning' }) return } - + if (!signer) { enqueueSnackbar('Wallet signer not available. Please try reconnecting your wallet.', { variant: 'error' }) return @@ -681,7 +673,7 @@ export default function TokenizeAsset() { sender: activeAddress, signer, receiver: receiverAddress, - amount: { microAlgo: Number(microAlgos) }, + amount: algorand.microAlgos(microAlgos), }) const txId = (result as { txId?: string }).txId @@ -811,7 +803,7 @@ export default function TokenizeAsset() { enqueueSnackbar('Please connect a wallet or continue with Google first.', { variant: 'warning' }) return } - + if (!signer) { enqueueSnackbar('Wallet signer not available. Please try reconnecting your wallet.', { variant: 'error' }) return