Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
06410eb
feat(truapi): derive funding accounts under fund.<suffix>
filvecchiato Oct 3, 2026
6101881
feat(truapi): watch funding deposits on Asset Hub
filvecchiato Oct 3, 2026
a64114d
feat(truapi): convert funding deposits into CASH on People
filvecchiato Oct 5, 2026
3ae59f7
fix(truapi): export the funding conversion types
filvecchiato Oct 5, 2026
7660760
feat(truapi-host-cli): add funding-check
filvecchiato Oct 5, 2026
94f5fd6
feat(truapi): credit converted funding deposits to the balance
filvecchiato Oct 5, 2026
ecbcafe
feat(truapi): derive funding accounts as getcash does
filvecchiato Oct 5, 2026
cb5a955
fix(truapi): bound funding reads and load signing metadata only to sign
filvecchiato Oct 5, 2026
95a0e3d
feat(truapi): quote funding deposits and read the PSM fee default
filvecchiato Oct 5, 2026
02041b7
feat(truapi): convert native and unserved stablecoin deposits through…
filvecchiato Oct 5, 2026
362ec83
fix(truapi): retry pool swaps only for fees and floor them at the target
filvecchiato Oct 5, 2026
0248bb5
feat(truapi-host-cli): stand-in top-up for funding-check
filvecchiato Oct 5, 2026
5372f59
chore: lock schnorrkel for truapi-host-cli
filvecchiato Oct 5, 2026
177b0d3
feat(truapi): native bridge for funding and top-ups
filvecchiato Oct 5, 2026
9ccaa88
Merge branch 'funding/03-topup' into funding/04-deposit-account
filvecchiato Oct 6, 2026
645fabf
fix(truapi): refuse the funding product's subtree secret
filvecchiato Oct 6, 2026
d6f7625
Merge branch 'funding/04-deposit-account' into funding/05-deposit-watch
filvecchiato Oct 6, 2026
20da23d
Merge branch 'funding/05-deposit-watch' into funding/06-convert
filvecchiato Oct 6, 2026
cd6de45
Merge branch 'funding/06-convert' into funding/07-cli-check
filvecchiato Oct 6, 2026
426f5b2
Merge branch 'funding/07-cli-check' into funding/08-credit
filvecchiato Oct 6, 2026
d8c6a67
Merge branch 'funding/08-credit' into funding/09-getcash-derivation
filvecchiato Oct 6, 2026
211f2e7
fix(truapi): normalize the paired entropy guard and say whose account…
filvecchiato Oct 6, 2026
1354207
Merge branch 'funding/09-getcash-derivation' into funding/10-sizing
filvecchiato Oct 6, 2026
1f732c6
Merge branch 'funding/10-sizing' into funding/11-pool
filvecchiato Oct 6, 2026
41e0313
Merge branch 'funding/11-pool' into funding/12-cli-topup
filvecchiato Oct 6, 2026
7881670
Merge branch 'funding/12-cli-topup' into funding/13-native-bridge
filvecchiato Oct 6, 2026
11e9594
feat(truapi): recover short, wrong-asset and late funding deposits
filvecchiato Oct 6, 2026
79f6720
fix(funding): gate deposits on the quote, convert late full deposits
filvecchiato Oct 6, 2026
47046d3
feat(truapi): settle partial funding claims and PSM refusals as getca…
filvecchiato Oct 6, 2026
20e6576
refactor(truapi): move the funding pipeline out of core
filvecchiato Oct 6, 2026
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
5 changes: 5 additions & 0 deletions .changeset/funding-native-bridge.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@parity/truapi": patch
---

