Skip to content

Commit cf0b2c3

Browse files
committed
feat(truapi): add testing API and versioned wiring
Adds the canonical testing module (api/testing.rs) and its v01/v02/versioned wiring used by the Rust host runtime and generated clients.
1 parent b6291db commit cf0b2c3

12 files changed

Lines changed: 263 additions & 10 deletions

File tree

js/packages/truapi/src/client.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ describe("generated client transport", () => {
8686
expectedFrame.set(expectedPayload, str.enc("p:1").length + 1);
8787

8888
expect(toHex(fixture.sent[0])).toBe(toHex(expectedFrame));
89-
expect(transport.truapiVersion).toBe(1);
89+
expect(transport.truapiVersion).toBe(2);
9090
expect(transport.codecVersion).toBe(1);
9191
});
9292

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ pub mod resource_allocation;
1414
pub mod signing;
1515
pub mod statement_store;
1616
pub mod system;
17+
#[cfg(debug_assertions)]
18+
pub mod testing;
1719
pub mod theme;
1820

1921
pub use account::Account;
@@ -30,9 +32,12 @@ pub use resource_allocation::ResourceAllocation;
3032
pub use signing::Signing;
3133
pub use statement_store::StatementStore;
3234
pub use system::System;
35+
#[cfg(debug_assertions)]
36+
pub use testing::Testing;
3337
pub use theme::Theme;
3438

3539
/// The unified TrUAPI contract.
40+
#[cfg(debug_assertions)]
3641
pub trait TrUApi:
3742
Account
3843
+ Chain
@@ -48,12 +53,59 @@ pub trait TrUApi:
4853
+ Signing
4954
+ StatementStore
5055
+ System
56+
+ Testing
5157
+ Theme
5258
+ Send
5359
+ Sync
5460
{
5561
}
5662

63+
#[cfg(not(debug_assertions))]
64+
pub trait TrUApi:
65+
Account
66+
+ Chain
67+
+ Chat
68+
+ CoinPayment
69+
+ Entropy
70+
+ LocalStorage
71+
+ Notifications
72+
+ Payment
73+
+ Permissions
74+
+ Preimage
75+
+ ResourceAllocation
76+
+ Signing
77+
+ StatementStore
78+
+ System
79+
+ Theme
80+
+ Send
81+
+ Sync
82+
{
83+
}
84+
85+
#[cfg(debug_assertions)]
86+
impl<T> TrUApi for T where
87+
T: Account
88+
+ Chain
89+
+ Chat
90+
+ CoinPayment
91+
+ Entropy
92+
+ LocalStorage
93+
+ Notifications
94+
+ Payment
95+
+ Permissions
96+
+ Preimage
97+
+ ResourceAllocation
98+
+ Signing
99+
+ StatementStore
100+
+ System
101+
+ Testing
102+
+ Theme
103+
+ Send
104+
+ Sync
105+
{
106+
}
107+
108+
#[cfg(not(debug_assertions))]
57109
impl<T> TrUApi for T where
58110
T: Account
59111
+ Chain

rust/crates/truapi/src/api/statement_store.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ use crate::versioned::statement_store::{
66
RemoteStatementStoreCreateProofAuthorizedResponse, RemoteStatementStoreCreateProofError,
77
RemoteStatementStoreCreateProofRequest, RemoteStatementStoreCreateProofResponse,
88
RemoteStatementStoreSubmitError, RemoteStatementStoreSubmitRequest,
9-
RemoteStatementStoreSubscribeItem, RemoteStatementStoreSubscribeRequest,
9+
RemoteStatementStoreSubscribeError, RemoteStatementStoreSubscribeItem,
10+
RemoteStatementStoreSubscribeRequest,
1011
};
1112
use crate::wire;
1213
use crate::{CallContext, CallError, Subscription};
@@ -56,8 +57,11 @@ pub trait StatementStore: Send + Sync {
5657
&self,
5758
_cx: &CallContext,
5859
_request: RemoteStatementStoreSubscribeRequest,
59-
) -> Subscription<RemoteStatementStoreSubscribeItem> {
60-
Subscription::empty()
60+
) -> Result<
61+
Subscription<RemoteStatementStoreSubscribeItem>,
62+
CallError<RemoteStatementStoreSubscribeError>,
63+
> {
64+
Err(CallError::unavailable())
6165
}
6266

6367
/// Create a proof for a statement.
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
//! Debug-only API used to verify wire-version and framework-error handling.
2+
3+
use crate::v01;
4+
use crate::v02;
5+
use crate::versioned::testing::{
6+
TestingVersionProbeError, TestingVersionProbeRequest, TestingVersionProbeResponse,
7+
};
8+
use crate::wire;
9+
use crate::{CallContext, CallError};
10+
11+
/// Development-only probes for generated client/runtime compatibility.
12+
pub trait Testing: Send + Sync {
13+
/// Echo the request version back to the caller.
14+
///
15+
/// ```ts
16+
/// const result = await truapi.testing.versionProbe({
17+
/// message: "hello from V2",
18+
/// marker: 42,
19+
/// });
20+
/// assert(result.isOk(), "testing version probe failed:", result);
21+
/// console.log("testing version probe:", result.value);
22+
/// ```
23+
#[wire(request_id = 164)]
24+
async fn version_probe(
25+
&self,
26+
_cx: &CallContext,
27+
request: TestingVersionProbeRequest,
28+
) -> Result<TestingVersionProbeResponse, CallError<TestingVersionProbeError>> {
29+
match request {
30+
TestingVersionProbeRequest::V1(inner) => Ok(TestingVersionProbeResponse::V1(
31+
v01::TestingVersionProbeResponse {
32+
received_version: 1,
33+
message: inner.message,
34+
},
35+
)),
36+
TestingVersionProbeRequest::V2(inner) => Ok(TestingVersionProbeResponse::V2(
37+
v02::TestingVersionProbeResponse {
38+
received_version: 2,
39+
message: inner.message,
40+
marker: inner.marker,
41+
},
42+
)),
43+
}
44+
}
45+
46+
/// Echo a framework/domain error on the public response channel.
47+
///
48+
/// ```ts
49+
/// const result = await truapi.testing.echoError({
50+
/// error: { tag: "HostFailure", value: { reason: "forced by test" } },
51+
/// });
52+
/// assert(result.isErr(), "expected host failure");
53+
/// console.log("echo error:", result.error);
54+
/// ```
55+
#[wire(request_id = 166)]
56+
async fn echo_error(
57+
&self,
58+
_cx: &CallContext,
59+
request: v01::EchoErrorRequest,
60+
) -> Result<(), CallError<v01::TestingVersionProbeError>> {
61+
Err(request.error.into())
62+
}
63+
}

rust/crates/truapi/src/lib.rs

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,62 @@
11
//! TrUAPI trait and type definitions for the host product SDK.
22
//!
3-
//! Concrete wire types live in per-version modules (currently [`v01`]).
4-
//! Versioned envelopes are in [`versioned`].
3+
//! Concrete wire types live in per-version modules. Versioned envelopes are in
4+
//! [`versioned`].
55
66
#![forbid(unsafe_code)]
77
#![allow(async_fn_in_trait)]
88

9-
use std::convert::Infallible;
10-
use std::pin::Pin;
9+
use core::convert::Infallible;
10+
use core::pin::Pin;
11+
use core::task::{Context, Poll};
1112
use std::sync::Arc;
1213
use std::sync::atomic::{AtomicBool, Ordering};
13-
use std::task::{Context, Poll};
1414

1515
use futures::Stream;
16+
use parity_scale_codec::{Decode, Encode};
1617

1718
pub mod api;
1819
pub mod v01;
20+
#[cfg(debug_assertions)]
21+
pub mod v02;
1922
pub mod versioned;
2023

24+
pub mod latest {
25+
pub use crate::v01::{
26+
AllocatableResource, GenericError, HostSignPayloadData, NotificationId, ProductAccountId,
27+
RawPayload, RemotePermission, ThemeVariant,
28+
};
29+
30+
pub type HostAccountGetAliasResponse = crate::v01::HostAccountGetAliasResponse;
31+
pub type HostDevicePermissionRequest = crate::v01::HostDevicePermissionRequest;
32+
pub type HostDevicePermissionResponse = crate::v01::HostDevicePermissionResponse;
33+
pub type HostFeatureSupportedRequest = crate::v01::HostFeatureSupportedRequest;
34+
pub type HostFeatureSupportedResponse = crate::v01::HostFeatureSupportedResponse;
35+
pub type HostLocalStorageReadError = crate::v01::HostLocalStorageReadError;
36+
pub type HostNavigateToError = crate::v01::HostNavigateToError;
37+
pub type HostPushNotificationRequest = crate::v01::HostPushNotificationRequest;
38+
pub type HostPushNotificationResponse = crate::v01::HostPushNotificationResponse;
39+
pub type HostRequestResourceAllocationRequest =
40+
crate::v01::HostRequestResourceAllocationRequest;
41+
pub type HostSignPayloadRequest = crate::v01::HostSignPayloadRequest;
42+
pub type HostSignPayloadWithLegacyAccountRequest =
43+
crate::v01::HostSignPayloadWithLegacyAccountRequest;
44+
pub type HostSignRawRequest = crate::v01::HostSignRawRequest;
45+
pub type HostSignRawWithLegacyAccountRequest = crate::v01::HostSignRawWithLegacyAccountRequest;
46+
pub type LegacyAccountTxPayload = crate::v01::LegacyAccountTxPayload;
47+
pub type PreimageSubmitError = crate::v01::PreimageSubmitError;
48+
pub type ProductAccountTxPayload = crate::v01::ProductAccountTxPayload;
49+
pub type RemotePermissionRequest = crate::v01::RemotePermissionRequest;
50+
pub type RemotePermissionResponse = crate::v01::RemotePermissionResponse;
51+
}
52+
2153
pub use truapi_macros::wire;
2254

2355
/// Per-message id carried from the transport frame.
2456
pub type RequestId = String;
2557

2658
/// Framework-level outcomes shared by API methods.
27-
#[derive(Debug, Clone, PartialEq, Eq)]
59+
#[derive(Debug, Clone, PartialEq, Eq, Encode, Decode)]
2860
pub enum CallError<D> {
2961
/// Method-specific failure.
3062
Domain(D),
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ mod resource_allocation;
1515
mod signing;
1616
mod statement_store;
1717
mod system;
18+
#[cfg(debug_assertions)]
19+
mod testing;
1820
mod theme;
1921
mod transaction;
2022

@@ -33,5 +35,7 @@ pub use resource_allocation::*;
3335
pub use signing::*;
3436
pub use statement_store::*;
3537
pub use system::*;
38+
#[cfg(debug_assertions)]
39+
pub use testing::*;
3640
pub use theme::*;
3741
pub use transaction::*;
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
use parity_scale_codec::{Decode, Encode};
2+
3+
use crate::CallError;
4+
5+
/// V1 request payload for the debug-only Testing API.
6+
#[derive(Debug, Clone, PartialEq, Eq, Encode, Decode)]
7+
pub struct TestingVersionProbeRequest {
8+
pub message: String,
9+
}
10+
11+
/// Request payload for echoing a framework/domain error through the wire shape.
12+
#[derive(Debug, Clone, PartialEq, Eq, Encode, Decode)]
13+
pub struct EchoErrorRequest {
14+
pub error: EchoError,
15+
}
16+
17+
/// Debug-only mirror of [`CallError`] used as a request payload.
18+
#[derive(Debug, Clone, PartialEq, Eq, Encode, Decode)]
19+
pub enum EchoError {
20+
Domain(TestingVersionProbeError),
21+
Denied,
22+
Unsupported,
23+
MalformedFrame { reason: String },
24+
HostFailure { reason: String },
25+
}
26+
27+
impl From<EchoError> for CallError<TestingVersionProbeError> {
28+
fn from(error: EchoError) -> Self {
29+
match error {
30+
EchoError::Domain(error) => Self::Domain(error),
31+
EchoError::Denied => Self::Denied,
32+
EchoError::Unsupported => Self::Unsupported,
33+
EchoError::MalformedFrame { reason } => Self::MalformedFrame { reason },
34+
EchoError::HostFailure { reason } => Self::HostFailure { reason },
35+
}
36+
}
37+
}
38+
39+
/// V1 response payload for the debug-only Testing API.
40+
#[derive(Debug, Clone, PartialEq, Eq, Encode, Decode)]
41+
pub struct TestingVersionProbeResponse {
42+
pub received_version: u8,
43+
pub message: String,
44+
}
45+
46+
/// Domain error for the debug-only Testing API.
47+
#[derive(Debug, Clone, PartialEq, Eq, Encode, Decode)]
48+
pub enum TestingVersionProbeError {
49+
Unknown { reason: String },
50+
}

rust/crates/truapi/src/v02.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
//! TrUAPI Protocol v0.2 type definitions.
2+
3+
mod testing;
4+
5+
pub use testing::*;
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
use parity_scale_codec::{Decode, Encode};
2+
3+
/// Request payload for the debug-only Testing API.
4+
#[derive(Debug, Clone, PartialEq, Eq, Encode, Decode)]
5+
pub struct TestingVersionProbeRequest {
6+
pub message: String,
7+
pub marker: u32,
8+
}
9+
10+
/// Response payload for the debug-only Testing API.
11+
#[derive(Debug, Clone, PartialEq, Eq, Encode, Decode)]
12+
pub struct TestingVersionProbeResponse {
13+
pub received_version: u8,
14+
pub message: String,
15+
pub marker: u32,
16+
}
17+
18+
/// Domain error for the debug-only Testing API.
19+
#[derive(Debug, Clone, PartialEq, Eq, Encode, Decode)]
20+
pub enum TestingVersionProbeError {
21+
Unknown { reason: String },
22+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ pub mod resource_allocation;
4444
pub mod signing;
4545
pub mod statement_store;
4646
pub mod system;
47+
#[cfg(debug_assertions)]
48+
pub mod testing;
4749
pub mod theme;
4850

4951
#[cfg(test)]

0 commit comments

Comments
 (0)