Events
The typed events every Aeva module emits — the change log the indexer derives its tables from (the contract as written in docs/spec/events.md, reproduced below). Every event is also a transaction log entry the explorer shows on the tx page (Logs & Events).
Status: v1 FROZEN as of M0.3 (+ the two M0.4 additive fields); frozen at the ceremony commit (decision 83). v2 (M1.1) is a post-genesis additive section: new events and additive fields only. Fields may be added with new field numbers; no field may be renamed, retyped, renumbered or removed; no event may be removed or have its emission conditions changed. Any change to this file is a consensus-API change and needs an ADR.
Consumers: the M0.4 indexer ([ADR-005]) derives the whole rights graph from these events alone; the chain’s own queries are used for reconciliation only. Wallets and explorers should read the indexer, not raw events.
Encoding
- Every event is a typed event (
EventManager.EmitTypedEvent): the ABCI eventtypeis the full proto message name (e.g.aeva.rights.v1.EventIssued) and every attribute is one top-level field,key= proto JSON field name,value= the field’s proto-JSON encoding as a JSON literal (strings are quoted:"400", messages are objects, enums are their names,bytesare base64, timestamps RFC3339).sdk.ParseTypedEventreverses this. - Baseapp appends two non-field attributes that decoders must ignore:
msg_index(tx events; the index of the message in the tx) andmode(BeginBlock|EndBlock, block-level events). - Amount fields (
units,new_supply,encumbered,amount) arecosmossdk.io/math.Int→ decimal strings,0 < v ≤ 2^128 − 1. There are no floats anywhere. - Addresses are bech32
aeva1…account strings. - Failed transactions revert their state; their typed events are not part
of the change log (a failed tx’s
TxResult.eventscarries only ante events). Consumers must skip events of txs withcode != 0.
Attribution
| where an event appears | attributed to |
|---|---|
block_results.txs_results[i].events | (height, tx_index = i, tx_hash, msg_index) |
block_results.finalize_block_events | (height) only; mode says BeginBlock/EndBlock |
Aeva emits block-level events only from EndBlock (settlement expiry sweep).
Ordering within a block
BeginBlock events → tx events in tx order, msg order, emission order → EndBlock events. The indexer derives state in exactly this order.
Catalogue
Int = math.Int decimal string. Timestamp = RFC3339 (google.protobuf.Timestamp).
bytes = base64 in JSON.
aeva.asset.v1
| event | # | field | type | notes |
|---|---|---|---|---|
EventAssetCreated | 1 | asset_id | string (64 lower-case hex) | |
| 2 | issuer | address | ||
| 3 | nonce | uint64 | issuer nonce consumed | |
| 4 | kind_count | uint32 | ||
| 5 | asset | aeva.asset.v1.Asset | M0.4 additive. Full asset as stored at creation: id, issuer, roles{custodian, transfer_agent, operator}, meta_hash, settlement_denom, kinds[]{kind_id, class, supply="0", decimals, bundle, term, transferable, policy_override}, policy, status=ASSET_STATUS_ACTIVE | |
EventPolicySet | 1 | asset_id | string | |
| 2 | target | enum PolicyTarget | POLICY_TARGET_ASSET | POLICY_TARGET_KIND | |
| 3 | kind_id | uint32 | meaningful when target == KIND | |
| 4 | policy | aeva.policy.v1.Policy | the new policy (oneof rule: open, all, any, credential, allowlist, max_holders) | |
EventStatusSet | 1 | asset_id | string | |
| 2 | status | enum AssetStatus | ASSET_STATUS_ACTIVE | ASSET_STATUS_FROZEN |
Emitted by: MsgCreateAsset, MsgSetPolicy, MsgSetStatus (one each).
aeva.rights.v1
| event | # | field | type | notes |
|---|---|---|---|---|
EventIssued | 1 | asset_id | string | |
| 2 | kind_id | uint32 | ||
| 3 | issuer | address | ||
| 4 | to | address | ||
| 5 | units | Int | ||
| 6 | new_supply | Int | post-value | |
EventRedeemed | 1 | asset_id | string | |
| 2 | kind_id | uint32 | ||
| 3 | holder | address | ||
| 4 | units | Int | ||
| 5 | new_supply | Int | post-value | |
EventTransferred | 1 | asset_id | string | |
| 2 | from | address | ||
| 3 | to | address | ||
| 4 | legs | []TransferLeg{kind_id uint32, units Int} | every leg of the message | |
EventParamsUpdated | 1 | params | Params{invariant_check_period uint64} | |
EventLocked | 1 | asset_id | string | |
| 2 | kind_id | uint32 | ||
| 3 | holder | address | ||
| 4 | ref | string | "<module>/<id>", e.g. settlement/42 | |
| 5 | units | Int | units locked by this call | |
| 6 | encumbered | Int | post-value of the position | |
EventUnlocked | 1 | asset_id | string | |
| 2 | kind_id | uint32 | ||
| 3 | holder | address | ||
| 4 | ref | string | ||
| 5 | units | Int | units released | |
| 6 | encumbered | Int | post-value of the position | |
EventLockedTransferred | 1 | asset_id | string | |
| 2 | kind_id | uint32 | ||
| 3 | from | address | lock holder | |
| 4 | to | address | receives free units | |
| 5 | ref | string | ||
| 6 | units | Int |
Emitted by: MsgIssue → EventIssued; MsgRedeem → EventRedeemed;
MsgTransfer → EventTransferred; MsgUpdateParams → EventParamsUpdated;
keeper Lock → EventLocked (today: inside settlement.MsgPropose);
keeper Unlock → EventUnlocked (inside settlement.MsgCancel, and in the
EndBlock expiry sweep); keeper TransferLocked → EventLockedTransferred
(inside settlement.MsgAccept). A lock event is always accompanied by the
caller’s own event in the same tx / block.
aeva.credential.v1
| event | # | field | type | notes |
|---|---|---|---|---|
EventAttested | 1 | subject | address | |
| 2 | type | string | ^[a-z0-9]+(\.[a-z0-9]+)*$, ≤ 64 | |
| 3 | attester | address | ||
| 4 | expiry | Timestamp | ||
| 5 | evidence_hash | bytes | empty or 32 bytes | |
EventRevoked | 1 | subject | address | |
| 2 | type | string | ||
| 3 | attester | address |
Emitted by: MsgAttest (upsert: re-attesting a revoked or expired record
emits EventAttested again with revoked implicitly reset to false),
MsgRevoke. No personal data is ever carried.
aeva.settlement.v1
Leg = {direction enum Direction, oneof kind: right{asset_id, kind_id, units Int} | coin{denom, amount Int}},
Direction ∈ {DIRECTION_PROPOSER_TO_COUNTERPARTY, DIRECTION_COUNTERPARTY_TO_PROPOSER}.
| event | # | field | type | notes |
|---|---|---|---|---|
EventProposed | 1 | id | uint64 | |
| 2 | proposer | address | ||
| 3 | counterparty | address | ||
| 4 | legs | []Leg | ||
| 5 | expiry | Timestamp | ||
| 6 | memo_hash | bytes | M0.4 additive. empty or 32 bytes | |
EventSettled | 1 | id | uint64 | |
| 2 | proposer | address | ||
| 3 | counterparty | address | ||
| 4 | legs | []Leg | every executed leg | |
EventCancelled | 1 | id | uint64 | |
| 2 | canceller | address | proposer or counterparty | |
EventExpired | 1 | id | uint64 | |
EventParamsUpdated | 1 | params | Params{max_ttl Duration, max_legs uint32, max_expirations_per_block uint32} |
Emitted by: MsgPropose → EventProposed (+ EventLocked per proposer
right leg); MsgAccept → EventSettled (+ EventLockedTransferred per
proposer right leg); MsgCancel before expiry → EventCancelled (+
EventUnlocked per proposer right leg); MsgCancel at/after expiry →
EventExpired (+ EventUnlocked…) in the tx; EndBlock sweep →
EventExpired (+ EventUnlocked…) as block-level events;
MsgUpdateParams → EventParamsUpdated.
v2 — post-genesis additive (M1.1, decision 92)
New events (all typed, same encoding and attribution rules). Existing events
are unchanged; EventAssetCreated.asset now carries Asset.liens_allowed (9)
by virtue of embedding the full Asset message, and KindInvariantStatus
(a query type, not an event) gains encumbrances_ok (8).
aeva.asset.v1 (v2)
| event | # | field | type | notes |
|---|---|---|---|---|
EventRolesSet | 1 | asset_id | string | |
| 2 | issuer | address | signer | |
| 3 | roles | Roles | new roles (custodian, transfer_agent, operator; empty = unset) | |
EventLiensAllowedSet | 1 | asset_id | string | |
| 2 | liens_allowed | bool | ||
EventKindPolicyCleared | 1 | asset_id | string | |
| 2 | kind_id | uint32 | the kind whose policy_override was removed (inherits the asset policy) |
Emitted by: MsgSetRoles → EventRolesSet; MsgSetLiensAllowed →
EventLiensAllowedSet; MsgSetPolicy{clear_kind} → EventKindPolicyCleared
(a MsgSetPolicy with asset / kind_id still emits EventPolicySet).
aeva.encumbrance.v1 (v2)
Encumbrances lock disjoint units under the lock ref encumbrance/<id>; every
creation is accompanied by aeva.rights.v1.EventLocked with that ref, every
release / expiry by EventUnlocked, every exercise by EventLockedTransferred
(holder → beneficiary) in the same tx / block.
| event | # | field | type | notes |
|---|---|---|---|---|
EventPledged | 1 | id | uint64 | |
| 2 | asset_id | string | ||
| 3 | kind_id | uint32 | ||
| 4 | holder | address | signer | |
| 5 | units | Int | ||
| 6 | beneficiary | address | ||
| 7 | holder_release_after | timestamp | optional; absent = the holder may never release | |
| 8 | exercisable | bool | ||
| 9 | expiry | timestamp | optional | |
| 10 | evidence_hash | bytes | empty or 32 bytes | |
EventLienCreated | 1 | id | uint64 | |
| 2 | asset_id | string | ||
| 3 | kind_id | uint32 | ||
| 4 | holder | address | the encumbered position’s holder | |
| 5 | units | Int | ||
| 6 | beneficiary | address | ||
| 7 | operator | address | signer; the asset’s operator role | |
| 8 | exercisable | bool | ||
| 9 | expiry | timestamp | optional | |
| 10 | evidence_hash | bytes | exactly 32 bytes | |
EventLockupCreated | 1 | id | uint64 | |
| 2 | asset_id | string | ||
| 3 | kind_id | uint32 | ||
| 4 | holder | address | the recipient of MsgIssue | |
| 5 | units | Int | the issued units | |
| 6 | issuer | address | ||
| 7 | holder_release_after | timestamp | MsgIssue.lockup_until | |
EventEncumbranceReleased | 1 | id | uint64 | |
| 2 | releaser | address | beneficiary, holder, operator or issuer per decision 85 | |
| 3 | units | Int | units returned to the holder | |
EventEncumbranceExercised | 1 | id | uint64 | |
| 2 | units | Int | units moved to the beneficiary | |
| 3 | remaining | Int | post-value; 0 = EXERCISED | |
| 4 | beneficiary | address | ||
EventEncumbranceExpired | 1 | id | uint64 | block-level (EndBlock sweep) |
EventParamsUpdated | 1 | params | Params | audit only |
Emitted by: MsgPledge → EventPledged; MsgLien → EventLienCreated;
MsgIssue{lockup_until} → EventLockupCreated (after EventIssued, same
tx); MsgRelease → EventEncumbranceReleased; MsgExercise →
EventEncumbranceExercised; EndBlock sweep → EventEncumbranceExpired;
MsgUpdateParams → EventParamsUpdated. A lazy expiry inside a failing
MsgRelease / MsgExercise is rolled back with the tx: the sweep is the
authoritative expiry path (same caveat as settlements).
aeva.asset.v1 (v2, M1.2)
| event | # | field | type | notes |
|---|---|---|---|---|
EventDistributionDenomsSet | 1 | asset_id | string | |
| 2 | denoms | string[] | the new allowlist (1..8); governs new distributions only |
Asset.distribution_denoms (10) is carried by EventAssetCreated.asset.
Emitted by: MsgSetDistributionDenoms → EventDistributionDenomsSet.
aeva.asset.v1 (v3, overnight phase 2 — issuance lock)
| event | # | field | type | notes |
|---|---|---|---|---|
EventIssuanceLocked | 1 | asset_id | string | emitted once per asset, ever |
| 2 | issuer | string | the signer |
Asset.issuance_locked (11) is false in every EventAssetCreated.asset
(a MsgCreateAsset with the flag set is rejected). Emitted by:
MsgLockIssuance → EventIssuanceLocked. A second lock fails with
ErrAlreadyLocked and emits nothing; MsgIssue on a locked asset fails with
ErrIssuanceLocked (asset codespace 18) and emits nothing.
aeva.payout.v1 (v2, M1.2, decision 103)
| event | # | field | type | notes |
|---|---|---|---|---|
EventDistributed | 1 | asset_id | string | |
| 2 | kind_id | uint32 | ||
| 3 | denom | string | ||
| 4 | payer | address | any signer | |
| 5 | amount | Int | base units deposited in the payout module account | |
| 6 | new_index | Int | post-value; scaled by 10^18 | |
| 7 | carry_scaled | Int | post-value; < supply | |
| 8 | supply | Int | the kind supply at this instant (the ex-date is this block) | |
EventPendingSettled | 1 | holder | address | |
| 2 | asset_id | string | ||
| 3 | kind_id | uint32 | ||
| 4 | denom | string | ||
| 5 | amount | Int | accrued moved into pending (units·(index − checkpoint) div 10^18) | |
| 6 | new_checkpoint | Int | post-value = the accrual index | |
EventClaimed | 1 | holder | address | |
| 2 | asset_id | string | ||
| 3 | kind_id | uint32 | ||
| 4 | denom | string | ||
| 5 | amount | Int | paid from the module account; pending is 0 afterwards | |
EventParamsUpdated | 1 | params | Params | audit only |
Emitted by: MsgDistribute → EventDistributed; the x/rights units-change
hook (Issue recipient, Redeem, Transfer both parties, TransferLocked both
parties — never Lock / Unlock) → EventPendingSettled for every accrual of
the (asset, kind) whose index moved since the holder’s checkpoint, before
the position event of the same tx; MsgClaim / MsgClaimAll →
EventPendingSettled (when accrued > 0) then EventClaimed per paid
(asset, kind, denom); MsgUpdateParams → EventParamsUpdated.
v3 — EVM facade (M5, decision 114): no new Aeva events
The AE-20 precompiles emit the same typed events as the native path: a
right or bundle transfer / transferFrom is one aeva.rights.v1.EventTransferred
(one leg per kind moved) inside a /cosmos.evm.vm.v1.MsgEthereumTx; the
payout hook’s EventPendingSettled precede it exactly as for MsgTransfer.
The ERC-20 Transfer / Approval logs live in cosmos/evm’s tx_log
attributes and are not part of this contract — the indexer derives from
typed events only (ADR-005, ADR-011). cosmos/evm’s own events
(ethereum_tx, tx_log, block_bloom, fee market events) are stored raw
like any other module’s; block_bloom carries a raw 256-byte value, which
the indexer stores hex-encoded. The indexer’s txs table gains the EVM
metadata of a MsgEthereumTx (eth hash, 0x from / to, value, status, gas,
revert reason) from the tx body and result, not from events.
Not events
Coin movements of settlement legs are ordinary x/bank events (coin_spent,
coin_received, transfer) and are not part of this contract; the settlement
legs in EventProposed / EventSettled are authoritative for what moved.
Module parameters are consensus state readable through the chain’s Params
queries; the EventParamsUpdated events exist for audit, not derivation.
Change log of this contract
| date | change |
|---|---|
| 2026-09-19 (M0.3) | catalogue frozen: 3 asset, 7 rights, 2 credential, 5 settlement events |
| 2026-09-19 (M0.4) | additive: EventAssetCreated.asset (5), EventProposed.memo_hash (6) |
| 2026-09-20 (M1.1) | v2 section: 3 asset + 7 encumbrance events; Asset.liens_allowed inside EventAssetCreated.asset |
| 2026-09-20 (M1.2) | v2: EventDistributionDenomsSet; 4 payout events; Asset.distribution_denoms inside EventAssetCreated.asset |
| 2026-09-21 (RH-2) | v5 section: 5 aeva.bridge.v1 events; I8 |
| 2026-09-21 (v0.12.0) | v6 section: aeva.fee.v1.EventParamsUpdated; the settlement denom is aeusd in every event payload (pre-genesis rename, ADR-016 §1) |
aeva.settlement.v1 (v3, M2)
EventCancelled gains reason (3): empty for a party’s cancel,
"LIQUIDATION" when x/waterfall cancelled the PENDING settlement of a
liquidating asset; canceller (2) is empty in that case.
aeva.waterfall.v1 (v3, M2, overnight phase 3)
| event | # | field | type | notes |
|---|---|---|---|---|
EventWaterfallSet | 1 | asset_id | string | |
| 2 | tiers | Tier[] | the whole new list (≤ 16) | |
EventLiquidated | 1 | asset_id | string | preceded by EventStatusSet{LIQUIDATING} |
| 2 | by | string | issuer or operator | |
| 3 | window_end | Timestamp | ||
| 4 | cancelled_settlements | uint32 | one EventCancelled{reason: LIQUIDATION} each, earlier in the tx | |
EventLiquidationSwept | 1 | asset_id | string | block-level (EndBlocker); preceded by EventStatusSet{LIQUIDATED} |
EventProceedsDeposited | 1–3 | asset_id, payer, coin{denom, amount} | ||
EventTierPaid | 1 | asset_id | string | one per tier that received something in a run |
| 2 | tier_index | uint32 | ||
| 3 | type | TierType | FIXED or PRO_RATA | |
| 4 | claimant | string | FIXED only | |
| 5 | kind_id | uint32 | PRO_RATA only (its EventDistributed precedes) | |
| 6 | amount | DenomAmount | this payment | |
| 7 | cumulative | Int | the tier’s total after it | |
EventWaterfallRun | 1–5 | asset_id, caller, paid_fixed[], routed_pro_rata[], leftover[] | per denom, this run | |
EventRedemptionFunded | 1–8 | asset_id, kind_id, denom, issuer, price_per_unit, amount, funded, until | funded is cumulative | |
EventRedeemedForPool | 1–7 | asset_id, kind_id, denom, holder, units (raw), paid, pool_paid | the EventRedeemed of x/rights precedes it in the tx | |
EventRedemptionWithdrawn | 1–5 | asset_id, kind_id, denom, issuer, amount | ||
EventSplit | 1–4 | asset_id, kind_id, factor, multiplier | the new multiplier = old × factor; raw events elsewhere are unchanged |
RightKind.multiplier (9) is carried by EventAssetCreated.asset (always 0
at creation).
aeva.payout.v1 (v3, M3, overnight phase 4)
| event | # | field | type | notes |
|---|---|---|---|---|
EventRouteCreated | 1–6 | asset_id, kind_id, ref, holder, recipient, units | preceded by the holder’s EventPendingSettled (units before the route) | |
EventRouteSettled | 1–6 | asset_id, kind_id, ref, denom, amount, new_checkpoint | the route’s accrued moved into its pending | |
EventRouteRemoved | 1–5 | asset_id, kind_id, ref, recipient, moved[]{denom, amount} | each moved went into the recipient’s own checkpoint pending; followed by EventUnlocked / the units move | |
EventClaimed | 6 | ref | string | set when the claim paid a routed entry |
aeva.payout.v1 (v4, v0.10.1 — P4)
| event | # | field | type | notes |
|---|---|---|---|---|
EventRouteReduced | 1–8 | asset_id, kind_id, ref, holder, recipient, units_removed, units, moved[]{denom, amount} | a partial exercise of a routed pledge: both parties settled (each moved went into the recipient’s own checkpoint pending), the route continues on units (> 0) with a fresh checkpoint at the current index; preceded by the holder’s / recipient’s EventPendingSettled and the route’s EventRouteSettled, followed by EventLockedTransferred. A full exercise emits EventRouteRemoved instead |
EventPendingSettled.amount for a holder with routes is (units − routed) × Δindex.
aeva.delegation.v1 (v3, M3)
| event | # | field | type | notes |
|---|---|---|---|---|
EventDelegated | 1 | delegation | Delegation | the full record (ended unset); EventLocked (ref delegation/<id>) and, for INCOME, EventRouteCreated in the same tx |
EventDelegationEnded | 1 | id | uint64 | |
| 2 | reason | EndReason | EXPIRED (block-level, sweep) · REVOKED · RETURNED; EventRouteRemoved (INCOME) and EventUnlocked follow |
aeva.encumbrance.v1 (v3, M3)
EventPledged gains income_to_beneficiary (11).
v5 — the Robinhood Chain bridge (RH-2, ADR-015)
aeva.bridge.v1 (v5)
The bridge modules are hyperlane-cosmos’ x/core (mailbox, ISMs, hooks)
and x/warp (tokens) behind Aeva’s own x/bridge route registry. The five
Aeva events below are the change-log contract; hyperlane’s own events
(hyperlane.core.v1.EventDispatch / EventProcess,
hyperlane.warp.v1.EventSendRemoteTransfer / EventReceiveRemoteTransfer,
the ISM / mailbox / token events) are emitted alongside them in the same tx
and are not part of the contract — consumers derive from aeva.bridge.v1.
| event | # | field | type | notes |
|---|---|---|---|---|
EventRouteSet | 1 | route | Route | the stored route: route_id, remote_domain, remote_contract (0x bytes32), direction (NATIVE_OUT · SYNTHETIC_IN), local_denom (native denom · hyperlane/<token id>), status, caps{window_seconds, outbound_limit, inbound_limit}, warp_token_id, display, exponent, outbound, inbound |
| 2 | created | bool | true on creation (the warp token was created and the remote router enrolled in the same tx), false on an update | |
EventRoutePaused | 1 | route_id | string | |
| 2 | paused | bool | true: both directions rejected from now on; false: resumed | |
EventBridgedOut | 1 | route_id | string | |
| 2 | sender | address | the local account debited (escrow for NATIVE_OUT, burn for SYNTHETIC_IN) | |
| 3 | remote_recipient | string | 0x bytes32 | |
| 4 | amount | Int | in local_denom | |
| 5 | message_id | string | the Hyperlane message id (0x bytes32); matches the remote process | |
EventBridgedIn | 1 | route_id | string | |
| 2 | recipient | address | the local account credited (release for NATIVE_OUT, mint for SYNTHETIC_IN) | |
| 3 | amount | Int | in local_denom | |
| 4 | message_id | string | the Hyperlane message id of the delivered message | |
EventCapExceeded | 1 | route_id | string | |
| 2 | flow | Flow | OUT · IN | |
| 3 | amount | Int | the rejected amount | |
| 4 | used | Int | the window total before the transfer | |
| 5 | limit | Int | the window limit |
Emission: EventRouteSet / EventRoutePaused from the governance messages
(MsgSetRoute, MsgPauseRoute); EventBridgedOut from MsgBridgeOut, the
only outbound path (hyperlane.warp’s MsgRemoteTransfer is rejected by the
bank restriction on the warp account); EventBridgedIn from the relayer’s
hyperlane.core.v1.MsgProcessMessage through the wrapped warp app handler.
EventCapExceeded is emitted in a failing execution: the message
returns ErrCapExceeded (codespace bridge, code 5) and the tx fails, so
the event is visible in simulation / CheckTx results and in the failing tx’s
error, never in a committed block’s events (the SDK discards a failed tx’s
message events). The indexer derives rejected transfers from the failed
MsgBridgeOut tx code instead. Inbound cap rejections fail the relayer’s
tx; the relayer retries when the window has room — nothing is queued on
chain. (Restated under v6.)
Invariant I8 (introduced 0.11.0): per NATIVE_OUT route, the warp collateral
escrowed for the route’s token == outbound − inbound; per native denom the
sum of those escrows == the warp module account’s balance; per SYNTHETIC_IN
route the synthetic’s bank supply == inbound − outbound.
v6 — v0.12.0 (ADR-016)
aeva.fee.v1 (v6)
| event | # | field | type | notes |
|---|---|---|---|---|
EventParamsUpdated | 1 | params | Params | {accept_aeusd}; governance (block-level, EndBlock) |
Not a derivation source (Conventions: params are read from the chain).
aeva.asset.v1 (v6 additions — RH-3)
| event | # | field | type | notes |
|---|---|---|---|---|
EventKindBridgeableSet | 1 | asset_id | string | |
| 2 | kind_id | uint32 | ||
| 3 | bridgeable | bool | the issuer’s flag (MsgSetKindBridgeable); a RIGHT_OUT route needs it and an OPEN effective policy |
Derives right_kinds.bridgeable.
aeva.bridge.v1 (v6 additions — RH-3, ADR-017)
Route gains asset_id, kind_id, bundle, escrow_address (set on
DIRECTION_RIGHT_OUT routes; local_denom is the pseudo denom
right/<asset>/<kind> or bundle/<asset>). EventRouteSet carries them.
| event | # | field | type | notes |
|---|---|---|---|---|
EventRightBridgedOut | 1 | route_id | string | |
| 2 | asset_id | string | ||
| 3 | kind_id | uint32 | ignored when bundle | |
| 4 | bundle | bool | whole bundles | |
| 5 | sender | address | the local holder debited (policy-checked transfer to the escrow) | |
| 6 | remote_recipient | 0x bytes32 | ||
| 7 | units | Int | raw units (bundle: whole bundles) | |
| 8 | message_id | 0x hex | ||
EventRightBridgedIn | 1 | route_id | string | |
| 2 | asset_id | string | ||
| 3 | kind_id | uint32 | ||
| 4 | bundle | bool | ||
| 5 | recipient | address | the local account credited (policy-checked transfer from the escrow) | |
| 6 | units | Int | ||
| 7 | message_id | 0x hex | ||
EventEscrowIncomeSwept | 1 | route_id | string | governance (MsgSweepEscrowIncome), block-level |
| 2 | recipient | address | ||
| 3 | swept | []DenomAmount | the escrow’s claimed income, per denom |
Derives bridge_routes.outbound / inbound (I8b: escrow units == outbound −
inbound), bridge_transfers rows with asset_id / kind_id / bundle, and
bridge_routes.income_swept. Nothing is minted on Aeva: a right transfer
never touches supply.
A note on EventCapExceeded
aeva.bridge.v1.EventCapExceeded is a CheckTx-level reason: it is emitted
in the execution that fails with bridge/5, so it shows up in simulation
and CheckTx results and in the failing tx’s error, and never appears in a
committed block. Consumers derive rejected transfers from the failed tx’s
code, not from this event.