Description
A single Stellar transaction can contain up to 100 operations of mixed types. The current backend only explains payment operations and skips everything else with a skipped_operations counter. This means most real-world transactions — which often combine create_account, change_trust, set_options, and payments — are only partially explained.
This issue makes the backend explain every operation in a transaction, returning a structured explanation for each one in order.
Current Behaviour
{
"payment_explanations": [...],
"skipped_operations": 3
}
Target Behaviour
{
"operations": [
{
"index": 0,
"type": "create_account",
"summary": "GABC… funded and activated a new Stellar account GDST… with 1.5 XLM",
"details": {
"funder": "GABC...",
"account": "GDST...",
"starting_balance": "1.5"
}
},
{
"index": 1,
"type": "payment",
"summary": "GABC… sent 100 USDC to GDST…",
"details": {
"from": "GABC...",
"to": "GDST...",
"amount": "100",
"asset": "USDC"
}
},
{
"index": 2,
"type": "change_trust",
"summary": "GDST… opted in to hold up to 10,000 USDC issued by GBBB…",
"details": {
"account": "GDST...",
"asset": "USDC",
"issuer": "GBBB...",
"limit": "10000"
}
}
],
"skipped_operations": 0
}
Operation Types to Support
| Type |
Plain-English pattern |
payment |
Already implemented — keep as-is |
create_account |
"{funder} funded and activated a new Stellar account {account} with {starting_balance} XLM" |
change_trust (add) |
"{account} opted in to hold up to {limit} {asset} issued by {issuer}" |
change_trust (remove) |
"{account} removed their trust line for {asset}" |
set_options |
"{account} updated account settings: {list of changes}" |
account_merge |
"{source} merged their account into {destination}, transferring all remaining XLM" |
manage_sell_offer (new) |
"{account} placed a sell order for {amount} {asset} at {price}" |
manage_sell_offer (cancel) |
"{account} cancelled sell order #{offer_id}" |
manage_buy_offer |
"{account} placed a buy order for {amount} {asset} at {price}" |
path_payment_strict_send |
"{from} sent {send_amount} {send_asset}, {to} received {dest_asset}" |
path_payment_strict_receive |
"{from} sent {src_asset}, {to} received exactly {dest_amount} {dest_asset}" |
| All others |
"{type} operation — full support coming soon" (never skip silently) |
Key Files
packages/core/src/explain/operation/ — add one file per new operation type
packages/core/src/explain/operation/mod.rs — register all new modules
packages/core/src/models/operation.rs — add new variants to Operation enum
packages/core/src/services/horizon.rs — ensure all operation fields are mapped
packages/core/src/explain/transaction.rs — update to return operations[] instead of payment_explanations[]
Backward Compatibility
The response must remain backward compatible:
- Keep
payment_explanations field populated (for existing frontend consumers)
- Add new
operations[] field alongside it
- Update
skipped_operations to only count truly unsupported types
Acceptance Criteria
Complexity: High · 200 pts
Description
A single Stellar transaction can contain up to 100 operations of mixed types. The current backend only explains
paymentoperations and skips everything else with askipped_operationscounter. This means most real-world transactions — which often combinecreate_account,change_trust,set_options, and payments — are only partially explained.This issue makes the backend explain every operation in a transaction, returning a structured explanation for each one in order.
Current Behaviour
{ "payment_explanations": [...], "skipped_operations": 3 }Target Behaviour
{ "operations": [ { "index": 0, "type": "create_account", "summary": "GABC… funded and activated a new Stellar account GDST… with 1.5 XLM", "details": { "funder": "GABC...", "account": "GDST...", "starting_balance": "1.5" } }, { "index": 1, "type": "payment", "summary": "GABC… sent 100 USDC to GDST…", "details": { "from": "GABC...", "to": "GDST...", "amount": "100", "asset": "USDC" } }, { "index": 2, "type": "change_trust", "summary": "GDST… opted in to hold up to 10,000 USDC issued by GBBB…", "details": { "account": "GDST...", "asset": "USDC", "issuer": "GBBB...", "limit": "10000" } } ], "skipped_operations": 0 }Operation Types to Support
paymentcreate_accountchange_trust(add)change_trust(remove)set_optionsaccount_mergemanage_sell_offer(new)manage_sell_offer(cancel)manage_buy_offerpath_payment_strict_sendpath_payment_strict_receiveKey Files
packages/core/src/explain/operation/— add one file per new operation typepackages/core/src/explain/operation/mod.rs— register all new modulespackages/core/src/models/operation.rs— add new variants toOperationenumpackages/core/src/services/horizon.rs— ensure all operation fields are mappedpackages/core/src/explain/transaction.rs— update to returnoperations[]instead ofpayment_explanations[]Backward Compatibility
The response must remain backward compatible:
payment_explanationsfield populated (for existing frontend consumers)operations[]field alongside itskipped_operationsto only count truly unsupported typesAcceptance Criteria
operations[]array present in response with correctindexandtypefieldspayment_explanationsstill populated for backward compatibilityskipped_operationsis 0 for transactions using only supported typescargo testpasses with no regressionsComplexity: High · 200 pts