What
In contracts/bulk_payment/src/lib.rs, all four event types are instantiated as bare struct expressions and immediately dropped, so no events are ever emitted to the ledger:
BatchExecutedEvent { batch_id, total_sent: total }; (~line 150)
PaymentSkippedEvent { ... }; (~line 202)
PaymentSentEvent { ... }; (~line 213)
BatchPartialEvent { batch_id, success_count, fail_count }; (~line 242)
Each needs to actually publish via the generated .publish(&env) call for #[contractevent] types.
Why
The backend runs a contract event indexer (backend/src/services/contractEventIndexer.ts, contractEventIndexerService.ts) that depends on these events for real-time payment tracking and analytics. Because the structs are constructed and discarded, zero events reach the ledger — the indexer silently has nothing to index, and on-chain auditability (a core README promise) is broken for bulk payments.
Scope
In scope:
- Publish all four events at their existing construction sites so they are emitted on-chain.
- Confirm the topics/data match what the indexer expects.
Out of scope:
- Adding new event types or changing event field shapes.
- Indexer-side changes (open a follow-up only if field shapes must change).
Acceptance criteria
execute_batch emits BatchExecutedEvent; execute_batch_partial emits BatchPartialEvent plus per-payment PaymentSentEvent/PaymentSkippedEvent.
- A test in
contracts/bulk_payment/src/test.rs asserts emitted events via env.events().all().
cargo test passes for the contract.
Technical context
- File:
contracts/bulk_payment/src/lib.rs (event structs defined ~lines 27-50).
#[contractevent] types expose a .publish(&env) method — see soroban-sdk contractevent docs.
- Sibling contract
cross_asset_payment has the identical bug (separate issue).
What
In
contracts/bulk_payment/src/lib.rs, all four event types are instantiated as bare struct expressions and immediately dropped, so no events are ever emitted to the ledger:BatchExecutedEvent { batch_id, total_sent: total };(~line 150)PaymentSkippedEvent { ... };(~line 202)PaymentSentEvent { ... };(~line 213)BatchPartialEvent { batch_id, success_count, fail_count };(~line 242)Each needs to actually publish via the generated
.publish(&env)call for#[contractevent]types.Why
The backend runs a contract event indexer (
backend/src/services/contractEventIndexer.ts,contractEventIndexerService.ts) that depends on these events for real-time payment tracking and analytics. Because the structs are constructed and discarded, zero events reach the ledger — the indexer silently has nothing to index, and on-chain auditability (a core README promise) is broken for bulk payments.Scope
In scope:
Out of scope:
Acceptance criteria
execute_batchemitsBatchExecutedEvent;execute_batch_partialemitsBatchPartialEventplus per-paymentPaymentSentEvent/PaymentSkippedEvent.contracts/bulk_payment/src/test.rsasserts emitted events viaenv.events().all().cargo testpasses for the contract.Technical context
contracts/bulk_payment/src/lib.rs(event structs defined ~lines 27-50).#[contractevent]types expose a.publish(&env)method — see soroban-sdk contractevent docs.cross_asset_paymenthas the identical bug (separate issue).