Replace getAddressReceiveRequests() and setAddressReceiveRequest() with three typed methods on interfaces::Wallet:
- getReceiveRequests() -> vector<WalletReceiveRequest>
- addReceiveRequest() -> optional<int64_t> (assigned ID)
- eraseReceiveRequest() -> bool
The previous interface passed serialized blobs between the wallet and GUI, forcing GUI code to handle serialization/deserialization of RecentRequestEntry objects directly. This created tight coupling to the wallet storage format and caused the GUI to crash on startup if it encountered a malformed entry.
The wallet layer now owns:
- ID assignment (scans existing keys for max ID, assigns max+1)
- Timestamp generation (calls GetTime() internally)
- Serialization via Qt-independent mirror structs (RecipientData, RequestEntryData) that are byte-compatible with the existing DB format
- Graceful error recovery: malformed entries are logged via LogWarning and skipped instead of crashing
The GUI (RecentRequestsTableModel) no longer contains any serialization logic. The SERIALIZE_METHODS macro, nVersion field, and nReceiveRequestsMaxId tracker are removed from RecentRequestEntry and the table model.
A regression test is added that writes a malformed blob directly into the wallet address book and verifies getReceiveRequests() returns successfully without crashing.