@@ -109,6 +109,48 @@ typedef struct FFISpvStats {
109109 uint64_t uptime;
110110} FFISpvStats;
111111
112+ /* *
113+ * A single compact block filter with its height.
114+ *
115+ * # Memory Management
116+ *
117+ * The `data` field is heap-allocated and must be freed using
118+ * `dash_spv_ffi_compact_filter_destroy` when no longer needed.
119+ */
120+ typedef struct FFICompactFilter {
121+ /* *
122+ * Block height for this filter
123+ */
124+ uint32_t height;
125+ /* *
126+ * Filter data bytes
127+ */
128+ uint8_t *data;
129+ /* *
130+ * Length of filter data
131+ */
132+ uintptr_t data_len;
133+ } FFICompactFilter;
134+
135+ /* *
136+ * Array of compact block filters.
137+ *
138+ * # Memory Management
139+ *
140+ * Both the array itself and each filter's data must be freed using
141+ * `dash_spv_ffi_compact_filters_destroy` when no longer needed.
142+ */
143+ typedef struct FFICompactFilters {
144+ /* *
145+ * Pointer to array of filters
146+ */
147+ struct FFICompactFilter *filters;
148+ /* *
149+ * Number of filters in the array
150+ */
151+ uintptr_t count;
152+ } FFICompactFilters;
153+
112154typedef void (*BlockCallback)(uint32_t height, const uint8_t (*hash)[32], void *user_data);
113155
114156typedef void (*TransactionCallback)(const uint8_t (*txid)[32],
@@ -171,6 +213,43 @@ typedef struct FFIWalletManager {
171213 uint8_t _private[0 ];
172214} FFIWalletManager;
173215
216+ /* *
217+ * A single filter match entry with height and wallet IDs.
218+ */
219+ typedef struct FFIFilterMatchEntry {
220+ /* *
221+ * Block height where filter matched
222+ */
223+ uint32_t height;
224+ /* *
225+ * Array of wallet IDs (32 bytes each) that matched at this height
226+ */
227+ uint8_t (*wallet_ids)[32 ];
228+ /* *
229+ * Number of wallet IDs
230+ */
231+ uintptr_t wallet_ids_count;
232+ } FFIFilterMatchEntry;
233+
234+ /* *
235+ * Array of filter match entries.
236+ *
237+ * # Memory Management
238+ *
239+ * Both the array itself and each entry's wallet_ids must be freed using
240+ * `dash_spv_ffi_filter_matches_destroy` when no longer needed.
241+ */
242+ typedef struct FFIFilterMatches {
243+ /* *
244+ * Pointer to array of match entries
245+ */
246+ struct FFIFilterMatchEntry *entries;
247+ /* *
248+ * Number of entries in the array
249+ */
250+ uintptr_t count;
251+ } FFIFilterMatches;
252+
174253/* *
175254 * Handle for Core SDK that can be passed to Platform SDK
176255 */
@@ -473,6 +552,36 @@ int32_t dash_spv_ffi_client_sync_to_tip_with_progress(struct FFIDashSpvClient *c
473552 */
474553 bool dash_spv_ffi_client_is_filter_sync_available (struct FFIDashSpvClient *client) ;
475554
555+ /* *
556+ * Load compact block filters in a given height range.
557+ *
558+ * Returns an `FFICompactFilters` struct containing all filters that exist in the range.
559+ * Missing filters are skipped. The caller must free the result using
560+ * `dash_spv_ffi_compact_filters_destroy`.
561+ *
562+ * # Parameters
563+ * - `client`: Valid pointer to an FFIDashSpvClient
564+ * - `start_height`: Starting block height (inclusive)
565+ * - `end_height`: Ending block height (exclusive)
566+ *
567+ * # Limits
568+ * - Maximum range size: 10,000 blocks
569+ * - If `end_height - start_height > 10000`, an error is returned
570+ *
571+ * # Returns
572+ * - Non-null pointer to FFICompactFilters on success
573+ * - Null pointer on error (check `dash_spv_ffi_get_last_error`)
574+ *
575+ * # Safety
576+ * - `client` must be a valid, non-null pointer
577+ * - Caller must call `dash_spv_ffi_compact_filters_destroy` on the returned pointer
578+ */
579+
580+ struct FFICompactFilters *dash_spv_ffi_client_load_filters (struct FFIDashSpvClient *client,
581+ uint32_t start_height,
582+ uint32_t end_height)
583+ ;
584+
476585/* *
477586 * Set event callbacks for the client.
478587 *
@@ -571,6 +680,36 @@ int32_t dash_spv_ffi_client_enable_mempool_tracking(struct FFIDashSpvClient *cli
571680 */
572681 void dash_spv_ffi_wallet_manager_free (struct FFIWalletManager *manager) ;
573682
683+ /* *
684+ * Get filter matched heights with wallet IDs in a given range.
685+ *
686+ * Returns an `FFIFilterMatches` struct containing all heights where filters matched
687+ * and the wallet IDs that matched at each height. The caller must free the result using
688+ * `dash_spv_ffi_filter_matches_destroy`.
689+ *
690+ * # Parameters
691+ * - `client`: Valid pointer to an FFIDashSpvClient
692+ * - `start_height`: Starting block height (inclusive)
693+ * - `end_height`: Ending block height (exclusive)
694+ *
695+ * # Limits
696+ * - Maximum range size: 10,000 blocks
697+ * - If `end_height - start_height > 10000`, an error is returned
698+ *
699+ * # Returns
700+ * - Non-null pointer to FFIFilterMatches on success
701+ * - Null pointer on error (check `dash_spv_ffi_get_last_error`)
702+ *
703+ * # Safety
704+ * - `client` must be a valid, non-null pointer
705+ * - Caller must call `dash_spv_ffi_filter_matches_destroy` on the returned pointer
706+ */
707+
708+ struct FFIFilterMatches *dash_spv_ffi_client_get_filter_matched_heights (struct FFIDashSpvClient *client,
709+ uint32_t start_height,
710+ uint32_t end_height)
711+ ;
712+
574713 struct FFIClientConfig *dash_spv_ffi_config_new (FFINetwork network) ;
575714
576715 struct FFIClientConfig *dash_spv_ffi_config_mainnet (void ) ;
@@ -976,6 +1115,50 @@ void dash_spv_ffi_unconfirmed_transaction_destroy_addresses(struct FFIString *ad
9761115 */
9771116 void dash_spv_ffi_unconfirmed_transaction_destroy (struct FFIUnconfirmedTransaction *tx) ;
9781117
1118+ /* *
1119+ * Destroys a single compact filter.
1120+ *
1121+ * # Safety
1122+ *
1123+ * - `filter` must be a valid pointer to an FFICompactFilter
1124+ * - The pointer must not be used after this function is called
1125+ * - This function should only be called once per allocation
1126+ */
1127+ void dash_spv_ffi_compact_filter_destroy (struct FFICompactFilter *filter) ;
1128+
1129+ /* *
1130+ * Destroys an array of compact filters.
1131+ *
1132+ * # Safety
1133+ *
1134+ * - `filters` must be a valid pointer to an FFICompactFilters struct
1135+ * - The pointer must not be used after this function is called
1136+ * - This function should only be called once per allocation
1137+ */
1138+ void dash_spv_ffi_compact_filters_destroy (struct FFICompactFilters *filters) ;
1139+
1140+ /* *
1141+ * Destroys a single filter match entry.
1142+ *
1143+ * # Safety
1144+ *
1145+ * - `entry` must be a valid pointer to an FFIFilterMatchEntry
1146+ * - The pointer must not be used after this function is called
1147+ * - This function should only be called once per allocation
1148+ */
1149+ void dash_spv_ffi_filter_match_entry_destroy (struct FFIFilterMatchEntry *entry) ;
1150+
1151+ /* *
1152+ * Destroys an array of filter match entries.
1153+ *
1154+ * # Safety
1155+ *
1156+ * - `matches` must be a valid pointer to an FFIFilterMatches struct
1157+ * - The pointer must not be used after this function is called
1158+ * - This function should only be called once per allocation
1159+ */
1160+ void dash_spv_ffi_filter_matches_destroy (struct FFIFilterMatches *matches) ;
1161+
9791162/* *
9801163 * Initialize logging for the SPV library.
9811164 *
0 commit comments