Native hosts drive funding through `NativeTrUApiHostRuntime`: `set_funding_callbacks` installs the overlay, `set_top_up_callbacks` and `notify_top_up_status` the top-up engine, and `open_funding` and `funding_session` open and read sessions. Amounts cross the FFI as decimal strings.
4 changes: 4 additions & 0 deletions rust/crates/truapi/RUNTIME.md
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,10 @@ AutoSigning without approval. Legacy-account signing still asks the user.
Balance card opens sessions with `open_funding`. The core owns the sessions,
persists them, expires them, and answers Funding calls `Unsupported` while no
overlay is installed.
Native hosts reach this through `NativeTrUApiHostRuntime`:
`set_funding_callbacks` (the overlay), `set_top_up_callbacks` with
`notify_top_up_status` (the top-up engine), `open_funding` and
`funding_session`. Amounts cross the FFI as decimal strings.
- `TopUpPlatform`: claim a top-up source's funds into the user's balance and
stream each top-up's status. Installed with `set_top_up_platform`. The core
requires a session and checks the source keys; the host owns claiming,
Expand Down
9 changes: 9 additions & 0 deletions rust/crates/truapi/src/host_core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -748,6 +748,15 @@ impl SigningHostRuntime {
installed
}

/// One funding session as the core holds it, for the host's own status
/// and history views.
pub fn funding_session(
&self,
intent: &str,
) -> Option<crate::host_logic::funding::FundingSession> {
self.services.funding().get(intent)
}

/// Open a funding session on the host's own behalf, as the Balance card's
/// Add and Withdraw do, and show the overlay. Returns the session id, or
/// `None` when the user dismissed the overlay without starting.
Expand Down
8 changes: 8 additions & 0 deletions rust/crates/truapi/src/host_logic/funding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ const SETTLED_HISTORY_LIMIT: usize = 50;

