{"id":47925016,"url":"https://github.com/ohaddahan/defi-tracker-lifecycle","last_synced_at":"2026-04-04T06:26:48.950Z","repository":{"id":339916500,"uuid":"1161795937","full_name":"ohaddahan/defi-tracker-lifecycle","owner":"ohaddahan","description":"Solana DeFi Tracker Lifecycle","archived":false,"fork":false,"pushed_at":"2026-03-05T18:49:43.000Z","size":2067,"stargazers_count":0,"open_issues_count":2,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-03-05T21:51:35.036Z","etag":null,"topics":["dca","defi","jupiter","kamino","lifecycle","limitorder","solana"],"latest_commit_sha":null,"homepage":"https://ohaddahan.github.io/defi-tracker-lifecycle/","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ohaddahan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-19T14:27:23.000Z","updated_at":"2026-03-05T18:50:01.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ohaddahan/defi-tracker-lifecycle","commit_stats":null,"previous_names":["ohaddahan/defi-tracker-lifecycle"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ohaddahan/defi-tracker-lifecycle","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ohaddahan%2Fdefi-tracker-lifecycle","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ohaddahan%2Fdefi-tracker-lifecycle/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ohaddahan%2Fdefi-tracker-lifecycle/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ohaddahan%2Fdefi-tracker-lifecycle/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ohaddahan","download_url":"https://codeload.github.com/ohaddahan/defi-tracker-lifecycle/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ohaddahan%2Fdefi-tracker-lifecycle/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31389986,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-04T04:26:24.776Z","status":"ssl_error","status_checked_at":"2026-04-04T04:23:34.147Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dca","defi","jupiter","kamino","lifecycle","limitorder","solana"],"created_at":"2026-04-04T06:26:48.046Z","updated_at":"2026-04-04T06:26:48.938Z","avatar_url":"https://github.com/ohaddahan.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# defi-tracker-lifecycle\n\nPure-logic crate for DeFi order lifecycle tracking on Solana. No IO, no database — just classification, correlation, and state machine logic.\n\nDocumentation site: \u003chttps://defi-tracker-lifecycle.turbine.cash/\u003e\n\n## Supported Protocols\n\n| Protocol | Program | Description |\n|----------|---------|-------------|\n| **DCA** | `DCA265Vj8a9CEuX1eb1LWRnDT7uK6q1xMipnNyatn23M` | Jupiter Dollar-Cost Averaging |\n| **Limit V1** | `jupoNjAxXgZ4rjzxzPMP4oxduvQsQtZzyknqvzYNrNu` | Jupiter Limit Orders V1 |\n| **Limit V2** | `j1o2qRpjcyUwEvwtcfhEQefh773ZgjxcVRry7LDqg5X` | Jupiter Limit Orders V2 |\n| **Kamino** | `LiMoM9rMhrdYrfzUCxQppvxCSG1FcrUK9G8uLq4A1GF` | Kamino Limit Orders |\n\n## Architecture\n\n### Event Processing Pipeline\n\n```mermaid\nflowchart TD\n    subgraph Input\n        Raw[\"RawInstruction / RawEvent\"]\n    end\n    subgraph Dispatch\n        Lookup[\"from_program_id()\"] --\u003e Adapter[\"adapter_for()\"]\n    end\n    subgraph Classify\n        CI[\"classify_instruction()\"]\n        CE[\"classify_and_resolve_event()\"]\n    end\n    subgraph Output\n        ET[\"EventType\"]\n        CO[\"CorrelationOutcome\"]\n        EP[\"EventPayload\"]\n    end\n\n    Raw --\u003e Lookup\n    Adapter --\u003e CI \u0026 CE\n    CI --\u003e ET\n    CE --\u003e ET \u0026 CO \u0026 EP\n```\n\n### Order Lifecycle State Machine\n\n```mermaid\nflowchart TD\n    Start(( )) --\u003e|Create| Active\n    Active --\u003e|FillDelta / MetadataOnly| Active\n    Active --\u003e|\"Close(Completed)\"| Completed\n    Active --\u003e|\"Close(Cancelled)\"| Cancelled\n    Active --\u003e|\"Close(Expired)\"| Expired\n\n    subgraph Terminal [\"Terminal — only MetadataOnly accepted\"]\n        Completed\n        Cancelled\n        Expired\n    end\n```\n\n## Core Concepts\n\n**`ProtocolAdapter`** — trait implemented by each protocol. Two phases:\n- **Classify**: maps instruction/event names to `EventType` (Created, FillCompleted, Closed, etc.)\n- **Resolve**: extracts order PDAs (`CorrelationOutcome`) and structured data (`EventPayload`)\n\n**`LifecycleEngine`** — stateless state machine that enforces transition rules:\n- Non-terminal orders accept all transitions\n- Terminal orders (Completed/Cancelled/Expired) only accept `MetadataOnly`\n- Snapshot deltas are always non-negative; regressions tracked separately\n\n**`ResolveContext`** — carries pre-fetched data needed for correlation (Kamino requires pre-fetched order PDAs since its events don't contain them directly)\n\n## Usage\n\n```rust\nuse defi_tracker_lifecycle::{\n    EventPayload, Protocol, adapter_for, event_type_to_transition, ResolveContext,\n    LifecycleEngine, TerminalStatus, TransitionDecision,\n};\n\n// 1. Identify protocol from program ID\nlet protocol = Protocol::from_program_id(\"DCA265Vj8a9CEuX1eb1LWRnDT7uK6q1xMipnNyatn23M\")\n    .ok_or(\"unknown program\")?;\nlet adapter = adapter_for(protocol);\n\n// 2. Classify + resolve an event in one pass\nlet ctx = ResolveContext { pre_fetched_order_pdas: None };\nlet (event_type, correlation, payload) = adapter\n    .classify_and_resolve_event(\u0026raw_event, \u0026ctx)\n    .ok_or(\"unknown event variant\")?  // None = unknown event variant\n    .map_err(|e| e.to_string())?;     // Err = malformed known event payload\n\n// 3. Map EventType to LifecycleTransition via the canonical mapping\nlet closed_status = match \u0026payload {\n    EventPayload::DcaClosed { status } =\u003e Some(*status),\n    EventPayload::KaminoDisplay { terminal_status, .. } =\u003e *terminal_status,\n    _ =\u003e None,\n};\nlet transition = event_type_to_transition(\u0026event_type, closed_status);\n\n// 4. Check state transition (pass None if not terminal)\nlet current_terminal: Option\u003cTerminalStatus\u003e = None;\nlet decision = LifecycleEngine::decide_transition(current_terminal, transition);\nmatch decision {\n    TransitionDecision::Apply =\u003e { /* update order status */ }\n    TransitionDecision::IgnoreTerminalViolation =\u003e { /* order is terminal, skip */ }\n}\n```\n\n## Testing\n\n```bash\ncargo test\ncargo test --all-features\ncargo clippy --all-targets --all-features\n```\n\n### Test Layers\n\n| Layer | What it catches |\n|-------|----------------|\n| Compile-time (`classify_decoded()`) | Upstream Carbon adds a new variant |\n| Mirror enum alignment | Mirror enum drifts from Carbon variants |\n| EventType reachability | A variant becomes dead/unreachable |\n| Unit tests | Individual classify/resolve logic per protocol |\n| Fixture tests | Real JSON from defi-tracker parses and classifies correctly |\n| End-to-end lifecycle | Full pipeline: raw JSON → adapter → state machine → status tracking |\n\n### Coverage (requires [cargo-llvm-cov](https://github.com/taiki-e/cargo-llvm-cov))\n\n```bash\ncargo llvm-cov                                        # text summary\ncargo llvm-cov --html                                 # HTML report → target/llvm-cov/html/\ncargo llvm-cov --lcov --output-path lcov.info         # LCOV for CI upload\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fohaddahan%2Fdefi-tracker-lifecycle","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fohaddahan%2Fdefi-tracker-lifecycle","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fohaddahan%2Fdefi-tracker-lifecycle/lists"}