Getting Started with Lichen
This guide walks you through everything needed to go from zero to your first on-chain transaction. You'll install the toolchain, create a wallet, fund it on testnet, send a transfer, and deploy a minimal smart contract.
Prerequisites
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustup default stable
rustup update
wasm32-unknown-unknown compilation target for smart
contract builds.rustup target add wasm32-unknown-unknown
# Using nvm (recommended)
nvm install 20
nvm use 20
# Verify
node --version # v20.x.x
npm --version # 10.x.x
lichen-validator release artifact, you can join mainnet directly
without a repository checkout. Use a writable state directory, keep the bundled
zk-prove tool beside the validator, copy the bundled seeds.json into the
state directory, and start the binary. See Validator Setup for Linux,
macOS, and Windows release install commands.
Install the CLI
The lichen CLI is your primary interface for interacting with the Lichen network. Install
it from crates.io or build from source.
Option A: Install from the repo checkout
cargo install --path cli/
Option B: Build from source
git clone https://github.com/lobstercove/lichen.git
cd lichen
cargo build --release
# Binary is at ./target/release/lichen
cp target/release/lichen ~/.cargo/bin/
Verify the installation:
$ lichen --version
lichen 0.5.10
Make lichen discoverable in new spores
echo 'export PATH="$HOME/.cargo/bin:$HOME/.lichen/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
command -v lichen
If command -v lichen is empty, run the binary directly until your shell profile is fixed:
./target/release/lichen --version
Create a Wallet
Generate a new keypair. This creates a native ML-DSA-65 seed and derives your versioned Lichen address.
$ lichen wallet create
Generating new Lichen keypair...
Name: wallet-1
Address: Mo1tABcDeFgH1jK2LmNoPqRsTuVwXyZ3456789ab
Path: ~/.lichen/wallets/wallet-1.json
Done! Fund your wallet with testnet tokens to get started.
You can also import an existing keypair file:
$ lichen wallet import my-wallet --keypair ~/backup/wallet.json
Browser Wallet Safety
If you later switch from the CLI to the browser wallet or the developer portals, treat custom RPC endpoints as transport only.
getSignedMetadataManifest and verified against the pinned release signer before the UI
trusts them. Generic chain reads can still use your selected RPC, but high-trust metadata and bridge
control-plane reads do not downgrade to arbitrary endpoints.
Get Testnet Tokens
You need LICN tokens to pay for transaction fees and contract deployments. On testnet, you can request free tokens from the faucet.
Option A: Web Faucet
Visit the Lichen Faucet and paste your address. You'll receive 10 LICN on testnet within seconds.
Option B: CLI Faucet
$ lichen airdrop 10 --rpc-url https://testnet-rpc.lichen.network
Requesting 10 LICN airdrop...
Transaction: 4xK9...mNpQ
New balance: 10.000000000 LICN
Airdrop successful!
First Transfer
Send LICN from your wallet to another address. This is the simplest transaction on Lichen.
$ lichen transfer Mo1tRecipientAddress123456789abcdefghijk 1.5 \
--rpc-url https://testnet-rpc.lichen.network
Sending 1.5 LICN...
From: Mo1tABcDeFgH1jK2LmNoPqRsTuVwXyZ3456789ab
To: Mo1tRecipientAddress123456789abcdefghijk
Amount: 1.500000000 LICN
Fee: 0.001000000 LICN
Transaction: 7zQ3...bRtW
Status: Finalized (slot 482,917)
Transfer complete!
Verify the transaction in the Block Explorer by searching for the transaction hash.
Deploy a Contract
Let's deploy a minimal "Hello World" smart contract. Lichen contracts are written in Rust and compiled to WASM.
$ cd contracts
$ cargo new --lib hello_world
$ cd hello_world
# Add the contract SDK from this repo in Cargo.toml:
# lichen-sdk = { package = "lichen-contract-sdk", path = "../../sdk" }
src/lib.rs and add the contract logic.#![no_std]
#![cfg_attr(target_arch = "wasm32", no_main)]
extern crate alloc;
use lichen_sdk::{contract, storage};
#[no_mangle]
pub extern "C" fn initialize() -> u32 {
storage::set(b"greeting", b"Hello, Lichen!");
0
}
#[no_mangle]
pub extern "C" fn set_greeting() -> u32 {
let args = contract::args();
if args.is_empty() {
return 1;
}
storage::set(b"greeting", &args);
0
}
#[no_mangle]
pub extern "C" fn get_greeting() -> u32 {
match storage::get(b"greeting") {
Some(value) => {
contract::set_return(&value);
0
}
None => 1,
}
}
$ cargo build --target wasm32-unknown-unknown --release
Compiling hello-world v0.1.0
Finished release [optimized] target(s) in 8.42s
$ lichen deploy target/wasm32-unknown-unknown/release/hello_world.wasm \
--rpc-url https://testnet-rpc.lichen.network \
--symbol HELLO --name "Hello World" --template infra
Deploying contract...
Program ID: Mo1tProg1D...xYz789
Symbol: HELLO
Template: infra
Size: 14,832 bytes
Deploy tx: 9kR7...sWmN
Fee: 25.001000000 LICN
Status: Finalized
Contract deployed successfully!
Interact via:
lichen call Mo1tProg1D...xYz789 set_greeting \
--args '["Hello, Lichen!"]' \
--rpc-url https://testnet-rpc.lichen.network
--symbol to register in the symbol registry during deploy.
Upgrades cost 10 LICN plus the base fee. Regular contract calls only pay the 0.001 LICN
base fee.
Next Steps
You've created a wallet, funded it, sent a transfer, and deployed a contract. Here's where to go next: