Skip to content

Commit 8569e21

Browse files
feat: standardize bill event schema and compatibility checks
1 parent 74502ff commit 8569e21

8 files changed

Lines changed: 1358 additions & 297 deletions

File tree

bill_payments/README.md

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -311,9 +311,51 @@ let overdue = bill_payments::get_overdue_bills(env, user_address);
311311

312312
## Events
313313

314-
The contract emits events for audit trails:
315-
- `BillEvent::Created`: When a bill is created
316-
- `BillEvent::Paid`: When a bill is paid
314+
The contract emits **typed, versioned events** using the `RemitwiseEvents` helper from `remitwise-common`. Every event follows a standardized schema to ensure downstream indexers and consumers can reliably decode event data across contract upgrades.
315+
316+
### Topic Convention
317+
318+
All events use a 4-topic tuple:
319+
320+
```text
321+
("Remitwise", category: u32, priority: u32, action: Symbol)
322+
```
323+
324+
| Position | Field | Description |
325+
|----------|------------|----------------------------------------------------|
326+
| 0 | Namespace | Always `"Remitwise"` — immutable across versions |
327+
| 1 | Category | `0`=Transaction, `1`=State, `3`=System |
328+
| 2 | Priority | `0`=Low, `1`=Medium, `2`=High |
329+
| 3 | Action | Short symbol: `"created"`, `"paid"`, `"canceled"`, etc |
330+
331+
### Event Types
332+
333+
| Operation | Event Struct | Action Symbol | Category | Priority |
334+
|------------------------|-----------------------|---------------|-------------|----------|
335+
| `create_bill` | `BillCreatedEvent` | `"created"` | State | Medium |
336+
| `pay_bill` | `BillPaidEvent` | `"paid"` | Transaction | High |
337+
| `cancel_bill` | `BillCancelledEvent` | `"canceled"` | State | Medium |
338+
| `archive_paid_bills` | `BillsArchivedEvent` | `"archived"` | System | Low |
339+
| `restore_bill` | `BillRestoredEvent` | `"restored"` | State | Medium |
340+
| `set_version` | `VersionUpgradeEvent` | `"upgraded"` | System | High |
341+
| `batch_pay_bills` | `BillPaidEvent` × N | `"paid"` | Transaction | High |
342+
| `pause` | `()` | `"paused"` | System | High |
343+
| `unpause` | `()` | `"unpaused"` | System | High |
344+
345+
### Schema Versioning & Backward Compatibility
346+
347+
Every event struct includes a `schema_version` field (currently `1`) that:
348+
349+
1. Allows downstream consumers to branch decoding logic per version.
350+
2. Guarantees that **field ordering is append-only** — new fields are always added at the end.
351+
3. Is enforced at **compile time** via `assert_min_fields!` macros in `events.rs`.
352+
353+
**Guarantees:**
354+
- Topic symbols (e.g., `"created"`, `"paid"`) are **never renamed** across versions.
355+
- The 4-topic structure `(Namespace, Category, Priority, Action)` is **immutable**.
356+
- Existing fields are **never removed or reordered** — only new optional fields may be appended.
357+
- All events are **deterministically reproducible** from the same contract state.
358+
317359

318360
## Integration Patterns
319361

@@ -335,7 +377,11 @@ Bills can represent insurance premiums, working alongside the insurance contract
335377

336378
## Security Considerations
337379

338-
- All functions require proper authorization
339-
- Owners can only manage their own bills
340-
- Input validation prevents invalid states
341-
- Storage TTL is managed to prevent bloat
380+
- All functions require proper authorization (`require_auth()`)
381+
- Owners can only manage their own bills (enforced by explicit owner check)
382+
- Input validation prevents invalid states (amount, frequency, due_date, currency)
383+
- Currency codes are validated (1-12 alphanumeric chars) and normalized
384+
- Event payloads contain only bill metadata — no sensitive data leakage
385+
- Storage TTL is managed to prevent bloat
386+
- Schema version in events prevents silent breaking changes to consumers
387+
- Compile-time `assert_min_fields!` macros catch accidental field-count regressions

0 commit comments

Comments
 (0)