Skip to content

Commit f9ad692

Browse files
authored
Merge pull request #170 from YahKazo/niff
feat:Contract — Event catalog: schema versioning for NestJS indexers and explorers
2 parents c337a61 + c2f18ae commit f9ad692

11 files changed

Lines changed: 1668 additions & 26 deletions

File tree

EVENT_DICTIONARY.md

Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
# niffyInsure — Event Dictionary
2+
3+
> **Schema version: 1**
4+
> Breaking changes (field removed / type changed) → semver-major contract release + `SCHEMA_VERSION` bump.
5+
> Adding new optional fields is backward-compatible; no bump required.
6+
7+
## Units
8+
9+
| Type | Unit | Notes |
10+
|------|------|-------|
11+
| Token amounts | **stroops** (i128 as string) | 1 XLM = 10 000 000 stroops (7 decimals). Never use floats. |
12+
| Time | **ledger sequence** (u32) | 1 ledger ≈ 5 s on Stellar mainnet. Multiply by 5 for wall-clock seconds. |
13+
| Boolean flags | **u32** (0 / 1) | Matches ABI encoding. `1 = true`, `0 = false`. |
14+
| Addresses | **Stellar address string** | Holder = `G…`, contract/asset = `C…`. |
15+
| Image reference | **FNV-1a u64 hash** | Hash of concatenated IPFS CIDs. Full CIDs stored off-chain. |
16+
17+
---
18+
19+
## Topic layout
20+
21+
Every event has at least two topics:
22+
23+
```
24+
topic[0] namespace "niffyins" (claim/admin events) | "niffyinsure" (policy events)
25+
topic[1] event name see table below
26+
topic[2+] identifiers claim_id, holder, asset, … (event-specific)
27+
```
28+
29+
The indexer discriminates events by `${topic[0]}:${topic[1]}`.
30+
31+
---
32+
33+
## Claim events (`namespace = "niffyins"`)
34+
35+
### `clm_filed` — claim filed
36+
37+
**Topics:** `("niffyins", "clm_filed", claim_id: u64, holder: Address)`
38+
39+
```json
40+
{
41+
"version": 1,
42+
"policy_id": 3,
43+
"amount": "5000000",
44+
"image_hash": 2864434397,
45+
"filed_at": 1234567
46+
}
47+
```
48+
49+
| Field | Type | Description |
50+
|-------|------|-------------|
51+
| `policy_id` | u32 | Per-holder policy identifier |
52+
| `amount` | string (stroops) | Requested payout |
53+
| `image_hash` | u64 | FNV-1a hash of IPFS CIDs |
54+
| `filed_at` | u32 (ledger) | Ledger when claim was filed |
55+
56+
---
57+
58+
### `vote_cast` — ballot cast
59+
60+
**Topics:** `("niffyins", "vote_cast", claim_id: u64, voter: Address)`
61+
62+
```json
63+
{
64+
"version": 1,
65+
"vote": "Approve",
66+
"approve_votes": 2,
67+
"reject_votes": 1,
68+
"at_ledger": 1234568
69+
}
70+
```
71+
72+
| Field | Type | Description |
73+
|-------|------|-------------|
74+
| `vote` | `"Approve"` \| `"Reject"` | This voter's choice |
75+
| `approve_votes` | u32 | Running approve tally after this vote |
76+
| `reject_votes` | u32 | Running reject tally after this vote |
77+
78+
---
79+
80+
### `clm_final` — claim finalized
81+
82+
Emitted when voting reaches majority **or** the vote window expires.
83+
84+
**Topics:** `("niffyins", "clm_final", claim_id: u64)`
85+
86+
```json
87+
{
88+
"version": 1,
89+
"status": "Approved",
90+
"approve_votes": 3,
91+
"reject_votes": 1,
92+
"at_ledger": 1355527
93+
}
94+
```
95+
96+
| Field | Type | Description |
97+
|-------|------|-------------|
98+
| `status` | `"Approved"` \| `"Rejected"` | Final outcome |
99+
100+
---
101+
102+
### `clm_paid` — payout executed
103+
104+
**Topics:** `("niffyins", "clm_paid", claim_id: u64)`
105+
106+
```json
107+
{
108+
"version": 1,
109+
"recipient": "G...",
110+
"amount": "5000000",
111+
"asset": "C...",
112+
"at_ledger": 1355528
113+
}
114+
```
115+
116+
| Field | Type | Description |
117+
|-------|------|-------------|
118+
| `amount` | string (stroops) | Actual payout transferred |
119+
| `asset` | string (C…) | Asset contract used for payout |
120+
121+
---
122+
123+
## Policy lifecycle events (`namespace = "niffyinsure"`)
124+
125+
### `PolicyInitiated` — policy bound
126+
127+
**Topics:** `("niffyinsure", "PolicyInitiated", holder: Address)`
128+
129+
```json
130+
{
131+
"version": 1,
132+
"policy_id": 1,
133+
"premium": "500000",
134+
"asset": "C...",
135+
"policy_type": "Auto",
136+
"region": "Medium",
137+
"coverage": "50000000",
138+
"start_ledger": 1234567,
139+
"end_ledger": 2285767
140+
}
141+
```
142+
143+
| Field | Type | Description |
144+
|-------|------|-------------|
145+
| `policy_id` | u32 | Per-holder identifier (not globally unique; use `holder + policy_id`) |
146+
| `premium` | string (stroops) | Premium paid at bind time |
147+
| `policy_type` | `"Auto"` \| `"Health"` \| `"Property"` | Coverage category |
148+
| `region` | `"Low"` \| `"Medium"` \| `"High"` | Geographic risk tier |
149+
| `coverage` | string (stroops) | Maximum payout |
150+
| `end_ledger` | u32 (ledger) | Expiry ledger |
151+
152+
---
153+
154+
### `PolicyRenewed` — policy renewed
155+
156+
**Topics:** `("niffyinsure", "PolicyRenewed", holder: Address)`
157+
158+
```json
159+
{
160+
"version": 1,
161+
"policy_id": 1,
162+
"premium": "500000",
163+
"new_end_ledger": 3336967
164+
}
165+
```
166+
167+
---
168+
169+
### `PolicyTerminated` — policy terminated
170+
171+
**Topics:** `("niffyinsure", "policy_terminated", holder: Address, policy_id: u32)`
172+
173+
```json
174+
{
175+
"reason_code": 1,
176+
"terminated_by_admin": 0,
177+
"open_claim_bypass": 0,
178+
"open_claims": 0,
179+
"at_ledger": 1234600
180+
}
181+
```
182+
183+
| `reason_code` | Meaning |
184+
|---------------|---------|
185+
| 1 | VoluntaryCancellation |
186+
| 2 | LapsedNonPayment |
187+
| 3 | UnderwritingVoid |
188+
| 4 | FraudOrMisrepresentation |
189+
| 5 | RegulatoryAction |
190+
| 6 | AdminOverride |
191+
192+
---
193+
194+
## Admin / config events (`namespace = "niffyins"`)
195+
196+
| Event | Topics | Key payload fields |
197+
|-------|--------|--------------------|
198+
| `tbl_upd` | `(NS, "tbl_upd")` | `table_version: u32` |
199+
| `asset_set` | `(NS, "asset_set", asset)` | `allowed: 0\|1` |
200+
| `adm_prop` | `(NS, "adm_prop", old_admin, new_admin)` | `version` only |
201+
| `adm_acc` | `(NS, "adm_acc", old_admin, new_admin)` | `version` only |
202+
| `adm_can` | `(NS, "adm_can", admin, cancelled_pending)` | `version` only |
203+
| `adm_tok` | `(NS, "adm_tok")` | `old_token`, `new_token` |
204+
| `adm_paus` | `(NS, "adm_paus", admin)` | `paused: 0\|1` |
205+
| `adm_drn` | `(NS, "adm_drn", admin)` | `recipient`, `amount` (stroops) |
206+
207+
---
208+
209+
## Versioning & migration
210+
211+
1. `SCHEMA_VERSION` in `events.rs` and `events.schema.ts` must stay in sync.
212+
2. A version bump is **required** when any field is removed or its type changes.
213+
3. The `EVENT_PARSERS` table in `events.schema.ts` maps `version → parser`; add a new entry for each bump and keep old entries for historical replay.
214+
4. CI regression tests in `events.test.ts` will fail on shape changes — this is intentional.
215+
216+
---
217+
218+
## What is NOT in events
219+
220+
- Raw IPFS URLs (use `image_hash` to look up off-chain).
221+
- Claim description text.
222+
- Voter lists (derive from `vote_cast` stream).
223+
- PII of any kind.

0 commit comments

Comments
 (0)