Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/_test_harness/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.tx3
11 changes: 11 additions & 0 deletions examples/_test_harness/devnet.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[[utxos]]
address = "@alice"
value = 100000000000

[[utxos]]
address = "@charlie"
value = 100000000000

[[utxos]]
address = "@bob"
value = 100000000000
29 changes: 29 additions & 0 deletions examples/_test_harness/main.tx3
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
party Sender;

party Receiver;

tx transfer_nft(
policy: Bytes,
asset_name: Bytes,
quantity: Int,
) {
input gas_source {
from: Sender,
min_amount: fees + min_utxo(token_target),
}

input token_source {
from: Sender,
min_amount: AnyAsset(policy, asset_name, quantity),
}

output token_target {
to: Receiver,
amount: AnyAsset(policy, asset_name, quantity) + min_utxo(token_target),
}

output change_target {
to: Sender,
amount: gas_source + token_source - AnyAsset(policy, asset_name, quantity) - min_utxo(token_target) - fees,
}
}
62 changes: 62 additions & 0 deletions examples/_test_harness/run_checks.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#!/usr/bin/env bash
# Test harness: runs `trix check` against each .tx3 example file
# Usage: ./run_checks.sh [path_to_examples_dir]

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
EXAMPLES_DIR="${1:-$(dirname "$SCRIPT_DIR")}"
HARNESS_DIR="$SCRIPT_DIR"
MAIN_TX3="$HARNESS_DIR/main.tx3"
BACKUP="$HARNESS_DIR/main.tx3.bak"

# Save original main.tx3
cp "$MAIN_TX3" "$BACKUP"

PASS=0
FAIL=0
PASS_FILES=()
FAIL_FILES=()

