{"id":13798555,"url":"https://github.com/ulamlabs/pytealext","last_synced_at":"2025-05-13T05:32:25.046Z","repository":{"id":41313410,"uuid":"408384388","full_name":"ulamlabs/pytealext","owner":"ulamlabs","description":"Language extensions for PyTEAL on Algorand","archived":false,"fork":false,"pushed_at":"2023-02-06T12:07:11.000Z","size":151,"stargazers_count":11,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-12T12:07:50.157Z","etag":null,"topics":["algorand","pyteal","teal"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-2.1","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ulamlabs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-09-20T09:34:30.000Z","updated_at":"2024-05-17T16:52:27.000Z","dependencies_parsed_at":"2023-02-19T07:16:01.880Z","dependency_job_id":null,"html_url":"https://github.com/ulamlabs/pytealext","commit_stats":null,"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ulamlabs%2Fpytealext","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ulamlabs%2Fpytealext/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ulamlabs%2Fpytealext/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ulamlabs%2Fpytealext/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ulamlabs","download_url":"https://codeload.github.com/ulamlabs/pytealext/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253883137,"owners_count":21978611,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["algorand","pyteal","teal"],"created_at":"2024-08-04T00:00:45.865Z","updated_at":"2025-05-13T05:32:24.675Z","avatar_url":"https://github.com/ulamlabs.png","language":"Python","funding_links":[],"categories":["Developer Resources"],"sub_categories":["Tools"],"readme":"# Pyteal Extensions\nAdditional useful operations for Python\n\n## Available Operations\n- `MulDiv64`: calculate `m1*m2/d` with no overflow on multiplication (TEAL 3+)\n- `Uint64Array`: for when you need convenient integer arrays.\n- `Mul128`, `FastExp`: Optimize operations that take uints and output bytes (big ints)\n- `Min`, `Max`: calculate minimum/maximum of 2 expressions, without using slots or evaluating arguments more than once (TEAL 4+)\n- `LazyAnd`, `LazyOr`: lazily evaluate arguments in And/Or operation\n- `SaturatingAdd`, `SaturatingSub`: saturating addition/subtraction\n- `AutoLoadScratchVar`: more convenient way to use scratch variables. Removes the need to use `.load()` everytime, adds `.increment()` method.\n- [Inner Transactions](https://github.com/ulamlabs/pytealext/blob/main/docs/inner_transactions.md): simplified making of inner transactions\n    - `MakeInnerPaymentTxn`, `MakeInnerAssetTransferTxn` and more!\n    - `MakeInnerGroupTxn` to execute inner atomic group transactions\n- `SerializeIntegers`, `DeserializeIntegers`, `DeserializeIntegersToSlots`: serialize/deserialize integers to/from bytes\n- `GlobalState`, `LocalState`, `GlobalStateArray`, `LocalStateArray`, `GlobalStateArray2D`, `LocalStateArray2D`: easily access global/local state\n\n### State manipulation\n`GlobalState` and `LocalState` allow for manipulating global and local state respectively.\nThey both have the same interface.\n```python\nfrom pyteal import App, Bytes, Int, Seq, TealType\nfrom pytealext import LocalState\n\nuser_counter = LocalState(\"UC\", TealType.uint64)\nprogram = Seq(\n    # increment using pyteal local state\n    App.localPut(Int(0), Bytes(\"UC\"), App.localGet(Int(0), Bytes(\"UC\")) + Int(1)),\n    # increment using put/get\n    user_counter.put(user_counter.get() + Int(1)),\n    # increment using add_assign\n    user_counter.add_assign(Int(1))\n    # decrement\n    user_counter.sub_assign(Int(1))\n)\n```\n\nWant to simulate arrays in the global state? Use `GlobalStateArray` and `LocalStateArray`.\nTechnically, the indexes can be any uint64 value and don't have to be sequential.\nEach array element takes one slot in the local/global state.\n```python\nfrom pyteal import Assert, For, Int, Return, ScratchVar, Seq\nfrom pytealext import LocalStateArray\n\nuser_counters = LocalStateArray(\"Counters\")\n    i = ScratchVar()\n    accumulator = ScratchVar()\n    program = Seq(\n        user_counters[0].put(Int(10)),\n        user_counters[0].add_assign(Int(1)),\n        user_counters[0].sub_assign(Int(2)),\n        Assert(user_counters[0].get() == Int(9)),\n        # set some other indexes\n        user_counters[1].put(Int(9)),\n        user_counters[2].put(Int(9)),\n        # Indexes can also be accessed with Exprs\n        accumulator.store(Int(0)),\n        For(i.store(Int(0)), i.load() \u003c Int(3), i.store(i.load() + Int(1))).Do(\n            accumulator.store(accumulator.load() + user_counters[i.load()].get())\n        ),\n        Return(accumulator.load() == Int(27)),\n    )\n```\n\n## Example usage\nExample usage for `LazyAnd`:\n```python\nfrom pyteal import Gtxn, TxnType, Bytes, Int\nfrom pytealext import LazyAnd\n\n# Evaluate fields of some transaction but don't panic if an argument down the line would panic\nvalidation = LazyAnd(\n    Gtxn[0].type_enum() == TxnType.ApplicationCall,\n    Gtxn[0].application_args.length() == Int(1),\n    Gtxn[0].application_args[0] == Bytes(\"AX\"),\n)\n```\n\n## Installation\n`pip install pytealext`\n\n## Testing\n`pytest`\n\n-------\nCreated by Łukasz Ptak and Paweł Rejkowicz\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fulamlabs%2Fpytealext","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fulamlabs%2Fpytealext","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fulamlabs%2Fpytealext/lists"}