Skip to content

Read & cache new anti-abuse-bond tags from the kind-38385 info event #594

Description

@grunch

Context

The mostrod daemon publishes a kind-38385 info event with the node's runtime policy: mostro_version, max_order_amount, expiration_seconds, fee, pow, LND status, etc. The mobile client already reads this event and caches the values internally.

mostro@ad1f74a ships seven new tags on the same event that advertise the anti-abuse bond policy of the connected node. These tags are critical for the Anti-Abuse Bond Support workstream — without them the app can't:

  • show the user, before they enter a trade, whether a bond is required, how much it will cost, and under what conditions it can be slashed;

  • render the payout forfeit deadline when the daemon asks the winning counterparty for a payout invoice. The `Action::AddBondInvoice` message deliberately carries no human-readable text (Mostro stays locale-agnostic). The client computes the deadline as `slashed_at + bond_payout_claim_window_days * 86400`, where:

    • `slashed_at` (Unix seconds, UTC) is shipped on the `Action::AddBondInvoice` message body in the new `Payload::BondPayoutRequest { order: SmallOrder, slashed_at: i64 }` variant (mostro-core 0.11.3). It is the fixed anchor: re-shipped verbatim on every cadence retry, so a recipient who was offline for days still computes the correct deadline once the message lands.
    • `bond_payout_claim_window_days` is the kind-38385 info-event tag this issue is about.

    This split is deliberate — relying on message receipt time for `slashed_at` would silently drift the deadline into the future for offline recipients. Handling the `BondPayoutRequest` payload itself is part of the umbrella Anti-Abuse Bond Support #591; this issue only needs to surface `bond_payout_claim_window_days` from the info event so the deadline computation has both inputs available.

Purpose of this issue

Just the reader/cache layer. The UI consumption, confirmation dialogs, and trade-flow integration are tracked in #591. This issue is scoped to: read these tags from the kind-38385 event and store them internally exactly like the other info-event tags already are (same model, same cache, same refresh cadence — whatever pattern is already in place for `mostro_version` / `fee` / etc.).

New tags

Tag Type Values When emitted
`bond_enabled` bool `"true"` | `"false"` Always — even when the feature is off (see "Disambiguation" below)
`bond_apply_to` enum `"take"` | `"make"` | `"both"` Only when `bond_enabled = true`
`bond_slash_on_waiting_timeout` bool `"true"` | `"false"` Only when `bond_enabled = true`
`bond_amount_pct` float e.g. `"0.01"` (1% of order amount) Only when `bond_enabled = true`
`bond_base_amount_sats` integer sats floor, e.g. `"1000"` Only when `bond_enabled = true`
`bond_slash_node_share_pct` float in `[0.0, 1.0]` e.g. `"0.5"` Only when `bond_enabled = true`
`bond_payout_claim_window_days` integer days, e.g. `"15"` Only when `bond_enabled = true`

Bond amount math: `max(bond_amount_pct * order_amount_sats, bond_base_amount_sats)`.

Slash split math: the winning counterparty receives `(1 - bond_slash_node_share_pct) * amount_sats`; the node retains the rest.

Disambiguation: three states, not two

Older mostrod versions don't emit `bond_enabled` at all. So the client must distinguish:

  1. Tag absent → daemon doesn't speak bond; treat as legacy / no bond.
  2. `bond_enabled = "false"` → modern daemon, but the operator hasn't enabled the feature; no bond will be requested.
  3. `bond_enabled = "true"` → bond is active; the other six tags will also be present.

This is the reason `bond_enabled` is the only one always emitted — please preserve that semantic when modelling the parsed state.

References

Metadata

Metadata

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions