The per-vault 30s dedup window on /notify is intentional anti-spam (confirmed in vultisig/vultisig-android#4454) — keep it, but three sharp edges hit legitimate flows (api/server.go):
- The key is per-vault, so any two independent back-to-back keysigns within 30s lose the second push (approve+swap is already chained, but general back-to-back txs should still work). Keying on a payload hash keeps replay-suppression while letting a different keysign through.
- The key is set before the enqueue — if the enqueue fails, the client's retry inside 30s is guaranteed-dropped. Set it only after successful enqueue.
- Suppression returns a plain 200, indistinguishable from success — clients can't surface anything. Return e.g. 429 so the sender can show "wait Xs" instead of a false "sent".
The per-vault 30s dedup window on
/notifyis intentional anti-spam (confirmed in vultisig/vultisig-android#4454) — keep it, but three sharp edges hit legitimate flows (api/server.go):