diff --git a/Cargo.lock b/Cargo.lock
index 140daec..38da55c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -607,7 +607,7 @@ checksum = "382ce8820a5bb815055d3553a610e8cb542b2d767bbacea99038afda96cd760d"
[[package]]
name = "cshell"
-version = "0.11.1"
+version = "0.12.0"
dependencies = [
"anyhow",
"backoff",
@@ -3589,9 +3589,9 @@ dependencies = [
[[package]]
name = "tx3-cardano"
-version = "0.11.4"
+version = "0.11.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca5f14e3e1b68b1bff81d58c891604a3087f34be70c2a2ad58a8605b6f15ed82"
+checksum = "9532e9d3e4f40b02b88023c082bd1e27c3e3467bb6a749f7b261e82712b0941c"
dependencies = [
"hex",
"pallas",
@@ -3604,9 +3604,9 @@ dependencies = [
[[package]]
name = "tx3-lang"
-version = "0.11.4"
+version = "0.11.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7607218726810f53079b50a63ff4b5e25a8ccf53a82a80d7b6cc1815feec7a65"
+checksum = "f9ffdc30232bfe0bfeced3d48768b8f00ed9f3015d9e78323ecda4cf45cbbd56"
dependencies = [
"bincode",
"hex",
diff --git a/Cargo.toml b/Cargo.toml
index 7611b22..df81caa 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -10,12 +10,12 @@ repository = "https://github.com/txpipe/cshell"
license = "Apache-2.0"
homepage = "https://docs.txpipe.io/cshell"
-keywords = ["cardano", "blockchain", "wallet", "cardano"]
+keywords = ["cardano", "blockchain", "wallet"]
categories = ["command-line-utilities", "blockchain", "cardano", "wallet"]
[dependencies]
-tx3-lang = "0.11.1"
-tx3-cardano = "0.11.1"
+tx3-lang = "0.11.5"
+tx3-cardano = "0.11.5"
tx3-sdk = "^0"
# tx3-lang = { git = "https://github.com/tx3-lang/tx3.git" }
diff --git a/docs/commands/_meta.yml b/docs/commands/_meta.yml
new file mode 100644
index 0000000..cf38a40
--- /dev/null
+++ b/docs/commands/_meta.yml
@@ -0,0 +1,3 @@
+label: Commands
+order: 5
+collapsed: true
\ No newline at end of file
diff --git a/docs/commands/search.mdx b/docs/commands/search.mdx
new file mode 100644
index 0000000..641724c
--- /dev/null
+++ b/docs/commands/search.mdx
@@ -0,0 +1,305 @@
+---
+title: Search Commands
+sidebar:
+ order: 6
+ label: search
+---
+
+import { Aside, CardGrid, LinkCard, Tabs, TabItem } from '@astrojs/starlight/components';
+
+The `search` command allows you to query blockchain data directly from the command line. You can search for blocks and transactions using various parameters.
+
+
+
+## Available Commands
+
+- **`search block`**: Query block information by tx-hash,slot
+- **`search transaction`**: Query transaction details by hash
+
+## Output Formats
+
+All search commands support multiple output formats:
+
+```bash
+# Table format (default)
+cshell search block
+
+# JSON format
+cshell search block --output-format json
+```
+
+### Supported Formats
+
+- **table**: Human-readable table format (default)
+- **json**: Machine-readable JSON format
+
+
+
+---
+
+## search block
+
+The `search block` command queries blockchain data to retrieve information about a specific block.
+
+### Usage
+
+```bash
+cshell search block
+```
+
+### Options
+
+Run `cshell search block --help` to see all available options.
+
+#### Output Format
+
+Use the `--output-format` flag to change the output format:
+
+```bash
+cshell search block --output-format json
+```
+
+Supported formats:
+- `table` (default): Human-readable table
+- `json`: Machine-readable JSON
+
+### Block Identifiers
+
+You can search for blocks using:
+
+```bash
+cshell search block 9a28855928d8a94ac0ec7a5c0a45298cdbf939d1f302deb2b9e54bafb48789f4,91460405
+```
+
+### Examples
+
+#### Basic Block Query
+
+
+
+```bash
+cshell search block
+```
+
+Output:
+```
+┌──────────────┬────┬───────────────────────────────────┬────────┬─────────┬──────────────┬────────────┬────────┐
+│ Block │ │ Hash │ Inputs │ Outputs │ Certificates │ Ref Inputs │ Datum │
+├──────────────┼────┼───────────────────────────────────┼────────┼─────────┼──────────────┼────────────┼────────┤
+│ 8f3a...1f2 │ 0 │ 7b2c3d4e5f6a7b8c9d0e1f2a3b4c5... │ 2 │ 3 │ 0 │ 0 │ empty │
+│ 8f3a...1f2 │ 1 │ 9c1d2e3f4a5b6c7d8e9f0a1b2c3d4... │ 1 │ 2 │ 0 │ 0 │ empty │
+└──────────────┴────┴───────────────────────────────────┴────────┴─────────┴──────────────┴────────────┴────────┘
+```
+
+
+```bash
+cshell search block --output-format json
+```
+
+Output:
+```json
+{
+ "auxiliary": {},
+ "collateral": {},
+ "fee": "200000",
+ "hash": "....",
+ "inputs": [
+ ...
+ ],
+ "outputs": [
+ ...
+ ],
+ "successful": true,
+ "validity": {},
+ "witnesses": {
+ ...
+ }
+}
+```
+
+
+
+#### Export Block Data
+
+Save block data to a file for later analysis:
+
+```bash
+cshell search block --output-format json > block-data.json
+```
+
+---
+
+## search transaction
+
+The `search transaction` command queries blockchain data to retrieve detailed information about a specific transaction.
+
+### Usage
+
+```bash
+cshell search transaction
+```
+
+### Options
+
+Run `cshell search transaction --help` to see all available options.
+
+#### Output Format
+
+Use the `--output-format` flag to change the output format:
+
+```bash
+cshell search transaction --output-format json
+```
+
+Supported formats:
+- `table` (default): Human-readable table
+- `json`: Machine-readable JSON
+
+### Examples
+
+#### Basic Transaction Query
+
+
+
+```bash
+cshell search transaction ef6350af39d35caa3130218f8fb103fa6bb585258d52366966ede8da2100d3c1
+```
+
+Output:
+```
+┌──────────────┬────┬───────────────────────────────────┬────────┬─────────┬──────────────┬────────────┬─────────┐
+│ Block │ │ Hash │ Inputs │ Outputs │ Certificates │ Ref Inputs │ Datum │
+├──────────────┼────┼───────────────────────────────────┼────────┼─────────┼──────────────┼────────────┼─────────┤
+│ f55c...19db │ 0 │ ef6350af39d35caa3130218f8fb10... │ 1 │ 2 │ 0 │ 1 │ contain │
+└──────────────┴────┴───────────────────────────────────┴────────┴─────────┴──────────────┴────────────┴─────────┘
+```
+
+
+```bash
+cshell search transaction --output-format json
+```
+
+Output:
+```json
+{
+ "auxiliary": {},
+ "collateral": {},
+ "fee": "174389",
+ "hash": "72NQrznTXKoxMCGPj7ED+mu1hSWNUjZpZu3o2iEA08E=",
+ "inputs": [
+ {
+ "outputIndex": 1,
+ "txHash": "2IQhCcVhqReK7BKTf604tlW/mG1LyDA3tKfX4eE9XBY="
+ }
+ ],
+ "outputs": [
+ {
+ "address": "cIe32DcyeHxWkqWXPdWwJEdAYiQQa6InY+6DaNY=",
+ "coin": "30000000",
+ "datum": {
+ ...
+ }
+ },
+ {
+ "address": "AFmvO2CJMAJJi9D8hL1k+Eh+7LDfhFrZ5gkyqoZ06yLq0b9uxm0QfpFnclhfG8g5C3ZJj74KBTZe",
+ "coin": "9729302444",
+ "datum": {}
+ }
+ ],
+ "referenceInputs": [
+ ...
+ ],
+ "successful": true,
+ "validity": {},
+ "witnesses": {
+ ...
+ }
+}
+```
+
+
+
+#### Export Transaction Data
+
+Save transaction details to a file:
+
+```bash
+cshell search transaction --output-format json > transaction.json
+```
+
+#### Check Transaction Outputs
+
+Extract specific outputs from a transaction:
+
+```bash
+cshell search transaction --output-format json | jq '.outputs'
+```
+
+### Use Cases
+
+#### 1. Transaction Confirmation
+
+Verify your submitted transaction:
+
+```bash
+cshell search transaction
+```
+
+If found, the transaction was successfully submitted and confirmed.
+
+#### 2. UTxO Verification
+
+Check if a specific UTxO exists and is unspent:
+
+```bash
+cshell search transaction --output-format json | jq '.outputs[0]'
+```
+
+#### 3. Payment Verification
+
+Confirm payment was received:
+
+```bash
+# Search for transaction
+cshell search transaction --output-format json
+
+# Check outputs for your address
+jq '.outputs[] | select(.address == "addr1...")' transaction.json
+```
+
+#### 4. Smart Contract Debugging
+
+Inspect transaction datum and redeemers:
+
+```bash
+cshell search transaction --output-format json | jq '.outputs[].datum'
+```
+
+#### 5. Token Verification
+
+Check native token transfers:
+
+```bash
+cshell search transaction --output-format json | jq '.outputs[].assets'
+```
+
+## Quick Reference
+
+
+
+## Related Commands
+
+- [`tx invoke`](/cshell/commands/tx) - Submit transactions
+- [`wallet balance`](/cshell/wallet) - Check wallet balance
+- [`explorer`](/cshell/explorer) - Visual block and transaction explorer
diff --git a/docs/commands/tx.mdx b/docs/commands/tx.mdx
new file mode 100644
index 0000000..3a0af8a
--- /dev/null
+++ b/docs/commands/tx.mdx
@@ -0,0 +1,374 @@
+---
+title: Transaction Commands
+sidebar:
+ order: 0
+ label: tx
+---
+
+import { Aside, CardGrid, LinkCard, Tabs, TabItem } from '@astrojs/starlight/components';
+
+The `tx` command (or `transactions`) provides a complete workflow for managing Cardano transactions in Cshell. You can execute transactions using [**tx3**](https://docs.txpipe.io/tx3) files, or work with individual steps of the transaction lifecycle.
+
+
+
+## Transaction Workflow
+
+Understanding the transaction lifecycle:
+
+1. **Write**: Create a tx3 file describing your transaction
+2. **Resolve**: Convert tx3 to CBOR format (handled by TRP)
+3. **Sign**: Add cryptographic signatures using your wallet
+4. **Submit**: Send the transaction to the blockchain
+
+The `tx invoke` command handles all these steps automatically, while individual commands let you control each step separately for advanced use cases.
+
+## Available Commands
+
+- **`tx invoke`**: Resolve, sign, and submit a tx3 transaction in one step
+- **`tx construct`**: Build transactions interactively or programmatically
+- **`tx resolve`**: Resolve a tx3 transaction to CBOR
+- **`tx sign`**: Sign a CBOR transaction
+- **`tx submit`**: Submit a CBOR transaction to the blockchain
+
+---
+
+## tx invoke
+
+The `tx invoke` command executes a complete transaction workflow: resolving a tx3 file, signing it with your wallet, and submitting it to the blockchain.
+
+### Usage
+
+```bash
+cshell tx invoke --tx3-file
+```
+
+### Options
+
+Run `cshell tx invoke --help` to see all available options.
+
+#### Using with Different Provider
+
+You can specify a different provider using flags:
+
+```bash
+cshell tx invoke --tx3-file ./transfer.tx3 --provider testnet
+```
+
+### How it Works
+
+When you run `tx invoke`, Cshell:
+
+1. **Reads** your tx3 file
+2. **Resolves** the transaction via your configured TRP server
+3. **Signs** the transaction using the appropriate wallet(s)
+4. **Submits** the signed transaction to the blockchain
+5. **Returns** the transaction hash
+
+
+
+---
+
+## tx construct
+
+The `tx construct` command provides tools for building transactions programmatically or interactively, offering more control than tx3 files for advanced use cases.
+
+### Available Subcommands
+
+The construct command includes several subcommands:
+
+```bash
+cshell tx construct --help
+```
+
+#### Wizard
+
+Generate a tx3 transaction using an interactive wizard:
+
+```bash
+cshell tx construct wizard
+```
+
+The wizard guides you through the transaction creation process step by step, asking for inputs, outputs, and other transaction details.
+
+#### Add Input
+
+Add a UTxO input to a transaction:
+
+```bash
+cshell tx construct add-input --tx3-file
+```
+
+**Options:**
+- `--tx3-file`: Path to the final tx3 file used to identify current transaction (tx3 file will be created on build command)
+- Additional options available with `--help`
+
+#### Add Output
+
+Add an output to a transaction:
+```bash
+cshell tx construct add-output --tx3-file
+```
+
+**Options:**
+- `--tx3-file`: Path to the final tx3 file used to identify current transaction (tx3 file will be created on build command)
+- Additional options for assets and datum with `--help`
+
+#### Build
+
+Generate the tx3 file from accumulated inputs and outputs:
+
+```bash
+cshell tx construct build --tx3-file
+```
+
+This will take all the inputs/outputs you've added by add-input / add-output commands and create a complete tx3 file.
+
+### Workflow Example
+
+Here's a typical workflow for constructing a transaction manually:
+
+```bash
+# Start with the wizard to set up basic structure
+cshell tx construct wizard
+
+# Or build step by step:
+
+# 1. Add input UTxO
+cshell tx construct add-input --tx3-file my-transaction.tx3
+
+# 2. Add output
+cshell tx construct add-output --tx3-file my-transaction.tx3
+
+# 3. Add change output
+cshell tx construct add-output --tx3-file my-transaction.tx3
+
+# 4. Build the transaction
+cshell tx construct build --tx3-file my-transaction.tx3
+```
+
+### Additional Help
+
+Each subcommand has its own help documentation:
+
+```bash
+cshell tx construct wizard --help
+cshell tx construct add-input --help
+cshell tx construct add-output --help
+cshell tx construct build --help
+```
+
+---
+
+## tx resolve
+
+The `tx resolve` command converts a tx3 file into CBOR format without signing or submitting it. This is useful for inspecting transaction details or preparing transactions for external signing.
+
+### Usage
+
+```bash
+cshell tx resolve --tx3-file
+```
+
+### Options
+
+Run `cshell tx resolve --help` to see all available options.
+
+### Examples
+
+#### Basic Resolution
+
+```bash
+cshell tx resolve --tx3-file ./transfer.tx3
+```
+
+This outputs the resolved CBOR transaction to stdout.
+
+
+
+#### With Different Provider
+
+```bash
+cshell tx resolve --tx3-file ./transfer.tx3 --provider testnet
+```
+
+---
+
+## tx sign
+
+The `tx sign` command signs a CBOR transaction with your wallet's private keys, preparing it for submission to the blockchain.
+
+### Usage
+
+```bash
+cshell tx sign
+```
+
+### Options
+
+Run `cshell tx sign --help` to see all available options.
+
+### Examples
+
+#### Basic Signing
+
+```bash
+# Sign a resolved transaction
+cshell tx sign
+```
+
+The signed transaction will be output to stdout.
+
+#### Specify Output File
+
+```bash
+cshell tx sign > signed.cbor
+```
+
+#### Sign with Specific Wallet
+
+If you have multiple wallets, specify which one to use:
+
+```bash
+cshell tx sign --signer my-wallet
+```
+
+### Workflow
+
+Typically used as part of a manual transaction workflow:
+
+```bash
+# 1. Resolve the transaction
+cshell tx resolve --tx3-file transfer.tx3
+
+# 2. Sign the transaction
+cshell tx sign
+
+# 3. Submit to blockchain
+cshell tx submit
+```
+
+
+
+---
+
+## tx submit
+
+The `tx submit` command broadcasts a signed CBOR transaction to the Cardano blockchain via your configured TRP provider.
+
+### Usage
+
+```bash
+cshell tx submit
+```
+
+### Options
+
+Run `cshell tx submit --help` to see all available options.
+
+### Examples
+
+#### Basic Submission
+
+```bash
+cshell tx submit
+```
+
+Successful submission returns a transaction hash:
+
+```
+Submitted TX:
+TX Hash: 8f3a2b1c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2
+```
+
+#### With Different Provider
+
+Submit to a specific provider:
+
+```bash
+cshell tx submit --provider mainnet
+```
+
+#### Save Transaction Hash
+
+Capture the transaction hash for later reference:
+
+```bash
+cshell tx submit > tx-submit-result.txt
+```
+
+### Complete Workflow
+
+Here's the full manual transaction workflow:
+
+```bash
+# 1. Resolve transaction
+cshell tx resolve --tx3-file transfer.tx3
+
+# 2. Sign transaction
+cshell tx sign
+
+# 3. Submit to blockchain
+cshell tx submit
+
+# 4. Monitor transaction (using the returned hash)
+cshell search transaction
+```
+
+
+
+### Verifying Submission
+
+After submitting, verify your transaction:
+
+#### Using Cshell Explorer
+
+
+
+```bash
+# Open explorer and check recent transactions
+cshell explorer
+```
+
+Navigate to the Transactions tab to see your submitted transaction.
+
+#### Using Search Command
+
+```bash
+# Search by transaction hash
+cshell search transaction
+```
+
+#### Check Wallet Balance
+
+```bash
+# Verify balance changes
+cshell wallet balance
+```
+
+---
+
+## Quick Reference
+
+
diff --git a/docs/usage.mdx b/docs/usage.mdx
index a1c6194..dbbab9d 100644
--- a/docs/usage.mdx
+++ b/docs/usage.mdx
@@ -4,49 +4,132 @@ sidebar:
order: 3
---
-import { Aside } from '@astrojs/starlight/components';
+import { Aside, CardGrid, LinkCard } from '@astrojs/starlight/components';
-With Cshell fully configured ([provider](/cshell/provider) and [wallet](/cshell/wallet)), it's time to start using it to manage transactions or fetch on-chain data.
-
-You can execute any transaction in Cshell using [**tx3**](https://docs.txpipe.io/tx3). Cshell will call the TRP to resolve and submit the transaction.
+With Cshell fully configured ([provider](/cshell/provider) and [wallet](/cshell/wallet)), you're ready to manage transactions and explore blockchain data.
-
+## Quick Start
-## Commands
-The commands below are used to handle transactions and fetch on-chain data.
+### Execute a Transaction
-### Transactions
-You can manage transactions by using Cshell's `tx` or `transactions` commands. To see which tx commands are available, run the following:
+The quickest way to submit a transaction is using [**tx3**](https://docs.txpipe.io/tx3) files:
```bash
-cshell tx --help
+cshell tx invoke --tx3-file ./my-transaction.tx3
```
-Use the `--help` flag with any command to view its available options.
+This will resolve, sign, and submit your transaction in one step.
+
+### Search Blockchain Data
+
+Query blocks and transactions:
```bash
-cshell tx invoke --help
+# Search for a specific block
+cshell search block
+
+# Search for a transaction
+cshell search transaction
```
-### Search
-You can search by block or transactions using the commands search. To see which search commands are available, run the following
+### Explore with GUI
-
+Launch the terminal-based explorer:
```bash
-cshell search --help
+cshell explorer
```
-Use the `--help` flag with any command to view its available options.
+## Available Commands
+
+Cshell provides several command groups for different operations:
+
+
+
+
+
+
+
+
+
+## Common Workflows
+
+### Send ADA
```bash
-cshell search block --help
+# 1. Create a tx3 file describing the transfer
+# 2. Execute the transaction
+cshell tx invoke --tx3-file ./transfer.tx3
```
+
+### Mint Tokens
+
+```bash
+# 1. Create a tx3 file with minting instructions
+# 2. Execute the transaction
+cshell tx invoke --tx3-file ./mint-token.tx3
+```
+
+### Verify a Transaction
+
+```bash
+# After submission, verify it was confirmed
+cshell search transaction
+```
+
+### Check Wallet Balance
+
+```bash
+cshell wallet balance
+```
+
+## Output Formats
+
+Many commands support multiple output formats:
+
+```bash
+# Human-readable table (default)
+cshell search block
+
+# Machine-readable JSON
+cshell search block --output-format json
+```
+
+
+
+## Next Steps
+
+- Learn about [transaction commands](/cshell/commands/tx) for managing transactions
+- Explore [search commands](/cshell/commands/search) for querying blockchain data
+- Check out the [examples](https://github.com/txpipe/cshell/tree/main/examples) for sample tx3 files
diff --git a/examples/README.md b/examples/README.md
new file mode 100644
index 0000000..f83a34c
--- /dev/null
+++ b/examples/README.md
@@ -0,0 +1,72 @@
+# TX3 Transaction Examples
+
+This directory contains example TX3 files to execute through CShell invoke.
+
+## Prerequisites
+
+Before running TX3 files, ensure you have:
+
+1. **CShell installed** - See the main [README](../README.md) for installation instructions
+2. **A CShell configuration file** - Created using `cshell provider create` and `cshell wallet create`
+3. **At least one provider configured** - For blockchain connectivity
+4. **At least one wallet configured** - For signing transactions
+
+## How to Execute TX3 Files
+
+Use the following command pattern to execute a TX3 file:
+
+```bash
+cshell -s ./cshell.toml tx invoke --tx3-file ./
+```
+
+### Command Breakdown
+
+- `cshell` - Runs CShell
+- `-s ` - Specifies the CShell configuration file path
+- `tx invoke` - Invokes a transaction
+- `--tx3-file ` - Path to the TX3 file to execute
+
+### Configuration File
+
+The `-s` flag points to your CShell configuration file (usually `cshell.toml`), which contains:
+- Provider settings
+- Wallet configurations
+
+## Available Examples
+
+### 1. `transfer.tx3` - Basic ADA Transfer
+
+Transfers ADA from one party to another with change calculation.
+
+**Parties**: `Sender`, `Receiver`
+**Parameters**: `quantity` (amount to transfer in lovelace)
+
+```bash
+cshell -s ~/.tx3/tmp/devnet_756435378c8d3771/cshell.toml tx invoke --tx3-file ./transfer.tx3
+```
+
+### 2. `mint_token.tx3` - Token Minting
+
+Creates new native tokens on Cardano.
+
+**Parties**: `Minter`
+**Parameters**:
+- `token_policy` (policy ID in bytes)
+- `token_name` (token name in bytes)
+- `quantity` (amount to mint)
+
+```bash
+cshell -s ~/.tx3/tmp/devnet_756435378c8d3771/cshell.toml tx invoke --tx3-file ./mint_token.tx3
+```
+
+### 3. `mint_with_script.tx3` - Plutus Script Token Minting
+
+Demonstrates token minting using a Plutus v3 script with a PIN-based vending machine mechanism. This example shows how to interact with smart contracts for token minting.
+
+**Parties**: `Customer`
+**Parameters**:
+- `pin` (PIN code in bytes)
+
+```bash
+cshell -s ~/.tx3/tmp/devnet_756435378c8d3771/cshell.toml tx invoke --tx3-file ./mint_with_script.tx3
+```
diff --git a/examples/mint_token.tx3 b/examples/mint_token.tx3
new file mode 100644
index 0000000..722cdff
--- /dev/null
+++ b/examples/mint_token.tx3
@@ -0,0 +1,27 @@
+party Minter;
+
+tx mint_token (
+ token_policy: Bytes,
+ token_name: Bytes,
+ quantity: Int,
+) {
+
+ locals {
+ token: AnyAsset(token_policy, token_name, quantity),
+ }
+
+ input source {
+ from: Minter,
+ min_amount: fees,
+ }
+
+ mint {
+ amount: token,
+ redeemer: (),
+ }
+
+ output destination {
+ to: Minter,
+ amount: source + token - fees,
+ }
+}
\ No newline at end of file
diff --git a/examples/mint_with_script.tx3 b/examples/mint_with_script.tx3
new file mode 100644
index 0000000..43ce50f
--- /dev/null
+++ b/examples/mint_with_script.tx3
@@ -0,0 +1,34 @@
+party Customer;
+
+policy VendingMachine = 0x3f2e288b4a19ab51d1775d2c6e397b43fad17cc8c47b988603136d73;
+
+asset COIN = 0x3f2e288b4a19ab51d1775d2c6e397b43fad17cc8c47b988603136d73."COIN";
+
+tx claim_tokens(
+ pin: Bytes,
+) {
+ input gas {
+ from: Customer,
+ min_amount: fees,
+ }
+
+ collateral {
+ from: Customer,
+ min_amount: fees,
+ }
+
+ mint {
+ amount: COIN(1),
+ redeemer: pin,
+ }
+
+ output {
+ to: Customer,
+ amount: gas - fees + COIN(1),
+ }
+
+ cardano::plutus_witness {
+ version: 3,
+ script: 0x5903e501010029800aba4aba2aba1aab9faab9eaab9dab9cab9a488888888c96600264653001300900198049805000cc0240092225980099b8748000c024dd500144c966002009007803c01e00f1323233223233225330103372c9210e70726f76696465642070696e3a20003732660046ea40052201001325330113372c92011370726f76696465642070696e20686173683a20003732660066ea400522010013371e0029111c4f43be03892183d6ea41480f616be43b58937aad2c7511e71be9f80d00379000260020026eb8024888c9660020071323233223300a00233714910101280059800800c4cdc52441035b5d2900006899b8a489035b5f20009800800ccdc52441025d2900006914c00402a00530070014029229800805400a002805100920305980099b880014803a266e0120f2010018acc004cdc4000a41000513370066e01208014001480362c80910121bac3015002375a60260026466ec0dd418098009ba73014001375400713259800800c4cdc52441027b7d00003899b8a489037b5f20003232330010010032259800800c400e264b30010018994c00402a6030003337149101023a200098008054c06400600a805100a180d00144ca6002015301800199b8a489023a200098008054c064006600e66008008004805100a180d0012032301a001406066e29220102207d0000340546eac00e264b3001001899b8a489025b5d00003899b8a489035b5f20009800800ccdc52441015d00003914c00401e0053004001401d229800803c00a0028039006202a3758007133006375a0060051323371491102682700329800800ccdc01b8d0024800666e292210127000044004444b3001337100049000440062646645300100699b800054800666e2ccdc00012cc004cdc40012402914818229037202e3371666e000056600266e2000520148a40c11481b9017002200c33706002901019b8600148080cdc70020012028375c00680b8dc5245022c2000223233001001003225980099b8700148002266e292210130000038acc004cdc4000a40011337149101012d0033002002337029000000c4cc014cdc2000a402866e2ccdc019b85001480512060003403880708888c8cc004004014896600200310058992cc004006266008602c00400d1330053016002330030030014054602c00280a0c0040048896600266e2400920008800c6600200733708004900a4cdc599b803370a004900a240c0002801900b201e375c601860146ea800a29410070c024004c014dd500545268a99801a4811856616c696461746f722072657475726e65642066616c7365001365640082a660049201206578706563742070696e3a20427974654172726179203d2072656465656d6572001601,
+ }
+}
\ No newline at end of file
diff --git a/examples/transfer.tx3 b/examples/transfer.tx3
new file mode 100644
index 0000000..6fb975f
--- /dev/null
+++ b/examples/transfer.tx3
@@ -0,0 +1,21 @@
+party Sender;
+party Receiver;
+
+tx transfer(
+ quantity: Int,
+) {
+ input source {
+ from: Sender,
+ min_amount: Ada(quantity) + fees,
+ }
+
+ output destination {
+ to: Receiver,
+ amount: Ada(quantity),
+ }
+
+ output {
+ to: Sender,
+ amount: source - Ada(quantity) - fees,
+ }
+}
diff --git a/src/tx/construct/add_input.rs b/src/tx/construct/add_input.rs
new file mode 100644
index 0000000..fbb3f07
--- /dev/null
+++ b/src/tx/construct/add_input.rs
@@ -0,0 +1,33 @@
+use std::{fs, path::PathBuf};
+
+use anyhow::{Result, Context};
+use clap::Parser;
+use tracing::instrument;
+
+#[derive(Parser, Clone)]
+pub struct Args {
+ /// Path for tx3 file to create the transaction
+ #[arg(long)]
+ tx3_file: PathBuf,
+}
+
+#[instrument("add-input", skip_all)]
+pub async fn run(args: Args, _ctx: &crate::Context) -> Result<()> {
+ let ast_path_buf = args.tx3_file.with_extension("ast");
+
+ let mut tx_builder = super::common::TransactionBuilder::from_ast(&ast_path_buf)?;
+
+ tx_builder.collect_inputs(true)?;
+
+ // Serialize and write AST
+ let ast_json = serde_json::to_string_pretty(&tx_builder.ast)
+ .context("Failed to serialize tx3 AST")?;
+
+ fs::write(&ast_path_buf, ast_json)
+ .with_context(|| format!("Failed to write tx3 AST file: {}", ast_path_buf.display()))?;
+
+ println!("\n✅ Input added successfully!");
+ println!("📄 File saved to: {}", ast_path_buf.display());
+
+ Ok(())
+}
\ No newline at end of file
diff --git a/src/tx/construct/add_output.rs b/src/tx/construct/add_output.rs
new file mode 100644
index 0000000..93cda06
--- /dev/null
+++ b/src/tx/construct/add_output.rs
@@ -0,0 +1,33 @@
+use std::{fs, path::PathBuf};
+
+use anyhow::{Result, Context};
+use clap::Parser;
+use tracing::instrument;
+
+#[derive(Parser, Clone)]
+pub struct Args {
+ /// Path for tx3 file to create the transaction
+ #[arg(long)]
+ tx3_file: PathBuf,
+}
+
+#[instrument("add-output", skip_all)]
+pub async fn run(args: Args, _ctx: &crate::Context) -> Result<()> {
+ let ast_path_buf = args.tx3_file.with_extension("ast");
+
+ let mut tx_builder = super::common::TransactionBuilder::from_ast(&ast_path_buf)?;
+
+ tx_builder.collect_outputs(true)?;
+
+ // Serialize and write AST
+ let ast_json = serde_json::to_string_pretty(&tx_builder.ast)
+ .context("Failed to serialize tx3 AST")?;
+
+ fs::write(&ast_path_buf, ast_json)
+ .with_context(|| format!("Failed to write tx3 AST file: {}", ast_path_buf.display()))?;
+
+ println!("\n✅ Output added successfully!");
+ println!("📄 File saved to: {}", ast_path_buf.display());
+
+ Ok(())
+}
\ No newline at end of file
diff --git a/src/tx/construct/build.rs b/src/tx/construct/build.rs
new file mode 100644
index 0000000..6f6f36b
--- /dev/null
+++ b/src/tx/construct/build.rs
@@ -0,0 +1,31 @@
+use std::{fs, path::PathBuf};
+
+use anyhow::{Result, Context};
+use clap::Parser;
+use tracing::instrument;
+
+#[derive(Parser, Clone)]
+pub struct Args {
+ /// Path for tx3 file to create the transaction
+ #[arg(long)]
+ tx3_file: PathBuf,
+}
+
+#[instrument("build", skip_all)]
+pub async fn run(args: Args, _ctx: &crate::Context) -> Result<()> {
+ let ast_path_buf = args.tx3_file.with_extension("ast");
+
+ let tx_builder = super::common::TransactionBuilder::from_ast(&ast_path_buf)?;
+
+ // Generate the tx3 content
+ let tx3_content = tx_builder.generate_tx3_content();
+
+ // Write to file
+ fs::write(&args.tx3_file, tx3_content)
+ .context("Failed to write tx3 file")?;
+
+ println!("\n✅ Transaction created successfully!");
+ println!("📄 File saved to: {}", args.tx3_file.display());
+
+ Ok(())
+}
\ No newline at end of file
diff --git a/src/tx/construct/common.rs b/src/tx/construct/common.rs
new file mode 100644
index 0000000..efd724d
--- /dev/null
+++ b/src/tx/construct/common.rs
@@ -0,0 +1,308 @@
+
+
+use std::{fs, path::PathBuf, str::FromStr};
+
+use anyhow::{Result, Context};
+use pallas::ledger::addresses::Address;
+use serde_json::json;
+use inquire::{Text, Confirm};
+
+pub struct TransactionBuilder {
+ pub ast: tx3_lang::ast::Program,
+ pub def_index: usize,
+}
+
+impl TransactionBuilder {
+ pub fn new(name: String, mut ast: tx3_lang::ast::Program) -> Result {
+ let mut def_index = ast.txs.iter().position(|tx| tx.name.value == name);
+
+ if def_index.is_none() {
+ println!("Creating new transaction: {}", name);
+ // Create it as JSON and parse it as TxDef
+ // TODO: Make scope pub in tx3_lang and construct directly or implement `Default`
+ let value = json!({
+ "name": tx3_lang::ast::Identifier::new(name),
+ "parameters": tx3_lang::ast::ParameterList {
+ parameters: Vec::new(),
+ span: tx3_lang::ast::Span::default(),
+ },
+ "references": [],
+ "inputs": [],
+ "outputs": [],
+ "mints": [],
+ "burns": [],
+ "adhoc": [],
+ "span": tx3_lang::ast::Span::default(),
+ "collateral": [],
+ });
+ let tx_def: tx3_lang::ast::TxDef =
+ serde_json::from_value(value)
+ .context("Failed to materialize TxDef from JSON template")?;
+
+ ast.txs.push(tx_def);
+
+ def_index = Some(ast.txs.len() - 1);
+ }
+
+ Ok(Self {
+ ast: ast.clone(),
+ def_index: def_index.unwrap(),
+ })
+ }
+
+ pub fn from_ast(ast_path_buf: &PathBuf) -> Result {
+ let ast = if ast_path_buf.exists() {
+ let ast_content = fs::read_to_string(ast_path_buf)
+ .context("Failed to read existing AST file")?;
+
+ serde_json::from_str(&ast_content)
+ .context("Failed to parse existing AST file")?
+ } else {
+ tx3_lang::ast::Program::default()
+ };
+
+ TransactionBuilder::new("new_transaction".to_string(), ast)
+ }
+
+ pub fn collect_inputs(&mut self, skip_question: bool) -> Result<()> {
+ println!("\n📥 Transaction Inputs");
+ println!("====================");
+
+ if !skip_question {
+ let add_inputs = Confirm::new("Do you want to add inputs to your transaction?")
+ .with_default(true)
+ .prompt()?;
+
+ if !add_inputs {
+ return Ok(());
+ }
+ }
+
+
+ loop {
+ let input_name = Text::new("Input name:")
+ .with_help_message("Enter input name (or 'done' to finish)")
+ .prompt()?;
+
+ if input_name.eq_ignore_ascii_case("done") {
+ break;
+ }
+
+ let mut input_block = tx3_lang::ast::InputBlock {
+ name: input_name.clone(),
+ span: tx3_lang::ast::Span::default(),
+ many: false,
+ fields: Vec::new(),
+ };
+
+ let utxo_ref = Text::new("Utxo Ref:")
+ .with_help_message("Enter the Utxo for this input (txid#index)")
+ .prompt()?;
+
+ let parts: Vec<&str> = utxo_ref.split('#').collect();
+ if parts.len() != 2 {
+ println!("Invalid Utxo Ref format. Expected format: txid#index");
+ continue;
+ }
+
+ // input_block.fields.push(tx3_lang::ast::InputBlockField::From(
+ // tx3_lang::ast::DataExpr::String(tx3_lang::ast::StringLiteral::new(address.to_bech32().unwrap())),
+ // ));
+
+ let txid = hex::decode(parts[0])
+ .context("Invalid txid hex in UTxO reference")?;
+
+ let index = parts[1]
+ .parse::()
+ .context("Invalid UTxO index")?;
+
+ input_block.fields.push(tx3_lang::ast::InputBlockField::Ref(
+ tx3_lang::ast::DataExpr::UtxoRef(tx3_lang::ast::UtxoRef {
+ txid,
+ index,
+ span: tx3_lang::ast::Span::default(),
+ }),
+ ));
+
+ let min_amount = Text::new("Minimum amount value:")
+ .with_default("1000000")
+ .prompt()?;
+
+ let min_amount_value = min_amount
+ .parse::()
+ .context("Invalid minimum amount value")?;
+
+ input_block.fields.push(tx3_lang::ast::InputBlockField::MinAmount(
+ tx3_lang::ast::DataExpr::StaticAssetConstructor(tx3_lang::ast::StaticAssetConstructor {
+ amount: Box::new(tx3_lang::ast::DataExpr::Number(min_amount_value)),
+ span: tx3_lang::ast::Span::default(),
+ r#type: tx3_lang::ast::Identifier::new("Ada".to_string()),
+ })
+ ));
+
+ self.ast.txs[self.def_index].inputs.push(input_block);
+
+ let add_more = Confirm::new("Add another input?")
+ .with_default(false)
+ .prompt()?;
+
+ if !add_more {
+ break;
+ }
+ }
+
+ Ok(())
+ }
+
+ pub fn collect_outputs(&mut self, skip_question: bool) -> Result<()> {
+ println!("\n📤 Transaction Outputs");
+ println!("=====================");
+
+ if !skip_question {
+ let add_outputs = Confirm::new("Do you want to add outputs to your transaction?")
+ .with_default(true)
+ .prompt()?;
+
+ if !add_outputs {
+ return Ok(());
+ }
+ }
+
+ loop {
+ let has_name = Confirm::new("Does this output have a name?")
+ .with_default(true)
+ .prompt()?;
+
+ let output_name = if has_name {
+ Some(Text::new("Output name:")
+ .with_help_message("Enter output name")
+ .prompt()?)
+ } else {
+ None
+ };
+
+ let mut output_block = tx3_lang::ast::OutputBlock {
+ name: output_name.as_ref().map(|name| tx3_lang::ast::Identifier::new(name.clone())),
+ span: tx3_lang::ast::Span::default(),
+ fields: Vec::new(),
+ };
+
+ let to_address = Text::new("To address:")
+ .with_help_message("Enter the address this output goes to")
+ .prompt()?;
+
+ // Validate address
+ let address = Address::from_str(&to_address)
+ .context("Invalid address")?;
+
+ let bech32 = address
+ .to_bech32()
+ .context("Failed to encode bech32 address")?;
+
+ output_block.fields.push(tx3_lang::ast::OutputBlockField::To(
+ Box::new(tx3_lang::ast::DataExpr::String(
+ tx3_lang::ast::StringLiteral::new(bech32)
+ )),
+ ));
+
+ let amount = Text::new("Amount:")
+ .with_default("1000000")
+ .prompt()?;
+
+ let amount_value = amount
+ .parse::()
+ .context("Invalid Ada amount")?;
+
+ output_block.fields.push(tx3_lang::ast::OutputBlockField::Amount(
+ Box::new(tx3_lang::ast::DataExpr::StaticAssetConstructor(tx3_lang::ast::StaticAssetConstructor {
+ amount: Box::new(tx3_lang::ast::DataExpr::Number(amount_value)),
+ span: tx3_lang::ast::Span::default(),
+ r#type: tx3_lang::ast::Identifier::new("Ada".to_string()),
+ }))
+ ));
+
+ self.ast.txs[self.def_index].outputs.push(output_block);
+
+
+ let add_more = Confirm::new("Add another output?")
+ .with_default(true)
+ .prompt()?;
+
+ if !add_more {
+ break;
+ }
+ }
+
+ Ok(())
+ }
+
+ pub fn generate_tx3_content(self) -> String {
+ let mut content = String::new();
+
+ // Add transaction
+ content.push_str(&format!("tx {}() {{\n", self.ast.txs[self.def_index].name.value));
+
+ // Add inputs
+ for input in &self.ast.txs[self.def_index].inputs {
+ content.push_str(&format!("\tinput {} {{\n", input.name));
+ input.fields.iter().for_each(|field| {
+ match field {
+ tx3_lang::ast::InputBlockField::From(
+ tx3_lang::ast::DataExpr::String(literal)
+ ) => {
+ content.push_str(&format!("\t\tfrom: \"{}\",\n", literal.value));
+ },
+ tx3_lang::ast::InputBlockField::Ref(
+ tx3_lang::ast::DataExpr::UtxoRef(utxoref)
+ ) => {
+ content.push_str(&format!("\t\tref: 0x{}#{},\n", hex::encode(&utxoref.txid), utxoref.index));
+ },
+ tx3_lang::ast::InputBlockField::MinAmount(
+ tx3_lang::ast::DataExpr::StaticAssetConstructor(constructor)
+ ) => {
+ let amount = match *constructor.amount {
+ tx3_lang::ast::DataExpr::Number(num) => num.to_string(),
+ _ => "unknown".to_string(),
+ };
+ content.push_str(&format!("\t\tmin_amount: {}({}),\n", constructor.r#type.value, amount));
+ },
+ _ => {}
+ }
+ });
+ content.push_str("\t}\n\n");
+ }
+
+ // Add outputs
+ for output in &self.ast.txs[self.def_index].outputs {
+ if let Some(name) = &output.name {
+ content.push_str(&format!("\toutput {} {{\n", name.value));
+ } else {
+ content.push_str("\toutput {\n");
+ }
+
+ output.fields.iter().for_each(|field| {
+ match field {
+ tx3_lang::ast::OutputBlockField::To(expr) => {
+ if let tx3_lang::ast::DataExpr::String(literal) = expr.as_ref() {
+ content.push_str(&format!("\t\tto: \"{}\",\n", literal.value));
+ }
+ },
+ tx3_lang::ast::OutputBlockField::Amount(expr) => {
+ if let tx3_lang::ast::DataExpr::StaticAssetConstructor(constructor) = expr.as_ref() {
+ let amount = match *constructor.amount {
+ tx3_lang::ast::DataExpr::Number(num) => num.to_string(),
+ _ => "unknown".to_string(),
+ };
+ content.push_str(&format!("\t\tamount: {}({}),\n", constructor.r#type.value, amount));
+ }
+ },
+ _ => {}
+ }
+ });
+ content.push_str("\t}\n\n");
+ }
+
+ content.push_str("}\n");
+ content
+ }
+}
diff --git a/src/tx/construct/mod.rs b/src/tx/construct/mod.rs
new file mode 100644
index 0000000..9c356de
--- /dev/null
+++ b/src/tx/construct/mod.rs
@@ -0,0 +1,41 @@
+use clap::{Parser, Subcommand};
+use tracing::instrument;
+
+mod wizard;
+mod common;
+mod add_input;
+mod add_output;
+mod build;
+
+#[derive(Parser)]
+pub struct Args {
+ #[command(subcommand)]
+ command: Commands,
+}
+
+#[derive(Subcommand)]
+enum Commands {
+ /// Generate a tx3 transaction using a wizard
+ Wizard(wizard::Args),
+
+ /// Add input to transaction
+ #[command(name = "add-input")]
+ AddInput(add_input::Args),
+
+ /// Add output to transaction
+ #[command(name = "add-output")]
+ AddOutput(add_output::Args),
+
+ /// Build the transaction
+ Build(build::Args),
+}
+
+#[instrument("construct", skip_all)]
+pub async fn run(args: Args, ctx: &crate::Context) -> anyhow::Result<()> {
+ match args.command {
+ Commands::Wizard(args) => wizard::run(args, ctx).await,
+ Commands::AddInput(args) => add_input::run(args, ctx).await,
+ Commands::AddOutput(args) => add_output::run(args, ctx).await,
+ Commands::Build(args) => build::run(args, ctx).await,
+ }
+}
diff --git a/src/tx/construct/wizard.rs b/src/tx/construct/wizard.rs
new file mode 100644
index 0000000..5ea5423
--- /dev/null
+++ b/src/tx/construct/wizard.rs
@@ -0,0 +1,57 @@
+use std::{fs, path::PathBuf};
+
+use anyhow::{Result, Context};
+use clap::Parser;
+use tracing::instrument;
+use inquire::Confirm;
+
+#[derive(Parser, Clone)]
+pub struct Args {
+ /// Path for tx3 file to create the transaction
+ #[arg(long)]
+ tx3_file: PathBuf,
+}
+
+#[instrument("wizard", skip_all)]
+pub async fn run(args: Args, _ctx: &crate::Context) -> Result<()> {
+ let ast_path_buf = args.tx3_file.with_extension("ast");
+
+ if args.tx3_file.exists() {
+ println!("⚠️ Warning: The specified tx3 file already exists and will be overwritten.");
+ let proceed = Confirm::new("Do you want to continue?")
+ .with_default(false)
+ .prompt()?;
+
+ if !proceed {
+ println!("Operation cancelled by user.");
+ return Ok(());
+ }
+ }
+
+ let mut tx_builder = super::common::TransactionBuilder::from_ast(&ast_path_buf)?;
+
+ tx_builder.collect_inputs(false)?;
+
+ tx_builder.collect_outputs(false)?;
+
+ let ast = tx_builder.ast.clone();
+
+ // Generate the tx3 content
+ let tx3_content = tx_builder.generate_tx3_content();
+
+ // Write to file
+ fs::write(&args.tx3_file, tx3_content)
+ .context("Failed to write tx3 file")?;
+
+ // Serialize and write AST
+ let ast_json = serde_json::to_string_pretty(&ast)
+ .context("Failed to serialize tx3 AST")?;
+
+ fs::write(&ast_path_buf, ast_json)
+ .with_context(|| format!("Failed to write tx3 AST file: {}", ast_path_buf.display()))?;
+
+ println!("\n✅ Transaction created successfully!");
+ println!("📄 File saved to: {}", args.tx3_file.display());
+
+ Ok(())
+}
diff --git a/src/tx/invoke.rs b/src/tx/invoke.rs
index 1c0ec3d..a9b9c49 100644
--- a/src/tx/invoke.rs
+++ b/src/tx/invoke.rs
@@ -91,7 +91,7 @@ pub async fn run(args: Args, ctx: &crate::Context) -> Result<()> {
}
OutputFormat::Table => {
- println!("Tx Hash: {}", hex::encode(&hash));
+ println!("Tx Hash: {}", &hash);
println!("Tx CBOR: {}", hex::encode(&cbor));
}
}
diff --git a/src/tx/mod.rs b/src/tx/mod.rs
index bef0ea8..da9bd82 100644
--- a/src/tx/mod.rs
+++ b/src/tx/mod.rs
@@ -7,6 +7,7 @@ mod invoke;
mod resolve;
mod sign;
mod submit;
+mod construct;
#[derive(Parser)]
pub struct Args {
@@ -27,6 +28,9 @@ enum Commands {
/// Submit a CBOR transaction
Submit(submit::Args),
+
+ /// Construct a new transaction using tx3
+ Construct(construct::Args),
}
#[instrument("transaction", skip_all)]
@@ -36,5 +40,6 @@ pub async fn run(args: Args, ctx: &crate::Context) -> anyhow::Result<()> {
Commands::Resolve(args) => resolve::run(args, ctx).await,
Commands::Sign(args) => sign::run(args, ctx).await,
Commands::Submit(args) => submit::run(args, ctx).await,
+ Commands::Construct(args) => construct::run(args, ctx).await,
}
}