for tx3_file in "$EXAMPLES_DIR"/*.tx3; do
filename="$(basename "$tx3_file")"

# Copy example content into main.tx3
cp "$tx3_file" "$MAIN_TX3"

# Run trix check
if output=$(cd "$HARNESS_DIR" && trix check 2>&1); then
PASS=$((PASS + 1))
PASS_FILES+=("$filename")
else
FAIL=$((FAIL + 1))
FAIL_FILES+=("$filename")
echo "FAIL: $filename"
echo "$output" | sed 's/^/ /'
echo ""
fi
done

# Restore original main.tx3
cp "$BACKUP" "$MAIN_TX3"
rm "$BACKUP"

echo "========================================="
echo "RESULTS: $PASS passed, $FAIL failed out of $((PASS + FAIL)) files"
echo "========================================="

if [ ${#PASS_FILES[@]} -gt 0 ]; then
echo ""
echo "PASSING:"
for f in "${PASS_FILES[@]}"; do
echo " ✓ $f"
done
fi

if [ ${#FAIL_FILES[@]} -gt 0 ]; then
echo ""
echo "FAILING:"
for f in "${FAIL_FILES[@]}"; do
echo " ✗ $f"
done
fi
33 changes: 33 additions & 0 deletions examples/_test_harness/tests/basic.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
file="./main.tx3"

[[wallets]]
name = "bob"
balance = 10000000

[[wallets]]
name = "alice"
balance = 5000000

[[transactions]]
description = "bob sends 2 ada to alice"
template = "transfer"
signers = ["bob"]
args = { quantity = 2000000, sender = "@bob", receiver = "@alice" }

[[transactions]]
description = "alice sends 2 ada to bob"
template = "transfer"
signers = ["alice"]
args = { quantity = 2000000, sender = "@alice", receiver = "@bob" }

[[expect]]
from = "@bob"

[[expect.min_amount]]
amount = 9638899

[[expect]]
from = "@alice"

[[expect.min_amount]]
amount = 4638899
7 changes: 7 additions & 0 deletions examples/_test_harness/trix.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[protocol]
name = "_test_harness"
version = "0.0.0"
main = "main.tx3"

[ledger]
family = "cardano"
20 changes: 20 additions & 0 deletions examples/aspirational/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Aspirational Examples

The `.tx3` files in this directory represent real-world Cardano contract
interfaces (JPG Store, Levvy Finance, SplashDEX, etc.) written in Tx3 syntax
that is **not yet supported** by the language.

These examples are **non-functional** and will not pass `trix check`. They exist
to capture desired language features and serve as design references for future
development.

## Why these fail

| File | Unsupported features used |
|------------------------|-----------------------------------------------------------------------------------------------------------------------------|
| `jpg.tx3` | Old-style policy constructors, array type syntax (`[]`), `outputs ... as` iteration, `required_signers:`, inline `metadata` |
| `levvy.simple.tx3` | Old-style policy constructors, `PlutusAddress()`, `now()`, `valid_from`/`valid_until` |
| `levvy.tx3` | All of the above plus `batch foreach`, `filter` lambdas, `let` bindings, `if/else`, `.sum()`, `Address()` |
| `splash.tx3` | Old-style policy constructors, `Option<>`, array type syntax, `IndexOf()`, `Asset()` |
| `plutus_addresses.tx3` | `func` definitions, `return`, `if/else`, `Hash<>` generics, union types (`\|`) |
| `spans.tx3` | References non-existent fields on inputs; unbalanced transaction |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
11 changes: 10 additions & 1 deletion examples/lang_tour.tx3
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ env {
field_b: Bytes,
field_c: Bool,
field_d: List<Bytes>,
field_e: Address,
}

party MyParty;
Expand All @@ -13,6 +14,7 @@ type MyRecord {
field3: Bytes,
field4: List<Int>,
field5: Map<Int, Bytes>,
field6: Bool,
}

type MyVariant {
Expand Down Expand Up @@ -76,15 +78,21 @@ tx my_tx(
output named_output {
to: MyParty,
datum: MyRecord {
field1: quantity,
field1: quantity + -1,
field2: (54 + 10) - (8 + 2),
field4: [1, 2, 3, source.field1],
field5: {1: "Value1", 2: "Value2",},
field6: true,
...source
},
amount: AnyAsset(source.field3, source.field2, source.field1) + Ada(40) + min_utxo(named_output),
}

output? optional_change {
to: MyParty,
amount: source - Ada(40) - fees,
}

signers {
MyParty,
0x0F5B22E57FEEB5B4FD1D501B007A427C56A76884D4978FAFEF979D9C,
Expand All @@ -102,6 +110,7 @@ tx my_tx(

locals {
local_var: concat("Lang", "Tour"),
negated_flag: !field_c,
}

cardano::vote_delegation_certificate {
Expand Down
141 changes: 141 additions & 0 deletions examples/policy_variants.tx3
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
// Policy definition styles and how each is used in practice.
//
// A policy name resolves to its hash when used in expressions. This means
// you can use a policy name anywhere a policy hash (Bytes) is expected:
// in AnyAsset(), output addresses, etc.
//
// The script and ref fields provide metadata for the compiler and TII
// output but are not currently accessible as sub-properties (e.g.,
// MyPolicy.script is not supported — this is a known limitation).

// Assign syntax — just a policy hash.
policy HashOnly = 0xABCDEF1234;

// Constructor with only hash — equivalent to assign, constructor form.
policy HashConstructor {
hash: 0xABCDEF1234,
}

// Hash + inline native script CBOR. The compiler knows about the script,
// but you must still attach it as a native witness in the transaction.
policy NativeScriptPolicy {
hash: 0xbd3ae991b5aafccafe5ca70758bd36a9b2f872f57f6d3a1ffa0eb777,
script: 0x820181820400,
}

// Hash + reference UTxO. The compiler knows where the script lives on-chain,
// but you must still include the reference input in the transaction.
policy RefScriptPolicy {
hash: 0xef7a1cebb2dc7de884ddf82f8fcbc91fe9750dcd8c12ec7643a99bbe,
ref: 0xDEADBEEF1234,
}

// Named assets bind a readable name to a policy hash + asset name.
asset NativeToken = 0xbd3ae991b5aafccafe5ca70758bd36a9b2f872f57f6d3a1ffa0eb777."NATIVE";
asset RefToken = 0xef7a1cebb2dc7de884ddf82f8fcbc91fe9750dcd8c12ec7643a99bbe."REFTOKEN";

party Minter;

// Using a policy name directly in AnyAsset — NativeScriptPolicy resolves to
// its hash, so AnyAsset(NativeScriptPolicy, ...) works like
// AnyAsset(0xbd3a..., ...).
tx mint_native_named(quantity: Int) {
input source {
from: Minter,
min_amount: fees,
}

mint {
amount: AnyAsset(NativeScriptPolicy, "NATIVE", quantity),
}

output {
to: Minter,
amount: source + AnyAsset(NativeScriptPolicy, "NATIVE", quantity) - fees,
}

// Native scripts must be provided as a witness. Since we can't yet
// reference NativeScriptPolicy.script, the CBOR must be repeated here.
cardano::native_witness {
script: 0x820181820400,
}
}

// Using a named asset with its matching policy. NativeToken is bound to
// the same policy hash as NativeScriptPolicy, so this is equivalent to
// the AnyAsset form above but more readable.
tx mint_native_asset(quantity: Int) {
input source {
from: Minter,
min_amount: fees,
}

mint {
amount: NativeToken(quantity),
}

output {
to: Minter,
amount: source + NativeToken(quantity) - fees,
}

cardano::native_witness {
script: 0x820181820400,
}
}

// Minting via a plutus policy whose script lives in a reference UTxO.
// Using RefScriptPolicy in AnyAsset resolves to its hash. The reference
// input must point to the same UTxO declared in the policy's ref field.
tx mint_with_ref_dynamic(quantity: Int) {
input source {
from: Minter,
min_amount: fees,
}

reference policy_script {
ref: 0xDEADBEEF1234#0,
}

collateral {
from: Minter,
min_amount: fees,
}

mint {
amount: AnyAsset(RefScriptPolicy, "REFTOKEN", quantity),
redeemer: (),
}

output {
to: Minter,
amount: source + AnyAsset(RefScriptPolicy, "REFTOKEN", quantity) - fees,
}
}

// Same as above but using the named asset RefToken instead of AnyAsset.
tx mint_with_ref_asset(quantity: Int) {
input source {
from: Minter,
min_amount: fees,
}

reference policy_script {
ref: 0xDEADBEEF1234#0,
}

collateral {
from: Minter,
min_amount: fees,
}

mint {
amount: RefToken(quantity),
redeemer: (),
}

output {
to: Minter,
amount: source + RefToken(quantity) - fees,
}
}
1 change: 1 addition & 0 deletions examples/reference_script.tx3
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ tx publish_plutus(
cardano::publish {
to: Receiver,
amount: Ada(quantity),
datum: 0xD87980,
version: 3,
script: 0x5101010023259800a518a4d136564004ae69,
}
Expand Down
2 changes: 1 addition & 1 deletion examples/swap_static.tx3
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ tx swap(
datum: PoolState {
pair_a: pool.pair_a - ask,
pair_b: pool.pair_b + bid,
...pool.datum
...pool
},
amount: pool,
}
Expand Down
Loading