Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions bindings/ios/bitkitcore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28476,6 +28476,19 @@ public func pubkySignUp(secretKeyHex: String, homeserverPublicKeyZ32: String, si
errorHandler: FfiConverterTypePubkyError_lift
)
}
/**
* Persist a successful outgoing RBF result, including its replacement fee rate, in one transaction.
* Call after the node has returned the replacement txid; this function does not broadcast anything.
*/
public func recordRbfBoost(walletId: String, originalActivityId: String, replacementTxId: String, feeRate: UInt64)throws {try rustCallWithError(FfiConverterTypeActivityError_lift) {
uniffi_bitkitcore_fn_func_record_rbf_boost(
FfiConverterString.lower(walletId),
FfiConverterString.lower(originalActivityId),
FfiConverterString.lower(replacementTxId),
FfiConverterUInt64.lower(feeRate),$0
)
}
}
/**
* Refresh all active CJIT entries in the database with latest data from the LSP
*/
Expand Down Expand Up @@ -29184,6 +29197,16 @@ public func upsertOnchainActivities(activities: [OnchainActivity])throws {try
)
}
}
/**
* Merge a sync/event snapshot without overwriting a known fee rate for the same wallet and txid.
* Generic upsert_activity/update_activity still accept explicit fee-rate corrections.
*/
public func upsertOnchainActivityPreservingFeeRate(activity: OnchainActivity)throws {try rustCallWithError(FfiConverterTypeActivityError_lift) {
uniffi_bitkitcore_fn_func_upsert_onchain_activity_preserving_fee_rate(
FfiConverterTypeOnchainActivity_lower(activity),$0
)
}
}
public func upsertOrders(orders: [IBtOrder])async throws {
return
try await uniffiRustCallAsync(
Expand Down Expand Up @@ -29741,6 +29764,9 @@ private let initializationResult: InitializationResult = {
if (uniffi_bitkitcore_checksum_func_pubky_sign_up() != 61692) {
return InitializationResult.apiChecksumMismatch
}
if (uniffi_bitkitcore_checksum_func_record_rbf_boost() != 15433) {
return InitializationResult.apiChecksumMismatch
}
if (uniffi_bitkitcore_checksum_func_refresh_active_cjit_entries() != 5324) {
return InitializationResult.apiChecksumMismatch
}
Expand Down Expand Up @@ -29894,6 +29920,9 @@ private let initializationResult: InitializationResult = {
if (uniffi_bitkitcore_checksum_func_upsert_onchain_activities() != 15461) {
return InitializationResult.apiChecksumMismatch
}
if (uniffi_bitkitcore_checksum_func_upsert_onchain_activity_preserving_fee_rate() != 13661) {
return InitializationResult.apiChecksumMismatch
}
if (uniffi_bitkitcore_checksum_func_upsert_orders() != 45856) {
return InitializationResult.apiChecksumMismatch
}
Expand Down
22 changes: 22 additions & 0 deletions bindings/ios/bitkitcoreFFI.h
Original file line number Diff line number Diff line change
Expand Up @@ -1462,6 +1462,11 @@ uint64_t uniffi_bitkitcore_fn_func_pubky_sign_in(RustBuffer secret_key_hex
uint64_t uniffi_bitkitcore_fn_func_pubky_sign_up(RustBuffer secret_key_hex, RustBuffer homeserver_public_key_z32, RustBuffer signup_code
);
#endif
#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_RECORD_RBF_BOOST
#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_RECORD_RBF_BOOST
void uniffi_bitkitcore_fn_func_record_rbf_boost(RustBuffer wallet_id, RustBuffer original_activity_id, RustBuffer replacement_tx_id, uint64_t fee_rate, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_REFRESH_ACTIVE_CJIT_ENTRIES
#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_REFRESH_ACTIVE_CJIT_ENTRIES
uint64_t uniffi_bitkitcore_fn_func_refresh_active_cjit_entries(void
Expand Down Expand Up @@ -1729,6 +1734,11 @@ void uniffi_bitkitcore_fn_func_upsert_lightning_activities(RustBuffer activities
void uniffi_bitkitcore_fn_func_upsert_onchain_activities(RustBuffer activities, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_UPSERT_ONCHAIN_ACTIVITY_PRESERVING_FEE_RATE
#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_UPSERT_ONCHAIN_ACTIVITY_PRESERVING_FEE_RATE
void uniffi_bitkitcore_fn_func_upsert_onchain_activity_preserving_fee_rate(RustBuffer activity, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_UPSERT_ORDERS
#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_FN_FUNC_UPSERT_ORDERS
uint64_t uniffi_bitkitcore_fn_func_upsert_orders(RustBuffer orders
Expand Down Expand Up @@ -2938,6 +2948,12 @@ uint16_t uniffi_bitkitcore_checksum_func_pubky_sign_in(void
#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_PUBKY_SIGN_UP
uint16_t uniffi_bitkitcore_checksum_func_pubky_sign_up(void

);
#endif
#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_RECORD_RBF_BOOST
#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_RECORD_RBF_BOOST
uint16_t uniffi_bitkitcore_checksum_func_record_rbf_boost(void

);
#endif
#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_REFRESH_ACTIVE_CJIT_ENTRIES
Expand Down Expand Up @@ -3244,6 +3260,12 @@ uint16_t uniffi_bitkitcore_checksum_func_upsert_lightning_activities(void
#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_UPSERT_ONCHAIN_ACTIVITIES
uint16_t uniffi_bitkitcore_checksum_func_upsert_onchain_activities(void

);
#endif
#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_UPSERT_ONCHAIN_ACTIVITY_PRESERVING_FEE_RATE
#define UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_UPSERT_ONCHAIN_ACTIVITY_PRESERVING_FEE_RATE
uint16_t uniffi_bitkitcore_checksum_func_upsert_onchain_activity_preserving_fee_rate(void

);
#endif
#ifndef UNIFFI_FFIDEF_UNIFFI_BITKITCORE_CHECKSUM_FUNC_UPSERT_ORDERS
Expand Down
40 changes: 40 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,46 @@ pub fn upsert_activity(activity: Activity) -> Result<(), ActivityError> {
db.upsert_activity(&activity)
}

/// Persist a successful outgoing RBF result, including its replacement fee rate, in one transaction.
/// Call after the node has returned the replacement txid; this function does not broadcast anything.
#[uniffi::export]
pub fn record_rbf_boost(
wallet_id: String,
original_activity_id: String,
replacement_tx_id: String,
fee_rate: u64,
) -> Result<(), ActivityError> {
let mut guard = get_activity_db()?;
let db = guard
.activity_db
.as_mut()
.ok_or(ActivityError::ConnectionError {
error_details: "Database not initialized. Call init_db first.".to_string(),
})?;
db.record_rbf_boost(
&wallet_id,
&original_activity_id,
&replacement_tx_id,
fee_rate,
)
}

/// Merge a sync/event snapshot without overwriting a known fee rate for the same wallet and txid.
/// Generic upsert_activity/update_activity still accept explicit fee-rate corrections.
#[uniffi::export]
pub fn upsert_onchain_activity_preserving_fee_rate(
activity: OnchainActivity,
) -> Result<(), ActivityError> {
let mut guard = get_activity_db()?;
let db = guard
.activity_db
.as_mut()
.ok_or(ActivityError::ConnectionError {
error_details: "Database not initialized. Call init_db first.".to_string(),
})?;
db.upsert_onchain_activity_preserving_fee_rate(&activity)
}

#[uniffi::export]
pub fn insert_activity(activity: Activity) -> Result<(), ActivityError> {
let mut guard = get_activity_db()?;
Expand Down
28 changes: 28 additions & 0 deletions src/modules/activity/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,17 @@ fn update_activity(activity_id: String, activity: Activity) -> Result<(), Activi
// Insert or update an activity
fn upsert_activity(activity: Activity) -> Result<(), ActivityError>

// Record a successful RBF result atomically (does not broadcast a transaction)
fn record_rbf_boost(
wallet_id: String,
original_activity_id: String,
replacement_tx_id: String,
fee_rate: u64
) -> Result<(), ActivityError>

// Merge a sync/event snapshot without replacing a known rate for the same wallet and txid
fn upsert_onchain_activity_preserving_fee_rate(activity: OnchainActivity) -> Result<(), ActivityError>

// Get a specific activity by wallet ID and activity ID
fn get_activity_by_id(wallet_id: String, activity_id: String) -> Result<Option<Activity>, ActivityError>

Expand Down Expand Up @@ -102,6 +113,23 @@ fn wipe_all_transaction_details() -> Result<(), ActivityError>
fn activity_wipe_all() -> Result<(), ActivityError>
```

### RBF fee rates and linkage

`record_rbf_boost` stores the selected fee rate only for the replacement txid. It
marks a still-pending original as boosted but leaves that transaction's own fee
and fee rate unchanged, so its history remains accurate if the original confirms.

For outgoing RBF transactions, `boost_tx_ids` on the replacement lists the original
transactions it replaces. This is not a bidirectional link: consumers populate it
from replacement events, and `record_rbf_boost` does not append the replacement
txid to the original's list.

`upsert_onchain_activity_preserving_fee_rate` preserves the stored rate for the
same wallet and txid while merging the snapshot's other fields. The caller must
supply the absolute `fee` for that txid, not the fee of a different transaction in
the RBF chain. A stale or fallback snapshot rate does not overwrite the recorded
rate; explicit corrections still use the generic update/upsert APIs.

## Usage Examples

### iOS (Swift)
Expand Down
Loading
Loading