Quickstart (CLI)
Create an asset, issue it, split a position, create an asset only credentialed holders may hold, and settle a delivery-versus-payment trade — twelve transactions, each followed by a link to the explorer.
You need: aevad (download and verify),
curl and jq. The commands run against the public testnet; set the four
variables to run them elsewhere.
The walkthrough uses a throwaway keyring (--keyring-backend test) in
~/.aeva-quickstart. Test tokens only.
0. Set up the shell
# --- where -------------------------------------------------------------------
export AEVA_NODE=${AEVA_NODE:-https://rpc.aevachain.com}
export AEVA_EXPLORER=${AEVA_EXPLORER:-https://explorer.aevachain.com}
export AEVA_FAUCET=${AEVA_FAUCET:-https://faucet.aevachain.com}
export AEVA_CHAIN_ID=${AEVA_CHAIN_ID:-aeva-testnet-1}
# a throwaway keyring for this walkthrough (test tokens only)
export AEVA_HOME=${AEVA_HOME:-$HOME/.aeva-quickstart}
alias_tx() { aevad tx "$@" --node "$AEVA_NODE" --chain-id "$AEVA_CHAIN_ID" --home "$AEVA_HOME" --keyring-backend test --gas 300000 --fees 7500000000000000aaeva -y -o json; }
wait_tx() { local t=""; for _ in $(seq 1 30); do t=$(aevad query tx "$1" --node "$AEVA_NODE" -o json 2>/dev/null) && break; sleep 1; done; [ -n "$t" ] || { echo "tx $1 not found" >&2; return 1; }; echo "$t"; [ "$(jq -r '.code // 0' <<<"$t")" = 0 ] || { jq -r '"tx refused: code \(.code) (\(.codespace)): \(.raw_log)"' <<<"$t" >&2; return 1; }; }
created_asset() { jq -r '.events[] | select(.type == "aeva.asset.v1.EventAssetCreated") | .attributes[] | select(.key == "asset_id") | .value | fromjson'; }alias_tx sends a transaction with a fixed gas limit and a fee of 0.0075 AEVA
(gas price 25 000 000 000 aaeva); wait_tx waits until the transaction is in
a block and fails, printing the reason, if the chain refused it;
created_asset reads the new asset’s id from the transaction’s events. Every
transaction pays its fee in AEVA.
1. Two accounts: one faucet claim, one transfer
The faucet gives one claim per address and per network every 24 hours, so the walkthrough claims once and funds the second account itself.
aevad keys add issuer --home "$AEVA_HOME" --keyring-backend test --no-backup >/dev/null 2>&1 || true
aevad keys add investor --home "$AEVA_HOME" --keyring-backend test --no-backup >/dev/null 2>&1 || true
ISSUER=$(aevad keys show issuer -a --home "$AEVA_HOME" --keyring-backend test)
INVESTOR=$(aevad keys show investor -a --home "$AEVA_HOME" --keyring-backend test)
curl -sf -X POST -H 'content-type: application/json' -d "{\"address\":\"$ISSUER\"}" "$AEVA_FAUCET/claim" | jq -r '"faucet → issuer: tx " + .tx_hash'
sleep 8
R=$(alias_tx bank send "$ISSUER" "$INVESTOR" 2000000000000000000aaeva,100000000aeusd --from issuer); wait_tx "$(jq -r .txhash <<<"$R")" >/dev/null # 1
echo "issuer: $AEVA_EXPLORER/address/$ISSUER"
echo "investor: $AEVA_EXPLORER/address/$INVESTOR"faucet → issuer: tx <transaction hash>
issuer: https://explorer.aevachain.com/address/aeva1…
investor: https://explorer.aevachain.com/address/aeva1…The investor now has 2 AEVA and 100 aeUSD. The claim also attested
testnet.verified for the issuer: the issuer’s account page shows it under
Credentials.
2. Create an asset with three right kinds and issue it
R=$(alias_tx asset create-asset ECONOMIC,INCOME,VOTE --settlement-denom aeusd --from issuer) # 2
ASSET=$(wait_tx "$(jq -r .txhash <<<"$R")" | created_asset)
echo "asset: $AEVA_EXPLORER/assets/$ASSET"
R=$(alias_tx rights issue "$ASSET" 0 "$ISSUER" 1000 --from issuer); wait_tx "$(jq -r .txhash <<<"$R")" >/dev/null # 3
R=$(alias_tx rights issue "$ASSET" 1 "$ISSUER" 1000 --from issuer); wait_tx "$(jq -r .txhash <<<"$R")" >/dev/null # 4
R=$(alias_tx rights issue "$ASSET" 2 "$ISSUER" 1000 --from issuer); wait_tx "$(jq -r .txhash <<<"$R")" >/dev/null # 5
echo "issued 1000 of each kind — rights graph (Holders tab): $AEVA_EXPLORER/assets/$ASSET"asset: https://explorer.aevachain.com/assets/<64 hex characters>
issued 1000 of each kind — rights graph (Holders tab): https://explorer.aevachain.com/assets/…The asset has three right kinds — 0 ECONOMIC, 1 INCOME, 2 VOTE — and a
supply of 1000 units of each, all held by the issuer. Its policy is OPEN
(anyone may hold).
3. Split: transfer part of the ECONOMIC and VOTE rights, keep the INCOME
R=$(alias_tx rights transfer "$INVESTOR" "$ASSET" 0:400,2:400 --from issuer); wait_tx "$(jq -r .txhash <<<"$R")" >/dev/null # 6
echo "investor now holds 400 ECONOMIC + 400 VOTE and 0 INCOME (whole units 0): $AEVA_EXPLORER/address/$INVESTOR"
echo "transfer tx: $AEVA_EXPLORER/tx/$(jq -r .txhash <<<"$R")"One transaction moved two kinds atomically. The investor holds a strip — some kinds of the asset without the others — so its whole units (units of every bundled kind at once) are 0.
4. A credentialed asset: only holders the issuer has attested
POLICY="{\"credential\":{\"type\":\"investor.verified\",\"attesters\":[\"$ISSUER\"]}}"
R=$(alias_tx asset create-asset ECONOMIC --settlement-denom aeusd --policy "$POLICY" --from issuer) # 7
CASSET=$(wait_tx "$(jq -r .txhash <<<"$R")" | created_asset)
R=$(alias_tx credential attest "$INVESTOR" investor.verified +720h --from issuer); wait_tx "$(jq -r .txhash <<<"$R")" >/dev/null # 8
R=$(alias_tx rights issue "$CASSET" 0 "$INVESTOR" 100 --from issuer); wait_tx "$(jq -r .txhash <<<"$R")" >/dev/null # 9
R=$(alias_tx rights transfer "$ISSUER" "$CASSET" 0:10 --from investor); wait_tx "$(jq -r .txhash <<<"$R")" >/dev/null || true # 10
echo "refused transfer (the rule path is on the tx page): $AEVA_EXPLORER/tx/$(jq -r .txhash <<<"$R")"
echo "credentialed asset (policy on the Kinds & Policy tab): $AEVA_EXPLORER/assets/$CASSET?tab=kinds"
echo "the investor's attestation: $AEVA_EXPLORER/address/$INVESTOR"tx refused: code 3 (policy): failed to execute message; message index: 0: policy denied at credential(investor.verified): …
refused transfer (the rule path is on the tx page): https://explorer.aevachain.com/tx/…The issue succeeds because the investor holds a valid investor.verified
attestation from the issuer (30 days, +720h). Transaction 10 is refused on
purpose: the investor sends 10 units back to the issuer, who holds no such
attestation. The transaction is in a block — it paid its fee — but nothing
moved, and the explorer’s transaction page shows the refusal and the rule that
refused it.
5. Delivery versus payment: 100 INCOME rights against 50 aeUSD
R=$(alias_tx settlement propose "$INVESTOR" "give:right:$ASSET:1:100,get:coin:50000000aeusd" --expires-in 1h --from issuer) # 11
wait_tx "$(jq -r .txhash <<<"$R")" >/dev/null
SID=$(aevad query settlement by-party "$ISSUER" --status pending --node "$AEVA_NODE" -o json | jq -r '.settlements | max_by(.id | tonumber) | .id')
echo "settlement id: $SID"
echo "pending (issuer's INCOME is locked, countdown in block time): $AEVA_EXPLORER/settlements/$SID"
R=$(alias_tx settlement accept "$SID" --from investor); wait_tx "$(jq -r .txhash <<<"$R")" >/dev/null # 12
echo "settled — both legs moved in one transaction: $AEVA_EXPLORER/settlements/$SID"
echo "accept tx: $AEVA_EXPLORER/tx/$(jq -r .txhash <<<"$R")"At propose, the issuer’s 100 INCOME units are locked (escrowed) in its
own position. At accept, the 100 INCOME units move to the investor and the
50 aeUSD (50 000 000 aeusd, 6 decimals) move to the issuer, in the same
transaction — or, if either side cannot deliver, nothing moves.
6. Check the integrity page
echo "chain vs indexer, every (asset, kind): $AEVA_EXPLORER/integrity"
aevad query rights invariant "$ASSET" --node "$AEVA_NODE" -o json | jq -c '{ok, kinds: [.kinds[] | {kind_id: (.kind_id // 0), sum_of_positions, supply}]}'chain vs indexer, every (asset, kind): https://explorer.aevachain.com/integrity
{"ok":true,"kinds":[{"kind_id":0,"sum_of_positions":"1000","supply":"1000"},{"kind_id":1,"sum_of_positions":"1000","supply":"1000"},{"kind_id":2,"sum_of_positions":"1000","supply":"1000"}]}For every kind, the units held add up to the supply: the chain’s conservation invariant, checked by the chain itself and by the indexer every block.
Twelve transactions in total: send, create, issue ×3, transfer, create,
attest, issue, transfer, propose, accept. Next: the Guides build on
this shell ($ISSUER, $INVESTOR, $ASSET).