Skip to content

Commit 1bcad6d

Browse files
authored
146 (#150)
* #146 feat: add raw initData accessor * #146 docs: add raw initData retrieval example to README * #146 refactor: split webapp.rs into logical modules Split monolithic webapp.rs (3591 lines) into 10 focused modules following Single Responsibility Principle: - types.rs (265 lines): All shared types, enums, and structs - core.rs (153 lines): Instance management and validation - lifecycle.rs (235 lines): App lifecycle and window control - buttons.rs (701 lines): All button operations (main, secondary, bottom, back) - dialogs.rs (102 lines): User dialogs and popups - navigation.rs (232 lines): Links, sharing, and navigation - permissions.rs (196 lines): Permission requests and file operations - theme.rs (53 lines): Theme and color management - viewport.rs (92 lines): Viewport and safe area operations - events.rs (276 lines): Event handling system Main webapp.rs reduced to 1401 lines (re-exports + tests). Benefits: - Each module has single clear responsibility - Easier maintenance and navigation - Better encapsulation with pub(super) visibility - No module exceeds 701 lines - All tests pass (207 tests) - Zero clippy warnings
1 parent 3b5eaa6 commit 1bcad6d

File tree

16 files changed

+2523
-2192
lines changed

16 files changed

+2523
-2192
lines changed

README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,30 @@ gyroscope, and device orientation sensors.
654654

655655
## Init data validation
656656

657+
### Retrieving raw initData
658+
659+
Retrieve the raw URL-encoded `initData` string for server-side authentication.
660+
The SDK captures this string during initialization and provides convenient
661+
access without requiring JavaScript reflection:
662+
663+
```rust,no_run
664+
use telegram_webapp_sdk::TelegramWebApp;
665+
666+
# fn run() -> Result<(), Box<dyn std::error::Error>> {
667+
// Get raw initData for backend validation
668+
let raw_init_data = TelegramWebApp::get_raw_init_data()?;
669+
670+
// Send to your backend for signature verification
671+
// POST /auth with body: { "init_data": raw_init_data }
672+
# Ok(())
673+
# }
674+
```
675+
676+
This eliminates the need for manual `Reflect` calls and ensures consistency
677+
with the parsed data available in the context.
678+
679+
### Validating initData
680+
657681
Validate the integrity of the `Telegram.WebApp.initData` payload on the server.
658682
The `validate_init_data` module is re-exported at the crate root and can be
659683
used directly or through the `TelegramWebApp::validate_init_data` helper:

src/core/context.rs

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ use super::types::{
1212
/// Global context of the Telegram Mini App, initialized once per app session.
1313
#[derive(Clone)]
1414
pub struct TelegramContext {
15-
pub init_data: TelegramInitData,
16-
pub theme_params: TelegramThemeParams
15+
pub init_data: TelegramInitData,
16+
pub theme_params: TelegramThemeParams,
17+
pub raw_init_data: String
1718
}
1819

1920
thread_local! {
@@ -28,12 +29,14 @@ impl TelegramContext {
2829
/// Returns an error if the context was already initialized.
2930
pub fn init(
3031
init_data: TelegramInitData,
31-
theme_params: TelegramThemeParams
32+
theme_params: TelegramThemeParams,
33+
raw_init_data: String
3234
) -> Result<(), &'static str> {
3335
CONTEXT.with(|cell| {
3436
cell.set(TelegramContext {
3537
init_data,
36-
theme_params
38+
theme_params,
39+
raw_init_data
3740
})
3841
.map_err(|_| "TelegramContext already initialized")
3942
})
@@ -48,6 +51,34 @@ impl TelegramContext {
4851
{
4952
CONTEXT.with(|cell| cell.get().map(f))
5053
}
54+
55+
/// Returns the raw initData string as provided by Telegram.
56+
///
57+
/// This is the URL-encoded initData string suitable for server-side
58+
/// signature validation. The string is captured during SDK initialization
59+
/// and remains unchanged.
60+
///
61+
/// # Errors
62+
///
63+
/// Returns an error if the SDK has not been initialized via
64+
/// [`crate::core::init::init_sdk`].
65+
///
66+
/// # Examples
67+
///
68+
/// ```no_run
69+
/// use telegram_webapp_sdk::core::context::TelegramContext;
70+
///
71+
/// match TelegramContext::get_raw_init_data() {
72+
/// Ok(raw) => {
73+
/// // Send to backend for validation
74+
/// println!("Raw initData: {}", raw);
75+
/// }
76+
/// Err(e) => eprintln!("Error: {}", e)
77+
/// }
78+
/// ```
79+
pub fn get_raw_init_data() -> Result<String, &'static str> {
80+
Self::get(|ctx| ctx.raw_init_data.clone()).ok_or("TelegramContext not initialized")
81+
}
5182
}
5283

5384
/// Returns launch parameters parsed from the current window location.

src/core/init.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ pub fn init_sdk() -> Result<(), JsValue> {
8181
// theme_params.clone().apply_to_root();
8282

8383
// === 5. Init global context ===
84-
TelegramContext::init(init_data, theme_params)?;
84+
TelegramContext::init(init_data, theme_params, init_data_str)?;
8585

8686
Ok(())
8787
}

0 commit comments

Comments
 (0)