{"id":34091122,"url":"https://github.com/kadirpekel/seal","last_synced_at":"2026-04-02T01:04:59.562Z","repository":{"id":75842021,"uuid":"604652883","full_name":"kadirpekel/seal","owner":"kadirpekel","description":"Write meaningful teal in s-expressions for Algorand!","archived":false,"fork":false,"pushed_at":"2023-03-09T19:43:20.000Z","size":133,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-12-16T17:56:43.444Z","etag":null,"topics":["algorand","avm","s-expression","smartcontract","teal"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kadirpekel.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-02-21T14:11:32.000Z","updated_at":"2025-01-30T15:19:19.000Z","dependencies_parsed_at":"2023-07-26T20:33:40.768Z","dependency_job_id":null,"html_url":"https://github.com/kadirpekel/seal","commit_stats":{"total_commits":31,"total_committers":1,"mean_commits":31.0,"dds":0.0,"last_synced_commit":"50e37efd15ca4d1a59931c72185609ffd041a2d8"},"previous_names":["kadirpekel/steal"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/kadirpekel/seal","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kadirpekel%2Fseal","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kadirpekel%2Fseal/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kadirpekel%2Fseal/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kadirpekel%2Fseal/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kadirpekel","download_url":"https://codeload.github.com/kadirpekel/seal/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kadirpekel%2Fseal/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31293632,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T21:15:39.731Z","status":"ssl_error","status_checked_at":"2026-04-01T21:15:34.046Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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","avm","s-expression","smartcontract","teal"],"created_at":"2025-12-14T14:33:00.801Z","updated_at":"2026-04-02T01:04:59.546Z","avatar_url":"https://github.com/kadirpekel.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"```\n\n ██╗███████╗███████╗ █████╗ ██╗     ██╗\n██╔╝██╔════╝██╔════╝██╔══██╗██║     ╚██╗\n██║ ███████╗█████╗  ███████║██║      ██║\n██║ ╚════██║██╔══╝  ██╔══██║██║      ██║\n╚██╗███████║███████╗██║  ██║███████╗██╔╝\n ╚═╝╚══════╝╚══════╝╚═╝  ╚═╝╚══════╝╚═╝\n\n          (teal makes sense)\n```\n\n## Write meaningful teal in s-expressions!\n\nSEAL is a minimlistic language with its powerful cross-compiler designed to simplify the process of writing Algorand TEAL programs using s-expressions. With SEAL, developers can write TEAL programs in a more readable and efficient way, making it accessible to both beginners and experienced developers alike. SEAL is built to take advantage of the easy-to-read nature of s-expressions, which makes it even easier to write and read TEAL programs. This tool is perfect for anyone looking to develop on the Algorand blockchain and write smart contracts in an efficient and streamlined way.\n\nSEAL does not add any additional layers of abstraction to the TEAL language. By building upon the existing foundations of TEAL and leveraging the readability and simplicity of s-expressions, SEAL provides a unique and innovative way of writing TEAL programs that is accessible to developers of all levels of experience. SEAL is designed to preserve the core functionality and \"opcodes\" of TEAL, while making it easier to read, write, and deploy programs on the Algorand blockchain. With SEAL, developers can benefit from a more streamlined and efficient workflow, without sacrificing the power and flexibility of TEAL. If you're looking for a tool that makes writing TEAL programs more accessible and easier than ever before, then SEAL is the perfect choice.\n\nSee a minimal example below to experience how SEAL enhances the readability and ease-of-use of TEAL:\n\n```typescript\n($MAX_SIZE 10) `This is a constant, name all capitalized`\n\n($i 0) `Variable assignment`\n\n`While loop reading and incrementing $i respectively`\n(@while (\u003c $i $MAX_SIZE)\n    ($i (+ $i 1))\n)\n```\n\nSimply compile your SEAL code to convert it to a valid TEAL language.\n\n```bash\n% seal compile demo.seal \u003e demo.teal\n```\n\nOur `seal` code will be compiled into a perfectly valid, well organized `teal` file.\n\n```teal\n#pragma version 8\nint 0\nstore 0 // $i\nwhile_0:\nload 0 // $i\nint 10 // $MAX_SIZE\n\u003c\nbz while_0_end\nload 0 // $i\nint 1\n+\nstore 0 // $i\nb while_0\nwhile_0_end:\n```\n\nYou're now perfectly ready to deploy and test out your newly created smart contract.\n\n```bash\n% sandbox copyTo demo.teal\n\u003e\u003e\u003e Now copying demo.teal to Algod container\n\n% sandbox goal app create [...] --approval-prog demo.teal\n\u003e\u003e\u003e Created app with app index 1\n\n% sandbox goal app optin [...] --app-id 1\n\u003e\u003e\u003e Transaction committed!\n\n% sandbox goal app call [...] --app-id 1 --app-arg 'str:visit'\n\u003e\u003e\u003e Transaction committed!\n\n% sandbox goal app read [...] --app-id 1 --local\n\u003e\u003e\u003e {\n\u003e\u003e\u003e   \"visits\": {\n\u003e\u003e\u003e     \"tt\": 2,\n\u003e\u003e\u003e     \"ui\": 1\n\u003e\u003e\u003e   }\n\u003e\u003e\u003e }\n```\n\n## Installation\n\nTo get started with SEAL, simply follow the installation instructions below and once installed, you can start writing TEAL programs in s-expressions and use SEAL to convert them into TEAL bytecode that can be deployed to the Algorand blockchain.\n\n```bash\n% pip install seal-lang\n```\n\n## Usage\n\nCli tool can be accessed simply typing `seal` in your commmand prompt where you can find basic usage info prompted.\n\n```bash\n% seal\n\u003e\u003e\u003e usage: seal [-h] [-v] {compile,spec} ...\n\u003e\u003e\u003e\n\u003e\u003e\u003e positional arguments:\n\u003e\u003e\u003e   {compile,spec}\n\u003e\u003e\u003e\n\u003e\u003e\u003e options:\n\u003e\u003e\u003e   -h, --help      show this help message and exit\n\u003e\u003e\u003e   -v, --version   show program's version number and exit\n```\n\n`compile` subcommand is also as follows, please note the `strict` option to\nenable strict compiler checks. More information will be available soon.\n\n```\n% seal compile --help\n\u003e\u003e\u003e usage: seal compile [-h] [-p PRAGMA_VERSION] path\n\u003e\u003e\u003e\n\u003e\u003e\u003e positional arguments:\n\u003e\u003e\u003e   path\n\u003e\u003e\u003e\n\u003e\u003e\u003e optional arguments:\n\u003e\u003e\u003e   -h, --help         show this help message and exit\n\u003e\u003e\u003e   -p PRAGMA_VERSION  pragma version\n```\n\n## Documenation\n\nSEAL simplifies the process of writing smart contracts in Algorand's teal language by providing a more concise syntax for managing the stack. With SEAL, you can use embedded s-expressions to define and manipulate the stack in a more intuitive way. This makes it easier to write and maintain complex smart contracts.\n\nFor example, consider the following code in original teal:\n\n```teal\nint 1\nint 2\nint 3\n+\n+\n```\n\nThis code pushes the values 1 and 2 onto the stack, adds them together, pushes the value 3 onto the stack, and adds it to the previous result. Using SEAL, you could write the same code more concisely like this:\n\n```typescript\n(+ 1 (+ 2 3))\n```\n\nThis code uses the + operator to add the values 1, 2, and 3 together, which are all pushed onto the stack automatically. As you can see, SEAL greatly simplifies the process of writing Algorand smart contracts by providing a more intuitive syntax for stack management.\n\n### Comments\n\nIn SEAL, comments are used to document the code and improve its readability. A comment in SEAL starts with a backtick symbol \\` and ends with another backtick symbol \\`. Everything between these two symbols is ignored by the compiler and does not emit any Teal code. Here's an example:\n\n```typescript\n`This is a single-line comment`\n```\n\nYou can also write multi-line comments in SEAL by using the backtick symbol multiple times. Here's an example:\n\n```typescript\n`\nThis is a\nmulti-line\ncomment\n`\n```\n\nIt's important to note that comments should be used sparingly and only when necessary to explain the code's purpose or implementation. Overuse of comments can make the code harder to read and maintain.\n\n### Literals\n\nLiterals in SEAL are used to represent values of integers and bytes. Integers are compiled to TEAL's `int` opcode, which pushes a 64-bit unsigned integer value onto the TEAL stack, while bytes are compiled to TEAL's `byte` opcode, which pushes a byte string value onto the TEAL stack.\n\nLiterals can be used in expressions, assigned to variables, and passed as function arguments. For example:\n\n```typescript\n42\n\"Hello World\"\n```\n\nCompiles into:\n\n```teal\nint 42\nbyte \"Hello World\"\n```\n\n### Constants\n\nConstants in SEAL are defined using all capitalized names starting with a `$` sign, like `$MAX_SIZE`. Constant definitions do not emit any code by themselves. Instead, when a constant is referred to using `$CONSTANT_NAME`, the value of the constant is substituted into the literal expression they hold.\n\nFor example:\n\n```typescript\n($MAX_SIZE 42)\n($MESSAGE \"Hello, World!\")\n($TRUE 1)\n\n$MAX_SIZE\n$MESSAGE\n$TRUE\n```\n\nCompiles into:\n\n```teal\nint 42 // $MAX_SIZE\nbyte \"Hello, World!\" // $MESSAGE\nint 1 // $TRUE\n```\n\n### Variables\n\nVariables in SEAL are defined using names starting with a lower case letter and a `$` sign, like `$my_var`. When a variable is defined, the value of the assigned expression is stored in the scratch space, using an auto-incremented index to denote where it's saved. Variables can be used in expressions, assigned new values, and passed as function arguments.\n\nTo refer to a variable, use its name starting with a `$` sign. The compiled code will then load the value from scratch space by using the indexed value.\n\nFor example:\n\n```typescript\n($my_var 42)\n($another_var \"Hello, World!\")\n\n$my_var\n$another_var\n```\n\nCompiles into:\n\n```teal\nint 42\nstore 0 // $my_var\n\nbyte \"Hello, World!\"\nstore 1 // $another_var\n\nload 0 // $my_var\nload 1 // $another_var\n```\n\nPlease note that the use of variables in SEAL is limited by the scratch space available in Algorand's TEAL language. TEAL has a maximum scratch space size of 256 slots, which limits the number of variables that can be used in a smart contract. It is important to carefully manage the use of variables and their associated memory usage to ensure that your smart contract stays within the limits of the TEAL language.\n\n### Opcodes\n\nIn SEAL, any sequence of characters that is not a special syntax element (such as those starting with $ or @) will be treated as a Teal opcode. Teal opcodes are the basic building blocks of Teal programs, and are used to perform various operations on the program's state and data.\n\nHere's a simple demonstration of how opcodes are called in SEAL:\n\n```typescript\nerr\n```\n\nCompiles into:\n\n```teal\nerr\n```\n\nIf any opcode requires stack arguments, you can construct your opcode call using s-expression syntax to manage the stack. For example:\n\n```typescript\n(assert (== 5 (+ 3 2)))\n```\n\nCompiles into:\n\n```teal\nint 5\nint 3\nint 2\n+\n==\nassert\n```\n\nYou can chain and nest several opcodes using the lisp-style syntax to create more complex operations.\n\n### Non strict modifier\n\nSEAL by default assumes and checks where opcode calls are perfectly constructed by supplying the desired number of stack args. If you supply wrong number of stack args to any opcode, the compiler will complain about the situation like below:\n\n```typescript\n4\n(assert (== (+ 5) 9))\n```\n\nCompile it:\n\n```bash\n% seal compile hede.seal\nCompiler error: Invalid number of stack args\nLn: 2, Col: 16, Token: +\n```\n\nNon script modifier will let you construct the opcode calls without enforcing you to provide expected number of stack args. There might be situations where you would like to bypass this check to get a successfull compilation. SEAL provides a very handy syntax for this kind of cases where you can prefix your opcode by using a single quote `'` so that SEAL compiler won't complain. Please see the example below:\n\n```\n4\n(assert (== ('+ 5) 9))\n```\n\n### Fields \u0026 Immediate Args\n\nIn Algorand, some opcodes like `global`, `txn`, `txna`, `gtxn`, `itxn_field` and several others behave like namespaces for accessing various transactional and global data in a smart contract. Also there are many other opcodes like `substring` accepting immediate arguments such as `start` and `end` to adjust the behaviour of regarding opcode rather than stack arguments.\n\nSEAL provides a specific syntax known as dot notation allowing developers to access fields within these namespaces using the format `namespace.field1.field2`. For example, `txn.ApplicationID` accesses the `ApplicationID` field within the `txn` namespace. Or to call `substring` accompanied with immediate args like `substring.3.5`.\n\nPlease find below to find out how dot notation is used to achieve specific use cases:\n\n```typescript\n(== txna.ApplicationArgs.0 (substring.0.5 \"Hello World\"))\n```\n\nCompiles into:\n\n```teal\ntxna ApplicationArgs 0\nbyte \"Hello World\"\nsubstring 0 5\n==\n```\n\n### Conditions\n\nConditions in SEAL are used for making decisions based on certain conditions. There are two types of conditions: single conditions and compound conditions.\n\n#### Single Conditions\n\nSingle conditions are constructed using the `@case` operator. The @case operator takes its first expression as the test value and the second expression as the action to take if the test is true. For example:\n\n```typescript\n(@case\n    (== $my_var \"Hello World\")\n    (return 1)\n)\n```\n\nThis condition will return 1 if the value of the variable `$my_var` is equal to \"Hello World\".\n\n#### Compound Conditions\n\nCompound conditions are constructed using the `@in` operator. The `@in` operator expects all of its children to be `@case` statements and works exactly like \"if .. else if .. else\" conditions. For example:\n\n```typescript\n(@in\n    (@case (== $my_var \"Hello World\") (return 1))\n    (@case (== $my_var \"Goodbye World\") (return 2))\n    (return 3)\n)\n```\n\nThis condition will check the value of the variable `$my_var` against the first `@case` statement, and if it's true, it will return `1`. If it's not true, it will check the second `@case` statement, and so on. If none of the `@case` statements are true, it will return `3`.\n\n### Loops\n\n#### While loops\n\nIn SEAL, a while loop is used to repeatedly execute a block of code while a certain condition is true. The syntax for a while loop in SEAL is as follows:\n\n```\n(@while (condition)\n    (block of code)\n)\n```\n\nThe condition is an expression that evaluates to a boolean value (true or false). If the condition is true, the block of code will execute. If the condition is false, the block of code will not execute.\n\nHere's an example of a while loop in SEAL that uses a counter to iterate through a loop:\n\n```typescript\n($MAX_SIZE 10)\n($i 0)\n(@while (\u003c $i $MAX_SIZE)\n    ($i (+ $i 1))\n)\n```\n\nCompiles to:\n\n```teal\nint 0\nstore 0 // $i\nwhile_0:\nload 0 // $i\nint 10 // $MAX_SIZE\n\u003c\nbz while_0_end\nload 0 // $i\nint 1\n+\nstore 0 // $i\nb while_0\nwhile_0_end:\n```\n\nIn this example, the `($MAX_SIZE 10)` expression sets a constant MAX_SIZE to 10 where `($i 0)` expression sets a variable `i` to 0. The `(@while (\u003c $i $MAX_SIZE)` expression sets up the while loop and specifies that the loop should continue while `i` is less than `MAX_SIZE`. The `($i (+ $i 1))` expression increments the value of `i` by 1 with each iteration of the loop.\n\nIt's important to ensure that the condition in a while loop will eventually evaluate to false, otherwise the loop will run indefinitely, which can cause the program to crash.\n\n### Labels\n\nLabels in Teal are named markers that allow the program to \"jump\" to a specific point in the code. In SEAL they are defined in similar way by using the syntax `labelname:` where labelname can be any valid identifier. Labels are commonly used with branching opcodes like `b`, `bz`, `bnz`, and many more, which allow the program to change the order of execution based on the instruction.\n\nHere you may find a demonstration on how to use labels in SEAL:\n\n```typescript\n(@case\n    (== txna.ApplicationArgs.0 \"foo\")\n    b.foo\n)\nerr\n\n(foo:\n    (assert\n        (== txna.ApplicationArgs.1 \"bar\")\n    )\n)\nerr\n```\n\nCompiles into:\n\n```teal\ntxna ApplicationArgs 0\nbyte \"foo\"\n==\nbz case_0\nb foo\ncase_0:\nerr\nfoo:\ntxna ApplicationArgs 1\nbyte \"bar\"\n==\nassert\nerr\n```\n\n#### Inner Transactions\n\nSEAL introduces the `#itxn` command as a shorthand for inner transactions in Algorand TEAL. The `#itxn` command encapsulates the functionality of `itxn_begin` and `itxn_submit` statements, making it easier for developers to express inner transactions in their smart contracts. With `#itxn`, developers can use `itxn_field` to set any attribute of the inner transaction and commit it eventually.\n\n```typescript\n(@itxn\n    (itxn_field.AssetAmount 1000)\n    (itxn_field.XferAsset txna.Assets.0)\n    (itxn_field.AssetReceiver txn.Sender)\n    (itxn_field.TypeEnum int.axfer)\n)\n```\n\nCompiles into:\n\n```teal\nitxn_begin\ntxna Assets 0\nitxn_field XferAsset\ntxn Sender\nitxn_field AssetReceiver\nint axfer\nitxn_field TypeEnum\nitxn_submit\n```\n\n#### Functions / Sub routines\n\nPlease advise your idea!\n\n## Disclaimer\n\nPlease note that SEAL is currently in the early stages of development and while not tested it thoroughly, it may still contain bugs or errors. As such, use SEAL with caution, and always test your programs thoroughly before deploying them to the Algorand blockchain.\n\nThis software cannot be held responsible for any errors or issues that may arise from the use of it.\n\nIf you encounter any problems or have any questions about SEAL, please don't hesitate to reach out or raise an issue.\nYour support and feedback is very much appreciated.\n\n## TODO\n\n- Indexed field access option for numeric fields where dot notation used\n- Comprehensive unit tests\n- Function call syntax and find a way to employ sub routines\n\n## Licence\n\nCopyright (c) 2023 Kadir Pekel.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkadirpekel%2Fseal","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkadirpekel%2Fseal","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkadirpekel%2Fseal/lists"}