/// What the core knows about one session, independent of any host surface.
#[derive(Debug, Clone, PartialEq, Eq, Encode, Decode)]
#[cfg_attr(
all(feature = "runtime", not(target_arch = "wasm32")),
derive(uniffi::Record)
)]
pub struct FundingSession {
/// Identifier handed back to the caller and used to re-attach.
pub intent: String,
Expand All @@ -41,6 +45,10 @@ pub struct FundingSession {

/// Stage of a session, as the core persists it.
#[derive(Debug, Clone, PartialEq, Eq, Encode, Decode)]
#[cfg_attr(
all(feature = "runtime", not(target_arch = "wasm32")),
derive(uniffi::Enum)
)]
pub enum FundingStage {
/// In flight.
Open,
Expand Down
20 changes: 20 additions & 0 deletions rust/crates/truapi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,26 @@ uniffi::custom_type!(Bytes32, Vec<u8>, {
try_lift: |bytes| Ok(bytes.as_slice().try_into()?),
});

/// A 64-byte value, such as an sr25519 secret key, passed as plain bytes on
/// FFI surfaces.
pub type Bytes64 = [u8; 64];

#[cfg(all(feature = "runtime", not(target_arch = "wasm32")))]
uniffi::custom_type!(Bytes64, Vec<u8>, {
remote,
lower: |bytes| bytes.to_vec(),
try_lift: |bytes| Ok(bytes.as_slice().try_into()?),
});

// Swift and Kotlin have no 128-bit integer, so amounts cross FFI surfaces as
// decimal strings.
#[cfg(all(feature = "runtime", not(target_arch = "wasm32")))]
uniffi::custom_type!(u128, String, {
remote,
lower: |amount| amount.to_string(),
try_lift: |amount| Ok(amount.parse()?),
});

/// Latest-version protocol payload types, unwrapped from their versioned
/// envelopes. Runtime code should use these instead of per-version modules.
pub mod latest {
Expand Down
4 changes: 2 additions & 2 deletions rust/crates/truapi/src/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ mod ws_bridge;
pub use crate::host_internal::sso_messages::SsoRequestOutcome;
pub use crate::host_logic::dotns::{NavigateDecision, PocketDeeplinkAction};
pub use callbacks::{
HostCallbacks, NativeChatCallbacks, NativeContactsCallbacks, NativePocketCallbacks,
NativePocketRemoval,
HostCallbacks, NativeChatCallbacks, NativeContactsCallbacks, NativeFundingCallbacks,
NativePocketCallbacks, NativePocketRemoval, NativeTopUpCallbacks,
};
pub use config::{HostRuntimeConfig, NativeRuntimeConfigError, ProductExecutionConfig};
pub use errors::{HostRejection, NativeCoreDatabaseError};
Expand Down
51 changes: 51 additions & 0 deletions rust/crates/truapi/src/native/callbacks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,3 +306,54 @@ pub trait NativeContactsCallbacks: Send + Sync {
product_id: String,
) -> Result<crate::platform::HostContactPick, HostRejection>;
}

/// Native funding overlay. A host with a funding modality passes an
/// implementation to [`NativeTrUApiHostRuntime::set_funding_callbacks`];
/// without one, funding requests answer `Unsupported`.
///
/// [`NativeTrUApiHostRuntime::set_funding_callbacks`]: super::NativeTrUApiHostRuntime::set_funding_callbacks
#[uniffi::export(rust, foreign)]
#[async_trait::async_trait]
pub trait NativeFundingCallbacks: Send + Sync {
/// Show the funding overlay for session `intent`, which `product_id`
/// opened, or the host itself when `None`, on the screen `direction`
/// names, and report whether the user started or dismissed it. `amount`
/// is a decimal string of CASH units.
async fn present_funding(
&self,
product_id: Option<String>,
intent: String,
direction: v01::FundingDirection,
amount: Option<u128>,
) -> Result<crate::platform::FundingPresentOutcome, HostRejection>;

/// A session's status changed, for host UI such as the in-flight pill.
fn funding_session_changed(&self, intent: String, status: v01::HostFundingStatusSubscribeItem);
}

/// Native top-up engine, which claims a source's funds into the user's
/// balance. A host passes an implementation to
/// [`NativeTrUApiHostRuntime::set_top_up_callbacks`] and reports each later
/// status with [`NativeTrUApiHostRuntime::notify_top_up_status`].
///
/// [`NativeTrUApiHostRuntime::set_top_up_callbacks`]: super::NativeTrUApiHostRuntime::set_top_up_callbacks
/// [`NativeTrUApiHostRuntime::notify_top_up_status`]: super::NativeTrUApiHostRuntime::notify_top_up_status
#[uniffi::export(rust, foreign)]
#[async_trait::async_trait]
pub trait NativeTopUpCallbacks: Send + Sync {
/// Start top-up `request` for `product_id`, returning once the host has
/// accepted it. Its amount is a decimal string of CASH units.
async fn top_up(
&self,
product_id: String,
request: v01::HostPaymentTopUpRequest,
) -> Result<(), v01::HostPaymentTopUpError>;

/// The current status of `product_id`'s top-up `id`, or `None` when the
/// host holds no such top-up.
fn top_up_status(
&self,
product_id: String,
id: crate::Bytes32,
) -> Result<Option<v01::HostPaymentTopUpStatusSubscribeItem>, HostRejection>;
}
10 changes: 10 additions & 0 deletions rust/crates/truapi/src/native/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,16 @@ impl From<uniffi::UnexpectedUniFFICallbackError> for v01::HostLocalStorageReadEr
}
}

impl From<uniffi::UnexpectedUniFFICallbackError> for v01::HostPaymentTopUpError {
fn from(err: uniffi::UnexpectedUniFFICallbackError) -> Self {
tracing::warn!(
reason = %err.reason,
"host callback threw an undeclared error; reporting it as a rejection"
);
v01::HostPaymentTopUpError::Unknown { reason: err.reason }
}
}

impl From<uniffi::UnexpectedUniFFICallbackError> for v01::HostNavigateToError {
fn from(err: uniffi::UnexpectedUniFFICallbackError) -> Self {
tracing::warn!(
Expand Down
Loading
Loading