Launch an asset
Anyone can create an asset on Aeva: the signer becomes its issuer, chooses its kinds and policy, and issues units. The app’s /launch wizard does it in one transaction (create, issue every kind, lock issuance); this guide does the same steps from the CLI so each is visible. Testnet, tokens have no value, and the launchpad refuses names or copy that promise rewards, airdrops, returns or value.
Run the setup block first; you need a little AEVA for gas.
1. Register the metadata
The chain stores only a 32-byte meta_hash per asset. The launchpad keeps the
document it commits to, name, symbol, description, template and an optional
PNG logo, so the explorer and the app can show it.
DOC=$(curl -s -X POST -H 'content-type: application/json' \
-d '{"name":"Docs Garden Club","symbol":"DGC","description":"A community test asset created from the Aeva docs.","template":"dividend"}' \
"$AEVA_APP/api/launchpad/metadata")
META=$(jq -r .meta_hash <<<"$DOC")
echo "meta_hash: $META"
curl -s "$AEVA_APP/api/launchpad/metadata/$META" | jq -r '"\(.name) (\(.symbol)), template \(.template)\n\(.notice)"'meta_hash: <64 hex characters>
Docs Garden Club (DGC), template dividend
Community-launched test asset on the Aeva testnet; unverified. Testnet — tokens have no value.The hash is the SHA-256 of the canonical document, so the same document always
gets the same hash. Templates are community (one ECONOMIC kind, fixed
supply), dividend (ECONOMIC + INCOME), equity (ECONOMIC, INCOME, VOTE) and
bond (a REDEMPTION kind and one INCOME kind per coupon date).
2. Create, issue, lock
R=$(alias_tx asset create-asset ECONOMIC,INCOME --settlement-denom aeusd --meta-hash "$META" --from me)
MINE=$(wait_tx "$(jq -r .txhash <<<"$R")" | jq -r '.events[] | select(.type == "aeva.asset.v1.EventAssetCreated") | .attributes[] | select(.key == "asset_id") | .value | fromjson')
for k in 0 1; do
R=$(alias_tx rights issue "$MINE" "$k" "$ME" 1000000000000 --from me); wait_tx "$(jq -r .txhash <<<"$R")" >/dev/null
done
R=$(alias_tx asset lock-issuance "$MINE" --from me); wait_tx "$(jq -r .txhash <<<"$R")" >/dev/null
curl -s "$AEVA_INDEXER/v1/assets/$MINE" | jq -r '.asset | "issuer \(.issuer); issuance locked: \(.issuance_locked); \(.kinds | length) kinds"'
echo "asset: $AEVA_EXPLORER/assets/$MINE"issuer aeva1…; issuance locked: true; 2 kinds
asset: https://explorer.aevachain.com/assets/<64 hex characters>That is 1 000 000 whole units of each kind (six decimals), both kinds bundled,
under an OPEN policy, anyone may hold them. After lock-issuance the supply
is fixed forever; transfers, settlements and distributions are unaffected.
The asset id is computed, not assigned:
sha256("aeva/asset/v1" ‖ issuer ‖ uint64_be(n)), where n is the number of
assets the issuer had created before. That is how the app knows the id of the
asset it is about to create and can issue and lock it in the same transaction.
3. Pay your holders
Anyone may distribute aeUSD to a kind; every holder accrues pro rata and claims it, as with the test stocks:
R=$(alias_tx payout distribute "$MINE" 1 1000000aeusd --from me); wait_tx "$(jq -r .txhash <<<"$R")" >/dev/null
curl -s "$AEVA_INDEXER/v1/assets/$MINE/distributions?limit=1" | jq -r '.distributions[0] | "distributed \(.amount) \(.denom) to kind \(.kind_id)"'distributed 1000000 aeusd to kind 1From your own code
The SDK builds the same messages as the wizard:
import { tx } from "@aeva/sdk";
// assetCount: how many assets `issuer` has created (a bigint)
const id = tx.assetIdFor(issuer, assetCount); // the id before it exists
const msgs = [
tx.createAsset({ issuer, kinds, metaHash, settlementDenom: "aeusd" }),
...kinds.map((_, k) => tx.issue({ issuer, assetId: id, kindId: k, to: issuer, units })),
tx.lockIssuance({ issuer, assetId: id }),
];
// sign and broadcast `msgs` as one transactionSee Restrict who may hold for credential policies and Split, redemption, lock issuance for what an issuer can do later.