feat(indexer): index community SKU and settings invoices on /api/v1/protocol/fees #1210

Closed
opened 2026-09-06 12:05:09 +00:00 by ops-worker · 7 comments
Member

Summary

Index community-tax SKU unlock and settings-batch invoices (canonical 50 UST1 each, forwarded to CMM) on GET /api/v1/protocol/fees. On-chain invoices and the community-token catalog already exist. The protocol fee API does not.

This issue already bundles both invoice kinds (sku_unlock + settings_fee). Do not split them. Do not mix factory pair-creation uluna (#1209). Design/home: #1213.

Closed marketing tracker: cl8y-marketing#4. Do not reopen it.

Land after (or stacked on) the pair-creation FeeSource widening pattern. Do not expand #1209’s MR.

Given / When / Then

Given a paid EnableFeature, UpdateSettings batch, or launcher create_token with sku_count > 0 on pinned/catalogued emitters
When the indexer ingests that success tx
Then it inserts one protocol_fee_events row per paid invoice (sku_unlock or settings_fee) with amount from the canonical attr / sku_count × 50e6
And launcher+token EnableFeature in the same tx is still one fee row
And migrate-adopt, tax skim, #595 swap/wrap legs, gas, and reverted invoices are not community fee rows

Not a duplicate / already implemented

Issue Why it is not this ticket
#1213 (closed) Design/home. No ingest.
#1209 Factory pair_creation uluna. Prerequisite pattern; different source.
#1211 Cohort split. Unjoined/unknown is OK until this stream exists.
#594 Catalog community_token_events — “which SKU,” not treasury USD.
#592 / #595 / #606 On-chain invoices / pay-with-any-token routing. Swap legs stay swap_amm / wrap.
#597 MM subscription invoices (out of scope).
#1202 Client events. Do not put invoice amounts there.

Not implemented: FeeSource has no sku_unlock / settings_fee. Catalog events are not read by /protocol/fees.


Current codebase

On-chain invoices (already correct)

INVOICE_UST1 = 50_000_000 (6 dp) in community-tax-token / launcher:

Path Who pays Amount Treasury path Wasm
Create with N unique SKUs Manager UST1 Send to pinned launcher 50 UST1 × N Launcher Transfer UST1 → CMM (does not also send to the token) Launcher action=create_token + sku_count; reply create_token_ready has no invoice attr
Create with 0 SKUs ExecuteMsg::CreateToken (no UST1) 0 None Not a fee
Later EnableFeature Manager → launcher → token 50 UST1 Launcher re-Sends UST1 to the token; token Transfers to CMM Token enable_feature + sku + invoice (launcher often has no invoice)
UpdateSettings batch Manager UST1 Send to token 50 UST1 flat (whole batch) Token Transfer → CMM Token update_settings + invoice
Free migrate-adopt None 0 None Not a fee
Wrong amount / no-op / already-on Revert — Fee not kept No success fee row

Pay-with-any-token (#595) only routes off-chain. Launcher/token still accept UST1 Send only. Swap/wrap legs on that path may already produce swap_amm / wrap protocol fees. Those are not community invoices.

Catalog ingest (exists; not the fee API)

community_tokens.rs (#594) parses enable_feature / update_settings / create_token_ready into community_token_events. Gaps vs treasury census:

  • create_token_ready stores no invoice amount (create-time N × 50 UST1 lives on launcher create_token).
  • enable_feature may insert two catalog rows in one tx (launcher + token).
  • GET /api/v1/protocol/fees does not read that table.

Protocol fee API

Seven FeeSources. COMMUNITY_TOKEN_LAUNCHER may be unset — omit community invoice sources then (do not fake $0), same as wrap/window. GET is O(1) rollup / 60s cache.

Frontend ProtocolFeeSourceKey has no SKU/settings labels.


Why the new implementation is needed

North-star ledgers should include project-team invoices, not only swap/book/wrap/window. Catalog /community-tokens answers “which token unlocked which SKU,” not “how much protocol invoice revenue in this window.”

Idle volume (event_count = 0) is not a reason to skip ingest. The first paid SKU must appear on the same API, with the same unpriced/idle/window semantics.


Constraints / guardrails

  • Do not mix pair_creation. Separate FeeSource string(s). Do not count factory creation_fee_uluna here.
  • Do not change S1 client analytics (#1202). No campaign_id on fee rows.
  • Count CMM UST1 invoice inflows only. Not tax skim, AutoLP, migrate-adopt, gas, Classic burn tax, or #595 swap/wrap legs.
  • One treasury row per paid invoice. EnableFeature: prefer token invoice attr (canonical 50e6). Ignore the launcher’s same-tx enable_feature as a second fee. Create with SKUs: count launcher create_token once (sku_count × 50e6). Do not also infer from create_token_ready.
  • Fail closed on amount. Require amount_raw > 0. Do not infer 50e6 × catalog SKU flags.
  • Pin emitters (#285). Launcher wasm only when reserved _contract_address equals pinned COMMUNITY_TOKEN_LAUNCHER. Token wasm only for catalogued community tokens. Spoof enable_feature from a random CW20 is ignored.
  • Asset identity is the UST1 CW20 contract (hub catalog), never symbol= and never $1 UST1.
  • GET stays O(1) rollup / 60s cache. Unconfigured launcher/catalog pins omit the sources. Configured + no events → idle "0".
  • Out of scope: changing INVOICE_UST1; MM subscription (#597); invoice-payer adapter wasm; exact-out /route/solve; marketing fee tables.

Relevant files

Path Why
indexer/src/indexer/protocol_fees.rs FeeSource / wrap-window pattern
indexer/src/indexer/parser.rs ingest_protocol_fee
indexer/src/indexer/community_tokens.rs Catalog only; do not treat as fee truth
indexer/src/db/queries/protocol_fees.rs Insert / rollup
indexer/src/config.rs COMMUNITY_TOKEN_LAUNCHER, hub UST1
indexer/src/api/protocol_fees.rs, protocol_fee_series.rs, api/defillama.rs Public ledger
indexer/tests/indexer_protocol_fees.rs, api_community_tokens.rs Fee + catalog regression
frontend-dapp/src/types/index.ts, components/protocol/ProtocolFeeStats.tsx Keys / labels
smartcontracts/contracts/community-tax-token/src/invoice.rs invoice attr (read-only)
smartcontracts/contracts/community-token-launcher/src/contract.rs sku_count (read-only)
skills/AGENTS_INDEXER_UST1_WINDOW_FEES.md, AGENTS_INDEXER_FEE_LEDGER_HOME.md, AGENTS_INDEXER_COMMUNITY_TOKENS.md Pattern / catalog ≠ fees

  1. After #1209 FeeSource widening exists (or in a follow-up change set on that pattern), add two sources:
    • sku_unlock — create-time paid SKUs and later EnableFeature (retail label SKU unlock).
    • settings_fee — UpdateSettings batches (retail label Settings invoice).
      Prefer two keys. One combined community_invoice only if Defillama/UI cannot take two.
  2. Parser (per-action scan, reserved _contract_address, same flattening as wrap #613):
    • Pinned launcher + action=create_token + sku_count > 0 → sku_unlock amount sku_count × 50_000_000. sku_count=0 → no row.
    • Catalogued token + action=enable_feature + positive invoice → sku_unlock. Drop launcher enable_feature in the same tx if the token segment is present.
    • Catalogued token + action=update_settings + positive invoice → settings_fee.
  3. Price via hub UST1 CW20 identity. Widen CHECKs, FeeSource::ALL, rollups, Defillama, frontend hide-idle.
  4. make verify-issue-1210. Catalog #594 tests stay green.

Reject: folding invoices into swap_amm or pair_creation; counting create_token_ready as a second fee.


Acceptance criteria

  • AC1. FeeSource includes community invoice source(s); CHECK, rollups, Defillama, and UI labels updated.
  • AC2. Paid EnableFeature (token invoice=50000000) inserts one sku_unlock row; launcher duplicate is not a second fee.
  • AC3. Paid UpdateSettings inserts one settings_fee row of 50e6, not 50 × field count.
  • AC4. Create with N unique SKUs inserts sku_unlock amount N × 50e6; create with 0 SKUs inserts none.
  • AC5. Free migrate-adopt, tax events, #595 swap/wrap legs, gas, and failed invoices are not ingested as community fees.
  • AC6. Spoof emitter / unreserved contract_address ignored (#285). Unconfigured launcher pin omits the source(s).
  • AC7. GET /api/v1/protocol/fees and /daily expose the new source(s) with idle/unpriced/window semantics. Frontend shows SKU unlock / Settings invoice when event_count > 0.
  • AC8. Pair-creation and S1 client events unchanged. Catalog #594 tests still pass. Uniqueness (tx_hash, source, ordinal).

Test plan (functional paths)

# Path Expect
T1 Token enable_feature + invoice=50000000 (catalogued) One sku_unlock row
T2 Same tx also has launcher enable_feature Still one fee row
T3 update_settings + invoice=50000000 (multi-field) One settings_fee of 50e6
T4 Launcher create_token sku_count=2 sku_unlock 100e6; create_token_ready not a second fee
T5 sku_count=0 / free CreateToken No community fee row
T6 migrate-adopt No community fee row
T7 Wrong amount / revert / FeatureAlreadyEnabled No fee row
T8 #595 wrap+swap then invoice Send Community row = UST1 invoice only; swap/wrap unchanged
T9 API windows; invalid window 400 New source(s) in by_source; additive JSON
T10 Idle configured, zero events "0" / hide-idle
T11 Unconfigured launcher pin Source omitted
T12 Unpriced UST1 hub Event stored; amount_usd null
T13 Catalog /community-tokens still inserts #594 tests green
T14 Existing sources (+ pair_creation if landed) make verify-issue-586 / #614 (and #1209 verify if present)

Test plan (attack, hack, and abuse)

# Vector Expect
A1 Spoof enable_feature invoice=50000000 from random contract Ignored unless catalogued token + reserved _contract_address
A2 Unreserved contract_address Ignored (#285)
A3 Double-count launcher + token EnableFeature Single fee row
A4 Count create_token and create_token_ready Single create-time fee
A5 Count #595 swap commission / wrap fee as SKU invoice Forbidden
A6 Count buy/sell/transfer tax or AutoLP skim Forbidden
A7 Infer 50e6 × enabled feature flags without a paid tx Forbidden
A8 invoice=0 / missing invoice on token EnableFeature No row
A9 Symbol spoof / $1 UST1 / vFDUSD Price via UST1 CW20 identity only
A10 Mix pair_creation uluna into these sources Forbidden
A11 Over-long / non-numeric invoice Parse fail; no panic; no row
A12 Replay / reorg Uniqueness

Verification criteria

  • Indexer fixtures: EnableFeature, settings batch, create N SKUs, create 0 SKUs, launcher+token same tx, spoof contract, migrate-adopt, missing invoice.
  • API tests: by_source keys, idle/unpriced, window allowlist.
  • Frontend type/label tests include the new key(s).
  • Existing protocol-fee, series, Defillama, and community-token catalog tests pass.
  • A LocalTerra paid SKU unlock txhash matches protocol_fee_events (sku_unlock, amount 50e6 UST1) and does not include swap/gas as that source.
  • docs/indexer-invariants.md protocol-fees row updated.
  • make verify-issue-1210 plus make verify-issue-586 / make verify-issue-614 / make verify-issue-594.
## Summary Index community-tax **SKU unlock** and **settings-batch** invoices (canonical **50 UST1** each, forwarded to CMM) on `GET /api/v1/protocol/fees`. On-chain invoices and the community-token **catalog** already exist. The protocol fee API does not. This issue **already bundles** both invoice kinds (`sku_unlock` + `settings_fee`). Do not split them. Do **not** mix factory pair-creation uluna ([#1209](https://git.cl8y.com/code/cl8y-dex-terraclassic/issues/1209)). Design/home: [#1213](https://git.cl8y.com/code/cl8y-dex-terraclassic/issues/1213). Closed marketing tracker: [cl8y-marketing#4](https://git.cl8y.com/PlasticDigits/cl8y-marketing/issues/4). Do not reopen it. Land **after (or stacked on)** the pair-creation `FeeSource` widening pattern. Do not expand #1209’s MR. ### Given / When / Then Given a paid EnableFeature, UpdateSettings batch, or launcher `create_token` with `sku_count` > 0 on pinned/catalogued emitters When the indexer ingests that success tx Then it inserts **one** `protocol_fee_events` row per paid invoice (`sku_unlock` or `settings_fee`) with amount from the canonical attr / `sku_count × 50e6` And launcher+token EnableFeature in the same tx is still **one** fee row And migrate-adopt, tax skim, #595 swap/wrap legs, gas, and reverted invoices are not community fee rows ### Not a duplicate / already implemented | Issue | Why it is not this ticket | | --- | --- | | [#1213](https://git.cl8y.com/code/cl8y-dex-terraclassic/issues/1213) (closed) | Design/home. No ingest. | | [#1209](https://git.cl8y.com/code/cl8y-dex-terraclassic/issues/1209) | Factory `pair_creation` uluna. Prerequisite pattern; different source. | | [#1211](https://git.cl8y.com/code/cl8y-dex-terraclassic/issues/1211) | Cohort split. Unjoined/`unknown` is OK until this stream exists. | | [#594](https://git.cl8y.com/code/cl8y-dex-terraclassic/issues/594) | Catalog `community_token_events` — “which SKU,” not treasury USD. | | [#592](https://git.cl8y.com/code/cl8y-dex-terraclassic/issues/592) / [#595](https://git.cl8y.com/code/cl8y-dex-terraclassic/issues/595) / [#606](https://git.cl8y.com/code/cl8y-dex-terraclassic/issues/606) | On-chain invoices / pay-with-any-token routing. Swap legs stay `swap_amm` / wrap. | | [#597](https://git.cl8y.com/code/cl8y-dex-terraclassic/issues/597) | MM subscription invoices (out of scope). | | [#1202](https://git.cl8y.com/code/cl8y-dex-terraclassic/issues/1202) | Client events. Do not put invoice amounts there. | **Not implemented:** `FeeSource` has no `sku_unlock` / `settings_fee`. Catalog events are not read by `/protocol/fees`. --- ## Current codebase ### On-chain invoices (already correct) `INVOICE_UST1 = 50_000_000` (6 dp) in [`community-tax-token`](smartcontracts/contracts/community-tax-token/src/invoice.rs) / launcher: | Path | Who pays | Amount | Treasury path | Wasm | | --- | --- | --- | --- | --- | | Create with **N unique SKUs** | Manager UST1 `Send` to **pinned launcher** | `50 UST1 × N` | Launcher `Transfer` UST1 → CMM (does **not** also send to the token) | Launcher `action=create_token` + `sku_count`; reply `create_token_ready` has **no** invoice attr | | Create with **0 SKUs** | `ExecuteMsg::CreateToken` (no UST1) | 0 | None | Not a fee | | Later **EnableFeature** | Manager → launcher → token | **50 UST1** | Launcher re-`Send`s UST1 to the token; **token** `Transfer`s to CMM | Token `enable_feature` + `sku` + `invoice` (launcher often has **no** `invoice`) | | **UpdateSettings** batch | Manager UST1 `Send` to **token** | **50 UST1** flat (whole batch) | Token `Transfer` → CMM | Token `update_settings` + `invoice` | | Free **migrate-adopt** | None | 0 | None | Not a fee | | Wrong amount / no-op / already-on | Revert | — | Fee not kept | No success fee row | Pay-with-any-token ([#595](https://git.cl8y.com/code/cl8y-dex-terraclassic/issues/595)) only routes off-chain. Launcher/token still accept **UST1 `Send` only**. Swap/wrap legs on that path may already produce `swap_amm` / wrap protocol fees. Those are **not** community invoices. ### Catalog ingest (exists; not the fee API) [`community_tokens.rs`](indexer/src/indexer/community_tokens.rs) (#594) parses `enable_feature` / `update_settings` / `create_token_ready` into `community_token_events`. Gaps vs treasury census: - `create_token_ready` stores **no** invoice amount (create-time `N × 50 UST1` lives on launcher `create_token`). - `enable_feature` may insert **two** catalog rows in one tx (launcher + token). - `GET /api/v1/protocol/fees` does not read that table. ### Protocol fee API Seven `FeeSource`s. `COMMUNITY_TOKEN_LAUNCHER` may be unset — omit community invoice sources then (do not fake `$0`), same as wrap/window. GET is O(1) rollup / 60s cache. Frontend `ProtocolFeeSourceKey` has no SKU/settings labels. --- ## Why the new implementation is needed North-star ledgers should include **project-team invoices**, not only swap/book/wrap/window. Catalog `/community-tokens` answers “which token unlocked which SKU,” not “how much protocol invoice revenue in this window.” Idle volume (`event_count = 0`) is not a reason to skip ingest. The first paid SKU must appear on the same API, with the same unpriced/idle/`window` semantics. --- ## Constraints / guardrails - **Do not mix `pair_creation`.** Separate `FeeSource` string(s). Do not count factory `creation_fee_uluna` here. - **Do not change S1 client analytics** (#1202). No `campaign_id` on fee rows. - **Count CMM UST1 invoice inflows only.** Not tax skim, AutoLP, migrate-adopt, gas, Classic burn tax, or #595 swap/wrap legs. - **One treasury row per paid invoice.** EnableFeature: prefer token `invoice` attr (canonical 50e6). Ignore the launcher’s same-tx `enable_feature` as a second fee. Create with SKUs: count launcher `create_token` **once** (`sku_count × 50e6`). Do not also infer from `create_token_ready`. - **Fail closed on amount.** Require `amount_raw > 0`. Do not infer `50e6 × catalog SKU flags`. - **Pin emitters (#285).** Launcher wasm only when reserved `_contract_address` equals pinned `COMMUNITY_TOKEN_LAUNCHER`. Token wasm only for **catalogued** community tokens. Spoof `enable_feature` from a random CW20 is ignored. - **Asset identity is the UST1 CW20 contract** (hub catalog), never `symbol=` and never `$1` UST1. - **GET stays O(1) rollup / 60s cache.** Unconfigured launcher/catalog pins **omit** the sources. Configured + no events → idle `"0"`. - **Out of scope:** changing `INVOICE_UST1`; MM subscription (#597); invoice-payer adapter wasm; exact-out `/route/solve`; marketing fee tables. --- ## Relevant files | Path | Why | | --- | --- | | `indexer/src/indexer/protocol_fees.rs` | `FeeSource` / wrap-window pattern | | `indexer/src/indexer/parser.rs` | `ingest_protocol_fee` | | `indexer/src/indexer/community_tokens.rs` | Catalog only; do not treat as fee truth | | `indexer/src/db/queries/protocol_fees.rs` | Insert / rollup | | `indexer/src/config.rs` | `COMMUNITY_TOKEN_LAUNCHER`, hub UST1 | | `indexer/src/api/protocol_fees.rs`, `protocol_fee_series.rs`, `api/defillama.rs` | Public ledger | | `indexer/tests/indexer_protocol_fees.rs`, `api_community_tokens.rs` | Fee + catalog regression | | `frontend-dapp/src/types/index.ts`, `components/protocol/ProtocolFeeStats.tsx` | Keys / labels | | `smartcontracts/contracts/community-tax-token/src/invoice.rs` | `invoice` attr (read-only) | | `smartcontracts/contracts/community-token-launcher/src/contract.rs` | `sku_count` (read-only) | | `skills/AGENTS_INDEXER_UST1_WINDOW_FEES.md`, `AGENTS_INDEXER_FEE_LEDGER_HOME.md`, `AGENTS_INDEXER_COMMUNITY_TOKENS.md` | Pattern / catalog ≠ fees | --- ## Recommended direction 1. After #1209 `FeeSource` widening exists (or in a follow-up change set on that pattern), add **two** sources: - `sku_unlock` — create-time paid SKUs **and** later EnableFeature (retail label **SKU unlock**). - `settings_fee` — UpdateSettings batches (retail label **Settings invoice**). Prefer two keys. One combined `community_invoice` only if Defillama/UI cannot take two. 2. Parser (per-action scan, reserved `_contract_address`, same flattening as wrap #613): - Pinned launcher + `action=create_token` + `sku_count` > 0 → `sku_unlock` amount `sku_count × 50_000_000`. `sku_count=0` → no row. - Catalogued token + `action=enable_feature` + positive `invoice` → `sku_unlock`. Drop launcher `enable_feature` in the same tx if the token segment is present. - Catalogued token + `action=update_settings` + positive `invoice` → `settings_fee`. 3. Price via hub **UST1 CW20** identity. Widen CHECKs, `FeeSource::ALL`, rollups, Defillama, frontend hide-idle. 4. `make verify-issue-1210`. Catalog #594 tests stay green. Reject: folding invoices into `swap_amm` or `pair_creation`; counting `create_token_ready` as a second fee. --- ## Acceptance criteria - [ ] **AC1.** `FeeSource` includes community invoice source(s); CHECK, rollups, Defillama, and UI labels updated. - [ ] **AC2.** Paid EnableFeature (token `invoice=50000000`) inserts **one** `sku_unlock` row; launcher duplicate is not a second fee. - [ ] **AC3.** Paid UpdateSettings inserts **one** `settings_fee` row of 50e6, not `50 × field count`. - [ ] **AC4.** Create with N unique SKUs inserts `sku_unlock` amount `N × 50e6`; create with 0 SKUs inserts none. - [ ] **AC5.** Free migrate-adopt, tax events, #595 swap/wrap legs, gas, and failed invoices are not ingested as community fees. - [ ] **AC6.** Spoof emitter / unreserved `contract_address` ignored (#285). Unconfigured launcher pin omits the source(s). - [ ] **AC7.** `GET /api/v1/protocol/fees` and `/daily` expose the new source(s) with idle/unpriced/`window` semantics. Frontend shows **SKU unlock** / **Settings invoice** when `event_count > 0`. - [ ] **AC8.** Pair-creation and S1 client events unchanged. Catalog #594 tests still pass. Uniqueness `(tx_hash, source, ordinal)`. --- ## Test plan (functional paths) | # | Path | Expect | | --- | --- | --- | | T1 | Token `enable_feature` + `invoice=50000000` (catalogued) | One `sku_unlock` row | | T2 | Same tx also has launcher `enable_feature` | Still **one** fee row | | T3 | `update_settings` + `invoice=50000000` (multi-field) | One `settings_fee` of 50e6 | | T4 | Launcher `create_token` `sku_count=2` | `sku_unlock` 100e6; `create_token_ready` not a second fee | | T5 | `sku_count=0` / free `CreateToken` | No community fee row | | T6 | `migrate-adopt` | No community fee row | | T7 | Wrong amount / revert / FeatureAlreadyEnabled | No fee row | | T8 | #595 wrap+swap then invoice Send | Community row = UST1 invoice only; swap/wrap unchanged | | T9 | API windows; invalid window 400 | New source(s) in `by_source`; additive JSON | | T10 | Idle configured, zero events | `"0"` / hide-idle | | T11 | Unconfigured launcher pin | Source omitted | | T12 | Unpriced UST1 hub | Event stored; `amount_usd` null | | T13 | Catalog `/community-tokens` still inserts | #594 tests green | | T14 | Existing sources (+ pair_creation if landed) | `make verify-issue-586` / `#614` (and #1209 verify if present) | --- ## Test plan (attack, hack, and abuse) | # | Vector | Expect | | --- | --- | --- | | A1 | Spoof `enable_feature` `invoice=50000000` from random contract | Ignored unless catalogued token + reserved `_contract_address` | | A2 | Unreserved `contract_address` | Ignored (#285) | | A3 | Double-count launcher + token EnableFeature | Single fee row | | A4 | Count `create_token` **and** `create_token_ready` | Single create-time fee | | A5 | Count #595 swap commission / wrap fee as SKU invoice | Forbidden | | A6 | Count buy/sell/transfer tax or AutoLP skim | Forbidden | | A7 | Infer `50e6 × enabled feature flags` without a paid tx | Forbidden | | A8 | `invoice=0` / missing invoice on token EnableFeature | No row | | A9 | Symbol spoof / `$1` UST1 / vFDUSD | Price via UST1 CW20 identity only | | A10 | Mix `pair_creation` uluna into these sources | Forbidden | | A11 | Over-long / non-numeric `invoice` | Parse fail; no panic; no row | | A12 | Replay / reorg | Uniqueness | --- ## Verification criteria - Indexer fixtures: EnableFeature, settings batch, create N SKUs, create 0 SKUs, launcher+token same tx, spoof contract, migrate-adopt, missing invoice. - API tests: `by_source` keys, idle/unpriced, window allowlist. - Frontend type/label tests include the new key(s). - Existing protocol-fee, series, Defillama, and community-token catalog tests pass. - A LocalTerra paid SKU unlock txhash matches `protocol_fee_events` (`sku_unlock`, amount 50e6 UST1) and does **not** include swap/gas as that source. - `docs/indexer-invariants.md` protocol-fees row updated. - `make verify-issue-1210` plus `make verify-issue-586` / `make verify-issue-614` / `make verify-issue-594`.

Related ingest siblings: #1209 #1210 #1211. Pair-creation implement home is #1209 (not marketing #1). Design/home epic: #1213.

Related ingest siblings: #1209 #1210 #1211. Pair-creation implement home is #1209 (not marketing #1). Design/home epic: #1213.
PlasticDigits changed title from feat: index community SKU and settings invoices on /api/v1/protocol/fees to feat(indexer): index community SKU and settings invoices on /api/v1/protocol/fees 2026-09-13 05:37:45 +00:00

Repair: DEX-native DoR. SKU unlock + settings invoices stay bundled here. Not implemented (catalog ≠ /protocol/fees). Stack after #1209; do not mix pair_creation.

Repair: DEX-native DoR. SKU unlock + settings invoices stay bundled here. Not implemented (catalog ≠ /protocol/fees). Stack after #1209; do not mix pair_creation.

Occupying-runner check: implement labels already present; no extra labels added.

Occupying-runner check: implement labels already present; no extra labels added.

/agent implement

/agent implement

/agent implement

/agent implement

/agent implement

/agent implement

Verification (2026-09-24): #1210 stays open. origin/main at 54c4868e still has only seven FeeSources; catalog events do not feed /protocol/fees. No newer issue replaces this ingest: #1213 is the home/docs epic; #1237/#1239 fix on-chain no-op charging; #1269 updates fee uniqueness.

Remaining:

  1. Add sku_unlock / settings_fee from positive CMM UST1 invoices (launcher create sku_count × 50e6; token EnableFeature invoice; one flat UpdateSettings invoice), with dedupe, fail-closed parsing, and verified emitter/origin (#594, #1229).
  2. Wire DB/API /fees + /daily, DeFiLlama, UI, and tests; preserve O(1)/60s, omitted-unconfigured, idle "0", and unpriced null. Exclude non-invoices; keep pair_creation #1209 and cohort #1211 separate.
  3. Inherit #1269 pair-aware uniqueness; add make verify-issue-1210 and paid LocalTerra row evidence.

Spec: docs/qa/issue-1210/README.md; invariants L1210-1–L1210-8 in skills/AGENTS_INDEXER_FEE_LEDGER_HOME.md. Related: #1209 #1211 #1213 #1269 #594 #595 #597 #1229 #1237 #1239.

Verification (2026-09-24): #1210 stays open. `origin/main` at `54c4868e` still has only seven `FeeSource`s; catalog events do not feed `/protocol/fees`. No newer issue replaces this ingest: #1213 is the home/docs epic; #1237/#1239 fix on-chain no-op charging; #1269 updates fee uniqueness. Remaining: 1. Add `sku_unlock` / `settings_fee` from positive CMM UST1 invoices (launcher create `sku_count × 50e6`; token EnableFeature invoice; one flat UpdateSettings invoice), with dedupe, fail-closed parsing, and verified emitter/origin (#594, #1229). 2. Wire DB/API `/fees` + `/daily`, DeFiLlama, UI, and tests; preserve O(1)/60s, omitted-unconfigured, idle `"0"`, and unpriced `null`. Exclude non-invoices; keep pair_creation #1209 and cohort #1211 separate. 3. Inherit #1269 pair-aware uniqueness; add `make verify-issue-1210` and paid LocalTerra row evidence. Spec: `docs/qa/issue-1210/README.md`; invariants L1210-1–L1210-8 in `skills/AGENTS_INDEXER_FEE_LEDGER_HOME.md`. Related: #1209 #1211 #1213 #1269 #594 #595 #597 #1229 #1237 #1239.
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
code/cl8y-dex-terraclassic#1210
No description provided.