LX Language Tools
The official VS Code extension for LX, the smart contract language of the LUXA blockchain.
Write a contract once. Ship it to CosmWasm and to the EVM.
Why LX?
LX is a small, strongly typed language for smart contracts. A single .lx file compiles to:
- CosmWasm (Rust) for the native LUXA chain (
luxa-1)
- EVM (Solidity ^0.8.20) for EVM-compatible networks
Both targets are generated from the same checked AST, and fixed / confidence are 18-decimal fixed-point integers on both of them, so the same contract produces the same numbers everywhere.
This extension gives you everything you need to write LX comfortably: highlighting, snippets, one-click compilation, and live error underlines that point at the exact line and column.
Features
|
Feature |
What you get |
| 🎨 |
Syntax highlighting |
contract, state, constant, event, error, init, action, query, verify, emit, let / mut let, map[K]V, list[T], use luxa::math;, and qualified paths such as math::sqrt |
| 🔴 |
Live diagnostics |
Red underlines for syntax, name-resolution and type errors, reported with line:column, all problems at once |
| ⚡ |
One-click compile |
Compile to CosmWasm, EVM, or both side by side |
| ✂️ |
Snippets |
Contract skeletons, actions, queries, custom errors, events |
| 🧩 |
Editor support |
Bracket matching, auto-closing pairs, comment toggling, smart indentation, // #region folding |
Quick start
- Install the extension and open (or create) a
.lx or .luxa file.
- Start from a snippet: type
contract and press Tab.
- Open the Command Palette (
Ctrl+Shift+P, Cmd+Shift+P on macOS) and run LX: Compile Source.
- Pick a target. The generated code opens in a new editor beside your contract.
You can also use the ▶ button in the editor title bar, or right-click inside a .lx file.
Live diagnostics
LX errors are underlined as you type, with the same positions the compiler reports.
action unstake(amount: u256) {
verify stake[caller] >= amount, InsufficientStake(amount);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error `InsufficientStake` requires 2 arguments, found 1
}
What is checked
| Stage |
Examples |
| Parse |
Missing ;, unexpected tokens, malformed types or tuples |
| Check |
Unknown identifiers, functions, events and errors; wrong argument counts; unknown use modules; assignments to constants or builtins; reserved names (sender, caller, height, time, value); event fields starting with _ |
| Types |
u64 vs u256 mixing, assignment to a non-mut variable, wrong fixed-point scaling, non-bool conditions, state changes inside a query |
How the underline is placed
- Declarations (
state, constant, event, error, parameters, use) are underlined at the declared name.
- Statements are underlined from their first token to the end of the line. Expressions do not carry their own position, so an error inside
a = colar; highlights the statement, not only colar.
- Syntax errors underline just the unexpected token.
- Columns are converted from UTF-8 bytes to editor characters, so accents or Arabic text earlier on the line do not shift the underline.
Stages run in cascade. If parsing fails you get that one error. If name checking finds problems, type checking waits until they are fixed. Within a stage you see every problem, not just the first.
Setting up diagnostics (Local luxac Binary)
Diagnostics run the local luxac compiler in --diagnostics mode and read its JSON output. The document text is sent to stdin, so unsaved changes are checked live.
Prebuilt Binaries & Verification Hashes
Pre-compiled standalone binaries can be built from source or verified from official releases:
| Platform |
Binary / Executable |
SHA-256 Checksum |
| 🪟 Windows (x64) |
luxac.exe (zip) |
B92920EDFE98F2C5B89FB4E9215D10ACF17538C2397CC37A8E8FA84CC67B05CE |
Note on Windows SmartScreen: Because luxac.exe is an independent open-source binary and not signed with an enterprise EV code-signing certificate, Windows Defender SmartScreen may display a warning on first execution. Click More info -> Run anyway, or compile directly from source:
ash cd core/luxa-compiler cargo build --release
(Prebuilt Linux and macOS standalone archives will be published alongside the official GitHub release workflow).
Alternatively, compile directly from source: cargo build --release in core/luxa-compiler.
Configuring the Path
Set the executable path in your VS Code settings.json:
// luxac is on your system PATH (default)
"lx.luxacPath": "luxac",
// or specify an explicit absolute path
"lx.luxacPath": "C:\tools\luxac\luxac.exe"
Diagnostics can be disabled with "lx.diagnostics.enable": false. Set "lx.diagnostics.delay" to adjust the debounce interval (in milliseconds).
Compiling
LX: Compile Source sends the active file to the LUXA cloud compiler and opens the result.
| Target |
Output |
Notes |
| CosmWasm (Rust) |
cw-storage-plus, CosmWasm std |
Native to luxa-1 |
| EVM (Solidity) |
^0.8.20, mappings, events |
For EVM-compatible networks |
| Both (Dual View) |
Two editors side by side |
Handy for comparing the targets |
Compilation errors from the cloud compiler are shown as a notification. For precise in-editor underlines, set up diagnostics.
Cloud Compiler Privacy & Custom Endpoints
By default, compilation calls the high-speed serverless service at https://compiler.luxaecosystem.xyz/api/compile.
- Compiler Data Retention: Source code is not retained or stored by the compiler service. Requests are processed transiently in memory to generate CosmWasm and Solidity artifacts and returned immediately. (To ensure reverse proxies, web servers, or intermediate CDNs never inspect request payloads, configure a self-hosted or local endpoint).
- Custom / Self-Hosted Endpoint: To keep all code strictly within a private network or air-gapped machine, launch a local compiler server and configure
settings.json:
// Self-hosted local or private corporate compiler endpoint
"lx.compilerEndpoint": "http://localhost:8080/api/compile"
The LX language at a glance
version = 1.0;
use luxa::math;
contract Staking {
state {
stake: map[address]u256;
last: map[address]u64;
}
constant COOLDOWN: u64 = 60;
error InsufficientStake(have: u256, need: u256);
error Cooldown(remaining: u64);
event Unstaked(who: address, amount: u256, at: u64);
action unstake(amount: u256) {
verify stake[caller] >= amount, InsufficientStake(stake[caller], amount);
verify time >= last[caller] + COOLDOWN, Cooldown(last[caller] + COOLDOWN - time);
stake[caller] -= amount;
last[caller] = time;
emit Unstaked(caller, amount, time);
}
query stake_of(who: address) -> u256 {
return stake[who];
}
}
Types
| Type |
Meaning |
u64, u256 |
Unsigned integers. Mixing them requires an explicit cast: u256(x), u64(x) |
bool, string, address, bytes32 |
Basic types |
fixed, confidence |
18-decimal fixed-point numbers, identical on both targets |
map[K]V, list[T] |
Collections |
(T1, T2, ...) |
Tuples, only as the return type of a query |
Context builtins
caller (alias sender), time, height, value. These names are reserved and cannot be redefined. value is not available inside a query.
Statements
let x = ...; declares an immutable variable, mut let x = ...; a mutable one. Other statements: assignment (=, +=, -=, *=, /=), if / else, verify cond, message;, emit Event(...);, return.
verify accepts a string literal or a declared custom error, which is cheaper on gas.
Built-in Functions
| Function |
Signature |
Description |
fibo(n) |
fibo(n: u64) -> u256 |
Computes the $n$-th Fibonacci number as u256. Bounded to $n \le 90$ on both CosmWasm and Solidity to prevent overflow and long loops. |
transfer(to, amount) |
transfer(to: address, amount: u256) |
Transfers native uluxa tokens from contract reserves to recipient. |
u64(x), u256(x) |
u64(...), u256(...) |
Explicit integer casting. |
Native funds (CosmWasm)
| Function |
Arguments |
Description |
funds(denom) |
1 |
Amount of denom sent with the call |
funds_count() |
0 |
Number of distinct denoms sent |
send(to, denom, amount) |
3 |
Send amount of denom to an address |
transfer(to, amount) |
2 |
Send uluxa |
CosmWasm only. EVM has no native denoms, so the generated Solidity contains a deliberately undeclared identifier (LX_ERROR_funds_is_cosmwasm_only_use_ERC20_on_EVM). solc then fails with a clear message instead of silently compiling wrong code. Use ERC20 on EVM.
Standard library
Import with use luxa::math;, then call math::sqrt(x) or the full path luxa::math::sqrt(x). Only the helpers you actually call are emitted into the generated code.
| Module |
Functions |
luxa::math |
sqrt, pow, min, max, abs |
luxa::string |
concat, len |
Rules enforced by the compiler
- A
query cannot modify state, emit events, or use value, and every path must return a value.
- Only a
query may declare a return type.
- Function parameters and
constants are not assignable.
neural.verify is rejected: the chain is deterministic, so verify proofs off-chain.
- Event field names cannot start with
_ (reserved by CosmWasm).
Snippets
Type the prefix and press Tab.
| Prefix |
Result |
contract |
Full contract skeleton |
action |
State-changing function |
query |
Read-only function |
error |
Custom error |
verify_err |
verify with a custom error |
emit |
Emit an on-chain event |
use |
Import a std module such as luxa::math |
Commands
| Command |
ID |
Where |
| LX: Compile Source |
lx.compileContract |
Command Palette, editor title bar, editor context menu |
Extension settings
| Setting |
Default |
Description |
lx.luxacPath |
"luxac" |
Path to the local luxac executable for live in-editor diagnostics. |
lx.compilerEndpoint |
"https://compiler.luxaecosystem.xyz/api/compile" |
Endpoint URL for the LX compiler service. ⚠️ Warning: Contract source code is transmitted over HTTP(S) to this address; only point this setting to a server you trust. |
lx.diagnostics.enable |
true |
Show diagnostics while editing, opening, and saving LX documents. |
lx.diagnostics.delay |
300 |
Delay in milliseconds after the last edit before re-checking. |
Troubleshooting
| Problem |
Fix |
| No underlines appear |
Check that the file is recognised as LX (bottom-right language indicator), lx.diagnostics.enable is true, and lx.luxacPath points to a working luxac. |
| "Cannot find the luxac executable" warning |
The executable was not found. Use an absolute path in lx.luxacPath. |
| Underlines lag behind typing |
Increase lx.diagnostics.delay. |
| "Unable to reach cloud compiler" |
The compile command needs network access to compiler.luxaecosystem.xyz. Diagnostics do not use it. |
| An error highlights the whole statement |
Expressions have no position of their own yet; the statement start is the most precise location available. |
Known limitations
- Error positions are per statement or declaration, not per sub-expression.
- Type checking runs only after name checking passes.
- The cloud compile command shows a single error message, without positions.
Contributing
Issues and pull requests are welcome at github.com/luxaecosystem/luxa-lang.
Release notes
0.2.10
- Corrected Snippets: Updated all snippet definitions to valid LX syntax (
map[address]u256;, semicolons, and correct types).
- Custom Compiler Endpoint: Added
lx.compilerEndpoint setting for private, offline, or self-hosted compilation.
- Prebuilt Binaries: Added direct download links for Windows, macOS, and Linux standalone
luxac binaries.
- English Documentation: Standardized all extension snippets and metadata to English.
0.2.9
- Improved cloud compilation requests by sending the source in both
source and code fields.
- Read and report compiler error details from JSON responses, including HTTP error statuses.
- Handle empty or invalid JSON responses without hiding the compilation error.
0.2.8
- Live in-editor diagnostics for syntax, name-resolution, and type errors.
- Run
luxac - --diagnostics via stdin so unsaved editor contents are checked.
- Convert UTF-8 byte columns to VS Code UTF-16 positions, including Arabic and other multibyte text.
- Highlight declarations such as
state, constant, event, error, parameters, and use.
0.2.7
- Release packaging and initial diagnostics integration.
0.2.6
- Syntax highlighting, snippets and cloud compilation for LX
License
MIT
| |