From 50f533afb55b605c969b0c2c3e8a6672325de3d2 Mon Sep 17 00:00:00 2001 From: Dmitrii Nikulin Date: Mon, 8 Jun 2026 19:38:32 +0300 Subject: [PATCH 1/9] feat: implement gasless transaction support --- .../presentation/actions/WalletActions.kt | 10 +- .../presentation/actions/WalletActionsImpl.kt | 5 +- .../ui/screen/LegacyWalletScreen.kt | 4 +- .../ui/screen/SendTransactionScreen.kt | 390 +++-- .../presentation/ui/screen/WalletScreen.kt | 4 +- .../presentation/viewmodel/SwapViewModel.kt | 4 +- .../viewmodel/WalletKitViewModel.kt | 11 +- .../viewmodel/WalletOperationsViewModel.kt | 96 +- .../main/java/io/ton/walletkit/ITONWallet.kt | 14 + .../java/io/ton/walletkit/ITONWalletKit.kt | 13 + .../generated/TONConnectionRequestEvent.kt | 2 +- .../api/generated/TONDefiProviderType.kt | 77 + .../api/generated/TONGaslessConfig.kt | 54 + .../generated/TONGaslessProviderMetadata.kt | 56 + .../TONGaslessProviderMetadataOverride.kt | 56 + .../api/generated/TONGaslessQuote.kt | 67 + .../api/generated/TONGaslessQuoteParams.kt | 67 + .../api/generated/TONGaslessSendParams.kt | 58 + .../api/generated/TONGaslessSendResponse.kt | 62 + .../api/generated/TONGaslessSupportedAsset.kt | 49 + .../walletkit/api/generated/TONSwapParams.kt | 4 +- .../api/generated/TONSwapQuoteParams.kt | 4 +- .../generated/TONTonApiGaslessChainConfig.kt | 54 + .../TONTonApiGaslessProviderConfig.kt | 70 + .../walletkit/gasless/ITONGaslessManager.kt | 74 + .../walletkit/gasless/TONGaslessProvider.kt | 29 + .../walletkit/walletkit-android-bridge.mjs | 1459 ++++++++++++----- .../java/io/ton/walletkit/core/TONWallet.kt | 14 +- .../io/ton/walletkit/core/TONWalletKit.kt | 14 + .../ton/walletkit/engine/WalletKitEngine.kt | 32 + .../engine/WebViewWalletKitEngine.kt | 42 + .../engine/operations/GaslessOperations.kt | 110 ++ .../engine/operations/WalletOperations.kt | 16 + .../operations/requests/GaslessRequests.kt | 74 + .../operations/requests/WalletRequests.kt | 7 + .../walletkit/gasless/TONGaslessManager.kt | 62 + .../constants/BridgeMethodConstants.kt | 35 + .../engine/operations/SwapOperationsTest.kt | 2 +- 38 files changed, 2564 insertions(+), 637 deletions(-) create mode 100644 TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONDefiProviderType.kt create mode 100644 TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessConfig.kt create mode 100644 TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessProviderMetadata.kt create mode 100644 TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessProviderMetadataOverride.kt create mode 100644 TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessQuote.kt create mode 100644 TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessQuoteParams.kt create mode 100644 TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessSendParams.kt create mode 100644 TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessSendResponse.kt create mode 100644 TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessSupportedAsset.kt create mode 100644 TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTonApiGaslessChainConfig.kt create mode 100644 TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTonApiGaslessProviderConfig.kt create mode 100644 TONWalletKit-Android/api/src/main/java/io/ton/walletkit/gasless/ITONGaslessManager.kt create mode 100644 TONWalletKit-Android/api/src/main/java/io/ton/walletkit/gasless/TONGaslessProvider.kt create mode 100644 TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/operations/GaslessOperations.kt create mode 100644 TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/operations/requests/GaslessRequests.kt create mode 100644 TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/gasless/TONGaslessManager.kt diff --git a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/actions/WalletActions.kt b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/actions/WalletActions.kt index 509b08e1..1b685c8f 100644 --- a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/actions/WalletActions.kt +++ b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/actions/WalletActions.kt @@ -30,6 +30,7 @@ import io.ton.walletkit.demo.presentation.model.SignDataRequestUi import io.ton.walletkit.demo.presentation.model.SignMessageRequestUi import io.ton.walletkit.demo.presentation.model.TransactionRequestUi import io.ton.walletkit.demo.presentation.model.WalletSummary +import io.ton.walletkit.demo.presentation.viewmodel.SendCurrency /** * Interface defining all wallet-related actions. @@ -69,7 +70,14 @@ interface WalletActions { fun onRejectSignMessage(request: SignMessageRequestUi) fun onConfirmSignerApproval() fun onCancelSignerApproval() - fun onSendTransaction(walletAddress: String, recipient: String, amount: String, comment: String) + fun onSendTransaction( + walletAddress: String, + recipient: String, + amount: String, + comment: String, + currency: SendCurrency, + gasless: Boolean, + ) fun onRefreshTransactions(address: String) fun onTransactionClick(transactionHash: String, walletAddress: String) fun onHandleUrl(url: String) diff --git a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/actions/WalletActionsImpl.kt b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/actions/WalletActionsImpl.kt index b5dd59ed..a681cb7f 100644 --- a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/actions/WalletActionsImpl.kt +++ b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/actions/WalletActionsImpl.kt @@ -30,6 +30,7 @@ import io.ton.walletkit.demo.presentation.model.SignDataRequestUi import io.ton.walletkit.demo.presentation.model.SignMessageRequestUi import io.ton.walletkit.demo.presentation.model.TransactionRequestUi import io.ton.walletkit.demo.presentation.model.WalletSummary +import io.ton.walletkit.demo.presentation.viewmodel.SendCurrency import io.ton.walletkit.demo.presentation.viewmodel.WalletKitViewModel import javax.inject.Inject @@ -111,7 +112,9 @@ class WalletActionsImpl @Inject constructor( recipient: String, amount: String, comment: String, - ) = viewModel.sendLocalTransaction(walletAddress, recipient, amount, comment) + currency: SendCurrency, + gasless: Boolean, + ) = viewModel.sendLocalTransaction(walletAddress, recipient, amount, comment, currency, gasless) override fun onRefreshTransactions(address: String) = viewModel.refreshTransactions(address) diff --git a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/ui/screen/LegacyWalletScreen.kt b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/ui/screen/LegacyWalletScreen.kt index 273f551c..70163ae8 100644 --- a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/ui/screen/LegacyWalletScreen.kt +++ b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/ui/screen/LegacyWalletScreen.kt @@ -215,8 +215,8 @@ fun LegacyWalletScreen( is SheetState.SendTransaction -> SendTransactionScreen( wallet = sheet.wallet, onBack = actions::onDismissSheet, - onSend = { recipient, amount, comment -> - actions.onSendTransaction(sheet.wallet.address, recipient, amount, comment) + onSend = { recipient, amount, comment, currency, gasless -> + actions.onSendTransaction(sheet.wallet.address, recipient, amount, comment, currency, gasless) }, error = state.error, isLoading = state.isSendingTransaction, diff --git a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/ui/screen/SendTransactionScreen.kt b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/ui/screen/SendTransactionScreen.kt index 31d4b9c9..4cd07c13 100644 --- a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/ui/screen/SendTransactionScreen.kt +++ b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/ui/screen/SendTransactionScreen.kt @@ -21,188 +21,261 @@ */ package io.ton.walletkit.demo.presentation.ui.screen +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.text.BasicTextField import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.foundation.verticalScroll -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.filled.ArrowBack -import androidx.compose.material3.Button -import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.OutlinedTextField -import androidx.compose.material3.Scaffold -import androidx.compose.material3.SnackbarHost -import androidx.compose.material3.SnackbarHostState -import androidx.compose.material3.Text -import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.SolidColor +import androidx.compose.ui.semantics.Role import androidx.compose.ui.text.input.KeyboardType -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import io.ton.walletkit.demo.R +import io.ton.walletkit.demo.designsystem.components.button.TonButton +import io.ton.walletkit.demo.designsystem.components.segmentedcontrol.TonSegmentedControl +import io.ton.walletkit.demo.designsystem.components.text.TonText +import io.ton.walletkit.demo.designsystem.components.toggle.TonSwitch +import io.ton.walletkit.demo.designsystem.icons.TonIcon +import io.ton.walletkit.demo.designsystem.icons.TonIconImage +import io.ton.walletkit.demo.designsystem.theme.SmoothCornerShape +import io.ton.walletkit.demo.designsystem.theme.TonTheme import io.ton.walletkit.demo.presentation.model.WalletSummary -import io.ton.walletkit.demo.presentation.ui.preview.PreviewData +import io.ton.walletkit.demo.presentation.ui.sheet.components.TonConnectSheetScaffold +import io.ton.walletkit.demo.presentation.ui.sheet.components.TonConnectSheetSection +import io.ton.walletkit.demo.presentation.util.abbreviated +import io.ton.walletkit.demo.presentation.viewmodel.SendCurrency -@OptIn(ExperimentalMaterial3Api::class) +/** + * Send sheet — design-system styled, matching the TonConnect transaction sheets. Picks the asset + * (TON / USDT), and for USDT offers a gasless toggle that routes the send through the relayer so + * the user pays the network fee in USDT instead of TON. + */ @Composable fun SendTransactionScreen( wallet: WalletSummary, onBack: () -> Unit, - onSend: (recipient: String, amount: String, comment: String) -> Unit, + onSend: (recipient: String, amount: String, comment: String, currency: SendCurrency, gasless: Boolean) -> Unit, error: String?, isLoading: Boolean, ) { + var currency by remember { mutableStateOf(SendCurrency.TON) } var recipient by remember { mutableStateOf("") } var amount by remember { mutableStateOf("") } var comment by remember { mutableStateOf("") } - val snackbarHostState = remember { SnackbarHostState() } - val scrollState = rememberScrollState() + var gasless by remember { mutableStateOf(false) } - LaunchedEffect(error) { - error?.let { - snackbarHostState.showSnackbar(it) - } - } + val recipientValid = recipient.isEmpty() || isValidAddress(recipient) + val amountValid = amount.isEmpty() || isValidAmount(amount) + val tonTooLarge = currency == SendCurrency.TON && amount.isNotEmpty() && isAmountTooLarge(amount, wallet.balance) + val canSend = !isLoading && + isValidAddress(recipient) && + isValidAmount(amount) && + !tonTooLarge - Scaffold( - topBar = { - TopAppBar( - title = { - Text( - text = stringResource(R.string.send_title), - style = MaterialTheme.typography.titleLarge, - fontWeight = FontWeight.SemiBold, - ) + TonConnectSheetScaffold( + footer = { + TonText( + text = if (gasless) { + "The relayer covers the TON gas — you pay the network fee in USDT." + } else { + "A small amount of TON is used as the network fee." }, - navigationIcon = { - IconButton(onClick = onBack) { - Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = stringResource(R.string.send_back_content_description)) - } + style = TonTheme.typography.caption2Medium, + color = TonTheme.colors.textTertiary, + modifier = Modifier.fillMaxWidth(), + ) + TonButton( + text = when { + isLoading -> "Sending…" + amount.isNotEmpty() -> "Send $amount ${currency.label}" + else -> "Send ${currency.label}" }, + onClick = { onSend(recipient.trim(), amount, comment, currency, gasless) }, + enabled = canSend, ) }, - snackbarHost = { SnackbarHost(snackbarHostState) }, - ) { padding -> - Column( - modifier = Modifier - .fillMaxSize() - .padding(padding) - .verticalScroll(scrollState) - .padding(horizontal = SEND_SCREEN_HORIZONTAL_PADDING, vertical = SEND_SCREEN_VERTICAL_PADDING), - verticalArrangement = Arrangement.spacedBy(SEND_SCREEN_SECTION_SPACING), - ) { - // Wallet Info - Column(verticalArrangement = Arrangement.spacedBy(SEND_SCREEN_SECTION_GAP)) { - Text( - stringResource(R.string.send_from_label), - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant, - ) - Text( - wallet.name, - style = MaterialTheme.typography.titleMedium, - fontWeight = FontWeight.SemiBold, - ) - Text( - stringResource(R.string.send_balance_format, wallet.balance ?: DEFAULT_BALANCE_FALLBACK), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant, - ) + ) { + // Header + Box(modifier = Modifier.fillMaxWidth()) { + TonText( + text = "Send", + style = TonTheme.typography.title2, + color = TonTheme.colors.textPrimary, + modifier = Modifier.align(Alignment.Center), + ) + Box( + modifier = Modifier + .align(Alignment.CenterEnd) + .size(28.dp) + .clip(CircleShape) + .background(TonTheme.colors.bgSecondary) + .clickable(role = Role.Button, onClick = onBack), + contentAlignment = Alignment.Center, + ) { + TonIconImage(icon = TonIcon.Close, size = 12.dp, tint = TonTheme.colors.textSecondary) } + } - // Recipient Address - OutlinedTextField( - value = recipient, - onValueChange = { recipient = it }, - label = { Text(stringResource(R.string.send_recipient_label)) }, - placeholder = { Text(stringResource(R.string.send_recipient_placeholder)) }, - modifier = Modifier.fillMaxWidth(), - singleLine = true, - isError = recipient.isNotEmpty() && !isValidAddress(recipient), - supportingText = { - if (recipient.isNotEmpty() && !isValidAddress(recipient)) { - Text(stringResource(R.string.send_recipient_error)) - } - }, - ) + // Asset picker + TonSegmentedControl( + selection = currency, + items = SendCurrency.entries, + title = { it.label }, + onSelect = { + currency = it + if (it == SendCurrency.TON) gasless = false + }, + modifier = Modifier.fillMaxWidth(), + ) - // Amount - OutlinedTextField( - value = amount, - onValueChange = { amount = it }, - label = { Text(stringResource(R.string.send_amount_label)) }, - placeholder = { Text(stringResource(R.string.send_amount_placeholder)) }, - modifier = Modifier.fillMaxWidth(), - singleLine = true, - keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Decimal), - isError = amount.isNotEmpty() && !isValidAmount(amount), - supportingText = { - if (amount.isNotEmpty() && !isValidAmount(amount)) { - Text(stringResource(R.string.send_amount_error)) - } else if (amount.isNotEmpty() && isAmountTooLarge(amount, wallet.balance)) { - Text(stringResource(R.string.send_amount_insufficient)) - } - }, + // From + TonConnectSheetSection(label = "From") { + TonText(wallet.name, style = TonTheme.typography.bodySemibold, color = TonTheme.colors.textPrimary) + TonText(wallet.address.abbreviated(), style = TonTheme.typography.subheadline2, color = TonTheme.colors.textSecondary) + TonText( + "Balance: ${wallet.balance ?: "0"} TON", + style = TonTheme.typography.subheadline2, + color = TonTheme.colors.textSecondary, ) + } + + // Recipient + SendField( + value = recipient, + onValueChange = { recipient = it }, + label = "Recipient", + placeholder = "EQ… / UQ…", + isError = !recipientValid, + supporting = if (!recipientValid) "Invalid TON address" else null, + ) - // Comment (Optional) - OutlinedTextField( + // Amount + SendField( + value = amount, + onValueChange = { amount = it }, + label = "Amount", + placeholder = "0", + keyboardType = KeyboardType.Decimal, + trailing = currency.label, + isError = !amountValid || tonTooLarge, + supporting = when { + !amountValid -> "Invalid amount" + tonTooLarge -> "Insufficient balance" + else -> null + }, + ) + + // Gasless toggle (USDT only) + if (currency == SendCurrency.USDT) { + Row( + modifier = Modifier + .fillMaxWidth() + .clip(SmoothCornerShape(12.dp)) + .background(TonTheme.colors.bgSecondary) + .padding(horizontal = 16.dp, vertical = 14.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + Column(modifier = Modifier.weight(1f)) { + TonText("Gasless", style = TonTheme.typography.bodySemibold, color = TonTheme.colors.textPrimary) + TonText( + "Pay the fee in USDT, no TON required", + style = TonTheme.typography.subheadline2, + color = TonTheme.colors.textSecondary, + ) + } + TonSwitch(checked = gasless, onCheckedChange = { gasless = it }) + } + } else { + // Comment is only carried on regular (non-gasless) transfers. + SendField( value = comment, onValueChange = { comment = it }, - label = { Text(stringResource(R.string.send_comment_label)) }, - placeholder = { Text(stringResource(R.string.send_comment_placeholder)) }, - modifier = Modifier.fillMaxWidth(), - singleLine = false, - maxLines = 3, - supportingText = { - Text(stringResource(R.string.helper_comment_visibility)) - }, + label = "Comment (optional)", + placeholder = "Add a message…", ) + } - Spacer(modifier = Modifier.height(SEND_BUTTON_TOP_SPACING)) - - // Send Button - Button( - onClick = { onSend(recipient, amount, comment) }, - modifier = Modifier.fillMaxWidth(), - enabled = !isLoading && - recipient.isNotEmpty() && - isValidAddress(recipient) && - amount.isNotEmpty() && - isValidAmount(amount) && - !isAmountTooLarge(amount, wallet.balance), + // Error + error?.let { + Box( + modifier = Modifier + .fillMaxWidth() + .clip(SmoothCornerShape(12.dp)) + .background(TonTheme.colors.bgBrandSubtle) + .padding(16.dp), ) { - Text( - if (isLoading) { - stringResource(R.string.send_button_loading) - } else { - stringResource(R.string.send_button_default) - }, - ) + TonText(it, style = TonTheme.typography.subheadline2, color = TonTheme.colors.textError) } + } + } +} - // Info - Text( - stringResource(R.string.send_info_message), - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant, +@Composable +private fun SendField( + value: String, + onValueChange: (String) -> Unit, + label: String, + placeholder: String, + modifier: Modifier = Modifier, + keyboardType: KeyboardType = KeyboardType.Text, + trailing: String? = null, + isError: Boolean = false, + supporting: String? = null, +) { + Column(modifier = modifier.fillMaxWidth(), verticalArrangement = Arrangement.spacedBy(6.dp)) { + TonText(label, style = TonTheme.typography.footnoteCaps, color = TonTheme.colors.textSecondary) + Row( + modifier = Modifier + .fillMaxWidth() + .clip(SmoothCornerShape(12.dp)) + .background(TonTheme.colors.bgSecondary) + .border( + width = 1.dp, + color = if (isError) TonTheme.colors.textError else Color.Transparent, + shape = SmoothCornerShape(12.dp), + ) + .padding(horizontal = 16.dp, vertical = 14.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + Box(modifier = Modifier.weight(1f)) { + if (value.isEmpty()) { + TonText(placeholder, style = TonTheme.typography.body, color = TonTheme.colors.textTertiary) + } + BasicTextField( + value = value, + onValueChange = onValueChange, + textStyle = TonTheme.typography.body.style.copy(color = TonTheme.colors.textPrimary), + cursorBrush = SolidColor(TonTheme.colors.bgBrand), + keyboardOptions = KeyboardOptions(keyboardType = keyboardType), + singleLine = true, + modifier = Modifier.fillMaxWidth(), + ) + } + trailing?.let { + TonText(it, style = TonTheme.typography.bodySemibold, color = TonTheme.colors.textSecondary) + } + } + supporting?.let { + TonText( + it, + style = TonTheme.typography.caption2Medium, + color = if (isError) TonTheme.colors.textError else TonTheme.colors.textTertiary, ) } } @@ -211,39 +284,16 @@ fun SendTransactionScreen( private fun isValidAddress(address: String): Boolean = address.length > MIN_ADDRESS_LENGTH && (address.startsWith(ADDRESS_MAIN_PREFIX) || address.startsWith(ADDRESS_TEST_PREFIX)) -private fun isValidAmount(amount: String): Boolean { - return runCatching { - val value = amount.toDoubleOrNull() ?: return false - value > 0 - }.getOrDefault(false) -} +private fun isValidAmount(amount: String): Boolean = runCatching { + (amount.toDoubleOrNull() ?: return false) > 0 +}.getOrDefault(false) -private fun isAmountTooLarge(amount: String, balance: String?): Boolean { - return runCatching { - val amountValue = amount.toDoubleOrNull() ?: return false - val balanceValue = balance?.toDoubleOrNull() ?: return true - amountValue > balanceValue - }.getOrDefault(true) -} +private fun isAmountTooLarge(amount: String, balance: String?): Boolean = runCatching { + val amountValue = amount.toDoubleOrNull() ?: return false + val balanceValue = balance?.toDoubleOrNull() ?: return true + amountValue > balanceValue +}.getOrDefault(true) -private val SEND_SCREEN_HORIZONTAL_PADDING = 20.dp -private val SEND_SCREEN_VERTICAL_PADDING = 16.dp -private val SEND_SCREEN_SECTION_SPACING = 24.dp -private val SEND_SCREEN_SECTION_GAP = 8.dp -private val SEND_BUTTON_TOP_SPACING = 16.dp -private const val DEFAULT_BALANCE_FALLBACK = "0" private const val MIN_ADDRESS_LENGTH = 10 private const val ADDRESS_MAIN_PREFIX = "EQ" private const val ADDRESS_TEST_PREFIX = "UQ" - -@Preview(showBackground = true) -@Composable -private fun SendTransactionScreenPreview() { - SendTransactionScreen( - wallet = PreviewData.wallet.copy(balance = "12.50"), - onBack = {}, - onSend = { _, _, _ -> }, - error = null, - isLoading = false, - ) -} diff --git a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/ui/screen/WalletScreen.kt b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/ui/screen/WalletScreen.kt index 96658342..7aba2ce4 100644 --- a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/ui/screen/WalletScreen.kt +++ b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/ui/screen/WalletScreen.kt @@ -326,8 +326,8 @@ fun WalletScreen( is SheetState.SendTransaction -> SendTransactionScreen( wallet = sheet.wallet, onBack = actions::onDismissSheet, - onSend = { recipient, amount, comment -> - actions.onSendTransaction(sheet.wallet.address, recipient, amount, comment) + onSend = { recipient, amount, comment, currency, gasless -> + actions.onSendTransaction(sheet.wallet.address, recipient, amount, comment, currency, gasless) }, error = state.error, isLoading = state.isSendingTransaction, diff --git a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/SwapViewModel.kt b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/SwapViewModel.kt index 63dc9ee6..f9bef9f5 100644 --- a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/SwapViewModel.kt +++ b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/SwapViewModel.kt @@ -160,8 +160,8 @@ class SwapViewModel( from = current.fromToken, to = current.toToken, network = TONNetwork.MAINNET, - slippageBps = current.slippageBps.toDouble(), - maxOutgoingMessages = 4.0, + slippageBps = current.slippageBps, + maxOutgoingMessages = 4, isReverseSwap = current.isReverseSwap, ), ) diff --git a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/WalletKitViewModel.kt b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/WalletKitViewModel.kt index ce96a9dd..50d450e7 100644 --- a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/WalletKitViewModel.kt +++ b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/WalletKitViewModel.kt @@ -939,8 +939,15 @@ class WalletKitViewModel @Inject constructor( } } - fun sendLocalTransaction(walletAddress: String, recipient: String, amount: String, comment: String = "") { - walletOperationsViewModel.sendLocalTransaction(walletAddress, recipient, amount, comment) + fun sendLocalTransaction( + walletAddress: String, + recipient: String, + amount: String, + comment: String = "", + currency: SendCurrency = SendCurrency.TON, + gasless: Boolean = false, + ) { + walletOperationsViewModel.sendLocalTransaction(walletAddress, recipient, amount, comment, currency, gasless) } fun toggleWalletSwitcher() { diff --git a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/WalletOperationsViewModel.kt b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/WalletOperationsViewModel.kt index 6d13957f..1a63abdf 100644 --- a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/WalletOperationsViewModel.kt +++ b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/WalletOperationsViewModel.kt @@ -26,6 +26,9 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import io.ton.walletkit.ITONWallet import io.ton.walletkit.ITONWalletKit +import io.ton.walletkit.api.generated.TONGaslessQuoteParams +import io.ton.walletkit.api.generated.TONGaslessSendParams +import io.ton.walletkit.api.generated.TONJettonsTransferRequest import io.ton.walletkit.api.generated.TONTransferRequest import io.ton.walletkit.demo.presentation.util.TonFormatter import io.ton.walletkit.model.TONUserFriendlyAddress @@ -33,6 +36,13 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch +import java.math.BigDecimal + +/** Asset the Send sheet can transfer. */ +enum class SendCurrency(val label: String) { + TON("TON"), + USDT("USDT"), +} /** * ViewModel for wallet operations like switching wallets and sending local transactions. @@ -93,6 +103,8 @@ class WalletOperationsViewModel( recipient: String, amount: String, comment: String = "", + currency: SendCurrency = SendCurrency.TON, + gasless: Boolean = false, ) { viewModelScope.launch { _state.value = _state.value.copy(isSendingTransaction = true, error = null) @@ -106,32 +118,31 @@ class WalletOperationsViewModel( return@launch } - // Convert TON to nanoTON - val amountInNano = try { - TonFormatter.tonToNano(amount) - } catch (e: Exception) { - _state.value = _state.value.copy( - isSendingTransaction = false, - error = "Invalid amount: ${e.message}", - ) - return@launch - } - runCatching { - // Step 1: Create transaction request - val request = TONTransferRequest( - recipientAddress = TONUserFriendlyAddress(recipient), - transferAmount = amountInNano, - comment = comment.takeIf { it.isNotBlank() }, - ) - val transactionRequest = wallet.transferTONTransaction(request) - - // Step 2: Send the transaction directly - wallet.send(transactionRequest) + when { + currency == SendCurrency.TON -> { + val request = TONTransferRequest( + recipientAddress = TONUserFriendlyAddress(recipient), + transferAmount = TonFormatter.tonToNano(amount), + comment = comment.takeIf { it.isNotBlank() }, + ) + wallet.send(wallet.transferTONTransaction(request)) + } + gasless -> sendUsdtGasless(wallet, recipient, amount) + else -> { + val request = TONJettonsTransferRequest( + jettonAddress = TONUserFriendlyAddress(USDT_MASTER), + transferAmount = toUsdtRawUnits(amount), + recipientAddress = TONUserFriendlyAddress(recipient), + comment = comment.takeIf { it.isNotBlank() }, + ) + wallet.send(wallet.transferJettonTransaction(request)) + } + } }.onSuccess { _state.value = _state.value.copy( isSendingTransaction = false, - successMessage = "Transaction initiated", + successMessage = if (gasless) "Sent gasless — relayer covered the gas" else "Transaction initiated", ) onTransactionInitiated(walletAddress) Log.d(TAG, "Local transaction initiated from $walletAddress") @@ -145,6 +156,43 @@ class WalletOperationsViewModel( } } + /** Send USDT via a relayer that covers the TON gas and charges a USDT fee: quote → sign → relay. */ + private suspend fun sendUsdtGasless(wallet: ITONWallet, recipient: String, amount: String) { + val gaslessManager = walletKit().gasless() + val provider = walletKit().tonApiGaslessProvider() + if (!gaslessManager.hasProvider(provider)) { + gaslessManager.registerProvider(provider) + gaslessManager.setDefaultProvider(provider) + } + + val transfer = wallet.transferJettonTransaction( + TONJettonsTransferRequest( + jettonAddress = TONUserFriendlyAddress(USDT_MASTER), + transferAmount = toUsdtRawUnits(amount), + recipientAddress = TONUserFriendlyAddress(recipient), + ), + ) + val quote = gaslessManager.getQuote( + TONGaslessQuoteParams( + network = wallet.network, + walletAddress = wallet.address, + walletPublicKey = wallet.publicKey(), + messages = transfer.messages, + feeAsset = TONUserFriendlyAddress(USDT_MASTER), + ), + ) + val internalBoc = wallet.signMessage(messages = quote.messages, validUntil = quote.validUntil) + gaslessManager.sendTransaction( + TONGaslessSendParams( + network = wallet.network, + walletPublicKey = wallet.publicKey(), + internalBoc = internalBoc, + ), + ) + } + + private fun toUsdtRawUnits(amount: String): String = BigDecimal(amount).movePointRight(USDT_DECIMALS).toBigInteger().toString() + /** * Clear error or success message. */ @@ -154,5 +202,9 @@ class WalletOperationsViewModel( companion object { private const val TAG = "WalletOperationsVM" + + /** Mainnet USDT (jUSDT) jetton master — the asset sent and the gasless fee asset. */ + private const val USDT_MASTER = "EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs" + private const val USDT_DECIMALS = 6 } } diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/ITONWallet.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/ITONWallet.kt index a5b16615..839ec24d 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/ITONWallet.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/ITONWallet.kt @@ -24,6 +24,8 @@ package io.ton.walletkit import io.ton.walletkit.api.generated.* import io.ton.walletkit.client.TONAPIClient import io.ton.walletkit.model.TONBalance +import io.ton.walletkit.model.TONBase64 +import io.ton.walletkit.model.TONHex import io.ton.walletkit.model.TONUserFriendlyAddress /** @@ -43,11 +45,23 @@ interface ITONWallet { /** API client backing this wallet — exposes per-wallet network and RPC. */ val client: TONAPIClient + /** Network this wallet is connected to. */ + val network: TONNetwork + /** * Get wallet balance. */ suspend fun balance(): TONBalance + /** Get this wallet's public key (hex). */ + suspend fun publicKey(): TONHex + + /** Sign a set of messages as a sign-message bundle, returning the signed internal BoC (used by gasless relay flows). */ + suspend fun signMessage( + messages: List, + validUntil: Double? = null, + ): TONBase64 + /** * Create a TON transfer transaction. * diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/ITONWalletKit.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/ITONWalletKit.kt index d08da819..b0a80e00 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/ITONWalletKit.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/ITONWalletKit.kt @@ -29,10 +29,13 @@ import io.ton.walletkit.api.generated.TONDeDustSwapProviderConfig import io.ton.walletkit.api.generated.TONNetwork import io.ton.walletkit.api.generated.TONOmnistonSwapProviderConfig import io.ton.walletkit.api.generated.TONSignatureDomain +import io.ton.walletkit.api.generated.TONTonApiGaslessProviderConfig import io.ton.walletkit.api.generated.TONTonApiStreamingProviderConfig import io.ton.walletkit.api.generated.TONTonCenterStreamingProviderConfig import io.ton.walletkit.api.generated.TONTransactionRequest import io.ton.walletkit.config.TONWalletKitConfiguration +import io.ton.walletkit.gasless.ITONGaslessManager +import io.ton.walletkit.gasless.TONGaslessProvider import io.ton.walletkit.internal.TONWalletKitFactory import io.ton.walletkit.listener.TONBridgeEventsHandler import io.ton.walletkit.model.KeyPair @@ -201,6 +204,16 @@ interface ITONWalletKit { */ suspend fun swap(): ITONSwapManager + // ── Gasless ── + + /** + * Create a TonAPI gasless provider. Register the returned handle with [gasless] before quoting. + */ + suspend fun tonApiGaslessProvider(config: TONTonApiGaslessProviderConfig? = null): TONGaslessProvider + + /** Get the gasless manager for registering providers and relaying gasless transactions. */ + suspend fun gasless(): ITONGaslessManager + // ── Staking ── /** diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONConnectionRequestEvent.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONConnectionRequestEvent.kt index 518b37ce..f1bf5a26 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONConnectionRequestEvent.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONConnectionRequestEvent.kt @@ -67,7 +67,7 @@ data class TONConnectionRequestEvent( val preview: TONConnectionRequestEventPreview, @SerialName(value = "from") - var from: kotlin.String? = null, + val from: kotlin.String? = null, @SerialName(value = "walletAddress") val walletAddress: io.ton.walletkit.model.TONUserFriendlyAddress? = null, diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONDefiProviderType.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONDefiProviderType.kt new file mode 100644 index 00000000..5ffeb08c --- /dev/null +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONDefiProviderType.kt @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2025 TonTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport", +) + +package io.ton.walletkit.api.generated + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +/** + * Discriminator for DeFi-style providers (swap quotes, staking, gasless relayers). + * + * Values: swap,staking,gasless + */ +@Serializable +enum class TONDefiProviderType(val value: kotlin.String) { + + @SerialName(value = "swap") + swap("swap"), + + @SerialName(value = "staking") + staking("staking"), + + @SerialName(value = "gasless") + gasless("gasless"), + ; + + /** + * Override [toString()] to avoid using the enum variable name as the value, and instead use + * the actual value defined in the API spec file. + * + * This solves a problem when the variable name and its value are different, and ensures that + * the client sends the correct enum values to the server always. + */ + override fun toString(): kotlin.String = value + + companion object { + /** + * Converts the provided [data] to a [String] on success, null otherwise. + */ + fun encode(data: kotlin.Any?): kotlin.String? = if (data is TONDefiProviderType) "$data" else null + + /** + * Returns a valid [TONDefiProviderType] for [data], null otherwise. + */ + fun decode(data: kotlin.Any?): TONDefiProviderType? = data?.let { + val normalizedData = "$it".lowercase() + values().firstOrNull { value -> + it == value || normalizedData == "$value".lowercase() + } + } + } +} diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessConfig.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessConfig.kt new file mode 100644 index 00000000..2fd03de5 --- /dev/null +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessConfig.kt @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2025 TonTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport", +) + +package io.ton.walletkit.api.generated + +import io.ton.walletkit.model.TONUserFriendlyAddress +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +/** + * Provider-level configuration for a gasless relayer on a given network. Bundles every piece of provider state a consumer needs to drive a gasless transfer end-to-end: - `relayAddress` — where the relayer wants residual TON (e.g. jetton-transfer `responseDestination`) returned to. - `supportedAssets` — what the relayer accepts as fee payment. + * + * @param relayAddress + * @param supportedAssets Assets the relayer accepts as fee payment. + */ +@Serializable +data class TONGaslessConfig( + + @SerialName(value = "relayAddress") + val relayAddress: io.ton.walletkit.model.TONUserFriendlyAddress, + + /* Assets the relayer accepts as fee payment. */ + @SerialName(value = "supportedAssets") + val supportedAssets: kotlin.collections.List, + +) { + + companion object +} diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessProviderMetadata.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessProviderMetadata.kt new file mode 100644 index 00000000..0977f84f --- /dev/null +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessProviderMetadata.kt @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2025 TonTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport", +) + +package io.ton.walletkit.api.generated + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +/** + * Static metadata for a gasless provider. + * + * @param name + * @param logo + * @param url + */ +@Serializable +data class TONGaslessProviderMetadata( + + @SerialName(value = "name") + val name: kotlin.String, + + @SerialName(value = "logo") + val logo: kotlin.String? = null, + + @SerialName(value = "url") + val url: kotlin.String? = null, + +) { + + companion object +} diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessProviderMetadataOverride.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessProviderMetadataOverride.kt new file mode 100644 index 00000000..e429a3ed --- /dev/null +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessProviderMetadataOverride.kt @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2025 TonTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport", +) + +package io.ton.walletkit.api.generated + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +/** + * Used in provider configuration to override fields of the provider's metadata. + * + * @param name + * @param logo + * @param url + */ +@Serializable +data class TONGaslessProviderMetadataOverride( + + @SerialName(value = "name") + val name: kotlin.String? = null, + + @SerialName(value = "logo") + val logo: kotlin.String? = null, + + @SerialName(value = "url") + val url: kotlin.String? = null, + +) { + + companion object +} diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessQuote.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessQuote.kt new file mode 100644 index 00000000..3b8f6a0d --- /dev/null +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessQuote.kt @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2025 TonTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport", +) + +package io.ton.walletkit.api.generated + +import io.ton.walletkit.model.TONUserFriendlyAddress +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +/** + * Quote for a gasless transaction produced by `GaslessProvider.getQuote`. Contains relayer-wrapped messages that should be passed to `wallet.signMessage` in place of the caller's original messages, together with the fee the relayer will deduct and the timestamp after which the bundle expires. + * + * @param network + * @param messages Relayer-wrapped messages ready to be signed + * @param fee + * @param validUntil Unix timestamp after which the bundle becomes invalid for relay + * @param from + */ +@Serializable +data class TONGaslessQuote( + + @SerialName(value = "network") + val network: TONNetwork, + + /* Relayer-wrapped messages ready to be signed */ + @SerialName(value = "messages") + val messages: kotlin.collections.List, + + @SerialName(value = "fee") + val fee: kotlin.String, + + /* Unix timestamp after which the bundle becomes invalid for relay */ + @SerialName(value = "validUntil") + val validUntil: kotlin.Double, + + @SerialName(value = "from") + val from: io.ton.walletkit.model.TONUserFriendlyAddress, + +) { + + companion object +} diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessQuoteParams.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessQuoteParams.kt new file mode 100644 index 00000000..9e11e049 --- /dev/null +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessQuoteParams.kt @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2025 TonTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport", +) + +package io.ton.walletkit.api.generated + +import io.ton.walletkit.model.TONUserFriendlyAddress +import kotlinx.serialization.Contextual +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +/** + * Parameters to quote a gasless transaction. The relayer wraps the caller's messages with fee-collection logic and returns a new set of messages that the wallet should sign via `signMessage`. + * + * @param network + * @param walletAddress + * @param walletPublicKey + * @param messages Messages that the caller wants to include in the transaction + * @param feeAsset + */ +@Serializable +data class TONGaslessQuoteParams( + + @SerialName(value = "network") + val network: TONNetwork, + + @SerialName(value = "walletAddress") + val walletAddress: io.ton.walletkit.model.TONUserFriendlyAddress, + + @Contextual @SerialName(value = "walletPublicKey") + val walletPublicKey: io.ton.walletkit.model.TONHex, + + /* Messages that the caller wants to include in the transaction */ + @SerialName(value = "messages") + val messages: kotlin.collections.List, + + @SerialName(value = "feeAsset") + val feeAsset: io.ton.walletkit.model.TONUserFriendlyAddress? = null, + +) { + + companion object +} diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessSendParams.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessSendParams.kt new file mode 100644 index 00000000..2599e623 --- /dev/null +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessSendParams.kt @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2025 TonTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport", +) + +package io.ton.walletkit.api.generated + +import io.ton.walletkit.model.TONBase64 +import kotlinx.serialization.Contextual +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +/** + * Parameters to submit a signed gasless transaction to the relayer. + * + * @param network + * @param walletPublicKey + * @param internalBoc + */ +@Serializable +data class TONGaslessSendParams( + + @SerialName(value = "network") + val network: TONNetwork, + + @Contextual @SerialName(value = "walletPublicKey") + val walletPublicKey: io.ton.walletkit.model.TONHex, + + @Contextual @SerialName(value = "internalBoc") + val internalBoc: io.ton.walletkit.model.TONBase64, + +) { + + companion object +} diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessSendResponse.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessSendResponse.kt new file mode 100644 index 00000000..b6a40dab --- /dev/null +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessSendResponse.kt @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2025 TonTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport", +) + +package io.ton.walletkit.api.generated + +import io.ton.walletkit.model.TONBase64 +import kotlinx.serialization.Contextual +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +/** + * Response from a gasless send. Extends `SendTransactionResponse` (`boc`, `normalizedBoc`, `normalizedHash` of the broadcasted external-in message) with the signed internal-message BoC produced by `wallet.signMessage` for the relayer to wrap. + * + * @param boc + * @param normalizedBoc + * @param normalizedHash + * @param internalBoc + */ +@Serializable +data class TONGaslessSendResponse( + + @Contextual @SerialName(value = "boc") + val boc: io.ton.walletkit.model.TONBase64, + + @Contextual @SerialName(value = "normalizedBoc") + val normalizedBoc: io.ton.walletkit.model.TONBase64, + + @Contextual @SerialName(value = "normalizedHash") + val normalizedHash: io.ton.walletkit.model.TONHex, + + @Contextual @SerialName(value = "internalBoc") + val internalBoc: io.ton.walletkit.model.TONBase64, + +) { + + companion object +} diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessSupportedAsset.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessSupportedAsset.kt new file mode 100644 index 00000000..be5e93ce --- /dev/null +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessSupportedAsset.kt @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2025 TonTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport", +) + +package io.ton.walletkit.api.generated + +import io.ton.walletkit.model.TONUserFriendlyAddress +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +/** + * An asset the relayer accepts as fee payment. Address shape is currently always a jetton master (TonAPI's only supported mode), but the type is intentionally generic so future relayers can advertise NFT items or other assets without re-shaping the model. + * + * @param address + */ +@Serializable +data class TONGaslessSupportedAsset( + + @SerialName(value = "address") + val address: io.ton.walletkit.model.TONUserFriendlyAddress, + +) { + + companion object +} diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSwapParams.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSwapParams.kt index e23b40b0..2d74c27b 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSwapParams.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSwapParams.kt @@ -51,9 +51,9 @@ data class TONSwapParams( @SerialName("destinationAddress") val destinationAddress: io.ton.walletkit.model.TONUserFriendlyAddress? = null, @SerialName("slippageBps") - val slippageBps: kotlin.Double? = null, + val slippageBps: kotlin.Int? = null, @SerialName("deadline") - val deadline: kotlin.Double? = null, + val deadline: kotlin.Int? = null, @SerialName("providerOptions") val providerOptions: TProviderOptions? = null, ) { diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSwapQuoteParams.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSwapQuoteParams.kt index 7bf1c75b..8a42eb8a 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSwapQuoteParams.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSwapQuoteParams.kt @@ -54,9 +54,9 @@ data class TONSwapQuoteParams( @SerialName("network") val network: TONNetwork, @SerialName("slippageBps") - val slippageBps: kotlin.Double? = null, + val slippageBps: kotlin.Int? = null, @SerialName("maxOutgoingMessages") - val maxOutgoingMessages: kotlin.Double? = null, + val maxOutgoingMessages: kotlin.Int? = null, @SerialName("providerOptions") val providerOptions: TProviderOptions? = null, @SerialName("isReverseSwap") diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTonApiGaslessChainConfig.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTonApiGaslessChainConfig.kt new file mode 100644 index 00000000..e67d0f89 --- /dev/null +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTonApiGaslessChainConfig.kt @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2025 TonTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport", +) + +package io.ton.walletkit.api.generated + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +/** + * Per-chain TonAPI gasless settings. + * + * @param endpoint TonAPI REST endpoint override for this chain (defaults to TonAPI's per-network host). + * @param apiKey Bearer token used for this chain's TonAPI calls. + */ +@Serializable +data class TONTonApiGaslessChainConfig( + + /* TonAPI REST endpoint override for this chain (defaults to TonAPI's per-network host). */ + @SerialName(value = "endpoint") + val endpoint: kotlin.String? = null, + + /* Bearer token used for this chain's TonAPI calls. */ + @SerialName(value = "apiKey") + val apiKey: kotlin.String? = null, + +) { + + companion object +} diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTonApiGaslessProviderConfig.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTonApiGaslessProviderConfig.kt new file mode 100644 index 00000000..9400a3b9 --- /dev/null +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTonApiGaslessProviderConfig.kt @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2025 TonTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport", +) + +package io.ton.walletkit.api.generated + +import kotlinx.serialization.Contextual +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +/** + * Configuration for `TonApiGaslessProvider`. One provider instance handles every configured chain. When `chains` is omitted, `createFromContext` auto-registers every network the kit was configured with. + * + * @param chains Per-chain settings keyed by `Network#chainId`. + * @param providerId Provider id. Defaults to `tonapi`. + * @param sendRetries Number of send retries on transient errors. Defaults to 5. + * @param sendRetryDelayMs Delay between send retries in ms. Defaults to 2000. + * @param configCacheTtlMs TTL for the in-memory `/v2/gasless/config` cache (ms). Defaults to 5 minutes. Set to `0` to disable caching. + */ +@Serializable +data class TONTonApiGaslessProviderConfig( + + /* Per-chain settings keyed by `Network#chainId`. */ + @Contextual @SerialName(value = "chains") + val chains: kotlin.collections.Map? = null, + + /* Provider id. Defaults to `tonapi`. */ + @SerialName(value = "providerId") + val providerId: kotlin.String? = null, + + /* Number of send retries on transient errors. Defaults to 5. */ + @SerialName(value = "sendRetries") + val sendRetries: kotlin.Double? = null, + + /* Delay between send retries in ms. Defaults to 2000. */ + @SerialName(value = "sendRetryDelayMs") + val sendRetryDelayMs: kotlin.Double? = null, + + /* TTL for the in-memory `/v2/gasless/config` cache (ms). Defaults to 5 minutes. Set to `0` to disable caching. */ + @SerialName(value = "configCacheTtlMs") + val configCacheTtlMs: kotlin.Double? = null, + +) { + + companion object +} diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/gasless/ITONGaslessManager.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/gasless/ITONGaslessManager.kt new file mode 100644 index 00000000..38930705 --- /dev/null +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/gasless/ITONGaslessManager.kt @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2025 TonTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package io.ton.walletkit.gasless + +import io.ton.walletkit.api.generated.TONGaslessConfig +import io.ton.walletkit.api.generated.TONGaslessProviderMetadata +import io.ton.walletkit.api.generated.TONGaslessQuote +import io.ton.walletkit.api.generated.TONGaslessQuoteParams +import io.ton.walletkit.api.generated.TONGaslessSendParams +import io.ton.walletkit.api.generated.TONGaslessSendResponse +import io.ton.walletkit.api.generated.TONNetwork + +/** + * Manages gasless relay providers and executes gasless operations. Obtain via + * [io.ton.walletkit.ITONWalletKit.gasless]. + * + * Gasless lets a wallet submit on-chain transactions without paying TON for gas: a relayer + * co-signs and covers the gas, taking a jetton fee in return. The flow is + * [getQuote] (sign the returned messages) → [sendTransaction]. + */ +interface ITONGaslessManager { + /** Register a provider returned from [io.ton.walletkit.ITONWalletKit.tonApiGaslessProvider]. */ + suspend fun registerProvider(provider: TONGaslessProvider) + + /** Set the default provider used when no provider is specified. */ + suspend fun setDefaultProvider(provider: TONGaslessProvider) + + /** All currently-registered providers. */ + suspend fun providers(): List + + /** Returns true if [provider] is currently registered. */ + suspend fun hasProvider(provider: TONGaslessProvider): Boolean + + /** Static metadata (display name, logo, url) for [provider], or the default provider. */ + suspend fun getMetadata(provider: TONGaslessProvider? = null): TONGaslessProviderMetadata + + /** + * Fetch the relayer's config — the relay address and the assets it accepts as fee payment. + * [network] defaults to the provider's first supported network. + */ + suspend fun getConfig(network: TONNetwork? = null, provider: TONGaslessProvider? = null): TONGaslessConfig + + /** + * Quote fees and obtain relayer-wrapped messages for signing. Pass the returned + * [TONGaslessQuote.messages] to the wallet's sign-message flow to obtain a signed internal BoC, + * then submit it via [sendTransaction]. + */ + suspend fun getQuote(params: TONGaslessQuoteParams, provider: TONGaslessProvider? = null): TONGaslessQuote + + /** Submit a signed transaction BoC to the relayer for on-chain execution. */ + suspend fun sendTransaction( + params: TONGaslessSendParams, + provider: TONGaslessProvider? = null, + ): TONGaslessSendResponse +} diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/gasless/TONGaslessProvider.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/gasless/TONGaslessProvider.kt new file mode 100644 index 00000000..21d0d726 --- /dev/null +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/gasless/TONGaslessProvider.kt @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2025 TonTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package io.ton.walletkit.gasless + +/** + * Handle to a gasless provider registered in the JS bridge. Obtain via + * [io.ton.walletkit.ITONWalletKit.tonApiGaslessProvider], then pass to + * [ITONGaslessManager.registerProvider]. + */ +data class TONGaslessProvider(val providerId: String) diff --git a/TONWalletKit-Android/impl/src/main/assets/walletkit/walletkit-android-bridge.mjs b/TONWalletKit-Android/impl/src/main/assets/walletkit/walletkit-android-bridge.mjs index b4959d6f..2cef7d7c 100644 --- a/TONWalletKit-Android/impl/src/main/assets/walletkit/walletkit-android-bridge.mjs +++ b/TONWalletKit-Android/impl/src/main/assets/walletkit/walletkit-android-bridge.mjs @@ -23646,7 +23646,7 @@ var init_WalletKitError = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/errors/index.js -var init_errors$3 = __esmMin((() => { +var init_errors$4 = __esmMin((() => { init_codes(); init_WalletKitError(); })); @@ -23792,7 +23792,7 @@ function HexToBase64(data) { } var init_base64 = __esmMin((() => { init_hex(); - init_errors$3(); + init_errors$4(); })); //#endregion //#region ../walletkit/dist/esm/types/toncenter/parsers/TonTransfer.js @@ -25016,17 +25016,17 @@ function createStorageAdapter(config = {}) { if (typeof localStorage !== "undefined") try { return new LocalStorageAdapter(config); } catch (error) { - log$38.warn("Failed to create LocalStorageAdapter, falling back to memory", { error }); + log$41.warn("Failed to create LocalStorageAdapter, falling back to memory", { error }); } if (config.allowMemory) return new MemoryStorageAdapter(config); else throw new Error("No storage adapter available"); } -var log$38; +var log$41; var init_adapters = __esmMin((() => { init_Logger(); init_local(); init_memory(); - log$38 = globalLogger.createChild("StorageAdapter"); + log$41 = globalLogger.createChild("StorageAdapter"); })); //#endregion //#region ../walletkit/dist/esm/storage/adapters/extension.js @@ -25078,10 +25078,10 @@ var init_extension = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/storage/Storage.js -var log$37, Storage; +var log$40, Storage; var init_Storage = __esmMin((() => { init_Logger(); - log$37 = globalLogger.createChild("Storage"); + log$40 = globalLogger.createChild("Storage"); Storage = class { adapter; constructor(adapter) { @@ -25098,7 +25098,7 @@ var init_Storage = __esmMin((() => { if (value === null) return null; return JSON.parse(value); } catch (error) { - log$37.warn("Failed to parse stored value", { + log$40.warn("Failed to parse stored value", { key, error }); @@ -25115,7 +25115,7 @@ var init_Storage = __esmMin((() => { const serialized = JSON.stringify(value); await this.adapter.set(key, serialized); } catch (error) { - log$37.error("Failed to serialize value for storage", { + log$40.error("Failed to serialize value for storage", { key, error }); @@ -25498,11 +25498,11 @@ var init_WalletManager = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/core/TONConnectStoredSessionManager.js -var log$36, TONConnectStoredSessionManager; +var log$39, TONConnectStoredSessionManager; var init_TONConnectStoredSessionManager = __esmMin((() => { init_esm$2(); init_Logger(); - log$36 = globalLogger.createChild("TONConnectStoredSessionManager"); + log$39 = globalLogger.createChild("TONConnectStoredSessionManager"); TONConnectStoredSessionManager = class { sessions = /* @__PURE__ */ new Map(); storage; @@ -25635,16 +25635,16 @@ var init_TONConnectStoredSessionManager = __esmMin((() => { const wallet = this.walletManager.getWallet(session.walletId); if (wallet) session.walletAddress = wallet.getAddress(); else { - log$36.warn("Session Wallet not found for session", { sessionId: session.sessionId }); + log$39.warn("Session Wallet not found for session", { sessionId: session.sessionId }); continue; } } this.sessions.set(session.sessionId, session); } - log$36.debug("Loaded session metadata", { count: storedSessions.length }); + log$39.debug("Loaded session metadata", { count: storedSessions.length }); } } catch (error) { - log$36.warn("Failed to load sessions from storage", { error }); + log$39.warn("Failed to load sessions from storage", { error }); } } /** @@ -25655,7 +25655,7 @@ var init_TONConnectStoredSessionManager = __esmMin((() => { const sessionsToStore = Array.from(this.sessions.values()); await this.storage.set(this.storageKey, sessionsToStore); } catch (error) { - log$36.warn("Failed to persist sessions to storage", { error }); + log$39.warn("Failed to persist sessions to storage", { error }); } } async migrateSessions() { @@ -27260,7 +27260,7 @@ var init_timeouts = __esmMin((() => { //#endregion //#region ../walletkit/dist/esm/bridge/injection/BridgeInjector.js var init_BridgeInjector = __esmMin((() => { - init_errors$3(); + init_errors$4(); })); //#endregion //#region ../walletkit/dist/esm/bridge/utils/messageTypes.js @@ -27282,15 +27282,15 @@ var init_JSBridgeInjector = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/core/BridgeManager.js -var log$34, BridgeManager; +var log$37, BridgeManager; var init_BridgeManager = __esmMin((() => { init_esm$2(); init_dist$1(); init_Logger(); init_uuid(); - init_errors$3(); + init_errors$4(); init_JSBridgeInjector(); - log$34 = globalLogger.createChild("BridgeManager"); + log$37 = globalLogger.createChild("BridgeManager"); BridgeManager = class { config; bridgeProvider; @@ -27332,7 +27332,7 @@ var init_BridgeManager = __esmMin((() => { this.walletKitConfig = walletKitConfig; this.jsBridgeTransport = config?.jsBridgeTransport; if (this.config.bridgeUrl && !this.config.disableHttpConnection) this.bridgeProvider = new C(this.config.bridgeUrl, this.queueBridgeEvent.bind(this), (error) => { - log$34.error("Bridge listener error", { error: error.toString() }); + log$37.error("Bridge listener error", { error: error.toString() }); this.analytics?.emitBridgeClientConnectError({ error_message: `${error?.toString() || "Unknown error"}${error?.errorCode ? ` (Code: ${error?.errorCode})` : ""}`, trace_id: error?.traceId, @@ -27346,12 +27346,12 @@ var init_BridgeManager = __esmMin((() => { */ async start() { if (this.isActive === true) { - log$34.warn("Bridge already started"); + log$37.warn("Bridge already started"); return; } this.isActive = true; if (this.isConnected === true) { - log$34.warn("Bridge already connected"); + log$37.warn("Bridge already connected"); return; } try { @@ -27363,7 +27363,7 @@ var init_BridgeManager = __esmMin((() => { } } catch (error) { this.isActive = false; - log$34.error("Failed to start bridge", { error }); + log$37.error("Failed to start bridge", { error }); throw error; } const requestProcessing = () => { @@ -27376,10 +27376,10 @@ var init_BridgeManager = __esmMin((() => { * Create new session for a dApp connection */ async createSession(appSessionId) { - log$34.info("[BRIDGE] Creating session", { appSessionId }); + log$37.info("[BRIDGE] Creating session", { appSessionId }); if (!await this.sessionManager.getSession(appSessionId)) throw new WalletKitError(ERROR_CODES.SESSION_NOT_FOUND, `Session not found`, void 0, { appSessionId }); if (this.bridgeProvider && this.isConnected) { - log$34.info("[BRIDGE] Updating clients"); + log$37.info("[BRIDGE] Updating clients"); await this.updateClients(); } } @@ -27388,7 +27388,7 @@ var init_BridgeManager = __esmMin((() => { */ async removeSession(appSessionId) { if (this.bridgeProvider && this.isConnected) await this.updateClients(); - log$34.debug("Session removed", { appSessionId }); + log$37.debug("Session removed", { appSessionId }); } /** * Send response to dApp @@ -27413,12 +27413,12 @@ var init_BridgeManager = __esmMin((() => { } try { await this.bridgeProvider.send(response, sessionCrypto, sessionId, { traceId: event?.traceId }); - log$34.debug("Response sent successfully", { + log$37.debug("Response sent successfully", { sessionId, requestId: event.id }); } catch (error) { - log$34.error("Failed to send response through bridge", { + log$37.error("Failed to send response through bridge", { sessionId, requestId: event.id, error @@ -27500,7 +27500,7 @@ var init_BridgeManager = __esmMin((() => { await this.bridgeProvider?.restoreConnection(clients, { lastEventId: this.lastEventId }); this.isConnected = true; this.reconnectAttempts = 0; - log$34.info("Bridge connected successfully"); + log$37.info("Bridge connected successfully"); if (this.analytics) { const client = clients[0]; this.analytics.emitBridgeClientConnectEstablished({ @@ -27509,7 +27509,7 @@ var init_BridgeManager = __esmMin((() => { }); } } catch (error) { - log$34.error("Bridge connection failed", { error: error?.toString() }); + log$37.error("Bridge connection failed", { error: error?.toString() }); this.analytics?.emitBridgeClientConnectError({ error_message: `${error?.toString() || "Unknown error"}${error?.errorCode ? ` (Code: ${error?.errorCode})` : ""}`, trace_id: error?.traceId ?? connectTraceId, @@ -27518,9 +27518,9 @@ var init_BridgeManager = __esmMin((() => { if (!this.config.disableHttpConnection) { if (this.reconnectAttempts < (this.config.maxReconnectAttempts || 5)) { this.reconnectAttempts++; - log$34.info("Bridge reconnection attempt", { attempt: this.reconnectAttempts }); + log$37.info("Bridge reconnection attempt", { attempt: this.reconnectAttempts }); setTimeout(() => { - this.connectToSSEBridge().catch((error) => log$34.error("Bridge reconnection failed", { error })); + this.connectToSSEBridge().catch((error) => log$37.error("Bridge reconnection failed", { error })); }, this.config.reconnectInterval); } } @@ -27541,10 +27541,10 @@ var init_BridgeManager = __esmMin((() => { * Add client to existing bridge connection */ async updateClients() { - log$34.debug("Updating clients"); + log$37.debug("Updating clients"); if (this.bridgeProvider) { const clients = await this.getClients(); - log$34.info("[BRIDGE] Restoring connection", { clients: clients.length }); + log$37.info("[BRIDGE] Restoring connection", { clients: clients.length }); await this.bridgeProvider.restoreConnection(clients, { lastEventId: this.lastEventId }); } } @@ -27552,17 +27552,17 @@ var init_BridgeManager = __esmMin((() => { * Queue incoming bridge events for processing */ queueBridgeEvent(event) { - log$34.debug("Bridge event queued", { + log$37.debug("Bridge event queued", { eventId: event?.id, event }); this.eventQueue.push(event); this.processBridgeEvents().catch((error) => { - log$34.error("Error in background event processing", { error }); + log$37.error("Error in background event processing", { error }); }); } queueJsBridgeEvent(messageInfo, event) { - log$34.debug("JS Bridge event queued", { eventId: messageInfo?.messageId }); + log$37.debug("JS Bridge event queued", { eventId: messageInfo?.messageId }); if (!event) return; if (!event.traceId) event.traceId = v7(); if (event.method == "connect") this.eventQueue.push({ @@ -27591,7 +27591,7 @@ var init_BridgeManager = __esmMin((() => { walletId: messageInfo.walletId }); this.processBridgeEvents().catch((error) => { - log$34.error("Error in background event processing", { error }); + log$37.error("Error in background event processing", { error }); }); } /** @@ -27603,7 +27603,7 @@ var init_BridgeManager = __esmMin((() => { */ async processBridgeEvents() { if (this.isProcessing) { - log$34.debug("Event processing already in progress, skipping"); + log$37.debug("Event processing already in progress, skipping"); return; } this.isProcessing = true; @@ -27616,7 +27616,7 @@ var init_BridgeManager = __esmMin((() => { } } } catch (error) { - log$34.error("Error during event processing", { error }); + log$37.error("Error during event processing", { error }); this.isProcessing = false; this.restartConnection(); return; @@ -27629,7 +27629,7 @@ var init_BridgeManager = __esmMin((() => { */ async handleBridgeEvent(event) { try { - log$34.info("Bridge event received", { event }); + log$37.info("Bridge event received", { event }); const rawEvent = { id: event.id || crypto.randomUUID(), method: event.method || "unknown", @@ -27683,12 +27683,12 @@ var init_BridgeManager = __esmMin((() => { try { await this.eventStore.storeEvent(rawEvent); if (this.eventEmitter) this.eventEmitter.emit("bridgeStorageUpdated", {}, "bridge-manager"); - log$34.info("Event stored durably", { + log$37.info("Event stored durably", { eventId: rawEvent.id, method: rawEvent.method }); } catch (error) { - log$34.error("Failed to store event durably", { + log$37.error("Failed to store event durably", { eventId: rawEvent.id, error: error.message }); @@ -27697,13 +27697,13 @@ var init_BridgeManager = __esmMin((() => { method: rawEvent.method }); } - log$34.info("Bridge event processed", { rawEvent }); + log$37.info("Bridge event processed", { rawEvent }); if (event?.lastEventId && event.lastEventId !== this.lastEventId) { this.lastEventId = event.lastEventId; await this.saveLastEventId(); } } catch (error) { - log$34.error("Error handling bridge event", { error }); + log$37.error("Error handling bridge event", { error }); } } /** @@ -27714,11 +27714,11 @@ var init_BridgeManager = __esmMin((() => { const savedEventId = await this.storage.get(this.storageKey); if (savedEventId) { this.lastEventId = savedEventId; - log$34.debug("Loaded last event ID from storage", { lastEventId: this.lastEventId }); + log$37.debug("Loaded last event ID from storage", { lastEventId: this.lastEventId }); } } catch (error) { const storageError = WalletKitError.fromError(ERROR_CODES.STORAGE_READ_FAILED, "Failed to load last event ID from storage", error); - log$34.warn("Failed to load last event ID from storage", { error: storageError }); + log$37.warn("Failed to load last event ID from storage", { error: storageError }); } } /** @@ -27728,11 +27728,11 @@ var init_BridgeManager = __esmMin((() => { try { if (this.lastEventId) { await this.storage.set(this.storageKey, this.lastEventId); - log$34.debug("Saved last event ID to storage", { lastEventId: this.lastEventId }); + log$37.debug("Saved last event ID to storage", { lastEventId: this.lastEventId }); } } catch (error) { const storageError = WalletKitError.fromError(ERROR_CODES.STORAGE_WRITE_FAILED, "Failed to save last event ID to storage", error); - log$34.warn("Failed to save last event ID to storage", { error: storageError }); + log$37.warn("Failed to save last event ID to storage", { error: storageError }); } } }; @@ -27796,14 +27796,14 @@ async function fetchManifest(manifestUrl, proxyUrl) { manifest: null, manifestFetchErrorCode: CONNECT_EVENT_ERROR_CODES$1.MANIFEST_CONTENT_ERROR }; - log$33.info("Direct manifest fetch failed, trying proxy", { manifestUrl }); + log$36.info("Direct manifest fetch failed, trying proxy", { manifestUrl }); return tryFetchManifest(`${proxyUrl}${manifestUrl}`); } async function tryFetchManifest(url) { try { const response = await fetch(url); if (!response.ok) { - log$33.error("Failed to fetch manifest not ok", { + log$36.error("Failed to fetch manifest not ok", { url, status: response.status }); @@ -27817,7 +27817,7 @@ async function tryFetchManifest(url) { manifestFetchErrorCode: void 0 }; } catch (e) { - log$33.error("Failed to fetch manifest catched", { + log$36.error("Failed to fetch manifest catched", { url, error: e }); @@ -27827,23 +27827,23 @@ async function tryFetchManifest(url) { }; } } -var log$33; +var log$36; var init_manifest = __esmMin((() => { init_esm$2(); init_url(); init_Logger(); - log$33 = globalLogger.createChild("ManifestUtils"); + log$36 = globalLogger.createChild("ManifestUtils"); })); //#endregion //#region ../walletkit/dist/esm/handlers/ConnectHandler.js -var log$32, ConnectHandler; +var log$35, ConnectHandler; var init_ConnectHandler = __esmMin((() => { init_esm$2(); init_Logger(); init_BasicHandler(); init_url(); init_manifest(); - log$32 = globalLogger.createChild("ConnectHandler"); + log$35 = globalLogger.createChild("ConnectHandler"); ConnectHandler = class extends BasicHandler { config; analytics; @@ -27864,7 +27864,7 @@ var init_ConnectHandler = __esmMin((() => { manifest = result.manifest; manifestFetchErrorCode = result.manifestFetchErrorCode; } catch (error) { - log$32.warn("Failed to fetch manifest", { error }); + log$35.warn("Failed to fetch manifest", { error }); } const preview = this.createPreview(event, manifestUrl, manifest, manifestFetchErrorCode); const connectEvent = { @@ -27925,14 +27925,14 @@ var init_ConnectHandler = __esmMin((() => { if (!finalManifestFetchErrorCode && dAppUrl) try { const parsedDAppUrl = new URL(dAppUrl); if (!isValidHost(parsedDAppUrl.host)) { - log$32.warn("Invalid dApp URL in manifest - invalid host format", { + log$35.warn("Invalid dApp URL in manifest - invalid host format", { dAppUrl, host: parsedDAppUrl.host }); finalManifestFetchErrorCode = CONNECT_EVENT_ERROR_CODES$1.MANIFEST_CONTENT_ERROR; } } catch (_) { - log$32.warn("Invalid dApp URL in manifest - failed to parse", { dAppUrl }); + log$35.warn("Invalid dApp URL in manifest - failed to parse", { dAppUrl }); finalManifestFetchErrorCode = CONNECT_EVENT_ERROR_CODES$1.MANIFEST_CONTENT_ERROR; } } @@ -28596,7 +28596,7 @@ async function resolveItemsToMessages(items, wallet) { messages.push(resolveNftItem(item, wallet)); break; default: - log$31.warn("Unknown item type, skipping", { item }); + log$34.warn("Unknown item type, skipping", { item }); break; } return messages; @@ -28649,13 +28649,13 @@ function resolveNftItem(item, wallet) { mode: { flags: [SendModeFlag.IGNORE_ERRORS, SendModeFlag.PAY_GAS_SEPARATELY] } }; } -var import_dist$33, log$31; +var import_dist$33, log$34; var init_itemsResolver = __esmMin((() => { import_dist$33 = require_dist$1(); init_models(); init_messageBuilders(); init_Logger(); - log$31 = globalLogger.createChild("ItemsResolver"); + log$34 = globalLogger.createChild("ItemsResolver"); })); //#endregion //#region ../walletkit/dist/esm/utils/events.js @@ -28717,7 +28717,7 @@ function parseTonConnectTransactionRequest(event, wallet) { validation: validateTransactionRequestForWallet(request, wallet, event.isLocal) }; } catch (error) { - log$30.error("Failed to parse transaction request", { error }); + log$33.error("Failed to parse transaction request", { error }); errors.push("Failed to parse transaction request"); return { result: void 0, @@ -28728,15 +28728,15 @@ function parseTonConnectTransactionRequest(event, wallet) { }; } } -var log$30; +var log$33; var init_events = __esmMin((() => { - init_errors$3(); + init_errors$4(); init_transactionValidators(); init_internal(); init_transaction$1(); init_itemsResolver(); init_Logger(); - log$30 = globalLogger.createChild("EventsUtils"); + log$33 = globalLogger.createChild("EventsUtils"); })); //#endregion //#region ../../node_modules/.pnpm/@noble+hashes@2.2.0/node_modules/@noble/hashes/utils.js @@ -29636,7 +29636,7 @@ var import_dist$32; var init_mnemonic = __esmMin((() => { import_dist$32 = require_dist$2(); init_bip39(); - init_errors$3(); + init_errors$4(); })); //#endregion //#region ../walletkit/dist/esm/utils/sign.js @@ -31070,7 +31070,7 @@ async function createTransactionPreviewIfPossible(config, client, request, walle try { preview = await CallForSuccess(() => createTransactionPreview(client, request, wallet, options)); } catch (error) { - log$29.error("Failed to create transaction preview", { error }); + log$32.error("Failed to create transaction preview", { error }); preview = { error: { code: ERROR_CODES.UNKNOWN_EMULATION_ERROR, @@ -31081,7 +31081,7 @@ async function createTransactionPreviewIfPossible(config, client, request, walle } return preview; } -var import_dist$20, log$29, SIGN_MODE_EMULATION_VALUE; +var import_dist$20, log$32, SIGN_MODE_EMULATION_VALUE; var init_transactionPreview = __esmMin((() => { import_dist$20 = require_dist$1(); init_map_emulation_trace(); @@ -31090,7 +31090,7 @@ var init_transactionPreview = __esmMin((() => { init_retry(); init_models(); init_Logger(); - log$29 = globalLogger.createChild("TransactionPreview"); + log$32 = globalLogger.createChild("TransactionPreview"); SIGN_MODE_EMULATION_VALUE = 2000000000n; })); //#endregion @@ -31290,6 +31290,55 @@ var init_toncenter$2 = __esmMin((() => { init_getTransactionStatus(); })); //#endregion +//#region ../walletkit/dist/esm/utils/checkSignMessageSupport.js +/** +* Throws {@link SupportError} (with a `code` discriminating the +* specific failure) when the connected wallet's advertised `Feature[]` cannot +* satisfy a SignMessage request — feature missing, `maxMessages` too low, +* missing extra-currency / item-type support. Logs a warning when the wallet +* didn't declare `maxMessages` (request may still be rejected by the wallet). +*/ +function checkSignMessageSupport(features, options) { + const signMessageFeature = features.find((feature) => !!feature && typeof feature === "object" && feature.name === "SignMessage"); + if (!signMessageFeature) throw new SupportError("Wallet doesn't support SignMessage feature.", SupportErrorCode.NotSupported); + if (options.requireExtraCurrencies && !signMessageFeature.extraCurrencySupported) throw new SupportError("Wallet is not able to handle such SignMessage request. Extra currencies support is required.", SupportErrorCode.ExtraCurrencyNotSupported); + if (options.requiredItemTypes?.length) { + const supportedTypes = signMessageFeature.itemTypes ?? []; + const unsupportedTypes = options.requiredItemTypes.filter((type) => !supportedTypes.includes(type)); + if (unsupportedTypes.length) throw new SupportError(signMessageFeature.itemTypes ? `Wallet doesn't support item types: ${unsupportedTypes.join(", ")} in SignMessage.` : "Wallet doesn't support structured items in SignMessage.", SupportErrorCode.ItemTypesNotSupported); + } + if (signMessageFeature.maxMessages !== void 0) { + if (signMessageFeature.maxMessages < options.requiredMessagesNumber) throw new SupportError(`Wallet is not able to handle such SignMessage request. Max support messages number is ${signMessageFeature.maxMessages}, but ${options.requiredMessagesNumber} is required.`, SupportErrorCode.TooManyMessages); + return; + } + log$31.warn("Connected wallet didn't provide information about max allowed messages in the SignMessage request. Request may be rejected by the wallet."); +} +var log$31, SupportErrorCode, SupportError; +var init_checkSignMessageSupport = __esmMin((() => { + init_Logger(); + log$31 = globalLogger.createChild("checkSignMessageSupport"); + (function(SupportErrorCode) { + /** Wallet did not advertise the `SignMessage` feature at all. */ + SupportErrorCode["NotSupported"] = "NOT_SUPPORTED"; + /** Wallet's `maxMessages` cap is lower than `requiredMessagesNumber`. */ + SupportErrorCode["TooManyMessages"] = "TOO_MANY_MESSAGES"; + /** Request includes extra-currency transfers, wallet's feature flag is not set. */ + SupportErrorCode["ExtraCurrencyNotSupported"] = "EXTRA_CURRENCY_NOT_SUPPORTED"; + /** Request requires structured item types the wallet did not list. */ + SupportErrorCode["ItemTypesNotSupported"] = "ITEM_TYPES_NOT_SUPPORTED"; + })(SupportErrorCode || (SupportErrorCode = {})); + SupportError = class extends Error { + code; + feature; + unsupportedItemTypes; + constructor(message, code) { + super(message); + this.name = "SupportError"; + this.code = code; + } + }; +})); +//#endregion //#region ../walletkit/dist/esm/utils/index.js var init_utils$2 = __esmMin((() => { init_Signer(); @@ -31319,17 +31368,18 @@ var init_utils$2 = __esmMin((() => { init_toncenter$2(); init_getNormalizedExtMessageHash(); init_manifest(); + init_checkSignMessageSupport(); })); //#endregion //#region ../walletkit/dist/esm/handlers/TransactionHandler.js -var log$28, TransactionHandler; +var log$30, TransactionHandler; var init_TransactionHandler = __esmMin((() => { init_esm$2(); init_Logger(); init_BasicHandler(); init_events(); init_utils$2(); - log$28 = globalLogger.createChild("TransactionHandler"); + log$30 = globalLogger.createChild("TransactionHandler"); TransactionHandler = class extends BasicHandler { config; walletManager; @@ -31351,7 +31401,7 @@ var init_TransactionHandler = __esmMin((() => { async handle(event) { const wallet = getWalletFromEvent(this.walletManager, event); if (!wallet) { - log$28.error("Wallet not found", { event }); + log$30.error("Wallet not found", { event }); return { error: { code: SEND_TRANSACTION_ERROR_CODES$1.UNKNOWN_APP_ERROR, @@ -31362,7 +31412,7 @@ var init_TransactionHandler = __esmMin((() => { } const requestValidation = this.parseTonConnectTransactionRequest(event, wallet); if (!requestValidation.result || !requestValidation?.validation?.isValid) { - log$28.error("Failed to parse transaction request", { + log$30.error("Failed to parse transaction request", { event, requestValidation }); @@ -31408,13 +31458,13 @@ var init_TransactionHandler = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/handlers/SignDataHandler.js -var log$27, SignDataHandler; +var log$29, SignDataHandler; var init_SignDataHandler = __esmMin((() => { init_internal(); init_BasicHandler(); init_Logger(); - init_errors$3(); - log$27 = globalLogger.createChild("SignDataHandler"); + init_errors$4(); + log$29 = globalLogger.createChild("SignDataHandler"); SignDataHandler = class extends BasicHandler { analytics; walletManager; @@ -31435,12 +31485,12 @@ var init_SignDataHandler = __esmMin((() => { const wallet = walletId ? this.walletManager.getWallet(walletId) : void 0; const payload = this.parseDataToSign(event); if (!payload) { - log$27.error("No data to sign found in request", { event }); + log$29.error("No data to sign found in request", { event }); throw new WalletKitError(ERROR_CODES.INVALID_REQUEST_EVENT, "No data to sign found in request", void 0, { eventId: event.id }); } const preview = this.createDataPreview(payload.data, event); if (!preview) { - log$27.error("No preview found for data", { data: payload }); + log$29.error("No preview found for data", { data: payload }); throw new WalletKitError(ERROR_CODES.RESPONSE_CREATION_FAILED, "Failed to create preview for sign data request", void 0, { eventId: event.id, data: payload @@ -31497,7 +31547,7 @@ var init_SignDataHandler = __esmMin((() => { } }; } catch (error) { - log$27.error("Error deserializing cell", { error }); + log$29.error("Error deserializing cell", { error }); return { type: "cell", value: { @@ -31511,14 +31561,14 @@ var init_SignDataHandler = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/handlers/SignMessageHandler.js -var log$26, SignMessageHandler; +var log$28, SignMessageHandler; var init_SignMessageHandler = __esmMin((() => { init_esm$2(); init_Logger(); init_BasicHandler(); init_utils$2(); init_events(); - log$26 = globalLogger.createChild("SignMessageHandler"); + log$28 = globalLogger.createChild("SignMessageHandler"); SignMessageHandler = class extends BasicHandler { config; walletManager; @@ -31540,7 +31590,7 @@ var init_SignMessageHandler = __esmMin((() => { async handle(event) { const wallet = getWalletFromEvent(this.walletManager, event); if (!wallet) { - log$26.error("Wallet not found", { event }); + log$28.error("Wallet not found", { event }); return { error: { code: SIGN_MESSAGE_ERROR_CODES.UNKNOWN_APP_ERROR, @@ -31551,7 +31601,7 @@ var init_SignMessageHandler = __esmMin((() => { } const requestValidation = this.parseTonConnectTransactionRequest(event, wallet); if (!requestValidation.result || !requestValidation?.validation?.isValid) { - log$26.error("Failed to parse sign message request", { + log$28.error("Failed to parse sign message request", { event, requestValidation }); @@ -31597,7 +31647,7 @@ var init_SignMessageHandler = __esmMin((() => { var DisconnectHandler; var init_DisconnectHandler = __esmMin((() => { init_BasicHandler(); - init_errors$3(); + init_errors$4(); DisconnectHandler = class extends BasicHandler { sessionManager; constructor(notify, sessionManager) { @@ -31636,7 +31686,7 @@ var init_DisconnectHandler = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/core/EventRouter.js -var log$25, EventRouter; +var log$27, EventRouter; var init_EventRouter = __esmMin((() => { init_ConnectHandler(); init_TransactionHandler(); @@ -31645,7 +31695,7 @@ var init_EventRouter = __esmMin((() => { init_DisconnectHandler(); init_events$1(); init_Logger(); - log$25 = globalLogger.createChild("EventRouter"); + log$27 = globalLogger.createChild("EventRouter"); EventRouter = class { config; eventEmitter; @@ -31677,7 +31727,7 @@ var init_EventRouter = __esmMin((() => { async routeEvent(event) { const validation = validateBridgeEvent(event); if (!validation.isValid) { - log$25.error("Invalid bridge event", { errors: validation.errors }); + log$27.error("Invalid bridge event", { errors: validation.errors }); return; } try { @@ -31692,7 +31742,7 @@ var init_EventRouter = __esmMin((() => { try { await this.bridgeManager.sendResponse(event, result); } catch (error) { - log$25.error("Error sending response for error event", { + log$27.error("Error sending response for error event", { error, event, result @@ -31704,7 +31754,7 @@ var init_EventRouter = __esmMin((() => { break; } } catch (error) { - log$25.error("Error routing event", { error }); + log$27.error("Error routing event", { error }); throw error; } } @@ -31833,7 +31883,7 @@ function hasConnectionResult(event) { */ async function signTransactionInternal(wallet, request) { const signedBoc = await wallet.getSignedSendTransaction(request, { fakeSignature: false }); - log$24.debug("Signing transaction", { + log$26.debug("Signing transaction", { messagesNumber: request.messages.length, fromAddress: request.fromAddress, validUntil: request.validUntil @@ -31889,7 +31939,7 @@ function parseDomain(url) { value: parsedUrl.host }; } catch (error) { - log$24.error("Failed to parse domain", { error }); + log$26.error("Failed to parse domain", { error }); return { lengthBytes: 0, value: "" @@ -31917,7 +31967,7 @@ function toTonConnectSignDataPayload(payload) { bytes: payload.data.value.content }; } -var import_dist$16, import_dist$17, log$24, RequestProcessor; +var import_dist$16, import_dist$17, log$26, RequestProcessor; var init_RequestProcessor = __esmMin((() => { import_dist$16 = require_dist$1(); init_esm$2(); @@ -31926,13 +31976,13 @@ var init_RequestProcessor = __esmMin((() => { init_tonProof(); init_retry(); init_getDefaultWalletConfig(); - init_errors$3(); + init_errors$4(); init_base64(); init_sign(); init_transaction$1(); init_utils$2(); init_events(); - log$24 = globalLogger.createChild("RequestProcessor"); + log$26 = globalLogger.createChild("RequestProcessor"); RequestProcessor = class { walletKitOptions; sessionManager; @@ -31995,7 +32045,7 @@ var init_RequestProcessor = __esmMin((() => { } return; } catch (error) { - log$24.error("Failed to approve connect request", { error }); + log$26.error("Failed to approve connect request", { error }); throw error; } } @@ -32130,7 +32180,7 @@ var init_RequestProcessor = __esmMin((() => { */ async rejectConnectRequest(event, reason, errorCode) { try { - log$24.info("Connect request rejected", { + log$26.info("Connect request rejected", { id: event.id, dAppName: event.preview.dAppInfo?.name || "", reason: reason || "User rejected connection" @@ -32147,7 +32197,7 @@ var init_RequestProcessor = __esmMin((() => { try { await this.bridgeManager.sendResponse(event, response, new SessionCrypto()); } catch (error) { - log$24.error("Failed to send connect request rejection response", { error }); + log$26.error("Failed to send connect request rejection response", { error }); } if (this.analytics) { const sessionData = event.from ? await this.sessionManager.getSession(sessionId) : void 0; @@ -32176,7 +32226,7 @@ var init_RequestProcessor = __esmMin((() => { } return; } catch (error) { - log$24.error("Failed to reject connect request", { error }); + log$26.error("Failed to reject connect request", { error }); throw error; } } @@ -32208,7 +32258,7 @@ var init_RequestProcessor = __esmMin((() => { return { signedBoc }; } } catch (error) { - log$24.error("Failed to approve transaction request", { error }); + log$26.error("Failed to approve transaction request", { error }); if (error instanceof WalletKitError) throw error; if (error?.message?.includes("Ledger device")) throw new WalletKitError(ERROR_CODES.LEDGER_DEVICE_ERROR, "Ledger device error", error); throw error; @@ -32258,7 +32308,7 @@ var init_RequestProcessor = __esmMin((() => { } return; } catch (error) { - log$24.error("Failed to reject transaction request", { error }); + log$26.error("Failed to reject transaction request", { error }); throw error; } } @@ -32289,7 +32339,7 @@ var init_RequestProcessor = __esmMin((() => { return { internalBoc }; } } catch (error) { - log$24.error("Failed to approve sign message request", { error }); + log$26.error("Failed to approve sign message request", { error }); throw error; } } @@ -32307,7 +32357,7 @@ var init_RequestProcessor = __esmMin((() => { }; await this.sendBridgeMessage(event, void 0, response); } catch (error) { - log$24.error("Failed to reject sign message request", { error }); + log$26.error("Failed to reject sign message request", { error }); throw error; } } @@ -32410,7 +32460,7 @@ var init_RequestProcessor = __esmMin((() => { }; } } catch (error) { - log$24.error("Failed to approve sign data request", { error: error?.message?.toString() ?? error?.toString() }); + log$26.error("Failed to approve sign data request", { error: error?.message?.toString() ?? error?.toString() }); if (error instanceof WalletKitError) throw error; throw error; } @@ -32445,7 +32495,7 @@ var init_RequestProcessor = __esmMin((() => { } return; } catch (error) { - log$24.error("Failed to reject sign data request", { error }); + log$26.error("Failed to reject sign data request", { error }); throw error; } } @@ -32522,14 +32572,14 @@ var init_RequestProcessor = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/core/EventStore.js -var getEventUUID, log$23, MAX_EVENT_SIZE_BYTES, StorageEventStore; +var getEventUUID, log$25, MAX_EVENT_SIZE_BYTES, StorageEventStore; var init_EventStore = __esmMin((() => { init_Logger(); init_events$1(); getEventUUID = () => { return crypto.randomUUID(); }; - log$23 = globalLogger.createChild("EventStore"); + log$25 = globalLogger.createChild("EventStore"); MAX_EVENT_SIZE_BYTES = 100 * 1024; StorageEventStore = class { storage; @@ -32562,7 +32612,7 @@ var init_EventStore = __esmMin((() => { sizeBytes }; await this.saveEvent(storedEvent); - log$23.info("Event stored", { + log$25.info("Event stored", { eventId: storedEvent.id, eventType, sizeBytes, @@ -32590,11 +32640,11 @@ var init_EventStore = __esmMin((() => { const allEvents = await this.getAllEventsFromStorage(); const event = allEvents[eventId]; if (!event) { - log$23.warn("Cannot lock non-existent event", { eventId }); + log$25.warn("Cannot lock non-existent event", { eventId }); return; } if (event.status !== "new") { - log$23.debug("Cannot lock event - not in new status", { + log$25.debug("Cannot lock event - not in new status", { eventId, status: event.status, lockedBy: event.lockedBy @@ -32609,7 +32659,7 @@ var init_EventStore = __esmMin((() => { }; allEvents[eventId] = updatedEvent; await this.storage.set(this.storageKey, allEvents); - log$23.debug("Event lock acquired", { + log$25.debug("Event lock acquired", { eventId, walletAddress: walletId }); @@ -32636,7 +32686,7 @@ var init_EventStore = __esmMin((() => { }; allEvents[eventId] = updatedEvent; await this.storage.set(this.storageKey, allEvents); - log$23.debug("Event retry count incremented", { + log$25.debug("Event retry count incremented", { eventId, retryCount: updatedEvent.retryCount, error @@ -32660,7 +32710,7 @@ var init_EventStore = __esmMin((() => { if (status === "completed") updatedEvent.completedAt = Date.now(); allEvents[eventId] = updatedEvent; await this.storage.set(this.storageKey, allEvents); - log$23.debug("Event status updated", { + log$25.debug("Event status updated", { eventId, oldStatus, newStatus: status @@ -32675,7 +32725,7 @@ var init_EventStore = __esmMin((() => { try { return (await this.getAllEventsFromStorage())[eventId] || null; } catch (error) { - log$23.warn("Failed to get event", { + log$25.warn("Failed to get event", { eventId, error }); @@ -32697,14 +32747,14 @@ var init_EventStore = __esmMin((() => { }; await this.saveEvent(recoveredEvent); recoveredCount++; - log$23.info("Recovered stale event", { + log$25.info("Recovered stale event", { eventId: event.id, lockedBy: event.lockedBy, staleMinutes: Math.round((now - event.processingStartedAt) / 6e4), retryCount: event.retryCount || 0 }); } - if (recoveredCount > 0) log$23.info("Event recovery completed", { recoveredCount }); + if (recoveredCount > 0) log$25.info("Event recovery completed", { recoveredCount }); return recoveredCount; } /** @@ -32717,7 +32767,7 @@ var init_EventStore = __esmMin((() => { const eventsToRemove = []; for (const event of events) if (event.status === "completed" && event.completedAt && event.completedAt < cutoffTime || event.status === "errored" && event.createdAt < cutoffTime) { eventsToRemove.push(event.id); - log$23.debug("Marked event for cleanup", { + log$25.debug("Marked event for cleanup", { eventId: event.id, status: event.status }); @@ -32731,7 +32781,7 @@ var init_EventStore = __esmMin((() => { } await this.storage.set(this.storageKey, allEvents); }); - log$23.info("Event cleanup completed", { cleanedUpCount }); + log$25.info("Event cleanup completed", { cleanedUpCount }); } return cleanedUpCount; } @@ -32743,7 +32793,7 @@ var init_EventStore = __esmMin((() => { const allEvents = await this.getAllEventsFromStorage(); return Object.values(allEvents); } catch (error) { - log$23.warn("Failed to get all events", { error }); + log$25.warn("Failed to get all events", { error }); return []; } } @@ -32765,7 +32815,7 @@ var init_EventStore = __esmMin((() => { try { return await this.storage.get(this.storageKey) || {}; } catch (error) { - log$23.warn("Failed to get events from storage", { error }); + log$25.warn("Failed to get events from storage", { error }); return {}; } } @@ -32798,10 +32848,10 @@ var init_EventStore = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/core/EventProcessor.js -var log$22, StorageEventProcessor; +var log$24, StorageEventProcessor; var init_EventProcessor = __esmMin((() => { init_Logger(); - log$22 = globalLogger.createChild("EventProcessor"); + log$24 = globalLogger.createChild("EventProcessor"); StorageEventProcessor = class { eventStore; config; @@ -32833,14 +32883,14 @@ var init_EventProcessor = __esmMin((() => { */ async startProcessing(walletId) { if (this.processorConfig.disableEvents) return; - if (walletId) if (this.registeredWallets.has(walletId)) log$22.debug("Processing already registered for wallet", { walletId }); + if (walletId) if (this.registeredWallets.has(walletId)) log$24.debug("Processing already registered for wallet", { walletId }); else { this.registeredWallets.add(walletId); - log$22.info("Registered wallet for event processing", { walletId }); + log$24.info("Registered wallet for event processing", { walletId }); } if (!this.isProcessing) { this.isProcessing = true; - log$22.info("Started global event processing loop"); + log$24.info("Started global event processing loop"); this.processEventsLoop(); } else this.triggerProcessing(); } @@ -32851,7 +32901,7 @@ var init_EventProcessor = __esmMin((() => { if (this.processorConfig.disableEvents) return; if (walletId) { this.registeredWallets.delete(walletId); - log$22.info("Unregistered wallet from event processing", { walletId }); + log$24.info("Unregistered wallet from event processing", { walletId }); } if (this.registeredWallets.size === 0 && this.isProcessing && !walletId) { this.isProcessing = false; @@ -32859,12 +32909,12 @@ var init_EventProcessor = __esmMin((() => { this.wakeUpResolver(); this.wakeUpResolver = void 0; } - log$22.info("Stopped global event processing loop (no more wallets)"); + log$24.info("Stopped global event processing loop (no more wallets)"); } } async clearRegisteredWallets() { this.registeredWallets.clear(); - log$22.info("Cleared registered wallets from event processing"); + log$24.info("Cleared registered wallets from event processing"); } /** * Process next available event from any source (wallet or no-wallet) @@ -32894,7 +32944,7 @@ var init_EventProcessor = __esmMin((() => { const walletId = allSessions.find((s) => s.sessionId === eventToUse.sessionId)?.walletId || "no-wallet"; return await this.processEvent(eventToUse, walletId); } catch (error) { - log$22.error("Error in processNextAvailableEvent", { error: error.message }); + log$24.error("Error in processNextAvailableEvent", { error: error.message }); return false; } } @@ -32904,9 +32954,9 @@ var init_EventProcessor = __esmMin((() => { async completeEvent(eventId) { try { await this.eventStore.updateEventStatus(eventId, "completed", "processing"); - log$22.debug("Event marked as completed", { eventId }); + log$24.debug("Event marked as completed", { eventId }); } catch (error) { - log$22.error("Failed to mark event as completed", { + log$24.error("Failed to mark event as completed", { eventId, error: error.message }); @@ -32917,14 +32967,14 @@ var init_EventProcessor = __esmMin((() => { */ startRecoveryLoop() { if (this.recoveryTimeoutId) { - log$22.debug("Recovery loop already running"); + log$24.debug("Recovery loop already running"); return; } const recoveryLoop = async () => { try { if (await this.eventStore.recoverStaleEvents(this.config.processingTimeoutMs) > 0) this.triggerProcessing(); } catch (error) { - log$22.error("Error in recovery loop", { error: error.message }); + log$24.error("Error in recovery loop", { error: error.message }); } if (this.recoveryTimeoutId !== void 0) this.recoveryTimeoutId = setTimeout(recoveryLoop, this.config.recoveryIntervalMs); }; @@ -32932,13 +32982,13 @@ var init_EventProcessor = __esmMin((() => { try { await this.eventStore.cleanupOldEvents(this.config.retentionMs); } catch (error) { - log$22.error("Error in cleanup loop", { error: error.message }); + log$24.error("Error in cleanup loop", { error: error.message }); } if (this.cleanupTimeoutId !== void 0) this.cleanupTimeoutId = setTimeout(cleanupLoop, this.config.cleanupIntervalMs); }; this.recoveryTimeoutId = setTimeout(recoveryLoop, this.config.recoveryIntervalMs); this.cleanupTimeoutId = setTimeout(cleanupLoop, this.config.cleanupIntervalMs); - log$22.info("Recovery and cleanup loops started"); + log$24.info("Recovery and cleanup loops started"); } /** * Stop the recovery process @@ -32952,7 +33002,7 @@ var init_EventProcessor = __esmMin((() => { clearTimeout(this.cleanupTimeoutId); this.cleanupTimeoutId = void 0; } - log$22.info("Recovery and cleanup loops stopped"); + log$24.info("Recovery and cleanup loops stopped"); } /** * Process a single event with retry logic @@ -32960,7 +33010,7 @@ var init_EventProcessor = __esmMin((() => { */ async processEvent(event, walletId) { if (!await this.eventStore.acquireLock(event.id, walletId)) { - log$22.debug("Failed to acquire lock on event", { + log$24.debug("Failed to acquire lock on event", { eventId: event.id, walletId }); @@ -32968,7 +33018,7 @@ var init_EventProcessor = __esmMin((() => { } const retryCount = event.retryCount || 0; if (retryCount >= this.config.maxRetries) { - log$22.error("Event exceeded max retries, marking as errored", { + log$24.error("Event exceeded max retries, marking as errored", { eventId: event.id, retryCount, maxRetries: this.config.maxRetries @@ -32976,14 +33026,14 @@ var init_EventProcessor = __esmMin((() => { try { await this.eventStore.updateEventStatus(event.id, "errored", "processing"); } catch (error) { - log$22.error("Failed to mark event as errored", { + log$24.error("Failed to mark event as errored", { eventId: event.id, error: error.message }); } return false; } - log$22.info("Processing event", { + log$24.info("Processing event", { eventId: event.id, eventType: event.eventType, walletId, @@ -33003,11 +33053,11 @@ var init_EventProcessor = __esmMin((() => { ...walletAddress ? { walletAddress } : {} }); await this.eventStore.updateEventStatus(event.id, "completed", "processing"); - log$22.info("Event processing completed", { eventId: event.id }); + log$24.info("Event processing completed", { eventId: event.id }); return true; } catch (error) { const errorMessage = error.message ?? "Unknown error"; - log$22.error("Error processing event", { + log$24.error("Error processing event", { eventId: event.id, error: errorMessage, retryCount @@ -33015,7 +33065,7 @@ var init_EventProcessor = __esmMin((() => { try { await this.eventStore.releaseLock(event.id, errorMessage); } catch (updateError) { - log$22.error("Failed to increment retry count", { + log$24.error("Failed to increment retry count", { eventId: event.id, error: updateError.message }); @@ -33030,18 +33080,18 @@ var init_EventProcessor = __esmMin((() => { while (this.isProcessing) try { if (!await this.processNextAvailableEvent()) await this.waitForWakeUpOrTimeout(500); } catch (error) { - log$22.error("Error in global processing loop", { error: error.message }); + log$24.error("Error in global processing loop", { error: error.message }); await this.waitForWakeUpOrTimeout(500); } this.wakeUpResolver = void 0; - log$22.debug("Global processing loop ended"); + log$24.debug("Global processing loop ended"); } /** * Trigger the global processing loop */ triggerProcessing() { if (this.isProcessing && this.wakeUpResolver) { - log$22.debug("Waking up global processing loop"); + log$24.debug("Waking up global processing loop"); this.wakeUpResolver(); } } @@ -33078,7 +33128,7 @@ var init_EventProcessor = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/core/wallet/extensions/ton.js -var log$21, WalletTonClass; +var log$23, WalletTonClass; var init_ton = __esmMin((() => { init_address$1(); init_validation(); @@ -33086,9 +33136,9 @@ var init_ton = __esmMin((() => { init_transactionPreview(); init_messageBuilders(); init_getNormalizedExtMessageHash(); - init_errors$3(); + init_errors$4(); init_Logger(); - log$21 = globalLogger.createChild("WalletTonClass"); + log$23 = globalLogger.createChild("WalletTonClass"); WalletTonClass = class { async createTransferTonTransaction(param) { if (!isValidAddress(param.recipientAddress)) throw new Error(`Invalid to address: ${param.recipientAddress}`); @@ -33149,7 +33199,7 @@ var init_ton = __esmMin((() => { normalizedHash }; } catch (error) { - log$21.error("Failed to send transaction", { error }); + log$23.error("Failed to send transaction", { error }); if (error instanceof WalletKitError) throw error; if (error?.message?.includes("Ledger device")) throw new WalletKitError(ERROR_CODES.LEDGER_DEVICE_ERROR, "Ledger device error", error); throw error; @@ -33265,7 +33315,7 @@ async function wrapWalletInterface(wallet) { } }); return newProxy; } -var log$20, Initializer; +var log$22, Initializer; var init_Initializer = __esmMin((() => { init_types$2(); init_storage(); @@ -33280,7 +33330,7 @@ var init_Initializer = __esmMin((() => { init_ton(); init_jetton$1(); init_nft(); - log$20 = globalLogger.createChild("Initializer"); + log$22 = globalLogger.createChild("Initializer"); Initializer = class { config; networkManager; @@ -33296,12 +33346,12 @@ var init_Initializer = __esmMin((() => { */ async initialize(options, networkManager) { try { - log$20.info("Initializing TonWalletKit..."); + log$22.info("Initializing TonWalletKit..."); this.networkManager = networkManager; const storage = this.initializeStorage(options); const { walletManager, sessionManager, bridgeManager, eventRouter, eventProcessor } = await this.initializeManagers(options, storage); const { requestProcessor } = this.initializeProcessors(sessionManager, bridgeManager, walletManager); - log$20.info("TonWalletKit initialized successfully"); + log$22.info("TonWalletKit initialized successfully"); return { walletManager, sessionManager, @@ -33312,7 +33362,7 @@ var init_Initializer = __esmMin((() => { eventProcessor }; } catch (error) { - log$20.error("Failed to initialize TonWalletKit", { error }); + log$22.error("Failed to initialize TonWalletKit", { error }); throw error; } } @@ -33348,9 +33398,9 @@ var init_Initializer = __esmMin((() => { const bridgeManager = new BridgeManager(options?.walletManifest, options?.bridge, sessionManager, storage, eventStore, eventRouter, options, this.eventEmitter, this.analyticsManager); eventRouter.setBridgeManager(bridgeManager); bridgeManager.start().then(() => { - log$20.info("Bridge manager started successfully"); + log$22.info("Bridge manager started successfully"); }).catch((e) => { - log$20.error("Could not start bridge manager", { error: e?.toString?.() }); + log$22.error("Could not start bridge manager", { error: e?.toString?.() }); }); const eventProcessor = new StorageEventProcessor(options?.eventProcessor, eventStore, DEFAULT_DURABLE_EVENTS_CONFIG, walletManager, sessionManager, eventRouter, this.eventEmitter); return { @@ -33372,7 +33422,7 @@ var init_Initializer = __esmMin((() => { */ async cleanup(components) { try { - log$20.info("Cleaning up TonWalletKit components..."); + log$22.info("Cleaning up TonWalletKit components..."); if (components.eventProcessor) { components.eventProcessor.stopRecoveryLoop(); await components.eventProcessor.clearRegisteredWallets(); @@ -33380,9 +33430,9 @@ var init_Initializer = __esmMin((() => { } if (components.bridgeManager) await components.bridgeManager.close(); if (components.eventRouter) components.eventRouter.clearCallbacks(); - log$20.info("TonWalletKit cleanup completed"); + log$22.info("TonWalletKit cleanup completed"); } catch (error) { - log$20.error("Error during cleanup", { error }); + log$22.error("Error during cleanup", { error }); } } }; @@ -33398,14 +33448,14 @@ function isTonAddress(address) { function createCacheKey(network, address) { return `${network.chainId}:${address}`; } -var import_dist$15, log$19, TON_ADDRESS, TON_INFO, JettonsManager; +var import_dist$15, log$21, TON_ADDRESS, TON_INFO, JettonsManager; var init_JettonsManager = __esmMin((() => { import_dist$15 = require_dist$1(); init_index_min(); init_Logger(); init_jettons(); init_utils$2(); - log$19 = globalLogger.createChild("JettonsManager"); + log$21 = globalLogger.createChild("JettonsManager"); TON_ADDRESS = "TON"; TON_INFO = { address: TON_ADDRESS, @@ -33432,7 +33482,7 @@ var init_JettonsManager = __esmMin((() => { ttl: 1e3 * 60 * 10 }); for (const network of this.networkManager.getConfiguredNetworks()) this.addTonToCache(network); - log$19.info("JettonsManager initialized", { cacheSize }); + log$21.info("JettonsManager initialized", { cacheSize }); } /** * Add TON native token to cache for a specific network @@ -33453,19 +33503,19 @@ var init_JettonsManager = __esmMin((() => { const cacheKey = this.normalizedCacheKey(targetNetwork, jettonAddress); const cachedInfo = this.cache.get(cacheKey); if (cachedInfo) { - log$19.debug("Jetton info found in cache", { + log$21.debug("Jetton info found in cache", { jettonAddress, network: targetNetwork }); return cachedInfo; } - log$19.debug("Jetton info not found in cache", { + log$21.debug("Jetton info not found in cache", { jettonAddress, network: targetNetwork }); const address = asMaybeAddressFriendly(jettonAddress); if (!address) { - log$19.error("Invalid jetton address format", { + log$21.error("Invalid jetton address format", { jettonAddress, network: targetNetwork }); @@ -33500,7 +33550,7 @@ var init_JettonsManager = __esmMin((() => { } return null; } catch (error) { - log$19.error("Error getting jetton info", { + log$21.error("Error getting jetton info", { error, jettonAddress, network: targetNetwork @@ -33519,7 +33569,7 @@ var init_JettonsManager = __esmMin((() => { const targetNetwork = network; try { const apiClient = this.networkManager.getClient(targetNetwork); - log$19.debug("Getting address jettons", { + log$21.debug("Getting address jettons", { userAddress, network: targetNetwork, offset, @@ -33533,13 +33583,13 @@ var init_JettonsManager = __esmMin((() => { if (!response.jettons) return []; const addressJettons = []; for (const item of response.jettons) addressJettons.push(item); - log$19.debug("Retrieved address jettons", { + log$21.debug("Retrieved address jettons", { count: addressJettons.length, network: targetNetwork }); return addressJettons; } catch (error) { - log$19.error("Failed to get address jettons", { + log$21.error("Failed to get address jettons", { error, userAddress, network: targetNetwork @@ -33563,14 +33613,14 @@ var init_JettonsManager = __esmMin((() => { uri: emulationInfo.extra.uri }; this.cache.set(cacheKey, jettonInfo); - log$19.debug("Added jetton info from emulation to cache", { + log$21.debug("Added jetton info from emulation to cache", { jettonAddress, network, name: jettonInfo.name, symbol: jettonInfo.symbol }); } catch (error) { - log$19.error("Error adding jetton from emulation", { + log$21.error("Error adding jetton from emulation", { error, jettonAddress, network @@ -33587,7 +33637,7 @@ var init_JettonsManager = __esmMin((() => { if (!addressMetadata.is_indexed || !addressMetadata.token_info) continue; const jettonMasterInfo = addressMetadata.token_info.find((info) => typeof info === "object" && info !== null && "type" in info && info.type === "jetton_masters"); if (jettonMasterInfo) { - log$19.debug("Adding jetton from emulation metadata", { + log$21.debug("Adding jetton from emulation metadata", { jettonAddress, network }); @@ -33595,12 +33645,12 @@ var init_JettonsManager = __esmMin((() => { addedCount++; } } - if (addedCount > 0) log$19.info("Added jettons from emulation metadata", { + if (addedCount > 0) log$21.info("Added jettons from emulation metadata", { addedCount, network }); } catch (error) { - log$19.error("Error adding jettons from emulation metadata", { + log$21.error("Error adding jettons from emulation metadata", { error, network }); @@ -33641,11 +33691,11 @@ var init_JettonsManager = __esmMin((() => { if (network) { for (const key of this.cache.keys()) if (key.startsWith(`${network.chainId}:`)) this.cache.delete(key); this.addTonToCache(network); - log$19.info("Jetton cache cleared for network", { network }); + log$21.info("Jetton cache cleared for network", { network }); } else { this.cache.clear(); for (const net of this.networkManager.getConfiguredNetworks()) this.addTonToCache(net); - log$19.info("Jetton cache cleared for all networks"); + log$21.info("Jetton cache cleared for all networks"); } } }; @@ -33661,7 +33711,7 @@ var init_SwapProvider = __esmMin((() => { //#endregion //#region ../walletkit/dist/esm/defi/errors.js var DefiErrorCode, DefiError; -var init_errors$2 = __esmMin((() => { +var init_errors$3 = __esmMin((() => { (function(DefiErrorCode) { DefiErrorCode["ProviderNotFound"] = "PROVIDER_NOT_FOUND"; DefiErrorCode["NoDefaultProvider"] = "NO_DEFAULT_PROVIDER"; @@ -33684,8 +33734,8 @@ var init_errors$2 = __esmMin((() => { //#endregion //#region ../walletkit/dist/esm/defi/swap/errors.js var SwapErrorCode, SwapError; -var init_errors$1 = __esmMin((() => { - init_errors$2(); +var init_errors$2 = __esmMin((() => { + init_errors$3(); (function(SwapErrorCode) { SwapErrorCode["InvalidQuote"] = "INVALID_QUOTE"; SwapErrorCode["InsufficientLiquidity"] = "INSUFFICIENT_LIQUIDITY"; @@ -33707,7 +33757,7 @@ var init_errors$1 = __esmMin((() => { var DefiManager; var init_DefiManager = __esmMin((() => { init_types$2(); - init_errors$2(); + init_errors$3(); DefiManager = class { createFactoryContext; providers = []; @@ -33805,12 +33855,12 @@ var init_DefiManager = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/defi/swap/SwapManager.js -var log$18, SwapManager; +var log$20, SwapManager; var init_SwapManager = __esmMin((() => { - init_errors$1(); + init_errors$2(); init_Logger(); init_DefiManager(); - log$18 = globalLogger.createChild("SwapManager"); + log$20 = globalLogger.createChild("SwapManager"); SwapManager = class extends DefiManager { constructor(createFactoryContext) { super(createFactoryContext); @@ -33822,7 +33872,7 @@ var init_SwapManager = __esmMin((() => { * @returns Promise resolving to swap quote */ async getQuote(params, providerId) { - log$18.debug("Getting swap quote", { + log$20.debug("Getting swap quote", { fromToken: params.from, toToken: params.to, amount: params.amount, @@ -33831,14 +33881,14 @@ var init_SwapManager = __esmMin((() => { }); try { const quote = await this.getProvider(providerId || this.defaultProviderId).getQuote(params); - log$18.debug("Received swap quote", { + log$20.debug("Received swap quote", { fromAmount: quote.fromAmount, toAmount: quote.toAmount, priceImpact: quote.priceImpact }); return quote; } catch (error) { - log$18.error("Failed to get swap quote", { + log$20.error("Failed to get swap quote", { error, params }); @@ -33852,16 +33902,16 @@ var init_SwapManager = __esmMin((() => { */ async buildSwapTransaction(params) { const providerId = params.quote.providerId || this.defaultProviderId; - log$18.debug("Building swap transaction", { + log$20.debug("Building swap transaction", { providerId, userAddress: params.userAddress }); try { const transaction = await this.getProvider(providerId).buildSwapTransaction(params); - log$18.debug("Built swap transaction", params.quote); + log$20.debug("Built swap transaction", params.quote); return transaction; } catch (error) { - log$18.error("Failed to build swap transaction", { + log$20.error("Failed to build swap transaction", { error, params }); @@ -33878,7 +33928,7 @@ var init_SwapManager = __esmMin((() => { var init_swap = __esmMin((() => { init_SwapProvider(); init_SwapManager(); - init_errors$1(); + init_errors$2(); })); //#endregion //#region ../walletkit/dist/esm/defi/staking/StakingProvider.js @@ -33895,8 +33945,8 @@ var init_StakingProvider = __esmMin((() => { //#endregion //#region ../walletkit/dist/esm/defi/staking/errors.js var StakingErrorCode, StakingError; -var init_errors = __esmMin((() => { - init_errors$2(); +var init_errors$1 = __esmMin((() => { + init_errors$3(); (function(StakingErrorCode) { StakingErrorCode["InvalidParams"] = "INVALID_PARAMS"; StakingErrorCode["UnsupportedOperation"] = "UNSUPPORTED_OPERATION"; @@ -33912,12 +33962,12 @@ var init_errors = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/defi/staking/StakingManager.js -var log$17, StakingManager; +var log$19, StakingManager; var init_StakingManager = __esmMin((() => { - init_errors(); + init_errors$1(); init_Logger(); init_DefiManager(); - log$17 = globalLogger.createChild("StakingManager"); + log$19 = globalLogger.createChild("StakingManager"); StakingManager = class extends DefiManager { constructor(createFactoryContext) { super(createFactoryContext); @@ -33928,13 +33978,13 @@ var init_StakingManager = __esmMin((() => { * @param providerId - Optional provider id to use */ async getQuote(params, providerId) { - log$17.debug("Getting staking quote", params); + log$19.debug("Getting staking quote", params); try { const quote = await this.getProvider(providerId).getQuote(params); - log$17.debug("Received staking quote", quote); + log$19.debug("Received staking quote", quote); return quote; } catch (error) { - log$17.error("Failed to get staking quote", { + log$19.error("Failed to get staking quote", { error, params }); @@ -33947,11 +33997,11 @@ var init_StakingManager = __esmMin((() => { * @param providerId - Optional provider id to use */ async buildStakeTransaction(params, providerId) { - log$17.debug("Building staking transaction", params); + log$19.debug("Building staking transaction", params); try { return await this.getProvider(providerId).buildStakeTransaction(params); } catch (error) { - log$17.error("Failed to build staking transaction", { + log$19.error("Failed to build staking transaction", { error, params }); @@ -33965,7 +34015,7 @@ var init_StakingManager = __esmMin((() => { * @param providerId - Optional provider id to use */ async getStakedBalance(userAddress, network, providerId) { - log$17.debug("Getting staking balance", { + log$19.debug("Getting staking balance", { userAddress, network, provider: providerId || this.defaultProviderId @@ -33973,7 +34023,7 @@ var init_StakingManager = __esmMin((() => { try { return await this.getProvider(providerId).getStakedBalance(userAddress, network); } catch (error) { - log$17.error("Failed to get staking balance", { + log$19.error("Failed to get staking balance", { error, userAddress, network @@ -33987,14 +34037,14 @@ var init_StakingManager = __esmMin((() => { * @param providerId - Optional provider id to use */ async getStakingProviderInfo(network, providerId) { - log$17.debug("Getting staking info", { + log$19.debug("Getting staking info", { network, provider: providerId || this.defaultProviderId }); try { return await this.getProvider(providerId).getStakingProviderInfo(network); } catch (error) { - log$17.error("Failed to get staking info", { + log$19.error("Failed to get staking info", { error, network }); @@ -34007,14 +34057,14 @@ var init_StakingManager = __esmMin((() => { * @param providerId - Optional provider id to use */ getStakingProviderMetadata(network, providerId) { - log$17.debug("Getting staking metadata", { + log$19.debug("Getting staking metadata", { network, provider: providerId || this.defaultProviderId }); try { return this.getProvider(providerId).getStakingProviderMetadata(network); } catch (error) { - log$17.error("Failed to get staking metadata", { + log$19.error("Failed to get staking metadata", { error, network }); @@ -34023,7 +34073,7 @@ var init_StakingManager = __esmMin((() => { } createError(message, code, details) { const errorCode = Object.values(StakingErrorCode).includes(code) ? code : StakingErrorCode.InvalidParams; - log$17.error(message, { + log$19.error(message, { code, details }); @@ -34036,14 +34086,140 @@ var init_StakingManager = __esmMin((() => { var init_staking = __esmMin((() => { init_StakingProvider(); init_StakingManager(); + init_errors$1(); +})); +//#endregion +//#region ../walletkit/dist/esm/defi/gasless/GaslessProvider.js +var GaslessProvider; +var init_GaslessProvider = __esmMin((() => { + GaslessProvider = class { + type = "gasless"; + }; +})); +//#endregion +//#region ../walletkit/dist/esm/defi/gasless/errors.js +var GaslessErrorCode, GaslessError; +var init_errors = __esmMin((() => { + init_errors$3(); + (function(GaslessErrorCode) { + GaslessErrorCode["UnsupportedFeeAsset"] = "UNSUPPORTED_FEE_ASSET"; + GaslessErrorCode["UnsupportedOperation"] = "UNSUPPORTED_OPERATION"; + GaslessErrorCode["QuoteFailed"] = "QUOTE_FAILED"; + GaslessErrorCode["SendFailed"] = "SEND_FAILED"; + GaslessErrorCode["ConfigFailed"] = "CONFIG_FAILED"; + GaslessErrorCode["SignMessageNotSupported"] = "SIGN_MESSAGE_NOT_SUPPORTED"; + GaslessErrorCode["TooManyMessages"] = "TOO_MANY_MESSAGES"; + GaslessErrorCode["QuoteExpired"] = "QUOTE_EXPIRED"; + GaslessErrorCode["WalletMismatch"] = "WALLET_MISMATCH"; + GaslessErrorCode["FeeAssetNotOwned"] = "FEE_ASSET_NOT_OWNED"; + })(GaslessErrorCode || (GaslessErrorCode = {})); + GaslessError = class extends DefiError { + code; + constructor(message, code, details) { + super(message, code, details); + this.name = "GaslessError"; + this.code = code; + } + }; +})); +//#endregion +//#region ../walletkit/dist/esm/defi/gasless/GaslessManager.js +var log$18, GaslessManager; +var init_GaslessManager = __esmMin((() => { + init_Logger(); + init_DefiManager(); + init_errors(); + log$18 = globalLogger.createChild("GaslessManager"); + GaslessManager = class extends DefiManager { + constructor(createFactoryContext) { + super(createFactoryContext); + } + /** + * Get static metadata for a gasless provider (display name, logo, url). + */ + async getMetadata(providerId) { + const selectedProviderId = providerId ?? this.defaultProviderId; + log$18.debug("Getting gasless provider metadata", { providerId: selectedProviderId }); + try { + return await this.getProvider(selectedProviderId).getMetadata(); + } catch (error) { + log$18.error("Failed to get gasless provider metadata", { error }); + throw error; + } + } + /** + * Fetch the relayer's configuration (relay address + accepted fee assets). + * + * `network` defaults to the provider's first supported network. + */ + async getConfig(network, providerId) { + const provider = this.getProvider(providerId ?? this.defaultProviderId); + const targetNetwork = network ?? provider.getSupportedNetworks()[0]; + log$18.debug("Getting gasless config", { + network: targetNetwork?.chainId, + providerId: providerId ?? this.defaultProviderId + }); + try { + return await provider.getConfig(targetNetwork); + } catch (error) { + log$18.error("Failed to get gasless config", { error }); + throw error; + } + } + /** + * Quote fees and obtain relayer-wrapped messages for signing. + */ + async getQuote(params, providerId) { + log$18.debug("Quoting gasless transaction", { + network: params.network.chainId, + walletAddress: params.walletAddress, + feeAsset: params.feeAsset, + messagesCount: params.messages.length, + providerId: providerId ?? this.defaultProviderId + }); + try { + return await this.getProvider(providerId ?? this.defaultProviderId).getQuote(params); + } catch (error) { + log$18.error("Failed to quote gasless transaction", { + error, + params + }); + throw error; + } + } + /** + * Submit a signed transaction BoC to the relayer. + */ + async sendTransaction(params, providerId) { + log$18.debug("Sending gasless transaction", { + network: params.network.chainId, + providerId: providerId ?? this.defaultProviderId + }); + try { + return await this.getProvider(providerId ?? this.defaultProviderId).sendTransaction(params); + } catch (error) { + log$18.error("Failed to send gasless transaction", { error }); + throw error; + } + } + createError(message, code, details) { + return new GaslessError(message, code, details); + } + }; +})); +//#endregion +//#region ../walletkit/dist/esm/defi/gasless/index.js +var init_gasless = __esmMin((() => { + init_GaslessProvider(); + init_GaslessManager(); init_errors(); })); //#endregion //#region ../walletkit/dist/esm/core/EventEmitter.js -var log$16, EventEmitter; +var log$17, EventEmitter; var init_EventEmitter = __esmMin((() => { init_Logger(); - log$16 = globalLogger.createChild("EventEmitter"); + log$17 = globalLogger.createChild("EventEmitter"); EventEmitter = class { listeners = {}; /** @@ -34054,7 +34230,7 @@ var init_EventEmitter = __esmMin((() => { const eventListeners = this.listeners[eventName]; if (!eventListeners) this.listeners[eventName] = new Set([listener]); else eventListeners.add(listener); - log$16.debug("Event listener added", { + log$17.debug("Event listener added", { eventName: String(eventName), totalListeners: this.listeners[eventName]?.size }); @@ -34098,10 +34274,10 @@ var init_EventEmitter = __esmMin((() => { removeAllListeners(eventName) { if (eventName) { delete this.listeners[eventName]; - log$16.debug("All listeners removed for event", { eventName: String(eventName) }); + log$17.debug("All listeners removed for event", { eventName: String(eventName) }); } else { this.listeners = {}; - log$16.debug("All event listeners cleared"); + log$17.debug("All event listeners cleared"); } } /** @@ -34120,12 +34296,12 @@ var init_EventEmitter = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/streaming/StreamingManager.js -var log$15, StreamingManager; +var log$16, StreamingManager; var init_StreamingManager = __esmMin((() => { init_Logger(); init_utils$2(); init_factory$2(); - log$15 = globalLogger.createChild("StreamingManager"); + log$16 = globalLogger.createChild("StreamingManager"); StreamingManager = class { createFactoryContext; providers = /* @__PURE__ */ new Map(); @@ -34141,7 +34317,7 @@ var init_StreamingManager = __esmMin((() => { const provider = resolveProvider(input, this.createFactoryContext()); const networkId = String(provider.network.chainId); if (this.providers.has(networkId)) { - log$15.warn(`Provider for network ${networkId} is already registered. Overriding.`); + log$16.warn(`Provider for network ${networkId} is already registered. Overriding.`); this.providerConnectionUnsubs.get(networkId)?.(); this.providers.get(networkId)?.disconnect(); } @@ -34392,13 +34568,13 @@ function pascalToKebab(value) { var init_utils$1 = __esmMin((() => {})); //#endregion //#region ../walletkit/dist/esm/analytics/AnalyticsManager.js -var log$14, AnalyticsManager; +var log$15, AnalyticsManager; var init_AnalyticsManager = __esmMin((() => { init_Logger(); init_swagger(); init_utils$1(); init_utils$2(); - log$14 = globalLogger.createChild("AnalyticsManager"); + log$15 = globalLogger.createChild("AnalyticsManager"); AnalyticsManager = class AnalyticsManager { api; baseEvent; @@ -34462,12 +34638,12 @@ var init_AnalyticsManager = __esmMin((() => { }; if (this.appInfo?.getLocale) enhancedEvent.locale = this.appInfo.getLocale(); if (this.appInfo?.getCurrentUserId) enhancedEvent.user_id = this.appInfo.getCurrentUserId(); - log$14.debug("Analytics event emitted", { event: enhancedEvent }); + log$15.debug("Analytics event emitted", { event: enhancedEvent }); this.events.push(enhancedEvent); if (this.events.length > this.maxQueueSize) { const removed = this.events.length - this.maxQueueSize; this.events = this.events.slice(removed); - log$14.warn("Analytics queue overflow, dropped oldest events", { count: removed }); + log$15.warn("Analytics queue overflow, dropped oldest events", { count: removed }); } if (this.events.length >= this.maxBatchSize) { this.flush(); @@ -34488,10 +34664,10 @@ var init_AnalyticsManager = __esmMin((() => { const eventsToSend = this.extractEventsToSend(); try { await this.processEventsBatch(eventsToSend); - log$14.debug("Analytics events sent successfully"); + log$15.debug("Analytics events sent successfully"); } catch (error) { this.restoreEvents(eventsToSend); - log$14.error("Failed to send analytics events", { error }); + log$15.error("Failed to send analytics events", { error }); } finally { this.isProcessing = false; this.scheduleNextFlushIfNeeded(); @@ -34509,7 +34685,7 @@ var init_AnalyticsManager = __esmMin((() => { return eventsToSend; } async processEventsBatch(eventsToSend) { - log$14.debug("Sending analytics events", { count: eventsToSend.length }); + log$15.debug("Sending analytics events", { count: eventsToSend.length }); try { const response = await this.sendEvents(eventsToSend); this.handleResponse(response); @@ -34531,7 +34707,7 @@ var init_AnalyticsManager = __esmMin((() => { if (this.events.length > this.maxQueueSize) { const removed = this.events.length - this.maxQueueSize; this.events = this.events.slice(0, this.maxQueueSize); - log$14.warn("Analytics queue overflow after restore, dropped oldest events", { count: removed }); + log$15.warn("Analytics queue overflow after restore, dropped oldest events", { count: removed }); } } scheduleNextFlushIfNeeded() { @@ -34550,7 +34726,7 @@ var init_AnalyticsManager = __esmMin((() => { return status === AnalyticsManager.HTTP_STATUS.TOO_MANY_REQUESTS; } handleClientError(status, statusText) { - log$14.error("Analytics API client error", { + log$15.error("Analytics API client error", { status, statusText }); @@ -35350,7 +35526,7 @@ var init_BaseApiClient = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/clients/toncenter/ApiClientToncenter.js -var import_dist$13, log$13, MAX_ACCOUNT_STATES_BATCH$1, ApiClientToncenter; +var import_dist$13, log$14, MAX_ACCOUNT_STATES_BATCH$1, ApiClientToncenter; var init_ApiClientToncenter = __esmMin((() => { import_dist$13 = require_dist$1(); init_base64(); @@ -35369,7 +35545,7 @@ var init_ApiClientToncenter = __esmMin((() => { init_utils(); init_TonClientError(); init_utils$2(); - log$13 = globalLogger.createChild("ApiClientToncenter"); + log$14 = globalLogger.createChild("ApiClientToncenter"); MAX_ACCOUNT_STATES_BATCH$1 = 100; ApiClientToncenter = class extends BaseApiClient { constructor(config = {}) { @@ -35517,7 +35693,7 @@ var init_ApiClientToncenter = __esmMin((() => { const fulfilledResult = results.find((result) => result.status === "fulfilled"); if (fulfilledResult) return fulfilledResult.value; results.forEach((result) => { - if (result.status === "rejected") log$13.error("Error fetching trace", { error: result.reason }); + if (result.status === "rejected") log$14.error("Error fetching trace", { error: result.reason }); }); throw new Error("Failed to fetch trace"); } @@ -35528,7 +35704,7 @@ var init_ApiClientToncenter = __esmMin((() => { }, void 0, void 0, (err) => err instanceof TonClientError ? err.status !== 422 : true); if (response?.traces?.length > 0) return response; } catch (error) { - log$13.error("Error fetching pending trace", { error }); + log$14.error("Error fetching pending trace", { error }); } throw new Error("Failed to fetch pending trace"); } @@ -35657,13 +35833,13 @@ var init_toncenter$1 = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/core/NetworkManager.js -var log$12, KitNetworkManager; +var log$13, KitNetworkManager; var init_NetworkManager = __esmMin((() => { init_toncenter$1(); init_Logger(); - init_errors$3(); + init_errors$4(); init_models(); - log$12 = globalLogger.createChild("NetworkManager"); + log$13 = globalLogger.createChild("NetworkManager"); KitNetworkManager = class { clients = /* @__PURE__ */ new Map(); constructor(options) { @@ -35676,7 +35852,7 @@ var init_NetworkManager = __esmMin((() => { initializeClients(options) { const networks = options.networks; if (!networks) { - log$12.warn("No networks configured in TonWalletKitOptions"); + log$13.warn("No networks configured in TonWalletKitOptions"); return; } for (const [chainId, networkConfig] of Object.entries(networks)) { @@ -35684,7 +35860,7 @@ var init_NetworkManager = __esmMin((() => { if (!networkConfig) continue; const client = this.createClient(network, networkConfig.apiClient, options); this.clients.set(network.chainId, client); - log$12.info("Initialized network client", { chainId }); + log$13.info("Initialized network client", { chainId }); } } /** @@ -35740,7 +35916,7 @@ var init_NetworkManager = __esmMin((() => { */ setClient(network, client) { this.clients.set(network.chainId, client); - log$12.info("Added/updated network client", { network }); + log$13.info("Added/updated network client", { network }); } }; })); @@ -35754,7 +35930,7 @@ function parseEmbeddedRequestFromReqParam(reqParam) { try { return toEmbeddedRequest(decodeEmbeddedRequestParam(reqParam)); } catch (error) { - log$11.warn("Failed to parse embedded request req parameter", { error }); + log$12.warn("Failed to parse embedded request req parameter", { error }); return; } } @@ -35780,20 +35956,20 @@ function toEmbeddedRequest(parsed) { }; } default: - log$11.warn("Unknown embedded request method", { method: parsed.method }); + log$12.warn("Unknown embedded request method", { method: parsed.method }); return; } } -var log$11; +var log$12; var init_embeddedRequest = __esmMin((() => { init_esm$2(); init_internal(); init_Logger(); - log$11 = globalLogger.createChild("embeddedRequestParser"); + log$12 = globalLogger.createChild("embeddedRequestParser"); })); //#endregion //#region ../walletkit/dist/esm/core/TonWalletKit.js -var import_dist$12, log$10, TonWalletKit$1; +var import_dist$12, log$11, TonWalletKit$1; var init_TonWalletKit = __esmMin((() => { import_dist$12 = require_dist$1(); init_esm$2(); @@ -35803,17 +35979,18 @@ var init_TonWalletKit = __esmMin((() => { init_ConnectHandler(); init_swap(); init_staking(); + init_gasless(); init_internal(); init_EventEmitter(); init_StreamingManager(); init_analytics(); init_getDefaultWalletConfig(); - init_errors$3(); + init_errors$4(); init_retry(); init_NetworkManager(); init_utils$2(); init_embeddedRequest(); - log$10 = globalLogger.createChild("TonWalletKit"); + log$11 = globalLogger.createChild("TonWalletKit"); TonWalletKit$1 = class { walletManager; sessionManager; @@ -35824,6 +36001,7 @@ var init_TonWalletKit = __esmMin((() => { swapManager; streamingManager; stakingManager; + gaslessManager; initializer; eventProcessor; bridgeManager; @@ -35850,9 +36028,10 @@ var init_TonWalletKit = __esmMin((() => { this.jettonsManager = new JettonsManager(1e4, this.eventEmitter, this.networkManager); this.swapManager = new SwapManager(() => this.createFactoryContext()); this.stakingManager = new StakingManager(() => this.createFactoryContext()); + this.gaslessManager = new GaslessManager(() => this.createFactoryContext()); this.eventEmitter.on("restoreConnection", async ({ payload: event }) => { if (!event.domain) { - log$10.error("Domain is required for restore connection"); + log$11.error("Domain is required for restore connection"); return this.sendErrorConnectResponse(event); } const sessions = await this.sessionManager.getSessions({ @@ -35862,12 +36041,12 @@ var init_TonWalletKit = __esmMin((() => { }); const session = sessions.length > 0 ? sessions[0] : void 0; if (!session) { - log$10.error("Session not found for domain", { domain: event.domain }); + log$11.error("Session not found for domain", { domain: event.domain }); return this.sendErrorConnectResponse(event); } const wallet = session.walletId ? this.walletManager?.getWallet(session.walletId) : void 0; if (!wallet) { - log$10.error("Wallet not found for session", { walletId: session.walletId }); + log$11.error("Wallet not found for session", { walletId: session.walletId }); return this.sendErrorConnectResponse(event); } const walletAddress = wallet.getAddress(); @@ -35921,7 +36100,7 @@ var init_TonWalletKit = __esmMin((() => { await this.eventProcessor.startProcessing(); this.isInitialized = true; } catch (error) { - log$10.error("TonWalletKit initialization failed", { error: error?.toString() }); + log$11.error("TonWalletKit initialization failed", { error: error?.toString() }); throw error; } } @@ -35951,7 +36130,7 @@ var init_TonWalletKit = __esmMin((() => { const walletId = wallet.getWalletId(); await this.eventProcessor.startProcessing(walletId); } catch (error) { - log$10.error("Failed to start event processing for wallet", { + log$11.error("Failed to start event processing for wallet", { walletAddress: wallet.getAddress(), error }); @@ -35971,7 +36150,7 @@ var init_TonWalletKit = __esmMin((() => { } getWallets() { if (!this.isInitialized) { - log$10.warn("TonWalletKit not yet initialized, returning empty array"); + log$11.warn("TonWalletKit not yet initialized, returning empty array"); return []; } return this.walletManager.getWallets(); @@ -35981,7 +36160,7 @@ var init_TonWalletKit = __esmMin((() => { */ getWallet(walletId) { if (!this.isInitialized) { - log$10.warn("TonWalletKit not yet initialized, returning undefined"); + log$11.warn("TonWalletKit not yet initialized, returning undefined"); return; } return this.walletManager.getWallet(walletId); @@ -36041,7 +36220,7 @@ var init_TonWalletKit = __esmMin((() => { payload: {} }, sessionCrypto), 10, 100); } catch (error) { - log$10.error("Failed to send disconnect to bridge", { + log$11.error("Failed to send disconnect to bridge", { sessionId, error }); @@ -36051,7 +36230,7 @@ var init_TonWalletKit = __esmMin((() => { if (sessionId) try { await removeSession(sessionId); } catch (error) { - log$10.error("Failed to remove session", { + log$11.error("Failed to remove session", { sessionId, error }); @@ -36061,7 +36240,7 @@ var init_TonWalletKit = __esmMin((() => { if (sessions.length > 0) for (const session of sessions) try { await removeSession(session.sessionId); } catch (error) { - log$10.error("Failed to remove session", { + log$11.error("Failed to remove session", { sessionId: session.sessionId, error }); @@ -36135,7 +36314,7 @@ var init_TonWalletKit = __esmMin((() => { const bridgeEvent = this.parseBridgeConnectEventFromUrl(url); return await new ConnectHandler(() => {}, this.config, this.analyticsManager).handle(bridgeEvent); } catch (error) { - log$10.error("Failed to create connection event from URL", { + log$11.error("Failed to create connection event from URL", { error, url }); @@ -36152,7 +36331,7 @@ var init_TonWalletKit = __esmMin((() => { const bridgeEvent = this.parseBridgeConnectEventFromUrl(url); await this.eventRouter.routeEvent(bridgeEvent); } catch (error) { - log$10.error("Failed to handle TON Connect URL", { + log$11.error("Failed to handle TON Connect URL", { error, url }); @@ -36196,7 +36375,7 @@ var init_TonWalletKit = __esmMin((() => { const params = {}; for (const [key, value] of parsedUrl.searchParams.entries()) params[key] = value; if (!params.v || !params.id || !params.r) { - log$10.warn("Missing required TON Connect URL parameters"); + log$11.warn("Missing required TON Connect URL parameters"); return null; } return { @@ -36208,7 +36387,7 @@ var init_TonWalletKit = __esmMin((() => { ...params }; } catch (error) { - log$10.error("Failed to parse TON Connect URL", { + log$11.error("Failed to parse TON Connect URL", { error, url }); @@ -36235,7 +36414,7 @@ var init_TonWalletKit = __esmMin((() => { domain: "" }; if (params.e) if (this.config.deviceInfo?.features.some((feature) => typeof feature === "object" && feature.name === "EmbeddedRequest")) bridgeEvent.embeddedRequest = parseEmbeddedRequestFromReqParam(params.e); - else log$10.warn("Embedded request feature is not supported in features, but we received request with embedded request payload", { features: this.config.deviceInfo?.features }); + else log$11.warn("Embedded request feature is not supported in features, but we received request with embedded request payload", { features: this.config.deviceInfo?.features }); return bridgeEvent; } async approveConnectRequest(event, response) { @@ -36352,6 +36531,12 @@ var init_TonWalletKit = __esmMin((() => { return this.stakingManager; } /** + * Gasless API access + */ + get gasless() { + return this.gaslessManager; + } + /** * Get the event emitter for this kit instance * Allows external components to listen to and emit events */ @@ -36559,9 +36744,9 @@ var init_map_nft_items = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/clients/tonapi/mappers/map-methods.js -var hexBocToBase64, decimalToInt257Hex, mapTonApiGetMethodArgs, mapTonApiTvmStackRecord; +var hexBocToBase64$1, decimalToInt257Hex, mapTonApiGetMethodArgs, mapTonApiTvmStackRecord; var init_map_methods = __esmMin((() => { - hexBocToBase64 = (hex) => { + hexBocToBase64$1 = (hex) => { return Buffer.from(hex, "hex").toString("base64"); }; decimalToInt257Hex = (value) => { @@ -36622,11 +36807,11 @@ var init_map_methods = __esmMin((() => { }; case "cell": return { type: "cell", - value: hexBocToBase64(item.cell) + value: hexBocToBase64$1(item.cell) }; case "slice": return { type: "slice", - value: hexBocToBase64(item.slice || item.cell) + value: hexBocToBase64$1(item.slice || item.cell) }; case "tuple": return { type: "tuple", @@ -37213,7 +37398,7 @@ var init_map_masterchain_info = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/clients/tonapi/ApiClientTonApi.js -var import_dist$10, log$9, MAX_ACCOUNT_STATES_BATCH, ApiClientTonApi; +var import_dist$10, log$10, MAX_ACCOUNT_STATES_BATCH, ApiClientTonApi; var init_ApiClientTonApi = __esmMin((() => { import_dist$10 = require_dist$1(); init_models(); @@ -37232,7 +37417,7 @@ var init_ApiClientTonApi = __esmMin((() => { init_map_traces(); init_map_events(); init_map_masterchain_info(); - log$9 = globalLogger.createChild("ApiClientTonApi"); + log$10 = globalLogger.createChild("ApiClientTonApi"); MAX_ACCOUNT_STATES_BATCH = 100; ApiClientTonApi = class extends BaseApiClient { constructor(config = {}) { @@ -37254,7 +37439,7 @@ var init_ApiClientTonApi = __esmMin((() => { return this.network; } async getAccountState(address, seqno) { - if (typeof seqno === "number") log$9.warn(`getAccountState: seqno=${seqno} is ignored — TonApi /v2/accounts endpoint does not support historical state queries.`); + if (typeof seqno === "number") log$10.warn(`getAccountState: seqno=${seqno} is ignored — TonApi /v2/accounts endpoint does not support historical state queries.`); try { return mapAccountState(await this.getJson(`/v2/blockchain/accounts/${address}`), address); } catch (e) { @@ -37563,14 +37748,14 @@ var init_actions = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/contracts/w5/WalletV5R1Adapter.js -var import_dist$6, import_dist$7, log$8, defaultWalletIdV5R1, WalletV5R1Adapter$1; +var import_dist$6, import_dist$7, log$9, defaultWalletIdV5R1, WalletV5R1Adapter$1; var init_WalletV5R1Adapter = __esmMin((() => { import_dist$6 = require_dist$1(); import_dist$7 = require_dist$1(); init_WalletV5R1(); init_WalletV5R1_source(); init_Logger(); - init_errors$3(); + init_errors$4(); init_sign$1(); init_address$1(); init_retry(); @@ -37578,7 +37763,7 @@ var init_WalletV5R1Adapter = __esmMin((() => { init_base64(); init_tonProof(); init_walletId(); - log$8 = globalLogger.createChild("WalletV5R1Adapter"); + log$9 = globalLogger.createChild("WalletV5R1Adapter"); defaultWalletIdV5R1 = 2147483409; WalletV5R1Adapter$1 = class WalletV5R1Adapter$1 { signer; @@ -37695,7 +37880,7 @@ var init_WalletV5R1Adapter = __esmMin((() => { try { return await this.walletContract.seqno; } catch (error) { - log$8.warn("Failed to get seqno", { error }); + log$9.warn("Failed to get seqno", { error }); throw error; } } @@ -37706,7 +37891,7 @@ var init_WalletV5R1Adapter = __esmMin((() => { try { return this.walletContract.walletId; } catch (error) { - log$8.warn("Failed to get wallet ID", { error }); + log$9.warn("Failed to get wallet ID", { error }); const walletId = this.config.walletId; return new WalletV5R1Id({ subwalletNumber: typeof walletId === "bigint" ? Number(walletId) : walletId || 0 }); } @@ -37718,7 +37903,7 @@ var init_WalletV5R1Adapter = __esmMin((() => { try { return (await this.client.getAccountState(asAddressFriendly(this.walletContract.address))).status === "active"; } catch (error) { - log$8.warn("Failed to check deployment status", { error }); + log$9.warn("Failed to check deployment status", { error }); return false; } } @@ -37750,13 +37935,13 @@ var init_WalletV5R1Adapter = __esmMin((() => { if (message.payload) try { msg.body = import_dist$6.Cell.fromBase64(message.payload); } catch (error) { - log$8.warn("Failed to load payload", { error }); + log$9.warn("Failed to load payload", { error }); throw WalletKitError.fromError(ERROR_CODES.CONTRACT_VALIDATION_FAILED, "Failed to parse transaction payload", error); } if (message.stateInit) try { msg.init = (0, import_dist$6.loadStateInit)(import_dist$6.Cell.fromBase64(message.stateInit).asSlice()); } catch (error) { - log$8.warn("Failed to load state init", { error }); + log$9.warn("Failed to load state init", { error }); throw WalletKitError.fromError(ERROR_CODES.CONTRACT_VALIDATION_FAILED, "Failed to parse state init", error); } return new ActionSendMsg(import_dist$6.SendMode.PAY_GAS_SEPARATELY + import_dist$6.SendMode.IGNORE_ERRORS, msg); @@ -37777,7 +37962,7 @@ var init_WalletV5R1Adapter = __esmMin((() => { auth_signed_internal: 1936289396 }; const opcode = options.authType === "internal" ? Opcodes.auth_signed_internal : Opcodes.auth_signed; - log$8.debug("createBodyV5 signing with opcode", { + log$9.debug("createBodyV5 signing with opcode", { authType: options.authType, opcode: `0x${opcode.toString(16)}` }); @@ -37836,14 +38021,14 @@ var init_WalletV5R1Adapter = __esmMin((() => { function walletV5ConfigToCell(config) { return (0, import_dist$5.beginCell)().storeBit(config.signatureAllowed).storeUint(config.seqno, 32).storeUint(config.walletId, 32).storeUint(config.publicKey, 256).storeDict(config.extensions, import_dist$5.Dictionary.Keys.BigUint(256), import_dist$5.Dictionary.Values.BigInt(1)).endCell(); } -var import_dist$5, log$7, Opcodes, WalletV5R1Id, WalletV5; +var import_dist$5, log$8, Opcodes, WalletV5R1Id, WalletV5; var init_WalletV5R1 = __esmMin((() => { import_dist$5 = require_dist$1(); init_WalletV5R1Adapter(); init_tvmStack(); init_utils$2(); init_Logger(); - log$7 = globalLogger.createChild("WalletV5R1"); + log$8 = globalLogger.createChild("WalletV5R1"); Opcodes = { action_send_msg: 247711853, action_set_code: 2907562126, @@ -37940,7 +38125,7 @@ var init_WalletV5R1 = __esmMin((() => { if (dataCell.bits.length < 33) return 0; return dataCell.asSlice().skip(1).loadUint(32); } catch (error) { - log$7.error("Failed to get seqno", { error }); + log$8.error("Failed to get seqno", { error }); return 0; } }); @@ -37971,12 +38156,12 @@ var init_WalletV5R1 = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/contracts/v4r2/WalletV4R2.js -var import_dist$4, log$6, WalletV4R2; +var import_dist$4, log$7, WalletV4R2; var init_WalletV4R2 = __esmMin((() => { import_dist$4 = require_dist$1(); init_tvmStack(); init_utils$2(); - log$6 = { error: (_message, _data) => {} }; + log$7 = { error: (_message, _data) => {} }; WalletV4R2 = class WalletV4R2 { address; init; @@ -38028,7 +38213,7 @@ var init_WalletV4R2 = __esmMin((() => { if (parsedStack[0]?.type === "int") return Number(parsedStack[0].value); else throw new Error("Stack is not an int"); } catch (error) { - log$6.error("Failed to get seqno", { error }); + log$7.error("Failed to get seqno", { error }); return 0; } } @@ -38049,7 +38234,7 @@ var init_WalletV4R2 = __esmMin((() => { if (parsedStack[0]?.type === "int") return Number(parsedStack[0].value); else throw new Error("Stack is not an int"); } catch (error) { - log$6.error("Failed to get subwallet id", { error }); + log$7.error("Failed to get subwallet id", { error }); return this.subwalletId; } } @@ -38090,7 +38275,7 @@ var init_constants = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/contracts/v4r2/WalletV4R2Adapter.js -var import_dist$2, log$5, WalletV4R2Adapter$1; +var import_dist$2, log$6, WalletV4R2Adapter$1; var init_WalletV4R2Adapter = __esmMin((() => { import_dist$2 = require_dist$1(); init_WalletV4R2(); @@ -38103,7 +38288,7 @@ var init_WalletV4R2Adapter = __esmMin((() => { init_Logger(); init_walletId(); init_utils$2(); - log$5 = globalLogger.createChild("WalletV4R2Adapter"); + log$6 = globalLogger.createChild("WalletV4R2Adapter"); WalletV4R2Adapter$1 = class WalletV4R2Adapter$1 { signer; config; @@ -38210,7 +38395,7 @@ var init_WalletV4R2Adapter = __esmMin((() => { }); return (0, import_dist$2.beginCell)().store((0, import_dist$2.storeMessage)(ext)).endCell().toBoc().toString("base64"); } catch (error) { - log$5.warn("Failed to get signed send transaction", { error }); + log$6.warn("Failed to get signed send transaction", { error }); throw error; } } @@ -38237,7 +38422,7 @@ var init_WalletV4R2Adapter = __esmMin((() => { try { return await this.walletContract.getSeqno(); } catch (error) { - log$5.warn("Failed to get seqno", { error }); + log$6.warn("Failed to get seqno", { error }); throw error; } } @@ -38248,7 +38433,7 @@ var init_WalletV4R2Adapter = __esmMin((() => { try { return await this.walletContract.getSubwalletId(); } catch (error) { - log$5.warn("Failed to get subwallet ID", { error }); + log$6.warn("Failed to get subwallet ID", { error }); return this.config.walletId ?? 698983191; } } @@ -38259,7 +38444,7 @@ var init_WalletV4R2Adapter = __esmMin((() => { try { return (await this.client.getAccountState(asAddressFriendly(this.walletContract.address))).status === "active"; } catch (error) { - log$5.warn("Failed to check deployment status", { error }); + log$6.warn("Failed to check deployment status", { error }); return false; } } @@ -38525,11 +38710,11 @@ var init_map_jettons = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/streaming/WebsocketStreamingProvider.js -var log$4, WebsocketStreamingProvider; +var log$5, WebsocketStreamingProvider; var init_WebsocketStreamingProvider = __esmMin((() => { init_Logger(); init_address$1(); - log$4 = globalLogger.createChild("WebsocketStreamingProvider"); + log$5 = globalLogger.createChild("WebsocketStreamingProvider"); WebsocketStreamingProvider = class WebsocketStreamingProvider { type = "streaming"; ws = null; @@ -38622,7 +38807,7 @@ var init_WebsocketStreamingProvider = __esmMin((() => { } this.isConnected = false; if (wasConnected) this.emitConnectionChange(false); - log$4.info("WebsocketStreamingProvider disconnected"); + log$5.info("WebsocketStreamingProvider disconnected"); } checkClose() { if (this.closeCheckTimeout) clearTimeout(this.closeCheckTimeout); @@ -38650,16 +38835,16 @@ var init_WebsocketStreamingProvider = __esmMin((() => { openConnection() { this.stopReconnect(); const url = this.getUrl(); - log$4.info("Connecting to WebSocket", { url: url.replace(/api_key=[^&]+/, "api_key=***") }); + log$5.info("Connecting to WebSocket", { url: url.replace(/api_key=[^&]+/, "api_key=***") }); try { this.ws = new WebSocket(url); } catch (error) { - log$4.error("WebSocket creation failed", { error }); + log$5.error("WebSocket creation failed", { error }); this.scheduleReconnect(); return; } this.ws.onopen = () => { - log$4.info("WebSocket connected"); + log$5.info("WebSocket connected"); this.isConnected = true; this.reconnectAttempts = 0; this.fullResync(); @@ -38668,13 +38853,13 @@ var init_WebsocketStreamingProvider = __esmMin((() => { }; this.ws.onmessage = this.onMessage.bind(this); this.ws.onerror = (error) => { - log$4.error("WebSocket error", { + log$5.error("WebSocket error", { readyState: this.ws?.readyState, error }); }; this.ws.onclose = () => { - log$4.info("WebSocket closed"); + log$5.info("WebSocket closed"); this.isConnected = false; this.stopPing(); this.ws = null; @@ -38709,7 +38894,7 @@ var init_WebsocketStreamingProvider = __esmMin((() => { this.reconnectAttempts++; const delays = WebsocketStreamingProvider.RECONNECT_DELAYS; const delayMs = delays[Math.min(this.reconnectAttempts - 1, delays.length - 1)]; - log$4.info(`Scheduling reconnect in ${delayMs}ms (attempt ${this.reconnectAttempts})`); + log$5.info(`Scheduling reconnect in ${delayMs}ms (attempt ${this.reconnectAttempts})`); this.reconnectTimeout = setTimeout(() => { this.reconnectTimeout = null; this.openConnection(); @@ -38732,7 +38917,7 @@ var init_WebsocketStreamingProvider = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/streaming/TonStreamingV2BaseProvider.js -var log$3, STREAMING_V2_WS_PATH, TonStreamingV2BaseProvider; +var log$4, STREAMING_V2_WS_PATH, TonStreamingV2BaseProvider; var init_TonStreamingV2BaseProvider = __esmMin((() => { init_index_min(); init_Logger(); @@ -38745,7 +38930,7 @@ var init_TonStreamingV2BaseProvider = __esmMin((() => { init_map_transactions(); init_map_jettons(); init_WebsocketStreamingProvider(); - log$3 = globalLogger.createChild("TonStreamingV2"); + log$4 = globalLogger.createChild("TonStreamingV2"); STREAMING_V2_WS_PATH = "/api/streaming/v2/ws"; TonStreamingV2BaseProvider = class extends WebsocketStreamingProvider { providerId; @@ -38787,7 +38972,7 @@ var init_TonStreamingV2BaseProvider = __esmMin((() => { }; } onWatch(type, id) { - log$3.info("onWatch triggered", { + log$4.info("onWatch triggered", { type, id, isConnected: this.isConnected, @@ -38796,7 +38981,7 @@ var init_TonStreamingV2BaseProvider = __esmMin((() => { this.requestSync(); } onUnwatch(type, id) { - log$3.info("onUnwatch triggered", { + log$4.info("onUnwatch triggered", { type, id, isConnected: this.isConnected, @@ -38809,7 +38994,7 @@ var init_TonStreamingV2BaseProvider = __esmMin((() => { clearTimeout(this.syncTimer); this.syncTimer = null; } - log$3.info("fullResync triggered", { + log$4.info("fullResync triggered", { isConnected: this.isConnected, readyState: this.ws?.readyState }); @@ -38832,7 +39017,7 @@ var init_TonStreamingV2BaseProvider = __esmMin((() => { addresses: Array.from(this.lastAddresses) }); this.lastAddresses.clear(); - log$3.info("Cleared all subscriptions", { msgId }); + log$4.info("Cleared all subscriptions", { msgId }); } return; } @@ -38849,7 +39034,7 @@ var init_TonStreamingV2BaseProvider = __esmMin((() => { ...request }); this.lastAddresses = addresses; - log$3.info("Sent monolithic subscription", { + log$4.info("Sent monolithic subscription", { msgId, types: Array.from(types), addressCount: addresses.size @@ -38859,7 +39044,7 @@ var init_TonStreamingV2BaseProvider = __esmMin((() => { try { const msg = JSON.parse(event.data); const m = msg; - log$3.debug("Streaming v2 WS received message:", m); + log$4.debug("Streaming v2 WS received message:", m); if (m.status === "subscribed" || m.status === "pong") return; if (isAccountStateNotification(msg)) { const update = mapBalance(msg); @@ -38867,7 +39052,7 @@ var init_TonStreamingV2BaseProvider = __esmMin((() => { return; } if (isTraceInvalidatedNotification(msg)) { - log$3.debug("Trace invalidated", { hash: msg.trace_external_hash_norm }); + log$4.debug("Trace invalidated", { hash: msg.trace_external_hash_norm }); const entry = this.traceCache.get(msg.trace_external_hash_norm); if (entry) { entry.accounts.forEach((account) => { @@ -38888,7 +39073,7 @@ var init_TonStreamingV2BaseProvider = __esmMin((() => { const finalityScore = this.getFinalityScore(msg.finality); const entry = this.traceCache.get(msg.trace_external_hash_norm); if (entry && finalityScore < entry.score) { - log$3.debug("Ignoring transactions notification due to lower finality", { + log$4.debug("Ignoring transactions notification due to lower finality", { hash: msg.trace_external_hash_norm, msgFinality: msg.finality, cachedScore: entry.score @@ -38917,7 +39102,7 @@ var init_TonStreamingV2BaseProvider = __esmMin((() => { return; } } catch (err) { - log$3.warn("Failed to parse WebSocket message", { error: err }); + log$4.warn("Failed to parse WebSocket message", { error: err }); } } requestSync() { @@ -39064,6 +39249,10 @@ var esm_exports = /* @__PURE__ */ __exportAll({ EventStoreError: () => EventStoreError, ExtensionStorageAdapter: () => ExtensionStorageAdapter, FakeSignature: () => FakeSignature, + GaslessError: () => GaslessError, + GaslessErrorCode: () => GaslessErrorCode, + GaslessManager: () => GaslessManager, + GaslessProvider: () => GaslessProvider, HexToBase64: () => HexToBase64, HexToBigInt: () => HexToBigInt, HexToUint8Array: () => HexToUint8Array, @@ -39098,6 +39287,8 @@ var esm_exports = /* @__PURE__ */ __exportAll({ StorageEventProcessor: () => StorageEventProcessor, StorageEventStore: () => StorageEventStore, StreamingManager: () => StreamingManager, + SupportError: () => SupportError, + SupportErrorCode: () => SupportErrorCode, SwapError: () => SwapError, SwapErrorCode: () => SwapErrorCode, SwapManager: () => SwapManager, @@ -39122,7 +39313,10 @@ var esm_exports = /* @__PURE__ */ __exportAll({ WalletV5R1CodeBoc: () => WalletV5R1CodeBoc, WalletV5R1CodeCell: () => WalletV5R1CodeCell, WalletV5R1Id: () => WalletV5R1Id, + asAddressFriendly: () => asAddressFriendly, + asBase64: () => asBase64, asHex: () => asHex, + checkSignMessageSupport: () => checkSignMessageSupport, compareAddress: () => compareAddress, createCommentPayload: () => createCommentPayload, createCommentPayloadBase64: () => createCommentPayloadBase64, @@ -39167,7 +39361,7 @@ var init_esm = __esmMin((() => { init_esm$2(); init_TonWalletKit(); init_types$2(); - init_errors$3(); + init_errors$4(); init_WalletManager(); init_TONConnectStoredSessionManager(); init_BridgeManager(); @@ -39175,9 +39369,10 @@ var init_esm = __esmMin((() => { init_RequestProcessor(); init_Initializer(); init_JettonsManager(); - init_errors$2(); + init_errors$3(); init_swap(); init_staking(); + init_gasless(); init_EventEmitter(); init_toncenter$1(); init_tonapi$1(); @@ -39209,6 +39404,7 @@ var init_esm = __esmMin((() => { init_withTimeout(); init_validation(); init_getDefaultWalletConfig(); + init_checkSignMessageSupport(); init_Signer(); init_tvmStack(); init_messageTypes(); @@ -40112,6 +40308,12 @@ async function getWalletAddress(args) { async function getWalletNetwork(args) { return wallet(args.walletId, "getNetwork"); } +async function getWalletPublicKey(args) { + return wallet(args.walletId, "getPublicKey"); +} +async function getSignedSignMessage(args) { + return wallet(args.walletId, "getSignedSignMessage", args.request); +} async function removeWallet(args) { return kit("removeWallet", args.walletId); } @@ -40345,7 +40547,7 @@ var getJettonWalletAddress = (args) => walletCall("getJettonWalletAddress", args init_models(); init_units(); var CACHE_TIMEOUT = 3e4; -var DEFAULT_METADATA = { +var DEFAULT_METADATA$1 = { [Network.mainnet().chainId]: { name: "Tonstakers", stakeToken: { @@ -40520,10 +40722,10 @@ var StakingCache = class { init_models(); init_Logger(); init_StakingProvider(); -init_errors(); +init_errors$1(); init_ApiClientTonApi(); init_units(); -var log$2 = globalLogger.createChild("TonStakersStakingProvider"); +var log$3 = globalLogger.createChild("TonStakersStakingProvider"); /** * TonStakersStakingProvider - Staking provider for the Tonstakers liquid staking protocol. * @@ -40549,7 +40751,7 @@ var TonStakersStakingProvider = class TonStakersStakingProvider extends StakingP this.cache = new StakingCache(); this.metadataByNetwork = {}; for (const [chainId, config] of Object.entries(chainConfig)) { - const defaultMetadata = DEFAULT_METADATA[chainId]; + const defaultMetadata = DEFAULT_METADATA$1[chainId]; const overrides = config.metadata ?? {}; const merged = { ...defaultMetadata, @@ -40569,7 +40771,7 @@ var TonStakersStakingProvider = class TonStakersStakingProvider extends StakingP }); this.metadataByNetwork[chainId] = merged; } - log$2.info("TonStakersStakingProvider initialized"); + log$3.info("TonStakersStakingProvider initialized"); } /** * Resolves API clients from {@link ProviderFactoryContext.networkManager} on each call. @@ -40580,7 +40782,7 @@ var TonStakersStakingProvider = class TonStakersStakingProvider extends StakingP for (const network of ctx.networkManager.getConfiguredNetworks()) { const chainId = network.chainId; const perChain = config[chainId] ?? {}; - const hasDefaultContract = !!DEFAULT_METADATA[chainId]?.contractAddress; + const hasDefaultContract = !!DEFAULT_METADATA$1[chainId]?.contractAddress; const hasCustomContract = !!perChain.metadata?.contractAddress; if (!hasDefaultContract && !hasCustomContract) continue; chainConfig[chainId] = perChain; @@ -40595,7 +40797,7 @@ var TonStakersStakingProvider = class TonStakersStakingProvider extends StakingP * @returns Quote with expected amounts and current APY (for stake direction) */ async getQuote(params) { - log$2.debug("TonStakers quote requested", { + log$3.debug("TonStakers quote requested", { direction: params.direction, amount: params.amount, userAddress: params.userAddress, @@ -40662,7 +40864,7 @@ var TonStakersStakingProvider = class TonStakersStakingProvider extends StakingP else return this.buildUnstakeTonTransaction(params); } async buildStakeTonTransaction(params) { - log$2.debug("TonStakers stake requested", { params }); + log$3.debug("TonStakers stake requested", { params }); if (params.quote.direction !== "stake") throw new StakingError("Invalid quote direction", StakingErrorCode.InvalidParams, { quote: params.quote }); const network = params.quote.network; const contractAddress = this.getStakingContractAddress(network); @@ -40687,7 +40889,7 @@ var TonStakersStakingProvider = class TonStakersStakingProvider extends StakingP * @returns Transaction request ready to be signed and sent */ async buildUnstakeTonTransaction(params) { - log$2.debug("TonStakers unstake requested", { + log$3.debug("TonStakers unstake requested", { amount: params.quote.amountIn, userAddress: params.userAddress }); @@ -40733,7 +40935,7 @@ var TonStakersStakingProvider = class TonStakersStakingProvider extends StakingP * @param network - Network to query (defaults to mainnet) */ async getStakedBalance(userAddress, network) { - log$2.debug("TonStakers balance requested", { + log$3.debug("TonStakers balance requested", { userAddress, network }); @@ -40745,12 +40947,12 @@ var TonStakersStakingProvider = class TonStakersStakingProvider extends StakingP try { stakedBalance = await contract.getStakedBalance(userAddress); } catch (error) { - log$2.warn("Failed to get staked balance", { error }); + log$3.warn("Failed to get staked balance", { error }); } try { instantUnstakeAvailable = await contract.getPoolBalance(); } catch (error) { - log$2.warn("Failed to get instant unstake liquidity", { error }); + log$3.warn("Failed to get instant unstake liquidity", { error }); } return { rawStakedBalance: stakedBalance, @@ -40760,7 +40962,7 @@ var TonStakersStakingProvider = class TonStakersStakingProvider extends StakingP providerId: this.providerId }; } catch (error) { - log$2.error("Failed to get balance", { + log$3.error("Failed to get balance", { error, userAddress, network @@ -40781,7 +40983,7 @@ var TonStakersStakingProvider = class TonStakersStakingProvider extends StakingP * @returns Staking info with APY and available instant liquidity */ async getStakingProviderInfo(network) { - log$2.debug("TonStakers info requested", { network }); + log$3.debug("TonStakers info requested", { network }); const targetNetwork = network ?? Network.mainnet(); const cacheKey = `staking-info:${targetNetwork.chainId}`; return await this.cache.get(cacheKey, async () => { @@ -43116,7 +43318,7 @@ function createBaseAddress() { address: "" }; } -var Address$4 = { +var Address$7 = { fromJSON(object) { return { blockchain: isSet$7(object.blockchain) ? globalThis.Number(object.blockchain) : 0, @@ -43130,7 +43332,7 @@ var Address$4 = { return obj; }, create(base) { - return Address$4.fromPartial(base ?? {}); + return Address$7.fromPartial(base ?? {}); }, fromPartial(object) { const message = createBaseAddress(); @@ -43207,15 +43409,15 @@ function createBaseSwapStep() { var SwapStep = { fromJSON(object) { return { - bidAssetAddress: isSet$6(object.bid_asset_address) ? Address$4.fromJSON(object.bid_asset_address) : void 0, - askAssetAddress: isSet$6(object.ask_asset_address) ? Address$4.fromJSON(object.ask_asset_address) : void 0, + bidAssetAddress: isSet$6(object.bid_asset_address) ? Address$7.fromJSON(object.bid_asset_address) : void 0, + askAssetAddress: isSet$6(object.ask_asset_address) ? Address$7.fromJSON(object.ask_asset_address) : void 0, chunks: globalThis.Array.isArray(object?.chunks) ? object.chunks.map((e) => SwapChunk.fromJSON(e)) : [] }; }, toJSON(message) { const obj = {}; - if (message.bidAssetAddress !== void 0) obj.bid_asset_address = Address$4.toJSON(message.bidAssetAddress); - if (message.askAssetAddress !== void 0) obj.ask_asset_address = Address$4.toJSON(message.askAssetAddress); + if (message.bidAssetAddress !== void 0) obj.bid_asset_address = Address$7.toJSON(message.bidAssetAddress); + if (message.askAssetAddress !== void 0) obj.ask_asset_address = Address$7.toJSON(message.askAssetAddress); if (message.chunks?.length) obj.chunks = message.chunks.map((e) => SwapChunk.toJSON(e)); return obj; }, @@ -43224,8 +43426,8 @@ var SwapStep = { }, fromPartial(object) { const message = createBaseSwapStep(); - message.bidAssetAddress = object.bidAssetAddress !== void 0 && object.bidAssetAddress !== null ? Address$4.fromPartial(object.bidAssetAddress) : void 0; - message.askAssetAddress = object.askAssetAddress !== void 0 && object.askAssetAddress !== null ? Address$4.fromPartial(object.askAssetAddress) : void 0; + message.bidAssetAddress = object.bidAssetAddress !== void 0 && object.bidAssetAddress !== null ? Address$7.fromPartial(object.bidAssetAddress) : void 0; + message.askAssetAddress = object.askAssetAddress !== void 0 && object.askAssetAddress !== null ? Address$7.fromPartial(object.askAssetAddress) : void 0; message.chunks = object.chunks?.map((e) => SwapChunk.fromPartial(e)) || []; return message; } @@ -43385,16 +43587,16 @@ function createBaseEscrowSettlementParams() { var EscrowSettlementParams = { fromJSON(object) { return { - contractAddress: isSet$5(object.contract_address) ? Address$4.fromJSON(object.contract_address) : void 0, - resolverAddress: isSet$5(object.resolver_address) ? Address$4.fromJSON(object.resolver_address) : void 0, + contractAddress: isSet$5(object.contract_address) ? Address$7.fromJSON(object.contract_address) : void 0, + resolverAddress: isSet$5(object.resolver_address) ? Address$7.fromJSON(object.resolver_address) : void 0, resolveTimeout: isSet$5(object.resolve_timeout) ? globalThis.Number(object.resolve_timeout) : 0, gasless: isSet$5(object.gasless) ? globalThis.Boolean(object.gasless) : false }; }, toJSON(message) { const obj = {}; - if (message.contractAddress !== void 0) obj.contract_address = Address$4.toJSON(message.contractAddress); - if (message.resolverAddress !== void 0) obj.resolver_address = Address$4.toJSON(message.resolverAddress); + if (message.contractAddress !== void 0) obj.contract_address = Address$7.toJSON(message.contractAddress); + if (message.resolverAddress !== void 0) obj.resolver_address = Address$7.toJSON(message.resolverAddress); if (message.resolveTimeout !== void 0) obj.resolve_timeout = Math.round(message.resolveTimeout); if (message.gasless !== void 0) obj.gasless = message.gasless; return obj; @@ -43404,8 +43606,8 @@ var EscrowSettlementParams = { }, fromPartial(object) { const message = createBaseEscrowSettlementParams(); - message.contractAddress = object.contractAddress !== void 0 && object.contractAddress !== null ? Address$4.fromPartial(object.contractAddress) : void 0; - message.resolverAddress = object.resolverAddress !== void 0 && object.resolverAddress !== null ? Address$4.fromPartial(object.resolverAddress) : void 0; + message.contractAddress = object.contractAddress !== void 0 && object.contractAddress !== null ? Address$7.fromPartial(object.contractAddress) : void 0; + message.resolverAddress = object.resolverAddress !== void 0 && object.resolverAddress !== null ? Address$7.fromPartial(object.resolverAddress) : void 0; message.resolveTimeout = object.resolveTimeout ?? 0; message.gasless = object.gasless ?? false; return message; @@ -43421,15 +43623,15 @@ function createBaseHtlcSettlementParams() { var HtlcSettlementParams = { fromJSON(object) { return { - contractAddress: isSet$5(object.contract_address) ? Address$4.fromJSON(object.contract_address) : void 0, - resolverAddress: isSet$5(object.resolver_address) ? Address$4.fromJSON(object.resolver_address) : void 0, + contractAddress: isSet$5(object.contract_address) ? Address$7.fromJSON(object.contract_address) : void 0, + resolverAddress: isSet$5(object.resolver_address) ? Address$7.fromJSON(object.resolver_address) : void 0, resolveTimeout: isSet$5(object.resolve_timeout) ? globalThis.Number(object.resolve_timeout) : 0 }; }, toJSON(message) { const obj = {}; - if (message.contractAddress !== void 0) obj.contract_address = Address$4.toJSON(message.contractAddress); - if (message.resolverAddress !== void 0) obj.resolver_address = Address$4.toJSON(message.resolverAddress); + if (message.contractAddress !== void 0) obj.contract_address = Address$7.toJSON(message.contractAddress); + if (message.resolverAddress !== void 0) obj.resolver_address = Address$7.toJSON(message.resolverAddress); if (message.resolveTimeout !== void 0) obj.resolve_timeout = Math.round(message.resolveTimeout); return obj; }, @@ -43438,8 +43640,8 @@ var HtlcSettlementParams = { }, fromPartial(object) { const message = createBaseHtlcSettlementParams(); - message.contractAddress = object.contractAddress !== void 0 && object.contractAddress !== null ? Address$4.fromPartial(object.contractAddress) : void 0; - message.resolverAddress = object.resolverAddress !== void 0 && object.resolverAddress !== null ? Address$4.fromPartial(object.resolverAddress) : void 0; + message.contractAddress = object.contractAddress !== void 0 && object.contractAddress !== null ? Address$7.fromPartial(object.contractAddress) : void 0; + message.resolverAddress = object.resolverAddress !== void 0 && object.resolverAddress !== null ? Address$7.fromPartial(object.resolverAddress) : void 0; message.resolveTimeout = object.resolveTimeout ?? 0; return message; } @@ -43458,10 +43660,10 @@ function createBaseQuoteRequest() { var QuoteRequest$1 = { fromJSON(object) { return { - bidAssetAddress: isSet$5(object.bid_asset_address) ? Address$4.fromJSON(object.bid_asset_address) : void 0, - askAssetAddress: isSet$5(object.ask_asset_address) ? Address$4.fromJSON(object.ask_asset_address) : void 0, + bidAssetAddress: isSet$5(object.bid_asset_address) ? Address$7.fromJSON(object.bid_asset_address) : void 0, + askAssetAddress: isSet$5(object.ask_asset_address) ? Address$7.fromJSON(object.ask_asset_address) : void 0, amount: isSet$5(object.amount) ? QuoteRequest_AmountOneOf.fromJSON(object.amount) : void 0, - referrerAddress: isSet$5(object.referrer_address) ? Address$4.fromJSON(object.referrer_address) : void 0, + referrerAddress: isSet$5(object.referrer_address) ? Address$7.fromJSON(object.referrer_address) : void 0, referrerFeeBps: isSet$5(object.referrer_fee_bps) ? globalThis.Number(object.referrer_fee_bps) : 0, settlementMethods: globalThis.Array.isArray(object?.settlement_methods) ? object.settlement_methods.map((e) => settlementMethodFromJSON(e)) : [], settlementParams: isSet$5(object.settlement_params) ? RequestSettlementParams.fromJSON(object.settlement_params) : void 0 @@ -43469,10 +43671,10 @@ var QuoteRequest$1 = { }, toJSON(message) { const obj = {}; - if (message.bidAssetAddress !== void 0) obj.bid_asset_address = Address$4.toJSON(message.bidAssetAddress); - if (message.askAssetAddress !== void 0) obj.ask_asset_address = Address$4.toJSON(message.askAssetAddress); + if (message.bidAssetAddress !== void 0) obj.bid_asset_address = Address$7.toJSON(message.bidAssetAddress); + if (message.askAssetAddress !== void 0) obj.ask_asset_address = Address$7.toJSON(message.askAssetAddress); if (message.amount !== void 0) obj.amount = QuoteRequest_AmountOneOf.toJSON(message.amount); - if (message.referrerAddress !== void 0) obj.referrer_address = Address$4.toJSON(message.referrerAddress); + if (message.referrerAddress !== void 0) obj.referrer_address = Address$7.toJSON(message.referrerAddress); if (message.referrerFeeBps !== void 0) obj.referrer_fee_bps = Math.round(message.referrerFeeBps); if (message.settlementMethods?.length) obj.settlement_methods = message.settlementMethods.map((e) => settlementMethodToJSON(e)); if (message.settlementParams !== void 0) obj.settlement_params = RequestSettlementParams.toJSON(message.settlementParams); @@ -43483,10 +43685,10 @@ var QuoteRequest$1 = { }, fromPartial(object) { const message = createBaseQuoteRequest(); - message.bidAssetAddress = object.bidAssetAddress !== void 0 && object.bidAssetAddress !== null ? Address$4.fromPartial(object.bidAssetAddress) : void 0; - message.askAssetAddress = object.askAssetAddress !== void 0 && object.askAssetAddress !== null ? Address$4.fromPartial(object.askAssetAddress) : void 0; + message.bidAssetAddress = object.bidAssetAddress !== void 0 && object.bidAssetAddress !== null ? Address$7.fromPartial(object.bidAssetAddress) : void 0; + message.askAssetAddress = object.askAssetAddress !== void 0 && object.askAssetAddress !== null ? Address$7.fromPartial(object.askAssetAddress) : void 0; message.amount = object.amount !== void 0 && object.amount !== null ? QuoteRequest_AmountOneOf.fromPartial(object.amount) : void 0; - message.referrerAddress = object.referrerAddress !== void 0 && object.referrerAddress !== null ? Address$4.fromPartial(object.referrerAddress) : void 0; + message.referrerAddress = object.referrerAddress !== void 0 && object.referrerAddress !== null ? Address$7.fromPartial(object.referrerAddress) : void 0; message.referrerFeeBps = object.referrerFeeBps ?? 0; message.settlementMethods = object.settlementMethods?.map((e) => e) || []; message.settlementParams = object.settlementParams !== void 0 && object.settlementParams !== null ? RequestSettlementParams.fromPartial(object.settlementParams) : void 0; @@ -43549,14 +43751,14 @@ var Quote = { quoteId: isSet$5(object.quote_id) ? globalThis.String(object.quote_id) : "", resolverId: isSet$5(object.resolver_id) ? globalThis.String(object.resolver_id) : "", resolverName: isSet$5(object.resolver_name) ? globalThis.String(object.resolver_name) : "", - bidAssetAddress: isSet$5(object.bid_asset_address) ? Address$4.fromJSON(object.bid_asset_address) : void 0, - askAssetAddress: isSet$5(object.ask_asset_address) ? Address$4.fromJSON(object.ask_asset_address) : void 0, + bidAssetAddress: isSet$5(object.bid_asset_address) ? Address$7.fromJSON(object.bid_asset_address) : void 0, + askAssetAddress: isSet$5(object.ask_asset_address) ? Address$7.fromJSON(object.ask_asset_address) : void 0, bidUnits: isSet$5(object.bid_units) ? globalThis.String(object.bid_units) : "", askUnits: isSet$5(object.ask_units) ? globalThis.String(object.ask_units) : "", - referrerAddress: isSet$5(object.referrer_address) ? Address$4.fromJSON(object.referrer_address) : void 0, - referrerFeeAsset: isSet$5(object.referrer_fee_asset) ? Address$4.fromJSON(object.referrer_fee_asset) : void 0, + referrerAddress: isSet$5(object.referrer_address) ? Address$7.fromJSON(object.referrer_address) : void 0, + referrerFeeAsset: isSet$5(object.referrer_fee_asset) ? Address$7.fromJSON(object.referrer_fee_asset) : void 0, referrerFeeUnits: isSet$5(object.referrer_fee_units) ? globalThis.String(object.referrer_fee_units) : "", - protocolFeeAsset: isSet$5(object.protocol_fee_asset) ? Address$4.fromJSON(object.protocol_fee_asset) : void 0, + protocolFeeAsset: isSet$5(object.protocol_fee_asset) ? Address$7.fromJSON(object.protocol_fee_asset) : void 0, protocolFeeUnits: isSet$5(object.protocol_fee_units) ? globalThis.String(object.protocol_fee_units) : "", quoteTimestamp: isSet$5(object.quote_timestamp) ? globalThis.Number(object.quote_timestamp) : 0, tradeStartDeadline: isSet$5(object.trade_start_deadline) ? globalThis.Number(object.trade_start_deadline) : 0, @@ -43570,14 +43772,14 @@ var Quote = { if (message.quoteId !== void 0) obj.quote_id = message.quoteId; if (message.resolverId !== void 0) obj.resolver_id = message.resolverId; if (message.resolverName !== void 0) obj.resolver_name = message.resolverName; - if (message.bidAssetAddress !== void 0) obj.bid_asset_address = Address$4.toJSON(message.bidAssetAddress); - if (message.askAssetAddress !== void 0) obj.ask_asset_address = Address$4.toJSON(message.askAssetAddress); + if (message.bidAssetAddress !== void 0) obj.bid_asset_address = Address$7.toJSON(message.bidAssetAddress); + if (message.askAssetAddress !== void 0) obj.ask_asset_address = Address$7.toJSON(message.askAssetAddress); if (message.bidUnits !== void 0) obj.bid_units = message.bidUnits; if (message.askUnits !== void 0) obj.ask_units = message.askUnits; - if (message.referrerAddress !== void 0) obj.referrer_address = Address$4.toJSON(message.referrerAddress); - if (message.referrerFeeAsset !== void 0) obj.referrer_fee_asset = Address$4.toJSON(message.referrerFeeAsset); + if (message.referrerAddress !== void 0) obj.referrer_address = Address$7.toJSON(message.referrerAddress); + if (message.referrerFeeAsset !== void 0) obj.referrer_fee_asset = Address$7.toJSON(message.referrerFeeAsset); if (message.referrerFeeUnits !== void 0) obj.referrer_fee_units = message.referrerFeeUnits; - if (message.protocolFeeAsset !== void 0) obj.protocol_fee_asset = Address$4.toJSON(message.protocolFeeAsset); + if (message.protocolFeeAsset !== void 0) obj.protocol_fee_asset = Address$7.toJSON(message.protocolFeeAsset); if (message.protocolFeeUnits !== void 0) obj.protocol_fee_units = message.protocolFeeUnits; if (message.quoteTimestamp !== void 0) obj.quote_timestamp = Math.round(message.quoteTimestamp); if (message.tradeStartDeadline !== void 0) obj.trade_start_deadline = Math.round(message.tradeStartDeadline); @@ -43594,14 +43796,14 @@ var Quote = { message.quoteId = object.quoteId ?? ""; message.resolverId = object.resolverId ?? ""; message.resolverName = object.resolverName ?? ""; - message.bidAssetAddress = object.bidAssetAddress !== void 0 && object.bidAssetAddress !== null ? Address$4.fromPartial(object.bidAssetAddress) : void 0; - message.askAssetAddress = object.askAssetAddress !== void 0 && object.askAssetAddress !== null ? Address$4.fromPartial(object.askAssetAddress) : void 0; + message.bidAssetAddress = object.bidAssetAddress !== void 0 && object.bidAssetAddress !== null ? Address$7.fromPartial(object.bidAssetAddress) : void 0; + message.askAssetAddress = object.askAssetAddress !== void 0 && object.askAssetAddress !== null ? Address$7.fromPartial(object.askAssetAddress) : void 0; message.bidUnits = object.bidUnits ?? ""; message.askUnits = object.askUnits ?? ""; - message.referrerAddress = object.referrerAddress !== void 0 && object.referrerAddress !== null ? Address$4.fromPartial(object.referrerAddress) : void 0; - message.referrerFeeAsset = object.referrerFeeAsset !== void 0 && object.referrerFeeAsset !== null ? Address$4.fromPartial(object.referrerFeeAsset) : void 0; + message.referrerAddress = object.referrerAddress !== void 0 && object.referrerAddress !== null ? Address$7.fromPartial(object.referrerAddress) : void 0; + message.referrerFeeAsset = object.referrerFeeAsset !== void 0 && object.referrerFeeAsset !== null ? Address$7.fromPartial(object.referrerFeeAsset) : void 0; message.referrerFeeUnits = object.referrerFeeUnits ?? ""; - message.protocolFeeAsset = object.protocolFeeAsset !== void 0 && object.protocolFeeAsset !== null ? Address$4.fromPartial(object.protocolFeeAsset) : void 0; + message.protocolFeeAsset = object.protocolFeeAsset !== void 0 && object.protocolFeeAsset !== null ? Address$7.fromPartial(object.protocolFeeAsset) : void 0; message.protocolFeeUnits = object.protocolFeeUnits ?? ""; message.quoteTimestamp = object.quoteTimestamp ?? 0; message.tradeStartDeadline = object.tradeStartDeadline ?? 0; @@ -43656,11 +43858,11 @@ function createBaseEscrowOrderListRequest() { } var EscrowOrderListRequest$1 = { fromJSON(object) { - return { traderWalletAddress: isSet$4(object.trader_wallet_address) ? Address$4.fromJSON(object.trader_wallet_address) : void 0 }; + return { traderWalletAddress: isSet$4(object.trader_wallet_address) ? Address$7.fromJSON(object.trader_wallet_address) : void 0 }; }, toJSON(message) { const obj = {}; - if (message.traderWalletAddress !== void 0) obj.trader_wallet_address = Address$4.toJSON(message.traderWalletAddress); + if (message.traderWalletAddress !== void 0) obj.trader_wallet_address = Address$7.toJSON(message.traderWalletAddress); return obj; }, create(base) { @@ -43668,7 +43870,7 @@ var EscrowOrderListRequest$1 = { }, fromPartial(object) { const message = createBaseEscrowOrderListRequest(); - message.traderWalletAddress = object.traderWalletAddress !== void 0 && object.traderWalletAddress !== null ? Address$4.fromPartial(object.traderWalletAddress) : void 0; + message.traderWalletAddress = object.traderWalletAddress !== void 0 && object.traderWalletAddress !== null ? Address$7.fromPartial(object.traderWalletAddress) : void 0; return message; } }; @@ -43704,14 +43906,14 @@ var EscrowOrderData$1 = { fromJSON(object) { return { quote: isSet$4(object.quote) ? Quote.fromJSON(object.quote) : void 0, - escrowItemAddress: isSet$4(object.escrow_item_address) ? Address$4.fromJSON(object.escrow_item_address) : void 0, + escrowItemAddress: isSet$4(object.escrow_item_address) ? Address$7.fromJSON(object.escrow_item_address) : void 0, outgoingTxHash: isSet$4(object.outgoing_tx_hash) ? globalThis.String(object.outgoing_tx_hash) : "" }; }, toJSON(message) { const obj = {}; if (message.quote !== void 0) obj.quote = Quote.toJSON(message.quote); - if (message.escrowItemAddress !== void 0) obj.escrow_item_address = Address$4.toJSON(message.escrowItemAddress); + if (message.escrowItemAddress !== void 0) obj.escrow_item_address = Address$7.toJSON(message.escrowItemAddress); if (message.outgoingTxHash !== void 0) obj.outgoing_tx_hash = message.outgoingTxHash; return obj; }, @@ -43721,7 +43923,7 @@ var EscrowOrderData$1 = { fromPartial(object) { const message = createBaseEscrowOrderData(); message.quote = object.quote !== void 0 && object.quote !== null ? Quote.fromPartial(object.quote) : void 0; - message.escrowItemAddress = object.escrowItemAddress !== void 0 && object.escrowItemAddress !== null ? Address$4.fromPartial(object.escrowItemAddress) : void 0; + message.escrowItemAddress = object.escrowItemAddress !== void 0 && object.escrowItemAddress !== null ? Address$7.fromPartial(object.escrowItemAddress) : void 0; message.outgoingTxHash = object.outgoingTxHash ?? ""; return message; } @@ -44025,7 +44227,7 @@ var SwapChunkStatus = { fromJSON(object) { return { protocol: isSet$2(object.protocol) ? globalThis.String(object.protocol) : "", - targetAddress: isSet$2(object.target_address) ? Address$4.fromJSON(object.target_address) : void 0, + targetAddress: isSet$2(object.target_address) ? Address$7.fromJSON(object.target_address) : void 0, bidUnits: isSet$2(object.bid_units) ? globalThis.String(object.bid_units) : "", expectedAskUnits: isSet$2(object.expected_ask_units) ? globalThis.String(object.expected_ask_units) : "", actualAskUnits: isSet$2(object.actual_ask_units) ? globalThis.String(object.actual_ask_units) : "", @@ -44036,7 +44238,7 @@ var SwapChunkStatus = { toJSON(message) { const obj = {}; if (message.protocol !== void 0) obj.protocol = message.protocol; - if (message.targetAddress !== void 0) obj.target_address = Address$4.toJSON(message.targetAddress); + if (message.targetAddress !== void 0) obj.target_address = Address$7.toJSON(message.targetAddress); if (message.bidUnits !== void 0) obj.bid_units = message.bidUnits; if (message.expectedAskUnits !== void 0) obj.expected_ask_units = message.expectedAskUnits; if (message.actualAskUnits !== void 0) obj.actual_ask_units = message.actualAskUnits; @@ -44050,7 +44252,7 @@ var SwapChunkStatus = { fromPartial(object) { const message = createBaseSwapChunkStatus(); message.protocol = object.protocol ?? ""; - message.targetAddress = object.targetAddress !== void 0 && object.targetAddress !== null ? Address$4.fromPartial(object.targetAddress) : void 0; + message.targetAddress = object.targetAddress !== void 0 && object.targetAddress !== null ? Address$7.fromPartial(object.targetAddress) : void 0; message.bidUnits = object.bidUnits ?? ""; message.expectedAskUnits = object.expectedAskUnits ?? ""; message.actualAskUnits = object.actualAskUnits ?? ""; @@ -44111,14 +44313,14 @@ function createBaseEscrowOrderStatus() { var EscrowOrderStatus = { fromJSON(object) { return { - targetAddress: isSet$2(object.target_address) ? Address$4.fromJSON(object.target_address) : void 0, + targetAddress: isSet$2(object.target_address) ? Address$7.fromJSON(object.target_address) : void 0, askUnits: isSet$2(object.ask_units) ? globalThis.String(object.ask_units) : "", txHash: isSet$2(object.tx_hash) ? globalThis.String(object.tx_hash) : "" }; }, toJSON(message) { const obj = {}; - if (message.targetAddress !== void 0) obj.target_address = Address$4.toJSON(message.targetAddress); + if (message.targetAddress !== void 0) obj.target_address = Address$7.toJSON(message.targetAddress); if (message.askUnits !== void 0) obj.ask_units = message.askUnits; if (message.txHash !== void 0) obj.tx_hash = message.txHash; return obj; @@ -44128,7 +44330,7 @@ var EscrowOrderStatus = { }, fromPartial(object) { const message = createBaseEscrowOrderStatus(); - message.targetAddress = object.targetAddress !== void 0 && object.targetAddress !== null ? Address$4.fromPartial(object.targetAddress) : void 0; + message.targetAddress = object.targetAddress !== void 0 && object.targetAddress !== null ? Address$7.fromPartial(object.targetAddress) : void 0; message.askUnits = object.askUnits ?? ""; message.txHash = object.txHash ?? ""; return message; @@ -44145,14 +44347,14 @@ var TrackTradeRequest$1 = { fromJSON(object) { return { quoteId: isSet$2(object.quote_id) ? globalThis.String(object.quote_id) : "", - traderWalletAddress: isSet$2(object.trader_wallet_address) ? Address$4.fromJSON(object.trader_wallet_address) : void 0, + traderWalletAddress: isSet$2(object.trader_wallet_address) ? Address$7.fromJSON(object.trader_wallet_address) : void 0, outgoingTxHash: isSet$2(object.outgoing_tx_hash) ? globalThis.String(object.outgoing_tx_hash) : "" }; }, toJSON(message) { const obj = {}; if (message.quoteId !== void 0) obj.quote_id = message.quoteId; - if (message.traderWalletAddress !== void 0) obj.trader_wallet_address = Address$4.toJSON(message.traderWalletAddress); + if (message.traderWalletAddress !== void 0) obj.trader_wallet_address = Address$7.toJSON(message.traderWalletAddress); if (message.outgoingTxHash !== void 0) obj.outgoing_tx_hash = message.outgoingTxHash; return obj; }, @@ -44162,7 +44364,7 @@ var TrackTradeRequest$1 = { fromPartial(object) { const message = createBaseTrackTradeRequest(); message.quoteId = object.quoteId ?? ""; - message.traderWalletAddress = object.traderWalletAddress !== void 0 && object.traderWalletAddress !== null ? Address$4.fromPartial(object.traderWalletAddress) : void 0; + message.traderWalletAddress = object.traderWalletAddress !== void 0 && object.traderWalletAddress !== null ? Address$7.fromPartial(object.traderWalletAddress) : void 0; message.outgoingTxHash = object.outgoingTxHash ?? ""; return message; } @@ -44248,13 +44450,13 @@ function createBaseClaimAvailable() { var ClaimAvailable = { fromJSON(object) { return { - contractAddress: isSet$2(object.contract_address) ? Address$4.fromJSON(object.contract_address) : void 0, + contractAddress: isSet$2(object.contract_address) ? Address$7.fromJSON(object.contract_address) : void 0, depositIndex: isSet$2(object.deposit_index) ? globalThis.Number(object.deposit_index) : 0 }; }, toJSON(message) { const obj = {}; - if (message.contractAddress !== void 0) obj.contract_address = Address$4.toJSON(message.contractAddress); + if (message.contractAddress !== void 0) obj.contract_address = Address$7.toJSON(message.contractAddress); if (message.depositIndex !== void 0) obj.deposit_index = Math.round(message.depositIndex); return obj; }, @@ -44263,7 +44465,7 @@ var ClaimAvailable = { }, fromPartial(object) { const message = createBaseClaimAvailable(); - message.contractAddress = object.contractAddress !== void 0 && object.contractAddress !== null ? Address$4.fromPartial(object.contractAddress) : void 0; + message.contractAddress = object.contractAddress !== void 0 && object.contractAddress !== null ? Address$7.fromPartial(object.contractAddress) : void 0; message.depositIndex = object.depositIndex ?? 0; return message; } @@ -44273,11 +44475,11 @@ function createBaseRefundAvailable() { } var RefundAvailable = { fromJSON(object) { - return { contractAddress: isSet$2(object.contract_address) ? Address$4.fromJSON(object.contract_address) : void 0 }; + return { contractAddress: isSet$2(object.contract_address) ? Address$7.fromJSON(object.contract_address) : void 0 }; }, toJSON(message) { const obj = {}; - if (message.contractAddress !== void 0) obj.contract_address = Address$4.toJSON(message.contractAddress); + if (message.contractAddress !== void 0) obj.contract_address = Address$7.toJSON(message.contractAddress); return obj; }, create(base) { @@ -44285,7 +44487,7 @@ var RefundAvailable = { }, fromPartial(object) { const message = createBaseRefundAvailable(); - message.contractAddress = object.contractAddress !== void 0 && object.contractAddress !== null ? Address$4.fromPartial(object.contractAddress) : void 0; + message.contractAddress = object.contractAddress !== void 0 && object.contractAddress !== null ? Address$7.fromPartial(object.contractAddress) : void 0; return message; } }; @@ -44454,20 +44656,20 @@ function createBaseBuildTransferRequest() { var BuildTransferRequest$1 = { fromJSON(object) { return { - sourceAddress: isSet$1(object.source_address) ? Address$4.fromJSON(object.source_address) : void 0, - destinationAddress: isSet$1(object.destination_address) ? Address$4.fromJSON(object.destination_address) : void 0, - gasExcessAddress: isSet$1(object.gas_excess_address) ? Address$4.fromJSON(object.gas_excess_address) : void 0, - refundAddress: isSet$1(object.refund_address) ? Address$4.fromJSON(object.refund_address) : void 0, + sourceAddress: isSet$1(object.source_address) ? Address$7.fromJSON(object.source_address) : void 0, + destinationAddress: isSet$1(object.destination_address) ? Address$7.fromJSON(object.destination_address) : void 0, + gasExcessAddress: isSet$1(object.gas_excess_address) ? Address$7.fromJSON(object.gas_excess_address) : void 0, + refundAddress: isSet$1(object.refund_address) ? Address$7.fromJSON(object.refund_address) : void 0, quote: isSet$1(object.quote) ? Quote.fromJSON(object.quote) : void 0, useRecommendedSlippage: isSet$1(object.use_recommended_slippage) ? globalThis.Boolean(object.use_recommended_slippage) : false }; }, toJSON(message) { const obj = {}; - if (message.sourceAddress !== void 0) obj.source_address = Address$4.toJSON(message.sourceAddress); - if (message.destinationAddress !== void 0) obj.destination_address = Address$4.toJSON(message.destinationAddress); - if (message.gasExcessAddress !== void 0) obj.gas_excess_address = Address$4.toJSON(message.gasExcessAddress); - if (message.refundAddress !== void 0) obj.refund_address = Address$4.toJSON(message.refundAddress); + if (message.sourceAddress !== void 0) obj.source_address = Address$7.toJSON(message.sourceAddress); + if (message.destinationAddress !== void 0) obj.destination_address = Address$7.toJSON(message.destinationAddress); + if (message.gasExcessAddress !== void 0) obj.gas_excess_address = Address$7.toJSON(message.gasExcessAddress); + if (message.refundAddress !== void 0) obj.refund_address = Address$7.toJSON(message.refundAddress); if (message.quote !== void 0) obj.quote = Quote.toJSON(message.quote); if (message.useRecommendedSlippage !== void 0) obj.use_recommended_slippage = message.useRecommendedSlippage; return obj; @@ -44477,10 +44679,10 @@ var BuildTransferRequest$1 = { }, fromPartial(object) { const message = createBaseBuildTransferRequest(); - message.sourceAddress = object.sourceAddress !== void 0 && object.sourceAddress !== null ? Address$4.fromPartial(object.sourceAddress) : void 0; - message.destinationAddress = object.destinationAddress !== void 0 && object.destinationAddress !== null ? Address$4.fromPartial(object.destinationAddress) : void 0; - message.gasExcessAddress = object.gasExcessAddress !== void 0 && object.gasExcessAddress !== null ? Address$4.fromPartial(object.gasExcessAddress) : void 0; - message.refundAddress = object.refundAddress !== void 0 && object.refundAddress !== null ? Address$4.fromPartial(object.refundAddress) : void 0; + message.sourceAddress = object.sourceAddress !== void 0 && object.sourceAddress !== null ? Address$7.fromPartial(object.sourceAddress) : void 0; + message.destinationAddress = object.destinationAddress !== void 0 && object.destinationAddress !== null ? Address$7.fromPartial(object.destinationAddress) : void 0; + message.gasExcessAddress = object.gasExcessAddress !== void 0 && object.gasExcessAddress !== null ? Address$7.fromPartial(object.gasExcessAddress) : void 0; + message.refundAddress = object.refundAddress !== void 0 && object.refundAddress !== null ? Address$7.fromPartial(object.refundAddress) : void 0; message.quote = object.quote !== void 0 && object.quote !== null ? Quote.fromPartial(object.quote) : void 0; message.useRecommendedSlippage = object.useRecommendedSlippage ?? false; return message; @@ -44496,16 +44698,16 @@ function createBaseBuildWithdrawalRequest() { var BuildWithdrawalRequest$1 = { fromJSON(object) { return { - sourceAddress: isSet$1(object.source_address) ? Address$4.fromJSON(object.source_address) : void 0, + sourceAddress: isSet$1(object.source_address) ? Address$7.fromJSON(object.source_address) : void 0, quoteId: isSet$1(object.quote_id) ? globalThis.String(object.quote_id) : "", - gasExcessAddress: isSet$1(object.gas_excess_address) ? Address$4.fromJSON(object.gas_excess_address) : void 0 + gasExcessAddress: isSet$1(object.gas_excess_address) ? Address$7.fromJSON(object.gas_excess_address) : void 0 }; }, toJSON(message) { const obj = {}; - if (message.sourceAddress !== void 0) obj.source_address = Address$4.toJSON(message.sourceAddress); + if (message.sourceAddress !== void 0) obj.source_address = Address$7.toJSON(message.sourceAddress); if (message.quoteId !== void 0) obj.quote_id = message.quoteId; - if (message.gasExcessAddress !== void 0) obj.gas_excess_address = Address$4.toJSON(message.gasExcessAddress); + if (message.gasExcessAddress !== void 0) obj.gas_excess_address = Address$7.toJSON(message.gasExcessAddress); return obj; }, create(base) { @@ -44513,9 +44715,9 @@ var BuildWithdrawalRequest$1 = { }, fromPartial(object) { const message = createBaseBuildWithdrawalRequest(); - message.sourceAddress = object.sourceAddress !== void 0 && object.sourceAddress !== null ? Address$4.fromPartial(object.sourceAddress) : void 0; + message.sourceAddress = object.sourceAddress !== void 0 && object.sourceAddress !== null ? Address$7.fromPartial(object.sourceAddress) : void 0; message.quoteId = object.quoteId ?? ""; - message.gasExcessAddress = object.gasExcessAddress !== void 0 && object.gasExcessAddress !== null ? Address$4.fromPartial(object.gasExcessAddress) : void 0; + message.gasExcessAddress = object.gasExcessAddress !== void 0 && object.gasExcessAddress !== null ? Address$7.fromPartial(object.gasExcessAddress) : void 0; return message; } }; @@ -44912,11 +45114,11 @@ var isOmnistonQuoteMetadata = (metadata) => { */ init_SwapProvider(); init_models(); -init_errors$1(); +init_errors$2(); init_Logger(); init_utils$2(); init_units(); -var log$1 = globalLogger.createChild("OmnistonSwapProvider"); +var log$2 = globalLogger.createChild("OmnistonSwapProvider"); /** * Swap provider implementation for Omniston (STON.fi) protocol * @@ -44966,7 +45168,7 @@ var OmnistonSwapProvider = class extends SwapProvider { ...this.metadata, ...config.metadata }; - log$1.info("OmnistonSwapProvider initialized", { + log$2.info("OmnistonSwapProvider initialized", { defaultSlippageBps: this.defaultSlippageBps, hasReferrer: !!this.referrerAddress }); @@ -44982,7 +45184,7 @@ var OmnistonSwapProvider = class extends SwapProvider { return this.omniston$; } async getQuote(params) { - log$1.debug("Getting Omniston quote", { + log$2.debug("Getting Omniston quote", { fromToken: params.from, toToken: params.to, amount: params.amount, @@ -45011,9 +45213,9 @@ var OmnistonSwapProvider = class extends SwapProvider { }; const quoteEvent = await new Promise((resolve, reject) => { let isSettled = false; - log$1.debug("Requesting quote", { quoteRequest }); + log$2.debug("Requesting quote", { quoteRequest }); const timeoutId = setTimeout(() => { - log$1.debug("Timeout reached"); + log$2.debug("Timeout reached"); if (!isSettled) { isSettled = true; reject(new SwapError("Quote request timed out", SwapErrorCode.NetworkError)); @@ -45022,7 +45224,7 @@ var OmnistonSwapProvider = class extends SwapProvider { }, this.quoteTimeoutMs); const unsubscribe = this.omniston.requestForQuote(quoteRequest).subscribe({ next: (event) => { - log$1.debug("Received quote event", event); + log$2.debug("Received quote event", event); if (isSettled) return; if (event.type === "noQuote") { isSettled = true; @@ -45051,14 +45253,14 @@ var OmnistonSwapProvider = class extends SwapProvider { if (quoteEvent.type !== "quoteUpdated") throw new SwapError("Quote data is missing", SwapErrorCode.InvalidQuote); const quote = quoteEvent.quote; const swapQuote = this.mapOmnistonQuoteToSwapQuote(quote, params); - log$1.debug("Received Omniston quote", { + log$2.debug("Received Omniston quote", { quoteId: quote.quoteId, bidUnits: quote.bidUnits, askUnits: quote.askUnits }); return swapQuote; } catch (error) { - log$1.error("Failed to get Omniston quote", { + log$2.error("Failed to get Omniston quote", { error, params }); @@ -45067,7 +45269,7 @@ var OmnistonSwapProvider = class extends SwapProvider { } } async buildSwapTransaction(params) { - log$1.debug("Building Omniston swap transaction", params); + log$2.debug("Building Omniston swap transaction", params); const metadata = params.quote.metadata; if (!metadata || !isOmnistonQuoteMetadata(metadata)) throw new SwapError("Invalid quote: missing Omniston quote data", SwapErrorCode.InvalidQuote); try { @@ -45096,13 +45298,13 @@ var OmnistonSwapProvider = class extends SwapProvider { })), network: params.quote.network }; - log$1.debug("Built Omniston swap transaction", { + log$2.debug("Built Omniston swap transaction", { quoteId: metadata.omnistonQuote.quoteId, transaction }); return transaction; } catch (error) { - log$1.error("Failed to build Omniston swap transaction", { + log$2.error("Failed to build Omniston swap transaction", { error, params }); @@ -45178,11 +45380,11 @@ var isDeDustQuoteMetadata = (metadata) => { */ init_SwapProvider(); init_models(); -init_errors$1(); +init_errors$2(); init_Logger(); init_utils$2(); init_units(); -var log = globalLogger.createChild("DeDustSwapProvider"); +var log$1 = globalLogger.createChild("DeDustSwapProvider"); /** * Default API URL for DeDust Router */ @@ -45245,7 +45447,7 @@ var DeDustSwapProvider = class extends SwapProvider { ...this.metadata, ...config.metadata }; - log.info("DeDustSwapProvider initialized", { + log$1.info("DeDustSwapProvider initialized", { apiUrl: this.apiUrl, defaultSlippageBps: this.defaultSlippageBps, hasReferral: !!this.referralAddress @@ -45258,7 +45460,7 @@ var DeDustSwapProvider = class extends SwapProvider { return [Network.mainnet()]; } async getQuote(params) { - log.debug("Getting DeDust quote", { + log$1.debug("Getting DeDust quote", { fromToken: params.from, toToken: params.to, amount: params.amount, @@ -45293,7 +45495,7 @@ var DeDustSwapProvider = class extends SwapProvider { }); if (!response.ok) { const errorText = await response.text(); - log.error("DeDust quote API error", { + log$1.error("DeDust quote API error", { status: response.status, error: errorText }); @@ -45321,7 +45523,7 @@ var DeDustSwapProvider = class extends SwapProvider { network: params.network, priceImpact: quoteResponse.price_impact ? Math.round(quoteResponse.price_impact * 100) : void 0 }; - log.debug("Received DeDust quote", { + log$1.debug("Received DeDust quote", { inAmount: quoteResponse.in_amount, outAmount: quoteResponse.out_amount, minReceived: minReceived.toString(), @@ -45329,7 +45531,7 @@ var DeDustSwapProvider = class extends SwapProvider { }); return swapQuote; } catch (error) { - log.error("Failed to get DeDust quote", { + log$1.error("Failed to get DeDust quote", { error, params }); @@ -45338,7 +45540,7 @@ var DeDustSwapProvider = class extends SwapProvider { } } async buildSwapTransaction(params) { - log.debug("Building DeDust swap transaction", params); + log$1.debug("Building DeDust swap transaction", params); const metadata = params.quote.metadata; if (!metadata || !isDeDustQuoteMetadata(metadata)) throw new SwapError("Invalid quote: missing DeDust quote data", SwapErrorCode.InvalidQuote); try { @@ -45361,7 +45563,7 @@ var DeDustSwapProvider = class extends SwapProvider { }); if (!response.ok) { const errorText = await response.text(); - log.error("DeDust swap API error", { + log$1.error("DeDust swap API error", { status: response.status, error: errorText }); @@ -45379,10 +45581,10 @@ var DeDustSwapProvider = class extends SwapProvider { })), network: params.quote.network }; - log.debug("Built DeDust swap transaction", { messageCount: transaction.messages.length }); + log$1.debug("Built DeDust swap transaction", { messageCount: transaction.messages.length }); return transaction; } catch (error) { - log.error("Failed to build DeDust swap transaction", { + log$1.error("Failed to build DeDust swap transaction", { error, params }); @@ -45493,6 +45695,396 @@ async function registerKotlinSwapProvider(args) { retainWithId(args.providerId, provider); (await getSwap()).registerProvider(provider); } +/** Static metadata returned by `TonApiGaslessProvider.getMetadata()`. */ +var DEFAULT_METADATA = { + name: "TonAPI", + url: "https://tonapi.io" +}; +//#endregion +//#region ../walletkit/dist/esm/defi/gasless/tonapi/helpers.js +init_models(); +init_TonClientError(); +/** +* Reconstruct a `Network` instance from a chainId string. Used to map +* `Object.keys(chainConfig)` back to `Network` objects. +*/ +var networkFromChainId = (chainId) => { + switch (chainId) { + case Network.mainnet().chainId: return Network.mainnet(); + case Network.testnet().chainId: return Network.testnet(); + case Network.tetra().chainId: return Network.tetra(); + default: return Network.custom(chainId); + } +}; +/** +* Decide whether a `/v2/gasless/send` failure is worth retrying. +* +* Retry on 5xx server errors and HTTP 408/429 (timeout / rate limit), and on +* non-HTTP errors (network failures: fetch `TypeError`, `AbortError`). +* +* Skip retry on 4xx client errors — they will not improve, and re-sending a +* BoC that was actually accepted would burn relayer gas on a duplicate +* (although the wallet's seqno guard prevents on-chain double-spend). +*/ +var isTransientError = (error) => { + if (error instanceof TonClientError) return error.status >= 500 || error.status === 408 || error.status === 429; + return error instanceof Error; +}; +//#endregion +//#region ../walletkit/dist/esm/defi/gasless/tonapi/mappers/map-gasless-config.js +init_address$1(); +/** +* Wire → domain: map TonAPI's `/v2/gasless/config` response to `GaslessConfig`. +* Bundles both the relay address (for jetton-transfer `responseDestination`) +* and the assets the relayer accepts as fee payment. +*/ +var mapGaslessConfig = (raw) => ({ + relayAddress: asAddressFriendly(raw.relay_address), + supportedAssets: raw.gas_jettons.map((jetton) => ({ address: asAddressFriendly(jetton.master_id) })) +}); +//#endregion +//#region ../walletkit/dist/esm/defi/gasless/tonapi/mappers/map-gasless-error.js +init_TonClientError(); +init_errors(); +var TONAPI_UNSUPPORTED_FEE_ASSET_CODE = 4e4; +var TONAPI_FEE_JETTON_UNRESOLVED_CODE = 40007; +var mapTonApiGaslessError = (error, fallbackCode, fallbackMessage) => { + if (error instanceof GaslessError) return error; + if (error instanceof TonClientError) { + const body = error.details; + if (body && typeof body === "object" && body.error_code === TONAPI_UNSUPPORTED_FEE_ASSET_CODE) return new GaslessError(body.error ?? "Fee asset is not supported by the gasless relayer", GaslessErrorCode.UnsupportedFeeAsset, error); + if (body && typeof body === "object" && body.error_code === TONAPI_FEE_JETTON_UNRESOLVED_CODE) return new GaslessError("You have never held the selected fee asset, so the relayer could not resolve its jetton wallet. Choose a fee asset you already own.", GaslessErrorCode.FeeAssetNotOwned, error); + } + return new GaslessError(error instanceof Error ? error.message : fallbackMessage, fallbackCode, error); +}; +//#endregion +//#region ../walletkit/dist/esm/defi/gasless/tonapi/utils.js +/** +* Copyright (c) TonTech. +* +* This source code is licensed under the MIT license found in the +* LICENSE file in the root directory of this source tree. +* +*/ +init_base64(); +init_hex(); +init_errors(); +var stripHexPrefix = (value) => { + return value.startsWith("0x") ? value.slice(2) : value; +}; +/** +* TonAPI returns BoCs as bare hex strings (no `0x` prefix); the walletkit domain +* uses base64 (`Base64String`). Re-encoding is byte-identical; `asHex` validates +* the hex first. Shared by the quote and send mappers. +*/ +var hexBocToBase64 = (hex) => { + return HexToBase64(asHex(hex.startsWith("0x") ? hex : `0x${hex}`)); +}; +var buildInternalMessageCell = (message) => { + const to = import_dist$1.Address.parse(message.address); + const value = BigInt(message.amount); + const body = message.payload ? import_dist$1.Cell.fromBase64(message.payload) : (0, import_dist$1.beginCell)().endCell(); + const init = message.stateInit ? (0, import_dist$1.loadStateInit)(import_dist$1.Cell.fromBase64(message.stateInit).beginParse()) : void 0; + return (0, import_dist$1.beginCell)().storeWritable((0, import_dist$1.storeMessageRelaxed)((0, import_dist$1.internal)({ + to, + value, + bounce: true, + body, + init + }))).endCell(); +}; +/** +* Convert an internal-message BoC (what `wallet.signMessage` returns) into an +* external message BoC that the relayer accepts for broadcast. +*/ +var internalBocToExternalMessageBoc = (internalBoc) => { + const { info, body, init } = (0, import_dist$1.loadMessageRelaxed)(import_dist$1.Cell.fromBase64(internalBoc).beginParse()); + if (info.type !== "internal") throw new GaslessError("Signed message must be an internal message", GaslessErrorCode.SendFailed); + return (0, import_dist$1.beginCell)().storeWritable((0, import_dist$1.storeMessage)((0, import_dist$1.external)({ + to: info.dest, + init: init ?? void 0, + body + }))).endCell(); +}; +//#endregion +//#region ../walletkit/dist/esm/defi/gasless/tonapi/mappers/map-gasless-quote.js +/** +* Copyright (c) TonTech. +* +* This source code is licensed under the MIT license found in the +* LICENSE file in the root directory of this source tree. +* +*/ +init_address$1(); +init_hex(); +/** +* Domain → wire: build the JSON body for `POST /v2/gasless/estimate/{master_id}`. +* +* Caller messages are encoded as hex BoCs of internal messages (TonAPI's wire format). +*/ +var buildGaslessQuoteRequest = (params) => ({ + wallet_address: import_dist$1.Address.parse(params.walletAddress).toRawString(), + wallet_public_key: stripHexPrefix(asHex(params.walletPublicKey)), + messages: params.messages.map((message) => ({ boc: buildInternalMessageCell(message).toBoc().toString("hex") })) +}); +/** +* Wire → domain: map the TonAPI estimate response to `GaslessQuote`. +* +* Hex BoCs in `payload` / `state_init` are converted back to base64. `network` +* is threaded in from the request — the relayer does not echo it. +*/ +var mapGaslessQuote = (raw, network) => ({ + network, + messages: raw.messages.map((message) => ({ + address: asAddressFriendly(message.address), + amount: message.amount, + payload: message.payload ? hexBocToBase64(message.payload) : void 0, + stateInit: message.state_init ? hexBocToBase64(message.state_init) : void 0 + })), + fee: raw.commission, + validUntil: raw.valid_until, + from: asAddressFriendly(raw.from) +}); +//#endregion +//#region ../walletkit/dist/esm/defi/gasless/tonapi/mappers/map-gasless-send.js +init_hex(); +init_getNormalizedExtMessageHash(); +init_errors(); +/** +* Domain → wire: build the JSON body for `POST /v2/gasless/send`. +* +* The signed internal-message BoC (returned by `wallet.signMessage`) is +* unwrapped into an external message BoC that the relayer can broadcast. +*/ +var buildGaslessSendRequest = (params) => ({ + wallet_public_key: stripHexPrefix(asHex(params.walletPublicKey)), + boc: internalBocToExternalMessageBoc(params.internalBoc).toBoc().toString("hex") +}); +/** +* Wire → domain: turn TonAPI's `GaslessTx` response into a `SendTransactionResponse`. +* +* Despite the OpenAPI description ("Normalized hash of the external message"), +* `external` is the **full hex BoC** of the external-in message the relayer +* actually broadcast — verified against live TonAPI. Crucially it is the +* *relayer's own* external message (addressed to the relayer's wallet), which +* differs from the external message we submit (addressed to the user's wallet), +* so it is the only source for the real on-chain hash. We re-encode it to base64 +* and normalize via `getNormalizedExtMessageHash` to yield the same +* `{ boc, normalizedBoc, normalizedHash }` triple as `wallet.sendTransaction`. +*/ +var mapGaslessSend = (raw) => { + if (!raw.external) throw new GaslessError("Relayer did not return the broadcasted external message", GaslessErrorCode.SendFailed, { protocolName: raw.protocol_name }); + try { + const boc = hexBocToBase64(raw.external); + const { hash: normalizedHash, boc: normalizedBoc } = getNormalizedExtMessageHash(boc); + return { + boc, + normalizedBoc, + normalizedHash + }; + } catch (cause) { + throw new GaslessError("Relayer `external` is not a parseable external-message BoC — TonAPI response format may have changed.", GaslessErrorCode.SendFailed, { + external: raw.external, + cause + }); + } +}; +//#endregion +//#region ../walletkit/dist/esm/defi/gasless/tonapi/TonApiGaslessProvider.js +/** +* Copyright (c) TonTech. +* +* This source code is licensed under the MIT license found in the +* LICENSE file in the root directory of this source tree. +* +*/ +init_index_min(); +init_ApiClientTonApi(); +init_Logger(); +init_delay(); +init_errors(); +init_GaslessProvider(); +var log = globalLogger.createChild("TonApiGaslessProvider"); +/** +* Gasless provider implementation backed by the public TonAPI REST API. +* +* Implements the flow documented at https://docs.tonapi.io/tonapi/rest-api/gasless. +* +* @example +* ```typescript +* import { Network } from '@ton/walletkit'; +* import { createTonApiGaslessProvider } from '@ton/walletkit/gasless/tonapi'; +* +* const provider = createTonApiGaslessProvider({ +* chains: { +* [Network.mainnet().chainId]: { apiKey: process.env.TON_API_KEY }, +* }, +* }); +* +* kit.gasless.registerProvider(provider); +* ``` +*/ +var TonApiGaslessProvider = class TonApiGaslessProvider extends GaslessProvider { + providerId; + chainConfig; + clients = {}; + sendRetries; + sendRetryDelayMs; + configCacheTtlMs; + configCache; + /** + * @internal Use {@link createTonApiGaslessProvider} (AppKit) or {@link TonApiGaslessProvider.createFromContext}. + */ + constructor(chainConfig, options) { + super(); + this.chainConfig = chainConfig; + this.providerId = options.providerId ?? "tonapi"; + this.sendRetries = options.sendRetries ?? 3; + this.sendRetryDelayMs = options.sendRetryDelayMs ?? 2e3; + this.configCacheTtlMs = options.configCacheTtlMs ?? 3e5; + if (this.configCacheTtlMs > 0) this.configCache = new U({ + max: Math.max(1, Object.keys(chainConfig).length), + ttl: this.configCacheTtlMs, + fetchMethod: (_chainId, _stale, { context }) => this.fetchConfig(context) + }); + log.info("TonApiGaslessProvider initialized", { + providerId: this.providerId, + chains: Object.keys(this.chainConfig) + }); + } + /** + * Build a provider that serves every network the kit was configured with. + * + * If `config.chains` is provided, only those chains are registered (and they + * must intersect with the kit's configured networks). Otherwise every + * configured network gets a default TonAPI client. + */ + static createFromContext(ctx, config = {}) { + const configuredChains = new Set(ctx.networkManager.getConfiguredNetworks().map((n) => n.chainId)); + const chainConfig = {}; + if (config.chains) for (const [chainId, perChain] of Object.entries(config.chains)) { + if (!configuredChains.has(chainId)) { + log.warn("Skipping TonApi gasless chain not configured in the kit", { chainId }); + continue; + } + chainConfig[chainId] = perChain; + } + else for (const chainId of configuredChains) chainConfig[chainId] = {}; + if (Object.keys(chainConfig).length === 0) throw new Error("createTonApiGaslessProvider: no eligible networks (configure at least one network in the kit, or pass `chains` matching a configured network)"); + return new TonApiGaslessProvider(chainConfig, config); + } + getSupportedNetworks() { + return Object.keys(this.chainConfig).map(networkFromChainId); + } + async getMetadata() { + return DEFAULT_METADATA; + } + async getConfig(network) { + if (!this.configCache) return this.fetchConfig(network); + const value = await this.configCache.fetch(network.chainId, { context: network }); + if (!value) throw new GaslessError("Gasless config cache returned no value", GaslessErrorCode.ConfigFailed); + return value; + } + async fetchConfig(network) { + try { + return mapGaslessConfig(await this.getClient(network).getJson("/v2/gasless/config")); + } catch (error) { + log.error("Failed to fetch gasless config", { + error, + chainId: network.chainId + }); + throw mapTonApiGaslessError(error, GaslessErrorCode.ConfigFailed, "Failed to fetch gasless config"); + } + } + async getQuote(params) { + if (!params.feeAsset) throw new GaslessError("TonAPI gasless requires `feeAsset` (jetton master). Free / sponsored modes are not supported by this provider.", GaslessErrorCode.UnsupportedOperation, { network: params.network.chainId }); + const masterId = import_dist$1.Address.parse(params.feeAsset).toRawString(); + const body = buildGaslessQuoteRequest(params); + try { + return mapGaslessQuote(await this.getClient(params.network).postJson(`/v2/gasless/estimate/${masterId}`, body), params.network); + } catch (error) { + log.error("Failed to quote gasless transaction", { + error, + params + }); + throw mapTonApiGaslessError(error, GaslessErrorCode.QuoteFailed, "Failed to quote gasless transaction"); + } + } + async sendTransaction(params) { + const body = buildGaslessSendRequest(params); + const http = this.getClient(params.network); + const attemptsTotal = this.sendRetries + 1; + let attempt = 0; + let lastError; + while (attempt < attemptsTotal) try { + return { + ...mapGaslessSend(await http.postJson("/v2/gasless/send", body)), + internalBoc: params.internalBoc + }; + } catch (error) { + lastError = error; + if (attempt === attemptsTotal - 1 || !isTransientError(error)) break; + await delay(this.sendRetryDelayMs * 2 ** attempt); + attempt++; + } + log.error("Failed to send gasless transaction", { + error: lastError, + chainId: params.network.chainId + }); + throw mapTonApiGaslessError(lastError, GaslessErrorCode.SendFailed, "Failed to send gasless transaction"); + } + getClient(network) { + const chainId = network.chainId; + const perChain = this.chainConfig[chainId]; + if (!perChain) throw new GaslessError(`TonApi gasless not configured for chain ${chainId}`, GaslessErrorCode.UnsupportedOperation, { + chainId, + configured: Object.keys(this.chainConfig) + }); + if (!this.clients[chainId]) this.clients[chainId] = new ApiClientTonApi({ + network, + endpoint: perChain.endpoint, + apiKey: perChain.apiKey + }); + return this.clients[chainId]; + } +}; +//#endregion +//#region src/api/gasless.ts +async function getGasless() { + const instance = await getKit(); + if (!instance.gasless) throw new Error("Gasless is not configured"); + return instance.gasless; +} +async function createTonApiGaslessProvider(args) { + const instance = await getKit(); + const provider = TonApiGaslessProvider.createFromContext(instance.createFactoryContext(), args?.config ?? {}); + retainWithId(provider.providerId, provider); + return { providerId: provider.providerId }; +} +async function registerGaslessProvider(args) { + (await getGasless()).registerProvider(get(args.providerId)); +} +async function setDefaultGaslessProvider(args) { + (await getGasless()).setDefaultProvider(args.providerId); +} +async function getRegisteredGaslessProviders() { + return { providerIds: (await getGasless()).getProviders().map((provider) => provider.providerId) }; +} +async function hasGaslessProvider(args) { + return { result: (await getGasless()).hasProvider(args.providerId) }; +} +async function getGaslessMetadata(args) { + return (await getGasless()).getMetadata(args.providerId); +} +async function getGaslessConfig(args) { + return (await getGasless()).getConfig(args.network, args.providerId); +} +async function getGaslessQuote(args) { + return (await getGasless()).getQuote(args.params, args.providerId); +} +async function gaslessSendTransaction(args) { + return (await getGasless()).sendTransaction(args.params, args.providerId); +} //#endregion //#region src/api/walletClient.ts async function walletClientSendBoc(args) { @@ -45548,6 +46140,8 @@ var api = { getWallet: getWalletById, getWalletAddress, getWalletNetwork, + getWalletPublicKey, + getSignedSignMessage, removeWallet, getBalance, getRecentTransactions, @@ -45620,6 +46214,15 @@ var api = { getSwapQuote, buildSwapTransaction, registerKotlinSwapProvider, + createTonApiGaslessProvider, + registerGaslessProvider, + setDefaultGaslessProvider, + getRegisteredGaslessProviders, + hasGaslessProvider, + getGaslessMetadata, + getGaslessConfig, + getGaslessQuote, + gaslessSendTransaction, walletClientSendBoc, walletClientRunGetMethod, walletClientGetBalance, diff --git a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/core/TONWallet.kt b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/core/TONWallet.kt index e0303edb..7e2325b9 100644 --- a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/core/TONWallet.kt +++ b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/core/TONWallet.kt @@ -29,6 +29,8 @@ import io.ton.walletkit.engine.WalletKitEngine import io.ton.walletkit.engine.model.WalletAccount import io.ton.walletkit.model.KeyPair import io.ton.walletkit.model.TONBalance +import io.ton.walletkit.model.TONBase64 +import io.ton.walletkit.model.TONHex import io.ton.walletkit.model.TONUserFriendlyAddress import io.ton.walletkit.session.TONConnectSession import kotlinx.serialization.json.Json @@ -60,7 +62,7 @@ import kotlinx.serialization.json.Json internal class TONWallet internal constructor( override val id: String, override val address: TONUserFriendlyAddress, - private val network: TONNetwork, + override val network: TONNetwork, private val engine: WalletKitEngine, private val account: WalletAccount, ) : ITONWallet { @@ -224,6 +226,16 @@ internal class TONWallet internal constructor( override suspend fun transferJettonTransaction(request: TONJettonsTransferRequest): TONTransactionRequest = engine.createTransferJettonTransaction(id, request) + override suspend fun publicKey(): TONHex = TONHex(engine.getWalletPublicKey(id)) + + override suspend fun signMessage( + messages: List, + validUntil: Double?, + ): TONBase64 { + val request = TONTransactionRequest(messages = messages, validUntil = validUntil, network = network) + return TONBase64(engine.getSignedSignMessage(id, request)) + } + /** * Get jettons owned by this wallet. * diff --git a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/core/TONWalletKit.kt b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/core/TONWalletKit.kt index e6892085..567ebc9a 100644 --- a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/core/TONWalletKit.kt +++ b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/core/TONWalletKit.kt @@ -32,6 +32,7 @@ import io.ton.walletkit.api.generated.TONDeDustSwapProviderConfig import io.ton.walletkit.api.generated.TONNetwork import io.ton.walletkit.api.generated.TONOmnistonSwapProviderConfig import io.ton.walletkit.api.generated.TONSignatureDomain +import io.ton.walletkit.api.generated.TONTonApiGaslessProviderConfig import io.ton.walletkit.api.generated.TONTonApiStreamingProviderConfig import io.ton.walletkit.api.generated.TONTonCenterStreamingProviderConfig import io.ton.walletkit.api.generated.TONTransactionRequest @@ -42,6 +43,9 @@ import io.ton.walletkit.core.streaming.TONStreamingManager import io.ton.walletkit.core.streaming.TONStreamingProviderImpl import io.ton.walletkit.engine.WalletKitEngine import io.ton.walletkit.engine.WebViewWalletKitEngine +import io.ton.walletkit.gasless.ITONGaslessManager +import io.ton.walletkit.gasless.TONGaslessManager +import io.ton.walletkit.gasless.TONGaslessProvider import io.ton.walletkit.internal.constants.BridgeMethodConstants import io.ton.walletkit.internal.util.WalletKitUtils import io.ton.walletkit.listener.TONBridgeEventsHandler @@ -126,6 +130,8 @@ internal class TONWalletKit private constructor( private val swapManager: ITONSwapManager = TONSwapManager(engine) + private val gaslessManager: ITONGaslessManager = TONGaslessManager(engine) + companion object { /** * Initialize TON Wallet Kit with configuration. @@ -479,6 +485,14 @@ internal class TONWalletKit private constructor( override suspend fun swap(): ITONSwapManager = swapManager + override suspend fun tonApiGaslessProvider(config: TONTonApiGaslessProviderConfig?): TONGaslessProvider { + checkNotDestroyed() + val providerId = engine.createTonApiGaslessProvider(config) + return TONGaslessProvider(providerId) + } + + override suspend fun gasless(): ITONGaslessManager = gaslessManager + override fun staking(): ITONStakingManager { checkNotDestroyed() return _stakingManager diff --git a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/WalletKitEngine.kt b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/WalletKitEngine.kt index a531e34c..1ffe4ff6 100644 --- a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/WalletKitEngine.kt +++ b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/WalletKitEngine.kt @@ -27,6 +27,12 @@ import io.ton.walletkit.api.generated.TONConnectionRequestEvent import io.ton.walletkit.api.generated.TONDeDustSwapProviderConfig import io.ton.walletkit.api.generated.TONEmbeddedRequestEvent import io.ton.walletkit.api.generated.TONEmulationResult +import io.ton.walletkit.api.generated.TONGaslessConfig +import io.ton.walletkit.api.generated.TONGaslessProviderMetadata +import io.ton.walletkit.api.generated.TONGaslessQuote +import io.ton.walletkit.api.generated.TONGaslessQuoteParams +import io.ton.walletkit.api.generated.TONGaslessSendParams +import io.ton.walletkit.api.generated.TONGaslessSendResponse import io.ton.walletkit.api.generated.TONGetMethodResult import io.ton.walletkit.api.generated.TONJettonsResponse import io.ton.walletkit.api.generated.TONJettonsTransferRequest @@ -56,6 +62,7 @@ import io.ton.walletkit.api.generated.TONStakingQuoteParams import io.ton.walletkit.api.generated.TONSwapParams import io.ton.walletkit.api.generated.TONSwapQuote import io.ton.walletkit.api.generated.TONSwapQuoteParams +import io.ton.walletkit.api.generated.TONTonApiGaslessProviderConfig import io.ton.walletkit.api.generated.TONTonStakersChainConfig import io.ton.walletkit.api.generated.TONTransactionEmulatedPreview import io.ton.walletkit.api.generated.TONTransactionPreviewOptions @@ -539,6 +546,11 @@ internal interface WalletKitEngine : RequestHandler { */ suspend fun getJettonWalletAddress(walletId: String, jettonAddress: String): String + suspend fun getWalletPublicKey(walletId: String): String + + /** Sign a transaction request as a sign-message bundle, returning the signed internal BoC (base64). */ + suspend fun getSignedSignMessage(walletId: String, request: TONTransactionRequest): String + // ── Swap ── suspend fun createOmnistonSwapProvider(config: TONOmnistonSwapProviderConfig?): String @@ -580,6 +592,26 @@ internal interface WalletKitEngine : RequestHandler { suspend fun buildSwapTransaction(params: TONSwapParams): TONTransactionRequest + // ── Gasless ── + + suspend fun createTonApiGaslessProvider(config: TONTonApiGaslessProviderConfig?): String + + suspend fun registerGaslessProvider(providerId: String) + + suspend fun setDefaultGaslessProvider(providerId: String) + + suspend fun getRegisteredGaslessProviders(): List + + suspend fun hasGaslessProvider(providerId: String): Boolean + + suspend fun getGaslessMetadata(providerId: String?): TONGaslessProviderMetadata + + suspend fun getGaslessConfig(network: TONNetwork?, providerId: String?): TONGaslessConfig + + suspend fun getGaslessQuote(params: TONGaslessQuoteParams, providerId: String?): TONGaslessQuote + + suspend fun gaslessSendTransaction(params: TONGaslessSendParams, providerId: String?): TONGaslessSendResponse + // ── Staking ── /** diff --git a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/WebViewWalletKitEngine.kt b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/WebViewWalletKitEngine.kt index f1016b07..0577bc50 100644 --- a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/WebViewWalletKitEngine.kt +++ b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/WebViewWalletKitEngine.kt @@ -29,6 +29,8 @@ import io.ton.walletkit.api.generated.TONConnectionRequestEvent import io.ton.walletkit.api.generated.TONDeDustSwapProviderConfig import io.ton.walletkit.api.generated.TONEmbeddedRequestEvent import io.ton.walletkit.api.generated.TONEmulationResult +import io.ton.walletkit.api.generated.TONGaslessQuoteParams +import io.ton.walletkit.api.generated.TONGaslessSendParams import io.ton.walletkit.api.generated.TONGetMethodResult import io.ton.walletkit.api.generated.TONJettonsResponse import io.ton.walletkit.api.generated.TONJettonsTransferRequest @@ -58,6 +60,7 @@ import io.ton.walletkit.api.generated.TONStakingQuoteParams import io.ton.walletkit.api.generated.TONSwapParams import io.ton.walletkit.api.generated.TONSwapQuote import io.ton.walletkit.api.generated.TONSwapQuoteParams +import io.ton.walletkit.api.generated.TONTonApiGaslessProviderConfig import io.ton.walletkit.api.generated.TONTonStakersChainConfig import io.ton.walletkit.api.generated.TONTransactionEmulatedPreview import io.ton.walletkit.api.generated.TONTransactionPreviewOptions @@ -87,6 +90,7 @@ import io.ton.walletkit.engine.operations.createOmnistonSwapProvider import io.ton.walletkit.engine.operations.createSignerFromCustom import io.ton.walletkit.engine.operations.createSignerFromMnemonic import io.ton.walletkit.engine.operations.createSignerFromSecretKey +import io.ton.walletkit.engine.operations.createTonApiGaslessProvider import io.ton.walletkit.engine.operations.createTonMnemonic import io.ton.walletkit.engine.operations.createTonStakersStakingProvider import io.ton.walletkit.engine.operations.createTransferJettonTransaction @@ -96,14 +100,20 @@ import io.ton.walletkit.engine.operations.createTransferNftTransaction import io.ton.walletkit.engine.operations.createTransferTonTransaction import io.ton.walletkit.engine.operations.createWalletAdapter import io.ton.walletkit.engine.operations.disconnectSession +import io.ton.walletkit.engine.operations.gaslessSendTransaction import io.ton.walletkit.engine.operations.getBalance +import io.ton.walletkit.engine.operations.getGaslessConfig +import io.ton.walletkit.engine.operations.getGaslessMetadata +import io.ton.walletkit.engine.operations.getGaslessQuote import io.ton.walletkit.engine.operations.getJettonBalance import io.ton.walletkit.engine.operations.getJettonWalletAddress import io.ton.walletkit.engine.operations.getJettons import io.ton.walletkit.engine.operations.getNft import io.ton.walletkit.engine.operations.getNfts +import io.ton.walletkit.engine.operations.getRegisteredGaslessProviders import io.ton.walletkit.engine.operations.getRegisteredStakingProviders import io.ton.walletkit.engine.operations.getRegisteredSwapProviders +import io.ton.walletkit.engine.operations.getSignedSignMessage import io.ton.walletkit.engine.operations.getStakedBalance import io.ton.walletkit.engine.operations.getStakingProviderInfo import io.ton.walletkit.engine.operations.getStakingProviderMetadata @@ -116,14 +126,17 @@ import io.ton.walletkit.engine.operations.getTransactionPreview import io.ton.walletkit.engine.operations.getWallet import io.ton.walletkit.engine.operations.getWalletAddress import io.ton.walletkit.engine.operations.getWalletNetwork +import io.ton.walletkit.engine.operations.getWalletPublicKey import io.ton.walletkit.engine.operations.getWallets import io.ton.walletkit.engine.operations.handleNewTransaction import io.ton.walletkit.engine.operations.handleTonConnectRequest import io.ton.walletkit.engine.operations.handleTonConnectUrl +import io.ton.walletkit.engine.operations.hasGaslessProvider import io.ton.walletkit.engine.operations.hasStakingProvider import io.ton.walletkit.engine.operations.hasSwapProvider import io.ton.walletkit.engine.operations.listSessions import io.ton.walletkit.engine.operations.mnemonicToKeyPair +import io.ton.walletkit.engine.operations.registerGaslessProvider import io.ton.walletkit.engine.operations.registerStakingProvider import io.ton.walletkit.engine.operations.registerSwapProvider import io.ton.walletkit.engine.operations.rejectConnect @@ -136,6 +149,7 @@ import io.ton.walletkit.engine.operations.removeWallet import io.ton.walletkit.engine.operations.responses.AddWalletResponse import io.ton.walletkit.engine.operations.responses.SignerInfoResponse import io.ton.walletkit.engine.operations.sendTransaction +import io.ton.walletkit.engine.operations.setDefaultGaslessProvider import io.ton.walletkit.engine.operations.setDefaultStakingProvider import io.ton.walletkit.engine.operations.setDefaultSwapProvider import io.ton.walletkit.engine.operations.sign @@ -548,6 +562,11 @@ internal class WebViewWalletKitEngine private constructor( override suspend fun getJettonWalletAddress(walletId: String, jettonAddress: String): String = rpcClient.getJettonWalletAddress(walletId, jettonAddress) + override suspend fun getWalletPublicKey(walletId: String): String = rpcClient.getWalletPublicKey(walletId) + + override suspend fun getSignedSignMessage(walletId: String, request: TONTransactionRequest): String = + rpcClient.getSignedSignMessage(walletId, request) + override suspend fun createOmnistonSwapProvider(config: TONOmnistonSwapProviderConfig?): String = rpcClient.createOmnistonSwapProvider(config) @@ -603,6 +622,29 @@ internal class WebViewWalletKitEngine private constructor( override suspend fun buildSwapTransaction(params: TONSwapParams): TONTransactionRequest = rpcClient.buildSwapTransaction(params) + override suspend fun createTonApiGaslessProvider(config: TONTonApiGaslessProviderConfig?): String = + rpcClient.createTonApiGaslessProvider(config) + + override suspend fun registerGaslessProvider(providerId: String) = rpcClient.registerGaslessProvider(providerId) + + override suspend fun setDefaultGaslessProvider(providerId: String) = + rpcClient.setDefaultGaslessProvider(providerId) + + override suspend fun getRegisteredGaslessProviders(): List = rpcClient.getRegisteredGaslessProviders() + + override suspend fun hasGaslessProvider(providerId: String): Boolean = rpcClient.hasGaslessProvider(providerId) + + override suspend fun getGaslessMetadata(providerId: String?) = rpcClient.getGaslessMetadata(providerId) + + override suspend fun getGaslessConfig(network: TONNetwork?, providerId: String?) = + rpcClient.getGaslessConfig(network, providerId) + + override suspend fun getGaslessQuote(params: TONGaslessQuoteParams, providerId: String?) = + rpcClient.getGaslessQuote(params, providerId) + + override suspend fun gaslessSendTransaction(params: TONGaslessSendParams, providerId: String?) = + rpcClient.gaslessSendTransaction(params, providerId) + override suspend fun createTonStakersStakingProvider(chainConfig: Map?): String = rpcClient.createTonStakersStakingProvider(chainConfig) diff --git a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/operations/GaslessOperations.kt b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/operations/GaslessOperations.kt new file mode 100644 index 00000000..55e3ee7b --- /dev/null +++ b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/operations/GaslessOperations.kt @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2025 TonTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package io.ton.walletkit.engine.operations + +import io.ton.walletkit.api.generated.TONGaslessConfig +import io.ton.walletkit.api.generated.TONGaslessProviderMetadata +import io.ton.walletkit.api.generated.TONGaslessQuote +import io.ton.walletkit.api.generated.TONGaslessQuoteParams +import io.ton.walletkit.api.generated.TONGaslessSendParams +import io.ton.walletkit.api.generated.TONGaslessSendResponse +import io.ton.walletkit.api.generated.TONNetwork +import io.ton.walletkit.api.generated.TONTonApiGaslessProviderConfig +import io.ton.walletkit.engine.infrastructure.BridgeRpcClient +import io.ton.walletkit.engine.infrastructure.callTyped +import io.ton.walletkit.engine.operations.requests.CreateTonApiGaslessProviderRequest +import io.ton.walletkit.engine.operations.requests.GaslessSendTransactionRequest +import io.ton.walletkit.engine.operations.requests.GetGaslessConfigRequest +import io.ton.walletkit.engine.operations.requests.GetGaslessMetadataRequest +import io.ton.walletkit.engine.operations.requests.GetGaslessQuoteRequest +import io.ton.walletkit.engine.operations.requests.HasGaslessProviderRequest +import io.ton.walletkit.engine.operations.requests.RegisterGaslessProviderRequest +import io.ton.walletkit.engine.operations.requests.SetDefaultGaslessProviderRequest +import io.ton.walletkit.engine.operations.responses.HasProviderResponse +import io.ton.walletkit.engine.operations.responses.ProviderIdResponse +import io.ton.walletkit.engine.operations.responses.ProviderIdsResponse +import io.ton.walletkit.internal.constants.BridgeMethodConstants +import kotlinx.serialization.json.Json + +internal suspend fun BridgeRpcClient.createTonApiGaslessProvider(config: TONTonApiGaslessProviderConfig?): String = + callTyped( + BridgeMethodConstants.METHOD_CREATE_TONAPI_GASLESS_PROVIDER, + CreateTonApiGaslessProviderRequest( + config = config?.let { Json.encodeToJsonElement(TONTonApiGaslessProviderConfig.serializer(), it) }, + ), + ).providerId + +internal suspend fun BridgeRpcClient.registerGaslessProvider(providerId: String) { + send(BridgeMethodConstants.METHOD_REGISTER_GASLESS_PROVIDER, RegisterGaslessProviderRequest(providerId)) +} + +internal suspend fun BridgeRpcClient.setDefaultGaslessProvider(providerId: String) { + send(BridgeMethodConstants.METHOD_SET_DEFAULT_GASLESS_PROVIDER, SetDefaultGaslessProviderRequest(providerId)) +} + +internal suspend fun BridgeRpcClient.getRegisteredGaslessProviders(): List = + callTyped(BridgeMethodConstants.METHOD_GET_REGISTERED_GASLESS_PROVIDERS).providerIds + +internal suspend fun BridgeRpcClient.hasGaslessProvider(providerId: String): Boolean = + callTyped( + BridgeMethodConstants.METHOD_HAS_GASLESS_PROVIDER, + HasGaslessProviderRequest(providerId), + ).result + +internal suspend fun BridgeRpcClient.getGaslessMetadata(providerId: String?): TONGaslessProviderMetadata = + callTyped( + BridgeMethodConstants.METHOD_GET_GASLESS_METADATA, + GetGaslessMetadataRequest(providerId), + ) + +internal suspend fun BridgeRpcClient.getGaslessConfig( + network: TONNetwork?, + providerId: String?, +): TONGaslessConfig = callTyped( + BridgeMethodConstants.METHOD_GET_GASLESS_CONFIG, + GetGaslessConfigRequest( + network = network?.let { json.encodeToJsonElement(TONNetwork.serializer(), it) }, + providerId = providerId, + ), +) + +internal suspend fun BridgeRpcClient.getGaslessQuote( + params: TONGaslessQuoteParams, + providerId: String?, +): TONGaslessQuote = callTyped( + BridgeMethodConstants.METHOD_GET_GASLESS_QUOTE, + GetGaslessQuoteRequest( + params = json.encodeToJsonElement(TONGaslessQuoteParams.serializer(), params), + providerId = providerId, + ), +) + +internal suspend fun BridgeRpcClient.gaslessSendTransaction( + params: TONGaslessSendParams, + providerId: String?, +): TONGaslessSendResponse = callTyped( + BridgeMethodConstants.METHOD_GASLESS_SEND_TRANSACTION, + GaslessSendTransactionRequest( + params = json.encodeToJsonElement(TONGaslessSendParams.serializer(), params), + providerId = providerId, + ), +) diff --git a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/operations/WalletOperations.kt b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/operations/WalletOperations.kt index 6cc14702..138165fa 100644 --- a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/operations/WalletOperations.kt +++ b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/operations/WalletOperations.kt @@ -24,6 +24,7 @@ package io.ton.walletkit.engine.operations import io.ton.walletkit.WalletKitBridgeException import io.ton.walletkit.api.generated.TONNetwork import io.ton.walletkit.api.generated.TONSignatureDomain +import io.ton.walletkit.api.generated.TONTransactionRequest import io.ton.walletkit.engine.infrastructure.BridgeRpcClient import io.ton.walletkit.engine.infrastructure.callTyped import io.ton.walletkit.engine.infrastructure.callTypedOrNull @@ -32,6 +33,7 @@ import io.ton.walletkit.engine.operations.requests.CreateAdapterRequest import io.ton.walletkit.engine.operations.requests.CreateSignerFromCustomRequest import io.ton.walletkit.engine.operations.requests.CreateSignerFromMnemonicRequest import io.ton.walletkit.engine.operations.requests.CreateSignerFromSecretKeyRequest +import io.ton.walletkit.engine.operations.requests.GetSignedSignMessageRequest import io.ton.walletkit.engine.operations.requests.WalletIdRequest import io.ton.walletkit.engine.operations.responses.AdapterInfoResponse import io.ton.walletkit.engine.operations.responses.AddWalletResponse @@ -99,6 +101,20 @@ internal suspend fun BridgeRpcClient.getWalletAddress(walletId: String): String internal suspend fun BridgeRpcClient.getWalletNetwork(walletId: String): TONNetwork = callTyped(BridgeMethodConstants.METHOD_GET_WALLET_NETWORK, WalletIdRequest(walletId = walletId)) +internal suspend fun BridgeRpcClient.getWalletPublicKey(walletId: String): String = + callTyped(BridgeMethodConstants.METHOD_GET_WALLET_PUBLIC_KEY, WalletIdRequest(walletId = walletId)) + +internal suspend fun BridgeRpcClient.getSignedSignMessage( + walletId: String, + request: TONTransactionRequest, +): String = callTyped( + BridgeMethodConstants.METHOD_GET_SIGNED_SIGN_MESSAGE, + GetSignedSignMessageRequest( + walletId = walletId, + request = json.encodeToJsonElement(TONTransactionRequest.serializer(), request), + ), +) + internal suspend fun BridgeRpcClient.removeWallet(walletId: String) { send(BridgeMethodConstants.METHOD_REMOVE_WALLET, WalletIdRequest(walletId = walletId)) } diff --git a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/operations/requests/GaslessRequests.kt b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/operations/requests/GaslessRequests.kt new file mode 100644 index 00000000..7658b6fe --- /dev/null +++ b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/operations/requests/GaslessRequests.kt @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2025 TonTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package io.ton.walletkit.engine.operations.requests + +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.JsonElement + +/** + * Internal bridge request models for gasless operations. + * + * @suppress Internal bridge communication only. + */ + +@Serializable +internal data class CreateTonApiGaslessProviderRequest( + val config: JsonElement? = null, +) + +@Serializable +internal data class RegisterGaslessProviderRequest( + val providerId: String, +) + +@Serializable +internal data class SetDefaultGaslessProviderRequest( + val providerId: String, +) + +@Serializable +internal data class HasGaslessProviderRequest( + val providerId: String, +) + +@Serializable +internal data class GetGaslessMetadataRequest( + val providerId: String? = null, +) + +@Serializable +internal data class GetGaslessConfigRequest( + val network: JsonElement? = null, + val providerId: String? = null, +) + +@Serializable +internal data class GetGaslessQuoteRequest( + val params: JsonElement, + val providerId: String? = null, +) + +@Serializable +internal data class GaslessSendTransactionRequest( + val params: JsonElement, + val providerId: String? = null, +) diff --git a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/operations/requests/WalletRequests.kt b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/operations/requests/WalletRequests.kt index 33eaa148..fb9df855 100644 --- a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/operations/requests/WalletRequests.kt +++ b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/operations/requests/WalletRequests.kt @@ -24,6 +24,7 @@ package io.ton.walletkit.engine.operations.requests import io.ton.walletkit.api.generated.TONNetwork import io.ton.walletkit.api.generated.TONSignatureDomain import kotlinx.serialization.Serializable +import kotlinx.serialization.json.JsonElement /** * Internal bridge request models for wallet operations. @@ -42,6 +43,12 @@ internal data class WalletIdRequest( val walletId: String, ) +@Serializable +internal data class GetSignedSignMessageRequest( + val walletId: String, + val request: JsonElement, +) + @Serializable internal data class CreateSignerFromMnemonicRequest( val mnemonic: List, diff --git a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/gasless/TONGaslessManager.kt b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/gasless/TONGaslessManager.kt new file mode 100644 index 00000000..03deac41 --- /dev/null +++ b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/gasless/TONGaslessManager.kt @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2025 TonTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package io.ton.walletkit.gasless + +import io.ton.walletkit.api.generated.TONGaslessConfig +import io.ton.walletkit.api.generated.TONGaslessProviderMetadata +import io.ton.walletkit.api.generated.TONGaslessQuote +import io.ton.walletkit.api.generated.TONGaslessQuoteParams +import io.ton.walletkit.api.generated.TONGaslessSendParams +import io.ton.walletkit.api.generated.TONGaslessSendResponse +import io.ton.walletkit.api.generated.TONNetwork +import io.ton.walletkit.engine.WalletKitEngine + +internal class TONGaslessManager( + private val engine: WalletKitEngine, +) : ITONGaslessManager { + + override suspend fun registerProvider(provider: TONGaslessProvider) = + engine.registerGaslessProvider(provider.providerId) + + override suspend fun setDefaultProvider(provider: TONGaslessProvider) = + engine.setDefaultGaslessProvider(provider.providerId) + + override suspend fun providers(): List = + engine.getRegisteredGaslessProviders().map { TONGaslessProvider(it) } + + override suspend fun hasProvider(provider: TONGaslessProvider): Boolean = + engine.hasGaslessProvider(provider.providerId) + + override suspend fun getMetadata(provider: TONGaslessProvider?): TONGaslessProviderMetadata = + engine.getGaslessMetadata(provider?.providerId) + + override suspend fun getConfig(network: TONNetwork?, provider: TONGaslessProvider?): TONGaslessConfig = + engine.getGaslessConfig(network, provider?.providerId) + + override suspend fun getQuote(params: TONGaslessQuoteParams, provider: TONGaslessProvider?): TONGaslessQuote = + engine.getGaslessQuote(params, provider?.providerId) + + override suspend fun sendTransaction( + params: TONGaslessSendParams, + provider: TONGaslessProvider?, + ): TONGaslessSendResponse = engine.gaslessSendTransaction(params, provider?.providerId) +} diff --git a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/internal/constants/BridgeMethodConstants.kt b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/internal/constants/BridgeMethodConstants.kt index 535db127..7078e009 100644 --- a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/internal/constants/BridgeMethodConstants.kt +++ b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/internal/constants/BridgeMethodConstants.kt @@ -72,6 +72,12 @@ internal object BridgeMethodConstants { /** Method name for getting a wallet's network. */ const val METHOD_GET_WALLET_NETWORK = "getWalletNetwork" + /** Method name for getting a wallet's public key. */ + const val METHOD_GET_WALLET_PUBLIC_KEY = "getWalletPublicKey" + + /** Method name for proactively signing a set of messages (used by gasless relay flows). */ + const val METHOD_GET_SIGNED_SIGN_MESSAGE = "getSignedSignMessage" + /** * Method name for removing a wallet. */ @@ -326,6 +332,35 @@ internal object BridgeMethodConstants { */ const val METHOD_REGISTER_KOTLIN_SWAP_PROVIDER = "registerKotlinSwapProvider" + // Gasless methods + + /** Create a TonAPI gasless provider instance. */ + const val METHOD_CREATE_TONAPI_GASLESS_PROVIDER = "createTonApiGaslessProvider" + + /** Register a previously created gasless provider with the gasless manager. */ + const val METHOD_REGISTER_GASLESS_PROVIDER = "registerGaslessProvider" + + /** Set the default gasless provider. */ + const val METHOD_SET_DEFAULT_GASLESS_PROVIDER = "setDefaultGaslessProvider" + + /** Get all registered gasless provider IDs. */ + const val METHOD_GET_REGISTERED_GASLESS_PROVIDERS = "getRegisteredGaslessProviders" + + /** Check if a gasless provider is registered. */ + const val METHOD_HAS_GASLESS_PROVIDER = "hasGaslessProvider" + + /** Get static metadata for a registered gasless provider. */ + const val METHOD_GET_GASLESS_METADATA = "getGaslessMetadata" + + /** Fetch the relayer config (relay address + accepted fee assets). */ + const val METHOD_GET_GASLESS_CONFIG = "getGaslessConfig" + + /** Quote fees and obtain relayer-wrapped messages for signing. */ + const val METHOD_GET_GASLESS_QUOTE = "getGaslessQuote" + + /** Submit a signed transaction BoC to the relayer. */ + const val METHOD_GASLESS_SEND_TRANSACTION = "gaslessSendTransaction" + // Staking methods /** Create a TonStakers staking provider instance. */ diff --git a/TONWalletKit-Android/impl/src/test/java/io/ton/walletkit/engine/operations/SwapOperationsTest.kt b/TONWalletKit-Android/impl/src/test/java/io/ton/walletkit/engine/operations/SwapOperationsTest.kt index 821b2a5b..5cf6b07c 100644 --- a/TONWalletKit-Android/impl/src/test/java/io/ton/walletkit/engine/operations/SwapOperationsTest.kt +++ b/TONWalletKit-Android/impl/src/test/java/io/ton/walletkit/engine/operations/SwapOperationsTest.kt @@ -286,7 +286,7 @@ class SwapOperationsTest : OperationsTestBase() { quote = swapQuoteModel(), userAddress = TONUserFriendlyAddress(USER_ADDRESS), destinationAddress = TONUserFriendlyAddress(USER_ADDRESS), - slippageBps = 100.0, + slippageBps = 100, ) rpcClient.buildSwapTransaction(params) From 23925351953bbacac969b163f4140e53612d224e Mon Sep 17 00:00:00 2001 From: Dmitrii Nikulin Date: Tue, 9 Jun 2026 17:41:27 +0300 Subject: [PATCH 2/9] feat: include responseDestination in TONJettonsTransferRequest --- .../viewmodel/WalletOperationsViewModel.kt | 16 +- .../generated/TONJettonsTransferRequest.kt | 4 + .../TONTonApiGaslessProviderConfig.kt | 20 +- .../walletkit/walletkit-android-bridge.mjs | 390 +++++++++--------- 4 files changed, 212 insertions(+), 218 deletions(-) diff --git a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/WalletOperationsViewModel.kt b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/WalletOperationsViewModel.kt index 1a63abdf..3d1a48a4 100644 --- a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/WalletOperationsViewModel.kt +++ b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/WalletOperationsViewModel.kt @@ -85,19 +85,7 @@ class WalletOperationsViewModel( } } - /** - * Send a local transaction (TON transfer). - * This creates a transaction request that will trigger the approval flow. - * - * This uses the standard JS WalletKit API: - * 1. wallet.createTransferTonTransaction(params) - creates transaction content - * 2. kit.handleNewTransaction(wallet, transaction) - triggers approval flow - * - * @param walletAddress The sender wallet address - * @param recipient The recipient address - * @param amount The amount in TON (will be converted to nanoTON) - * @param comment Optional comment for the transaction - */ + /** Build and send a transfer: TON, USDT, or gasless USDT (relayer covers the gas). */ fun sendLocalTransaction( walletAddress: String, recipient: String, @@ -165,11 +153,13 @@ class WalletOperationsViewModel( gaslessManager.setDefaultProvider(provider) } + val config = gaslessManager.getConfig(network = wallet.network) val transfer = wallet.transferJettonTransaction( TONJettonsTransferRequest( jettonAddress = TONUserFriendlyAddress(USDT_MASTER), transferAmount = toUsdtRawUnits(amount), recipientAddress = TONUserFriendlyAddress(recipient), + responseDestination = config.relayAddress, ), ) val quote = gaslessManager.getQuote( diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONJettonsTransferRequest.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONJettonsTransferRequest.kt index 503746c4..61bf1611 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONJettonsTransferRequest.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONJettonsTransferRequest.kt @@ -38,6 +38,7 @@ import kotlinx.serialization.Serializable * @param jettonAddress * @param transferAmount * @param recipientAddress + * @param responseDestination * @param comment Human-readable comment attached to the transfer */ @Serializable @@ -52,6 +53,9 @@ data class TONJettonsTransferRequest( @SerialName(value = "recipientAddress") val recipientAddress: io.ton.walletkit.model.TONUserFriendlyAddress, + @SerialName(value = "responseDestination") + val responseDestination: io.ton.walletkit.model.TONUserFriendlyAddress? = null, + /* Human-readable comment attached to the transfer */ @SerialName(value = "comment") val comment: kotlin.String? = null, diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTonApiGaslessProviderConfig.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTonApiGaslessProviderConfig.kt index 9400a3b9..837cc0be 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTonApiGaslessProviderConfig.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTonApiGaslessProviderConfig.kt @@ -38,7 +38,9 @@ import kotlinx.serialization.Serializable * @param chains Per-chain settings keyed by `Network#chainId`. * @param providerId Provider id. Defaults to `tonapi`. * @param sendRetries Number of send retries on transient errors. Defaults to 5. - * @param sendRetryDelayMs Delay between send retries in ms. Defaults to 2000. + * @param sendRetryDelayMs Delay between send retries in ms. Defaults to 1000. + * @param quoteRetries Number of quote retries on transient errors (5xx / network). Defaults to 5. + * @param quoteRetryDelayMs Fixed delay between quote retries in ms. Defaults to 1000. * @param configCacheTtlMs TTL for the in-memory `/v2/gasless/config` cache (ms). Defaults to 5 minutes. Set to `0` to disable caching. */ @Serializable @@ -54,15 +56,23 @@ data class TONTonApiGaslessProviderConfig( /* Number of send retries on transient errors. Defaults to 5. */ @SerialName(value = "sendRetries") - val sendRetries: kotlin.Double? = null, + val sendRetries: kotlin.Int? = null, - /* Delay between send retries in ms. Defaults to 2000. */ + /* Delay between send retries in ms. Defaults to 1000. */ @SerialName(value = "sendRetryDelayMs") - val sendRetryDelayMs: kotlin.Double? = null, + val sendRetryDelayMs: kotlin.Int? = null, + + /* Number of quote retries on transient errors (5xx / network). Defaults to 5. */ + @SerialName(value = "quoteRetries") + val quoteRetries: kotlin.Int? = null, + + /* Fixed delay between quote retries in ms. Defaults to 1000. */ + @SerialName(value = "quoteRetryDelayMs") + val quoteRetryDelayMs: kotlin.Int? = null, /* TTL for the in-memory `/v2/gasless/config` cache (ms). Defaults to 5 minutes. Set to `0` to disable caching. */ @SerialName(value = "configCacheTtlMs") - val configCacheTtlMs: kotlin.Double? = null, + val configCacheTtlMs: kotlin.Int? = null, ) { diff --git a/TONWalletKit-Android/impl/src/main/assets/walletkit/walletkit-android-bridge.mjs b/TONWalletKit-Android/impl/src/main/assets/walletkit/walletkit-android-bridge.mjs index 2cef7d7c..f5502331 100644 --- a/TONWalletKit-Android/impl/src/main/assets/walletkit/walletkit-android-bridge.mjs +++ b/TONWalletKit-Android/impl/src/main/assets/walletkit/walletkit-android-bridge.mjs @@ -25016,17 +25016,17 @@ function createStorageAdapter(config = {}) { if (typeof localStorage !== "undefined") try { return new LocalStorageAdapter(config); } catch (error) { - log$41.warn("Failed to create LocalStorageAdapter, falling back to memory", { error }); + log$40.warn("Failed to create LocalStorageAdapter, falling back to memory", { error }); } if (config.allowMemory) return new MemoryStorageAdapter(config); else throw new Error("No storage adapter available"); } -var log$41; +var log$40; var init_adapters = __esmMin((() => { init_Logger(); init_local(); init_memory(); - log$41 = globalLogger.createChild("StorageAdapter"); + log$40 = globalLogger.createChild("StorageAdapter"); })); //#endregion //#region ../walletkit/dist/esm/storage/adapters/extension.js @@ -25078,10 +25078,10 @@ var init_extension = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/storage/Storage.js -var log$40, Storage; +var log$39, Storage; var init_Storage = __esmMin((() => { init_Logger(); - log$40 = globalLogger.createChild("Storage"); + log$39 = globalLogger.createChild("Storage"); Storage = class { adapter; constructor(adapter) { @@ -25098,7 +25098,7 @@ var init_Storage = __esmMin((() => { if (value === null) return null; return JSON.parse(value); } catch (error) { - log$40.warn("Failed to parse stored value", { + log$39.warn("Failed to parse stored value", { key, error }); @@ -25115,7 +25115,7 @@ var init_Storage = __esmMin((() => { const serialized = JSON.stringify(value); await this.adapter.set(key, serialized); } catch (error) { - log$40.error("Failed to serialize value for storage", { + log$39.error("Failed to serialize value for storage", { key, error }); @@ -25498,11 +25498,11 @@ var init_WalletManager = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/core/TONConnectStoredSessionManager.js -var log$39, TONConnectStoredSessionManager; +var log$38, TONConnectStoredSessionManager; var init_TONConnectStoredSessionManager = __esmMin((() => { init_esm$2(); init_Logger(); - log$39 = globalLogger.createChild("TONConnectStoredSessionManager"); + log$38 = globalLogger.createChild("TONConnectStoredSessionManager"); TONConnectStoredSessionManager = class { sessions = /* @__PURE__ */ new Map(); storage; @@ -25635,16 +25635,16 @@ var init_TONConnectStoredSessionManager = __esmMin((() => { const wallet = this.walletManager.getWallet(session.walletId); if (wallet) session.walletAddress = wallet.getAddress(); else { - log$39.warn("Session Wallet not found for session", { sessionId: session.sessionId }); + log$38.warn("Session Wallet not found for session", { sessionId: session.sessionId }); continue; } } this.sessions.set(session.sessionId, session); } - log$39.debug("Loaded session metadata", { count: storedSessions.length }); + log$38.debug("Loaded session metadata", { count: storedSessions.length }); } } catch (error) { - log$39.warn("Failed to load sessions from storage", { error }); + log$38.warn("Failed to load sessions from storage", { error }); } } /** @@ -25655,7 +25655,7 @@ var init_TONConnectStoredSessionManager = __esmMin((() => { const sessionsToStore = Array.from(this.sessions.values()); await this.storage.set(this.storageKey, sessionsToStore); } catch (error) { - log$39.warn("Failed to persist sessions to storage", { error }); + log$38.warn("Failed to persist sessions to storage", { error }); } } async migrateSessions() { @@ -27198,16 +27198,6 @@ function getDeviceInfoForWallet(walletAdapter, deviceInfoOptions) { }); return baseDeviceInfo; } -/** -* Extract maximum number of outgoing messages from wallet features -* @param features - Array of wallet features from getSupportedFeatures() -* @returns Maximum number of outgoing messages the wallet can handle (default: 1) -*/ -function getMaxOutgoingMessages(features) { - const sendTransactionFeature = features.find((feature) => feature !== "SendTransaction" && feature.name === "SendTransaction"); - if (sendTransactionFeature) return sendTransactionFeature.maxMessages; - return 1; -} function addLegacySendTransactionFeature(options) { const features = options.features; const hasSendTransactionString = features.some((feature) => feature === "SendTransaction"); @@ -27282,7 +27272,7 @@ var init_JSBridgeInjector = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/core/BridgeManager.js -var log$37, BridgeManager; +var log$36, BridgeManager; var init_BridgeManager = __esmMin((() => { init_esm$2(); init_dist$1(); @@ -27290,7 +27280,7 @@ var init_BridgeManager = __esmMin((() => { init_uuid(); init_errors$4(); init_JSBridgeInjector(); - log$37 = globalLogger.createChild("BridgeManager"); + log$36 = globalLogger.createChild("BridgeManager"); BridgeManager = class { config; bridgeProvider; @@ -27332,7 +27322,7 @@ var init_BridgeManager = __esmMin((() => { this.walletKitConfig = walletKitConfig; this.jsBridgeTransport = config?.jsBridgeTransport; if (this.config.bridgeUrl && !this.config.disableHttpConnection) this.bridgeProvider = new C(this.config.bridgeUrl, this.queueBridgeEvent.bind(this), (error) => { - log$37.error("Bridge listener error", { error: error.toString() }); + log$36.error("Bridge listener error", { error: error.toString() }); this.analytics?.emitBridgeClientConnectError({ error_message: `${error?.toString() || "Unknown error"}${error?.errorCode ? ` (Code: ${error?.errorCode})` : ""}`, trace_id: error?.traceId, @@ -27346,12 +27336,12 @@ var init_BridgeManager = __esmMin((() => { */ async start() { if (this.isActive === true) { - log$37.warn("Bridge already started"); + log$36.warn("Bridge already started"); return; } this.isActive = true; if (this.isConnected === true) { - log$37.warn("Bridge already connected"); + log$36.warn("Bridge already connected"); return; } try { @@ -27363,7 +27353,7 @@ var init_BridgeManager = __esmMin((() => { } } catch (error) { this.isActive = false; - log$37.error("Failed to start bridge", { error }); + log$36.error("Failed to start bridge", { error }); throw error; } const requestProcessing = () => { @@ -27376,10 +27366,10 @@ var init_BridgeManager = __esmMin((() => { * Create new session for a dApp connection */ async createSession(appSessionId) { - log$37.info("[BRIDGE] Creating session", { appSessionId }); + log$36.info("[BRIDGE] Creating session", { appSessionId }); if (!await this.sessionManager.getSession(appSessionId)) throw new WalletKitError(ERROR_CODES.SESSION_NOT_FOUND, `Session not found`, void 0, { appSessionId }); if (this.bridgeProvider && this.isConnected) { - log$37.info("[BRIDGE] Updating clients"); + log$36.info("[BRIDGE] Updating clients"); await this.updateClients(); } } @@ -27388,7 +27378,7 @@ var init_BridgeManager = __esmMin((() => { */ async removeSession(appSessionId) { if (this.bridgeProvider && this.isConnected) await this.updateClients(); - log$37.debug("Session removed", { appSessionId }); + log$36.debug("Session removed", { appSessionId }); } /** * Send response to dApp @@ -27413,12 +27403,12 @@ var init_BridgeManager = __esmMin((() => { } try { await this.bridgeProvider.send(response, sessionCrypto, sessionId, { traceId: event?.traceId }); - log$37.debug("Response sent successfully", { + log$36.debug("Response sent successfully", { sessionId, requestId: event.id }); } catch (error) { - log$37.error("Failed to send response through bridge", { + log$36.error("Failed to send response through bridge", { sessionId, requestId: event.id, error @@ -27500,7 +27490,7 @@ var init_BridgeManager = __esmMin((() => { await this.bridgeProvider?.restoreConnection(clients, { lastEventId: this.lastEventId }); this.isConnected = true; this.reconnectAttempts = 0; - log$37.info("Bridge connected successfully"); + log$36.info("Bridge connected successfully"); if (this.analytics) { const client = clients[0]; this.analytics.emitBridgeClientConnectEstablished({ @@ -27509,7 +27499,7 @@ var init_BridgeManager = __esmMin((() => { }); } } catch (error) { - log$37.error("Bridge connection failed", { error: error?.toString() }); + log$36.error("Bridge connection failed", { error: error?.toString() }); this.analytics?.emitBridgeClientConnectError({ error_message: `${error?.toString() || "Unknown error"}${error?.errorCode ? ` (Code: ${error?.errorCode})` : ""}`, trace_id: error?.traceId ?? connectTraceId, @@ -27518,9 +27508,9 @@ var init_BridgeManager = __esmMin((() => { if (!this.config.disableHttpConnection) { if (this.reconnectAttempts < (this.config.maxReconnectAttempts || 5)) { this.reconnectAttempts++; - log$37.info("Bridge reconnection attempt", { attempt: this.reconnectAttempts }); + log$36.info("Bridge reconnection attempt", { attempt: this.reconnectAttempts }); setTimeout(() => { - this.connectToSSEBridge().catch((error) => log$37.error("Bridge reconnection failed", { error })); + this.connectToSSEBridge().catch((error) => log$36.error("Bridge reconnection failed", { error })); }, this.config.reconnectInterval); } } @@ -27541,10 +27531,10 @@ var init_BridgeManager = __esmMin((() => { * Add client to existing bridge connection */ async updateClients() { - log$37.debug("Updating clients"); + log$36.debug("Updating clients"); if (this.bridgeProvider) { const clients = await this.getClients(); - log$37.info("[BRIDGE] Restoring connection", { clients: clients.length }); + log$36.info("[BRIDGE] Restoring connection", { clients: clients.length }); await this.bridgeProvider.restoreConnection(clients, { lastEventId: this.lastEventId }); } } @@ -27552,17 +27542,17 @@ var init_BridgeManager = __esmMin((() => { * Queue incoming bridge events for processing */ queueBridgeEvent(event) { - log$37.debug("Bridge event queued", { + log$36.debug("Bridge event queued", { eventId: event?.id, event }); this.eventQueue.push(event); this.processBridgeEvents().catch((error) => { - log$37.error("Error in background event processing", { error }); + log$36.error("Error in background event processing", { error }); }); } queueJsBridgeEvent(messageInfo, event) { - log$37.debug("JS Bridge event queued", { eventId: messageInfo?.messageId }); + log$36.debug("JS Bridge event queued", { eventId: messageInfo?.messageId }); if (!event) return; if (!event.traceId) event.traceId = v7(); if (event.method == "connect") this.eventQueue.push({ @@ -27591,7 +27581,7 @@ var init_BridgeManager = __esmMin((() => { walletId: messageInfo.walletId }); this.processBridgeEvents().catch((error) => { - log$37.error("Error in background event processing", { error }); + log$36.error("Error in background event processing", { error }); }); } /** @@ -27603,7 +27593,7 @@ var init_BridgeManager = __esmMin((() => { */ async processBridgeEvents() { if (this.isProcessing) { - log$37.debug("Event processing already in progress, skipping"); + log$36.debug("Event processing already in progress, skipping"); return; } this.isProcessing = true; @@ -27616,7 +27606,7 @@ var init_BridgeManager = __esmMin((() => { } } } catch (error) { - log$37.error("Error during event processing", { error }); + log$36.error("Error during event processing", { error }); this.isProcessing = false; this.restartConnection(); return; @@ -27629,7 +27619,7 @@ var init_BridgeManager = __esmMin((() => { */ async handleBridgeEvent(event) { try { - log$37.info("Bridge event received", { event }); + log$36.info("Bridge event received", { event }); const rawEvent = { id: event.id || crypto.randomUUID(), method: event.method || "unknown", @@ -27683,12 +27673,12 @@ var init_BridgeManager = __esmMin((() => { try { await this.eventStore.storeEvent(rawEvent); if (this.eventEmitter) this.eventEmitter.emit("bridgeStorageUpdated", {}, "bridge-manager"); - log$37.info("Event stored durably", { + log$36.info("Event stored durably", { eventId: rawEvent.id, method: rawEvent.method }); } catch (error) { - log$37.error("Failed to store event durably", { + log$36.error("Failed to store event durably", { eventId: rawEvent.id, error: error.message }); @@ -27697,13 +27687,13 @@ var init_BridgeManager = __esmMin((() => { method: rawEvent.method }); } - log$37.info("Bridge event processed", { rawEvent }); + log$36.info("Bridge event processed", { rawEvent }); if (event?.lastEventId && event.lastEventId !== this.lastEventId) { this.lastEventId = event.lastEventId; await this.saveLastEventId(); } } catch (error) { - log$37.error("Error handling bridge event", { error }); + log$36.error("Error handling bridge event", { error }); } } /** @@ -27714,11 +27704,11 @@ var init_BridgeManager = __esmMin((() => { const savedEventId = await this.storage.get(this.storageKey); if (savedEventId) { this.lastEventId = savedEventId; - log$37.debug("Loaded last event ID from storage", { lastEventId: this.lastEventId }); + log$36.debug("Loaded last event ID from storage", { lastEventId: this.lastEventId }); } } catch (error) { const storageError = WalletKitError.fromError(ERROR_CODES.STORAGE_READ_FAILED, "Failed to load last event ID from storage", error); - log$37.warn("Failed to load last event ID from storage", { error: storageError }); + log$36.warn("Failed to load last event ID from storage", { error: storageError }); } } /** @@ -27728,11 +27718,11 @@ var init_BridgeManager = __esmMin((() => { try { if (this.lastEventId) { await this.storage.set(this.storageKey, this.lastEventId); - log$37.debug("Saved last event ID to storage", { lastEventId: this.lastEventId }); + log$36.debug("Saved last event ID to storage", { lastEventId: this.lastEventId }); } } catch (error) { const storageError = WalletKitError.fromError(ERROR_CODES.STORAGE_WRITE_FAILED, "Failed to save last event ID to storage", error); - log$37.warn("Failed to save last event ID to storage", { error: storageError }); + log$36.warn("Failed to save last event ID to storage", { error: storageError }); } } }; @@ -27796,14 +27786,14 @@ async function fetchManifest(manifestUrl, proxyUrl) { manifest: null, manifestFetchErrorCode: CONNECT_EVENT_ERROR_CODES$1.MANIFEST_CONTENT_ERROR }; - log$36.info("Direct manifest fetch failed, trying proxy", { manifestUrl }); + log$35.info("Direct manifest fetch failed, trying proxy", { manifestUrl }); return tryFetchManifest(`${proxyUrl}${manifestUrl}`); } async function tryFetchManifest(url) { try { const response = await fetch(url); if (!response.ok) { - log$36.error("Failed to fetch manifest not ok", { + log$35.error("Failed to fetch manifest not ok", { url, status: response.status }); @@ -27817,7 +27807,7 @@ async function tryFetchManifest(url) { manifestFetchErrorCode: void 0 }; } catch (e) { - log$36.error("Failed to fetch manifest catched", { + log$35.error("Failed to fetch manifest catched", { url, error: e }); @@ -27827,23 +27817,23 @@ async function tryFetchManifest(url) { }; } } -var log$36; +var log$35; var init_manifest = __esmMin((() => { init_esm$2(); init_url(); init_Logger(); - log$36 = globalLogger.createChild("ManifestUtils"); + log$35 = globalLogger.createChild("ManifestUtils"); })); //#endregion //#region ../walletkit/dist/esm/handlers/ConnectHandler.js -var log$35, ConnectHandler; +var log$34, ConnectHandler; var init_ConnectHandler = __esmMin((() => { init_esm$2(); init_Logger(); init_BasicHandler(); init_url(); init_manifest(); - log$35 = globalLogger.createChild("ConnectHandler"); + log$34 = globalLogger.createChild("ConnectHandler"); ConnectHandler = class extends BasicHandler { config; analytics; @@ -27864,7 +27854,7 @@ var init_ConnectHandler = __esmMin((() => { manifest = result.manifest; manifestFetchErrorCode = result.manifestFetchErrorCode; } catch (error) { - log$35.warn("Failed to fetch manifest", { error }); + log$34.warn("Failed to fetch manifest", { error }); } const preview = this.createPreview(event, manifestUrl, manifest, manifestFetchErrorCode); const connectEvent = { @@ -27925,14 +27915,14 @@ var init_ConnectHandler = __esmMin((() => { if (!finalManifestFetchErrorCode && dAppUrl) try { const parsedDAppUrl = new URL(dAppUrl); if (!isValidHost(parsedDAppUrl.host)) { - log$35.warn("Invalid dApp URL in manifest - invalid host format", { + log$34.warn("Invalid dApp URL in manifest - invalid host format", { dAppUrl, host: parsedDAppUrl.host }); finalManifestFetchErrorCode = CONNECT_EVENT_ERROR_CODES$1.MANIFEST_CONTENT_ERROR; } } catch (_) { - log$35.warn("Invalid dApp URL in manifest - failed to parse", { dAppUrl }); + log$34.warn("Invalid dApp URL in manifest - failed to parse", { dAppUrl }); finalManifestFetchErrorCode = CONNECT_EVENT_ERROR_CODES$1.MANIFEST_CONTENT_ERROR; } } @@ -28596,7 +28586,7 @@ async function resolveItemsToMessages(items, wallet) { messages.push(resolveNftItem(item, wallet)); break; default: - log$34.warn("Unknown item type, skipping", { item }); + log$33.warn("Unknown item type, skipping", { item }); break; } return messages; @@ -28649,13 +28639,13 @@ function resolveNftItem(item, wallet) { mode: { flags: [SendModeFlag.IGNORE_ERRORS, SendModeFlag.PAY_GAS_SEPARATELY] } }; } -var import_dist$33, log$34; +var import_dist$33, log$33; var init_itemsResolver = __esmMin((() => { import_dist$33 = require_dist$1(); init_models(); init_messageBuilders(); init_Logger(); - log$34 = globalLogger.createChild("ItemsResolver"); + log$33 = globalLogger.createChild("ItemsResolver"); })); //#endregion //#region ../walletkit/dist/esm/utils/events.js @@ -28717,7 +28707,7 @@ function parseTonConnectTransactionRequest(event, wallet) { validation: validateTransactionRequestForWallet(request, wallet, event.isLocal) }; } catch (error) { - log$33.error("Failed to parse transaction request", { error }); + log$32.error("Failed to parse transaction request", { error }); errors.push("Failed to parse transaction request"); return { result: void 0, @@ -28728,7 +28718,7 @@ function parseTonConnectTransactionRequest(event, wallet) { }; } } -var log$33; +var log$32; var init_events = __esmMin((() => { init_errors$4(); init_transactionValidators(); @@ -28736,7 +28726,7 @@ var init_events = __esmMin((() => { init_transaction$1(); init_itemsResolver(); init_Logger(); - log$33 = globalLogger.createChild("EventsUtils"); + log$32 = globalLogger.createChild("EventsUtils"); })); //#endregion //#region ../../node_modules/.pnpm/@noble+hashes@2.2.0/node_modules/@noble/hashes/utils.js @@ -31070,7 +31060,7 @@ async function createTransactionPreviewIfPossible(config, client, request, walle try { preview = await CallForSuccess(() => createTransactionPreview(client, request, wallet, options)); } catch (error) { - log$32.error("Failed to create transaction preview", { error }); + log$31.error("Failed to create transaction preview", { error }); preview = { error: { code: ERROR_CODES.UNKNOWN_EMULATION_ERROR, @@ -31081,7 +31071,7 @@ async function createTransactionPreviewIfPossible(config, client, request, walle } return preview; } -var import_dist$20, log$32, SIGN_MODE_EMULATION_VALUE; +var import_dist$20, log$31, SIGN_MODE_EMULATION_VALUE; var init_transactionPreview = __esmMin((() => { import_dist$20 = require_dist$1(); init_map_emulation_trace(); @@ -31090,7 +31080,7 @@ var init_transactionPreview = __esmMin((() => { init_retry(); init_models(); init_Logger(); - log$32 = globalLogger.createChild("TransactionPreview"); + log$31 = globalLogger.createChild("TransactionPreview"); SIGN_MODE_EMULATION_VALUE = 2000000000n; })); //#endregion @@ -31290,53 +31280,49 @@ var init_toncenter$2 = __esmMin((() => { init_getTransactionStatus(); })); //#endregion -//#region ../walletkit/dist/esm/utils/checkSignMessageSupport.js +//#region ../walletkit/dist/esm/utils/features/getMaxOutgoingMessages.js /** -* Throws {@link SupportError} (with a `code` discriminating the -* specific failure) when the connected wallet's advertised `Feature[]` cannot -* satisfy a SignMessage request — feature missing, `maxMessages` too low, -* missing extra-currency / item-type support. Logs a warning when the wallet -* didn't declare `maxMessages` (request may still be rejected by the wallet). +* Copyright (c) TonTech. +* +* This source code is licensed under the MIT license found in the +* LICENSE file in the root directory of this source tree. +* */ -function checkSignMessageSupport(features, options) { - const signMessageFeature = features.find((feature) => !!feature && typeof feature === "object" && feature.name === "SignMessage"); - if (!signMessageFeature) throw new SupportError("Wallet doesn't support SignMessage feature.", SupportErrorCode.NotSupported); - if (options.requireExtraCurrencies && !signMessageFeature.extraCurrencySupported) throw new SupportError("Wallet is not able to handle such SignMessage request. Extra currencies support is required.", SupportErrorCode.ExtraCurrencyNotSupported); - if (options.requiredItemTypes?.length) { - const supportedTypes = signMessageFeature.itemTypes ?? []; - const unsupportedTypes = options.requiredItemTypes.filter((type) => !supportedTypes.includes(type)); - if (unsupportedTypes.length) throw new SupportError(signMessageFeature.itemTypes ? `Wallet doesn't support item types: ${unsupportedTypes.join(", ")} in SignMessage.` : "Wallet doesn't support structured items in SignMessage.", SupportErrorCode.ItemTypesNotSupported); - } - if (signMessageFeature.maxMessages !== void 0) { - if (signMessageFeature.maxMessages < options.requiredMessagesNumber) throw new SupportError(`Wallet is not able to handle such SignMessage request. Max support messages number is ${signMessageFeature.maxMessages}, but ${options.requiredMessagesNumber} is required.`, SupportErrorCode.TooManyMessages); - return; - } - log$31.warn("Connected wallet didn't provide information about max allowed messages in the SignMessage request. Request may be rejected by the wallet."); +/** +* Maximum number of messages the wallet can handle for the given feature. +* Defaults to the `SendTransaction` cap (used e.g. by the swap flow); pass +* `'SignMessage'` for the gasless flow, whose cap lives on a different feature. +* @param features - Array of wallet features from getSupportedFeatures() +* @returns Maximum number of messages the wallet can handle (default: 1 when the +* feature is not advertised) +*/ +function getMaxOutgoingMessages(features, featureName = "SendTransaction") { + return features.find((f) => typeof f === "object" && f.name === featureName)?.maxMessages ?? 1; } -var log$31, SupportErrorCode, SupportError; -var init_checkSignMessageSupport = __esmMin((() => { - init_Logger(); - log$31 = globalLogger.createChild("checkSignMessageSupport"); - (function(SupportErrorCode) { - /** Wallet did not advertise the `SignMessage` feature at all. */ - SupportErrorCode["NotSupported"] = "NOT_SUPPORTED"; - /** Wallet's `maxMessages` cap is lower than `requiredMessagesNumber`. */ - SupportErrorCode["TooManyMessages"] = "TOO_MANY_MESSAGES"; - /** Request includes extra-currency transfers, wallet's feature flag is not set. */ - SupportErrorCode["ExtraCurrencyNotSupported"] = "EXTRA_CURRENCY_NOT_SUPPORTED"; - /** Request requires structured item types the wallet did not list. */ - SupportErrorCode["ItemTypesNotSupported"] = "ITEM_TYPES_NOT_SUPPORTED"; - })(SupportErrorCode || (SupportErrorCode = {})); - SupportError = class extends Error { - code; - feature; - unsupportedItemTypes; - constructor(message, code) { - super(message); - this.name = "SupportError"; - this.code = code; - } - }; +var init_getMaxOutgoingMessages = __esmMin((() => {})); +//#endregion +//#region ../walletkit/dist/esm/utils/features/hasSignMessageSupport.js +/** +* Copyright (c) TonTech. +* +* This source code is licensed under the MIT license found in the +* LICENSE file in the root directory of this source tree. +* +*/ +/** Find the wallet's advertised `SignMessage` feature, if any. */ +function findSignMessageFeature(features) { + return features.find((feature) => !!feature && typeof feature === "object" && feature.name === "SignMessage"); +} +/** Whether the connected wallet advertises the `SignMessage` feature. */ +function hasSignMessageSupport(features) { + return findSignMessageFeature(features) !== void 0; +} +var init_hasSignMessageSupport = __esmMin((() => {})); +//#endregion +//#region ../walletkit/dist/esm/utils/features/index.js +var init_features = __esmMin((() => { + init_getMaxOutgoingMessages(); + init_hasSignMessageSupport(); })); //#endregion //#region ../walletkit/dist/esm/utils/index.js @@ -31368,7 +31354,7 @@ var init_utils$2 = __esmMin((() => { init_toncenter$2(); init_getNormalizedExtMessageHash(); init_manifest(); - init_checkSignMessageSupport(); + init_features(); })); //#endregion //#region ../walletkit/dist/esm/handlers/TransactionHandler.js @@ -33229,7 +33215,7 @@ var init_jetton$1 = __esmMin((() => { payload: createJettonTransferPayload({ amount: BigInt(params.transferAmount), destination: params.recipientAddress, - responseDestination: this.getAddress(), + responseDestination: params.responseDestination || this.getAddress(), comment: params.comment }), fromAddress: this.getAddress() @@ -36501,6 +36487,27 @@ var init_TonWalletKit = __esmMin((() => { this.isInitialized = false; } /** + * Add a provider + */ + registerProvider(input) { + const provider = typeof input === "function" ? input(this.createFactoryContext()) : input; + switch (provider.type) { + case "swap": + this.swapManager.registerProvider(provider); + break; + case "staking": + this.stakingManager.registerProvider(provider); + break; + case "streaming": + this.streamingManager.registerProvider(provider); + break; + case "gasless": + this.gaslessManager.registerProvider(provider); + break; + default: throw new Error("Unknown provider type"); + } + } + /** * Jettons API access */ get jettons() { @@ -39287,8 +39294,6 @@ var esm_exports = /* @__PURE__ */ __exportAll({ StorageEventProcessor: () => StorageEventProcessor, StorageEventStore: () => StorageEventStore, StreamingManager: () => StreamingManager, - SupportError: () => SupportError, - SupportErrorCode: () => SupportErrorCode, SwapError: () => SwapError, SwapErrorCode: () => SwapErrorCode, SwapManager: () => SwapManager, @@ -39316,7 +39321,6 @@ var esm_exports = /* @__PURE__ */ __exportAll({ asAddressFriendly: () => asAddressFriendly, asBase64: () => asBase64, asHex: () => asHex, - checkSignMessageSupport: () => checkSignMessageSupport, compareAddress: () => compareAddress, createCommentPayload: () => createCommentPayload, createCommentPayloadBase64: () => createCommentPayloadBase64, @@ -39345,6 +39349,7 @@ var esm_exports = /* @__PURE__ */ __exportAll({ getNftsFromClient: () => getNftsFromClient, getNormalizedExtMessageHash: () => getNormalizedExtMessageHash, getTransactionStatus: () => getTransactionStatus, + hasSignMessageSupport: () => hasSignMessageSupport, isValidAddress: () => isValidAddress, packActionsList: () => packActionsList, parseUnits: () => parseUnits, @@ -39404,7 +39409,7 @@ var init_esm = __esmMin((() => { init_withTimeout(); init_validation(); init_getDefaultWalletConfig(); - init_checkSignMessageSupport(); + init_features(); init_Signer(); init_tvmStack(); init_messageTypes(); @@ -45701,63 +45706,6 @@ var DEFAULT_METADATA = { url: "https://tonapi.io" }; //#endregion -//#region ../walletkit/dist/esm/defi/gasless/tonapi/helpers.js -init_models(); -init_TonClientError(); -/** -* Reconstruct a `Network` instance from a chainId string. Used to map -* `Object.keys(chainConfig)` back to `Network` objects. -*/ -var networkFromChainId = (chainId) => { - switch (chainId) { - case Network.mainnet().chainId: return Network.mainnet(); - case Network.testnet().chainId: return Network.testnet(); - case Network.tetra().chainId: return Network.tetra(); - default: return Network.custom(chainId); - } -}; -/** -* Decide whether a `/v2/gasless/send` failure is worth retrying. -* -* Retry on 5xx server errors and HTTP 408/429 (timeout / rate limit), and on -* non-HTTP errors (network failures: fetch `TypeError`, `AbortError`). -* -* Skip retry on 4xx client errors — they will not improve, and re-sending a -* BoC that was actually accepted would burn relayer gas on a duplicate -* (although the wallet's seqno guard prevents on-chain double-spend). -*/ -var isTransientError = (error) => { - if (error instanceof TonClientError) return error.status >= 500 || error.status === 408 || error.status === 429; - return error instanceof Error; -}; -//#endregion -//#region ../walletkit/dist/esm/defi/gasless/tonapi/mappers/map-gasless-config.js -init_address$1(); -/** -* Wire → domain: map TonAPI's `/v2/gasless/config` response to `GaslessConfig`. -* Bundles both the relay address (for jetton-transfer `responseDestination`) -* and the assets the relayer accepts as fee payment. -*/ -var mapGaslessConfig = (raw) => ({ - relayAddress: asAddressFriendly(raw.relay_address), - supportedAssets: raw.gas_jettons.map((jetton) => ({ address: asAddressFriendly(jetton.master_id) })) -}); -//#endregion -//#region ../walletkit/dist/esm/defi/gasless/tonapi/mappers/map-gasless-error.js -init_TonClientError(); -init_errors(); -var TONAPI_UNSUPPORTED_FEE_ASSET_CODE = 4e4; -var TONAPI_FEE_JETTON_UNRESOLVED_CODE = 40007; -var mapTonApiGaslessError = (error, fallbackCode, fallbackMessage) => { - if (error instanceof GaslessError) return error; - if (error instanceof TonClientError) { - const body = error.details; - if (body && typeof body === "object" && body.error_code === TONAPI_UNSUPPORTED_FEE_ASSET_CODE) return new GaslessError(body.error ?? "Fee asset is not supported by the gasless relayer", GaslessErrorCode.UnsupportedFeeAsset, error); - if (body && typeof body === "object" && body.error_code === TONAPI_FEE_JETTON_UNRESOLVED_CODE) return new GaslessError("You have never held the selected fee asset, so the relayer could not resolve its jetton wallet. Choose a fee asset you already own.", GaslessErrorCode.FeeAssetNotOwned, error); - } - return new GaslessError(error instanceof Error ? error.message : fallbackMessage, fallbackCode, error); -}; -//#endregion //#region ../walletkit/dist/esm/defi/gasless/tonapi/utils.js /** * Copyright (c) TonTech. @@ -45766,6 +45714,8 @@ var mapTonApiGaslessError = (error, fallbackCode, fallbackMessage) => { * LICENSE file in the root directory of this source tree. * */ +init_models(); +init_TonClientError(); init_base64(); init_hex(); init_errors(); @@ -45806,6 +45756,48 @@ var internalBocToExternalMessageBoc = (internalBoc) => { body }))).endCell(); }; +/** +* Reconstruct a `Network` instance from a chainId string. Used to map +* `Object.keys(chainConfig)` back to `Network` objects. +*/ +var networkFromChainId = (chainId) => { + switch (chainId) { + case Network.mainnet().chainId: return Network.mainnet(); + case Network.testnet().chainId: return Network.testnet(); + case Network.tetra().chainId: return Network.tetra(); + default: return Network.custom(chainId); + } +}; +/** +* Decide whether a TonAPI gasless request failure (`/v2/gasless/estimate` or +* `/v2/gasless/send`) is worth retrying. +* +* Retry on 5xx server errors and HTTP 408/429 (timeout / rate limit), and on +* non-HTTP errors (network failures: fetch `TypeError`, `AbortError`). +*/ +var isTransientError = (error) => { + if (error instanceof TonClientError) return error.status >= 500 || error.status === 408 || error.status === 429; + return error instanceof Error; +}; +//#endregion +//#region ../walletkit/dist/esm/defi/gasless/tonapi/mappers/map-gasless-config.js +init_address$1(); +/** +* Wire → domain: map TonAPI's `/v2/gasless/config` response to `GaslessConfig`. +* Bundles both the relay address (for jetton-transfer `responseDestination`) +* and the assets the relayer accepts as fee payment. +*/ +var mapGaslessConfig = (raw) => ({ + relayAddress: asAddressFriendly(raw.relay_address), + supportedAssets: raw.gas_jettons.map((jetton) => ({ address: asAddressFriendly(jetton.master_id) })) +}); +//#endregion +//#region ../walletkit/dist/esm/defi/gasless/tonapi/mappers/map-gasless-error.js +init_errors(); +var mapTonApiGaslessError = (error, fallbackCode, fallbackMessage) => { + if (error instanceof GaslessError) return error; + return new GaslessError(error instanceof Error ? error.message : fallbackMessage, fallbackCode, error); +}; //#endregion //#region ../walletkit/dist/esm/defi/gasless/tonapi/mappers/map-gasless-quote.js /** @@ -45901,7 +45893,7 @@ var mapGaslessSend = (raw) => { init_index_min(); init_ApiClientTonApi(); init_Logger(); -init_delay(); +init_retry(); init_errors(); init_GaslessProvider(); var log = globalLogger.createChild("TonApiGaslessProvider"); @@ -45930,6 +45922,8 @@ var TonApiGaslessProvider = class TonApiGaslessProvider extends GaslessProvider clients = {}; sendRetries; sendRetryDelayMs; + quoteRetries; + quoteRetryDelayMs; configCacheTtlMs; configCache; /** @@ -45939,8 +45933,10 @@ var TonApiGaslessProvider = class TonApiGaslessProvider extends GaslessProvider super(); this.chainConfig = chainConfig; this.providerId = options.providerId ?? "tonapi"; - this.sendRetries = options.sendRetries ?? 3; - this.sendRetryDelayMs = options.sendRetryDelayMs ?? 2e3; + this.sendRetries = options.sendRetries ?? 5; + this.sendRetryDelayMs = options.sendRetryDelayMs ?? 1e3; + this.quoteRetries = options.quoteRetries ?? 5; + this.quoteRetryDelayMs = options.quoteRetryDelayMs ?? 1e3; this.configCacheTtlMs = options.configCacheTtlMs ?? 3e5; if (this.configCacheTtlMs > 0) this.configCache = new U({ max: Math.max(1, Object.keys(chainConfig).length), @@ -46001,7 +45997,8 @@ var TonApiGaslessProvider = class TonApiGaslessProvider extends GaslessProvider const masterId = import_dist$1.Address.parse(params.feeAsset).toRawString(); const body = buildGaslessQuoteRequest(params); try { - return mapGaslessQuote(await this.getClient(params.network).postJson(`/v2/gasless/estimate/${masterId}`, body), params.network); + const http = this.getClient(params.network); + return mapGaslessQuote(await CallForSuccess(() => http.postJson(`/v2/gasless/estimate/${masterId}`, body), this.quoteRetries + 1, this.quoteRetryDelayMs, isTransientError), params.network); } catch (error) { log.error("Failed to quote gasless transaction", { error, @@ -46013,25 +46010,18 @@ var TonApiGaslessProvider = class TonApiGaslessProvider extends GaslessProvider async sendTransaction(params) { const body = buildGaslessSendRequest(params); const http = this.getClient(params.network); - const attemptsTotal = this.sendRetries + 1; - let attempt = 0; - let lastError; - while (attempt < attemptsTotal) try { + try { return { - ...mapGaslessSend(await http.postJson("/v2/gasless/send", body)), + ...mapGaslessSend(await CallForSuccess(() => http.postJson("/v2/gasless/send", body), this.sendRetries + 1, this.sendRetryDelayMs, isTransientError)), internalBoc: params.internalBoc }; } catch (error) { - lastError = error; - if (attempt === attemptsTotal - 1 || !isTransientError(error)) break; - await delay(this.sendRetryDelayMs * 2 ** attempt); - attempt++; - } - log.error("Failed to send gasless transaction", { - error: lastError, - chainId: params.network.chainId - }); - throw mapTonApiGaslessError(lastError, GaslessErrorCode.SendFailed, "Failed to send gasless transaction"); + log.error("Failed to send gasless transaction", { + error, + chainId: params.network.chainId + }); + throw mapTonApiGaslessError(error, GaslessErrorCode.SendFailed, "Failed to send gasless transaction"); + } } getClient(network) { const chainId = network.chainId; From 61da9f8c611a37b8c252ab4e605afe56a35749bb Mon Sep 17 00:00:00 2001 From: Dmitrii Nikulin Date: Mon, 15 Jun 2026 12:15:39 +0300 Subject: [PATCH 3/9] chore: update mjs --- TONWalletKit-Android/gradle.properties | 2 +- .../walletkit/walletkit-android-bridge.mjs | 1269 ++++++----------- 2 files changed, 465 insertions(+), 806 deletions(-) diff --git a/TONWalletKit-Android/gradle.properties b/TONWalletKit-Android/gradle.properties index 4eab9b05..31f1b307 100644 --- a/TONWalletKit-Android/gradle.properties +++ b/TONWalletKit-Android/gradle.properties @@ -9,4 +9,4 @@ POM_ARTIFACT_ID=walletkit # Pinned kit tag for the committed WalletKit bridge bundle. CI verifies the bundle matches a # build of this tag; bump it by hand, then rebuild and recommit the bundle. -WALLETKIT_BRIDGE_TAG=v1.0.0-alpha.3 +WALLETKIT_BRIDGE_TAG=v1.0.0 diff --git a/TONWalletKit-Android/impl/src/main/assets/walletkit/walletkit-android-bridge.mjs b/TONWalletKit-Android/impl/src/main/assets/walletkit/walletkit-android-bridge.mjs index f5502331..b25ef25e 100644 --- a/TONWalletKit-Android/impl/src/main/assets/walletkit/walletkit-android-bridge.mjs +++ b/TONWalletKit-Android/impl/src/main/assets/walletkit/walletkit-android-bridge.mjs @@ -4027,7 +4027,7 @@ var require_nacl_fast = /* @__PURE__ */ __commonJSMin(((exports, module) => { })(typeof module !== "undefined" && module.exports ? module.exports : self.nacl = self.nacl || {}); })); //#endregion -//#region ../../node_modules/.pnpm/@tonconnect+protocol@2.5.0-alpha.1/node_modules/@tonconnect/protocol/lib/esm/index.mjs +//#region ../../node_modules/.pnpm/@tonconnect+protocol@3.0.0/node_modules/@tonconnect/protocol/lib/esm/index.mjs function encodeUint8Array$1(value, urlSafe) { const encoded = import_nacl_util$1.default.encodeBase64(value); if (!urlSafe) return encoded; @@ -4183,16 +4183,22 @@ function decodeEmbeddedRequestParam(reqParam) { const json = fromBase64Url(reqParam); return decodeWireEmbeddedRequest(JSON.parse(json)); } +/** Concatenate two byte arrays into a new `Uint8Array`. */ function concatUint8Arrays(buffer1, buffer2) { const mergedArray = new Uint8Array(buffer1.length + buffer2.length); mergedArray.set(buffer1); mergedArray.set(buffer2, buffer1.length); return mergedArray; } +/** +* Split `array` at `index` and return the two halves as fresh +* `Uint8Array`s. +*/ function splitToUint8Arrays(array, index) { if (index >= array.length) throw new Error("Index is out of buffer"); return [array.slice(0, index), array.slice(index)]; } +/** Hex-encode a byte array, lowercase, no `0x` prefix. */ function toHexString(byteArray) { let hexString = ""; byteArray.forEach((byte) => { @@ -4200,6 +4206,9 @@ function toHexString(byteArray) { }); return hexString; } +/** +* Inverse of {@link toHexString}. Throws when `hexString` has an odd length. +*/ function hexToByteArray$1(hexString) { if (hexString.length % 2 !== 0) throw new Error(`Cannot convert ${hexString} to bytesArray`); const result = new Uint8Array(hexString.length / 2); @@ -4211,30 +4220,49 @@ var init_esm$2 = __esmMin((() => { import_nacl_util$1 = /* @__PURE__ */ __toESM(require_nacl_util(), 1); import_nacl_fast$2 = /* @__PURE__ */ __toESM(require_nacl_fast(), 1); (function(CONNECT_EVENT_ERROR_CODES) { + /** Unexpected wallet-side failure. */ CONNECT_EVENT_ERROR_CODES[CONNECT_EVENT_ERROR_CODES["UNKNOWN_ERROR"] = 0] = "UNKNOWN_ERROR"; + /** Request payload is malformed. */ CONNECT_EVENT_ERROR_CODES[CONNECT_EVENT_ERROR_CODES["BAD_REQUEST_ERROR"] = 1] = "BAD_REQUEST_ERROR"; + /** Wallet could not fetch the `tonconnect-manifest.json`. */ CONNECT_EVENT_ERROR_CODES[CONNECT_EVENT_ERROR_CODES["MANIFEST_NOT_FOUND_ERROR"] = 2] = "MANIFEST_NOT_FOUND_ERROR"; + /** Manifest was fetched but fails JSON / schema validation. */ CONNECT_EVENT_ERROR_CODES[CONNECT_EVENT_ERROR_CODES["MANIFEST_CONTENT_ERROR"] = 3] = "MANIFEST_CONTENT_ERROR"; + /** Wallet does not know the app / session. */ CONNECT_EVENT_ERROR_CODES[CONNECT_EVENT_ERROR_CODES["UNKNOWN_APP_ERROR"] = 100] = "UNKNOWN_APP_ERROR"; + /** User explicitly declined the connect prompt. */ CONNECT_EVENT_ERROR_CODES[CONNECT_EVENT_ERROR_CODES["USER_REJECTS_ERROR"] = 300] = "USER_REJECTS_ERROR"; + /** Wallet does not support the requested method. */ CONNECT_EVENT_ERROR_CODES[CONNECT_EVENT_ERROR_CODES["METHOD_NOT_SUPPORTED"] = 400] = "METHOD_NOT_SUPPORTED"; })(CONNECT_EVENT_ERROR_CODES$1 || (CONNECT_EVENT_ERROR_CODES$1 = {})); (function(CONNECT_ITEM_ERROR_CODES) { + /** Unexpected wallet-side failure. */ CONNECT_ITEM_ERROR_CODES[CONNECT_ITEM_ERROR_CODES["UNKNOWN_ERROR"] = 0] = "UNKNOWN_ERROR"; + /** Wallet does not support this connect item. */ CONNECT_ITEM_ERROR_CODES[CONNECT_ITEM_ERROR_CODES["METHOD_NOT_SUPPORTED"] = 400] = "METHOD_NOT_SUPPORTED"; })(CONNECT_ITEM_ERROR_CODES$1 || (CONNECT_ITEM_ERROR_CODES$1 = {})); (function(SEND_TRANSACTION_ERROR_CODES) { + /** Unexpected wallet-side failure. */ SEND_TRANSACTION_ERROR_CODES[SEND_TRANSACTION_ERROR_CODES["UNKNOWN_ERROR"] = 0] = "UNKNOWN_ERROR"; + /** Request payload is malformed. */ SEND_TRANSACTION_ERROR_CODES[SEND_TRANSACTION_ERROR_CODES["BAD_REQUEST_ERROR"] = 1] = "BAD_REQUEST_ERROR"; + /** Wallet does not know the dApp / session. */ SEND_TRANSACTION_ERROR_CODES[SEND_TRANSACTION_ERROR_CODES["UNKNOWN_APP_ERROR"] = 100] = "UNKNOWN_APP_ERROR"; + /** User explicitly declined the transaction. */ SEND_TRANSACTION_ERROR_CODES[SEND_TRANSACTION_ERROR_CODES["USER_REJECTS_ERROR"] = 300] = "USER_REJECTS_ERROR"; + /** Wallet does not support the method. */ SEND_TRANSACTION_ERROR_CODES[SEND_TRANSACTION_ERROR_CODES["METHOD_NOT_SUPPORTED"] = 400] = "METHOD_NOT_SUPPORTED"; })(SEND_TRANSACTION_ERROR_CODES$1 || (SEND_TRANSACTION_ERROR_CODES$1 = {})); (function(SIGN_DATA_ERROR_CODES) { + /** Unexpected wallet-side failure. */ SIGN_DATA_ERROR_CODES[SIGN_DATA_ERROR_CODES["UNKNOWN_ERROR"] = 0] = "UNKNOWN_ERROR"; + /** Invalid request payload. */ SIGN_DATA_ERROR_CODES[SIGN_DATA_ERROR_CODES["BAD_REQUEST_ERROR"] = 1] = "BAD_REQUEST_ERROR"; + /** Wallet does not know the dApp / session. */ SIGN_DATA_ERROR_CODES[SIGN_DATA_ERROR_CODES["UNKNOWN_APP_ERROR"] = 100] = "UNKNOWN_APP_ERROR"; + /** User explicitly declined. */ SIGN_DATA_ERROR_CODES[SIGN_DATA_ERROR_CODES["USER_REJECTS_ERROR"] = 300] = "USER_REJECTS_ERROR"; + /** Wallet does not support `signData` method or the requested `type`. */ SIGN_DATA_ERROR_CODES[SIGN_DATA_ERROR_CODES["METHOD_NOT_SUPPORTED"] = 400] = "METHOD_NOT_SUPPORTED"; })(SIGN_DATA_ERROR_CODES$1 || (SIGN_DATA_ERROR_CODES$1 = {})); (function(DISCONNECT_ERROR_CODES) { @@ -4244,10 +4272,15 @@ var init_esm$2 = __esmMin((() => { DISCONNECT_ERROR_CODES[DISCONNECT_ERROR_CODES["METHOD_NOT_SUPPORTED"] = 400] = "METHOD_NOT_SUPPORTED"; })(DISCONNECT_ERROR_CODES$1 || (DISCONNECT_ERROR_CODES$1 = {})); (function(SIGN_MESSAGE_ERROR_CODES) { + /** Unexpected wallet-side failure. */ SIGN_MESSAGE_ERROR_CODES[SIGN_MESSAGE_ERROR_CODES["UNKNOWN_ERROR"] = 0] = "UNKNOWN_ERROR"; + /** Invalid request payload. */ SIGN_MESSAGE_ERROR_CODES[SIGN_MESSAGE_ERROR_CODES["BAD_REQUEST_ERROR"] = 1] = "BAD_REQUEST_ERROR"; + /** Wallet does not know the dApp / session. */ SIGN_MESSAGE_ERROR_CODES[SIGN_MESSAGE_ERROR_CODES["UNKNOWN_APP_ERROR"] = 100] = "UNKNOWN_APP_ERROR"; + /** User explicitly declined. */ SIGN_MESSAGE_ERROR_CODES[SIGN_MESSAGE_ERROR_CODES["USER_REJECTS_ERROR"] = 300] = "USER_REJECTS_ERROR"; + /** Wallet does not support `signMessage`. */ SIGN_MESSAGE_ERROR_CODES[SIGN_MESSAGE_ERROR_CODES["METHOD_NOT_SUPPORTED"] = 400] = "METHOD_NOT_SUPPORTED"; })(SIGN_MESSAGE_ERROR_CODES || (SIGN_MESSAGE_ERROR_CODES = {})); (function(CHAIN) { @@ -4259,6 +4292,10 @@ var init_esm$2 = __esmMin((() => { decode: decode$1 }; SessionCrypto = class { + /** + * Reuse an existing {@link KeyPair} (resuming a session) or generate a + * fresh one (`crypto_box.keyPair()`) when omitted. + */ constructor(keyPair) { this.nonceLength = 24; this.keyPair = keyPair ? this.createKeypairFromString(keyPair) : this.createKeypair(); @@ -4276,17 +4313,31 @@ var init_esm$2 = __esmMin((() => { createNonce() { return import_nacl_fast$2.default.randomBytes(this.nonceLength); } + /** + * Encrypt `message` for `receiverPublicKey` using a fresh 24-byte random + * nonce. Returns `nonce || ciphertext` as raw bytes; base64-encode this + * value before placing it in the bridge `POST /message` body. + */ encrypt(message, receiverPublicKey) { const encodedMessage = new TextEncoder().encode(message); const nonce = this.createNonce(); return concatUint8Arrays(nonce, import_nacl_fast$2.default.box(encodedMessage, nonce, receiverPublicKey, this.keyPair.secretKey)); } + /** + * Decrypt the `nonce || ciphertext` blob received from the bridge. + * Throws if `nacl.box.open` rejects the message — wrong key, truncated + * input or tampered ciphertext. + */ decrypt(message, senderPublicKey) { const [nonce, internalMessage] = splitToUint8Arrays(message, this.nonceLength); const decrypted = import_nacl_fast$2.default.box.open(internalMessage, nonce, senderPublicKey, this.keyPair.secretKey); if (!decrypted) throw new Error(`Decryption error: \n message: ${message.toString()} \n sender pubkey: ${senderPublicKey.toString()} \n keypair pubkey: ${this.keyPair.publicKey.toString()} \n keypair secretkey: ${this.keyPair.secretKey.toString()}`); return new TextDecoder().decode(decrypted); } + /** + * Export the underlying keypair as a {@link KeyPair} of hex strings. + * Persist this in dApp / wallet storage to resume the session later. + */ stringifyKeypair() { return { publicKey: toHexString(this.keyPair.publicKey), @@ -24905,7 +24956,7 @@ async function CallForSuccess(toCall, attempts = 20, delayMs = 100, shouldRetry) return await toCall(); } catch (err) { lastError = err; - if (shouldRetry && !shouldRetry(err)) throw err; + if (typeof shouldRetry === "function" && shouldRetry(err) === false) throw err; i++; await delay(delayMs); } @@ -25016,17 +25067,17 @@ function createStorageAdapter(config = {}) { if (typeof localStorage !== "undefined") try { return new LocalStorageAdapter(config); } catch (error) { - log$40.warn("Failed to create LocalStorageAdapter, falling back to memory", { error }); + log$39.warn("Failed to create LocalStorageAdapter, falling back to memory", { error }); } if (config.allowMemory) return new MemoryStorageAdapter(config); else throw new Error("No storage adapter available"); } -var log$40; +var log$39; var init_adapters = __esmMin((() => { init_Logger(); init_local(); init_memory(); - log$40 = globalLogger.createChild("StorageAdapter"); + log$39 = globalLogger.createChild("StorageAdapter"); })); //#endregion //#region ../walletkit/dist/esm/storage/adapters/extension.js @@ -25078,10 +25129,10 @@ var init_extension = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/storage/Storage.js -var log$39, Storage; +var log$38, Storage; var init_Storage = __esmMin((() => { init_Logger(); - log$39 = globalLogger.createChild("Storage"); + log$38 = globalLogger.createChild("Storage"); Storage = class { adapter; constructor(adapter) { @@ -25098,7 +25149,7 @@ var init_Storage = __esmMin((() => { if (value === null) return null; return JSON.parse(value); } catch (error) { - log$39.warn("Failed to parse stored value", { + log$38.warn("Failed to parse stored value", { key, error }); @@ -25115,7 +25166,7 @@ var init_Storage = __esmMin((() => { const serialized = JSON.stringify(value); await this.adapter.set(key, serialized); } catch (error) { - log$39.error("Failed to serialize value for storage", { + log$38.error("Failed to serialize value for storage", { key, error }); @@ -25498,11 +25549,11 @@ var init_WalletManager = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/core/TONConnectStoredSessionManager.js -var log$38, TONConnectStoredSessionManager; +var log$37, TONConnectStoredSessionManager; var init_TONConnectStoredSessionManager = __esmMin((() => { init_esm$2(); init_Logger(); - log$38 = globalLogger.createChild("TONConnectStoredSessionManager"); + log$37 = globalLogger.createChild("TONConnectStoredSessionManager"); TONConnectStoredSessionManager = class { sessions = /* @__PURE__ */ new Map(); storage; @@ -25635,16 +25686,16 @@ var init_TONConnectStoredSessionManager = __esmMin((() => { const wallet = this.walletManager.getWallet(session.walletId); if (wallet) session.walletAddress = wallet.getAddress(); else { - log$38.warn("Session Wallet not found for session", { sessionId: session.sessionId }); + log$37.warn("Session Wallet not found for session", { sessionId: session.sessionId }); continue; } } this.sessions.set(session.sessionId, session); } - log$38.debug("Loaded session metadata", { count: storedSessions.length }); + log$37.debug("Loaded session metadata", { count: storedSessions.length }); } } catch (error) { - log$38.warn("Failed to load sessions from storage", { error }); + log$37.warn("Failed to load sessions from storage", { error }); } } /** @@ -25655,7 +25706,7 @@ var init_TONConnectStoredSessionManager = __esmMin((() => { const sessionsToStore = Array.from(this.sessions.values()); await this.storage.set(this.storageKey, sessionsToStore); } catch (error) { - log$38.warn("Failed to persist sessions to storage", { error }); + log$37.warn("Failed to persist sessions to storage", { error }); } } async migrateSessions() { @@ -27272,7 +27323,7 @@ var init_JSBridgeInjector = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/core/BridgeManager.js -var log$36, BridgeManager; +var log$35, BridgeManager; var init_BridgeManager = __esmMin((() => { init_esm$2(); init_dist$1(); @@ -27280,7 +27331,7 @@ var init_BridgeManager = __esmMin((() => { init_uuid(); init_errors$4(); init_JSBridgeInjector(); - log$36 = globalLogger.createChild("BridgeManager"); + log$35 = globalLogger.createChild("BridgeManager"); BridgeManager = class { config; bridgeProvider; @@ -27322,7 +27373,7 @@ var init_BridgeManager = __esmMin((() => { this.walletKitConfig = walletKitConfig; this.jsBridgeTransport = config?.jsBridgeTransport; if (this.config.bridgeUrl && !this.config.disableHttpConnection) this.bridgeProvider = new C(this.config.bridgeUrl, this.queueBridgeEvent.bind(this), (error) => { - log$36.error("Bridge listener error", { error: error.toString() }); + log$35.error("Bridge listener error", { error: error.toString() }); this.analytics?.emitBridgeClientConnectError({ error_message: `${error?.toString() || "Unknown error"}${error?.errorCode ? ` (Code: ${error?.errorCode})` : ""}`, trace_id: error?.traceId, @@ -27336,12 +27387,12 @@ var init_BridgeManager = __esmMin((() => { */ async start() { if (this.isActive === true) { - log$36.warn("Bridge already started"); + log$35.warn("Bridge already started"); return; } this.isActive = true; if (this.isConnected === true) { - log$36.warn("Bridge already connected"); + log$35.warn("Bridge already connected"); return; } try { @@ -27353,7 +27404,7 @@ var init_BridgeManager = __esmMin((() => { } } catch (error) { this.isActive = false; - log$36.error("Failed to start bridge", { error }); + log$35.error("Failed to start bridge", { error }); throw error; } const requestProcessing = () => { @@ -27366,10 +27417,10 @@ var init_BridgeManager = __esmMin((() => { * Create new session for a dApp connection */ async createSession(appSessionId) { - log$36.info("[BRIDGE] Creating session", { appSessionId }); + log$35.info("[BRIDGE] Creating session", { appSessionId }); if (!await this.sessionManager.getSession(appSessionId)) throw new WalletKitError(ERROR_CODES.SESSION_NOT_FOUND, `Session not found`, void 0, { appSessionId }); if (this.bridgeProvider && this.isConnected) { - log$36.info("[BRIDGE] Updating clients"); + log$35.info("[BRIDGE] Updating clients"); await this.updateClients(); } } @@ -27378,7 +27429,7 @@ var init_BridgeManager = __esmMin((() => { */ async removeSession(appSessionId) { if (this.bridgeProvider && this.isConnected) await this.updateClients(); - log$36.debug("Session removed", { appSessionId }); + log$35.debug("Session removed", { appSessionId }); } /** * Send response to dApp @@ -27403,12 +27454,12 @@ var init_BridgeManager = __esmMin((() => { } try { await this.bridgeProvider.send(response, sessionCrypto, sessionId, { traceId: event?.traceId }); - log$36.debug("Response sent successfully", { + log$35.debug("Response sent successfully", { sessionId, requestId: event.id }); } catch (error) { - log$36.error("Failed to send response through bridge", { + log$35.error("Failed to send response through bridge", { sessionId, requestId: event.id, error @@ -27490,7 +27541,7 @@ var init_BridgeManager = __esmMin((() => { await this.bridgeProvider?.restoreConnection(clients, { lastEventId: this.lastEventId }); this.isConnected = true; this.reconnectAttempts = 0; - log$36.info("Bridge connected successfully"); + log$35.info("Bridge connected successfully"); if (this.analytics) { const client = clients[0]; this.analytics.emitBridgeClientConnectEstablished({ @@ -27499,7 +27550,7 @@ var init_BridgeManager = __esmMin((() => { }); } } catch (error) { - log$36.error("Bridge connection failed", { error: error?.toString() }); + log$35.error("Bridge connection failed", { error: error?.toString() }); this.analytics?.emitBridgeClientConnectError({ error_message: `${error?.toString() || "Unknown error"}${error?.errorCode ? ` (Code: ${error?.errorCode})` : ""}`, trace_id: error?.traceId ?? connectTraceId, @@ -27508,9 +27559,9 @@ var init_BridgeManager = __esmMin((() => { if (!this.config.disableHttpConnection) { if (this.reconnectAttempts < (this.config.maxReconnectAttempts || 5)) { this.reconnectAttempts++; - log$36.info("Bridge reconnection attempt", { attempt: this.reconnectAttempts }); + log$35.info("Bridge reconnection attempt", { attempt: this.reconnectAttempts }); setTimeout(() => { - this.connectToSSEBridge().catch((error) => log$36.error("Bridge reconnection failed", { error })); + this.connectToSSEBridge().catch((error) => log$35.error("Bridge reconnection failed", { error })); }, this.config.reconnectInterval); } } @@ -27531,10 +27582,10 @@ var init_BridgeManager = __esmMin((() => { * Add client to existing bridge connection */ async updateClients() { - log$36.debug("Updating clients"); + log$35.debug("Updating clients"); if (this.bridgeProvider) { const clients = await this.getClients(); - log$36.info("[BRIDGE] Restoring connection", { clients: clients.length }); + log$35.info("[BRIDGE] Restoring connection", { clients: clients.length }); await this.bridgeProvider.restoreConnection(clients, { lastEventId: this.lastEventId }); } } @@ -27542,17 +27593,17 @@ var init_BridgeManager = __esmMin((() => { * Queue incoming bridge events for processing */ queueBridgeEvent(event) { - log$36.debug("Bridge event queued", { + log$35.debug("Bridge event queued", { eventId: event?.id, event }); this.eventQueue.push(event); this.processBridgeEvents().catch((error) => { - log$36.error("Error in background event processing", { error }); + log$35.error("Error in background event processing", { error }); }); } queueJsBridgeEvent(messageInfo, event) { - log$36.debug("JS Bridge event queued", { eventId: messageInfo?.messageId }); + log$35.debug("JS Bridge event queued", { eventId: messageInfo?.messageId }); if (!event) return; if (!event.traceId) event.traceId = v7(); if (event.method == "connect") this.eventQueue.push({ @@ -27581,7 +27632,7 @@ var init_BridgeManager = __esmMin((() => { walletId: messageInfo.walletId }); this.processBridgeEvents().catch((error) => { - log$36.error("Error in background event processing", { error }); + log$35.error("Error in background event processing", { error }); }); } /** @@ -27593,7 +27644,7 @@ var init_BridgeManager = __esmMin((() => { */ async processBridgeEvents() { if (this.isProcessing) { - log$36.debug("Event processing already in progress, skipping"); + log$35.debug("Event processing already in progress, skipping"); return; } this.isProcessing = true; @@ -27606,7 +27657,7 @@ var init_BridgeManager = __esmMin((() => { } } } catch (error) { - log$36.error("Error during event processing", { error }); + log$35.error("Error during event processing", { error }); this.isProcessing = false; this.restartConnection(); return; @@ -27619,7 +27670,7 @@ var init_BridgeManager = __esmMin((() => { */ async handleBridgeEvent(event) { try { - log$36.info("Bridge event received", { event }); + log$35.info("Bridge event received", { event }); const rawEvent = { id: event.id || crypto.randomUUID(), method: event.method || "unknown", @@ -27673,12 +27724,12 @@ var init_BridgeManager = __esmMin((() => { try { await this.eventStore.storeEvent(rawEvent); if (this.eventEmitter) this.eventEmitter.emit("bridgeStorageUpdated", {}, "bridge-manager"); - log$36.info("Event stored durably", { + log$35.info("Event stored durably", { eventId: rawEvent.id, method: rawEvent.method }); } catch (error) { - log$36.error("Failed to store event durably", { + log$35.error("Failed to store event durably", { eventId: rawEvent.id, error: error.message }); @@ -27687,13 +27738,13 @@ var init_BridgeManager = __esmMin((() => { method: rawEvent.method }); } - log$36.info("Bridge event processed", { rawEvent }); + log$35.info("Bridge event processed", { rawEvent }); if (event?.lastEventId && event.lastEventId !== this.lastEventId) { this.lastEventId = event.lastEventId; await this.saveLastEventId(); } } catch (error) { - log$36.error("Error handling bridge event", { error }); + log$35.error("Error handling bridge event", { error }); } } /** @@ -27704,11 +27755,11 @@ var init_BridgeManager = __esmMin((() => { const savedEventId = await this.storage.get(this.storageKey); if (savedEventId) { this.lastEventId = savedEventId; - log$36.debug("Loaded last event ID from storage", { lastEventId: this.lastEventId }); + log$35.debug("Loaded last event ID from storage", { lastEventId: this.lastEventId }); } } catch (error) { const storageError = WalletKitError.fromError(ERROR_CODES.STORAGE_READ_FAILED, "Failed to load last event ID from storage", error); - log$36.warn("Failed to load last event ID from storage", { error: storageError }); + log$35.warn("Failed to load last event ID from storage", { error: storageError }); } } /** @@ -27718,11 +27769,11 @@ var init_BridgeManager = __esmMin((() => { try { if (this.lastEventId) { await this.storage.set(this.storageKey, this.lastEventId); - log$36.debug("Saved last event ID to storage", { lastEventId: this.lastEventId }); + log$35.debug("Saved last event ID to storage", { lastEventId: this.lastEventId }); } } catch (error) { const storageError = WalletKitError.fromError(ERROR_CODES.STORAGE_WRITE_FAILED, "Failed to save last event ID to storage", error); - log$36.warn("Failed to save last event ID to storage", { error: storageError }); + log$35.warn("Failed to save last event ID to storage", { error: storageError }); } } }; @@ -27786,14 +27837,14 @@ async function fetchManifest(manifestUrl, proxyUrl) { manifest: null, manifestFetchErrorCode: CONNECT_EVENT_ERROR_CODES$1.MANIFEST_CONTENT_ERROR }; - log$35.info("Direct manifest fetch failed, trying proxy", { manifestUrl }); + log$34.info("Direct manifest fetch failed, trying proxy", { manifestUrl }); return tryFetchManifest(`${proxyUrl}${manifestUrl}`); } async function tryFetchManifest(url) { try { const response = await fetch(url); if (!response.ok) { - log$35.error("Failed to fetch manifest not ok", { + log$34.error("Failed to fetch manifest not ok", { url, status: response.status }); @@ -27807,7 +27858,7 @@ async function tryFetchManifest(url) { manifestFetchErrorCode: void 0 }; } catch (e) { - log$35.error("Failed to fetch manifest catched", { + log$34.error("Failed to fetch manifest catched", { url, error: e }); @@ -27817,23 +27868,23 @@ async function tryFetchManifest(url) { }; } } -var log$35; +var log$34; var init_manifest = __esmMin((() => { init_esm$2(); init_url(); init_Logger(); - log$35 = globalLogger.createChild("ManifestUtils"); + log$34 = globalLogger.createChild("ManifestUtils"); })); //#endregion //#region ../walletkit/dist/esm/handlers/ConnectHandler.js -var log$34, ConnectHandler; +var log$33, ConnectHandler; var init_ConnectHandler = __esmMin((() => { init_esm$2(); init_Logger(); init_BasicHandler(); init_url(); init_manifest(); - log$34 = globalLogger.createChild("ConnectHandler"); + log$33 = globalLogger.createChild("ConnectHandler"); ConnectHandler = class extends BasicHandler { config; analytics; @@ -27854,7 +27905,7 @@ var init_ConnectHandler = __esmMin((() => { manifest = result.manifest; manifestFetchErrorCode = result.manifestFetchErrorCode; } catch (error) { - log$34.warn("Failed to fetch manifest", { error }); + log$33.warn("Failed to fetch manifest", { error }); } const preview = this.createPreview(event, manifestUrl, manifest, manifestFetchErrorCode); const connectEvent = { @@ -27915,14 +27966,14 @@ var init_ConnectHandler = __esmMin((() => { if (!finalManifestFetchErrorCode && dAppUrl) try { const parsedDAppUrl = new URL(dAppUrl); if (!isValidHost(parsedDAppUrl.host)) { - log$34.warn("Invalid dApp URL in manifest - invalid host format", { + log$33.warn("Invalid dApp URL in manifest - invalid host format", { dAppUrl, host: parsedDAppUrl.host }); finalManifestFetchErrorCode = CONNECT_EVENT_ERROR_CODES$1.MANIFEST_CONTENT_ERROR; } } catch (_) { - log$34.warn("Invalid dApp URL in manifest - failed to parse", { dAppUrl }); + log$33.warn("Invalid dApp URL in manifest - failed to parse", { dAppUrl }); finalManifestFetchErrorCode = CONNECT_EVENT_ERROR_CODES$1.MANIFEST_CONTENT_ERROR; } } @@ -28586,7 +28637,7 @@ async function resolveItemsToMessages(items, wallet) { messages.push(resolveNftItem(item, wallet)); break; default: - log$33.warn("Unknown item type, skipping", { item }); + log$32.warn("Unknown item type, skipping", { item }); break; } return messages; @@ -28639,13 +28690,13 @@ function resolveNftItem(item, wallet) { mode: { flags: [SendModeFlag.IGNORE_ERRORS, SendModeFlag.PAY_GAS_SEPARATELY] } }; } -var import_dist$33, log$33; +var import_dist$33, log$32; var init_itemsResolver = __esmMin((() => { import_dist$33 = require_dist$1(); init_models(); init_messageBuilders(); init_Logger(); - log$33 = globalLogger.createChild("ItemsResolver"); + log$32 = globalLogger.createChild("ItemsResolver"); })); //#endregion //#region ../walletkit/dist/esm/utils/events.js @@ -28707,7 +28758,7 @@ function parseTonConnectTransactionRequest(event, wallet) { validation: validateTransactionRequestForWallet(request, wallet, event.isLocal) }; } catch (error) { - log$32.error("Failed to parse transaction request", { error }); + log$31.error("Failed to parse transaction request", { error }); errors.push("Failed to parse transaction request"); return { result: void 0, @@ -28718,7 +28769,7 @@ function parseTonConnectTransactionRequest(event, wallet) { }; } } -var log$32; +var log$31; var init_events = __esmMin((() => { init_errors$4(); init_transactionValidators(); @@ -28726,7 +28777,7 @@ var init_events = __esmMin((() => { init_transaction$1(); init_itemsResolver(); init_Logger(); - log$32 = globalLogger.createChild("EventsUtils"); + log$31 = globalLogger.createChild("EventsUtils"); })); //#endregion //#region ../../node_modules/.pnpm/@noble+hashes@2.2.0/node_modules/@noble/hashes/utils.js @@ -31060,7 +31111,7 @@ async function createTransactionPreviewIfPossible(config, client, request, walle try { preview = await CallForSuccess(() => createTransactionPreview(client, request, wallet, options)); } catch (error) { - log$31.error("Failed to create transaction preview", { error }); + log$30.error("Failed to create transaction preview", { error }); preview = { error: { code: ERROR_CODES.UNKNOWN_EMULATION_ERROR, @@ -31071,7 +31122,7 @@ async function createTransactionPreviewIfPossible(config, client, request, walle } return preview; } -var import_dist$20, log$31, SIGN_MODE_EMULATION_VALUE; +var import_dist$20, log$30, SIGN_MODE_EMULATION_VALUE; var init_transactionPreview = __esmMin((() => { import_dist$20 = require_dist$1(); init_map_emulation_trace(); @@ -31080,7 +31131,7 @@ var init_transactionPreview = __esmMin((() => { init_retry(); init_models(); init_Logger(); - log$31 = globalLogger.createChild("TransactionPreview"); + log$30 = globalLogger.createChild("TransactionPreview"); SIGN_MODE_EMULATION_VALUE = 2000000000n; })); //#endregion @@ -31358,14 +31409,14 @@ var init_utils$2 = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/handlers/TransactionHandler.js -var log$30, TransactionHandler; +var log$29, TransactionHandler; var init_TransactionHandler = __esmMin((() => { init_esm$2(); init_Logger(); init_BasicHandler(); init_events(); init_utils$2(); - log$30 = globalLogger.createChild("TransactionHandler"); + log$29 = globalLogger.createChild("TransactionHandler"); TransactionHandler = class extends BasicHandler { config; walletManager; @@ -31387,7 +31438,7 @@ var init_TransactionHandler = __esmMin((() => { async handle(event) { const wallet = getWalletFromEvent(this.walletManager, event); if (!wallet) { - log$30.error("Wallet not found", { event }); + log$29.error("Wallet not found", { event }); return { error: { code: SEND_TRANSACTION_ERROR_CODES$1.UNKNOWN_APP_ERROR, @@ -31398,7 +31449,7 @@ var init_TransactionHandler = __esmMin((() => { } const requestValidation = this.parseTonConnectTransactionRequest(event, wallet); if (!requestValidation.result || !requestValidation?.validation?.isValid) { - log$30.error("Failed to parse transaction request", { + log$29.error("Failed to parse transaction request", { event, requestValidation }); @@ -31444,13 +31495,13 @@ var init_TransactionHandler = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/handlers/SignDataHandler.js -var log$29, SignDataHandler; +var log$28, SignDataHandler; var init_SignDataHandler = __esmMin((() => { init_internal(); init_BasicHandler(); init_Logger(); init_errors$4(); - log$29 = globalLogger.createChild("SignDataHandler"); + log$28 = globalLogger.createChild("SignDataHandler"); SignDataHandler = class extends BasicHandler { analytics; walletManager; @@ -31471,12 +31522,12 @@ var init_SignDataHandler = __esmMin((() => { const wallet = walletId ? this.walletManager.getWallet(walletId) : void 0; const payload = this.parseDataToSign(event); if (!payload) { - log$29.error("No data to sign found in request", { event }); + log$28.error("No data to sign found in request", { event }); throw new WalletKitError(ERROR_CODES.INVALID_REQUEST_EVENT, "No data to sign found in request", void 0, { eventId: event.id }); } const preview = this.createDataPreview(payload.data, event); if (!preview) { - log$29.error("No preview found for data", { data: payload }); + log$28.error("No preview found for data", { data: payload }); throw new WalletKitError(ERROR_CODES.RESPONSE_CREATION_FAILED, "Failed to create preview for sign data request", void 0, { eventId: event.id, data: payload @@ -31533,7 +31584,7 @@ var init_SignDataHandler = __esmMin((() => { } }; } catch (error) { - log$29.error("Error deserializing cell", { error }); + log$28.error("Error deserializing cell", { error }); return { type: "cell", value: { @@ -31547,14 +31598,14 @@ var init_SignDataHandler = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/handlers/SignMessageHandler.js -var log$28, SignMessageHandler; +var log$27, SignMessageHandler; var init_SignMessageHandler = __esmMin((() => { init_esm$2(); init_Logger(); init_BasicHandler(); init_utils$2(); init_events(); - log$28 = globalLogger.createChild("SignMessageHandler"); + log$27 = globalLogger.createChild("SignMessageHandler"); SignMessageHandler = class extends BasicHandler { config; walletManager; @@ -31576,7 +31627,7 @@ var init_SignMessageHandler = __esmMin((() => { async handle(event) { const wallet = getWalletFromEvent(this.walletManager, event); if (!wallet) { - log$28.error("Wallet not found", { event }); + log$27.error("Wallet not found", { event }); return { error: { code: SIGN_MESSAGE_ERROR_CODES.UNKNOWN_APP_ERROR, @@ -31587,7 +31638,7 @@ var init_SignMessageHandler = __esmMin((() => { } const requestValidation = this.parseTonConnectTransactionRequest(event, wallet); if (!requestValidation.result || !requestValidation?.validation?.isValid) { - log$28.error("Failed to parse sign message request", { + log$27.error("Failed to parse sign message request", { event, requestValidation }); @@ -31672,7 +31723,7 @@ var init_DisconnectHandler = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/core/EventRouter.js -var log$27, EventRouter; +var log$26, EventRouter; var init_EventRouter = __esmMin((() => { init_ConnectHandler(); init_TransactionHandler(); @@ -31681,7 +31732,7 @@ var init_EventRouter = __esmMin((() => { init_DisconnectHandler(); init_events$1(); init_Logger(); - log$27 = globalLogger.createChild("EventRouter"); + log$26 = globalLogger.createChild("EventRouter"); EventRouter = class { config; eventEmitter; @@ -31713,7 +31764,7 @@ var init_EventRouter = __esmMin((() => { async routeEvent(event) { const validation = validateBridgeEvent(event); if (!validation.isValid) { - log$27.error("Invalid bridge event", { errors: validation.errors }); + log$26.error("Invalid bridge event", { errors: validation.errors }); return; } try { @@ -31728,7 +31779,7 @@ var init_EventRouter = __esmMin((() => { try { await this.bridgeManager.sendResponse(event, result); } catch (error) { - log$27.error("Error sending response for error event", { + log$26.error("Error sending response for error event", { error, event, result @@ -31740,7 +31791,7 @@ var init_EventRouter = __esmMin((() => { break; } } catch (error) { - log$27.error("Error routing event", { error }); + log$26.error("Error routing event", { error }); throw error; } } @@ -31869,7 +31920,7 @@ function hasConnectionResult(event) { */ async function signTransactionInternal(wallet, request) { const signedBoc = await wallet.getSignedSendTransaction(request, { fakeSignature: false }); - log$26.debug("Signing transaction", { + log$25.debug("Signing transaction", { messagesNumber: request.messages.length, fromAddress: request.fromAddress, validUntil: request.validUntil @@ -31925,7 +31976,7 @@ function parseDomain(url) { value: parsedUrl.host }; } catch (error) { - log$26.error("Failed to parse domain", { error }); + log$25.error("Failed to parse domain", { error }); return { lengthBytes: 0, value: "" @@ -31953,7 +32004,7 @@ function toTonConnectSignDataPayload(payload) { bytes: payload.data.value.content }; } -var import_dist$16, import_dist$17, log$26, RequestProcessor; +var import_dist$16, import_dist$17, log$25, RequestProcessor; var init_RequestProcessor = __esmMin((() => { import_dist$16 = require_dist$1(); init_esm$2(); @@ -31968,7 +32019,7 @@ var init_RequestProcessor = __esmMin((() => { init_transaction$1(); init_utils$2(); init_events(); - log$26 = globalLogger.createChild("RequestProcessor"); + log$25 = globalLogger.createChild("RequestProcessor"); RequestProcessor = class { walletKitOptions; sessionManager; @@ -32031,7 +32082,7 @@ var init_RequestProcessor = __esmMin((() => { } return; } catch (error) { - log$26.error("Failed to approve connect request", { error }); + log$25.error("Failed to approve connect request", { error }); throw error; } } @@ -32166,7 +32217,7 @@ var init_RequestProcessor = __esmMin((() => { */ async rejectConnectRequest(event, reason, errorCode) { try { - log$26.info("Connect request rejected", { + log$25.info("Connect request rejected", { id: event.id, dAppName: event.preview.dAppInfo?.name || "", reason: reason || "User rejected connection" @@ -32183,7 +32234,7 @@ var init_RequestProcessor = __esmMin((() => { try { await this.bridgeManager.sendResponse(event, response, new SessionCrypto()); } catch (error) { - log$26.error("Failed to send connect request rejection response", { error }); + log$25.error("Failed to send connect request rejection response", { error }); } if (this.analytics) { const sessionData = event.from ? await this.sessionManager.getSession(sessionId) : void 0; @@ -32212,7 +32263,7 @@ var init_RequestProcessor = __esmMin((() => { } return; } catch (error) { - log$26.error("Failed to reject connect request", { error }); + log$25.error("Failed to reject connect request", { error }); throw error; } } @@ -32244,7 +32295,7 @@ var init_RequestProcessor = __esmMin((() => { return { signedBoc }; } } catch (error) { - log$26.error("Failed to approve transaction request", { error }); + log$25.error("Failed to approve transaction request", { error }); if (error instanceof WalletKitError) throw error; if (error?.message?.includes("Ledger device")) throw new WalletKitError(ERROR_CODES.LEDGER_DEVICE_ERROR, "Ledger device error", error); throw error; @@ -32294,7 +32345,7 @@ var init_RequestProcessor = __esmMin((() => { } return; } catch (error) { - log$26.error("Failed to reject transaction request", { error }); + log$25.error("Failed to reject transaction request", { error }); throw error; } } @@ -32325,7 +32376,7 @@ var init_RequestProcessor = __esmMin((() => { return { internalBoc }; } } catch (error) { - log$26.error("Failed to approve sign message request", { error }); + log$25.error("Failed to approve sign message request", { error }); throw error; } } @@ -32343,7 +32394,7 @@ var init_RequestProcessor = __esmMin((() => { }; await this.sendBridgeMessage(event, void 0, response); } catch (error) { - log$26.error("Failed to reject sign message request", { error }); + log$25.error("Failed to reject sign message request", { error }); throw error; } } @@ -32446,7 +32497,7 @@ var init_RequestProcessor = __esmMin((() => { }; } } catch (error) { - log$26.error("Failed to approve sign data request", { error: error?.message?.toString() ?? error?.toString() }); + log$25.error("Failed to approve sign data request", { error: error?.message?.toString() ?? error?.toString() }); if (error instanceof WalletKitError) throw error; throw error; } @@ -32481,7 +32532,7 @@ var init_RequestProcessor = __esmMin((() => { } return; } catch (error) { - log$26.error("Failed to reject sign data request", { error }); + log$25.error("Failed to reject sign data request", { error }); throw error; } } @@ -32558,14 +32609,14 @@ var init_RequestProcessor = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/core/EventStore.js -var getEventUUID, log$25, MAX_EVENT_SIZE_BYTES, StorageEventStore; +var getEventUUID, log$24, MAX_EVENT_SIZE_BYTES, StorageEventStore; var init_EventStore = __esmMin((() => { init_Logger(); init_events$1(); getEventUUID = () => { return crypto.randomUUID(); }; - log$25 = globalLogger.createChild("EventStore"); + log$24 = globalLogger.createChild("EventStore"); MAX_EVENT_SIZE_BYTES = 100 * 1024; StorageEventStore = class { storage; @@ -32598,7 +32649,7 @@ var init_EventStore = __esmMin((() => { sizeBytes }; await this.saveEvent(storedEvent); - log$25.info("Event stored", { + log$24.info("Event stored", { eventId: storedEvent.id, eventType, sizeBytes, @@ -32626,11 +32677,11 @@ var init_EventStore = __esmMin((() => { const allEvents = await this.getAllEventsFromStorage(); const event = allEvents[eventId]; if (!event) { - log$25.warn("Cannot lock non-existent event", { eventId }); + log$24.warn("Cannot lock non-existent event", { eventId }); return; } if (event.status !== "new") { - log$25.debug("Cannot lock event - not in new status", { + log$24.debug("Cannot lock event - not in new status", { eventId, status: event.status, lockedBy: event.lockedBy @@ -32645,7 +32696,7 @@ var init_EventStore = __esmMin((() => { }; allEvents[eventId] = updatedEvent; await this.storage.set(this.storageKey, allEvents); - log$25.debug("Event lock acquired", { + log$24.debug("Event lock acquired", { eventId, walletAddress: walletId }); @@ -32672,7 +32723,7 @@ var init_EventStore = __esmMin((() => { }; allEvents[eventId] = updatedEvent; await this.storage.set(this.storageKey, allEvents); - log$25.debug("Event retry count incremented", { + log$24.debug("Event retry count incremented", { eventId, retryCount: updatedEvent.retryCount, error @@ -32696,7 +32747,7 @@ var init_EventStore = __esmMin((() => { if (status === "completed") updatedEvent.completedAt = Date.now(); allEvents[eventId] = updatedEvent; await this.storage.set(this.storageKey, allEvents); - log$25.debug("Event status updated", { + log$24.debug("Event status updated", { eventId, oldStatus, newStatus: status @@ -32711,7 +32762,7 @@ var init_EventStore = __esmMin((() => { try { return (await this.getAllEventsFromStorage())[eventId] || null; } catch (error) { - log$25.warn("Failed to get event", { + log$24.warn("Failed to get event", { eventId, error }); @@ -32733,14 +32784,14 @@ var init_EventStore = __esmMin((() => { }; await this.saveEvent(recoveredEvent); recoveredCount++; - log$25.info("Recovered stale event", { + log$24.info("Recovered stale event", { eventId: event.id, lockedBy: event.lockedBy, staleMinutes: Math.round((now - event.processingStartedAt) / 6e4), retryCount: event.retryCount || 0 }); } - if (recoveredCount > 0) log$25.info("Event recovery completed", { recoveredCount }); + if (recoveredCount > 0) log$24.info("Event recovery completed", { recoveredCount }); return recoveredCount; } /** @@ -32753,7 +32804,7 @@ var init_EventStore = __esmMin((() => { const eventsToRemove = []; for (const event of events) if (event.status === "completed" && event.completedAt && event.completedAt < cutoffTime || event.status === "errored" && event.createdAt < cutoffTime) { eventsToRemove.push(event.id); - log$25.debug("Marked event for cleanup", { + log$24.debug("Marked event for cleanup", { eventId: event.id, status: event.status }); @@ -32767,7 +32818,7 @@ var init_EventStore = __esmMin((() => { } await this.storage.set(this.storageKey, allEvents); }); - log$25.info("Event cleanup completed", { cleanedUpCount }); + log$24.info("Event cleanup completed", { cleanedUpCount }); } return cleanedUpCount; } @@ -32779,7 +32830,7 @@ var init_EventStore = __esmMin((() => { const allEvents = await this.getAllEventsFromStorage(); return Object.values(allEvents); } catch (error) { - log$25.warn("Failed to get all events", { error }); + log$24.warn("Failed to get all events", { error }); return []; } } @@ -32801,7 +32852,7 @@ var init_EventStore = __esmMin((() => { try { return await this.storage.get(this.storageKey) || {}; } catch (error) { - log$25.warn("Failed to get events from storage", { error }); + log$24.warn("Failed to get events from storage", { error }); return {}; } } @@ -32834,10 +32885,10 @@ var init_EventStore = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/core/EventProcessor.js -var log$24, StorageEventProcessor; +var log$23, StorageEventProcessor; var init_EventProcessor = __esmMin((() => { init_Logger(); - log$24 = globalLogger.createChild("EventProcessor"); + log$23 = globalLogger.createChild("EventProcessor"); StorageEventProcessor = class { eventStore; config; @@ -32869,14 +32920,14 @@ var init_EventProcessor = __esmMin((() => { */ async startProcessing(walletId) { if (this.processorConfig.disableEvents) return; - if (walletId) if (this.registeredWallets.has(walletId)) log$24.debug("Processing already registered for wallet", { walletId }); + if (walletId) if (this.registeredWallets.has(walletId)) log$23.debug("Processing already registered for wallet", { walletId }); else { this.registeredWallets.add(walletId); - log$24.info("Registered wallet for event processing", { walletId }); + log$23.info("Registered wallet for event processing", { walletId }); } if (!this.isProcessing) { this.isProcessing = true; - log$24.info("Started global event processing loop"); + log$23.info("Started global event processing loop"); this.processEventsLoop(); } else this.triggerProcessing(); } @@ -32887,7 +32938,7 @@ var init_EventProcessor = __esmMin((() => { if (this.processorConfig.disableEvents) return; if (walletId) { this.registeredWallets.delete(walletId); - log$24.info("Unregistered wallet from event processing", { walletId }); + log$23.info("Unregistered wallet from event processing", { walletId }); } if (this.registeredWallets.size === 0 && this.isProcessing && !walletId) { this.isProcessing = false; @@ -32895,12 +32946,12 @@ var init_EventProcessor = __esmMin((() => { this.wakeUpResolver(); this.wakeUpResolver = void 0; } - log$24.info("Stopped global event processing loop (no more wallets)"); + log$23.info("Stopped global event processing loop (no more wallets)"); } } async clearRegisteredWallets() { this.registeredWallets.clear(); - log$24.info("Cleared registered wallets from event processing"); + log$23.info("Cleared registered wallets from event processing"); } /** * Process next available event from any source (wallet or no-wallet) @@ -32930,7 +32981,7 @@ var init_EventProcessor = __esmMin((() => { const walletId = allSessions.find((s) => s.sessionId === eventToUse.sessionId)?.walletId || "no-wallet"; return await this.processEvent(eventToUse, walletId); } catch (error) { - log$24.error("Error in processNextAvailableEvent", { error: error.message }); + log$23.error("Error in processNextAvailableEvent", { error: error.message }); return false; } } @@ -32940,9 +32991,9 @@ var init_EventProcessor = __esmMin((() => { async completeEvent(eventId) { try { await this.eventStore.updateEventStatus(eventId, "completed", "processing"); - log$24.debug("Event marked as completed", { eventId }); + log$23.debug("Event marked as completed", { eventId }); } catch (error) { - log$24.error("Failed to mark event as completed", { + log$23.error("Failed to mark event as completed", { eventId, error: error.message }); @@ -32953,14 +33004,14 @@ var init_EventProcessor = __esmMin((() => { */ startRecoveryLoop() { if (this.recoveryTimeoutId) { - log$24.debug("Recovery loop already running"); + log$23.debug("Recovery loop already running"); return; } const recoveryLoop = async () => { try { if (await this.eventStore.recoverStaleEvents(this.config.processingTimeoutMs) > 0) this.triggerProcessing(); } catch (error) { - log$24.error("Error in recovery loop", { error: error.message }); + log$23.error("Error in recovery loop", { error: error.message }); } if (this.recoveryTimeoutId !== void 0) this.recoveryTimeoutId = setTimeout(recoveryLoop, this.config.recoveryIntervalMs); }; @@ -32968,13 +33019,13 @@ var init_EventProcessor = __esmMin((() => { try { await this.eventStore.cleanupOldEvents(this.config.retentionMs); } catch (error) { - log$24.error("Error in cleanup loop", { error: error.message }); + log$23.error("Error in cleanup loop", { error: error.message }); } if (this.cleanupTimeoutId !== void 0) this.cleanupTimeoutId = setTimeout(cleanupLoop, this.config.cleanupIntervalMs); }; this.recoveryTimeoutId = setTimeout(recoveryLoop, this.config.recoveryIntervalMs); this.cleanupTimeoutId = setTimeout(cleanupLoop, this.config.cleanupIntervalMs); - log$24.info("Recovery and cleanup loops started"); + log$23.info("Recovery and cleanup loops started"); } /** * Stop the recovery process @@ -32988,7 +33039,7 @@ var init_EventProcessor = __esmMin((() => { clearTimeout(this.cleanupTimeoutId); this.cleanupTimeoutId = void 0; } - log$24.info("Recovery and cleanup loops stopped"); + log$23.info("Recovery and cleanup loops stopped"); } /** * Process a single event with retry logic @@ -32996,7 +33047,7 @@ var init_EventProcessor = __esmMin((() => { */ async processEvent(event, walletId) { if (!await this.eventStore.acquireLock(event.id, walletId)) { - log$24.debug("Failed to acquire lock on event", { + log$23.debug("Failed to acquire lock on event", { eventId: event.id, walletId }); @@ -33004,7 +33055,7 @@ var init_EventProcessor = __esmMin((() => { } const retryCount = event.retryCount || 0; if (retryCount >= this.config.maxRetries) { - log$24.error("Event exceeded max retries, marking as errored", { + log$23.error("Event exceeded max retries, marking as errored", { eventId: event.id, retryCount, maxRetries: this.config.maxRetries @@ -33012,14 +33063,14 @@ var init_EventProcessor = __esmMin((() => { try { await this.eventStore.updateEventStatus(event.id, "errored", "processing"); } catch (error) { - log$24.error("Failed to mark event as errored", { + log$23.error("Failed to mark event as errored", { eventId: event.id, error: error.message }); } return false; } - log$24.info("Processing event", { + log$23.info("Processing event", { eventId: event.id, eventType: event.eventType, walletId, @@ -33039,11 +33090,11 @@ var init_EventProcessor = __esmMin((() => { ...walletAddress ? { walletAddress } : {} }); await this.eventStore.updateEventStatus(event.id, "completed", "processing"); - log$24.info("Event processing completed", { eventId: event.id }); + log$23.info("Event processing completed", { eventId: event.id }); return true; } catch (error) { const errorMessage = error.message ?? "Unknown error"; - log$24.error("Error processing event", { + log$23.error("Error processing event", { eventId: event.id, error: errorMessage, retryCount @@ -33051,7 +33102,7 @@ var init_EventProcessor = __esmMin((() => { try { await this.eventStore.releaseLock(event.id, errorMessage); } catch (updateError) { - log$24.error("Failed to increment retry count", { + log$23.error("Failed to increment retry count", { eventId: event.id, error: updateError.message }); @@ -33066,18 +33117,18 @@ var init_EventProcessor = __esmMin((() => { while (this.isProcessing) try { if (!await this.processNextAvailableEvent()) await this.waitForWakeUpOrTimeout(500); } catch (error) { - log$24.error("Error in global processing loop", { error: error.message }); + log$23.error("Error in global processing loop", { error: error.message }); await this.waitForWakeUpOrTimeout(500); } this.wakeUpResolver = void 0; - log$24.debug("Global processing loop ended"); + log$23.debug("Global processing loop ended"); } /** * Trigger the global processing loop */ triggerProcessing() { if (this.isProcessing && this.wakeUpResolver) { - log$24.debug("Waking up global processing loop"); + log$23.debug("Waking up global processing loop"); this.wakeUpResolver(); } } @@ -33114,7 +33165,7 @@ var init_EventProcessor = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/core/wallet/extensions/ton.js -var log$23, WalletTonClass; +var log$22, WalletTonClass; var init_ton = __esmMin((() => { init_address$1(); init_validation(); @@ -33124,7 +33175,7 @@ var init_ton = __esmMin((() => { init_getNormalizedExtMessageHash(); init_errors$4(); init_Logger(); - log$23 = globalLogger.createChild("WalletTonClass"); + log$22 = globalLogger.createChild("WalletTonClass"); WalletTonClass = class { async createTransferTonTransaction(param) { if (!isValidAddress(param.recipientAddress)) throw new Error(`Invalid to address: ${param.recipientAddress}`); @@ -33185,7 +33236,7 @@ var init_ton = __esmMin((() => { normalizedHash }; } catch (error) { - log$23.error("Failed to send transaction", { error }); + log$22.error("Failed to send transaction", { error }); if (error instanceof WalletKitError) throw error; if (error?.message?.includes("Ledger device")) throw new WalletKitError(ERROR_CODES.LEDGER_DEVICE_ERROR, "Ledger device error", error); throw error; @@ -33301,7 +33352,7 @@ async function wrapWalletInterface(wallet) { } }); return newProxy; } -var log$22, Initializer; +var log$21, Initializer; var init_Initializer = __esmMin((() => { init_types$2(); init_storage(); @@ -33316,7 +33367,7 @@ var init_Initializer = __esmMin((() => { init_ton(); init_jetton$1(); init_nft(); - log$22 = globalLogger.createChild("Initializer"); + log$21 = globalLogger.createChild("Initializer"); Initializer = class { config; networkManager; @@ -33332,12 +33383,12 @@ var init_Initializer = __esmMin((() => { */ async initialize(options, networkManager) { try { - log$22.info("Initializing TonWalletKit..."); + log$21.info("Initializing TonWalletKit..."); this.networkManager = networkManager; const storage = this.initializeStorage(options); const { walletManager, sessionManager, bridgeManager, eventRouter, eventProcessor } = await this.initializeManagers(options, storage); const { requestProcessor } = this.initializeProcessors(sessionManager, bridgeManager, walletManager); - log$22.info("TonWalletKit initialized successfully"); + log$21.info("TonWalletKit initialized successfully"); return { walletManager, sessionManager, @@ -33348,7 +33399,7 @@ var init_Initializer = __esmMin((() => { eventProcessor }; } catch (error) { - log$22.error("Failed to initialize TonWalletKit", { error }); + log$21.error("Failed to initialize TonWalletKit", { error }); throw error; } } @@ -33384,9 +33435,9 @@ var init_Initializer = __esmMin((() => { const bridgeManager = new BridgeManager(options?.walletManifest, options?.bridge, sessionManager, storage, eventStore, eventRouter, options, this.eventEmitter, this.analyticsManager); eventRouter.setBridgeManager(bridgeManager); bridgeManager.start().then(() => { - log$22.info("Bridge manager started successfully"); + log$21.info("Bridge manager started successfully"); }).catch((e) => { - log$22.error("Could not start bridge manager", { error: e?.toString?.() }); + log$21.error("Could not start bridge manager", { error: e?.toString?.() }); }); const eventProcessor = new StorageEventProcessor(options?.eventProcessor, eventStore, DEFAULT_DURABLE_EVENTS_CONFIG, walletManager, sessionManager, eventRouter, this.eventEmitter); return { @@ -33408,7 +33459,7 @@ var init_Initializer = __esmMin((() => { */ async cleanup(components) { try { - log$22.info("Cleaning up TonWalletKit components..."); + log$21.info("Cleaning up TonWalletKit components..."); if (components.eventProcessor) { components.eventProcessor.stopRecoveryLoop(); await components.eventProcessor.clearRegisteredWallets(); @@ -33416,9 +33467,9 @@ var init_Initializer = __esmMin((() => { } if (components.bridgeManager) await components.bridgeManager.close(); if (components.eventRouter) components.eventRouter.clearCallbacks(); - log$22.info("TonWalletKit cleanup completed"); + log$21.info("TonWalletKit cleanup completed"); } catch (error) { - log$22.error("Error during cleanup", { error }); + log$21.error("Error during cleanup", { error }); } } }; @@ -33434,14 +33485,14 @@ function isTonAddress(address) { function createCacheKey(network, address) { return `${network.chainId}:${address}`; } -var import_dist$15, log$21, TON_ADDRESS, TON_INFO, JettonsManager; +var import_dist$15, log$20, TON_ADDRESS, TON_INFO, JettonsManager; var init_JettonsManager = __esmMin((() => { import_dist$15 = require_dist$1(); init_index_min(); init_Logger(); init_jettons(); init_utils$2(); - log$21 = globalLogger.createChild("JettonsManager"); + log$20 = globalLogger.createChild("JettonsManager"); TON_ADDRESS = "TON"; TON_INFO = { address: TON_ADDRESS, @@ -33468,7 +33519,7 @@ var init_JettonsManager = __esmMin((() => { ttl: 1e3 * 60 * 10 }); for (const network of this.networkManager.getConfiguredNetworks()) this.addTonToCache(network); - log$21.info("JettonsManager initialized", { cacheSize }); + log$20.info("JettonsManager initialized", { cacheSize }); } /** * Add TON native token to cache for a specific network @@ -33489,19 +33540,19 @@ var init_JettonsManager = __esmMin((() => { const cacheKey = this.normalizedCacheKey(targetNetwork, jettonAddress); const cachedInfo = this.cache.get(cacheKey); if (cachedInfo) { - log$21.debug("Jetton info found in cache", { + log$20.debug("Jetton info found in cache", { jettonAddress, network: targetNetwork }); return cachedInfo; } - log$21.debug("Jetton info not found in cache", { + log$20.debug("Jetton info not found in cache", { jettonAddress, network: targetNetwork }); const address = asMaybeAddressFriendly(jettonAddress); if (!address) { - log$21.error("Invalid jetton address format", { + log$20.error("Invalid jetton address format", { jettonAddress, network: targetNetwork }); @@ -33536,7 +33587,7 @@ var init_JettonsManager = __esmMin((() => { } return null; } catch (error) { - log$21.error("Error getting jetton info", { + log$20.error("Error getting jetton info", { error, jettonAddress, network: targetNetwork @@ -33555,7 +33606,7 @@ var init_JettonsManager = __esmMin((() => { const targetNetwork = network; try { const apiClient = this.networkManager.getClient(targetNetwork); - log$21.debug("Getting address jettons", { + log$20.debug("Getting address jettons", { userAddress, network: targetNetwork, offset, @@ -33569,13 +33620,13 @@ var init_JettonsManager = __esmMin((() => { if (!response.jettons) return []; const addressJettons = []; for (const item of response.jettons) addressJettons.push(item); - log$21.debug("Retrieved address jettons", { + log$20.debug("Retrieved address jettons", { count: addressJettons.length, network: targetNetwork }); return addressJettons; } catch (error) { - log$21.error("Failed to get address jettons", { + log$20.error("Failed to get address jettons", { error, userAddress, network: targetNetwork @@ -33599,14 +33650,14 @@ var init_JettonsManager = __esmMin((() => { uri: emulationInfo.extra.uri }; this.cache.set(cacheKey, jettonInfo); - log$21.debug("Added jetton info from emulation to cache", { + log$20.debug("Added jetton info from emulation to cache", { jettonAddress, network, name: jettonInfo.name, symbol: jettonInfo.symbol }); } catch (error) { - log$21.error("Error adding jetton from emulation", { + log$20.error("Error adding jetton from emulation", { error, jettonAddress, network @@ -33623,7 +33674,7 @@ var init_JettonsManager = __esmMin((() => { if (!addressMetadata.is_indexed || !addressMetadata.token_info) continue; const jettonMasterInfo = addressMetadata.token_info.find((info) => typeof info === "object" && info !== null && "type" in info && info.type === "jetton_masters"); if (jettonMasterInfo) { - log$21.debug("Adding jetton from emulation metadata", { + log$20.debug("Adding jetton from emulation metadata", { jettonAddress, network }); @@ -33631,12 +33682,12 @@ var init_JettonsManager = __esmMin((() => { addedCount++; } } - if (addedCount > 0) log$21.info("Added jettons from emulation metadata", { + if (addedCount > 0) log$20.info("Added jettons from emulation metadata", { addedCount, network }); } catch (error) { - log$21.error("Error adding jettons from emulation metadata", { + log$20.error("Error adding jettons from emulation metadata", { error, network }); @@ -33677,11 +33728,11 @@ var init_JettonsManager = __esmMin((() => { if (network) { for (const key of this.cache.keys()) if (key.startsWith(`${network.chainId}:`)) this.cache.delete(key); this.addTonToCache(network); - log$21.info("Jetton cache cleared for network", { network }); + log$20.info("Jetton cache cleared for network", { network }); } else { this.cache.clear(); for (const net of this.networkManager.getConfiguredNetworks()) this.addTonToCache(net); - log$21.info("Jetton cache cleared for all networks"); + log$20.info("Jetton cache cleared for all networks"); } } }; @@ -33841,12 +33892,12 @@ var init_DefiManager = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/defi/swap/SwapManager.js -var log$20, SwapManager; +var log$19, SwapManager; var init_SwapManager = __esmMin((() => { init_errors$2(); init_Logger(); init_DefiManager(); - log$20 = globalLogger.createChild("SwapManager"); + log$19 = globalLogger.createChild("SwapManager"); SwapManager = class extends DefiManager { constructor(createFactoryContext) { super(createFactoryContext); @@ -33858,7 +33909,7 @@ var init_SwapManager = __esmMin((() => { * @returns Promise resolving to swap quote */ async getQuote(params, providerId) { - log$20.debug("Getting swap quote", { + log$19.debug("Getting swap quote", { fromToken: params.from, toToken: params.to, amount: params.amount, @@ -33867,14 +33918,14 @@ var init_SwapManager = __esmMin((() => { }); try { const quote = await this.getProvider(providerId || this.defaultProviderId).getQuote(params); - log$20.debug("Received swap quote", { + log$19.debug("Received swap quote", { fromAmount: quote.fromAmount, toAmount: quote.toAmount, priceImpact: quote.priceImpact }); return quote; } catch (error) { - log$20.error("Failed to get swap quote", { + log$19.error("Failed to get swap quote", { error, params }); @@ -33888,16 +33939,16 @@ var init_SwapManager = __esmMin((() => { */ async buildSwapTransaction(params) { const providerId = params.quote.providerId || this.defaultProviderId; - log$20.debug("Building swap transaction", { + log$19.debug("Building swap transaction", { providerId, userAddress: params.userAddress }); try { const transaction = await this.getProvider(providerId).buildSwapTransaction(params); - log$20.debug("Built swap transaction", params.quote); + log$19.debug("Built swap transaction", params.quote); return transaction; } catch (error) { - log$20.error("Failed to build swap transaction", { + log$19.error("Failed to build swap transaction", { error, params }); @@ -33948,12 +33999,12 @@ var init_errors$1 = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/defi/staking/StakingManager.js -var log$19, StakingManager; +var log$18, StakingManager; var init_StakingManager = __esmMin((() => { init_errors$1(); init_Logger(); init_DefiManager(); - log$19 = globalLogger.createChild("StakingManager"); + log$18 = globalLogger.createChild("StakingManager"); StakingManager = class extends DefiManager { constructor(createFactoryContext) { super(createFactoryContext); @@ -33964,13 +34015,13 @@ var init_StakingManager = __esmMin((() => { * @param providerId - Optional provider id to use */ async getQuote(params, providerId) { - log$19.debug("Getting staking quote", params); + log$18.debug("Getting staking quote", params); try { const quote = await this.getProvider(providerId).getQuote(params); - log$19.debug("Received staking quote", quote); + log$18.debug("Received staking quote", quote); return quote; } catch (error) { - log$19.error("Failed to get staking quote", { + log$18.error("Failed to get staking quote", { error, params }); @@ -33983,11 +34034,11 @@ var init_StakingManager = __esmMin((() => { * @param providerId - Optional provider id to use */ async buildStakeTransaction(params, providerId) { - log$19.debug("Building staking transaction", params); + log$18.debug("Building staking transaction", params); try { return await this.getProvider(providerId).buildStakeTransaction(params); } catch (error) { - log$19.error("Failed to build staking transaction", { + log$18.error("Failed to build staking transaction", { error, params }); @@ -34001,7 +34052,7 @@ var init_StakingManager = __esmMin((() => { * @param providerId - Optional provider id to use */ async getStakedBalance(userAddress, network, providerId) { - log$19.debug("Getting staking balance", { + log$18.debug("Getting staking balance", { userAddress, network, provider: providerId || this.defaultProviderId @@ -34009,7 +34060,7 @@ var init_StakingManager = __esmMin((() => { try { return await this.getProvider(providerId).getStakedBalance(userAddress, network); } catch (error) { - log$19.error("Failed to get staking balance", { + log$18.error("Failed to get staking balance", { error, userAddress, network @@ -34023,14 +34074,14 @@ var init_StakingManager = __esmMin((() => { * @param providerId - Optional provider id to use */ async getStakingProviderInfo(network, providerId) { - log$19.debug("Getting staking info", { + log$18.debug("Getting staking info", { network, provider: providerId || this.defaultProviderId }); try { return await this.getProvider(providerId).getStakingProviderInfo(network); } catch (error) { - log$19.error("Failed to get staking info", { + log$18.error("Failed to get staking info", { error, network }); @@ -34043,14 +34094,14 @@ var init_StakingManager = __esmMin((() => { * @param providerId - Optional provider id to use */ getStakingProviderMetadata(network, providerId) { - log$19.debug("Getting staking metadata", { + log$18.debug("Getting staking metadata", { network, provider: providerId || this.defaultProviderId }); try { return this.getProvider(providerId).getStakingProviderMetadata(network); } catch (error) { - log$19.error("Failed to get staking metadata", { + log$18.error("Failed to get staking metadata", { error, network }); @@ -34059,7 +34110,7 @@ var init_StakingManager = __esmMin((() => { } createError(message, code, details) { const errorCode = Object.values(StakingErrorCode).includes(code) ? code : StakingErrorCode.InvalidParams; - log$19.error(message, { + log$18.error(message, { code, details }); @@ -34110,12 +34161,12 @@ var init_errors = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/defi/gasless/GaslessManager.js -var log$18, GaslessManager; +var log$17, GaslessManager; var init_GaslessManager = __esmMin((() => { init_Logger(); init_DefiManager(); init_errors(); - log$18 = globalLogger.createChild("GaslessManager"); + log$17 = globalLogger.createChild("GaslessManager"); GaslessManager = class extends DefiManager { constructor(createFactoryContext) { super(createFactoryContext); @@ -34125,11 +34176,11 @@ var init_GaslessManager = __esmMin((() => { */ async getMetadata(providerId) { const selectedProviderId = providerId ?? this.defaultProviderId; - log$18.debug("Getting gasless provider metadata", { providerId: selectedProviderId }); + log$17.debug("Getting gasless provider metadata", { providerId: selectedProviderId }); try { return await this.getProvider(selectedProviderId).getMetadata(); } catch (error) { - log$18.error("Failed to get gasless provider metadata", { error }); + log$17.error("Failed to get gasless provider metadata", { error }); throw error; } } @@ -34141,14 +34192,14 @@ var init_GaslessManager = __esmMin((() => { async getConfig(network, providerId) { const provider = this.getProvider(providerId ?? this.defaultProviderId); const targetNetwork = network ?? provider.getSupportedNetworks()[0]; - log$18.debug("Getting gasless config", { + log$17.debug("Getting gasless config", { network: targetNetwork?.chainId, providerId: providerId ?? this.defaultProviderId }); try { return await provider.getConfig(targetNetwork); } catch (error) { - log$18.error("Failed to get gasless config", { error }); + log$17.error("Failed to get gasless config", { error }); throw error; } } @@ -34156,7 +34207,7 @@ var init_GaslessManager = __esmMin((() => { * Quote fees and obtain relayer-wrapped messages for signing. */ async getQuote(params, providerId) { - log$18.debug("Quoting gasless transaction", { + log$17.debug("Quoting gasless transaction", { network: params.network.chainId, walletAddress: params.walletAddress, feeAsset: params.feeAsset, @@ -34166,7 +34217,7 @@ var init_GaslessManager = __esmMin((() => { try { return await this.getProvider(providerId ?? this.defaultProviderId).getQuote(params); } catch (error) { - log$18.error("Failed to quote gasless transaction", { + log$17.error("Failed to quote gasless transaction", { error, params }); @@ -34177,14 +34228,14 @@ var init_GaslessManager = __esmMin((() => { * Submit a signed transaction BoC to the relayer. */ async sendTransaction(params, providerId) { - log$18.debug("Sending gasless transaction", { + log$17.debug("Sending gasless transaction", { network: params.network.chainId, providerId: providerId ?? this.defaultProviderId }); try { return await this.getProvider(providerId ?? this.defaultProviderId).sendTransaction(params); } catch (error) { - log$18.error("Failed to send gasless transaction", { error }); + log$17.error("Failed to send gasless transaction", { error }); throw error; } } @@ -34202,10 +34253,10 @@ var init_gasless = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/core/EventEmitter.js -var log$17, EventEmitter; +var log$16, EventEmitter; var init_EventEmitter = __esmMin((() => { init_Logger(); - log$17 = globalLogger.createChild("EventEmitter"); + log$16 = globalLogger.createChild("EventEmitter"); EventEmitter = class { listeners = {}; /** @@ -34216,7 +34267,7 @@ var init_EventEmitter = __esmMin((() => { const eventListeners = this.listeners[eventName]; if (!eventListeners) this.listeners[eventName] = new Set([listener]); else eventListeners.add(listener); - log$17.debug("Event listener added", { + log$16.debug("Event listener added", { eventName: String(eventName), totalListeners: this.listeners[eventName]?.size }); @@ -34260,10 +34311,10 @@ var init_EventEmitter = __esmMin((() => { removeAllListeners(eventName) { if (eventName) { delete this.listeners[eventName]; - log$17.debug("All listeners removed for event", { eventName: String(eventName) }); + log$16.debug("All listeners removed for event", { eventName: String(eventName) }); } else { this.listeners = {}; - log$17.debug("All event listeners cleared"); + log$16.debug("All event listeners cleared"); } } /** @@ -34282,12 +34333,12 @@ var init_EventEmitter = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/streaming/StreamingManager.js -var log$16, StreamingManager; +var log$15, StreamingManager; var init_StreamingManager = __esmMin((() => { init_Logger(); init_utils$2(); init_factory$2(); - log$16 = globalLogger.createChild("StreamingManager"); + log$15 = globalLogger.createChild("StreamingManager"); StreamingManager = class { createFactoryContext; providers = /* @__PURE__ */ new Map(); @@ -34303,7 +34354,7 @@ var init_StreamingManager = __esmMin((() => { const provider = resolveProvider(input, this.createFactoryContext()); const networkId = String(provider.network.chainId); if (this.providers.has(networkId)) { - log$16.warn(`Provider for network ${networkId} is already registered. Overriding.`); + log$15.warn(`Provider for network ${networkId} is already registered. Overriding.`); this.providerConnectionUnsubs.get(networkId)?.(); this.providers.get(networkId)?.disconnect(); } @@ -34554,13 +34605,13 @@ function pascalToKebab(value) { var init_utils$1 = __esmMin((() => {})); //#endregion //#region ../walletkit/dist/esm/analytics/AnalyticsManager.js -var log$15, AnalyticsManager; +var log$14, AnalyticsManager; var init_AnalyticsManager = __esmMin((() => { init_Logger(); init_swagger(); init_utils$1(); init_utils$2(); - log$15 = globalLogger.createChild("AnalyticsManager"); + log$14 = globalLogger.createChild("AnalyticsManager"); AnalyticsManager = class AnalyticsManager { api; baseEvent; @@ -34624,12 +34675,12 @@ var init_AnalyticsManager = __esmMin((() => { }; if (this.appInfo?.getLocale) enhancedEvent.locale = this.appInfo.getLocale(); if (this.appInfo?.getCurrentUserId) enhancedEvent.user_id = this.appInfo.getCurrentUserId(); - log$15.debug("Analytics event emitted", { event: enhancedEvent }); + log$14.debug("Analytics event emitted", { event: enhancedEvent }); this.events.push(enhancedEvent); if (this.events.length > this.maxQueueSize) { const removed = this.events.length - this.maxQueueSize; this.events = this.events.slice(removed); - log$15.warn("Analytics queue overflow, dropped oldest events", { count: removed }); + log$14.warn("Analytics queue overflow, dropped oldest events", { count: removed }); } if (this.events.length >= this.maxBatchSize) { this.flush(); @@ -34650,10 +34701,10 @@ var init_AnalyticsManager = __esmMin((() => { const eventsToSend = this.extractEventsToSend(); try { await this.processEventsBatch(eventsToSend); - log$15.debug("Analytics events sent successfully"); + log$14.debug("Analytics events sent successfully"); } catch (error) { this.restoreEvents(eventsToSend); - log$15.error("Failed to send analytics events", { error }); + log$14.error("Failed to send analytics events", { error }); } finally { this.isProcessing = false; this.scheduleNextFlushIfNeeded(); @@ -34671,7 +34722,7 @@ var init_AnalyticsManager = __esmMin((() => { return eventsToSend; } async processEventsBatch(eventsToSend) { - log$15.debug("Sending analytics events", { count: eventsToSend.length }); + log$14.debug("Sending analytics events", { count: eventsToSend.length }); try { const response = await this.sendEvents(eventsToSend); this.handleResponse(response); @@ -34693,7 +34744,7 @@ var init_AnalyticsManager = __esmMin((() => { if (this.events.length > this.maxQueueSize) { const removed = this.events.length - this.maxQueueSize; this.events = this.events.slice(0, this.maxQueueSize); - log$15.warn("Analytics queue overflow after restore, dropped oldest events", { count: removed }); + log$14.warn("Analytics queue overflow after restore, dropped oldest events", { count: removed }); } } scheduleNextFlushIfNeeded() { @@ -34712,7 +34763,7 @@ var init_AnalyticsManager = __esmMin((() => { return status === AnalyticsManager.HTTP_STATUS.TOO_MANY_REQUESTS; } handleClientError(status, statusText) { - log$15.error("Analytics API client error", { + log$14.error("Analytics API client error", { status, statusText }); @@ -35512,7 +35563,7 @@ var init_BaseApiClient = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/clients/toncenter/ApiClientToncenter.js -var import_dist$13, log$14, MAX_ACCOUNT_STATES_BATCH$1, ApiClientToncenter; +var import_dist$13, log$13, MAX_ACCOUNT_STATES_BATCH$1, ApiClientToncenter; var init_ApiClientToncenter = __esmMin((() => { import_dist$13 = require_dist$1(); init_base64(); @@ -35531,7 +35582,7 @@ var init_ApiClientToncenter = __esmMin((() => { init_utils(); init_TonClientError(); init_utils$2(); - log$14 = globalLogger.createChild("ApiClientToncenter"); + log$13 = globalLogger.createChild("ApiClientToncenter"); MAX_ACCOUNT_STATES_BATCH$1 = 100; ApiClientToncenter = class extends BaseApiClient { constructor(config = {}) { @@ -35679,7 +35730,7 @@ var init_ApiClientToncenter = __esmMin((() => { const fulfilledResult = results.find((result) => result.status === "fulfilled"); if (fulfilledResult) return fulfilledResult.value; results.forEach((result) => { - if (result.status === "rejected") log$14.error("Error fetching trace", { error: result.reason }); + if (result.status === "rejected") log$13.error("Error fetching trace", { error: result.reason }); }); throw new Error("Failed to fetch trace"); } @@ -35690,7 +35741,7 @@ var init_ApiClientToncenter = __esmMin((() => { }, void 0, void 0, (err) => err instanceof TonClientError ? err.status !== 422 : true); if (response?.traces?.length > 0) return response; } catch (error) { - log$14.error("Error fetching pending trace", { error }); + log$13.error("Error fetching pending trace", { error }); } throw new Error("Failed to fetch pending trace"); } @@ -35819,13 +35870,13 @@ var init_toncenter$1 = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/core/NetworkManager.js -var log$13, KitNetworkManager; +var log$12, KitNetworkManager; var init_NetworkManager = __esmMin((() => { init_toncenter$1(); init_Logger(); init_errors$4(); init_models(); - log$13 = globalLogger.createChild("NetworkManager"); + log$12 = globalLogger.createChild("NetworkManager"); KitNetworkManager = class { clients = /* @__PURE__ */ new Map(); constructor(options) { @@ -35838,7 +35889,7 @@ var init_NetworkManager = __esmMin((() => { initializeClients(options) { const networks = options.networks; if (!networks) { - log$13.warn("No networks configured in TonWalletKitOptions"); + log$12.warn("No networks configured in TonWalletKitOptions"); return; } for (const [chainId, networkConfig] of Object.entries(networks)) { @@ -35846,7 +35897,7 @@ var init_NetworkManager = __esmMin((() => { if (!networkConfig) continue; const client = this.createClient(network, networkConfig.apiClient, options); this.clients.set(network.chainId, client); - log$13.info("Initialized network client", { chainId }); + log$12.info("Initialized network client", { chainId }); } } /** @@ -35902,7 +35953,7 @@ var init_NetworkManager = __esmMin((() => { */ setClient(network, client) { this.clients.set(network.chainId, client); - log$13.info("Added/updated network client", { network }); + log$12.info("Added/updated network client", { network }); } }; })); @@ -35916,7 +35967,7 @@ function parseEmbeddedRequestFromReqParam(reqParam) { try { return toEmbeddedRequest(decodeEmbeddedRequestParam(reqParam)); } catch (error) { - log$12.warn("Failed to parse embedded request req parameter", { error }); + log$11.warn("Failed to parse embedded request req parameter", { error }); return; } } @@ -35942,20 +35993,20 @@ function toEmbeddedRequest(parsed) { }; } default: - log$12.warn("Unknown embedded request method", { method: parsed.method }); + log$11.warn("Unknown embedded request method", { method: parsed.method }); return; } } -var log$12; +var log$11; var init_embeddedRequest = __esmMin((() => { init_esm$2(); init_internal(); init_Logger(); - log$12 = globalLogger.createChild("embeddedRequestParser"); + log$11 = globalLogger.createChild("embeddedRequestParser"); })); //#endregion //#region ../walletkit/dist/esm/core/TonWalletKit.js -var import_dist$12, log$11, TonWalletKit$1; +var import_dist$12, log$10, TonWalletKit$1; var init_TonWalletKit = __esmMin((() => { import_dist$12 = require_dist$1(); init_esm$2(); @@ -35976,7 +36027,7 @@ var init_TonWalletKit = __esmMin((() => { init_NetworkManager(); init_utils$2(); init_embeddedRequest(); - log$11 = globalLogger.createChild("TonWalletKit"); + log$10 = globalLogger.createChild("TonWalletKit"); TonWalletKit$1 = class { walletManager; sessionManager; @@ -36017,7 +36068,7 @@ var init_TonWalletKit = __esmMin((() => { this.gaslessManager = new GaslessManager(() => this.createFactoryContext()); this.eventEmitter.on("restoreConnection", async ({ payload: event }) => { if (!event.domain) { - log$11.error("Domain is required for restore connection"); + log$10.error("Domain is required for restore connection"); return this.sendErrorConnectResponse(event); } const sessions = await this.sessionManager.getSessions({ @@ -36027,12 +36078,12 @@ var init_TonWalletKit = __esmMin((() => { }); const session = sessions.length > 0 ? sessions[0] : void 0; if (!session) { - log$11.error("Session not found for domain", { domain: event.domain }); + log$10.error("Session not found for domain", { domain: event.domain }); return this.sendErrorConnectResponse(event); } const wallet = session.walletId ? this.walletManager?.getWallet(session.walletId) : void 0; if (!wallet) { - log$11.error("Wallet not found for session", { walletId: session.walletId }); + log$10.error("Wallet not found for session", { walletId: session.walletId }); return this.sendErrorConnectResponse(event); } const walletAddress = wallet.getAddress(); @@ -36086,7 +36137,7 @@ var init_TonWalletKit = __esmMin((() => { await this.eventProcessor.startProcessing(); this.isInitialized = true; } catch (error) { - log$11.error("TonWalletKit initialization failed", { error: error?.toString() }); + log$10.error("TonWalletKit initialization failed", { error: error?.toString() }); throw error; } } @@ -36116,7 +36167,7 @@ var init_TonWalletKit = __esmMin((() => { const walletId = wallet.getWalletId(); await this.eventProcessor.startProcessing(walletId); } catch (error) { - log$11.error("Failed to start event processing for wallet", { + log$10.error("Failed to start event processing for wallet", { walletAddress: wallet.getAddress(), error }); @@ -36136,7 +36187,7 @@ var init_TonWalletKit = __esmMin((() => { } getWallets() { if (!this.isInitialized) { - log$11.warn("TonWalletKit not yet initialized, returning empty array"); + log$10.warn("TonWalletKit not yet initialized, returning empty array"); return []; } return this.walletManager.getWallets(); @@ -36146,7 +36197,7 @@ var init_TonWalletKit = __esmMin((() => { */ getWallet(walletId) { if (!this.isInitialized) { - log$11.warn("TonWalletKit not yet initialized, returning undefined"); + log$10.warn("TonWalletKit not yet initialized, returning undefined"); return; } return this.walletManager.getWallet(walletId); @@ -36206,7 +36257,7 @@ var init_TonWalletKit = __esmMin((() => { payload: {} }, sessionCrypto), 10, 100); } catch (error) { - log$11.error("Failed to send disconnect to bridge", { + log$10.error("Failed to send disconnect to bridge", { sessionId, error }); @@ -36216,7 +36267,7 @@ var init_TonWalletKit = __esmMin((() => { if (sessionId) try { await removeSession(sessionId); } catch (error) { - log$11.error("Failed to remove session", { + log$10.error("Failed to remove session", { sessionId, error }); @@ -36226,7 +36277,7 @@ var init_TonWalletKit = __esmMin((() => { if (sessions.length > 0) for (const session of sessions) try { await removeSession(session.sessionId); } catch (error) { - log$11.error("Failed to remove session", { + log$10.error("Failed to remove session", { sessionId: session.sessionId, error }); @@ -36300,7 +36351,7 @@ var init_TonWalletKit = __esmMin((() => { const bridgeEvent = this.parseBridgeConnectEventFromUrl(url); return await new ConnectHandler(() => {}, this.config, this.analyticsManager).handle(bridgeEvent); } catch (error) { - log$11.error("Failed to create connection event from URL", { + log$10.error("Failed to create connection event from URL", { error, url }); @@ -36317,7 +36368,7 @@ var init_TonWalletKit = __esmMin((() => { const bridgeEvent = this.parseBridgeConnectEventFromUrl(url); await this.eventRouter.routeEvent(bridgeEvent); } catch (error) { - log$11.error("Failed to handle TON Connect URL", { + log$10.error("Failed to handle TON Connect URL", { error, url }); @@ -36361,7 +36412,7 @@ var init_TonWalletKit = __esmMin((() => { const params = {}; for (const [key, value] of parsedUrl.searchParams.entries()) params[key] = value; if (!params.v || !params.id || !params.r) { - log$11.warn("Missing required TON Connect URL parameters"); + log$10.warn("Missing required TON Connect URL parameters"); return null; } return { @@ -36373,7 +36424,7 @@ var init_TonWalletKit = __esmMin((() => { ...params }; } catch (error) { - log$11.error("Failed to parse TON Connect URL", { + log$10.error("Failed to parse TON Connect URL", { error, url }); @@ -36400,7 +36451,7 @@ var init_TonWalletKit = __esmMin((() => { domain: "" }; if (params.e) if (this.config.deviceInfo?.features.some((feature) => typeof feature === "object" && feature.name === "EmbeddedRequest")) bridgeEvent.embeddedRequest = parseEmbeddedRequestFromReqParam(params.e); - else log$11.warn("Embedded request feature is not supported in features, but we received request with embedded request payload", { features: this.config.deviceInfo?.features }); + else log$10.warn("Embedded request feature is not supported in features, but we received request with embedded request payload", { features: this.config.deviceInfo?.features }); return bridgeEvent; } async approveConnectRequest(event, response) { @@ -36751,9 +36802,9 @@ var init_map_nft_items = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/clients/tonapi/mappers/map-methods.js -var hexBocToBase64$1, decimalToInt257Hex, mapTonApiGetMethodArgs, mapTonApiTvmStackRecord; +var hexBocToBase64, decimalToInt257Hex, mapTonApiGetMethodArgs, mapTonApiTvmStackRecord; var init_map_methods = __esmMin((() => { - hexBocToBase64$1 = (hex) => { + hexBocToBase64 = (hex) => { return Buffer.from(hex, "hex").toString("base64"); }; decimalToInt257Hex = (value) => { @@ -36814,11 +36865,11 @@ var init_map_methods = __esmMin((() => { }; case "cell": return { type: "cell", - value: hexBocToBase64$1(item.cell) + value: hexBocToBase64(item.cell) }; case "slice": return { type: "slice", - value: hexBocToBase64$1(item.slice || item.cell) + value: hexBocToBase64(item.slice || item.cell) }; case "tuple": return { type: "tuple", @@ -37405,7 +37456,7 @@ var init_map_masterchain_info = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/clients/tonapi/ApiClientTonApi.js -var import_dist$10, log$10, MAX_ACCOUNT_STATES_BATCH, ApiClientTonApi; +var import_dist$10, log$9, MAX_ACCOUNT_STATES_BATCH, ApiClientTonApi; var init_ApiClientTonApi = __esmMin((() => { import_dist$10 = require_dist$1(); init_models(); @@ -37424,7 +37475,7 @@ var init_ApiClientTonApi = __esmMin((() => { init_map_traces(); init_map_events(); init_map_masterchain_info(); - log$10 = globalLogger.createChild("ApiClientTonApi"); + log$9 = globalLogger.createChild("ApiClientTonApi"); MAX_ACCOUNT_STATES_BATCH = 100; ApiClientTonApi = class extends BaseApiClient { constructor(config = {}) { @@ -37446,7 +37497,7 @@ var init_ApiClientTonApi = __esmMin((() => { return this.network; } async getAccountState(address, seqno) { - if (typeof seqno === "number") log$10.warn(`getAccountState: seqno=${seqno} is ignored — TonApi /v2/accounts endpoint does not support historical state queries.`); + if (typeof seqno === "number") log$9.warn(`getAccountState: seqno=${seqno} is ignored — TonApi /v2/accounts endpoint does not support historical state queries.`); try { return mapAccountState(await this.getJson(`/v2/blockchain/accounts/${address}`), address); } catch (e) { @@ -37755,7 +37806,7 @@ var init_actions = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/contracts/w5/WalletV5R1Adapter.js -var import_dist$6, import_dist$7, log$9, defaultWalletIdV5R1, WalletV5R1Adapter$1; +var import_dist$6, import_dist$7, log$8, defaultWalletIdV5R1, WalletV5R1Adapter$1; var init_WalletV5R1Adapter = __esmMin((() => { import_dist$6 = require_dist$1(); import_dist$7 = require_dist$1(); @@ -37770,7 +37821,7 @@ var init_WalletV5R1Adapter = __esmMin((() => { init_base64(); init_tonProof(); init_walletId(); - log$9 = globalLogger.createChild("WalletV5R1Adapter"); + log$8 = globalLogger.createChild("WalletV5R1Adapter"); defaultWalletIdV5R1 = 2147483409; WalletV5R1Adapter$1 = class WalletV5R1Adapter$1 { signer; @@ -37887,7 +37938,7 @@ var init_WalletV5R1Adapter = __esmMin((() => { try { return await this.walletContract.seqno; } catch (error) { - log$9.warn("Failed to get seqno", { error }); + log$8.warn("Failed to get seqno", { error }); throw error; } } @@ -37898,7 +37949,7 @@ var init_WalletV5R1Adapter = __esmMin((() => { try { return this.walletContract.walletId; } catch (error) { - log$9.warn("Failed to get wallet ID", { error }); + log$8.warn("Failed to get wallet ID", { error }); const walletId = this.config.walletId; return new WalletV5R1Id({ subwalletNumber: typeof walletId === "bigint" ? Number(walletId) : walletId || 0 }); } @@ -37910,7 +37961,7 @@ var init_WalletV5R1Adapter = __esmMin((() => { try { return (await this.client.getAccountState(asAddressFriendly(this.walletContract.address))).status === "active"; } catch (error) { - log$9.warn("Failed to check deployment status", { error }); + log$8.warn("Failed to check deployment status", { error }); return false; } } @@ -37942,13 +37993,13 @@ var init_WalletV5R1Adapter = __esmMin((() => { if (message.payload) try { msg.body = import_dist$6.Cell.fromBase64(message.payload); } catch (error) { - log$9.warn("Failed to load payload", { error }); + log$8.warn("Failed to load payload", { error }); throw WalletKitError.fromError(ERROR_CODES.CONTRACT_VALIDATION_FAILED, "Failed to parse transaction payload", error); } if (message.stateInit) try { msg.init = (0, import_dist$6.loadStateInit)(import_dist$6.Cell.fromBase64(message.stateInit).asSlice()); } catch (error) { - log$9.warn("Failed to load state init", { error }); + log$8.warn("Failed to load state init", { error }); throw WalletKitError.fromError(ERROR_CODES.CONTRACT_VALIDATION_FAILED, "Failed to parse state init", error); } return new ActionSendMsg(import_dist$6.SendMode.PAY_GAS_SEPARATELY + import_dist$6.SendMode.IGNORE_ERRORS, msg); @@ -37969,7 +38020,7 @@ var init_WalletV5R1Adapter = __esmMin((() => { auth_signed_internal: 1936289396 }; const opcode = options.authType === "internal" ? Opcodes.auth_signed_internal : Opcodes.auth_signed; - log$9.debug("createBodyV5 signing with opcode", { + log$8.debug("createBodyV5 signing with opcode", { authType: options.authType, opcode: `0x${opcode.toString(16)}` }); @@ -38028,14 +38079,14 @@ var init_WalletV5R1Adapter = __esmMin((() => { function walletV5ConfigToCell(config) { return (0, import_dist$5.beginCell)().storeBit(config.signatureAllowed).storeUint(config.seqno, 32).storeUint(config.walletId, 32).storeUint(config.publicKey, 256).storeDict(config.extensions, import_dist$5.Dictionary.Keys.BigUint(256), import_dist$5.Dictionary.Values.BigInt(1)).endCell(); } -var import_dist$5, log$8, Opcodes, WalletV5R1Id, WalletV5; +var import_dist$5, log$7, Opcodes, WalletV5R1Id, WalletV5; var init_WalletV5R1 = __esmMin((() => { import_dist$5 = require_dist$1(); init_WalletV5R1Adapter(); init_tvmStack(); init_utils$2(); init_Logger(); - log$8 = globalLogger.createChild("WalletV5R1"); + log$7 = globalLogger.createChild("WalletV5R1"); Opcodes = { action_send_msg: 247711853, action_set_code: 2907562126, @@ -38132,7 +38183,7 @@ var init_WalletV5R1 = __esmMin((() => { if (dataCell.bits.length < 33) return 0; return dataCell.asSlice().skip(1).loadUint(32); } catch (error) { - log$8.error("Failed to get seqno", { error }); + log$7.error("Failed to get seqno", { error }); return 0; } }); @@ -38163,12 +38214,12 @@ var init_WalletV5R1 = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/contracts/v4r2/WalletV4R2.js -var import_dist$4, log$7, WalletV4R2; +var import_dist$4, log$6, WalletV4R2; var init_WalletV4R2 = __esmMin((() => { import_dist$4 = require_dist$1(); init_tvmStack(); init_utils$2(); - log$7 = { error: (_message, _data) => {} }; + log$6 = { error: (_message, _data) => {} }; WalletV4R2 = class WalletV4R2 { address; init; @@ -38220,7 +38271,7 @@ var init_WalletV4R2 = __esmMin((() => { if (parsedStack[0]?.type === "int") return Number(parsedStack[0].value); else throw new Error("Stack is not an int"); } catch (error) { - log$7.error("Failed to get seqno", { error }); + log$6.error("Failed to get seqno", { error }); return 0; } } @@ -38241,7 +38292,7 @@ var init_WalletV4R2 = __esmMin((() => { if (parsedStack[0]?.type === "int") return Number(parsedStack[0].value); else throw new Error("Stack is not an int"); } catch (error) { - log$7.error("Failed to get subwallet id", { error }); + log$6.error("Failed to get subwallet id", { error }); return this.subwalletId; } } @@ -38282,7 +38333,7 @@ var init_constants = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/contracts/v4r2/WalletV4R2Adapter.js -var import_dist$2, log$6, WalletV4R2Adapter$1; +var import_dist$2, log$5, WalletV4R2Adapter$1; var init_WalletV4R2Adapter = __esmMin((() => { import_dist$2 = require_dist$1(); init_WalletV4R2(); @@ -38295,7 +38346,7 @@ var init_WalletV4R2Adapter = __esmMin((() => { init_Logger(); init_walletId(); init_utils$2(); - log$6 = globalLogger.createChild("WalletV4R2Adapter"); + log$5 = globalLogger.createChild("WalletV4R2Adapter"); WalletV4R2Adapter$1 = class WalletV4R2Adapter$1 { signer; config; @@ -38402,7 +38453,7 @@ var init_WalletV4R2Adapter = __esmMin((() => { }); return (0, import_dist$2.beginCell)().store((0, import_dist$2.storeMessage)(ext)).endCell().toBoc().toString("base64"); } catch (error) { - log$6.warn("Failed to get signed send transaction", { error }); + log$5.warn("Failed to get signed send transaction", { error }); throw error; } } @@ -38429,7 +38480,7 @@ var init_WalletV4R2Adapter = __esmMin((() => { try { return await this.walletContract.getSeqno(); } catch (error) { - log$6.warn("Failed to get seqno", { error }); + log$5.warn("Failed to get seqno", { error }); throw error; } } @@ -38440,7 +38491,7 @@ var init_WalletV4R2Adapter = __esmMin((() => { try { return await this.walletContract.getSubwalletId(); } catch (error) { - log$6.warn("Failed to get subwallet ID", { error }); + log$5.warn("Failed to get subwallet ID", { error }); return this.config.walletId ?? 698983191; } } @@ -38451,7 +38502,7 @@ var init_WalletV4R2Adapter = __esmMin((() => { try { return (await this.client.getAccountState(asAddressFriendly(this.walletContract.address))).status === "active"; } catch (error) { - log$6.warn("Failed to check deployment status", { error }); + log$5.warn("Failed to check deployment status", { error }); return false; } } @@ -38717,11 +38768,11 @@ var init_map_jettons = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/streaming/WebsocketStreamingProvider.js -var log$5, WebsocketStreamingProvider; +var log$4, WebsocketStreamingProvider; var init_WebsocketStreamingProvider = __esmMin((() => { init_Logger(); init_address$1(); - log$5 = globalLogger.createChild("WebsocketStreamingProvider"); + log$4 = globalLogger.createChild("WebsocketStreamingProvider"); WebsocketStreamingProvider = class WebsocketStreamingProvider { type = "streaming"; ws = null; @@ -38814,7 +38865,7 @@ var init_WebsocketStreamingProvider = __esmMin((() => { } this.isConnected = false; if (wasConnected) this.emitConnectionChange(false); - log$5.info("WebsocketStreamingProvider disconnected"); + log$4.info("WebsocketStreamingProvider disconnected"); } checkClose() { if (this.closeCheckTimeout) clearTimeout(this.closeCheckTimeout); @@ -38842,16 +38893,16 @@ var init_WebsocketStreamingProvider = __esmMin((() => { openConnection() { this.stopReconnect(); const url = this.getUrl(); - log$5.info("Connecting to WebSocket", { url: url.replace(/api_key=[^&]+/, "api_key=***") }); + log$4.info("Connecting to WebSocket", { url: url.replace(/api_key=[^&]+/, "api_key=***") }); try { this.ws = new WebSocket(url); } catch (error) { - log$5.error("WebSocket creation failed", { error }); + log$4.error("WebSocket creation failed", { error }); this.scheduleReconnect(); return; } this.ws.onopen = () => { - log$5.info("WebSocket connected"); + log$4.info("WebSocket connected"); this.isConnected = true; this.reconnectAttempts = 0; this.fullResync(); @@ -38860,13 +38911,13 @@ var init_WebsocketStreamingProvider = __esmMin((() => { }; this.ws.onmessage = this.onMessage.bind(this); this.ws.onerror = (error) => { - log$5.error("WebSocket error", { + log$4.error("WebSocket error", { readyState: this.ws?.readyState, error }); }; this.ws.onclose = () => { - log$5.info("WebSocket closed"); + log$4.info("WebSocket closed"); this.isConnected = false; this.stopPing(); this.ws = null; @@ -38901,7 +38952,7 @@ var init_WebsocketStreamingProvider = __esmMin((() => { this.reconnectAttempts++; const delays = WebsocketStreamingProvider.RECONNECT_DELAYS; const delayMs = delays[Math.min(this.reconnectAttempts - 1, delays.length - 1)]; - log$5.info(`Scheduling reconnect in ${delayMs}ms (attempt ${this.reconnectAttempts})`); + log$4.info(`Scheduling reconnect in ${delayMs}ms (attempt ${this.reconnectAttempts})`); this.reconnectTimeout = setTimeout(() => { this.reconnectTimeout = null; this.openConnection(); @@ -38924,7 +38975,7 @@ var init_WebsocketStreamingProvider = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/streaming/TonStreamingV2BaseProvider.js -var log$4, STREAMING_V2_WS_PATH, TonStreamingV2BaseProvider; +var log$3, STREAMING_V2_WS_PATH, TonStreamingV2BaseProvider; var init_TonStreamingV2BaseProvider = __esmMin((() => { init_index_min(); init_Logger(); @@ -38937,7 +38988,7 @@ var init_TonStreamingV2BaseProvider = __esmMin((() => { init_map_transactions(); init_map_jettons(); init_WebsocketStreamingProvider(); - log$4 = globalLogger.createChild("TonStreamingV2"); + log$3 = globalLogger.createChild("TonStreamingV2"); STREAMING_V2_WS_PATH = "/api/streaming/v2/ws"; TonStreamingV2BaseProvider = class extends WebsocketStreamingProvider { providerId; @@ -38979,7 +39030,7 @@ var init_TonStreamingV2BaseProvider = __esmMin((() => { }; } onWatch(type, id) { - log$4.info("onWatch triggered", { + log$3.info("onWatch triggered", { type, id, isConnected: this.isConnected, @@ -38988,7 +39039,7 @@ var init_TonStreamingV2BaseProvider = __esmMin((() => { this.requestSync(); } onUnwatch(type, id) { - log$4.info("onUnwatch triggered", { + log$3.info("onUnwatch triggered", { type, id, isConnected: this.isConnected, @@ -39001,7 +39052,7 @@ var init_TonStreamingV2BaseProvider = __esmMin((() => { clearTimeout(this.syncTimer); this.syncTimer = null; } - log$4.info("fullResync triggered", { + log$3.info("fullResync triggered", { isConnected: this.isConnected, readyState: this.ws?.readyState }); @@ -39024,7 +39075,7 @@ var init_TonStreamingV2BaseProvider = __esmMin((() => { addresses: Array.from(this.lastAddresses) }); this.lastAddresses.clear(); - log$4.info("Cleared all subscriptions", { msgId }); + log$3.info("Cleared all subscriptions", { msgId }); } return; } @@ -39041,7 +39092,7 @@ var init_TonStreamingV2BaseProvider = __esmMin((() => { ...request }); this.lastAddresses = addresses; - log$4.info("Sent monolithic subscription", { + log$3.info("Sent monolithic subscription", { msgId, types: Array.from(types), addressCount: addresses.size @@ -39051,7 +39102,7 @@ var init_TonStreamingV2BaseProvider = __esmMin((() => { try { const msg = JSON.parse(event.data); const m = msg; - log$4.debug("Streaming v2 WS received message:", m); + log$3.debug("Streaming v2 WS received message:", m); if (m.status === "subscribed" || m.status === "pong") return; if (isAccountStateNotification(msg)) { const update = mapBalance(msg); @@ -39059,7 +39110,7 @@ var init_TonStreamingV2BaseProvider = __esmMin((() => { return; } if (isTraceInvalidatedNotification(msg)) { - log$4.debug("Trace invalidated", { hash: msg.trace_external_hash_norm }); + log$3.debug("Trace invalidated", { hash: msg.trace_external_hash_norm }); const entry = this.traceCache.get(msg.trace_external_hash_norm); if (entry) { entry.accounts.forEach((account) => { @@ -39080,7 +39131,7 @@ var init_TonStreamingV2BaseProvider = __esmMin((() => { const finalityScore = this.getFinalityScore(msg.finality); const entry = this.traceCache.get(msg.trace_external_hash_norm); if (entry && finalityScore < entry.score) { - log$4.debug("Ignoring transactions notification due to lower finality", { + log$3.debug("Ignoring transactions notification due to lower finality", { hash: msg.trace_external_hash_norm, msgFinality: msg.finality, cachedScore: entry.score @@ -39109,7 +39160,7 @@ var init_TonStreamingV2BaseProvider = __esmMin((() => { return; } } catch (err) { - log$4.warn("Failed to parse WebSocket message", { error: err }); + log$3.warn("Failed to parse WebSocket message", { error: err }); } } requestSync() { @@ -40313,12 +40364,6 @@ async function getWalletAddress(args) { async function getWalletNetwork(args) { return wallet(args.walletId, "getNetwork"); } -async function getWalletPublicKey(args) { - return wallet(args.walletId, "getPublicKey"); -} -async function getSignedSignMessage(args) { - return wallet(args.walletId, "getSignedSignMessage", args.request); -} async function removeWallet(args) { return kit("removeWallet", args.walletId); } @@ -40552,7 +40597,7 @@ var getJettonWalletAddress = (args) => walletCall("getJettonWalletAddress", args init_models(); init_units(); var CACHE_TIMEOUT = 3e4; -var DEFAULT_METADATA$1 = { +var DEFAULT_METADATA = { [Network.mainnet().chainId]: { name: "Tonstakers", stakeToken: { @@ -40730,7 +40775,7 @@ init_StakingProvider(); init_errors$1(); init_ApiClientTonApi(); init_units(); -var log$3 = globalLogger.createChild("TonStakersStakingProvider"); +var log$2 = globalLogger.createChild("TonStakersStakingProvider"); /** * TonStakersStakingProvider - Staking provider for the Tonstakers liquid staking protocol. * @@ -40756,7 +40801,7 @@ var TonStakersStakingProvider = class TonStakersStakingProvider extends StakingP this.cache = new StakingCache(); this.metadataByNetwork = {}; for (const [chainId, config] of Object.entries(chainConfig)) { - const defaultMetadata = DEFAULT_METADATA$1[chainId]; + const defaultMetadata = DEFAULT_METADATA[chainId]; const overrides = config.metadata ?? {}; const merged = { ...defaultMetadata, @@ -40776,7 +40821,7 @@ var TonStakersStakingProvider = class TonStakersStakingProvider extends StakingP }); this.metadataByNetwork[chainId] = merged; } - log$3.info("TonStakersStakingProvider initialized"); + log$2.info("TonStakersStakingProvider initialized"); } /** * Resolves API clients from {@link ProviderFactoryContext.networkManager} on each call. @@ -40787,7 +40832,7 @@ var TonStakersStakingProvider = class TonStakersStakingProvider extends StakingP for (const network of ctx.networkManager.getConfiguredNetworks()) { const chainId = network.chainId; const perChain = config[chainId] ?? {}; - const hasDefaultContract = !!DEFAULT_METADATA$1[chainId]?.contractAddress; + const hasDefaultContract = !!DEFAULT_METADATA[chainId]?.contractAddress; const hasCustomContract = !!perChain.metadata?.contractAddress; if (!hasDefaultContract && !hasCustomContract) continue; chainConfig[chainId] = perChain; @@ -40802,7 +40847,7 @@ var TonStakersStakingProvider = class TonStakersStakingProvider extends StakingP * @returns Quote with expected amounts and current APY (for stake direction) */ async getQuote(params) { - log$3.debug("TonStakers quote requested", { + log$2.debug("TonStakers quote requested", { direction: params.direction, amount: params.amount, userAddress: params.userAddress, @@ -40869,7 +40914,7 @@ var TonStakersStakingProvider = class TonStakersStakingProvider extends StakingP else return this.buildUnstakeTonTransaction(params); } async buildStakeTonTransaction(params) { - log$3.debug("TonStakers stake requested", { params }); + log$2.debug("TonStakers stake requested", { params }); if (params.quote.direction !== "stake") throw new StakingError("Invalid quote direction", StakingErrorCode.InvalidParams, { quote: params.quote }); const network = params.quote.network; const contractAddress = this.getStakingContractAddress(network); @@ -40894,7 +40939,7 @@ var TonStakersStakingProvider = class TonStakersStakingProvider extends StakingP * @returns Transaction request ready to be signed and sent */ async buildUnstakeTonTransaction(params) { - log$3.debug("TonStakers unstake requested", { + log$2.debug("TonStakers unstake requested", { amount: params.quote.amountIn, userAddress: params.userAddress }); @@ -40940,7 +40985,7 @@ var TonStakersStakingProvider = class TonStakersStakingProvider extends StakingP * @param network - Network to query (defaults to mainnet) */ async getStakedBalance(userAddress, network) { - log$3.debug("TonStakers balance requested", { + log$2.debug("TonStakers balance requested", { userAddress, network }); @@ -40952,12 +40997,12 @@ var TonStakersStakingProvider = class TonStakersStakingProvider extends StakingP try { stakedBalance = await contract.getStakedBalance(userAddress); } catch (error) { - log$3.warn("Failed to get staked balance", { error }); + log$2.warn("Failed to get staked balance", { error }); } try { instantUnstakeAvailable = await contract.getPoolBalance(); } catch (error) { - log$3.warn("Failed to get instant unstake liquidity", { error }); + log$2.warn("Failed to get instant unstake liquidity", { error }); } return { rawStakedBalance: stakedBalance, @@ -40967,7 +41012,7 @@ var TonStakersStakingProvider = class TonStakersStakingProvider extends StakingP providerId: this.providerId }; } catch (error) { - log$3.error("Failed to get balance", { + log$2.error("Failed to get balance", { error, userAddress, network @@ -40988,7 +41033,7 @@ var TonStakersStakingProvider = class TonStakersStakingProvider extends StakingP * @returns Staking info with APY and available instant liquidity */ async getStakingProviderInfo(network) { - log$3.debug("TonStakers info requested", { network }); + log$2.debug("TonStakers info requested", { network }); const targetNetwork = network ?? Network.mainnet(); const cacheKey = `staking-info:${targetNetwork.chainId}`; return await this.cache.get(cacheKey, async () => { @@ -43323,7 +43368,7 @@ function createBaseAddress() { address: "" }; } -var Address$7 = { +var Address$4 = { fromJSON(object) { return { blockchain: isSet$7(object.blockchain) ? globalThis.Number(object.blockchain) : 0, @@ -43337,7 +43382,7 @@ var Address$7 = { return obj; }, create(base) { - return Address$7.fromPartial(base ?? {}); + return Address$4.fromPartial(base ?? {}); }, fromPartial(object) { const message = createBaseAddress(); @@ -43414,15 +43459,15 @@ function createBaseSwapStep() { var SwapStep = { fromJSON(object) { return { - bidAssetAddress: isSet$6(object.bid_asset_address) ? Address$7.fromJSON(object.bid_asset_address) : void 0, - askAssetAddress: isSet$6(object.ask_asset_address) ? Address$7.fromJSON(object.ask_asset_address) : void 0, + bidAssetAddress: isSet$6(object.bid_asset_address) ? Address$4.fromJSON(object.bid_asset_address) : void 0, + askAssetAddress: isSet$6(object.ask_asset_address) ? Address$4.fromJSON(object.ask_asset_address) : void 0, chunks: globalThis.Array.isArray(object?.chunks) ? object.chunks.map((e) => SwapChunk.fromJSON(e)) : [] }; }, toJSON(message) { const obj = {}; - if (message.bidAssetAddress !== void 0) obj.bid_asset_address = Address$7.toJSON(message.bidAssetAddress); - if (message.askAssetAddress !== void 0) obj.ask_asset_address = Address$7.toJSON(message.askAssetAddress); + if (message.bidAssetAddress !== void 0) obj.bid_asset_address = Address$4.toJSON(message.bidAssetAddress); + if (message.askAssetAddress !== void 0) obj.ask_asset_address = Address$4.toJSON(message.askAssetAddress); if (message.chunks?.length) obj.chunks = message.chunks.map((e) => SwapChunk.toJSON(e)); return obj; }, @@ -43431,8 +43476,8 @@ var SwapStep = { }, fromPartial(object) { const message = createBaseSwapStep(); - message.bidAssetAddress = object.bidAssetAddress !== void 0 && object.bidAssetAddress !== null ? Address$7.fromPartial(object.bidAssetAddress) : void 0; - message.askAssetAddress = object.askAssetAddress !== void 0 && object.askAssetAddress !== null ? Address$7.fromPartial(object.askAssetAddress) : void 0; + message.bidAssetAddress = object.bidAssetAddress !== void 0 && object.bidAssetAddress !== null ? Address$4.fromPartial(object.bidAssetAddress) : void 0; + message.askAssetAddress = object.askAssetAddress !== void 0 && object.askAssetAddress !== null ? Address$4.fromPartial(object.askAssetAddress) : void 0; message.chunks = object.chunks?.map((e) => SwapChunk.fromPartial(e)) || []; return message; } @@ -43592,16 +43637,16 @@ function createBaseEscrowSettlementParams() { var EscrowSettlementParams = { fromJSON(object) { return { - contractAddress: isSet$5(object.contract_address) ? Address$7.fromJSON(object.contract_address) : void 0, - resolverAddress: isSet$5(object.resolver_address) ? Address$7.fromJSON(object.resolver_address) : void 0, + contractAddress: isSet$5(object.contract_address) ? Address$4.fromJSON(object.contract_address) : void 0, + resolverAddress: isSet$5(object.resolver_address) ? Address$4.fromJSON(object.resolver_address) : void 0, resolveTimeout: isSet$5(object.resolve_timeout) ? globalThis.Number(object.resolve_timeout) : 0, gasless: isSet$5(object.gasless) ? globalThis.Boolean(object.gasless) : false }; }, toJSON(message) { const obj = {}; - if (message.contractAddress !== void 0) obj.contract_address = Address$7.toJSON(message.contractAddress); - if (message.resolverAddress !== void 0) obj.resolver_address = Address$7.toJSON(message.resolverAddress); + if (message.contractAddress !== void 0) obj.contract_address = Address$4.toJSON(message.contractAddress); + if (message.resolverAddress !== void 0) obj.resolver_address = Address$4.toJSON(message.resolverAddress); if (message.resolveTimeout !== void 0) obj.resolve_timeout = Math.round(message.resolveTimeout); if (message.gasless !== void 0) obj.gasless = message.gasless; return obj; @@ -43611,8 +43656,8 @@ var EscrowSettlementParams = { }, fromPartial(object) { const message = createBaseEscrowSettlementParams(); - message.contractAddress = object.contractAddress !== void 0 && object.contractAddress !== null ? Address$7.fromPartial(object.contractAddress) : void 0; - message.resolverAddress = object.resolverAddress !== void 0 && object.resolverAddress !== null ? Address$7.fromPartial(object.resolverAddress) : void 0; + message.contractAddress = object.contractAddress !== void 0 && object.contractAddress !== null ? Address$4.fromPartial(object.contractAddress) : void 0; + message.resolverAddress = object.resolverAddress !== void 0 && object.resolverAddress !== null ? Address$4.fromPartial(object.resolverAddress) : void 0; message.resolveTimeout = object.resolveTimeout ?? 0; message.gasless = object.gasless ?? false; return message; @@ -43628,15 +43673,15 @@ function createBaseHtlcSettlementParams() { var HtlcSettlementParams = { fromJSON(object) { return { - contractAddress: isSet$5(object.contract_address) ? Address$7.fromJSON(object.contract_address) : void 0, - resolverAddress: isSet$5(object.resolver_address) ? Address$7.fromJSON(object.resolver_address) : void 0, + contractAddress: isSet$5(object.contract_address) ? Address$4.fromJSON(object.contract_address) : void 0, + resolverAddress: isSet$5(object.resolver_address) ? Address$4.fromJSON(object.resolver_address) : void 0, resolveTimeout: isSet$5(object.resolve_timeout) ? globalThis.Number(object.resolve_timeout) : 0 }; }, toJSON(message) { const obj = {}; - if (message.contractAddress !== void 0) obj.contract_address = Address$7.toJSON(message.contractAddress); - if (message.resolverAddress !== void 0) obj.resolver_address = Address$7.toJSON(message.resolverAddress); + if (message.contractAddress !== void 0) obj.contract_address = Address$4.toJSON(message.contractAddress); + if (message.resolverAddress !== void 0) obj.resolver_address = Address$4.toJSON(message.resolverAddress); if (message.resolveTimeout !== void 0) obj.resolve_timeout = Math.round(message.resolveTimeout); return obj; }, @@ -43645,8 +43690,8 @@ var HtlcSettlementParams = { }, fromPartial(object) { const message = createBaseHtlcSettlementParams(); - message.contractAddress = object.contractAddress !== void 0 && object.contractAddress !== null ? Address$7.fromPartial(object.contractAddress) : void 0; - message.resolverAddress = object.resolverAddress !== void 0 && object.resolverAddress !== null ? Address$7.fromPartial(object.resolverAddress) : void 0; + message.contractAddress = object.contractAddress !== void 0 && object.contractAddress !== null ? Address$4.fromPartial(object.contractAddress) : void 0; + message.resolverAddress = object.resolverAddress !== void 0 && object.resolverAddress !== null ? Address$4.fromPartial(object.resolverAddress) : void 0; message.resolveTimeout = object.resolveTimeout ?? 0; return message; } @@ -43665,10 +43710,10 @@ function createBaseQuoteRequest() { var QuoteRequest$1 = { fromJSON(object) { return { - bidAssetAddress: isSet$5(object.bid_asset_address) ? Address$7.fromJSON(object.bid_asset_address) : void 0, - askAssetAddress: isSet$5(object.ask_asset_address) ? Address$7.fromJSON(object.ask_asset_address) : void 0, + bidAssetAddress: isSet$5(object.bid_asset_address) ? Address$4.fromJSON(object.bid_asset_address) : void 0, + askAssetAddress: isSet$5(object.ask_asset_address) ? Address$4.fromJSON(object.ask_asset_address) : void 0, amount: isSet$5(object.amount) ? QuoteRequest_AmountOneOf.fromJSON(object.amount) : void 0, - referrerAddress: isSet$5(object.referrer_address) ? Address$7.fromJSON(object.referrer_address) : void 0, + referrerAddress: isSet$5(object.referrer_address) ? Address$4.fromJSON(object.referrer_address) : void 0, referrerFeeBps: isSet$5(object.referrer_fee_bps) ? globalThis.Number(object.referrer_fee_bps) : 0, settlementMethods: globalThis.Array.isArray(object?.settlement_methods) ? object.settlement_methods.map((e) => settlementMethodFromJSON(e)) : [], settlementParams: isSet$5(object.settlement_params) ? RequestSettlementParams.fromJSON(object.settlement_params) : void 0 @@ -43676,10 +43721,10 @@ var QuoteRequest$1 = { }, toJSON(message) { const obj = {}; - if (message.bidAssetAddress !== void 0) obj.bid_asset_address = Address$7.toJSON(message.bidAssetAddress); - if (message.askAssetAddress !== void 0) obj.ask_asset_address = Address$7.toJSON(message.askAssetAddress); + if (message.bidAssetAddress !== void 0) obj.bid_asset_address = Address$4.toJSON(message.bidAssetAddress); + if (message.askAssetAddress !== void 0) obj.ask_asset_address = Address$4.toJSON(message.askAssetAddress); if (message.amount !== void 0) obj.amount = QuoteRequest_AmountOneOf.toJSON(message.amount); - if (message.referrerAddress !== void 0) obj.referrer_address = Address$7.toJSON(message.referrerAddress); + if (message.referrerAddress !== void 0) obj.referrer_address = Address$4.toJSON(message.referrerAddress); if (message.referrerFeeBps !== void 0) obj.referrer_fee_bps = Math.round(message.referrerFeeBps); if (message.settlementMethods?.length) obj.settlement_methods = message.settlementMethods.map((e) => settlementMethodToJSON(e)); if (message.settlementParams !== void 0) obj.settlement_params = RequestSettlementParams.toJSON(message.settlementParams); @@ -43690,10 +43735,10 @@ var QuoteRequest$1 = { }, fromPartial(object) { const message = createBaseQuoteRequest(); - message.bidAssetAddress = object.bidAssetAddress !== void 0 && object.bidAssetAddress !== null ? Address$7.fromPartial(object.bidAssetAddress) : void 0; - message.askAssetAddress = object.askAssetAddress !== void 0 && object.askAssetAddress !== null ? Address$7.fromPartial(object.askAssetAddress) : void 0; + message.bidAssetAddress = object.bidAssetAddress !== void 0 && object.bidAssetAddress !== null ? Address$4.fromPartial(object.bidAssetAddress) : void 0; + message.askAssetAddress = object.askAssetAddress !== void 0 && object.askAssetAddress !== null ? Address$4.fromPartial(object.askAssetAddress) : void 0; message.amount = object.amount !== void 0 && object.amount !== null ? QuoteRequest_AmountOneOf.fromPartial(object.amount) : void 0; - message.referrerAddress = object.referrerAddress !== void 0 && object.referrerAddress !== null ? Address$7.fromPartial(object.referrerAddress) : void 0; + message.referrerAddress = object.referrerAddress !== void 0 && object.referrerAddress !== null ? Address$4.fromPartial(object.referrerAddress) : void 0; message.referrerFeeBps = object.referrerFeeBps ?? 0; message.settlementMethods = object.settlementMethods?.map((e) => e) || []; message.settlementParams = object.settlementParams !== void 0 && object.settlementParams !== null ? RequestSettlementParams.fromPartial(object.settlementParams) : void 0; @@ -43756,14 +43801,14 @@ var Quote = { quoteId: isSet$5(object.quote_id) ? globalThis.String(object.quote_id) : "", resolverId: isSet$5(object.resolver_id) ? globalThis.String(object.resolver_id) : "", resolverName: isSet$5(object.resolver_name) ? globalThis.String(object.resolver_name) : "", - bidAssetAddress: isSet$5(object.bid_asset_address) ? Address$7.fromJSON(object.bid_asset_address) : void 0, - askAssetAddress: isSet$5(object.ask_asset_address) ? Address$7.fromJSON(object.ask_asset_address) : void 0, + bidAssetAddress: isSet$5(object.bid_asset_address) ? Address$4.fromJSON(object.bid_asset_address) : void 0, + askAssetAddress: isSet$5(object.ask_asset_address) ? Address$4.fromJSON(object.ask_asset_address) : void 0, bidUnits: isSet$5(object.bid_units) ? globalThis.String(object.bid_units) : "", askUnits: isSet$5(object.ask_units) ? globalThis.String(object.ask_units) : "", - referrerAddress: isSet$5(object.referrer_address) ? Address$7.fromJSON(object.referrer_address) : void 0, - referrerFeeAsset: isSet$5(object.referrer_fee_asset) ? Address$7.fromJSON(object.referrer_fee_asset) : void 0, + referrerAddress: isSet$5(object.referrer_address) ? Address$4.fromJSON(object.referrer_address) : void 0, + referrerFeeAsset: isSet$5(object.referrer_fee_asset) ? Address$4.fromJSON(object.referrer_fee_asset) : void 0, referrerFeeUnits: isSet$5(object.referrer_fee_units) ? globalThis.String(object.referrer_fee_units) : "", - protocolFeeAsset: isSet$5(object.protocol_fee_asset) ? Address$7.fromJSON(object.protocol_fee_asset) : void 0, + protocolFeeAsset: isSet$5(object.protocol_fee_asset) ? Address$4.fromJSON(object.protocol_fee_asset) : void 0, protocolFeeUnits: isSet$5(object.protocol_fee_units) ? globalThis.String(object.protocol_fee_units) : "", quoteTimestamp: isSet$5(object.quote_timestamp) ? globalThis.Number(object.quote_timestamp) : 0, tradeStartDeadline: isSet$5(object.trade_start_deadline) ? globalThis.Number(object.trade_start_deadline) : 0, @@ -43777,14 +43822,14 @@ var Quote = { if (message.quoteId !== void 0) obj.quote_id = message.quoteId; if (message.resolverId !== void 0) obj.resolver_id = message.resolverId; if (message.resolverName !== void 0) obj.resolver_name = message.resolverName; - if (message.bidAssetAddress !== void 0) obj.bid_asset_address = Address$7.toJSON(message.bidAssetAddress); - if (message.askAssetAddress !== void 0) obj.ask_asset_address = Address$7.toJSON(message.askAssetAddress); + if (message.bidAssetAddress !== void 0) obj.bid_asset_address = Address$4.toJSON(message.bidAssetAddress); + if (message.askAssetAddress !== void 0) obj.ask_asset_address = Address$4.toJSON(message.askAssetAddress); if (message.bidUnits !== void 0) obj.bid_units = message.bidUnits; if (message.askUnits !== void 0) obj.ask_units = message.askUnits; - if (message.referrerAddress !== void 0) obj.referrer_address = Address$7.toJSON(message.referrerAddress); - if (message.referrerFeeAsset !== void 0) obj.referrer_fee_asset = Address$7.toJSON(message.referrerFeeAsset); + if (message.referrerAddress !== void 0) obj.referrer_address = Address$4.toJSON(message.referrerAddress); + if (message.referrerFeeAsset !== void 0) obj.referrer_fee_asset = Address$4.toJSON(message.referrerFeeAsset); if (message.referrerFeeUnits !== void 0) obj.referrer_fee_units = message.referrerFeeUnits; - if (message.protocolFeeAsset !== void 0) obj.protocol_fee_asset = Address$7.toJSON(message.protocolFeeAsset); + if (message.protocolFeeAsset !== void 0) obj.protocol_fee_asset = Address$4.toJSON(message.protocolFeeAsset); if (message.protocolFeeUnits !== void 0) obj.protocol_fee_units = message.protocolFeeUnits; if (message.quoteTimestamp !== void 0) obj.quote_timestamp = Math.round(message.quoteTimestamp); if (message.tradeStartDeadline !== void 0) obj.trade_start_deadline = Math.round(message.tradeStartDeadline); @@ -43801,14 +43846,14 @@ var Quote = { message.quoteId = object.quoteId ?? ""; message.resolverId = object.resolverId ?? ""; message.resolverName = object.resolverName ?? ""; - message.bidAssetAddress = object.bidAssetAddress !== void 0 && object.bidAssetAddress !== null ? Address$7.fromPartial(object.bidAssetAddress) : void 0; - message.askAssetAddress = object.askAssetAddress !== void 0 && object.askAssetAddress !== null ? Address$7.fromPartial(object.askAssetAddress) : void 0; + message.bidAssetAddress = object.bidAssetAddress !== void 0 && object.bidAssetAddress !== null ? Address$4.fromPartial(object.bidAssetAddress) : void 0; + message.askAssetAddress = object.askAssetAddress !== void 0 && object.askAssetAddress !== null ? Address$4.fromPartial(object.askAssetAddress) : void 0; message.bidUnits = object.bidUnits ?? ""; message.askUnits = object.askUnits ?? ""; - message.referrerAddress = object.referrerAddress !== void 0 && object.referrerAddress !== null ? Address$7.fromPartial(object.referrerAddress) : void 0; - message.referrerFeeAsset = object.referrerFeeAsset !== void 0 && object.referrerFeeAsset !== null ? Address$7.fromPartial(object.referrerFeeAsset) : void 0; + message.referrerAddress = object.referrerAddress !== void 0 && object.referrerAddress !== null ? Address$4.fromPartial(object.referrerAddress) : void 0; + message.referrerFeeAsset = object.referrerFeeAsset !== void 0 && object.referrerFeeAsset !== null ? Address$4.fromPartial(object.referrerFeeAsset) : void 0; message.referrerFeeUnits = object.referrerFeeUnits ?? ""; - message.protocolFeeAsset = object.protocolFeeAsset !== void 0 && object.protocolFeeAsset !== null ? Address$7.fromPartial(object.protocolFeeAsset) : void 0; + message.protocolFeeAsset = object.protocolFeeAsset !== void 0 && object.protocolFeeAsset !== null ? Address$4.fromPartial(object.protocolFeeAsset) : void 0; message.protocolFeeUnits = object.protocolFeeUnits ?? ""; message.quoteTimestamp = object.quoteTimestamp ?? 0; message.tradeStartDeadline = object.tradeStartDeadline ?? 0; @@ -43863,11 +43908,11 @@ function createBaseEscrowOrderListRequest() { } var EscrowOrderListRequest$1 = { fromJSON(object) { - return { traderWalletAddress: isSet$4(object.trader_wallet_address) ? Address$7.fromJSON(object.trader_wallet_address) : void 0 }; + return { traderWalletAddress: isSet$4(object.trader_wallet_address) ? Address$4.fromJSON(object.trader_wallet_address) : void 0 }; }, toJSON(message) { const obj = {}; - if (message.traderWalletAddress !== void 0) obj.trader_wallet_address = Address$7.toJSON(message.traderWalletAddress); + if (message.traderWalletAddress !== void 0) obj.trader_wallet_address = Address$4.toJSON(message.traderWalletAddress); return obj; }, create(base) { @@ -43875,7 +43920,7 @@ var EscrowOrderListRequest$1 = { }, fromPartial(object) { const message = createBaseEscrowOrderListRequest(); - message.traderWalletAddress = object.traderWalletAddress !== void 0 && object.traderWalletAddress !== null ? Address$7.fromPartial(object.traderWalletAddress) : void 0; + message.traderWalletAddress = object.traderWalletAddress !== void 0 && object.traderWalletAddress !== null ? Address$4.fromPartial(object.traderWalletAddress) : void 0; return message; } }; @@ -43911,14 +43956,14 @@ var EscrowOrderData$1 = { fromJSON(object) { return { quote: isSet$4(object.quote) ? Quote.fromJSON(object.quote) : void 0, - escrowItemAddress: isSet$4(object.escrow_item_address) ? Address$7.fromJSON(object.escrow_item_address) : void 0, + escrowItemAddress: isSet$4(object.escrow_item_address) ? Address$4.fromJSON(object.escrow_item_address) : void 0, outgoingTxHash: isSet$4(object.outgoing_tx_hash) ? globalThis.String(object.outgoing_tx_hash) : "" }; }, toJSON(message) { const obj = {}; if (message.quote !== void 0) obj.quote = Quote.toJSON(message.quote); - if (message.escrowItemAddress !== void 0) obj.escrow_item_address = Address$7.toJSON(message.escrowItemAddress); + if (message.escrowItemAddress !== void 0) obj.escrow_item_address = Address$4.toJSON(message.escrowItemAddress); if (message.outgoingTxHash !== void 0) obj.outgoing_tx_hash = message.outgoingTxHash; return obj; }, @@ -43928,7 +43973,7 @@ var EscrowOrderData$1 = { fromPartial(object) { const message = createBaseEscrowOrderData(); message.quote = object.quote !== void 0 && object.quote !== null ? Quote.fromPartial(object.quote) : void 0; - message.escrowItemAddress = object.escrowItemAddress !== void 0 && object.escrowItemAddress !== null ? Address$7.fromPartial(object.escrowItemAddress) : void 0; + message.escrowItemAddress = object.escrowItemAddress !== void 0 && object.escrowItemAddress !== null ? Address$4.fromPartial(object.escrowItemAddress) : void 0; message.outgoingTxHash = object.outgoingTxHash ?? ""; return message; } @@ -44232,7 +44277,7 @@ var SwapChunkStatus = { fromJSON(object) { return { protocol: isSet$2(object.protocol) ? globalThis.String(object.protocol) : "", - targetAddress: isSet$2(object.target_address) ? Address$7.fromJSON(object.target_address) : void 0, + targetAddress: isSet$2(object.target_address) ? Address$4.fromJSON(object.target_address) : void 0, bidUnits: isSet$2(object.bid_units) ? globalThis.String(object.bid_units) : "", expectedAskUnits: isSet$2(object.expected_ask_units) ? globalThis.String(object.expected_ask_units) : "", actualAskUnits: isSet$2(object.actual_ask_units) ? globalThis.String(object.actual_ask_units) : "", @@ -44243,7 +44288,7 @@ var SwapChunkStatus = { toJSON(message) { const obj = {}; if (message.protocol !== void 0) obj.protocol = message.protocol; - if (message.targetAddress !== void 0) obj.target_address = Address$7.toJSON(message.targetAddress); + if (message.targetAddress !== void 0) obj.target_address = Address$4.toJSON(message.targetAddress); if (message.bidUnits !== void 0) obj.bid_units = message.bidUnits; if (message.expectedAskUnits !== void 0) obj.expected_ask_units = message.expectedAskUnits; if (message.actualAskUnits !== void 0) obj.actual_ask_units = message.actualAskUnits; @@ -44257,7 +44302,7 @@ var SwapChunkStatus = { fromPartial(object) { const message = createBaseSwapChunkStatus(); message.protocol = object.protocol ?? ""; - message.targetAddress = object.targetAddress !== void 0 && object.targetAddress !== null ? Address$7.fromPartial(object.targetAddress) : void 0; + message.targetAddress = object.targetAddress !== void 0 && object.targetAddress !== null ? Address$4.fromPartial(object.targetAddress) : void 0; message.bidUnits = object.bidUnits ?? ""; message.expectedAskUnits = object.expectedAskUnits ?? ""; message.actualAskUnits = object.actualAskUnits ?? ""; @@ -44318,14 +44363,14 @@ function createBaseEscrowOrderStatus() { var EscrowOrderStatus = { fromJSON(object) { return { - targetAddress: isSet$2(object.target_address) ? Address$7.fromJSON(object.target_address) : void 0, + targetAddress: isSet$2(object.target_address) ? Address$4.fromJSON(object.target_address) : void 0, askUnits: isSet$2(object.ask_units) ? globalThis.String(object.ask_units) : "", txHash: isSet$2(object.tx_hash) ? globalThis.String(object.tx_hash) : "" }; }, toJSON(message) { const obj = {}; - if (message.targetAddress !== void 0) obj.target_address = Address$7.toJSON(message.targetAddress); + if (message.targetAddress !== void 0) obj.target_address = Address$4.toJSON(message.targetAddress); if (message.askUnits !== void 0) obj.ask_units = message.askUnits; if (message.txHash !== void 0) obj.tx_hash = message.txHash; return obj; @@ -44335,7 +44380,7 @@ var EscrowOrderStatus = { }, fromPartial(object) { const message = createBaseEscrowOrderStatus(); - message.targetAddress = object.targetAddress !== void 0 && object.targetAddress !== null ? Address$7.fromPartial(object.targetAddress) : void 0; + message.targetAddress = object.targetAddress !== void 0 && object.targetAddress !== null ? Address$4.fromPartial(object.targetAddress) : void 0; message.askUnits = object.askUnits ?? ""; message.txHash = object.txHash ?? ""; return message; @@ -44352,14 +44397,14 @@ var TrackTradeRequest$1 = { fromJSON(object) { return { quoteId: isSet$2(object.quote_id) ? globalThis.String(object.quote_id) : "", - traderWalletAddress: isSet$2(object.trader_wallet_address) ? Address$7.fromJSON(object.trader_wallet_address) : void 0, + traderWalletAddress: isSet$2(object.trader_wallet_address) ? Address$4.fromJSON(object.trader_wallet_address) : void 0, outgoingTxHash: isSet$2(object.outgoing_tx_hash) ? globalThis.String(object.outgoing_tx_hash) : "" }; }, toJSON(message) { const obj = {}; if (message.quoteId !== void 0) obj.quote_id = message.quoteId; - if (message.traderWalletAddress !== void 0) obj.trader_wallet_address = Address$7.toJSON(message.traderWalletAddress); + if (message.traderWalletAddress !== void 0) obj.trader_wallet_address = Address$4.toJSON(message.traderWalletAddress); if (message.outgoingTxHash !== void 0) obj.outgoing_tx_hash = message.outgoingTxHash; return obj; }, @@ -44369,7 +44414,7 @@ var TrackTradeRequest$1 = { fromPartial(object) { const message = createBaseTrackTradeRequest(); message.quoteId = object.quoteId ?? ""; - message.traderWalletAddress = object.traderWalletAddress !== void 0 && object.traderWalletAddress !== null ? Address$7.fromPartial(object.traderWalletAddress) : void 0; + message.traderWalletAddress = object.traderWalletAddress !== void 0 && object.traderWalletAddress !== null ? Address$4.fromPartial(object.traderWalletAddress) : void 0; message.outgoingTxHash = object.outgoingTxHash ?? ""; return message; } @@ -44455,13 +44500,13 @@ function createBaseClaimAvailable() { var ClaimAvailable = { fromJSON(object) { return { - contractAddress: isSet$2(object.contract_address) ? Address$7.fromJSON(object.contract_address) : void 0, + contractAddress: isSet$2(object.contract_address) ? Address$4.fromJSON(object.contract_address) : void 0, depositIndex: isSet$2(object.deposit_index) ? globalThis.Number(object.deposit_index) : 0 }; }, toJSON(message) { const obj = {}; - if (message.contractAddress !== void 0) obj.contract_address = Address$7.toJSON(message.contractAddress); + if (message.contractAddress !== void 0) obj.contract_address = Address$4.toJSON(message.contractAddress); if (message.depositIndex !== void 0) obj.deposit_index = Math.round(message.depositIndex); return obj; }, @@ -44470,7 +44515,7 @@ var ClaimAvailable = { }, fromPartial(object) { const message = createBaseClaimAvailable(); - message.contractAddress = object.contractAddress !== void 0 && object.contractAddress !== null ? Address$7.fromPartial(object.contractAddress) : void 0; + message.contractAddress = object.contractAddress !== void 0 && object.contractAddress !== null ? Address$4.fromPartial(object.contractAddress) : void 0; message.depositIndex = object.depositIndex ?? 0; return message; } @@ -44480,11 +44525,11 @@ function createBaseRefundAvailable() { } var RefundAvailable = { fromJSON(object) { - return { contractAddress: isSet$2(object.contract_address) ? Address$7.fromJSON(object.contract_address) : void 0 }; + return { contractAddress: isSet$2(object.contract_address) ? Address$4.fromJSON(object.contract_address) : void 0 }; }, toJSON(message) { const obj = {}; - if (message.contractAddress !== void 0) obj.contract_address = Address$7.toJSON(message.contractAddress); + if (message.contractAddress !== void 0) obj.contract_address = Address$4.toJSON(message.contractAddress); return obj; }, create(base) { @@ -44492,7 +44537,7 @@ var RefundAvailable = { }, fromPartial(object) { const message = createBaseRefundAvailable(); - message.contractAddress = object.contractAddress !== void 0 && object.contractAddress !== null ? Address$7.fromPartial(object.contractAddress) : void 0; + message.contractAddress = object.contractAddress !== void 0 && object.contractAddress !== null ? Address$4.fromPartial(object.contractAddress) : void 0; return message; } }; @@ -44661,20 +44706,20 @@ function createBaseBuildTransferRequest() { var BuildTransferRequest$1 = { fromJSON(object) { return { - sourceAddress: isSet$1(object.source_address) ? Address$7.fromJSON(object.source_address) : void 0, - destinationAddress: isSet$1(object.destination_address) ? Address$7.fromJSON(object.destination_address) : void 0, - gasExcessAddress: isSet$1(object.gas_excess_address) ? Address$7.fromJSON(object.gas_excess_address) : void 0, - refundAddress: isSet$1(object.refund_address) ? Address$7.fromJSON(object.refund_address) : void 0, + sourceAddress: isSet$1(object.source_address) ? Address$4.fromJSON(object.source_address) : void 0, + destinationAddress: isSet$1(object.destination_address) ? Address$4.fromJSON(object.destination_address) : void 0, + gasExcessAddress: isSet$1(object.gas_excess_address) ? Address$4.fromJSON(object.gas_excess_address) : void 0, + refundAddress: isSet$1(object.refund_address) ? Address$4.fromJSON(object.refund_address) : void 0, quote: isSet$1(object.quote) ? Quote.fromJSON(object.quote) : void 0, useRecommendedSlippage: isSet$1(object.use_recommended_slippage) ? globalThis.Boolean(object.use_recommended_slippage) : false }; }, toJSON(message) { const obj = {}; - if (message.sourceAddress !== void 0) obj.source_address = Address$7.toJSON(message.sourceAddress); - if (message.destinationAddress !== void 0) obj.destination_address = Address$7.toJSON(message.destinationAddress); - if (message.gasExcessAddress !== void 0) obj.gas_excess_address = Address$7.toJSON(message.gasExcessAddress); - if (message.refundAddress !== void 0) obj.refund_address = Address$7.toJSON(message.refundAddress); + if (message.sourceAddress !== void 0) obj.source_address = Address$4.toJSON(message.sourceAddress); + if (message.destinationAddress !== void 0) obj.destination_address = Address$4.toJSON(message.destinationAddress); + if (message.gasExcessAddress !== void 0) obj.gas_excess_address = Address$4.toJSON(message.gasExcessAddress); + if (message.refundAddress !== void 0) obj.refund_address = Address$4.toJSON(message.refundAddress); if (message.quote !== void 0) obj.quote = Quote.toJSON(message.quote); if (message.useRecommendedSlippage !== void 0) obj.use_recommended_slippage = message.useRecommendedSlippage; return obj; @@ -44684,10 +44729,10 @@ var BuildTransferRequest$1 = { }, fromPartial(object) { const message = createBaseBuildTransferRequest(); - message.sourceAddress = object.sourceAddress !== void 0 && object.sourceAddress !== null ? Address$7.fromPartial(object.sourceAddress) : void 0; - message.destinationAddress = object.destinationAddress !== void 0 && object.destinationAddress !== null ? Address$7.fromPartial(object.destinationAddress) : void 0; - message.gasExcessAddress = object.gasExcessAddress !== void 0 && object.gasExcessAddress !== null ? Address$7.fromPartial(object.gasExcessAddress) : void 0; - message.refundAddress = object.refundAddress !== void 0 && object.refundAddress !== null ? Address$7.fromPartial(object.refundAddress) : void 0; + message.sourceAddress = object.sourceAddress !== void 0 && object.sourceAddress !== null ? Address$4.fromPartial(object.sourceAddress) : void 0; + message.destinationAddress = object.destinationAddress !== void 0 && object.destinationAddress !== null ? Address$4.fromPartial(object.destinationAddress) : void 0; + message.gasExcessAddress = object.gasExcessAddress !== void 0 && object.gasExcessAddress !== null ? Address$4.fromPartial(object.gasExcessAddress) : void 0; + message.refundAddress = object.refundAddress !== void 0 && object.refundAddress !== null ? Address$4.fromPartial(object.refundAddress) : void 0; message.quote = object.quote !== void 0 && object.quote !== null ? Quote.fromPartial(object.quote) : void 0; message.useRecommendedSlippage = object.useRecommendedSlippage ?? false; return message; @@ -44703,16 +44748,16 @@ function createBaseBuildWithdrawalRequest() { var BuildWithdrawalRequest$1 = { fromJSON(object) { return { - sourceAddress: isSet$1(object.source_address) ? Address$7.fromJSON(object.source_address) : void 0, + sourceAddress: isSet$1(object.source_address) ? Address$4.fromJSON(object.source_address) : void 0, quoteId: isSet$1(object.quote_id) ? globalThis.String(object.quote_id) : "", - gasExcessAddress: isSet$1(object.gas_excess_address) ? Address$7.fromJSON(object.gas_excess_address) : void 0 + gasExcessAddress: isSet$1(object.gas_excess_address) ? Address$4.fromJSON(object.gas_excess_address) : void 0 }; }, toJSON(message) { const obj = {}; - if (message.sourceAddress !== void 0) obj.source_address = Address$7.toJSON(message.sourceAddress); + if (message.sourceAddress !== void 0) obj.source_address = Address$4.toJSON(message.sourceAddress); if (message.quoteId !== void 0) obj.quote_id = message.quoteId; - if (message.gasExcessAddress !== void 0) obj.gas_excess_address = Address$7.toJSON(message.gasExcessAddress); + if (message.gasExcessAddress !== void 0) obj.gas_excess_address = Address$4.toJSON(message.gasExcessAddress); return obj; }, create(base) { @@ -44720,9 +44765,9 @@ var BuildWithdrawalRequest$1 = { }, fromPartial(object) { const message = createBaseBuildWithdrawalRequest(); - message.sourceAddress = object.sourceAddress !== void 0 && object.sourceAddress !== null ? Address$7.fromPartial(object.sourceAddress) : void 0; + message.sourceAddress = object.sourceAddress !== void 0 && object.sourceAddress !== null ? Address$4.fromPartial(object.sourceAddress) : void 0; message.quoteId = object.quoteId ?? ""; - message.gasExcessAddress = object.gasExcessAddress !== void 0 && object.gasExcessAddress !== null ? Address$7.fromPartial(object.gasExcessAddress) : void 0; + message.gasExcessAddress = object.gasExcessAddress !== void 0 && object.gasExcessAddress !== null ? Address$4.fromPartial(object.gasExcessAddress) : void 0; return message; } }; @@ -45123,7 +45168,7 @@ init_errors$2(); init_Logger(); init_utils$2(); init_units(); -var log$2 = globalLogger.createChild("OmnistonSwapProvider"); +var log$1 = globalLogger.createChild("OmnistonSwapProvider"); /** * Swap provider implementation for Omniston (STON.fi) protocol * @@ -45173,7 +45218,7 @@ var OmnistonSwapProvider = class extends SwapProvider { ...this.metadata, ...config.metadata }; - log$2.info("OmnistonSwapProvider initialized", { + log$1.info("OmnistonSwapProvider initialized", { defaultSlippageBps: this.defaultSlippageBps, hasReferrer: !!this.referrerAddress }); @@ -45189,7 +45234,7 @@ var OmnistonSwapProvider = class extends SwapProvider { return this.omniston$; } async getQuote(params) { - log$2.debug("Getting Omniston quote", { + log$1.debug("Getting Omniston quote", { fromToken: params.from, toToken: params.to, amount: params.amount, @@ -45218,9 +45263,9 @@ var OmnistonSwapProvider = class extends SwapProvider { }; const quoteEvent = await new Promise((resolve, reject) => { let isSettled = false; - log$2.debug("Requesting quote", { quoteRequest }); + log$1.debug("Requesting quote", { quoteRequest }); const timeoutId = setTimeout(() => { - log$2.debug("Timeout reached"); + log$1.debug("Timeout reached"); if (!isSettled) { isSettled = true; reject(new SwapError("Quote request timed out", SwapErrorCode.NetworkError)); @@ -45229,7 +45274,7 @@ var OmnistonSwapProvider = class extends SwapProvider { }, this.quoteTimeoutMs); const unsubscribe = this.omniston.requestForQuote(quoteRequest).subscribe({ next: (event) => { - log$2.debug("Received quote event", event); + log$1.debug("Received quote event", event); if (isSettled) return; if (event.type === "noQuote") { isSettled = true; @@ -45258,14 +45303,14 @@ var OmnistonSwapProvider = class extends SwapProvider { if (quoteEvent.type !== "quoteUpdated") throw new SwapError("Quote data is missing", SwapErrorCode.InvalidQuote); const quote = quoteEvent.quote; const swapQuote = this.mapOmnistonQuoteToSwapQuote(quote, params); - log$2.debug("Received Omniston quote", { + log$1.debug("Received Omniston quote", { quoteId: quote.quoteId, bidUnits: quote.bidUnits, askUnits: quote.askUnits }); return swapQuote; } catch (error) { - log$2.error("Failed to get Omniston quote", { + log$1.error("Failed to get Omniston quote", { error, params }); @@ -45274,7 +45319,7 @@ var OmnistonSwapProvider = class extends SwapProvider { } } async buildSwapTransaction(params) { - log$2.debug("Building Omniston swap transaction", params); + log$1.debug("Building Omniston swap transaction", params); const metadata = params.quote.metadata; if (!metadata || !isOmnistonQuoteMetadata(metadata)) throw new SwapError("Invalid quote: missing Omniston quote data", SwapErrorCode.InvalidQuote); try { @@ -45303,13 +45348,13 @@ var OmnistonSwapProvider = class extends SwapProvider { })), network: params.quote.network }; - log$2.debug("Built Omniston swap transaction", { + log$1.debug("Built Omniston swap transaction", { quoteId: metadata.omnistonQuote.quoteId, transaction }); return transaction; } catch (error) { - log$2.error("Failed to build Omniston swap transaction", { + log$1.error("Failed to build Omniston swap transaction", { error, params }); @@ -45389,7 +45434,7 @@ init_errors$2(); init_Logger(); init_utils$2(); init_units(); -var log$1 = globalLogger.createChild("DeDustSwapProvider"); +var log = globalLogger.createChild("DeDustSwapProvider"); /** * Default API URL for DeDust Router */ @@ -45452,7 +45497,7 @@ var DeDustSwapProvider = class extends SwapProvider { ...this.metadata, ...config.metadata }; - log$1.info("DeDustSwapProvider initialized", { + log.info("DeDustSwapProvider initialized", { apiUrl: this.apiUrl, defaultSlippageBps: this.defaultSlippageBps, hasReferral: !!this.referralAddress @@ -45465,7 +45510,7 @@ var DeDustSwapProvider = class extends SwapProvider { return [Network.mainnet()]; } async getQuote(params) { - log$1.debug("Getting DeDust quote", { + log.debug("Getting DeDust quote", { fromToken: params.from, toToken: params.to, amount: params.amount, @@ -45500,7 +45545,7 @@ var DeDustSwapProvider = class extends SwapProvider { }); if (!response.ok) { const errorText = await response.text(); - log$1.error("DeDust quote API error", { + log.error("DeDust quote API error", { status: response.status, error: errorText }); @@ -45528,7 +45573,7 @@ var DeDustSwapProvider = class extends SwapProvider { network: params.network, priceImpact: quoteResponse.price_impact ? Math.round(quoteResponse.price_impact * 100) : void 0 }; - log$1.debug("Received DeDust quote", { + log.debug("Received DeDust quote", { inAmount: quoteResponse.in_amount, outAmount: quoteResponse.out_amount, minReceived: minReceived.toString(), @@ -45536,7 +45581,7 @@ var DeDustSwapProvider = class extends SwapProvider { }); return swapQuote; } catch (error) { - log$1.error("Failed to get DeDust quote", { + log.error("Failed to get DeDust quote", { error, params }); @@ -45545,7 +45590,7 @@ var DeDustSwapProvider = class extends SwapProvider { } } async buildSwapTransaction(params) { - log$1.debug("Building DeDust swap transaction", params); + log.debug("Building DeDust swap transaction", params); const metadata = params.quote.metadata; if (!metadata || !isDeDustQuoteMetadata(metadata)) throw new SwapError("Invalid quote: missing DeDust quote data", SwapErrorCode.InvalidQuote); try { @@ -45568,7 +45613,7 @@ var DeDustSwapProvider = class extends SwapProvider { }); if (!response.ok) { const errorText = await response.text(); - log$1.error("DeDust swap API error", { + log.error("DeDust swap API error", { status: response.status, error: errorText }); @@ -45586,10 +45631,10 @@ var DeDustSwapProvider = class extends SwapProvider { })), network: params.quote.network }; - log$1.debug("Built DeDust swap transaction", { messageCount: transaction.messages.length }); + log.debug("Built DeDust swap transaction", { messageCount: transaction.messages.length }); return transaction; } catch (error) { - log$1.error("Failed to build DeDust swap transaction", { + log.error("Failed to build DeDust swap transaction", { error, params }); @@ -45700,381 +45745,6 @@ async function registerKotlinSwapProvider(args) { retainWithId(args.providerId, provider); (await getSwap()).registerProvider(provider); } -/** Static metadata returned by `TonApiGaslessProvider.getMetadata()`. */ -var DEFAULT_METADATA = { - name: "TonAPI", - url: "https://tonapi.io" -}; -//#endregion -//#region ../walletkit/dist/esm/defi/gasless/tonapi/utils.js -/** -* Copyright (c) TonTech. -* -* This source code is licensed under the MIT license found in the -* LICENSE file in the root directory of this source tree. -* -*/ -init_models(); -init_TonClientError(); -init_base64(); -init_hex(); -init_errors(); -var stripHexPrefix = (value) => { - return value.startsWith("0x") ? value.slice(2) : value; -}; -/** -* TonAPI returns BoCs as bare hex strings (no `0x` prefix); the walletkit domain -* uses base64 (`Base64String`). Re-encoding is byte-identical; `asHex` validates -* the hex first. Shared by the quote and send mappers. -*/ -var hexBocToBase64 = (hex) => { - return HexToBase64(asHex(hex.startsWith("0x") ? hex : `0x${hex}`)); -}; -var buildInternalMessageCell = (message) => { - const to = import_dist$1.Address.parse(message.address); - const value = BigInt(message.amount); - const body = message.payload ? import_dist$1.Cell.fromBase64(message.payload) : (0, import_dist$1.beginCell)().endCell(); - const init = message.stateInit ? (0, import_dist$1.loadStateInit)(import_dist$1.Cell.fromBase64(message.stateInit).beginParse()) : void 0; - return (0, import_dist$1.beginCell)().storeWritable((0, import_dist$1.storeMessageRelaxed)((0, import_dist$1.internal)({ - to, - value, - bounce: true, - body, - init - }))).endCell(); -}; -/** -* Convert an internal-message BoC (what `wallet.signMessage` returns) into an -* external message BoC that the relayer accepts for broadcast. -*/ -var internalBocToExternalMessageBoc = (internalBoc) => { - const { info, body, init } = (0, import_dist$1.loadMessageRelaxed)(import_dist$1.Cell.fromBase64(internalBoc).beginParse()); - if (info.type !== "internal") throw new GaslessError("Signed message must be an internal message", GaslessErrorCode.SendFailed); - return (0, import_dist$1.beginCell)().storeWritable((0, import_dist$1.storeMessage)((0, import_dist$1.external)({ - to: info.dest, - init: init ?? void 0, - body - }))).endCell(); -}; -/** -* Reconstruct a `Network` instance from a chainId string. Used to map -* `Object.keys(chainConfig)` back to `Network` objects. -*/ -var networkFromChainId = (chainId) => { - switch (chainId) { - case Network.mainnet().chainId: return Network.mainnet(); - case Network.testnet().chainId: return Network.testnet(); - case Network.tetra().chainId: return Network.tetra(); - default: return Network.custom(chainId); - } -}; -/** -* Decide whether a TonAPI gasless request failure (`/v2/gasless/estimate` or -* `/v2/gasless/send`) is worth retrying. -* -* Retry on 5xx server errors and HTTP 408/429 (timeout / rate limit), and on -* non-HTTP errors (network failures: fetch `TypeError`, `AbortError`). -*/ -var isTransientError = (error) => { - if (error instanceof TonClientError) return error.status >= 500 || error.status === 408 || error.status === 429; - return error instanceof Error; -}; -//#endregion -//#region ../walletkit/dist/esm/defi/gasless/tonapi/mappers/map-gasless-config.js -init_address$1(); -/** -* Wire → domain: map TonAPI's `/v2/gasless/config` response to `GaslessConfig`. -* Bundles both the relay address (for jetton-transfer `responseDestination`) -* and the assets the relayer accepts as fee payment. -*/ -var mapGaslessConfig = (raw) => ({ - relayAddress: asAddressFriendly(raw.relay_address), - supportedAssets: raw.gas_jettons.map((jetton) => ({ address: asAddressFriendly(jetton.master_id) })) -}); -//#endregion -//#region ../walletkit/dist/esm/defi/gasless/tonapi/mappers/map-gasless-error.js -init_errors(); -var mapTonApiGaslessError = (error, fallbackCode, fallbackMessage) => { - if (error instanceof GaslessError) return error; - return new GaslessError(error instanceof Error ? error.message : fallbackMessage, fallbackCode, error); -}; -//#endregion -//#region ../walletkit/dist/esm/defi/gasless/tonapi/mappers/map-gasless-quote.js -/** -* Copyright (c) TonTech. -* -* This source code is licensed under the MIT license found in the -* LICENSE file in the root directory of this source tree. -* -*/ -init_address$1(); -init_hex(); -/** -* Domain → wire: build the JSON body for `POST /v2/gasless/estimate/{master_id}`. -* -* Caller messages are encoded as hex BoCs of internal messages (TonAPI's wire format). -*/ -var buildGaslessQuoteRequest = (params) => ({ - wallet_address: import_dist$1.Address.parse(params.walletAddress).toRawString(), - wallet_public_key: stripHexPrefix(asHex(params.walletPublicKey)), - messages: params.messages.map((message) => ({ boc: buildInternalMessageCell(message).toBoc().toString("hex") })) -}); -/** -* Wire → domain: map the TonAPI estimate response to `GaslessQuote`. -* -* Hex BoCs in `payload` / `state_init` are converted back to base64. `network` -* is threaded in from the request — the relayer does not echo it. -*/ -var mapGaslessQuote = (raw, network) => ({ - network, - messages: raw.messages.map((message) => ({ - address: asAddressFriendly(message.address), - amount: message.amount, - payload: message.payload ? hexBocToBase64(message.payload) : void 0, - stateInit: message.state_init ? hexBocToBase64(message.state_init) : void 0 - })), - fee: raw.commission, - validUntil: raw.valid_until, - from: asAddressFriendly(raw.from) -}); -//#endregion -//#region ../walletkit/dist/esm/defi/gasless/tonapi/mappers/map-gasless-send.js -init_hex(); -init_getNormalizedExtMessageHash(); -init_errors(); -/** -* Domain → wire: build the JSON body for `POST /v2/gasless/send`. -* -* The signed internal-message BoC (returned by `wallet.signMessage`) is -* unwrapped into an external message BoC that the relayer can broadcast. -*/ -var buildGaslessSendRequest = (params) => ({ - wallet_public_key: stripHexPrefix(asHex(params.walletPublicKey)), - boc: internalBocToExternalMessageBoc(params.internalBoc).toBoc().toString("hex") -}); -/** -* Wire → domain: turn TonAPI's `GaslessTx` response into a `SendTransactionResponse`. -* -* Despite the OpenAPI description ("Normalized hash of the external message"), -* `external` is the **full hex BoC** of the external-in message the relayer -* actually broadcast — verified against live TonAPI. Crucially it is the -* *relayer's own* external message (addressed to the relayer's wallet), which -* differs from the external message we submit (addressed to the user's wallet), -* so it is the only source for the real on-chain hash. We re-encode it to base64 -* and normalize via `getNormalizedExtMessageHash` to yield the same -* `{ boc, normalizedBoc, normalizedHash }` triple as `wallet.sendTransaction`. -*/ -var mapGaslessSend = (raw) => { - if (!raw.external) throw new GaslessError("Relayer did not return the broadcasted external message", GaslessErrorCode.SendFailed, { protocolName: raw.protocol_name }); - try { - const boc = hexBocToBase64(raw.external); - const { hash: normalizedHash, boc: normalizedBoc } = getNormalizedExtMessageHash(boc); - return { - boc, - normalizedBoc, - normalizedHash - }; - } catch (cause) { - throw new GaslessError("Relayer `external` is not a parseable external-message BoC — TonAPI response format may have changed.", GaslessErrorCode.SendFailed, { - external: raw.external, - cause - }); - } -}; -//#endregion -//#region ../walletkit/dist/esm/defi/gasless/tonapi/TonApiGaslessProvider.js -/** -* Copyright (c) TonTech. -* -* This source code is licensed under the MIT license found in the -* LICENSE file in the root directory of this source tree. -* -*/ -init_index_min(); -init_ApiClientTonApi(); -init_Logger(); -init_retry(); -init_errors(); -init_GaslessProvider(); -var log = globalLogger.createChild("TonApiGaslessProvider"); -/** -* Gasless provider implementation backed by the public TonAPI REST API. -* -* Implements the flow documented at https://docs.tonapi.io/tonapi/rest-api/gasless. -* -* @example -* ```typescript -* import { Network } from '@ton/walletkit'; -* import { createTonApiGaslessProvider } from '@ton/walletkit/gasless/tonapi'; -* -* const provider = createTonApiGaslessProvider({ -* chains: { -* [Network.mainnet().chainId]: { apiKey: process.env.TON_API_KEY }, -* }, -* }); -* -* kit.gasless.registerProvider(provider); -* ``` -*/ -var TonApiGaslessProvider = class TonApiGaslessProvider extends GaslessProvider { - providerId; - chainConfig; - clients = {}; - sendRetries; - sendRetryDelayMs; - quoteRetries; - quoteRetryDelayMs; - configCacheTtlMs; - configCache; - /** - * @internal Use {@link createTonApiGaslessProvider} (AppKit) or {@link TonApiGaslessProvider.createFromContext}. - */ - constructor(chainConfig, options) { - super(); - this.chainConfig = chainConfig; - this.providerId = options.providerId ?? "tonapi"; - this.sendRetries = options.sendRetries ?? 5; - this.sendRetryDelayMs = options.sendRetryDelayMs ?? 1e3; - this.quoteRetries = options.quoteRetries ?? 5; - this.quoteRetryDelayMs = options.quoteRetryDelayMs ?? 1e3; - this.configCacheTtlMs = options.configCacheTtlMs ?? 3e5; - if (this.configCacheTtlMs > 0) this.configCache = new U({ - max: Math.max(1, Object.keys(chainConfig).length), - ttl: this.configCacheTtlMs, - fetchMethod: (_chainId, _stale, { context }) => this.fetchConfig(context) - }); - log.info("TonApiGaslessProvider initialized", { - providerId: this.providerId, - chains: Object.keys(this.chainConfig) - }); - } - /** - * Build a provider that serves every network the kit was configured with. - * - * If `config.chains` is provided, only those chains are registered (and they - * must intersect with the kit's configured networks). Otherwise every - * configured network gets a default TonAPI client. - */ - static createFromContext(ctx, config = {}) { - const configuredChains = new Set(ctx.networkManager.getConfiguredNetworks().map((n) => n.chainId)); - const chainConfig = {}; - if (config.chains) for (const [chainId, perChain] of Object.entries(config.chains)) { - if (!configuredChains.has(chainId)) { - log.warn("Skipping TonApi gasless chain not configured in the kit", { chainId }); - continue; - } - chainConfig[chainId] = perChain; - } - else for (const chainId of configuredChains) chainConfig[chainId] = {}; - if (Object.keys(chainConfig).length === 0) throw new Error("createTonApiGaslessProvider: no eligible networks (configure at least one network in the kit, or pass `chains` matching a configured network)"); - return new TonApiGaslessProvider(chainConfig, config); - } - getSupportedNetworks() { - return Object.keys(this.chainConfig).map(networkFromChainId); - } - async getMetadata() { - return DEFAULT_METADATA; - } - async getConfig(network) { - if (!this.configCache) return this.fetchConfig(network); - const value = await this.configCache.fetch(network.chainId, { context: network }); - if (!value) throw new GaslessError("Gasless config cache returned no value", GaslessErrorCode.ConfigFailed); - return value; - } - async fetchConfig(network) { - try { - return mapGaslessConfig(await this.getClient(network).getJson("/v2/gasless/config")); - } catch (error) { - log.error("Failed to fetch gasless config", { - error, - chainId: network.chainId - }); - throw mapTonApiGaslessError(error, GaslessErrorCode.ConfigFailed, "Failed to fetch gasless config"); - } - } - async getQuote(params) { - if (!params.feeAsset) throw new GaslessError("TonAPI gasless requires `feeAsset` (jetton master). Free / sponsored modes are not supported by this provider.", GaslessErrorCode.UnsupportedOperation, { network: params.network.chainId }); - const masterId = import_dist$1.Address.parse(params.feeAsset).toRawString(); - const body = buildGaslessQuoteRequest(params); - try { - const http = this.getClient(params.network); - return mapGaslessQuote(await CallForSuccess(() => http.postJson(`/v2/gasless/estimate/${masterId}`, body), this.quoteRetries + 1, this.quoteRetryDelayMs, isTransientError), params.network); - } catch (error) { - log.error("Failed to quote gasless transaction", { - error, - params - }); - throw mapTonApiGaslessError(error, GaslessErrorCode.QuoteFailed, "Failed to quote gasless transaction"); - } - } - async sendTransaction(params) { - const body = buildGaslessSendRequest(params); - const http = this.getClient(params.network); - try { - return { - ...mapGaslessSend(await CallForSuccess(() => http.postJson("/v2/gasless/send", body), this.sendRetries + 1, this.sendRetryDelayMs, isTransientError)), - internalBoc: params.internalBoc - }; - } catch (error) { - log.error("Failed to send gasless transaction", { - error, - chainId: params.network.chainId - }); - throw mapTonApiGaslessError(error, GaslessErrorCode.SendFailed, "Failed to send gasless transaction"); - } - } - getClient(network) { - const chainId = network.chainId; - const perChain = this.chainConfig[chainId]; - if (!perChain) throw new GaslessError(`TonApi gasless not configured for chain ${chainId}`, GaslessErrorCode.UnsupportedOperation, { - chainId, - configured: Object.keys(this.chainConfig) - }); - if (!this.clients[chainId]) this.clients[chainId] = new ApiClientTonApi({ - network, - endpoint: perChain.endpoint, - apiKey: perChain.apiKey - }); - return this.clients[chainId]; - } -}; -//#endregion -//#region src/api/gasless.ts -async function getGasless() { - const instance = await getKit(); - if (!instance.gasless) throw new Error("Gasless is not configured"); - return instance.gasless; -} -async function createTonApiGaslessProvider(args) { - const instance = await getKit(); - const provider = TonApiGaslessProvider.createFromContext(instance.createFactoryContext(), args?.config ?? {}); - retainWithId(provider.providerId, provider); - return { providerId: provider.providerId }; -} -async function registerGaslessProvider(args) { - (await getGasless()).registerProvider(get(args.providerId)); -} -async function setDefaultGaslessProvider(args) { - (await getGasless()).setDefaultProvider(args.providerId); -} -async function getRegisteredGaslessProviders() { - return { providerIds: (await getGasless()).getProviders().map((provider) => provider.providerId) }; -} -async function hasGaslessProvider(args) { - return { result: (await getGasless()).hasProvider(args.providerId) }; -} -async function getGaslessMetadata(args) { - return (await getGasless()).getMetadata(args.providerId); -} -async function getGaslessConfig(args) { - return (await getGasless()).getConfig(args.network, args.providerId); -} -async function getGaslessQuote(args) { - return (await getGasless()).getQuote(args.params, args.providerId); -} -async function gaslessSendTransaction(args) { - return (await getGasless()).sendTransaction(args.params, args.providerId); -} //#endregion //#region src/api/walletClient.ts async function walletClientSendBoc(args) { @@ -46130,8 +45800,6 @@ var api = { getWallet: getWalletById, getWalletAddress, getWalletNetwork, - getWalletPublicKey, - getSignedSignMessage, removeWallet, getBalance, getRecentTransactions, @@ -46204,15 +45872,6 @@ var api = { getSwapQuote, buildSwapTransaction, registerKotlinSwapProvider, - createTonApiGaslessProvider, - registerGaslessProvider, - setDefaultGaslessProvider, - getRegisteredGaslessProviders, - hasGaslessProvider, - getGaslessMetadata, - getGaslessConfig, - getGaslessQuote, - gaslessSendTransaction, walletClientSendBoc, walletClientRunGetMethod, walletClientGetBalance, From 4611ffea7b72445b37eecefb09a14be2e89cb65a Mon Sep 17 00:00:00 2001 From: Dmitrii Nikulin Date: Mon, 15 Jun 2026 12:25:22 +0300 Subject: [PATCH 4/9] chore: regen models --- .../api/generated/TONConnectionApprovalProof.kt | 3 +-- .../api/generated/TONConnectionRequestEvent.kt | 2 +- .../api/generated/TONEmulationMessageContent.kt | 2 +- .../walletkit/api/generated/TONGaslessConfig.kt | 4 ++-- .../api/generated/TONGaslessProviderMetadata.kt | 6 +++--- .../TONGaslessProviderMetadataOverride.kt | 6 +++--- .../ton/walletkit/api/generated/TONGaslessQuote.kt | 10 +++++----- .../api/generated/TONGaslessQuoteParams.kt | 10 +++++----- .../api/generated/TONGaslessSendParams.kt | 8 ++++---- .../api/generated/TONGaslessSendResponse.kt | 14 +++++++------- .../api/generated/TONGaslessSupportedAsset.kt | 2 +- .../api/generated/TONJettonTransferItem.kt | 5 ++--- .../api/generated/TONJettonsTransferRequest.kt | 2 +- .../generated/TONNFTRawTransferRequestMessage.kt | 5 ++--- .../walletkit/api/generated/TONNftTransferItem.kt | 5 ++--- .../ton/walletkit/api/generated/TONProofMessage.kt | 2 +- .../TONSendTransactionApprovalResponse.kt | 3 +-- .../api/generated/TONSendTransactionResponse.kt | 4 ++-- .../walletkit/api/generated/TONSignDataBinary.kt | 3 +-- .../ton/walletkit/api/generated/TONSignDataCell.kt | 3 +-- .../api/generated/TONSignDataPreviewBinary.kt | 3 +-- .../api/generated/TONSignDataPreviewCell.kt | 2 +- .../generated/TONSignMessageApprovalResponse.kt | 3 +-- .../ton/walletkit/api/generated/TONSwapParams.kt | 4 ++-- .../walletkit/api/generated/TONSwapQuoteParams.kt | 4 ++-- .../api/generated/TONTonApiGaslessChainConfig.kt | 4 ++-- .../generated/TONTonApiGaslessProviderConfig.kt | 14 +++++++------- .../walletkit/api/generated/TONTonTransferItem.kt | 5 ++--- .../api/generated/TONTransactionMessageContent.kt | 2 +- .../api/generated/TONTransactionRequestMessage.kt | 5 ++--- .../walletkit/api/generated/TONTransferRequest.kt | 5 ++--- 31 files changed, 69 insertions(+), 81 deletions(-) diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONConnectionApprovalProof.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONConnectionApprovalProof.kt index 265a4c05..932e0772 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONConnectionApprovalProof.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONConnectionApprovalProof.kt @@ -29,7 +29,6 @@ package io.ton.walletkit.api.generated import io.ton.walletkit.model.TONBase64 -import kotlinx.serialization.Contextual import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -44,7 +43,7 @@ import kotlinx.serialization.Serializable @Serializable data class TONConnectionApprovalProof( - @Contextual @SerialName(value = "signature") + @SerialName(value = "signature") var signature: io.ton.walletkit.model.TONBase64, @SerialName(value = "timestamp") diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONConnectionRequestEvent.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONConnectionRequestEvent.kt index bcc5d440..e9d15451 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONConnectionRequestEvent.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONConnectionRequestEvent.kt @@ -67,7 +67,7 @@ data class TONConnectionRequestEvent( var preview: TONConnectionRequestEventPreview, @SerialName(value = "from") - val from: kotlin.String? = null, + var from: kotlin.String? = null, @SerialName(value = "walletAddress") var walletAddress: io.ton.walletkit.model.TONUserFriendlyAddress? = null, diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONEmulationMessageContent.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONEmulationMessageContent.kt index 4224ef63..637478d4 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONEmulationMessageContent.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONEmulationMessageContent.kt @@ -46,7 +46,7 @@ data class TONEmulationMessageContent( @Contextual @SerialName(value = "hash") var hash: io.ton.walletkit.model.TONHex? = null, - @Contextual @SerialName(value = "body") + @SerialName(value = "body") var body: io.ton.walletkit.model.TONBase64? = null, /* Structured decoded representation of the message body, if available */ diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessConfig.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessConfig.kt index 2fd03de5..f4c354f5 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessConfig.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessConfig.kt @@ -42,11 +42,11 @@ import kotlinx.serialization.Serializable data class TONGaslessConfig( @SerialName(value = "relayAddress") - val relayAddress: io.ton.walletkit.model.TONUserFriendlyAddress, + var relayAddress: io.ton.walletkit.model.TONUserFriendlyAddress, /* Assets the relayer accepts as fee payment. */ @SerialName(value = "supportedAssets") - val supportedAssets: kotlin.collections.List, + var supportedAssets: kotlin.collections.List, ) { diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessProviderMetadata.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessProviderMetadata.kt index 0977f84f..5d74180c 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessProviderMetadata.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessProviderMetadata.kt @@ -42,13 +42,13 @@ import kotlinx.serialization.Serializable data class TONGaslessProviderMetadata( @SerialName(value = "name") - val name: kotlin.String, + var name: kotlin.String, @SerialName(value = "logo") - val logo: kotlin.String? = null, + var logo: kotlin.String? = null, @SerialName(value = "url") - val url: kotlin.String? = null, + var url: kotlin.String? = null, ) { diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessProviderMetadataOverride.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessProviderMetadataOverride.kt index e429a3ed..6d4f3c14 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessProviderMetadataOverride.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessProviderMetadataOverride.kt @@ -42,13 +42,13 @@ import kotlinx.serialization.Serializable data class TONGaslessProviderMetadataOverride( @SerialName(value = "name") - val name: kotlin.String? = null, + var name: kotlin.String? = null, @SerialName(value = "logo") - val logo: kotlin.String? = null, + var logo: kotlin.String? = null, @SerialName(value = "url") - val url: kotlin.String? = null, + var url: kotlin.String? = null, ) { diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessQuote.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessQuote.kt index 3b8f6a0d..35560a69 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessQuote.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessQuote.kt @@ -45,21 +45,21 @@ import kotlinx.serialization.Serializable data class TONGaslessQuote( @SerialName(value = "network") - val network: TONNetwork, + var network: TONNetwork, /* Relayer-wrapped messages ready to be signed */ @SerialName(value = "messages") - val messages: kotlin.collections.List, + var messages: kotlin.collections.List, @SerialName(value = "fee") - val fee: kotlin.String, + var fee: kotlin.String, /* Unix timestamp after which the bundle becomes invalid for relay */ @SerialName(value = "validUntil") - val validUntil: kotlin.Double, + var validUntil: kotlin.Double, @SerialName(value = "from") - val from: io.ton.walletkit.model.TONUserFriendlyAddress, + var from: io.ton.walletkit.model.TONUserFriendlyAddress, ) { diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessQuoteParams.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessQuoteParams.kt index 9e11e049..f24123e3 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessQuoteParams.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessQuoteParams.kt @@ -46,20 +46,20 @@ import kotlinx.serialization.Serializable data class TONGaslessQuoteParams( @SerialName(value = "network") - val network: TONNetwork, + var network: TONNetwork, @SerialName(value = "walletAddress") - val walletAddress: io.ton.walletkit.model.TONUserFriendlyAddress, + var walletAddress: io.ton.walletkit.model.TONUserFriendlyAddress, @Contextual @SerialName(value = "walletPublicKey") - val walletPublicKey: io.ton.walletkit.model.TONHex, + var walletPublicKey: io.ton.walletkit.model.TONHex, /* Messages that the caller wants to include in the transaction */ @SerialName(value = "messages") - val messages: kotlin.collections.List, + var messages: kotlin.collections.List, @SerialName(value = "feeAsset") - val feeAsset: io.ton.walletkit.model.TONUserFriendlyAddress? = null, + var feeAsset: io.ton.walletkit.model.TONUserFriendlyAddress? = null, ) { diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessSendParams.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessSendParams.kt index 2599e623..754dd83c 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessSendParams.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessSendParams.kt @@ -44,13 +44,13 @@ import kotlinx.serialization.Serializable data class TONGaslessSendParams( @SerialName(value = "network") - val network: TONNetwork, + var network: TONNetwork, @Contextual @SerialName(value = "walletPublicKey") - val walletPublicKey: io.ton.walletkit.model.TONHex, + var walletPublicKey: io.ton.walletkit.model.TONHex, - @Contextual @SerialName(value = "internalBoc") - val internalBoc: io.ton.walletkit.model.TONBase64, + @SerialName(value = "internalBoc") + var internalBoc: io.ton.walletkit.model.TONBase64, ) { diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessSendResponse.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessSendResponse.kt index b6a40dab..a2535082 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessSendResponse.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessSendResponse.kt @@ -44,17 +44,17 @@ import kotlinx.serialization.Serializable @Serializable data class TONGaslessSendResponse( - @Contextual @SerialName(value = "boc") - val boc: io.ton.walletkit.model.TONBase64, + @SerialName(value = "boc") + var boc: io.ton.walletkit.model.TONBase64, - @Contextual @SerialName(value = "normalizedBoc") - val normalizedBoc: io.ton.walletkit.model.TONBase64, + @SerialName(value = "normalizedBoc") + var normalizedBoc: io.ton.walletkit.model.TONBase64, @Contextual @SerialName(value = "normalizedHash") - val normalizedHash: io.ton.walletkit.model.TONHex, + var normalizedHash: io.ton.walletkit.model.TONHex, - @Contextual @SerialName(value = "internalBoc") - val internalBoc: io.ton.walletkit.model.TONBase64, + @SerialName(value = "internalBoc") + var internalBoc: io.ton.walletkit.model.TONBase64, ) { diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessSupportedAsset.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessSupportedAsset.kt index be5e93ce..120db4c2 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessSupportedAsset.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessSupportedAsset.kt @@ -41,7 +41,7 @@ import kotlinx.serialization.Serializable data class TONGaslessSupportedAsset( @SerialName(value = "address") - val address: io.ton.walletkit.model.TONUserFriendlyAddress, + var address: io.ton.walletkit.model.TONUserFriendlyAddress, ) { diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONJettonTransferItem.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONJettonTransferItem.kt index e9b2e427..9d3d9611 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONJettonTransferItem.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONJettonTransferItem.kt @@ -29,7 +29,6 @@ package io.ton.walletkit.api.generated import io.ton.walletkit.model.TONBase64 -import kotlinx.serialization.Contextual import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -67,13 +66,13 @@ data class TONJettonTransferItem( @SerialName(value = "responseDestination") var responseDestination: kotlin.String? = null, - @Contextual @SerialName(value = "customPayload") + @SerialName(value = "customPayload") var customPayload: io.ton.walletkit.model.TONBase64? = null, @SerialName(value = "forwardAmount") var forwardAmount: kotlin.String? = null, - @Contextual @SerialName(value = "forwardPayload") + @SerialName(value = "forwardPayload") var forwardPayload: io.ton.walletkit.model.TONBase64? = null, @SerialName("type") val type: kotlin.String = "jetton", diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONJettonsTransferRequest.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONJettonsTransferRequest.kt index eb685c0a..1be0d29c 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONJettonsTransferRequest.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONJettonsTransferRequest.kt @@ -54,7 +54,7 @@ data class TONJettonsTransferRequest( var recipientAddress: io.ton.walletkit.model.TONUserFriendlyAddress, @SerialName(value = "responseDestination") - val responseDestination: io.ton.walletkit.model.TONUserFriendlyAddress? = null, + var responseDestination: io.ton.walletkit.model.TONUserFriendlyAddress? = null, /* Human-readable comment attached to the transfer */ @SerialName(value = "comment") diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONNFTRawTransferRequestMessage.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONNFTRawTransferRequestMessage.kt index 12f81c5f..4e516913 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONNFTRawTransferRequestMessage.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONNFTRawTransferRequestMessage.kt @@ -30,7 +30,6 @@ package io.ton.walletkit.api.generated import io.ton.walletkit.model.TONBase64 import io.ton.walletkit.model.TONUserFriendlyAddress -import kotlinx.serialization.Contextual import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -59,10 +58,10 @@ data class TONNFTRawTransferRequestMessage( @SerialName(value = "responseDestination") var responseDestination: io.ton.walletkit.model.TONUserFriendlyAddress? = null, - @Contextual @SerialName(value = "customPayload") + @SerialName(value = "customPayload") var customPayload: io.ton.walletkit.model.TONBase64? = null, - @Contextual @SerialName(value = "forwardPayload") + @SerialName(value = "forwardPayload") var forwardPayload: io.ton.walletkit.model.TONBase64? = null, ) { diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONNftTransferItem.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONNftTransferItem.kt index 54e4d021..420a3e9c 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONNftTransferItem.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONNftTransferItem.kt @@ -29,7 +29,6 @@ package io.ton.walletkit.api.generated import io.ton.walletkit.model.TONBase64 -import kotlinx.serialization.Contextual import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -63,13 +62,13 @@ data class TONNftTransferItem( @SerialName(value = "responseDestination") var responseDestination: kotlin.String? = null, - @Contextual @SerialName(value = "customPayload") + @SerialName(value = "customPayload") var customPayload: io.ton.walletkit.model.TONBase64? = null, @SerialName(value = "forwardAmount") var forwardAmount: kotlin.String? = null, - @Contextual @SerialName(value = "forwardPayload") + @SerialName(value = "forwardPayload") var forwardPayload: io.ton.walletkit.model.TONBase64? = null, @SerialName("type") val type: kotlin.String = "nft", diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONProofMessage.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONProofMessage.kt index 1393e8e5..0aa357a9 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONProofMessage.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONProofMessage.kt @@ -65,7 +65,7 @@ data class TONProofMessage( @SerialName(value = "payload") var payload: kotlin.String, - @Contextual @SerialName(value = "stateInit") + @SerialName(value = "stateInit") var stateInit: io.ton.walletkit.model.TONBase64, @Contextual @SerialName(value = "signature") diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSendTransactionApprovalResponse.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSendTransactionApprovalResponse.kt index c8524669..388153f7 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSendTransactionApprovalResponse.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSendTransactionApprovalResponse.kt @@ -29,7 +29,6 @@ package io.ton.walletkit.api.generated import io.ton.walletkit.model.TONBase64 -import kotlinx.serialization.Contextual import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -41,7 +40,7 @@ import kotlinx.serialization.Serializable @Serializable data class TONSendTransactionApprovalResponse( - @Contextual @SerialName(value = "signedBoc") + @SerialName(value = "signedBoc") var signedBoc: io.ton.walletkit.model.TONBase64, ) { diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSendTransactionResponse.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSendTransactionResponse.kt index 5272bf89..6e11145d 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSendTransactionResponse.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSendTransactionResponse.kt @@ -43,10 +43,10 @@ import kotlinx.serialization.Serializable @Serializable data class TONSendTransactionResponse( - @Contextual @SerialName(value = "boc") + @SerialName(value = "boc") var boc: io.ton.walletkit.model.TONBase64, - @Contextual @SerialName(value = "normalizedBoc") + @SerialName(value = "normalizedBoc") var normalizedBoc: io.ton.walletkit.model.TONBase64, @Contextual @SerialName(value = "normalizedHash") diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSignDataBinary.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSignDataBinary.kt index fb8f2c81..a19c6f72 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSignDataBinary.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSignDataBinary.kt @@ -29,7 +29,6 @@ package io.ton.walletkit.api.generated import io.ton.walletkit.model.TONBase64 -import kotlinx.serialization.Contextual import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -41,7 +40,7 @@ import kotlinx.serialization.Serializable @Serializable data class TONSignDataBinary( - @Contextual @SerialName(value = "content") + @SerialName(value = "content") var content: io.ton.walletkit.model.TONBase64, ) { diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSignDataCell.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSignDataCell.kt index 1d837b5f..a90ce968 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSignDataCell.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSignDataCell.kt @@ -29,7 +29,6 @@ package io.ton.walletkit.api.generated import io.ton.walletkit.model.TONBase64 -import kotlinx.serialization.Contextual import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -46,7 +45,7 @@ data class TONSignDataCell( @SerialName(value = "schema") var schema: kotlin.String, - @Contextual @SerialName(value = "content") + @SerialName(value = "content") var content: io.ton.walletkit.model.TONBase64, ) { diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSignDataPreviewBinary.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSignDataPreviewBinary.kt index 7440a895..fc922837 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSignDataPreviewBinary.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSignDataPreviewBinary.kt @@ -29,7 +29,6 @@ package io.ton.walletkit.api.generated import io.ton.walletkit.model.TONBase64 -import kotlinx.serialization.Contextual import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -41,7 +40,7 @@ import kotlinx.serialization.Serializable @Serializable data class TONSignDataPreviewBinary( - @Contextual @SerialName(value = "content") + @SerialName(value = "content") var content: io.ton.walletkit.model.TONBase64, ) { diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSignDataPreviewCell.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSignDataPreviewCell.kt index 29d6c00d..ce1b35e4 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSignDataPreviewCell.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSignDataPreviewCell.kt @@ -47,7 +47,7 @@ data class TONSignDataPreviewCell( @SerialName(value = "schema") var schema: kotlin.String, - @Contextual @SerialName(value = "content") + @SerialName(value = "content") var content: io.ton.walletkit.model.TONBase64, @Contextual @SerialName(value = "parsed") diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSignMessageApprovalResponse.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSignMessageApprovalResponse.kt index 44a1b8b1..f075715d 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSignMessageApprovalResponse.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSignMessageApprovalResponse.kt @@ -29,7 +29,6 @@ package io.ton.walletkit.api.generated import io.ton.walletkit.model.TONBase64 -import kotlinx.serialization.Contextual import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -41,7 +40,7 @@ import kotlinx.serialization.Serializable @Serializable data class TONSignMessageApprovalResponse( - @Contextual @SerialName(value = "internalBoc") + @SerialName(value = "internalBoc") var internalBoc: io.ton.walletkit.model.TONBase64, ) { diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSwapParams.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSwapParams.kt index 51b08a6c..2600cbe4 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSwapParams.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSwapParams.kt @@ -51,9 +51,9 @@ data class TONSwapParams( @SerialName("destinationAddress") var destinationAddress: io.ton.walletkit.model.TONUserFriendlyAddress? = null, @SerialName("slippageBps") - val slippageBps: kotlin.Int? = null, + var slippageBps: kotlin.Int? = null, @SerialName("deadline") - val deadline: kotlin.Int? = null, + var deadline: kotlin.Int? = null, @SerialName("providerOptions") var providerOptions: TProviderOptions? = null, ) { diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSwapQuoteParams.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSwapQuoteParams.kt index bce4aaf5..6d020d4e 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSwapQuoteParams.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONSwapQuoteParams.kt @@ -54,9 +54,9 @@ data class TONSwapQuoteParams( @SerialName("network") var network: TONNetwork, @SerialName("slippageBps") - val slippageBps: kotlin.Int? = null, + var slippageBps: kotlin.Int? = null, @SerialName("maxOutgoingMessages") - val maxOutgoingMessages: kotlin.Int? = null, + var maxOutgoingMessages: kotlin.Int? = null, @SerialName("providerOptions") var providerOptions: TProviderOptions? = null, @SerialName("isReverseSwap") diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTonApiGaslessChainConfig.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTonApiGaslessChainConfig.kt index e67d0f89..11a6f12c 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTonApiGaslessChainConfig.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTonApiGaslessChainConfig.kt @@ -42,11 +42,11 @@ data class TONTonApiGaslessChainConfig( /* TonAPI REST endpoint override for this chain (defaults to TonAPI's per-network host). */ @SerialName(value = "endpoint") - val endpoint: kotlin.String? = null, + var endpoint: kotlin.String? = null, /* Bearer token used for this chain's TonAPI calls. */ @SerialName(value = "apiKey") - val apiKey: kotlin.String? = null, + var apiKey: kotlin.String? = null, ) { diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTonApiGaslessProviderConfig.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTonApiGaslessProviderConfig.kt index 837cc0be..fcca21b4 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTonApiGaslessProviderConfig.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTonApiGaslessProviderConfig.kt @@ -48,31 +48,31 @@ data class TONTonApiGaslessProviderConfig( /* Per-chain settings keyed by `Network#chainId`. */ @Contextual @SerialName(value = "chains") - val chains: kotlin.collections.Map? = null, + var chains: kotlin.collections.Map? = null, /* Provider id. Defaults to `tonapi`. */ @SerialName(value = "providerId") - val providerId: kotlin.String? = null, + var providerId: kotlin.String? = null, /* Number of send retries on transient errors. Defaults to 5. */ @SerialName(value = "sendRetries") - val sendRetries: kotlin.Int? = null, + var sendRetries: kotlin.Int? = null, /* Delay between send retries in ms. Defaults to 1000. */ @SerialName(value = "sendRetryDelayMs") - val sendRetryDelayMs: kotlin.Int? = null, + var sendRetryDelayMs: kotlin.Int? = null, /* Number of quote retries on transient errors (5xx / network). Defaults to 5. */ @SerialName(value = "quoteRetries") - val quoteRetries: kotlin.Int? = null, + var quoteRetries: kotlin.Int? = null, /* Fixed delay between quote retries in ms. Defaults to 1000. */ @SerialName(value = "quoteRetryDelayMs") - val quoteRetryDelayMs: kotlin.Int? = null, + var quoteRetryDelayMs: kotlin.Int? = null, /* TTL for the in-memory `/v2/gasless/config` cache (ms). Defaults to 5 minutes. Set to `0` to disable caching. */ @SerialName(value = "configCacheTtlMs") - val configCacheTtlMs: kotlin.Int? = null, + var configCacheTtlMs: kotlin.Int? = null, ) { diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTonTransferItem.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTonTransferItem.kt index 20c95cd8..e769785e 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTonTransferItem.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTonTransferItem.kt @@ -29,7 +29,6 @@ package io.ton.walletkit.api.generated import io.ton.walletkit.model.TONBase64 -import kotlinx.serialization.Contextual import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -51,10 +50,10 @@ data class TONTonTransferItem( @SerialName(value = "amount") var amount: kotlin.String, - @Contextual @SerialName(value = "payload") + @SerialName(value = "payload") var payload: io.ton.walletkit.model.TONBase64? = null, - @Contextual @SerialName(value = "stateInit") + @SerialName(value = "stateInit") var stateInit: io.ton.walletkit.model.TONBase64? = null, /* Map of extra currency IDs to their amounts. Extra currencies are additional tokens that can be attached to TON messages. */ diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTransactionMessageContent.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTransactionMessageContent.kt index 24528e81..b1a76c8a 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTransactionMessageContent.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTransactionMessageContent.kt @@ -47,7 +47,7 @@ data class TONTransactionMessageContent( @SerialName(value = "hash") var hash: kotlin.String? = null, - @Contextual @SerialName(value = "body") + @SerialName(value = "body") var body: io.ton.walletkit.model.TONBase64? = null, /* The decoded metadata from the initial state body */ diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTransactionRequestMessage.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTransactionRequestMessage.kt index d259b301..a39ec6ef 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTransactionRequestMessage.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTransactionRequestMessage.kt @@ -29,7 +29,6 @@ package io.ton.walletkit.api.generated import io.ton.walletkit.model.TONBase64 -import kotlinx.serialization.Contextual import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -60,10 +59,10 @@ data class TONTransactionRequestMessage( @SerialName(value = "extraCurrency") var extraCurrency: kotlin.collections.Map? = null, - @Contextual @SerialName(value = "stateInit") + @SerialName(value = "stateInit") var stateInit: io.ton.walletkit.model.TONBase64? = null, - @Contextual @SerialName(value = "payload") + @SerialName(value = "payload") var payload: io.ton.walletkit.model.TONBase64? = null, ) { diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTransferRequest.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTransferRequest.kt index 00e9b3c7..beade7e8 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTransferRequest.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTransferRequest.kt @@ -30,7 +30,6 @@ package io.ton.walletkit.api.generated import io.ton.walletkit.model.TONBase64 import io.ton.walletkit.model.TONUserFriendlyAddress -import kotlinx.serialization.Contextual import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -61,10 +60,10 @@ data class TONTransferRequest( @SerialName(value = "extraCurrency") var extraCurrency: kotlin.collections.Map? = null, - @Contextual @SerialName(value = "stateInit") + @SerialName(value = "stateInit") var stateInit: io.ton.walletkit.model.TONBase64? = null, - @Contextual @SerialName(value = "payload") + @SerialName(value = "payload") var payload: io.ton.walletkit.model.TONBase64? = null, /* Human-readable text comment attached to the transfer */ From c0f5aaaee29349c371a7a60f4fdbd6dad4bd40fd Mon Sep 17 00:00:00 2001 From: Dmitrii Nikulin Date: Tue, 16 Jun 2026 10:51:21 +0300 Subject: [PATCH 5/9] chore: fix comments --- .../viewmodel/WalletOperationsViewModel.kt | 4 +- .../main/java/io/ton/walletkit/ITONWallet.kt | 10 +- .../java/io/ton/walletkit/ITONWalletKit.kt | 4 +- .../java/io/ton/walletkit/TONProviderType.kt | 3 +- .../api/generated/TONAccountState.kt | 4 +- .../api/generated/TONGaslessConfig.kt | 2 +- .../api/generated/TONStakingProviderInfo.kt | 4 +- .../generated/TONStakingProviderMetadata.kt | 4 +- .../api/generated/TONStakingQuoteParams.kt | 2 +- .../api/generated/TONStakingTokenInfo.kt | 4 +- .../walletkit/api/generated/TONTokenInfo.kt | 6 +- .../api/generated/TONTransferRequest.kt | 2 +- .../walletkit/gasless/ITONGaslessManager.kt | 39 +- .../walletkit/gasless/ITONGaslessProvider.kt | 57 + .../gasless/TONGaslessProviderIdentifier.kt | 37 + .../TONApiGaslessProviderIdentifier.kt} | 17 +- .../ton/walletkit/model/TONWalletAdapter.kt | 2 +- .../walletkit/walletkit-android-bridge.mjs | 1305 +++++++++++------ .../java/io/ton/walletkit/core/TONWallet.kt | 46 +- .../io/ton/walletkit/core/TONWalletKit.kt | 10 +- .../ton/walletkit/engine/WalletKitEngine.kt | 26 + .../engine/WebViewWalletKitEngine.kt | 26 + .../engine/adapter/BridgeWalletAdapter.kt | 2 +- .../engine/operations/WalletOperations.kt | 47 + .../operations/requests/WalletRequests.kt | 21 + .../gasless/BuiltInGaslessProvider.kt | 56 + .../walletkit/gasless/TONGaslessManager.kt | 39 +- .../constants/BridgeMethodConstants.kt | 12 + .../ton/walletkit/CustomWalletAdapterTest.kt | 4 +- .../mockbridge/infra/MockScenario.kt | 2 +- 30 files changed, 1267 insertions(+), 530 deletions(-) create mode 100644 TONWalletKit-Android/api/src/main/java/io/ton/walletkit/gasless/ITONGaslessProvider.kt create mode 100644 TONWalletKit-Android/api/src/main/java/io/ton/walletkit/gasless/TONGaslessProviderIdentifier.kt rename TONWalletKit-Android/api/src/main/java/io/ton/walletkit/gasless/{TONGaslessProvider.kt => tonapi/TONApiGaslessProviderIdentifier.kt} (71%) create mode 100644 TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/gasless/BuiltInGaslessProvider.kt diff --git a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/WalletOperationsViewModel.kt b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/WalletOperationsViewModel.kt index 3d1a48a4..883671a8 100644 --- a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/WalletOperationsViewModel.kt +++ b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/WalletOperationsViewModel.kt @@ -148,9 +148,9 @@ class WalletOperationsViewModel( private suspend fun sendUsdtGasless(wallet: ITONWallet, recipient: String, amount: String) { val gaslessManager = walletKit().gasless() val provider = walletKit().tonApiGaslessProvider() - if (!gaslessManager.hasProvider(provider)) { + if (!gaslessManager.hasProvider(provider.identifier)) { gaslessManager.registerProvider(provider) - gaslessManager.setDefaultProvider(provider) + gaslessManager.setDefaultProvider(provider.identifier) } val config = gaslessManager.getConfig(network = wallet.network) diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/ITONWallet.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/ITONWallet.kt index 839ec24d..6c8ab019 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/ITONWallet.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/ITONWallet.kt @@ -25,13 +25,16 @@ import io.ton.walletkit.api.generated.* import io.ton.walletkit.client.TONAPIClient import io.ton.walletkit.model.TONBalance import io.ton.walletkit.model.TONBase64 -import io.ton.walletkit.model.TONHex import io.ton.walletkit.model.TONUserFriendlyAddress +import io.ton.walletkit.model.TONWalletAdapter /** * TON wallet instance for transaction management and dApp interactions. + * + * Inherits the account-level adapter surface ([TONWalletAdapter]) — `publicKey()`, `network()`, + * `address(testnet)`, `stateInit()`, and the signing primitives. */ -interface ITONWallet { +interface ITONWallet : TONWalletAdapter { /** * Unique wallet identifier. */ @@ -53,9 +56,6 @@ interface ITONWallet { */ suspend fun balance(): TONBalance - /** Get this wallet's public key (hex). */ - suspend fun publicKey(): TONHex - /** Sign a set of messages as a sign-message bundle, returning the signed internal BoC (used by gasless relay flows). */ suspend fun signMessage( messages: List, diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/ITONWalletKit.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/ITONWalletKit.kt index b0a80e00..488d608b 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/ITONWalletKit.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/ITONWalletKit.kt @@ -35,7 +35,7 @@ import io.ton.walletkit.api.generated.TONTonCenterStreamingProviderConfig import io.ton.walletkit.api.generated.TONTransactionRequest import io.ton.walletkit.config.TONWalletKitConfiguration import io.ton.walletkit.gasless.ITONGaslessManager -import io.ton.walletkit.gasless.TONGaslessProvider +import io.ton.walletkit.gasless.tonapi.TONApiGaslessProvider import io.ton.walletkit.internal.TONWalletKitFactory import io.ton.walletkit.listener.TONBridgeEventsHandler import io.ton.walletkit.model.KeyPair @@ -209,7 +209,7 @@ interface ITONWalletKit { /** * Create a TonAPI gasless provider. Register the returned handle with [gasless] before quoting. */ - suspend fun tonApiGaslessProvider(config: TONTonApiGaslessProviderConfig? = null): TONGaslessProvider + suspend fun tonApiGaslessProvider(config: TONTonApiGaslessProviderConfig? = null): TONApiGaslessProvider /** Get the gasless manager for registering providers and relaying gasless transactions. */ suspend fun gasless(): ITONGaslessManager diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/TONProviderType.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/TONProviderType.kt index 46cd4b4f..798cbe5a 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/TONProviderType.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/TONProviderType.kt @@ -23,10 +23,11 @@ package io.ton.walletkit /** * Discriminator for the domain a provider belongs to. - * Used to tell swap, staking, and streaming providers apart at runtime. + * Used to tell swap, staking, streaming, and gasless providers apart at runtime. */ enum class TONProviderType { Swap, Staking, Streaming, + Gasless, } diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONAccountState.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONAccountState.kt index 600c325d..84439891 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONAccountState.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONAccountState.kt @@ -39,7 +39,7 @@ import kotlinx.serialization.Serializable * @param address * @param status * @param rawBalance - * @param balance Balance formatted in TON (10^9 nanotons = 1 TON). + * @param balance Balance formatted in GRAM (10^9 nano units = 1 GRAM). * @param extraCurrencies Map of extra currency IDs to their amounts. Extra currencies are additional tokens that can be attached to TON messages. * @param code Base64-encoded contract code BOC. Omitted if the contract is not deployed. * @param `data` Base64-encoded contract data BOC. Omitted if the contract is not deployed. @@ -58,7 +58,7 @@ data class TONAccountState( @SerialName(value = "rawBalance") var rawBalance: kotlin.String, - /* Balance formatted in TON (10^9 nanotons = 1 TON). */ + /* Balance formatted in GRAM (10^9 nano units = 1 GRAM). */ @SerialName(value = "balance") var balance: kotlin.String, diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessConfig.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessConfig.kt index f4c354f5..1b7a814a 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessConfig.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONGaslessConfig.kt @@ -33,7 +33,7 @@ import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable /** - * Provider-level configuration for a gasless relayer on a given network. Bundles every piece of provider state a consumer needs to drive a gasless transfer end-to-end: - `relayAddress` — where the relayer wants residual TON (e.g. jetton-transfer `responseDestination`) returned to. - `supportedAssets` — what the relayer accepts as fee payment. + * Provider-level configuration for a gasless relayer on a given network. Bundles every piece of provider state a consumer needs to drive a gasless transfer end-to-end: - `relayAddress` — where the relayer wants residual GRAM (e.g. jetton-transfer `responseDestination`) returned to. - `supportedAssets` — what the relayer accepts as fee payment. * * @param relayAddress * @param supportedAssets Assets the relayer accepts as fee payment. diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONStakingProviderInfo.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONStakingProviderInfo.kt index 830b27a6..98837d81 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONStakingProviderInfo.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONStakingProviderInfo.kt @@ -37,7 +37,7 @@ import kotlinx.serialization.Serializable * @param apy Annual Percentage Yield in basis points (100 = 1%) * @param rawInstantUnstakeAvailable * @param instantUnstakeAvailable Amount available for instant unstake - * @param exchangeRate Exchange rate between stakeToken and receiveToken (e.g. 1 TON = 0.95 tsTON). Undefined when there is no receiveToken (direct/custodial staking). + * @param exchangeRate Exchange rate between stakeToken and receiveToken (e.g. 1 GRAM = 0.95 tsTON). Undefined when there is no receiveToken (direct/custodial staking). */ @Serializable data class TONStakingProviderInfo( @@ -53,7 +53,7 @@ data class TONStakingProviderInfo( @SerialName(value = "instantUnstakeAvailable") var instantUnstakeAvailable: kotlin.String? = null, - /* Exchange rate between stakeToken and receiveToken (e.g. 1 TON = 0.95 tsTON). Undefined when there is no receiveToken (direct/custodial staking). */ + /* Exchange rate between stakeToken and receiveToken (e.g. 1 GRAM = 0.95 tsTON). Undefined when there is no receiveToken (direct/custodial staking). */ @SerialName(value = "exchangeRate") var exchangeRate: kotlin.String? = null, diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONStakingProviderMetadata.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONStakingProviderMetadata.kt index 4b7a17d1..1afce44b 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONStakingProviderMetadata.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONStakingProviderMetadata.kt @@ -38,7 +38,7 @@ import kotlinx.serialization.Serializable * * @param name Human-readable provider name (e.g. \"Tonstakers\") * @param supportedUnstakeModes Supported unstake modes for this provider - * @param supportsReversedQuote Whether provider supports reversed quote format (e.g., passing TON instead of tsTON for unstake) + * @param supportsReversedQuote Whether provider supports reversed quote format (e.g., passing GRAM instead of tsTON for unstake) * @param stakeToken * @param receiveToken * @param contractAddress @@ -54,7 +54,7 @@ data class TONStakingProviderMetadata( @SerialName(value = "supportedUnstakeModes") var supportedUnstakeModes: kotlin.collections.List<@Contextual TONUnstakeMode>, - /* Whether provider supports reversed quote format (e.g., passing TON instead of tsTON for unstake) */ + /* Whether provider supports reversed quote format (e.g., passing GRAM instead of tsTON for unstake) */ @SerialName(value = "supportsReversedQuote") var supportsReversedQuote: kotlin.Boolean, diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONStakingQuoteParams.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONStakingQuoteParams.kt index 3cdbf68b..a2b4a325 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONStakingQuoteParams.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONStakingQuoteParams.kt @@ -40,7 +40,7 @@ import kotlinx.serialization.Serializable * @param userAddress * @param network * @param unstakeMode - * @param isReversed If true, for unstake requests the amount is specified in the staking coin (e.g. TON) instead of the Liquid Staking Token (e.g. tsTON). + * @param isReversed If true, for unstake requests the amount is specified in the staking coin (e.g. GRAM) instead of the Liquid Staking Token (e.g. tsTON). * @param providerOptions Provider-specific options */ @Serializable diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONStakingTokenInfo.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONStakingTokenInfo.kt index 24cd304d..1a31044d 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONStakingTokenInfo.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONStakingTokenInfo.kt @@ -36,7 +36,7 @@ import kotlinx.serialization.Serializable * * @param ticker * @param decimals - * @param address 'ton' for native TON, otherwise contract address in friendly format + * @param address 'ton' for native GRAM, otherwise contract address in friendly format */ @Serializable data class TONStakingTokenInfo( @@ -47,7 +47,7 @@ data class TONStakingTokenInfo( @SerialName(value = "decimals") var decimals: kotlin.Int, - /* 'ton' for native TON, otherwise contract address in friendly format */ + /* 'ton' for native GRAM, otherwise contract address in friendly format */ @SerialName(value = "address") var address: kotlin.String, diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTokenInfo.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTokenInfo.kt index e5b2b422..0b4b1781 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTokenInfo.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTokenInfo.kt @@ -32,13 +32,13 @@ import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable /** - * Display information for a token (TON, Jetton, or NFT). + * Display information for a token (GRAM, Jetton, or NFT). * * @param name Display name of the token * @param description Human-readable description of the token * @param image * @param animation - * @param symbol Ticker symbol of the token (e.g., \"TON\", \"USDT\") + * @param symbol Ticker symbol of the token (e.g., \"GRAM\", \"USDT\") */ @Serializable data class TONTokenInfo( @@ -57,7 +57,7 @@ data class TONTokenInfo( @SerialName(value = "animation") var animation: TONTokenAnimation? = null, - /* Ticker symbol of the token (e.g., \"TON\", \"USDT\") */ + /* Ticker symbol of the token (e.g., \"GRAM\", \"USDT\") */ @SerialName(value = "symbol") var symbol: kotlin.String? = null, diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTransferRequest.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTransferRequest.kt index beade7e8..7dc97de8 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTransferRequest.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONTransferRequest.kt @@ -34,7 +34,7 @@ import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable /** - * Request parameters for transferring TON to another address. + * Request parameters for transferring GRAM to another address. * * @param transferAmount * @param recipientAddress diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/gasless/ITONGaslessManager.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/gasless/ITONGaslessManager.kt index 38930705..947077bc 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/gasless/ITONGaslessManager.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/gasless/ITONGaslessManager.kt @@ -36,39 +36,54 @@ import io.ton.walletkit.api.generated.TONNetwork * Gasless lets a wallet submit on-chain transactions without paying TON for gas: a relayer * co-signs and covers the gas, taking a jetton fee in return. The flow is * [getQuote] (sign the returned messages) → [sendTransaction]. + * + * Providers are registered as objects but referenced everywhere else by their + * [TONGaslessProviderIdentifier]. */ interface ITONGaslessManager { - /** Register a provider returned from [io.ton.walletkit.ITONWalletKit.tonApiGaslessProvider]. */ - suspend fun registerProvider(provider: TONGaslessProvider) + /** + * Register a provider. Accepts any [ITONGaslessProvider] — the SDK's built-in provider + * returned from [io.ton.walletkit.ITONWalletKit.tonApiGaslessProvider], or a custom conformer. + */ + suspend fun registerProvider(provider: ITONGaslessProvider) - /** Set the default provider used when no provider is specified. */ - suspend fun setDefaultProvider(provider: TONGaslessProvider) + /** Set the default provider used when no identifier is specified. */ + suspend fun setDefaultProvider(identifier: TONGaslessProviderIdentifier) /** All currently-registered providers. */ - suspend fun providers(): List + suspend fun providers(): List + + /** Returns true if a provider with the given [identifier] is currently registered. */ + suspend fun hasProvider(identifier: TONGaslessProviderIdentifier): Boolean - /** Returns true if [provider] is currently registered. */ - suspend fun hasProvider(provider: TONGaslessProvider): Boolean + /** Returns a handle to the provider with [identifier]. */ + suspend fun provider(identifier: TONGaslessProviderIdentifier): ITONGaslessProvider? - /** Static metadata (display name, logo, url) for [provider], or the default provider. */ - suspend fun getMetadata(provider: TONGaslessProvider? = null): TONGaslessProviderMetadata + /** Static metadata (display name, logo, url) for [identifier], or the default provider. */ + suspend fun getMetadata(identifier: TONGaslessProviderIdentifier? = null): TONGaslessProviderMetadata /** * Fetch the relayer's config — the relay address and the assets it accepts as fee payment. * [network] defaults to the provider's first supported network. */ - suspend fun getConfig(network: TONNetwork? = null, provider: TONGaslessProvider? = null): TONGaslessConfig + suspend fun getConfig( + network: TONNetwork? = null, + identifier: TONGaslessProviderIdentifier? = null, + ): TONGaslessConfig /** * Quote fees and obtain relayer-wrapped messages for signing. Pass the returned * [TONGaslessQuote.messages] to the wallet's sign-message flow to obtain a signed internal BoC, * then submit it via [sendTransaction]. */ - suspend fun getQuote(params: TONGaslessQuoteParams, provider: TONGaslessProvider? = null): TONGaslessQuote + suspend fun getQuote( + params: TONGaslessQuoteParams, + identifier: TONGaslessProviderIdentifier? = null, + ): TONGaslessQuote /** Submit a signed transaction BoC to the relayer for on-chain execution. */ suspend fun sendTransaction( params: TONGaslessSendParams, - provider: TONGaslessProvider? = null, + identifier: TONGaslessProviderIdentifier? = null, ): TONGaslessSendResponse } diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/gasless/ITONGaslessProvider.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/gasless/ITONGaslessProvider.kt new file mode 100644 index 00000000..2295ec56 --- /dev/null +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/gasless/ITONGaslessProvider.kt @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2025 TonTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package io.ton.walletkit.gasless + +import io.ton.walletkit.TONProviderType +import io.ton.walletkit.api.generated.TONGaslessConfig +import io.ton.walletkit.api.generated.TONGaslessProviderMetadata +import io.ton.walletkit.api.generated.TONGaslessQuote +import io.ton.walletkit.api.generated.TONGaslessQuoteParams +import io.ton.walletkit.api.generated.TONGaslessSendParams +import io.ton.walletkit.api.generated.TONGaslessSendResponse +import io.ton.walletkit.api.generated.TONNetwork + +/** + * Contract every gasless provider must satisfy. + * + * The built-in TonAPI provider (returned from [io.ton.walletkit.ITONWalletKit.tonApiGaslessProvider]) + * implements this interface. + */ +interface ITONGaslessProvider { + /** Always [TONProviderType.Gasless]. Used to discriminate at runtime across domains. */ + val type: TONProviderType get() = TONProviderType.Gasless + + /** Typed provider identifier. */ + val identifier: TONGaslessProviderIdentifier + + /** Static descriptive metadata (name, logo, url). */ + suspend fun metadata(): TONGaslessProviderMetadata + + /** Relayer config — the relay address and accepted fee assets. [network] defaults to the provider's first supported network. */ + suspend fun getConfig(network: TONNetwork? = null): TONGaslessConfig + + /** Quote fees and obtain relayer-wrapped messages for signing. */ + suspend fun getQuote(params: TONGaslessQuoteParams): TONGaslessQuote + + /** Submit a signed transaction BoC to the relayer for on-chain execution. */ + suspend fun sendTransaction(params: TONGaslessSendParams): TONGaslessSendResponse +} diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/gasless/TONGaslessProviderIdentifier.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/gasless/TONGaslessProviderIdentifier.kt new file mode 100644 index 00000000..09194f54 --- /dev/null +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/gasless/TONGaslessProviderIdentifier.kt @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2025 TonTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package io.ton.walletkit.gasless + +/** + * Identifies a gasless provider by its [name] (the provider id used by the JS bridge). + * + * The gasless manager references providers by identifier rather than by the whole provider object. + * Built-in providers expose a concrete identifier (e.g. + * [io.ton.walletkit.gasless.tonapi.TONApiGaslessProviderIdentifier]); use + * [AnyTONGaslessProviderIdentifier] to refer to a provider by a raw id string. + */ +interface TONGaslessProviderIdentifier { + val name: String +} + +/** Type-erased gasless provider identifier carrying just the provider [name]. */ +data class AnyTONGaslessProviderIdentifier(override val name: String) : TONGaslessProviderIdentifier diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/gasless/TONGaslessProvider.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/gasless/tonapi/TONApiGaslessProviderIdentifier.kt similarity index 71% rename from TONWalletKit-Android/api/src/main/java/io/ton/walletkit/gasless/TONGaslessProvider.kt rename to TONWalletKit-Android/api/src/main/java/io/ton/walletkit/gasless/tonapi/TONApiGaslessProviderIdentifier.kt index 21d0d726..d78f48db 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/gasless/TONGaslessProvider.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/gasless/tonapi/TONApiGaslessProviderIdentifier.kt @@ -19,11 +19,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package io.ton.walletkit.gasless +package io.ton.walletkit.gasless.tonapi -/** - * Handle to a gasless provider registered in the JS bridge. Obtain via - * [io.ton.walletkit.ITONWalletKit.tonApiGaslessProvider], then pass to - * [ITONGaslessManager.registerProvider]. - */ -data class TONGaslessProvider(val providerId: String) +import io.ton.walletkit.gasless.ITONGaslessProvider +import io.ton.walletkit.gasless.TONGaslessProviderIdentifier + +/** Identifier for the built-in TonAPI gasless provider. */ +class TONApiGaslessProviderIdentifier(override val name: String = "tonApiGasless") : + TONGaslessProviderIdentifier + +/** Typed handle for the built-in TonAPI gasless provider. */ +typealias TONApiGaslessProvider = ITONGaslessProvider diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/model/TONWalletAdapter.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/model/TONWalletAdapter.kt index 59e8f4ce..4de7022e 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/model/TONWalletAdapter.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/model/TONWalletAdapter.kt @@ -34,7 +34,7 @@ interface TONWalletAdapter { /** Stable unique wallet identifier. */ fun identifier(): String - fun publicKey(): TONHex + suspend fun publicKey(): TONHex fun network(): TONNetwork diff --git a/TONWalletKit-Android/impl/src/main/assets/walletkit/walletkit-android-bridge.mjs b/TONWalletKit-Android/impl/src/main/assets/walletkit/walletkit-android-bridge.mjs index b25ef25e..d7e3a9f6 100644 --- a/TONWalletKit-Android/impl/src/main/assets/walletkit/walletkit-android-bridge.mjs +++ b/TONWalletKit-Android/impl/src/main/assets/walletkit/walletkit-android-bridge.mjs @@ -23868,9 +23868,9 @@ function parseOutgoingTonTransfers(tx, addressBook, status) { ...comment !== void 0 ? { comment } : {} }, simplePreview: { - name: "Ton Transfer", - description: `Transferring ${(0, import_dist$39.fromNano)(String(amount))} TON`, - value: `${(0, import_dist$39.fromNano)(String(amount))} TON`, + name: "Gram Transfer", + description: `Transferring ${(0, import_dist$39.fromNano)(String(amount))} GRAM`, + value: `${(0, import_dist$39.fromNano)(String(amount))} GRAM`, accounts: [toAccount(sender, addressBook), recipientAccount] }, baseTransactions: [Base64ToHex(tx.hash)] @@ -23901,9 +23901,9 @@ function parseIncomingTonTransfers(tx, addressBook, status) { ...comment !== void 0 ? { comment } : {} }, simplePreview: { - name: "Ton Transfer", - description: `Transferring ${(0, import_dist$39.fromNano)(String(amount))} TON`, - value: `${(0, import_dist$39.fromNano)(String(amount))} TON`, + name: "Gram Transfer", + description: `Transferring ${(0, import_dist$39.fromNano)(String(amount))} GRAM`, + value: `${(0, import_dist$39.fromNano)(String(amount))} GRAM`, accounts: [toAccount(sender, addressBook), recipientAccount] }, baseTransactions: [Base64ToHex(tx.hash)] @@ -23917,7 +23917,7 @@ function computeStatus$1(tx) { return !aborted && computeSuccess && actionSuccess ? "success" : "failure"; } /** -* Compute status specifically for incoming TON transfers. +* Compute status specifically for incoming GRAM transfers. * For incoming transfers, if funds were credited (credit_ph has credit > 0), * it's considered successful even if compute phase failed. */ @@ -23982,7 +23982,7 @@ function parseContractActions(ownerFriendly, transactions, addressBook) { simplePreview: { name: "Smart Contract Execution", description: "Execution of smart contract", - value: `${(0, import_dist$38.fromNano)(String(tonAttached))} TON`, + value: `${(0, import_dist$38.fromNano)(String(tonAttached))} GRAM`, accounts: [toAccount(ownerFriendly, addressBook), toContractAccount$2(contractAddress, addressBook)] }, baseTransactions: [baseTx] @@ -24693,7 +24693,7 @@ function buildEvent(data, account, actions, addressBook) { }; } /** -* Helper: Filter actions based on priority (Jetton/NFT take precedence over TON transfers) +* Helper: Filter actions based on priority (Jetton/NFT take precedence over GRAM transfers) */ function filterActionsByPriority(actions) { const hasJetton = actions.some((a) => a.type === "JettonTransfer"); @@ -25067,17 +25067,17 @@ function createStorageAdapter(config = {}) { if (typeof localStorage !== "undefined") try { return new LocalStorageAdapter(config); } catch (error) { - log$39.warn("Failed to create LocalStorageAdapter, falling back to memory", { error }); + log$40.warn("Failed to create LocalStorageAdapter, falling back to memory", { error }); } if (config.allowMemory) return new MemoryStorageAdapter(config); else throw new Error("No storage adapter available"); } -var log$39; +var log$40; var init_adapters = __esmMin((() => { init_Logger(); init_local(); init_memory(); - log$39 = globalLogger.createChild("StorageAdapter"); + log$40 = globalLogger.createChild("StorageAdapter"); })); //#endregion //#region ../walletkit/dist/esm/storage/adapters/extension.js @@ -25129,10 +25129,10 @@ var init_extension = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/storage/Storage.js -var log$38, Storage; +var log$39, Storage; var init_Storage = __esmMin((() => { init_Logger(); - log$38 = globalLogger.createChild("Storage"); + log$39 = globalLogger.createChild("Storage"); Storage = class { adapter; constructor(adapter) { @@ -25149,7 +25149,7 @@ var init_Storage = __esmMin((() => { if (value === null) return null; return JSON.parse(value); } catch (error) { - log$38.warn("Failed to parse stored value", { + log$39.warn("Failed to parse stored value", { key, error }); @@ -25166,7 +25166,7 @@ var init_Storage = __esmMin((() => { const serialized = JSON.stringify(value); await this.adapter.set(key, serialized); } catch (error) { - log$38.error("Failed to serialize value for storage", { + log$39.error("Failed to serialize value for storage", { key, error }); @@ -25344,8 +25344,8 @@ function validateMessageObject(message, requireFriendlyAddress = true) { if (!message.address || typeof message.address !== "string") errors.push("to address is required and must be a string"); else if (requireFriendlyAddress ? !isFriendlyTonAddress(message.address) : !isValidAddress(message.address)) errors.push(requireFriendlyAddress ? "to address must be a valid friendly TON address" : "to address must be a valid TON address"); if (message.amount !== void 0) { - if (!isValidNanotonAmount(message.amount)) errors.push("value must be a valid nanonton amount (string of digits)"); - } else errors.push("value must be a valid nanonton amount (string of digits)"); + if (!isValidNanoAmount(message.amount)) errors.push("value must be a valid nano units amount (string of digits)"); + } else errors.push("value must be a valid nano units amount (string of digits)"); if (message.payload) { if (typeof message.payload !== "string") errors.push("payload must be a string if provided"); else if (!isValidBOC(message.payload)) errors.push("payload must be a valid base64 string if provided"); @@ -25429,9 +25429,9 @@ function validateStructuredItems(items) { }; } /** -* Check if value is a valid nanonton amount +* Check if value is a valid nano units amount */ -function isValidNanotonAmount(amount) { +function isValidNanoAmount(amount) { if (typeof amount !== "string") return false; const amountStr = String(amount); const parsed = BigInt(amountStr); @@ -25549,11 +25549,11 @@ var init_WalletManager = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/core/TONConnectStoredSessionManager.js -var log$37, TONConnectStoredSessionManager; +var log$38, TONConnectStoredSessionManager; var init_TONConnectStoredSessionManager = __esmMin((() => { init_esm$2(); init_Logger(); - log$37 = globalLogger.createChild("TONConnectStoredSessionManager"); + log$38 = globalLogger.createChild("TONConnectStoredSessionManager"); TONConnectStoredSessionManager = class { sessions = /* @__PURE__ */ new Map(); storage; @@ -25686,16 +25686,16 @@ var init_TONConnectStoredSessionManager = __esmMin((() => { const wallet = this.walletManager.getWallet(session.walletId); if (wallet) session.walletAddress = wallet.getAddress(); else { - log$37.warn("Session Wallet not found for session", { sessionId: session.sessionId }); + log$38.warn("Session Wallet not found for session", { sessionId: session.sessionId }); continue; } } this.sessions.set(session.sessionId, session); } - log$37.debug("Loaded session metadata", { count: storedSessions.length }); + log$38.debug("Loaded session metadata", { count: storedSessions.length }); } } catch (error) { - log$37.warn("Failed to load sessions from storage", { error }); + log$38.warn("Failed to load sessions from storage", { error }); } } /** @@ -25706,7 +25706,7 @@ var init_TONConnectStoredSessionManager = __esmMin((() => { const sessionsToStore = Array.from(this.sessions.values()); await this.storage.set(this.storageKey, sessionsToStore); } catch (error) { - log$37.warn("Failed to persist sessions to storage", { error }); + log$38.warn("Failed to persist sessions to storage", { error }); } } async migrateSessions() { @@ -27323,7 +27323,7 @@ var init_JSBridgeInjector = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/core/BridgeManager.js -var log$35, BridgeManager; +var log$36, BridgeManager; var init_BridgeManager = __esmMin((() => { init_esm$2(); init_dist$1(); @@ -27331,7 +27331,7 @@ var init_BridgeManager = __esmMin((() => { init_uuid(); init_errors$4(); init_JSBridgeInjector(); - log$35 = globalLogger.createChild("BridgeManager"); + log$36 = globalLogger.createChild("BridgeManager"); BridgeManager = class { config; bridgeProvider; @@ -27373,7 +27373,7 @@ var init_BridgeManager = __esmMin((() => { this.walletKitConfig = walletKitConfig; this.jsBridgeTransport = config?.jsBridgeTransport; if (this.config.bridgeUrl && !this.config.disableHttpConnection) this.bridgeProvider = new C(this.config.bridgeUrl, this.queueBridgeEvent.bind(this), (error) => { - log$35.error("Bridge listener error", { error: error.toString() }); + log$36.error("Bridge listener error", { error: error.toString() }); this.analytics?.emitBridgeClientConnectError({ error_message: `${error?.toString() || "Unknown error"}${error?.errorCode ? ` (Code: ${error?.errorCode})` : ""}`, trace_id: error?.traceId, @@ -27387,12 +27387,12 @@ var init_BridgeManager = __esmMin((() => { */ async start() { if (this.isActive === true) { - log$35.warn("Bridge already started"); + log$36.warn("Bridge already started"); return; } this.isActive = true; if (this.isConnected === true) { - log$35.warn("Bridge already connected"); + log$36.warn("Bridge already connected"); return; } try { @@ -27404,7 +27404,7 @@ var init_BridgeManager = __esmMin((() => { } } catch (error) { this.isActive = false; - log$35.error("Failed to start bridge", { error }); + log$36.error("Failed to start bridge", { error }); throw error; } const requestProcessing = () => { @@ -27417,10 +27417,10 @@ var init_BridgeManager = __esmMin((() => { * Create new session for a dApp connection */ async createSession(appSessionId) { - log$35.info("[BRIDGE] Creating session", { appSessionId }); + log$36.info("[BRIDGE] Creating session", { appSessionId }); if (!await this.sessionManager.getSession(appSessionId)) throw new WalletKitError(ERROR_CODES.SESSION_NOT_FOUND, `Session not found`, void 0, { appSessionId }); if (this.bridgeProvider && this.isConnected) { - log$35.info("[BRIDGE] Updating clients"); + log$36.info("[BRIDGE] Updating clients"); await this.updateClients(); } } @@ -27429,7 +27429,7 @@ var init_BridgeManager = __esmMin((() => { */ async removeSession(appSessionId) { if (this.bridgeProvider && this.isConnected) await this.updateClients(); - log$35.debug("Session removed", { appSessionId }); + log$36.debug("Session removed", { appSessionId }); } /** * Send response to dApp @@ -27454,12 +27454,12 @@ var init_BridgeManager = __esmMin((() => { } try { await this.bridgeProvider.send(response, sessionCrypto, sessionId, { traceId: event?.traceId }); - log$35.debug("Response sent successfully", { + log$36.debug("Response sent successfully", { sessionId, requestId: event.id }); } catch (error) { - log$35.error("Failed to send response through bridge", { + log$36.error("Failed to send response through bridge", { sessionId, requestId: event.id, error @@ -27541,7 +27541,7 @@ var init_BridgeManager = __esmMin((() => { await this.bridgeProvider?.restoreConnection(clients, { lastEventId: this.lastEventId }); this.isConnected = true; this.reconnectAttempts = 0; - log$35.info("Bridge connected successfully"); + log$36.info("Bridge connected successfully"); if (this.analytics) { const client = clients[0]; this.analytics.emitBridgeClientConnectEstablished({ @@ -27550,7 +27550,7 @@ var init_BridgeManager = __esmMin((() => { }); } } catch (error) { - log$35.error("Bridge connection failed", { error: error?.toString() }); + log$36.error("Bridge connection failed", { error: error?.toString() }); this.analytics?.emitBridgeClientConnectError({ error_message: `${error?.toString() || "Unknown error"}${error?.errorCode ? ` (Code: ${error?.errorCode})` : ""}`, trace_id: error?.traceId ?? connectTraceId, @@ -27559,9 +27559,9 @@ var init_BridgeManager = __esmMin((() => { if (!this.config.disableHttpConnection) { if (this.reconnectAttempts < (this.config.maxReconnectAttempts || 5)) { this.reconnectAttempts++; - log$35.info("Bridge reconnection attempt", { attempt: this.reconnectAttempts }); + log$36.info("Bridge reconnection attempt", { attempt: this.reconnectAttempts }); setTimeout(() => { - this.connectToSSEBridge().catch((error) => log$35.error("Bridge reconnection failed", { error })); + this.connectToSSEBridge().catch((error) => log$36.error("Bridge reconnection failed", { error })); }, this.config.reconnectInterval); } } @@ -27582,10 +27582,10 @@ var init_BridgeManager = __esmMin((() => { * Add client to existing bridge connection */ async updateClients() { - log$35.debug("Updating clients"); + log$36.debug("Updating clients"); if (this.bridgeProvider) { const clients = await this.getClients(); - log$35.info("[BRIDGE] Restoring connection", { clients: clients.length }); + log$36.info("[BRIDGE] Restoring connection", { clients: clients.length }); await this.bridgeProvider.restoreConnection(clients, { lastEventId: this.lastEventId }); } } @@ -27593,17 +27593,17 @@ var init_BridgeManager = __esmMin((() => { * Queue incoming bridge events for processing */ queueBridgeEvent(event) { - log$35.debug("Bridge event queued", { + log$36.debug("Bridge event queued", { eventId: event?.id, event }); this.eventQueue.push(event); this.processBridgeEvents().catch((error) => { - log$35.error("Error in background event processing", { error }); + log$36.error("Error in background event processing", { error }); }); } queueJsBridgeEvent(messageInfo, event) { - log$35.debug("JS Bridge event queued", { eventId: messageInfo?.messageId }); + log$36.debug("JS Bridge event queued", { eventId: messageInfo?.messageId }); if (!event) return; if (!event.traceId) event.traceId = v7(); if (event.method == "connect") this.eventQueue.push({ @@ -27632,7 +27632,7 @@ var init_BridgeManager = __esmMin((() => { walletId: messageInfo.walletId }); this.processBridgeEvents().catch((error) => { - log$35.error("Error in background event processing", { error }); + log$36.error("Error in background event processing", { error }); }); } /** @@ -27644,7 +27644,7 @@ var init_BridgeManager = __esmMin((() => { */ async processBridgeEvents() { if (this.isProcessing) { - log$35.debug("Event processing already in progress, skipping"); + log$36.debug("Event processing already in progress, skipping"); return; } this.isProcessing = true; @@ -27657,7 +27657,7 @@ var init_BridgeManager = __esmMin((() => { } } } catch (error) { - log$35.error("Error during event processing", { error }); + log$36.error("Error during event processing", { error }); this.isProcessing = false; this.restartConnection(); return; @@ -27670,7 +27670,7 @@ var init_BridgeManager = __esmMin((() => { */ async handleBridgeEvent(event) { try { - log$35.info("Bridge event received", { event }); + log$36.info("Bridge event received", { event }); const rawEvent = { id: event.id || crypto.randomUUID(), method: event.method || "unknown", @@ -27724,12 +27724,12 @@ var init_BridgeManager = __esmMin((() => { try { await this.eventStore.storeEvent(rawEvent); if (this.eventEmitter) this.eventEmitter.emit("bridgeStorageUpdated", {}, "bridge-manager"); - log$35.info("Event stored durably", { + log$36.info("Event stored durably", { eventId: rawEvent.id, method: rawEvent.method }); } catch (error) { - log$35.error("Failed to store event durably", { + log$36.error("Failed to store event durably", { eventId: rawEvent.id, error: error.message }); @@ -27738,13 +27738,13 @@ var init_BridgeManager = __esmMin((() => { method: rawEvent.method }); } - log$35.info("Bridge event processed", { rawEvent }); + log$36.info("Bridge event processed", { rawEvent }); if (event?.lastEventId && event.lastEventId !== this.lastEventId) { this.lastEventId = event.lastEventId; await this.saveLastEventId(); } } catch (error) { - log$35.error("Error handling bridge event", { error }); + log$36.error("Error handling bridge event", { error }); } } /** @@ -27755,11 +27755,11 @@ var init_BridgeManager = __esmMin((() => { const savedEventId = await this.storage.get(this.storageKey); if (savedEventId) { this.lastEventId = savedEventId; - log$35.debug("Loaded last event ID from storage", { lastEventId: this.lastEventId }); + log$36.debug("Loaded last event ID from storage", { lastEventId: this.lastEventId }); } } catch (error) { const storageError = WalletKitError.fromError(ERROR_CODES.STORAGE_READ_FAILED, "Failed to load last event ID from storage", error); - log$35.warn("Failed to load last event ID from storage", { error: storageError }); + log$36.warn("Failed to load last event ID from storage", { error: storageError }); } } /** @@ -27769,11 +27769,11 @@ var init_BridgeManager = __esmMin((() => { try { if (this.lastEventId) { await this.storage.set(this.storageKey, this.lastEventId); - log$35.debug("Saved last event ID to storage", { lastEventId: this.lastEventId }); + log$36.debug("Saved last event ID to storage", { lastEventId: this.lastEventId }); } } catch (error) { const storageError = WalletKitError.fromError(ERROR_CODES.STORAGE_WRITE_FAILED, "Failed to save last event ID to storage", error); - log$35.warn("Failed to save last event ID to storage", { error: storageError }); + log$36.warn("Failed to save last event ID to storage", { error: storageError }); } } }; @@ -27837,14 +27837,14 @@ async function fetchManifest(manifestUrl, proxyUrl) { manifest: null, manifestFetchErrorCode: CONNECT_EVENT_ERROR_CODES$1.MANIFEST_CONTENT_ERROR }; - log$34.info("Direct manifest fetch failed, trying proxy", { manifestUrl }); + log$35.info("Direct manifest fetch failed, trying proxy", { manifestUrl }); return tryFetchManifest(`${proxyUrl}${manifestUrl}`); } async function tryFetchManifest(url) { try { const response = await fetch(url); if (!response.ok) { - log$34.error("Failed to fetch manifest not ok", { + log$35.error("Failed to fetch manifest not ok", { url, status: response.status }); @@ -27858,7 +27858,7 @@ async function tryFetchManifest(url) { manifestFetchErrorCode: void 0 }; } catch (e) { - log$34.error("Failed to fetch manifest catched", { + log$35.error("Failed to fetch manifest catched", { url, error: e }); @@ -27868,23 +27868,23 @@ async function tryFetchManifest(url) { }; } } -var log$34; +var log$35; var init_manifest = __esmMin((() => { init_esm$2(); init_url(); init_Logger(); - log$34 = globalLogger.createChild("ManifestUtils"); + log$35 = globalLogger.createChild("ManifestUtils"); })); //#endregion //#region ../walletkit/dist/esm/handlers/ConnectHandler.js -var log$33, ConnectHandler; +var log$34, ConnectHandler; var init_ConnectHandler = __esmMin((() => { init_esm$2(); init_Logger(); init_BasicHandler(); init_url(); init_manifest(); - log$33 = globalLogger.createChild("ConnectHandler"); + log$34 = globalLogger.createChild("ConnectHandler"); ConnectHandler = class extends BasicHandler { config; analytics; @@ -27905,7 +27905,7 @@ var init_ConnectHandler = __esmMin((() => { manifest = result.manifest; manifestFetchErrorCode = result.manifestFetchErrorCode; } catch (error) { - log$33.warn("Failed to fetch manifest", { error }); + log$34.warn("Failed to fetch manifest", { error }); } const preview = this.createPreview(event, manifestUrl, manifest, manifestFetchErrorCode); const connectEvent = { @@ -27966,14 +27966,14 @@ var init_ConnectHandler = __esmMin((() => { if (!finalManifestFetchErrorCode && dAppUrl) try { const parsedDAppUrl = new URL(dAppUrl); if (!isValidHost(parsedDAppUrl.host)) { - log$33.warn("Invalid dApp URL in manifest - invalid host format", { + log$34.warn("Invalid dApp URL in manifest - invalid host format", { dAppUrl, host: parsedDAppUrl.host }); finalManifestFetchErrorCode = CONNECT_EVENT_ERROR_CODES$1.MANIFEST_CONTENT_ERROR; } } catch (_) { - log$33.warn("Invalid dApp URL in manifest - failed to parse", { dAppUrl }); + log$34.warn("Invalid dApp URL in manifest - failed to parse", { dAppUrl }); finalManifestFetchErrorCode = CONNECT_EVENT_ERROR_CODES$1.MANIFEST_CONTENT_ERROR; } } @@ -28108,7 +28108,7 @@ var AssetType; var init_AssetType = __esmMin((() => { (function(AssetType) { /** - * Native TON cryptocurrency + * Native GRAM cryptocurrency */ AssetType["ton"] = "ton"; /** @@ -28637,7 +28637,7 @@ async function resolveItemsToMessages(items, wallet) { messages.push(resolveNftItem(item, wallet)); break; default: - log$32.warn("Unknown item type, skipping", { item }); + log$33.warn("Unknown item type, skipping", { item }); break; } return messages; @@ -28690,13 +28690,13 @@ function resolveNftItem(item, wallet) { mode: { flags: [SendModeFlag.IGNORE_ERRORS, SendModeFlag.PAY_GAS_SEPARATELY] } }; } -var import_dist$33, log$32; +var import_dist$33, log$33; var init_itemsResolver = __esmMin((() => { import_dist$33 = require_dist$1(); init_models(); init_messageBuilders(); init_Logger(); - log$32 = globalLogger.createChild("ItemsResolver"); + log$33 = globalLogger.createChild("ItemsResolver"); })); //#endregion //#region ../walletkit/dist/esm/utils/events.js @@ -28758,7 +28758,7 @@ function parseTonConnectTransactionRequest(event, wallet) { validation: validateTransactionRequestForWallet(request, wallet, event.isLocal) }; } catch (error) { - log$31.error("Failed to parse transaction request", { error }); + log$32.error("Failed to parse transaction request", { error }); errors.push("Failed to parse transaction request"); return { result: void 0, @@ -28769,7 +28769,7 @@ function parseTonConnectTransactionRequest(event, wallet) { }; } } -var log$31; +var log$32; var init_events = __esmMin((() => { init_errors$4(); init_transactionValidators(); @@ -28777,7 +28777,7 @@ var init_events = __esmMin((() => { init_transaction$1(); init_itemsResolver(); init_Logger(); - log$31 = globalLogger.createChild("EventsUtils"); + log$32 = globalLogger.createChild("EventsUtils"); })); //#endregion //#region ../../node_modules/.pnpm/@noble+hashes@2.2.0/node_modules/@noble/hashes/utils.js @@ -30162,7 +30162,7 @@ var init_map_emulation_trace = __esmMin((() => { init_address$1(); })); //#endregion -//#region ../../node_modules/.pnpm/lru-cache@11.5.0/node_modules/lru-cache/dist/esm/browser/index.min.js +//#region ../../node_modules/.pnpm/lru-cache@11.5.1/node_modules/lru-cache/dist/esm/browser/index.min.js var L, S, W, M, D, j, I, P, k, T, G, O, R, U; var init_index_min = __esmMin((() => { L = { hasSubscribers: !1 }, S = L, W = L; @@ -31111,7 +31111,7 @@ async function createTransactionPreviewIfPossible(config, client, request, walle try { preview = await CallForSuccess(() => createTransactionPreview(client, request, wallet, options)); } catch (error) { - log$30.error("Failed to create transaction preview", { error }); + log$31.error("Failed to create transaction preview", { error }); preview = { error: { code: ERROR_CODES.UNKNOWN_EMULATION_ERROR, @@ -31122,7 +31122,7 @@ async function createTransactionPreviewIfPossible(config, client, request, walle } return preview; } -var import_dist$20, log$30, SIGN_MODE_EMULATION_VALUE; +var import_dist$20, log$31, SIGN_MODE_EMULATION_VALUE; var init_transactionPreview = __esmMin((() => { import_dist$20 = require_dist$1(); init_map_emulation_trace(); @@ -31131,7 +31131,7 @@ var init_transactionPreview = __esmMin((() => { init_retry(); init_models(); init_Logger(); - log$30 = globalLogger.createChild("TransactionPreview"); + log$31 = globalLogger.createChild("TransactionPreview"); SIGN_MODE_EMULATION_VALUE = 2000000000n; })); //#endregion @@ -31409,14 +31409,14 @@ var init_utils$2 = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/handlers/TransactionHandler.js -var log$29, TransactionHandler; +var log$30, TransactionHandler; var init_TransactionHandler = __esmMin((() => { init_esm$2(); init_Logger(); init_BasicHandler(); init_events(); init_utils$2(); - log$29 = globalLogger.createChild("TransactionHandler"); + log$30 = globalLogger.createChild("TransactionHandler"); TransactionHandler = class extends BasicHandler { config; walletManager; @@ -31438,7 +31438,7 @@ var init_TransactionHandler = __esmMin((() => { async handle(event) { const wallet = getWalletFromEvent(this.walletManager, event); if (!wallet) { - log$29.error("Wallet not found", { event }); + log$30.error("Wallet not found", { event }); return { error: { code: SEND_TRANSACTION_ERROR_CODES$1.UNKNOWN_APP_ERROR, @@ -31449,7 +31449,7 @@ var init_TransactionHandler = __esmMin((() => { } const requestValidation = this.parseTonConnectTransactionRequest(event, wallet); if (!requestValidation.result || !requestValidation?.validation?.isValid) { - log$29.error("Failed to parse transaction request", { + log$30.error("Failed to parse transaction request", { event, requestValidation }); @@ -31495,13 +31495,13 @@ var init_TransactionHandler = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/handlers/SignDataHandler.js -var log$28, SignDataHandler; +var log$29, SignDataHandler; var init_SignDataHandler = __esmMin((() => { init_internal(); init_BasicHandler(); init_Logger(); init_errors$4(); - log$28 = globalLogger.createChild("SignDataHandler"); + log$29 = globalLogger.createChild("SignDataHandler"); SignDataHandler = class extends BasicHandler { analytics; walletManager; @@ -31522,12 +31522,12 @@ var init_SignDataHandler = __esmMin((() => { const wallet = walletId ? this.walletManager.getWallet(walletId) : void 0; const payload = this.parseDataToSign(event); if (!payload) { - log$28.error("No data to sign found in request", { event }); + log$29.error("No data to sign found in request", { event }); throw new WalletKitError(ERROR_CODES.INVALID_REQUEST_EVENT, "No data to sign found in request", void 0, { eventId: event.id }); } const preview = this.createDataPreview(payload.data, event); if (!preview) { - log$28.error("No preview found for data", { data: payload }); + log$29.error("No preview found for data", { data: payload }); throw new WalletKitError(ERROR_CODES.RESPONSE_CREATION_FAILED, "Failed to create preview for sign data request", void 0, { eventId: event.id, data: payload @@ -31584,7 +31584,7 @@ var init_SignDataHandler = __esmMin((() => { } }; } catch (error) { - log$28.error("Error deserializing cell", { error }); + log$29.error("Error deserializing cell", { error }); return { type: "cell", value: { @@ -31598,14 +31598,14 @@ var init_SignDataHandler = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/handlers/SignMessageHandler.js -var log$27, SignMessageHandler; +var log$28, SignMessageHandler; var init_SignMessageHandler = __esmMin((() => { init_esm$2(); init_Logger(); init_BasicHandler(); init_utils$2(); init_events(); - log$27 = globalLogger.createChild("SignMessageHandler"); + log$28 = globalLogger.createChild("SignMessageHandler"); SignMessageHandler = class extends BasicHandler { config; walletManager; @@ -31627,7 +31627,7 @@ var init_SignMessageHandler = __esmMin((() => { async handle(event) { const wallet = getWalletFromEvent(this.walletManager, event); if (!wallet) { - log$27.error("Wallet not found", { event }); + log$28.error("Wallet not found", { event }); return { error: { code: SIGN_MESSAGE_ERROR_CODES.UNKNOWN_APP_ERROR, @@ -31638,7 +31638,7 @@ var init_SignMessageHandler = __esmMin((() => { } const requestValidation = this.parseTonConnectTransactionRequest(event, wallet); if (!requestValidation.result || !requestValidation?.validation?.isValid) { - log$27.error("Failed to parse sign message request", { + log$28.error("Failed to parse sign message request", { event, requestValidation }); @@ -31723,7 +31723,7 @@ var init_DisconnectHandler = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/core/EventRouter.js -var log$26, EventRouter; +var log$27, EventRouter; var init_EventRouter = __esmMin((() => { init_ConnectHandler(); init_TransactionHandler(); @@ -31732,7 +31732,7 @@ var init_EventRouter = __esmMin((() => { init_DisconnectHandler(); init_events$1(); init_Logger(); - log$26 = globalLogger.createChild("EventRouter"); + log$27 = globalLogger.createChild("EventRouter"); EventRouter = class { config; eventEmitter; @@ -31764,7 +31764,7 @@ var init_EventRouter = __esmMin((() => { async routeEvent(event) { const validation = validateBridgeEvent(event); if (!validation.isValid) { - log$26.error("Invalid bridge event", { errors: validation.errors }); + log$27.error("Invalid bridge event", { errors: validation.errors }); return; } try { @@ -31779,7 +31779,7 @@ var init_EventRouter = __esmMin((() => { try { await this.bridgeManager.sendResponse(event, result); } catch (error) { - log$26.error("Error sending response for error event", { + log$27.error("Error sending response for error event", { error, event, result @@ -31791,7 +31791,7 @@ var init_EventRouter = __esmMin((() => { break; } } catch (error) { - log$26.error("Error routing event", { error }); + log$27.error("Error routing event", { error }); throw error; } } @@ -31920,7 +31920,7 @@ function hasConnectionResult(event) { */ async function signTransactionInternal(wallet, request) { const signedBoc = await wallet.getSignedSendTransaction(request, { fakeSignature: false }); - log$25.debug("Signing transaction", { + log$26.debug("Signing transaction", { messagesNumber: request.messages.length, fromAddress: request.fromAddress, validUntil: request.validUntil @@ -31976,7 +31976,7 @@ function parseDomain(url) { value: parsedUrl.host }; } catch (error) { - log$25.error("Failed to parse domain", { error }); + log$26.error("Failed to parse domain", { error }); return { lengthBytes: 0, value: "" @@ -32004,7 +32004,7 @@ function toTonConnectSignDataPayload(payload) { bytes: payload.data.value.content }; } -var import_dist$16, import_dist$17, log$25, RequestProcessor; +var import_dist$16, import_dist$17, log$26, RequestProcessor; var init_RequestProcessor = __esmMin((() => { import_dist$16 = require_dist$1(); init_esm$2(); @@ -32019,7 +32019,7 @@ var init_RequestProcessor = __esmMin((() => { init_transaction$1(); init_utils$2(); init_events(); - log$25 = globalLogger.createChild("RequestProcessor"); + log$26 = globalLogger.createChild("RequestProcessor"); RequestProcessor = class { walletKitOptions; sessionManager; @@ -32082,7 +32082,7 @@ var init_RequestProcessor = __esmMin((() => { } return; } catch (error) { - log$25.error("Failed to approve connect request", { error }); + log$26.error("Failed to approve connect request", { error }); throw error; } } @@ -32217,7 +32217,7 @@ var init_RequestProcessor = __esmMin((() => { */ async rejectConnectRequest(event, reason, errorCode) { try { - log$25.info("Connect request rejected", { + log$26.info("Connect request rejected", { id: event.id, dAppName: event.preview.dAppInfo?.name || "", reason: reason || "User rejected connection" @@ -32234,7 +32234,7 @@ var init_RequestProcessor = __esmMin((() => { try { await this.bridgeManager.sendResponse(event, response, new SessionCrypto()); } catch (error) { - log$25.error("Failed to send connect request rejection response", { error }); + log$26.error("Failed to send connect request rejection response", { error }); } if (this.analytics) { const sessionData = event.from ? await this.sessionManager.getSession(sessionId) : void 0; @@ -32263,7 +32263,7 @@ var init_RequestProcessor = __esmMin((() => { } return; } catch (error) { - log$25.error("Failed to reject connect request", { error }); + log$26.error("Failed to reject connect request", { error }); throw error; } } @@ -32295,7 +32295,7 @@ var init_RequestProcessor = __esmMin((() => { return { signedBoc }; } } catch (error) { - log$25.error("Failed to approve transaction request", { error }); + log$26.error("Failed to approve transaction request", { error }); if (error instanceof WalletKitError) throw error; if (error?.message?.includes("Ledger device")) throw new WalletKitError(ERROR_CODES.LEDGER_DEVICE_ERROR, "Ledger device error", error); throw error; @@ -32345,7 +32345,7 @@ var init_RequestProcessor = __esmMin((() => { } return; } catch (error) { - log$25.error("Failed to reject transaction request", { error }); + log$26.error("Failed to reject transaction request", { error }); throw error; } } @@ -32376,7 +32376,7 @@ var init_RequestProcessor = __esmMin((() => { return { internalBoc }; } } catch (error) { - log$25.error("Failed to approve sign message request", { error }); + log$26.error("Failed to approve sign message request", { error }); throw error; } } @@ -32394,7 +32394,7 @@ var init_RequestProcessor = __esmMin((() => { }; await this.sendBridgeMessage(event, void 0, response); } catch (error) { - log$25.error("Failed to reject sign message request", { error }); + log$26.error("Failed to reject sign message request", { error }); throw error; } } @@ -32497,7 +32497,7 @@ var init_RequestProcessor = __esmMin((() => { }; } } catch (error) { - log$25.error("Failed to approve sign data request", { error: error?.message?.toString() ?? error?.toString() }); + log$26.error("Failed to approve sign data request", { error: error?.message?.toString() ?? error?.toString() }); if (error instanceof WalletKitError) throw error; throw error; } @@ -32532,7 +32532,7 @@ var init_RequestProcessor = __esmMin((() => { } return; } catch (error) { - log$25.error("Failed to reject sign data request", { error }); + log$26.error("Failed to reject sign data request", { error }); throw error; } } @@ -32609,14 +32609,14 @@ var init_RequestProcessor = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/core/EventStore.js -var getEventUUID, log$24, MAX_EVENT_SIZE_BYTES, StorageEventStore; +var getEventUUID, log$25, MAX_EVENT_SIZE_BYTES, StorageEventStore; var init_EventStore = __esmMin((() => { init_Logger(); init_events$1(); getEventUUID = () => { return crypto.randomUUID(); }; - log$24 = globalLogger.createChild("EventStore"); + log$25 = globalLogger.createChild("EventStore"); MAX_EVENT_SIZE_BYTES = 100 * 1024; StorageEventStore = class { storage; @@ -32649,7 +32649,7 @@ var init_EventStore = __esmMin((() => { sizeBytes }; await this.saveEvent(storedEvent); - log$24.info("Event stored", { + log$25.info("Event stored", { eventId: storedEvent.id, eventType, sizeBytes, @@ -32677,11 +32677,11 @@ var init_EventStore = __esmMin((() => { const allEvents = await this.getAllEventsFromStorage(); const event = allEvents[eventId]; if (!event) { - log$24.warn("Cannot lock non-existent event", { eventId }); + log$25.warn("Cannot lock non-existent event", { eventId }); return; } if (event.status !== "new") { - log$24.debug("Cannot lock event - not in new status", { + log$25.debug("Cannot lock event - not in new status", { eventId, status: event.status, lockedBy: event.lockedBy @@ -32696,7 +32696,7 @@ var init_EventStore = __esmMin((() => { }; allEvents[eventId] = updatedEvent; await this.storage.set(this.storageKey, allEvents); - log$24.debug("Event lock acquired", { + log$25.debug("Event lock acquired", { eventId, walletAddress: walletId }); @@ -32723,7 +32723,7 @@ var init_EventStore = __esmMin((() => { }; allEvents[eventId] = updatedEvent; await this.storage.set(this.storageKey, allEvents); - log$24.debug("Event retry count incremented", { + log$25.debug("Event retry count incremented", { eventId, retryCount: updatedEvent.retryCount, error @@ -32747,7 +32747,7 @@ var init_EventStore = __esmMin((() => { if (status === "completed") updatedEvent.completedAt = Date.now(); allEvents[eventId] = updatedEvent; await this.storage.set(this.storageKey, allEvents); - log$24.debug("Event status updated", { + log$25.debug("Event status updated", { eventId, oldStatus, newStatus: status @@ -32762,7 +32762,7 @@ var init_EventStore = __esmMin((() => { try { return (await this.getAllEventsFromStorage())[eventId] || null; } catch (error) { - log$24.warn("Failed to get event", { + log$25.warn("Failed to get event", { eventId, error }); @@ -32784,14 +32784,14 @@ var init_EventStore = __esmMin((() => { }; await this.saveEvent(recoveredEvent); recoveredCount++; - log$24.info("Recovered stale event", { + log$25.info("Recovered stale event", { eventId: event.id, lockedBy: event.lockedBy, staleMinutes: Math.round((now - event.processingStartedAt) / 6e4), retryCount: event.retryCount || 0 }); } - if (recoveredCount > 0) log$24.info("Event recovery completed", { recoveredCount }); + if (recoveredCount > 0) log$25.info("Event recovery completed", { recoveredCount }); return recoveredCount; } /** @@ -32804,7 +32804,7 @@ var init_EventStore = __esmMin((() => { const eventsToRemove = []; for (const event of events) if (event.status === "completed" && event.completedAt && event.completedAt < cutoffTime || event.status === "errored" && event.createdAt < cutoffTime) { eventsToRemove.push(event.id); - log$24.debug("Marked event for cleanup", { + log$25.debug("Marked event for cleanup", { eventId: event.id, status: event.status }); @@ -32818,7 +32818,7 @@ var init_EventStore = __esmMin((() => { } await this.storage.set(this.storageKey, allEvents); }); - log$24.info("Event cleanup completed", { cleanedUpCount }); + log$25.info("Event cleanup completed", { cleanedUpCount }); } return cleanedUpCount; } @@ -32830,7 +32830,7 @@ var init_EventStore = __esmMin((() => { const allEvents = await this.getAllEventsFromStorage(); return Object.values(allEvents); } catch (error) { - log$24.warn("Failed to get all events", { error }); + log$25.warn("Failed to get all events", { error }); return []; } } @@ -32852,7 +32852,7 @@ var init_EventStore = __esmMin((() => { try { return await this.storage.get(this.storageKey) || {}; } catch (error) { - log$24.warn("Failed to get events from storage", { error }); + log$25.warn("Failed to get events from storage", { error }); return {}; } } @@ -32885,10 +32885,10 @@ var init_EventStore = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/core/EventProcessor.js -var log$23, StorageEventProcessor; +var log$24, StorageEventProcessor; var init_EventProcessor = __esmMin((() => { init_Logger(); - log$23 = globalLogger.createChild("EventProcessor"); + log$24 = globalLogger.createChild("EventProcessor"); StorageEventProcessor = class { eventStore; config; @@ -32920,14 +32920,14 @@ var init_EventProcessor = __esmMin((() => { */ async startProcessing(walletId) { if (this.processorConfig.disableEvents) return; - if (walletId) if (this.registeredWallets.has(walletId)) log$23.debug("Processing already registered for wallet", { walletId }); + if (walletId) if (this.registeredWallets.has(walletId)) log$24.debug("Processing already registered for wallet", { walletId }); else { this.registeredWallets.add(walletId); - log$23.info("Registered wallet for event processing", { walletId }); + log$24.info("Registered wallet for event processing", { walletId }); } if (!this.isProcessing) { this.isProcessing = true; - log$23.info("Started global event processing loop"); + log$24.info("Started global event processing loop"); this.processEventsLoop(); } else this.triggerProcessing(); } @@ -32938,7 +32938,7 @@ var init_EventProcessor = __esmMin((() => { if (this.processorConfig.disableEvents) return; if (walletId) { this.registeredWallets.delete(walletId); - log$23.info("Unregistered wallet from event processing", { walletId }); + log$24.info("Unregistered wallet from event processing", { walletId }); } if (this.registeredWallets.size === 0 && this.isProcessing && !walletId) { this.isProcessing = false; @@ -32946,12 +32946,12 @@ var init_EventProcessor = __esmMin((() => { this.wakeUpResolver(); this.wakeUpResolver = void 0; } - log$23.info("Stopped global event processing loop (no more wallets)"); + log$24.info("Stopped global event processing loop (no more wallets)"); } } async clearRegisteredWallets() { this.registeredWallets.clear(); - log$23.info("Cleared registered wallets from event processing"); + log$24.info("Cleared registered wallets from event processing"); } /** * Process next available event from any source (wallet or no-wallet) @@ -32981,7 +32981,7 @@ var init_EventProcessor = __esmMin((() => { const walletId = allSessions.find((s) => s.sessionId === eventToUse.sessionId)?.walletId || "no-wallet"; return await this.processEvent(eventToUse, walletId); } catch (error) { - log$23.error("Error in processNextAvailableEvent", { error: error.message }); + log$24.error("Error in processNextAvailableEvent", { error: error.message }); return false; } } @@ -32991,9 +32991,9 @@ var init_EventProcessor = __esmMin((() => { async completeEvent(eventId) { try { await this.eventStore.updateEventStatus(eventId, "completed", "processing"); - log$23.debug("Event marked as completed", { eventId }); + log$24.debug("Event marked as completed", { eventId }); } catch (error) { - log$23.error("Failed to mark event as completed", { + log$24.error("Failed to mark event as completed", { eventId, error: error.message }); @@ -33004,14 +33004,14 @@ var init_EventProcessor = __esmMin((() => { */ startRecoveryLoop() { if (this.recoveryTimeoutId) { - log$23.debug("Recovery loop already running"); + log$24.debug("Recovery loop already running"); return; } const recoveryLoop = async () => { try { if (await this.eventStore.recoverStaleEvents(this.config.processingTimeoutMs) > 0) this.triggerProcessing(); } catch (error) { - log$23.error("Error in recovery loop", { error: error.message }); + log$24.error("Error in recovery loop", { error: error.message }); } if (this.recoveryTimeoutId !== void 0) this.recoveryTimeoutId = setTimeout(recoveryLoop, this.config.recoveryIntervalMs); }; @@ -33019,13 +33019,13 @@ var init_EventProcessor = __esmMin((() => { try { await this.eventStore.cleanupOldEvents(this.config.retentionMs); } catch (error) { - log$23.error("Error in cleanup loop", { error: error.message }); + log$24.error("Error in cleanup loop", { error: error.message }); } if (this.cleanupTimeoutId !== void 0) this.cleanupTimeoutId = setTimeout(cleanupLoop, this.config.cleanupIntervalMs); }; this.recoveryTimeoutId = setTimeout(recoveryLoop, this.config.recoveryIntervalMs); this.cleanupTimeoutId = setTimeout(cleanupLoop, this.config.cleanupIntervalMs); - log$23.info("Recovery and cleanup loops started"); + log$24.info("Recovery and cleanup loops started"); } /** * Stop the recovery process @@ -33039,7 +33039,7 @@ var init_EventProcessor = __esmMin((() => { clearTimeout(this.cleanupTimeoutId); this.cleanupTimeoutId = void 0; } - log$23.info("Recovery and cleanup loops stopped"); + log$24.info("Recovery and cleanup loops stopped"); } /** * Process a single event with retry logic @@ -33047,7 +33047,7 @@ var init_EventProcessor = __esmMin((() => { */ async processEvent(event, walletId) { if (!await this.eventStore.acquireLock(event.id, walletId)) { - log$23.debug("Failed to acquire lock on event", { + log$24.debug("Failed to acquire lock on event", { eventId: event.id, walletId }); @@ -33055,7 +33055,7 @@ var init_EventProcessor = __esmMin((() => { } const retryCount = event.retryCount || 0; if (retryCount >= this.config.maxRetries) { - log$23.error("Event exceeded max retries, marking as errored", { + log$24.error("Event exceeded max retries, marking as errored", { eventId: event.id, retryCount, maxRetries: this.config.maxRetries @@ -33063,14 +33063,14 @@ var init_EventProcessor = __esmMin((() => { try { await this.eventStore.updateEventStatus(event.id, "errored", "processing"); } catch (error) { - log$23.error("Failed to mark event as errored", { + log$24.error("Failed to mark event as errored", { eventId: event.id, error: error.message }); } return false; } - log$23.info("Processing event", { + log$24.info("Processing event", { eventId: event.id, eventType: event.eventType, walletId, @@ -33090,11 +33090,11 @@ var init_EventProcessor = __esmMin((() => { ...walletAddress ? { walletAddress } : {} }); await this.eventStore.updateEventStatus(event.id, "completed", "processing"); - log$23.info("Event processing completed", { eventId: event.id }); + log$24.info("Event processing completed", { eventId: event.id }); return true; } catch (error) { const errorMessage = error.message ?? "Unknown error"; - log$23.error("Error processing event", { + log$24.error("Error processing event", { eventId: event.id, error: errorMessage, retryCount @@ -33102,7 +33102,7 @@ var init_EventProcessor = __esmMin((() => { try { await this.eventStore.releaseLock(event.id, errorMessage); } catch (updateError) { - log$23.error("Failed to increment retry count", { + log$24.error("Failed to increment retry count", { eventId: event.id, error: updateError.message }); @@ -33117,18 +33117,18 @@ var init_EventProcessor = __esmMin((() => { while (this.isProcessing) try { if (!await this.processNextAvailableEvent()) await this.waitForWakeUpOrTimeout(500); } catch (error) { - log$23.error("Error in global processing loop", { error: error.message }); + log$24.error("Error in global processing loop", { error: error.message }); await this.waitForWakeUpOrTimeout(500); } this.wakeUpResolver = void 0; - log$23.debug("Global processing loop ended"); + log$24.debug("Global processing loop ended"); } /** * Trigger the global processing loop */ triggerProcessing() { if (this.isProcessing && this.wakeUpResolver) { - log$23.debug("Waking up global processing loop"); + log$24.debug("Waking up global processing loop"); this.wakeUpResolver(); } } @@ -33165,7 +33165,7 @@ var init_EventProcessor = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/core/wallet/extensions/ton.js -var log$22, WalletTonClass; +var log$23, WalletTonClass; var init_ton = __esmMin((() => { init_address$1(); init_validation(); @@ -33175,11 +33175,11 @@ var init_ton = __esmMin((() => { init_getNormalizedExtMessageHash(); init_errors$4(); init_Logger(); - log$22 = globalLogger.createChild("WalletTonClass"); + log$23 = globalLogger.createChild("WalletTonClass"); WalletTonClass = class { async createTransferTonTransaction(param) { if (!isValidAddress(param.recipientAddress)) throw new Error(`Invalid to address: ${param.recipientAddress}`); - if (!isValidNanotonAmount(param.transferAmount)) throw new Error(`Invalid amount: ${param.transferAmount}`); + if (!isValidNanoAmount(param.transferAmount)) throw new Error(`Invalid amount: ${param.transferAmount}`); let body; if (param.payload) body = param.payload; else if (param.comment) body = createCommentPayloadBase64(param.comment); @@ -33201,7 +33201,7 @@ var init_ton = __esmMin((() => { const messages = []; for (const param of params) { if (!isValidAddress(param.recipientAddress)) throw new Error(`Invalid to address: ${param.recipientAddress}`); - if (!isValidNanotonAmount(param.transferAmount)) throw new Error(`Invalid amount: ${param.transferAmount}`); + if (!isValidNanoAmount(param.transferAmount)) throw new Error(`Invalid amount: ${param.transferAmount}`); let body; if (param.payload) body = param.payload; else if (param.comment) body = createCommentPayloadBase64(param.comment); @@ -33236,7 +33236,7 @@ var init_ton = __esmMin((() => { normalizedHash }; } catch (error) { - log$22.error("Failed to send transaction", { error }); + log$23.error("Failed to send transaction", { error }); if (error instanceof WalletKitError) throw error; if (error?.message?.includes("Ledger device")) throw new WalletKitError(ERROR_CODES.LEDGER_DEVICE_ERROR, "Ledger device error", error); throw error; @@ -33352,7 +33352,7 @@ async function wrapWalletInterface(wallet) { } }); return newProxy; } -var log$21, Initializer; +var log$22, Initializer; var init_Initializer = __esmMin((() => { init_types$2(); init_storage(); @@ -33367,7 +33367,7 @@ var init_Initializer = __esmMin((() => { init_ton(); init_jetton$1(); init_nft(); - log$21 = globalLogger.createChild("Initializer"); + log$22 = globalLogger.createChild("Initializer"); Initializer = class { config; networkManager; @@ -33383,12 +33383,12 @@ var init_Initializer = __esmMin((() => { */ async initialize(options, networkManager) { try { - log$21.info("Initializing TonWalletKit..."); + log$22.info("Initializing TonWalletKit..."); this.networkManager = networkManager; const storage = this.initializeStorage(options); const { walletManager, sessionManager, bridgeManager, eventRouter, eventProcessor } = await this.initializeManagers(options, storage); const { requestProcessor } = this.initializeProcessors(sessionManager, bridgeManager, walletManager); - log$21.info("TonWalletKit initialized successfully"); + log$22.info("TonWalletKit initialized successfully"); return { walletManager, sessionManager, @@ -33399,7 +33399,7 @@ var init_Initializer = __esmMin((() => { eventProcessor }; } catch (error) { - log$21.error("Failed to initialize TonWalletKit", { error }); + log$22.error("Failed to initialize TonWalletKit", { error }); throw error; } } @@ -33435,9 +33435,9 @@ var init_Initializer = __esmMin((() => { const bridgeManager = new BridgeManager(options?.walletManifest, options?.bridge, sessionManager, storage, eventStore, eventRouter, options, this.eventEmitter, this.analyticsManager); eventRouter.setBridgeManager(bridgeManager); bridgeManager.start().then(() => { - log$21.info("Bridge manager started successfully"); + log$22.info("Bridge manager started successfully"); }).catch((e) => { - log$21.error("Could not start bridge manager", { error: e?.toString?.() }); + log$22.error("Could not start bridge manager", { error: e?.toString?.() }); }); const eventProcessor = new StorageEventProcessor(options?.eventProcessor, eventStore, DEFAULT_DURABLE_EVENTS_CONFIG, walletManager, sessionManager, eventRouter, this.eventEmitter); return { @@ -33459,7 +33459,7 @@ var init_Initializer = __esmMin((() => { */ async cleanup(components) { try { - log$21.info("Cleaning up TonWalletKit components..."); + log$22.info("Cleaning up TonWalletKit components..."); if (components.eventProcessor) { components.eventProcessor.stopRecoveryLoop(); await components.eventProcessor.clearRegisteredWallets(); @@ -33467,9 +33467,9 @@ var init_Initializer = __esmMin((() => { } if (components.bridgeManager) await components.bridgeManager.close(); if (components.eventRouter) components.eventRouter.clearCallbacks(); - log$21.info("TonWalletKit cleanup completed"); + log$22.info("TonWalletKit cleanup completed"); } catch (error) { - log$21.error("Error during cleanup", { error }); + log$22.error("Error during cleanup", { error }); } } }; @@ -33485,19 +33485,19 @@ function isTonAddress(address) { function createCacheKey(network, address) { return `${network.chainId}:${address}`; } -var import_dist$15, log$20, TON_ADDRESS, TON_INFO, JettonsManager; +var import_dist$15, log$21, GRAM_ADDRESS, TON_INFO, JettonsManager; var init_JettonsManager = __esmMin((() => { import_dist$15 = require_dist$1(); init_index_min(); init_Logger(); init_jettons(); init_utils$2(); - log$20 = globalLogger.createChild("JettonsManager"); - TON_ADDRESS = "TON"; + log$21 = globalLogger.createChild("JettonsManager"); + GRAM_ADDRESS = "TON"; TON_INFO = { - address: TON_ADDRESS, - name: "TON", - symbol: "TON", + address: GRAM_ADDRESS, + name: "Gram", + symbol: "GRAM", description: "The Open Network native token", decimals: 9, totalSupply: "5000000000000000000", @@ -33519,13 +33519,13 @@ var init_JettonsManager = __esmMin((() => { ttl: 1e3 * 60 * 10 }); for (const network of this.networkManager.getConfiguredNetworks()) this.addTonToCache(network); - log$20.info("JettonsManager initialized", { cacheSize }); + log$21.info("JettonsManager initialized", { cacheSize }); } /** - * Add TON native token to cache for a specific network + * Add GRAM native token to cache for a specific network */ addTonToCache(network) { - const cacheKey = createCacheKey(network, TON_ADDRESS); + const cacheKey = createCacheKey(network, GRAM_ADDRESS); this.cache.set(cacheKey, TON_INFO); } /** @@ -33540,19 +33540,19 @@ var init_JettonsManager = __esmMin((() => { const cacheKey = this.normalizedCacheKey(targetNetwork, jettonAddress); const cachedInfo = this.cache.get(cacheKey); if (cachedInfo) { - log$20.debug("Jetton info found in cache", { + log$21.debug("Jetton info found in cache", { jettonAddress, network: targetNetwork }); return cachedInfo; } - log$20.debug("Jetton info not found in cache", { + log$21.debug("Jetton info not found in cache", { jettonAddress, network: targetNetwork }); const address = asMaybeAddressFriendly(jettonAddress); if (!address) { - log$20.error("Invalid jetton address format", { + log$21.error("Invalid jetton address format", { jettonAddress, network: targetNetwork }); @@ -33587,7 +33587,7 @@ var init_JettonsManager = __esmMin((() => { } return null; } catch (error) { - log$20.error("Error getting jetton info", { + log$21.error("Error getting jetton info", { error, jettonAddress, network: targetNetwork @@ -33606,7 +33606,7 @@ var init_JettonsManager = __esmMin((() => { const targetNetwork = network; try { const apiClient = this.networkManager.getClient(targetNetwork); - log$20.debug("Getting address jettons", { + log$21.debug("Getting address jettons", { userAddress, network: targetNetwork, offset, @@ -33620,13 +33620,13 @@ var init_JettonsManager = __esmMin((() => { if (!response.jettons) return []; const addressJettons = []; for (const item of response.jettons) addressJettons.push(item); - log$20.debug("Retrieved address jettons", { + log$21.debug("Retrieved address jettons", { count: addressJettons.length, network: targetNetwork }); return addressJettons; } catch (error) { - log$20.error("Failed to get address jettons", { + log$21.error("Failed to get address jettons", { error, userAddress, network: targetNetwork @@ -33650,14 +33650,14 @@ var init_JettonsManager = __esmMin((() => { uri: emulationInfo.extra.uri }; this.cache.set(cacheKey, jettonInfo); - log$20.debug("Added jetton info from emulation to cache", { + log$21.debug("Added jetton info from emulation to cache", { jettonAddress, network, name: jettonInfo.name, symbol: jettonInfo.symbol }); } catch (error) { - log$20.error("Error adding jetton from emulation", { + log$21.error("Error adding jetton from emulation", { error, jettonAddress, network @@ -33674,7 +33674,7 @@ var init_JettonsManager = __esmMin((() => { if (!addressMetadata.is_indexed || !addressMetadata.token_info) continue; const jettonMasterInfo = addressMetadata.token_info.find((info) => typeof info === "object" && info !== null && "type" in info && info.type === "jetton_masters"); if (jettonMasterInfo) { - log$20.debug("Adding jetton from emulation metadata", { + log$21.debug("Adding jetton from emulation metadata", { jettonAddress, network }); @@ -33682,12 +33682,12 @@ var init_JettonsManager = __esmMin((() => { addedCount++; } } - if (addedCount > 0) log$20.info("Added jettons from emulation metadata", { + if (addedCount > 0) log$21.info("Added jettons from emulation metadata", { addedCount, network }); } catch (error) { - log$20.error("Error adding jettons from emulation metadata", { + log$21.error("Error adding jettons from emulation metadata", { error, network }); @@ -33697,7 +33697,7 @@ var init_JettonsManager = __esmMin((() => { * Normalize jetton address for consistent caching */ normalizedCacheKey(network, address) { - if (isTonAddress(address)) return createCacheKey(network, TON_ADDRESS); + if (isTonAddress(address)) return createCacheKey(network, GRAM_ADDRESS); return createCacheKey(network, import_dist$15.Address.parse(address).toString()); } /** @@ -33728,11 +33728,11 @@ var init_JettonsManager = __esmMin((() => { if (network) { for (const key of this.cache.keys()) if (key.startsWith(`${network.chainId}:`)) this.cache.delete(key); this.addTonToCache(network); - log$20.info("Jetton cache cleared for network", { network }); + log$21.info("Jetton cache cleared for network", { network }); } else { this.cache.clear(); for (const net of this.networkManager.getConfiguredNetworks()) this.addTonToCache(net); - log$20.info("Jetton cache cleared for all networks"); + log$21.info("Jetton cache cleared for all networks"); } } }; @@ -33892,12 +33892,12 @@ var init_DefiManager = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/defi/swap/SwapManager.js -var log$19, SwapManager; +var log$20, SwapManager; var init_SwapManager = __esmMin((() => { init_errors$2(); init_Logger(); init_DefiManager(); - log$19 = globalLogger.createChild("SwapManager"); + log$20 = globalLogger.createChild("SwapManager"); SwapManager = class extends DefiManager { constructor(createFactoryContext) { super(createFactoryContext); @@ -33909,7 +33909,7 @@ var init_SwapManager = __esmMin((() => { * @returns Promise resolving to swap quote */ async getQuote(params, providerId) { - log$19.debug("Getting swap quote", { + log$20.debug("Getting swap quote", { fromToken: params.from, toToken: params.to, amount: params.amount, @@ -33918,14 +33918,14 @@ var init_SwapManager = __esmMin((() => { }); try { const quote = await this.getProvider(providerId || this.defaultProviderId).getQuote(params); - log$19.debug("Received swap quote", { + log$20.debug("Received swap quote", { fromAmount: quote.fromAmount, toAmount: quote.toAmount, priceImpact: quote.priceImpact }); return quote; } catch (error) { - log$19.error("Failed to get swap quote", { + log$20.error("Failed to get swap quote", { error, params }); @@ -33939,16 +33939,16 @@ var init_SwapManager = __esmMin((() => { */ async buildSwapTransaction(params) { const providerId = params.quote.providerId || this.defaultProviderId; - log$19.debug("Building swap transaction", { + log$20.debug("Building swap transaction", { providerId, userAddress: params.userAddress }); try { const transaction = await this.getProvider(providerId).buildSwapTransaction(params); - log$19.debug("Built swap transaction", params.quote); + log$20.debug("Built swap transaction", params.quote); return transaction; } catch (error) { - log$19.error("Failed to build swap transaction", { + log$20.error("Failed to build swap transaction", { error, params }); @@ -33999,12 +33999,12 @@ var init_errors$1 = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/defi/staking/StakingManager.js -var log$18, StakingManager; +var log$19, StakingManager; var init_StakingManager = __esmMin((() => { init_errors$1(); init_Logger(); init_DefiManager(); - log$18 = globalLogger.createChild("StakingManager"); + log$19 = globalLogger.createChild("StakingManager"); StakingManager = class extends DefiManager { constructor(createFactoryContext) { super(createFactoryContext); @@ -34015,13 +34015,13 @@ var init_StakingManager = __esmMin((() => { * @param providerId - Optional provider id to use */ async getQuote(params, providerId) { - log$18.debug("Getting staking quote", params); + log$19.debug("Getting staking quote", params); try { const quote = await this.getProvider(providerId).getQuote(params); - log$18.debug("Received staking quote", quote); + log$19.debug("Received staking quote", quote); return quote; } catch (error) { - log$18.error("Failed to get staking quote", { + log$19.error("Failed to get staking quote", { error, params }); @@ -34029,16 +34029,16 @@ var init_StakingManager = __esmMin((() => { } } /** - * Stake TON using a provider + * Stake GRAM using a provider * @param params - Staking parameters * @param providerId - Optional provider id to use */ async buildStakeTransaction(params, providerId) { - log$18.debug("Building staking transaction", params); + log$19.debug("Building staking transaction", params); try { return await this.getProvider(providerId).buildStakeTransaction(params); } catch (error) { - log$18.error("Failed to build staking transaction", { + log$19.error("Failed to build staking transaction", { error, params }); @@ -34052,7 +34052,7 @@ var init_StakingManager = __esmMin((() => { * @param providerId - Optional provider id to use */ async getStakedBalance(userAddress, network, providerId) { - log$18.debug("Getting staking balance", { + log$19.debug("Getting staking balance", { userAddress, network, provider: providerId || this.defaultProviderId @@ -34060,7 +34060,7 @@ var init_StakingManager = __esmMin((() => { try { return await this.getProvider(providerId).getStakedBalance(userAddress, network); } catch (error) { - log$18.error("Failed to get staking balance", { + log$19.error("Failed to get staking balance", { error, userAddress, network @@ -34074,14 +34074,14 @@ var init_StakingManager = __esmMin((() => { * @param providerId - Optional provider id to use */ async getStakingProviderInfo(network, providerId) { - log$18.debug("Getting staking info", { + log$19.debug("Getting staking info", { network, provider: providerId || this.defaultProviderId }); try { return await this.getProvider(providerId).getStakingProviderInfo(network); } catch (error) { - log$18.error("Failed to get staking info", { + log$19.error("Failed to get staking info", { error, network }); @@ -34094,14 +34094,14 @@ var init_StakingManager = __esmMin((() => { * @param providerId - Optional provider id to use */ getStakingProviderMetadata(network, providerId) { - log$18.debug("Getting staking metadata", { + log$19.debug("Getting staking metadata", { network, provider: providerId || this.defaultProviderId }); try { return this.getProvider(providerId).getStakingProviderMetadata(network); } catch (error) { - log$18.error("Failed to get staking metadata", { + log$19.error("Failed to get staking metadata", { error, network }); @@ -34110,7 +34110,7 @@ var init_StakingManager = __esmMin((() => { } createError(message, code, details) { const errorCode = Object.values(StakingErrorCode).includes(code) ? code : StakingErrorCode.InvalidParams; - log$18.error(message, { + log$19.error(message, { code, details }); @@ -34161,12 +34161,12 @@ var init_errors = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/defi/gasless/GaslessManager.js -var log$17, GaslessManager; +var log$18, GaslessManager; var init_GaslessManager = __esmMin((() => { init_Logger(); init_DefiManager(); init_errors(); - log$17 = globalLogger.createChild("GaslessManager"); + log$18 = globalLogger.createChild("GaslessManager"); GaslessManager = class extends DefiManager { constructor(createFactoryContext) { super(createFactoryContext); @@ -34176,11 +34176,11 @@ var init_GaslessManager = __esmMin((() => { */ async getMetadata(providerId) { const selectedProviderId = providerId ?? this.defaultProviderId; - log$17.debug("Getting gasless provider metadata", { providerId: selectedProviderId }); + log$18.debug("Getting gasless provider metadata", { providerId: selectedProviderId }); try { return await this.getProvider(selectedProviderId).getMetadata(); } catch (error) { - log$17.error("Failed to get gasless provider metadata", { error }); + log$18.error("Failed to get gasless provider metadata", { error }); throw error; } } @@ -34192,14 +34192,14 @@ var init_GaslessManager = __esmMin((() => { async getConfig(network, providerId) { const provider = this.getProvider(providerId ?? this.defaultProviderId); const targetNetwork = network ?? provider.getSupportedNetworks()[0]; - log$17.debug("Getting gasless config", { + log$18.debug("Getting gasless config", { network: targetNetwork?.chainId, providerId: providerId ?? this.defaultProviderId }); try { return await provider.getConfig(targetNetwork); } catch (error) { - log$17.error("Failed to get gasless config", { error }); + log$18.error("Failed to get gasless config", { error }); throw error; } } @@ -34207,7 +34207,7 @@ var init_GaslessManager = __esmMin((() => { * Quote fees and obtain relayer-wrapped messages for signing. */ async getQuote(params, providerId) { - log$17.debug("Quoting gasless transaction", { + log$18.debug("Quoting gasless transaction", { network: params.network.chainId, walletAddress: params.walletAddress, feeAsset: params.feeAsset, @@ -34217,7 +34217,7 @@ var init_GaslessManager = __esmMin((() => { try { return await this.getProvider(providerId ?? this.defaultProviderId).getQuote(params); } catch (error) { - log$17.error("Failed to quote gasless transaction", { + log$18.error("Failed to quote gasless transaction", { error, params }); @@ -34228,14 +34228,14 @@ var init_GaslessManager = __esmMin((() => { * Submit a signed transaction BoC to the relayer. */ async sendTransaction(params, providerId) { - log$17.debug("Sending gasless transaction", { + log$18.debug("Sending gasless transaction", { network: params.network.chainId, providerId: providerId ?? this.defaultProviderId }); try { return await this.getProvider(providerId ?? this.defaultProviderId).sendTransaction(params); } catch (error) { - log$17.error("Failed to send gasless transaction", { error }); + log$18.error("Failed to send gasless transaction", { error }); throw error; } } @@ -34253,10 +34253,10 @@ var init_gasless = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/core/EventEmitter.js -var log$16, EventEmitter; +var log$17, EventEmitter; var init_EventEmitter = __esmMin((() => { init_Logger(); - log$16 = globalLogger.createChild("EventEmitter"); + log$17 = globalLogger.createChild("EventEmitter"); EventEmitter = class { listeners = {}; /** @@ -34267,7 +34267,7 @@ var init_EventEmitter = __esmMin((() => { const eventListeners = this.listeners[eventName]; if (!eventListeners) this.listeners[eventName] = new Set([listener]); else eventListeners.add(listener); - log$16.debug("Event listener added", { + log$17.debug("Event listener added", { eventName: String(eventName), totalListeners: this.listeners[eventName]?.size }); @@ -34311,10 +34311,10 @@ var init_EventEmitter = __esmMin((() => { removeAllListeners(eventName) { if (eventName) { delete this.listeners[eventName]; - log$16.debug("All listeners removed for event", { eventName: String(eventName) }); + log$17.debug("All listeners removed for event", { eventName: String(eventName) }); } else { this.listeners = {}; - log$16.debug("All event listeners cleared"); + log$17.debug("All event listeners cleared"); } } /** @@ -34333,12 +34333,12 @@ var init_EventEmitter = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/streaming/StreamingManager.js -var log$15, StreamingManager; +var log$16, StreamingManager; var init_StreamingManager = __esmMin((() => { init_Logger(); init_utils$2(); init_factory$2(); - log$15 = globalLogger.createChild("StreamingManager"); + log$16 = globalLogger.createChild("StreamingManager"); StreamingManager = class { createFactoryContext; providers = /* @__PURE__ */ new Map(); @@ -34354,7 +34354,7 @@ var init_StreamingManager = __esmMin((() => { const provider = resolveProvider(input, this.createFactoryContext()); const networkId = String(provider.network.chainId); if (this.providers.has(networkId)) { - log$15.warn(`Provider for network ${networkId} is already registered. Overriding.`); + log$16.warn(`Provider for network ${networkId} is already registered. Overriding.`); this.providerConnectionUnsubs.get(networkId)?.(); this.providers.get(networkId)?.disconnect(); } @@ -34605,13 +34605,13 @@ function pascalToKebab(value) { var init_utils$1 = __esmMin((() => {})); //#endregion //#region ../walletkit/dist/esm/analytics/AnalyticsManager.js -var log$14, AnalyticsManager; +var log$15, AnalyticsManager; var init_AnalyticsManager = __esmMin((() => { init_Logger(); init_swagger(); init_utils$1(); init_utils$2(); - log$14 = globalLogger.createChild("AnalyticsManager"); + log$15 = globalLogger.createChild("AnalyticsManager"); AnalyticsManager = class AnalyticsManager { api; baseEvent; @@ -34675,12 +34675,12 @@ var init_AnalyticsManager = __esmMin((() => { }; if (this.appInfo?.getLocale) enhancedEvent.locale = this.appInfo.getLocale(); if (this.appInfo?.getCurrentUserId) enhancedEvent.user_id = this.appInfo.getCurrentUserId(); - log$14.debug("Analytics event emitted", { event: enhancedEvent }); + log$15.debug("Analytics event emitted", { event: enhancedEvent }); this.events.push(enhancedEvent); if (this.events.length > this.maxQueueSize) { const removed = this.events.length - this.maxQueueSize; this.events = this.events.slice(removed); - log$14.warn("Analytics queue overflow, dropped oldest events", { count: removed }); + log$15.warn("Analytics queue overflow, dropped oldest events", { count: removed }); } if (this.events.length >= this.maxBatchSize) { this.flush(); @@ -34701,10 +34701,10 @@ var init_AnalyticsManager = __esmMin((() => { const eventsToSend = this.extractEventsToSend(); try { await this.processEventsBatch(eventsToSend); - log$14.debug("Analytics events sent successfully"); + log$15.debug("Analytics events sent successfully"); } catch (error) { this.restoreEvents(eventsToSend); - log$14.error("Failed to send analytics events", { error }); + log$15.error("Failed to send analytics events", { error }); } finally { this.isProcessing = false; this.scheduleNextFlushIfNeeded(); @@ -34722,7 +34722,7 @@ var init_AnalyticsManager = __esmMin((() => { return eventsToSend; } async processEventsBatch(eventsToSend) { - log$14.debug("Sending analytics events", { count: eventsToSend.length }); + log$15.debug("Sending analytics events", { count: eventsToSend.length }); try { const response = await this.sendEvents(eventsToSend); this.handleResponse(response); @@ -34744,7 +34744,7 @@ var init_AnalyticsManager = __esmMin((() => { if (this.events.length > this.maxQueueSize) { const removed = this.events.length - this.maxQueueSize; this.events = this.events.slice(0, this.maxQueueSize); - log$14.warn("Analytics queue overflow after restore, dropped oldest events", { count: removed }); + log$15.warn("Analytics queue overflow after restore, dropped oldest events", { count: removed }); } } scheduleNextFlushIfNeeded() { @@ -34763,7 +34763,7 @@ var init_AnalyticsManager = __esmMin((() => { return status === AnalyticsManager.HTTP_STATUS.TOO_MANY_REQUESTS; } handleClientError(status, statusText) { - log$14.error("Analytics API client error", { + log$15.error("Analytics API client error", { status, statusText }); @@ -35563,7 +35563,7 @@ var init_BaseApiClient = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/clients/toncenter/ApiClientToncenter.js -var import_dist$13, log$13, MAX_ACCOUNT_STATES_BATCH$1, ApiClientToncenter; +var import_dist$13, log$14, MAX_ACCOUNT_STATES_BATCH$1, ApiClientToncenter; var init_ApiClientToncenter = __esmMin((() => { import_dist$13 = require_dist$1(); init_base64(); @@ -35582,7 +35582,7 @@ var init_ApiClientToncenter = __esmMin((() => { init_utils(); init_TonClientError(); init_utils$2(); - log$13 = globalLogger.createChild("ApiClientToncenter"); + log$14 = globalLogger.createChild("ApiClientToncenter"); MAX_ACCOUNT_STATES_BATCH$1 = 100; ApiClientToncenter = class extends BaseApiClient { constructor(config = {}) { @@ -35730,7 +35730,7 @@ var init_ApiClientToncenter = __esmMin((() => { const fulfilledResult = results.find((result) => result.status === "fulfilled"); if (fulfilledResult) return fulfilledResult.value; results.forEach((result) => { - if (result.status === "rejected") log$13.error("Error fetching trace", { error: result.reason }); + if (result.status === "rejected") log$14.error("Error fetching trace", { error: result.reason }); }); throw new Error("Failed to fetch trace"); } @@ -35741,7 +35741,7 @@ var init_ApiClientToncenter = __esmMin((() => { }, void 0, void 0, (err) => err instanceof TonClientError ? err.status !== 422 : true); if (response?.traces?.length > 0) return response; } catch (error) { - log$13.error("Error fetching pending trace", { error }); + log$14.error("Error fetching pending trace", { error }); } throw new Error("Failed to fetch pending trace"); } @@ -35870,13 +35870,13 @@ var init_toncenter$1 = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/core/NetworkManager.js -var log$12, KitNetworkManager; +var log$13, KitNetworkManager; var init_NetworkManager = __esmMin((() => { init_toncenter$1(); init_Logger(); init_errors$4(); init_models(); - log$12 = globalLogger.createChild("NetworkManager"); + log$13 = globalLogger.createChild("NetworkManager"); KitNetworkManager = class { clients = /* @__PURE__ */ new Map(); constructor(options) { @@ -35889,7 +35889,7 @@ var init_NetworkManager = __esmMin((() => { initializeClients(options) { const networks = options.networks; if (!networks) { - log$12.warn("No networks configured in TonWalletKitOptions"); + log$13.warn("No networks configured in TonWalletKitOptions"); return; } for (const [chainId, networkConfig] of Object.entries(networks)) { @@ -35897,7 +35897,7 @@ var init_NetworkManager = __esmMin((() => { if (!networkConfig) continue; const client = this.createClient(network, networkConfig.apiClient, options); this.clients.set(network.chainId, client); - log$12.info("Initialized network client", { chainId }); + log$13.info("Initialized network client", { chainId }); } } /** @@ -35953,7 +35953,7 @@ var init_NetworkManager = __esmMin((() => { */ setClient(network, client) { this.clients.set(network.chainId, client); - log$12.info("Added/updated network client", { network }); + log$13.info("Added/updated network client", { network }); } }; })); @@ -35967,7 +35967,7 @@ function parseEmbeddedRequestFromReqParam(reqParam) { try { return toEmbeddedRequest(decodeEmbeddedRequestParam(reqParam)); } catch (error) { - log$11.warn("Failed to parse embedded request req parameter", { error }); + log$12.warn("Failed to parse embedded request req parameter", { error }); return; } } @@ -35993,20 +35993,20 @@ function toEmbeddedRequest(parsed) { }; } default: - log$11.warn("Unknown embedded request method", { method: parsed.method }); + log$12.warn("Unknown embedded request method", { method: parsed.method }); return; } } -var log$11; +var log$12; var init_embeddedRequest = __esmMin((() => { init_esm$2(); init_internal(); init_Logger(); - log$11 = globalLogger.createChild("embeddedRequestParser"); + log$12 = globalLogger.createChild("embeddedRequestParser"); })); //#endregion //#region ../walletkit/dist/esm/core/TonWalletKit.js -var import_dist$12, log$10, TonWalletKit$1; +var import_dist$12, log$11, TonWalletKit$1; var init_TonWalletKit = __esmMin((() => { import_dist$12 = require_dist$1(); init_esm$2(); @@ -36027,7 +36027,7 @@ var init_TonWalletKit = __esmMin((() => { init_NetworkManager(); init_utils$2(); init_embeddedRequest(); - log$10 = globalLogger.createChild("TonWalletKit"); + log$11 = globalLogger.createChild("TonWalletKit"); TonWalletKit$1 = class { walletManager; sessionManager; @@ -36068,7 +36068,7 @@ var init_TonWalletKit = __esmMin((() => { this.gaslessManager = new GaslessManager(() => this.createFactoryContext()); this.eventEmitter.on("restoreConnection", async ({ payload: event }) => { if (!event.domain) { - log$10.error("Domain is required for restore connection"); + log$11.error("Domain is required for restore connection"); return this.sendErrorConnectResponse(event); } const sessions = await this.sessionManager.getSessions({ @@ -36078,12 +36078,12 @@ var init_TonWalletKit = __esmMin((() => { }); const session = sessions.length > 0 ? sessions[0] : void 0; if (!session) { - log$10.error("Session not found for domain", { domain: event.domain }); + log$11.error("Session not found for domain", { domain: event.domain }); return this.sendErrorConnectResponse(event); } const wallet = session.walletId ? this.walletManager?.getWallet(session.walletId) : void 0; if (!wallet) { - log$10.error("Wallet not found for session", { walletId: session.walletId }); + log$11.error("Wallet not found for session", { walletId: session.walletId }); return this.sendErrorConnectResponse(event); } const walletAddress = wallet.getAddress(); @@ -36137,7 +36137,7 @@ var init_TonWalletKit = __esmMin((() => { await this.eventProcessor.startProcessing(); this.isInitialized = true; } catch (error) { - log$10.error("TonWalletKit initialization failed", { error: error?.toString() }); + log$11.error("TonWalletKit initialization failed", { error: error?.toString() }); throw error; } } @@ -36167,7 +36167,7 @@ var init_TonWalletKit = __esmMin((() => { const walletId = wallet.getWalletId(); await this.eventProcessor.startProcessing(walletId); } catch (error) { - log$10.error("Failed to start event processing for wallet", { + log$11.error("Failed to start event processing for wallet", { walletAddress: wallet.getAddress(), error }); @@ -36187,7 +36187,7 @@ var init_TonWalletKit = __esmMin((() => { } getWallets() { if (!this.isInitialized) { - log$10.warn("TonWalletKit not yet initialized, returning empty array"); + log$11.warn("TonWalletKit not yet initialized, returning empty array"); return []; } return this.walletManager.getWallets(); @@ -36197,7 +36197,7 @@ var init_TonWalletKit = __esmMin((() => { */ getWallet(walletId) { if (!this.isInitialized) { - log$10.warn("TonWalletKit not yet initialized, returning undefined"); + log$11.warn("TonWalletKit not yet initialized, returning undefined"); return; } return this.walletManager.getWallet(walletId); @@ -36257,7 +36257,7 @@ var init_TonWalletKit = __esmMin((() => { payload: {} }, sessionCrypto), 10, 100); } catch (error) { - log$10.error("Failed to send disconnect to bridge", { + log$11.error("Failed to send disconnect to bridge", { sessionId, error }); @@ -36267,7 +36267,7 @@ var init_TonWalletKit = __esmMin((() => { if (sessionId) try { await removeSession(sessionId); } catch (error) { - log$10.error("Failed to remove session", { + log$11.error("Failed to remove session", { sessionId, error }); @@ -36277,7 +36277,7 @@ var init_TonWalletKit = __esmMin((() => { if (sessions.length > 0) for (const session of sessions) try { await removeSession(session.sessionId); } catch (error) { - log$10.error("Failed to remove session", { + log$11.error("Failed to remove session", { sessionId: session.sessionId, error }); @@ -36351,7 +36351,7 @@ var init_TonWalletKit = __esmMin((() => { const bridgeEvent = this.parseBridgeConnectEventFromUrl(url); return await new ConnectHandler(() => {}, this.config, this.analyticsManager).handle(bridgeEvent); } catch (error) { - log$10.error("Failed to create connection event from URL", { + log$11.error("Failed to create connection event from URL", { error, url }); @@ -36368,7 +36368,7 @@ var init_TonWalletKit = __esmMin((() => { const bridgeEvent = this.parseBridgeConnectEventFromUrl(url); await this.eventRouter.routeEvent(bridgeEvent); } catch (error) { - log$10.error("Failed to handle TON Connect URL", { + log$11.error("Failed to handle TON Connect URL", { error, url }); @@ -36412,7 +36412,7 @@ var init_TonWalletKit = __esmMin((() => { const params = {}; for (const [key, value] of parsedUrl.searchParams.entries()) params[key] = value; if (!params.v || !params.id || !params.r) { - log$10.warn("Missing required TON Connect URL parameters"); + log$11.warn("Missing required TON Connect URL parameters"); return null; } return { @@ -36424,7 +36424,7 @@ var init_TonWalletKit = __esmMin((() => { ...params }; } catch (error) { - log$10.error("Failed to parse TON Connect URL", { + log$11.error("Failed to parse TON Connect URL", { error, url }); @@ -36451,7 +36451,7 @@ var init_TonWalletKit = __esmMin((() => { domain: "" }; if (params.e) if (this.config.deviceInfo?.features.some((feature) => typeof feature === "object" && feature.name === "EmbeddedRequest")) bridgeEvent.embeddedRequest = parseEmbeddedRequestFromReqParam(params.e); - else log$10.warn("Embedded request feature is not supported in features, but we received request with embedded request payload", { features: this.config.deviceInfo?.features }); + else log$11.warn("Embedded request feature is not supported in features, but we received request with embedded request payload", { features: this.config.deviceInfo?.features }); return bridgeEvent; } async approveConnectRequest(event, response) { @@ -36802,9 +36802,9 @@ var init_map_nft_items = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/clients/tonapi/mappers/map-methods.js -var hexBocToBase64, decimalToInt257Hex, mapTonApiGetMethodArgs, mapTonApiTvmStackRecord; +var hexBocToBase64$1, decimalToInt257Hex, mapTonApiGetMethodArgs, mapTonApiTvmStackRecord; var init_map_methods = __esmMin((() => { - hexBocToBase64 = (hex) => { + hexBocToBase64$1 = (hex) => { return Buffer.from(hex, "hex").toString("base64"); }; decimalToInt257Hex = (value) => { @@ -36865,11 +36865,11 @@ var init_map_methods = __esmMin((() => { }; case "cell": return { type: "cell", - value: hexBocToBase64(item.cell) + value: hexBocToBase64$1(item.cell) }; case "slice": return { type: "slice", - value: hexBocToBase64(item.slice || item.cell) + value: hexBocToBase64$1(item.slice || item.cell) }; case "tuple": return { type: "tuple", @@ -37456,7 +37456,7 @@ var init_map_masterchain_info = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/clients/tonapi/ApiClientTonApi.js -var import_dist$10, log$9, MAX_ACCOUNT_STATES_BATCH, ApiClientTonApi; +var import_dist$10, log$10, MAX_ACCOUNT_STATES_BATCH, ApiClientTonApi; var init_ApiClientTonApi = __esmMin((() => { import_dist$10 = require_dist$1(); init_models(); @@ -37475,7 +37475,7 @@ var init_ApiClientTonApi = __esmMin((() => { init_map_traces(); init_map_events(); init_map_masterchain_info(); - log$9 = globalLogger.createChild("ApiClientTonApi"); + log$10 = globalLogger.createChild("ApiClientTonApi"); MAX_ACCOUNT_STATES_BATCH = 100; ApiClientTonApi = class extends BaseApiClient { constructor(config = {}) { @@ -37497,7 +37497,7 @@ var init_ApiClientTonApi = __esmMin((() => { return this.network; } async getAccountState(address, seqno) { - if (typeof seqno === "number") log$9.warn(`getAccountState: seqno=${seqno} is ignored — TonApi /v2/accounts endpoint does not support historical state queries.`); + if (typeof seqno === "number") log$10.warn(`getAccountState: seqno=${seqno} is ignored — TonApi /v2/accounts endpoint does not support historical state queries.`); try { return mapAccountState(await this.getJson(`/v2/blockchain/accounts/${address}`), address); } catch (e) { @@ -37806,7 +37806,7 @@ var init_actions = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/contracts/w5/WalletV5R1Adapter.js -var import_dist$6, import_dist$7, log$8, defaultWalletIdV5R1, WalletV5R1Adapter$1; +var import_dist$6, import_dist$7, log$9, defaultWalletIdV5R1, WalletV5R1Adapter$1; var init_WalletV5R1Adapter = __esmMin((() => { import_dist$6 = require_dist$1(); import_dist$7 = require_dist$1(); @@ -37821,7 +37821,7 @@ var init_WalletV5R1Adapter = __esmMin((() => { init_base64(); init_tonProof(); init_walletId(); - log$8 = globalLogger.createChild("WalletV5R1Adapter"); + log$9 = globalLogger.createChild("WalletV5R1Adapter"); defaultWalletIdV5R1 = 2147483409; WalletV5R1Adapter$1 = class WalletV5R1Adapter$1 { signer; @@ -37938,7 +37938,7 @@ var init_WalletV5R1Adapter = __esmMin((() => { try { return await this.walletContract.seqno; } catch (error) { - log$8.warn("Failed to get seqno", { error }); + log$9.warn("Failed to get seqno", { error }); throw error; } } @@ -37949,7 +37949,7 @@ var init_WalletV5R1Adapter = __esmMin((() => { try { return this.walletContract.walletId; } catch (error) { - log$8.warn("Failed to get wallet ID", { error }); + log$9.warn("Failed to get wallet ID", { error }); const walletId = this.config.walletId; return new WalletV5R1Id({ subwalletNumber: typeof walletId === "bigint" ? Number(walletId) : walletId || 0 }); } @@ -37961,7 +37961,7 @@ var init_WalletV5R1Adapter = __esmMin((() => { try { return (await this.client.getAccountState(asAddressFriendly(this.walletContract.address))).status === "active"; } catch (error) { - log$8.warn("Failed to check deployment status", { error }); + log$9.warn("Failed to check deployment status", { error }); return false; } } @@ -37993,13 +37993,13 @@ var init_WalletV5R1Adapter = __esmMin((() => { if (message.payload) try { msg.body = import_dist$6.Cell.fromBase64(message.payload); } catch (error) { - log$8.warn("Failed to load payload", { error }); + log$9.warn("Failed to load payload", { error }); throw WalletKitError.fromError(ERROR_CODES.CONTRACT_VALIDATION_FAILED, "Failed to parse transaction payload", error); } if (message.stateInit) try { msg.init = (0, import_dist$6.loadStateInit)(import_dist$6.Cell.fromBase64(message.stateInit).asSlice()); } catch (error) { - log$8.warn("Failed to load state init", { error }); + log$9.warn("Failed to load state init", { error }); throw WalletKitError.fromError(ERROR_CODES.CONTRACT_VALIDATION_FAILED, "Failed to parse state init", error); } return new ActionSendMsg(import_dist$6.SendMode.PAY_GAS_SEPARATELY + import_dist$6.SendMode.IGNORE_ERRORS, msg); @@ -38020,7 +38020,7 @@ var init_WalletV5R1Adapter = __esmMin((() => { auth_signed_internal: 1936289396 }; const opcode = options.authType === "internal" ? Opcodes.auth_signed_internal : Opcodes.auth_signed; - log$8.debug("createBodyV5 signing with opcode", { + log$9.debug("createBodyV5 signing with opcode", { authType: options.authType, opcode: `0x${opcode.toString(16)}` }); @@ -38079,14 +38079,14 @@ var init_WalletV5R1Adapter = __esmMin((() => { function walletV5ConfigToCell(config) { return (0, import_dist$5.beginCell)().storeBit(config.signatureAllowed).storeUint(config.seqno, 32).storeUint(config.walletId, 32).storeUint(config.publicKey, 256).storeDict(config.extensions, import_dist$5.Dictionary.Keys.BigUint(256), import_dist$5.Dictionary.Values.BigInt(1)).endCell(); } -var import_dist$5, log$7, Opcodes, WalletV5R1Id, WalletV5; +var import_dist$5, log$8, Opcodes, WalletV5R1Id, WalletV5; var init_WalletV5R1 = __esmMin((() => { import_dist$5 = require_dist$1(); init_WalletV5R1Adapter(); init_tvmStack(); init_utils$2(); init_Logger(); - log$7 = globalLogger.createChild("WalletV5R1"); + log$8 = globalLogger.createChild("WalletV5R1"); Opcodes = { action_send_msg: 247711853, action_set_code: 2907562126, @@ -38183,7 +38183,7 @@ var init_WalletV5R1 = __esmMin((() => { if (dataCell.bits.length < 33) return 0; return dataCell.asSlice().skip(1).loadUint(32); } catch (error) { - log$7.error("Failed to get seqno", { error }); + log$8.error("Failed to get seqno", { error }); return 0; } }); @@ -38214,12 +38214,12 @@ var init_WalletV5R1 = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/contracts/v4r2/WalletV4R2.js -var import_dist$4, log$6, WalletV4R2; +var import_dist$4, log$7, WalletV4R2; var init_WalletV4R2 = __esmMin((() => { import_dist$4 = require_dist$1(); init_tvmStack(); init_utils$2(); - log$6 = { error: (_message, _data) => {} }; + log$7 = { error: (_message, _data) => {} }; WalletV4R2 = class WalletV4R2 { address; init; @@ -38271,7 +38271,7 @@ var init_WalletV4R2 = __esmMin((() => { if (parsedStack[0]?.type === "int") return Number(parsedStack[0].value); else throw new Error("Stack is not an int"); } catch (error) { - log$6.error("Failed to get seqno", { error }); + log$7.error("Failed to get seqno", { error }); return 0; } } @@ -38292,7 +38292,7 @@ var init_WalletV4R2 = __esmMin((() => { if (parsedStack[0]?.type === "int") return Number(parsedStack[0].value); else throw new Error("Stack is not an int"); } catch (error) { - log$6.error("Failed to get subwallet id", { error }); + log$7.error("Failed to get subwallet id", { error }); return this.subwalletId; } } @@ -38333,7 +38333,7 @@ var init_constants = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/contracts/v4r2/WalletV4R2Adapter.js -var import_dist$2, log$5, WalletV4R2Adapter$1; +var import_dist$2, log$6, WalletV4R2Adapter$1; var init_WalletV4R2Adapter = __esmMin((() => { import_dist$2 = require_dist$1(); init_WalletV4R2(); @@ -38346,7 +38346,7 @@ var init_WalletV4R2Adapter = __esmMin((() => { init_Logger(); init_walletId(); init_utils$2(); - log$5 = globalLogger.createChild("WalletV4R2Adapter"); + log$6 = globalLogger.createChild("WalletV4R2Adapter"); WalletV4R2Adapter$1 = class WalletV4R2Adapter$1 { signer; config; @@ -38453,7 +38453,7 @@ var init_WalletV4R2Adapter = __esmMin((() => { }); return (0, import_dist$2.beginCell)().store((0, import_dist$2.storeMessage)(ext)).endCell().toBoc().toString("base64"); } catch (error) { - log$5.warn("Failed to get signed send transaction", { error }); + log$6.warn("Failed to get signed send transaction", { error }); throw error; } } @@ -38480,7 +38480,7 @@ var init_WalletV4R2Adapter = __esmMin((() => { try { return await this.walletContract.getSeqno(); } catch (error) { - log$5.warn("Failed to get seqno", { error }); + log$6.warn("Failed to get seqno", { error }); throw error; } } @@ -38491,7 +38491,7 @@ var init_WalletV4R2Adapter = __esmMin((() => { try { return await this.walletContract.getSubwalletId(); } catch (error) { - log$5.warn("Failed to get subwallet ID", { error }); + log$6.warn("Failed to get subwallet ID", { error }); return this.config.walletId ?? 698983191; } } @@ -38502,7 +38502,7 @@ var init_WalletV4R2Adapter = __esmMin((() => { try { return (await this.client.getAccountState(asAddressFriendly(this.walletContract.address))).status === "active"; } catch (error) { - log$5.warn("Failed to check deployment status", { error }); + log$6.warn("Failed to check deployment status", { error }); return false; } } @@ -38768,11 +38768,11 @@ var init_map_jettons = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/streaming/WebsocketStreamingProvider.js -var log$4, WebsocketStreamingProvider; +var log$5, WebsocketStreamingProvider; var init_WebsocketStreamingProvider = __esmMin((() => { init_Logger(); init_address$1(); - log$4 = globalLogger.createChild("WebsocketStreamingProvider"); + log$5 = globalLogger.createChild("WebsocketStreamingProvider"); WebsocketStreamingProvider = class WebsocketStreamingProvider { type = "streaming"; ws = null; @@ -38865,7 +38865,7 @@ var init_WebsocketStreamingProvider = __esmMin((() => { } this.isConnected = false; if (wasConnected) this.emitConnectionChange(false); - log$4.info("WebsocketStreamingProvider disconnected"); + log$5.info("WebsocketStreamingProvider disconnected"); } checkClose() { if (this.closeCheckTimeout) clearTimeout(this.closeCheckTimeout); @@ -38893,16 +38893,16 @@ var init_WebsocketStreamingProvider = __esmMin((() => { openConnection() { this.stopReconnect(); const url = this.getUrl(); - log$4.info("Connecting to WebSocket", { url: url.replace(/api_key=[^&]+/, "api_key=***") }); + log$5.info("Connecting to WebSocket", { url: url.replace(/api_key=[^&]+/, "api_key=***") }); try { this.ws = new WebSocket(url); } catch (error) { - log$4.error("WebSocket creation failed", { error }); + log$5.error("WebSocket creation failed", { error }); this.scheduleReconnect(); return; } this.ws.onopen = () => { - log$4.info("WebSocket connected"); + log$5.info("WebSocket connected"); this.isConnected = true; this.reconnectAttempts = 0; this.fullResync(); @@ -38911,13 +38911,13 @@ var init_WebsocketStreamingProvider = __esmMin((() => { }; this.ws.onmessage = this.onMessage.bind(this); this.ws.onerror = (error) => { - log$4.error("WebSocket error", { + log$5.error("WebSocket error", { readyState: this.ws?.readyState, error }); }; this.ws.onclose = () => { - log$4.info("WebSocket closed"); + log$5.info("WebSocket closed"); this.isConnected = false; this.stopPing(); this.ws = null; @@ -38952,7 +38952,7 @@ var init_WebsocketStreamingProvider = __esmMin((() => { this.reconnectAttempts++; const delays = WebsocketStreamingProvider.RECONNECT_DELAYS; const delayMs = delays[Math.min(this.reconnectAttempts - 1, delays.length - 1)]; - log$4.info(`Scheduling reconnect in ${delayMs}ms (attempt ${this.reconnectAttempts})`); + log$5.info(`Scheduling reconnect in ${delayMs}ms (attempt ${this.reconnectAttempts})`); this.reconnectTimeout = setTimeout(() => { this.reconnectTimeout = null; this.openConnection(); @@ -38975,7 +38975,7 @@ var init_WebsocketStreamingProvider = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/streaming/TonStreamingV2BaseProvider.js -var log$3, STREAMING_V2_WS_PATH, TonStreamingV2BaseProvider; +var log$4, STREAMING_V2_WS_PATH, TonStreamingV2BaseProvider; var init_TonStreamingV2BaseProvider = __esmMin((() => { init_index_min(); init_Logger(); @@ -38988,7 +38988,7 @@ var init_TonStreamingV2BaseProvider = __esmMin((() => { init_map_transactions(); init_map_jettons(); init_WebsocketStreamingProvider(); - log$3 = globalLogger.createChild("TonStreamingV2"); + log$4 = globalLogger.createChild("TonStreamingV2"); STREAMING_V2_WS_PATH = "/api/streaming/v2/ws"; TonStreamingV2BaseProvider = class extends WebsocketStreamingProvider { providerId; @@ -39030,7 +39030,7 @@ var init_TonStreamingV2BaseProvider = __esmMin((() => { }; } onWatch(type, id) { - log$3.info("onWatch triggered", { + log$4.info("onWatch triggered", { type, id, isConnected: this.isConnected, @@ -39039,7 +39039,7 @@ var init_TonStreamingV2BaseProvider = __esmMin((() => { this.requestSync(); } onUnwatch(type, id) { - log$3.info("onUnwatch triggered", { + log$4.info("onUnwatch triggered", { type, id, isConnected: this.isConnected, @@ -39052,7 +39052,7 @@ var init_TonStreamingV2BaseProvider = __esmMin((() => { clearTimeout(this.syncTimer); this.syncTimer = null; } - log$3.info("fullResync triggered", { + log$4.info("fullResync triggered", { isConnected: this.isConnected, readyState: this.ws?.readyState }); @@ -39075,7 +39075,7 @@ var init_TonStreamingV2BaseProvider = __esmMin((() => { addresses: Array.from(this.lastAddresses) }); this.lastAddresses.clear(); - log$3.info("Cleared all subscriptions", { msgId }); + log$4.info("Cleared all subscriptions", { msgId }); } return; } @@ -39092,7 +39092,7 @@ var init_TonStreamingV2BaseProvider = __esmMin((() => { ...request }); this.lastAddresses = addresses; - log$3.info("Sent monolithic subscription", { + log$4.info("Sent monolithic subscription", { msgId, types: Array.from(types), addressCount: addresses.size @@ -39102,7 +39102,7 @@ var init_TonStreamingV2BaseProvider = __esmMin((() => { try { const msg = JSON.parse(event.data); const m = msg; - log$3.debug("Streaming v2 WS received message:", m); + log$4.debug("Streaming v2 WS received message:", m); if (m.status === "subscribed" || m.status === "pong") return; if (isAccountStateNotification(msg)) { const update = mapBalance(msg); @@ -39110,7 +39110,7 @@ var init_TonStreamingV2BaseProvider = __esmMin((() => { return; } if (isTraceInvalidatedNotification(msg)) { - log$3.debug("Trace invalidated", { hash: msg.trace_external_hash_norm }); + log$4.debug("Trace invalidated", { hash: msg.trace_external_hash_norm }); const entry = this.traceCache.get(msg.trace_external_hash_norm); if (entry) { entry.accounts.forEach((account) => { @@ -39131,7 +39131,7 @@ var init_TonStreamingV2BaseProvider = __esmMin((() => { const finalityScore = this.getFinalityScore(msg.finality); const entry = this.traceCache.get(msg.trace_external_hash_norm); if (entry && finalityScore < entry.score) { - log$3.debug("Ignoring transactions notification due to lower finality", { + log$4.debug("Ignoring transactions notification due to lower finality", { hash: msg.trace_external_hash_norm, msgFinality: msg.finality, cachedScore: entry.score @@ -39160,7 +39160,7 @@ var init_TonStreamingV2BaseProvider = __esmMin((() => { return; } } catch (err) { - log$3.warn("Failed to parse WebSocket message", { error: err }); + log$4.warn("Failed to parse WebSocket message", { error: err }); } } requestSync() { @@ -39928,11 +39928,14 @@ async function initTonWalletKit(config, deps) { if (type === "tonapi") apiClient = new ApiClientTonApi({ endpoint: netConfig.apiClientConfiguration?.url, apiKey: netConfig.apiClientConfiguration?.key, + timeout: netConfig.apiClientConfiguration?.timeout, network: netConfig.network }); else if (type === "toncenter") apiClient = new ApiClientToncenter({ endpoint: netConfig.apiClientConfiguration?.url, - apiKey: netConfig.apiClientConfiguration?.key + apiKey: netConfig.apiClientConfiguration?.key, + timeout: netConfig.apiClientConfiguration?.timeout, + network: netConfig.network }); else apiClient = netConfig.apiClientConfiguration; networksConfig[netConfig.network.chainId] = { apiClient }; @@ -40364,6 +40367,24 @@ async function getWalletAddress(args) { async function getWalletNetwork(args) { return wallet(args.walletId, "getNetwork"); } +async function getWalletPublicKey(args) { + return wallet(args.walletId, "getPublicKey"); +} +async function getSignedSignMessage(args) { + return wallet(args.walletId, "getSignedSignMessage", args.request); +} +async function getWalletStateInit(args) { + return wallet(args.walletId, "getStateInit"); +} +async function getSignedSendTransaction(args) { + return wallet(args.walletId, "getSignedSendTransaction", args.input, { fakeSignature: args.fakeSignature ?? false }); +} +async function getSignedSignData(args) { + return wallet(args.walletId, "getSignedSignData", args.input, { fakeSignature: args.fakeSignature ?? false }); +} +async function getSignedTonProof(args) { + return wallet(args.walletId, "getSignedTonProof", args.input, { fakeSignature: args.fakeSignature ?? false }); +} async function removeWallet(args) { return kit("removeWallet", args.walletId); } @@ -40597,11 +40618,11 @@ var getJettonWalletAddress = (args) => walletCall("getJettonWalletAddress", args init_models(); init_units(); var CACHE_TIMEOUT = 3e4; -var DEFAULT_METADATA = { +var DEFAULT_METADATA$1 = { [Network.mainnet().chainId]: { name: "Tonstakers", stakeToken: { - ticker: "TON", + ticker: "GRAM", decimals: 9, address: "ton" }, @@ -40621,7 +40642,7 @@ var DEFAULT_METADATA = { [Network.testnet().chainId]: { name: "Tonstakers", stakeToken: { - ticker: "TON", + ticker: "GRAM", decimals: 9, address: "ton" }, @@ -40775,13 +40796,13 @@ init_StakingProvider(); init_errors$1(); init_ApiClientTonApi(); init_units(); -var log$2 = globalLogger.createChild("TonStakersStakingProvider"); +var log$3 = globalLogger.createChild("TonStakersStakingProvider"); /** * TonStakersStakingProvider - Staking provider for the Tonstakers liquid staking protocol. * * This provider implements all staking operations. It supports: -* - Stake: Deposit TON to receive tsTON liquid staking tokens -* - Unstake: Burn tsTON to withdraw TON with {@link UnstakeMode} values: +* - Stake: Deposit GRAM to receive tsTON liquid staking tokens +* - Unstake: Burn tsTON to withdraw GRAM with {@link UnstakeMode} values: * - `INSTANT` – immediate withdrawal if the pool has liquidity (`fillOrKill`) * - `WHEN_AVAILABLE` – withdraw when liquidity is available (non–fill-or-kill) * - `ROUND_END` – wait until round end for the projected rate @@ -40801,7 +40822,7 @@ var TonStakersStakingProvider = class TonStakersStakingProvider extends StakingP this.cache = new StakingCache(); this.metadataByNetwork = {}; for (const [chainId, config] of Object.entries(chainConfig)) { - const defaultMetadata = DEFAULT_METADATA[chainId]; + const defaultMetadata = DEFAULT_METADATA$1[chainId]; const overrides = config.metadata ?? {}; const merged = { ...defaultMetadata, @@ -40821,7 +40842,7 @@ var TonStakersStakingProvider = class TonStakersStakingProvider extends StakingP }); this.metadataByNetwork[chainId] = merged; } - log$2.info("TonStakersStakingProvider initialized"); + log$3.info("TonStakersStakingProvider initialized"); } /** * Resolves API clients from {@link ProviderFactoryContext.networkManager} on each call. @@ -40832,7 +40853,7 @@ var TonStakersStakingProvider = class TonStakersStakingProvider extends StakingP for (const network of ctx.networkManager.getConfiguredNetworks()) { const chainId = network.chainId; const perChain = config[chainId] ?? {}; - const hasDefaultContract = !!DEFAULT_METADATA[chainId]?.contractAddress; + const hasDefaultContract = !!DEFAULT_METADATA$1[chainId]?.contractAddress; const hasCustomContract = !!perChain.metadata?.contractAddress; if (!hasDefaultContract && !hasCustomContract) continue; chainConfig[chainId] = perChain; @@ -40847,7 +40868,7 @@ var TonStakersStakingProvider = class TonStakersStakingProvider extends StakingP * @returns Quote with expected amounts and current APY (for stake direction) */ async getQuote(params) { - log$2.debug("TonStakers quote requested", { + log$3.debug("TonStakers quote requested", { direction: params.direction, amount: params.amount, userAddress: params.userAddress, @@ -40900,11 +40921,11 @@ var TonStakersStakingProvider = class TonStakersStakingProvider extends StakingP }; } /** - * Build a transaction for staking TON. + * Build a transaction for staking GRAM. * - * The stake operation sends TON to the Tonstakers pool contract + * The stake operation sends GRAM to the Tonstakers pool contract * and receives tsTON liquid staking tokens in return. - * A fee reserve of 1 TON is automatically added to the amount. + * A fee reserve of 1 GRAM is automatically added to the amount. * * @param params - Stake parameters including quote and user address * @returns Transaction request ready to be signed and sent @@ -40914,7 +40935,7 @@ var TonStakersStakingProvider = class TonStakersStakingProvider extends StakingP else return this.buildUnstakeTonTransaction(params); } async buildStakeTonTransaction(params) { - log$2.debug("TonStakers stake requested", { params }); + log$3.debug("TonStakers stake requested", { params }); if (params.quote.direction !== "stake") throw new StakingError("Invalid quote direction", StakingErrorCode.InvalidParams, { quote: params.quote }); const network = params.quote.network; const contractAddress = this.getStakingContractAddress(network); @@ -40939,7 +40960,7 @@ var TonStakersStakingProvider = class TonStakersStakingProvider extends StakingP * @returns Transaction request ready to be signed and sent */ async buildUnstakeTonTransaction(params) { - log$2.debug("TonStakers unstake requested", { + log$3.debug("TonStakers unstake requested", { amount: params.quote.amountIn, userAddress: params.userAddress }); @@ -40985,7 +41006,7 @@ var TonStakersStakingProvider = class TonStakersStakingProvider extends StakingP * @param network - Network to query (defaults to mainnet) */ async getStakedBalance(userAddress, network) { - log$2.debug("TonStakers balance requested", { + log$3.debug("TonStakers balance requested", { userAddress, network }); @@ -40997,12 +41018,12 @@ var TonStakersStakingProvider = class TonStakersStakingProvider extends StakingP try { stakedBalance = await contract.getStakedBalance(userAddress); } catch (error) { - log$2.warn("Failed to get staked balance", { error }); + log$3.warn("Failed to get staked balance", { error }); } try { instantUnstakeAvailable = await contract.getPoolBalance(); } catch (error) { - log$2.warn("Failed to get instant unstake liquidity", { error }); + log$3.warn("Failed to get instant unstake liquidity", { error }); } return { rawStakedBalance: stakedBalance, @@ -41012,7 +41033,7 @@ var TonStakersStakingProvider = class TonStakersStakingProvider extends StakingP providerId: this.providerId }; } catch (error) { - log$2.error("Failed to get balance", { + log$3.error("Failed to get balance", { error, userAddress, network @@ -41033,7 +41054,7 @@ var TonStakersStakingProvider = class TonStakersStakingProvider extends StakingP * @returns Staking info with APY and available instant liquidity */ async getStakingProviderInfo(network) { - log$2.debug("TonStakers info requested", { network }); + log$3.debug("TonStakers info requested", { network }); const targetNetwork = network ?? Network.mainnet(); const cacheKey = `staking-info:${targetNetwork.chainId}`; return await this.cache.get(cacheKey, async () => { @@ -43368,7 +43389,7 @@ function createBaseAddress() { address: "" }; } -var Address$4 = { +var Address$7 = { fromJSON(object) { return { blockchain: isSet$7(object.blockchain) ? globalThis.Number(object.blockchain) : 0, @@ -43382,7 +43403,7 @@ var Address$4 = { return obj; }, create(base) { - return Address$4.fromPartial(base ?? {}); + return Address$7.fromPartial(base ?? {}); }, fromPartial(object) { const message = createBaseAddress(); @@ -43459,15 +43480,15 @@ function createBaseSwapStep() { var SwapStep = { fromJSON(object) { return { - bidAssetAddress: isSet$6(object.bid_asset_address) ? Address$4.fromJSON(object.bid_asset_address) : void 0, - askAssetAddress: isSet$6(object.ask_asset_address) ? Address$4.fromJSON(object.ask_asset_address) : void 0, + bidAssetAddress: isSet$6(object.bid_asset_address) ? Address$7.fromJSON(object.bid_asset_address) : void 0, + askAssetAddress: isSet$6(object.ask_asset_address) ? Address$7.fromJSON(object.ask_asset_address) : void 0, chunks: globalThis.Array.isArray(object?.chunks) ? object.chunks.map((e) => SwapChunk.fromJSON(e)) : [] }; }, toJSON(message) { const obj = {}; - if (message.bidAssetAddress !== void 0) obj.bid_asset_address = Address$4.toJSON(message.bidAssetAddress); - if (message.askAssetAddress !== void 0) obj.ask_asset_address = Address$4.toJSON(message.askAssetAddress); + if (message.bidAssetAddress !== void 0) obj.bid_asset_address = Address$7.toJSON(message.bidAssetAddress); + if (message.askAssetAddress !== void 0) obj.ask_asset_address = Address$7.toJSON(message.askAssetAddress); if (message.chunks?.length) obj.chunks = message.chunks.map((e) => SwapChunk.toJSON(e)); return obj; }, @@ -43476,8 +43497,8 @@ var SwapStep = { }, fromPartial(object) { const message = createBaseSwapStep(); - message.bidAssetAddress = object.bidAssetAddress !== void 0 && object.bidAssetAddress !== null ? Address$4.fromPartial(object.bidAssetAddress) : void 0; - message.askAssetAddress = object.askAssetAddress !== void 0 && object.askAssetAddress !== null ? Address$4.fromPartial(object.askAssetAddress) : void 0; + message.bidAssetAddress = object.bidAssetAddress !== void 0 && object.bidAssetAddress !== null ? Address$7.fromPartial(object.bidAssetAddress) : void 0; + message.askAssetAddress = object.askAssetAddress !== void 0 && object.askAssetAddress !== null ? Address$7.fromPartial(object.askAssetAddress) : void 0; message.chunks = object.chunks?.map((e) => SwapChunk.fromPartial(e)) || []; return message; } @@ -43637,16 +43658,16 @@ function createBaseEscrowSettlementParams() { var EscrowSettlementParams = { fromJSON(object) { return { - contractAddress: isSet$5(object.contract_address) ? Address$4.fromJSON(object.contract_address) : void 0, - resolverAddress: isSet$5(object.resolver_address) ? Address$4.fromJSON(object.resolver_address) : void 0, + contractAddress: isSet$5(object.contract_address) ? Address$7.fromJSON(object.contract_address) : void 0, + resolverAddress: isSet$5(object.resolver_address) ? Address$7.fromJSON(object.resolver_address) : void 0, resolveTimeout: isSet$5(object.resolve_timeout) ? globalThis.Number(object.resolve_timeout) : 0, gasless: isSet$5(object.gasless) ? globalThis.Boolean(object.gasless) : false }; }, toJSON(message) { const obj = {}; - if (message.contractAddress !== void 0) obj.contract_address = Address$4.toJSON(message.contractAddress); - if (message.resolverAddress !== void 0) obj.resolver_address = Address$4.toJSON(message.resolverAddress); + if (message.contractAddress !== void 0) obj.contract_address = Address$7.toJSON(message.contractAddress); + if (message.resolverAddress !== void 0) obj.resolver_address = Address$7.toJSON(message.resolverAddress); if (message.resolveTimeout !== void 0) obj.resolve_timeout = Math.round(message.resolveTimeout); if (message.gasless !== void 0) obj.gasless = message.gasless; return obj; @@ -43656,8 +43677,8 @@ var EscrowSettlementParams = { }, fromPartial(object) { const message = createBaseEscrowSettlementParams(); - message.contractAddress = object.contractAddress !== void 0 && object.contractAddress !== null ? Address$4.fromPartial(object.contractAddress) : void 0; - message.resolverAddress = object.resolverAddress !== void 0 && object.resolverAddress !== null ? Address$4.fromPartial(object.resolverAddress) : void 0; + message.contractAddress = object.contractAddress !== void 0 && object.contractAddress !== null ? Address$7.fromPartial(object.contractAddress) : void 0; + message.resolverAddress = object.resolverAddress !== void 0 && object.resolverAddress !== null ? Address$7.fromPartial(object.resolverAddress) : void 0; message.resolveTimeout = object.resolveTimeout ?? 0; message.gasless = object.gasless ?? false; return message; @@ -43673,15 +43694,15 @@ function createBaseHtlcSettlementParams() { var HtlcSettlementParams = { fromJSON(object) { return { - contractAddress: isSet$5(object.contract_address) ? Address$4.fromJSON(object.contract_address) : void 0, - resolverAddress: isSet$5(object.resolver_address) ? Address$4.fromJSON(object.resolver_address) : void 0, + contractAddress: isSet$5(object.contract_address) ? Address$7.fromJSON(object.contract_address) : void 0, + resolverAddress: isSet$5(object.resolver_address) ? Address$7.fromJSON(object.resolver_address) : void 0, resolveTimeout: isSet$5(object.resolve_timeout) ? globalThis.Number(object.resolve_timeout) : 0 }; }, toJSON(message) { const obj = {}; - if (message.contractAddress !== void 0) obj.contract_address = Address$4.toJSON(message.contractAddress); - if (message.resolverAddress !== void 0) obj.resolver_address = Address$4.toJSON(message.resolverAddress); + if (message.contractAddress !== void 0) obj.contract_address = Address$7.toJSON(message.contractAddress); + if (message.resolverAddress !== void 0) obj.resolver_address = Address$7.toJSON(message.resolverAddress); if (message.resolveTimeout !== void 0) obj.resolve_timeout = Math.round(message.resolveTimeout); return obj; }, @@ -43690,8 +43711,8 @@ var HtlcSettlementParams = { }, fromPartial(object) { const message = createBaseHtlcSettlementParams(); - message.contractAddress = object.contractAddress !== void 0 && object.contractAddress !== null ? Address$4.fromPartial(object.contractAddress) : void 0; - message.resolverAddress = object.resolverAddress !== void 0 && object.resolverAddress !== null ? Address$4.fromPartial(object.resolverAddress) : void 0; + message.contractAddress = object.contractAddress !== void 0 && object.contractAddress !== null ? Address$7.fromPartial(object.contractAddress) : void 0; + message.resolverAddress = object.resolverAddress !== void 0 && object.resolverAddress !== null ? Address$7.fromPartial(object.resolverAddress) : void 0; message.resolveTimeout = object.resolveTimeout ?? 0; return message; } @@ -43710,10 +43731,10 @@ function createBaseQuoteRequest() { var QuoteRequest$1 = { fromJSON(object) { return { - bidAssetAddress: isSet$5(object.bid_asset_address) ? Address$4.fromJSON(object.bid_asset_address) : void 0, - askAssetAddress: isSet$5(object.ask_asset_address) ? Address$4.fromJSON(object.ask_asset_address) : void 0, + bidAssetAddress: isSet$5(object.bid_asset_address) ? Address$7.fromJSON(object.bid_asset_address) : void 0, + askAssetAddress: isSet$5(object.ask_asset_address) ? Address$7.fromJSON(object.ask_asset_address) : void 0, amount: isSet$5(object.amount) ? QuoteRequest_AmountOneOf.fromJSON(object.amount) : void 0, - referrerAddress: isSet$5(object.referrer_address) ? Address$4.fromJSON(object.referrer_address) : void 0, + referrerAddress: isSet$5(object.referrer_address) ? Address$7.fromJSON(object.referrer_address) : void 0, referrerFeeBps: isSet$5(object.referrer_fee_bps) ? globalThis.Number(object.referrer_fee_bps) : 0, settlementMethods: globalThis.Array.isArray(object?.settlement_methods) ? object.settlement_methods.map((e) => settlementMethodFromJSON(e)) : [], settlementParams: isSet$5(object.settlement_params) ? RequestSettlementParams.fromJSON(object.settlement_params) : void 0 @@ -43721,10 +43742,10 @@ var QuoteRequest$1 = { }, toJSON(message) { const obj = {}; - if (message.bidAssetAddress !== void 0) obj.bid_asset_address = Address$4.toJSON(message.bidAssetAddress); - if (message.askAssetAddress !== void 0) obj.ask_asset_address = Address$4.toJSON(message.askAssetAddress); + if (message.bidAssetAddress !== void 0) obj.bid_asset_address = Address$7.toJSON(message.bidAssetAddress); + if (message.askAssetAddress !== void 0) obj.ask_asset_address = Address$7.toJSON(message.askAssetAddress); if (message.amount !== void 0) obj.amount = QuoteRequest_AmountOneOf.toJSON(message.amount); - if (message.referrerAddress !== void 0) obj.referrer_address = Address$4.toJSON(message.referrerAddress); + if (message.referrerAddress !== void 0) obj.referrer_address = Address$7.toJSON(message.referrerAddress); if (message.referrerFeeBps !== void 0) obj.referrer_fee_bps = Math.round(message.referrerFeeBps); if (message.settlementMethods?.length) obj.settlement_methods = message.settlementMethods.map((e) => settlementMethodToJSON(e)); if (message.settlementParams !== void 0) obj.settlement_params = RequestSettlementParams.toJSON(message.settlementParams); @@ -43735,10 +43756,10 @@ var QuoteRequest$1 = { }, fromPartial(object) { const message = createBaseQuoteRequest(); - message.bidAssetAddress = object.bidAssetAddress !== void 0 && object.bidAssetAddress !== null ? Address$4.fromPartial(object.bidAssetAddress) : void 0; - message.askAssetAddress = object.askAssetAddress !== void 0 && object.askAssetAddress !== null ? Address$4.fromPartial(object.askAssetAddress) : void 0; + message.bidAssetAddress = object.bidAssetAddress !== void 0 && object.bidAssetAddress !== null ? Address$7.fromPartial(object.bidAssetAddress) : void 0; + message.askAssetAddress = object.askAssetAddress !== void 0 && object.askAssetAddress !== null ? Address$7.fromPartial(object.askAssetAddress) : void 0; message.amount = object.amount !== void 0 && object.amount !== null ? QuoteRequest_AmountOneOf.fromPartial(object.amount) : void 0; - message.referrerAddress = object.referrerAddress !== void 0 && object.referrerAddress !== null ? Address$4.fromPartial(object.referrerAddress) : void 0; + message.referrerAddress = object.referrerAddress !== void 0 && object.referrerAddress !== null ? Address$7.fromPartial(object.referrerAddress) : void 0; message.referrerFeeBps = object.referrerFeeBps ?? 0; message.settlementMethods = object.settlementMethods?.map((e) => e) || []; message.settlementParams = object.settlementParams !== void 0 && object.settlementParams !== null ? RequestSettlementParams.fromPartial(object.settlementParams) : void 0; @@ -43801,14 +43822,14 @@ var Quote = { quoteId: isSet$5(object.quote_id) ? globalThis.String(object.quote_id) : "", resolverId: isSet$5(object.resolver_id) ? globalThis.String(object.resolver_id) : "", resolverName: isSet$5(object.resolver_name) ? globalThis.String(object.resolver_name) : "", - bidAssetAddress: isSet$5(object.bid_asset_address) ? Address$4.fromJSON(object.bid_asset_address) : void 0, - askAssetAddress: isSet$5(object.ask_asset_address) ? Address$4.fromJSON(object.ask_asset_address) : void 0, + bidAssetAddress: isSet$5(object.bid_asset_address) ? Address$7.fromJSON(object.bid_asset_address) : void 0, + askAssetAddress: isSet$5(object.ask_asset_address) ? Address$7.fromJSON(object.ask_asset_address) : void 0, bidUnits: isSet$5(object.bid_units) ? globalThis.String(object.bid_units) : "", askUnits: isSet$5(object.ask_units) ? globalThis.String(object.ask_units) : "", - referrerAddress: isSet$5(object.referrer_address) ? Address$4.fromJSON(object.referrer_address) : void 0, - referrerFeeAsset: isSet$5(object.referrer_fee_asset) ? Address$4.fromJSON(object.referrer_fee_asset) : void 0, + referrerAddress: isSet$5(object.referrer_address) ? Address$7.fromJSON(object.referrer_address) : void 0, + referrerFeeAsset: isSet$5(object.referrer_fee_asset) ? Address$7.fromJSON(object.referrer_fee_asset) : void 0, referrerFeeUnits: isSet$5(object.referrer_fee_units) ? globalThis.String(object.referrer_fee_units) : "", - protocolFeeAsset: isSet$5(object.protocol_fee_asset) ? Address$4.fromJSON(object.protocol_fee_asset) : void 0, + protocolFeeAsset: isSet$5(object.protocol_fee_asset) ? Address$7.fromJSON(object.protocol_fee_asset) : void 0, protocolFeeUnits: isSet$5(object.protocol_fee_units) ? globalThis.String(object.protocol_fee_units) : "", quoteTimestamp: isSet$5(object.quote_timestamp) ? globalThis.Number(object.quote_timestamp) : 0, tradeStartDeadline: isSet$5(object.trade_start_deadline) ? globalThis.Number(object.trade_start_deadline) : 0, @@ -43822,14 +43843,14 @@ var Quote = { if (message.quoteId !== void 0) obj.quote_id = message.quoteId; if (message.resolverId !== void 0) obj.resolver_id = message.resolverId; if (message.resolverName !== void 0) obj.resolver_name = message.resolverName; - if (message.bidAssetAddress !== void 0) obj.bid_asset_address = Address$4.toJSON(message.bidAssetAddress); - if (message.askAssetAddress !== void 0) obj.ask_asset_address = Address$4.toJSON(message.askAssetAddress); + if (message.bidAssetAddress !== void 0) obj.bid_asset_address = Address$7.toJSON(message.bidAssetAddress); + if (message.askAssetAddress !== void 0) obj.ask_asset_address = Address$7.toJSON(message.askAssetAddress); if (message.bidUnits !== void 0) obj.bid_units = message.bidUnits; if (message.askUnits !== void 0) obj.ask_units = message.askUnits; - if (message.referrerAddress !== void 0) obj.referrer_address = Address$4.toJSON(message.referrerAddress); - if (message.referrerFeeAsset !== void 0) obj.referrer_fee_asset = Address$4.toJSON(message.referrerFeeAsset); + if (message.referrerAddress !== void 0) obj.referrer_address = Address$7.toJSON(message.referrerAddress); + if (message.referrerFeeAsset !== void 0) obj.referrer_fee_asset = Address$7.toJSON(message.referrerFeeAsset); if (message.referrerFeeUnits !== void 0) obj.referrer_fee_units = message.referrerFeeUnits; - if (message.protocolFeeAsset !== void 0) obj.protocol_fee_asset = Address$4.toJSON(message.protocolFeeAsset); + if (message.protocolFeeAsset !== void 0) obj.protocol_fee_asset = Address$7.toJSON(message.protocolFeeAsset); if (message.protocolFeeUnits !== void 0) obj.protocol_fee_units = message.protocolFeeUnits; if (message.quoteTimestamp !== void 0) obj.quote_timestamp = Math.round(message.quoteTimestamp); if (message.tradeStartDeadline !== void 0) obj.trade_start_deadline = Math.round(message.tradeStartDeadline); @@ -43846,14 +43867,14 @@ var Quote = { message.quoteId = object.quoteId ?? ""; message.resolverId = object.resolverId ?? ""; message.resolverName = object.resolverName ?? ""; - message.bidAssetAddress = object.bidAssetAddress !== void 0 && object.bidAssetAddress !== null ? Address$4.fromPartial(object.bidAssetAddress) : void 0; - message.askAssetAddress = object.askAssetAddress !== void 0 && object.askAssetAddress !== null ? Address$4.fromPartial(object.askAssetAddress) : void 0; + message.bidAssetAddress = object.bidAssetAddress !== void 0 && object.bidAssetAddress !== null ? Address$7.fromPartial(object.bidAssetAddress) : void 0; + message.askAssetAddress = object.askAssetAddress !== void 0 && object.askAssetAddress !== null ? Address$7.fromPartial(object.askAssetAddress) : void 0; message.bidUnits = object.bidUnits ?? ""; message.askUnits = object.askUnits ?? ""; - message.referrerAddress = object.referrerAddress !== void 0 && object.referrerAddress !== null ? Address$4.fromPartial(object.referrerAddress) : void 0; - message.referrerFeeAsset = object.referrerFeeAsset !== void 0 && object.referrerFeeAsset !== null ? Address$4.fromPartial(object.referrerFeeAsset) : void 0; + message.referrerAddress = object.referrerAddress !== void 0 && object.referrerAddress !== null ? Address$7.fromPartial(object.referrerAddress) : void 0; + message.referrerFeeAsset = object.referrerFeeAsset !== void 0 && object.referrerFeeAsset !== null ? Address$7.fromPartial(object.referrerFeeAsset) : void 0; message.referrerFeeUnits = object.referrerFeeUnits ?? ""; - message.protocolFeeAsset = object.protocolFeeAsset !== void 0 && object.protocolFeeAsset !== null ? Address$4.fromPartial(object.protocolFeeAsset) : void 0; + message.protocolFeeAsset = object.protocolFeeAsset !== void 0 && object.protocolFeeAsset !== null ? Address$7.fromPartial(object.protocolFeeAsset) : void 0; message.protocolFeeUnits = object.protocolFeeUnits ?? ""; message.quoteTimestamp = object.quoteTimestamp ?? 0; message.tradeStartDeadline = object.tradeStartDeadline ?? 0; @@ -43908,11 +43929,11 @@ function createBaseEscrowOrderListRequest() { } var EscrowOrderListRequest$1 = { fromJSON(object) { - return { traderWalletAddress: isSet$4(object.trader_wallet_address) ? Address$4.fromJSON(object.trader_wallet_address) : void 0 }; + return { traderWalletAddress: isSet$4(object.trader_wallet_address) ? Address$7.fromJSON(object.trader_wallet_address) : void 0 }; }, toJSON(message) { const obj = {}; - if (message.traderWalletAddress !== void 0) obj.trader_wallet_address = Address$4.toJSON(message.traderWalletAddress); + if (message.traderWalletAddress !== void 0) obj.trader_wallet_address = Address$7.toJSON(message.traderWalletAddress); return obj; }, create(base) { @@ -43920,7 +43941,7 @@ var EscrowOrderListRequest$1 = { }, fromPartial(object) { const message = createBaseEscrowOrderListRequest(); - message.traderWalletAddress = object.traderWalletAddress !== void 0 && object.traderWalletAddress !== null ? Address$4.fromPartial(object.traderWalletAddress) : void 0; + message.traderWalletAddress = object.traderWalletAddress !== void 0 && object.traderWalletAddress !== null ? Address$7.fromPartial(object.traderWalletAddress) : void 0; return message; } }; @@ -43956,14 +43977,14 @@ var EscrowOrderData$1 = { fromJSON(object) { return { quote: isSet$4(object.quote) ? Quote.fromJSON(object.quote) : void 0, - escrowItemAddress: isSet$4(object.escrow_item_address) ? Address$4.fromJSON(object.escrow_item_address) : void 0, + escrowItemAddress: isSet$4(object.escrow_item_address) ? Address$7.fromJSON(object.escrow_item_address) : void 0, outgoingTxHash: isSet$4(object.outgoing_tx_hash) ? globalThis.String(object.outgoing_tx_hash) : "" }; }, toJSON(message) { const obj = {}; if (message.quote !== void 0) obj.quote = Quote.toJSON(message.quote); - if (message.escrowItemAddress !== void 0) obj.escrow_item_address = Address$4.toJSON(message.escrowItemAddress); + if (message.escrowItemAddress !== void 0) obj.escrow_item_address = Address$7.toJSON(message.escrowItemAddress); if (message.outgoingTxHash !== void 0) obj.outgoing_tx_hash = message.outgoingTxHash; return obj; }, @@ -43973,7 +43994,7 @@ var EscrowOrderData$1 = { fromPartial(object) { const message = createBaseEscrowOrderData(); message.quote = object.quote !== void 0 && object.quote !== null ? Quote.fromPartial(object.quote) : void 0; - message.escrowItemAddress = object.escrowItemAddress !== void 0 && object.escrowItemAddress !== null ? Address$4.fromPartial(object.escrowItemAddress) : void 0; + message.escrowItemAddress = object.escrowItemAddress !== void 0 && object.escrowItemAddress !== null ? Address$7.fromPartial(object.escrowItemAddress) : void 0; message.outgoingTxHash = object.outgoingTxHash ?? ""; return message; } @@ -44277,7 +44298,7 @@ var SwapChunkStatus = { fromJSON(object) { return { protocol: isSet$2(object.protocol) ? globalThis.String(object.protocol) : "", - targetAddress: isSet$2(object.target_address) ? Address$4.fromJSON(object.target_address) : void 0, + targetAddress: isSet$2(object.target_address) ? Address$7.fromJSON(object.target_address) : void 0, bidUnits: isSet$2(object.bid_units) ? globalThis.String(object.bid_units) : "", expectedAskUnits: isSet$2(object.expected_ask_units) ? globalThis.String(object.expected_ask_units) : "", actualAskUnits: isSet$2(object.actual_ask_units) ? globalThis.String(object.actual_ask_units) : "", @@ -44288,7 +44309,7 @@ var SwapChunkStatus = { toJSON(message) { const obj = {}; if (message.protocol !== void 0) obj.protocol = message.protocol; - if (message.targetAddress !== void 0) obj.target_address = Address$4.toJSON(message.targetAddress); + if (message.targetAddress !== void 0) obj.target_address = Address$7.toJSON(message.targetAddress); if (message.bidUnits !== void 0) obj.bid_units = message.bidUnits; if (message.expectedAskUnits !== void 0) obj.expected_ask_units = message.expectedAskUnits; if (message.actualAskUnits !== void 0) obj.actual_ask_units = message.actualAskUnits; @@ -44302,7 +44323,7 @@ var SwapChunkStatus = { fromPartial(object) { const message = createBaseSwapChunkStatus(); message.protocol = object.protocol ?? ""; - message.targetAddress = object.targetAddress !== void 0 && object.targetAddress !== null ? Address$4.fromPartial(object.targetAddress) : void 0; + message.targetAddress = object.targetAddress !== void 0 && object.targetAddress !== null ? Address$7.fromPartial(object.targetAddress) : void 0; message.bidUnits = object.bidUnits ?? ""; message.expectedAskUnits = object.expectedAskUnits ?? ""; message.actualAskUnits = object.actualAskUnits ?? ""; @@ -44363,14 +44384,14 @@ function createBaseEscrowOrderStatus() { var EscrowOrderStatus = { fromJSON(object) { return { - targetAddress: isSet$2(object.target_address) ? Address$4.fromJSON(object.target_address) : void 0, + targetAddress: isSet$2(object.target_address) ? Address$7.fromJSON(object.target_address) : void 0, askUnits: isSet$2(object.ask_units) ? globalThis.String(object.ask_units) : "", txHash: isSet$2(object.tx_hash) ? globalThis.String(object.tx_hash) : "" }; }, toJSON(message) { const obj = {}; - if (message.targetAddress !== void 0) obj.target_address = Address$4.toJSON(message.targetAddress); + if (message.targetAddress !== void 0) obj.target_address = Address$7.toJSON(message.targetAddress); if (message.askUnits !== void 0) obj.ask_units = message.askUnits; if (message.txHash !== void 0) obj.tx_hash = message.txHash; return obj; @@ -44380,7 +44401,7 @@ var EscrowOrderStatus = { }, fromPartial(object) { const message = createBaseEscrowOrderStatus(); - message.targetAddress = object.targetAddress !== void 0 && object.targetAddress !== null ? Address$4.fromPartial(object.targetAddress) : void 0; + message.targetAddress = object.targetAddress !== void 0 && object.targetAddress !== null ? Address$7.fromPartial(object.targetAddress) : void 0; message.askUnits = object.askUnits ?? ""; message.txHash = object.txHash ?? ""; return message; @@ -44397,14 +44418,14 @@ var TrackTradeRequest$1 = { fromJSON(object) { return { quoteId: isSet$2(object.quote_id) ? globalThis.String(object.quote_id) : "", - traderWalletAddress: isSet$2(object.trader_wallet_address) ? Address$4.fromJSON(object.trader_wallet_address) : void 0, + traderWalletAddress: isSet$2(object.trader_wallet_address) ? Address$7.fromJSON(object.trader_wallet_address) : void 0, outgoingTxHash: isSet$2(object.outgoing_tx_hash) ? globalThis.String(object.outgoing_tx_hash) : "" }; }, toJSON(message) { const obj = {}; if (message.quoteId !== void 0) obj.quote_id = message.quoteId; - if (message.traderWalletAddress !== void 0) obj.trader_wallet_address = Address$4.toJSON(message.traderWalletAddress); + if (message.traderWalletAddress !== void 0) obj.trader_wallet_address = Address$7.toJSON(message.traderWalletAddress); if (message.outgoingTxHash !== void 0) obj.outgoing_tx_hash = message.outgoingTxHash; return obj; }, @@ -44414,7 +44435,7 @@ var TrackTradeRequest$1 = { fromPartial(object) { const message = createBaseTrackTradeRequest(); message.quoteId = object.quoteId ?? ""; - message.traderWalletAddress = object.traderWalletAddress !== void 0 && object.traderWalletAddress !== null ? Address$4.fromPartial(object.traderWalletAddress) : void 0; + message.traderWalletAddress = object.traderWalletAddress !== void 0 && object.traderWalletAddress !== null ? Address$7.fromPartial(object.traderWalletAddress) : void 0; message.outgoingTxHash = object.outgoingTxHash ?? ""; return message; } @@ -44500,13 +44521,13 @@ function createBaseClaimAvailable() { var ClaimAvailable = { fromJSON(object) { return { - contractAddress: isSet$2(object.contract_address) ? Address$4.fromJSON(object.contract_address) : void 0, + contractAddress: isSet$2(object.contract_address) ? Address$7.fromJSON(object.contract_address) : void 0, depositIndex: isSet$2(object.deposit_index) ? globalThis.Number(object.deposit_index) : 0 }; }, toJSON(message) { const obj = {}; - if (message.contractAddress !== void 0) obj.contract_address = Address$4.toJSON(message.contractAddress); + if (message.contractAddress !== void 0) obj.contract_address = Address$7.toJSON(message.contractAddress); if (message.depositIndex !== void 0) obj.deposit_index = Math.round(message.depositIndex); return obj; }, @@ -44515,7 +44536,7 @@ var ClaimAvailable = { }, fromPartial(object) { const message = createBaseClaimAvailable(); - message.contractAddress = object.contractAddress !== void 0 && object.contractAddress !== null ? Address$4.fromPartial(object.contractAddress) : void 0; + message.contractAddress = object.contractAddress !== void 0 && object.contractAddress !== null ? Address$7.fromPartial(object.contractAddress) : void 0; message.depositIndex = object.depositIndex ?? 0; return message; } @@ -44525,11 +44546,11 @@ function createBaseRefundAvailable() { } var RefundAvailable = { fromJSON(object) { - return { contractAddress: isSet$2(object.contract_address) ? Address$4.fromJSON(object.contract_address) : void 0 }; + return { contractAddress: isSet$2(object.contract_address) ? Address$7.fromJSON(object.contract_address) : void 0 }; }, toJSON(message) { const obj = {}; - if (message.contractAddress !== void 0) obj.contract_address = Address$4.toJSON(message.contractAddress); + if (message.contractAddress !== void 0) obj.contract_address = Address$7.toJSON(message.contractAddress); return obj; }, create(base) { @@ -44537,7 +44558,7 @@ var RefundAvailable = { }, fromPartial(object) { const message = createBaseRefundAvailable(); - message.contractAddress = object.contractAddress !== void 0 && object.contractAddress !== null ? Address$4.fromPartial(object.contractAddress) : void 0; + message.contractAddress = object.contractAddress !== void 0 && object.contractAddress !== null ? Address$7.fromPartial(object.contractAddress) : void 0; return message; } }; @@ -44706,20 +44727,20 @@ function createBaseBuildTransferRequest() { var BuildTransferRequest$1 = { fromJSON(object) { return { - sourceAddress: isSet$1(object.source_address) ? Address$4.fromJSON(object.source_address) : void 0, - destinationAddress: isSet$1(object.destination_address) ? Address$4.fromJSON(object.destination_address) : void 0, - gasExcessAddress: isSet$1(object.gas_excess_address) ? Address$4.fromJSON(object.gas_excess_address) : void 0, - refundAddress: isSet$1(object.refund_address) ? Address$4.fromJSON(object.refund_address) : void 0, + sourceAddress: isSet$1(object.source_address) ? Address$7.fromJSON(object.source_address) : void 0, + destinationAddress: isSet$1(object.destination_address) ? Address$7.fromJSON(object.destination_address) : void 0, + gasExcessAddress: isSet$1(object.gas_excess_address) ? Address$7.fromJSON(object.gas_excess_address) : void 0, + refundAddress: isSet$1(object.refund_address) ? Address$7.fromJSON(object.refund_address) : void 0, quote: isSet$1(object.quote) ? Quote.fromJSON(object.quote) : void 0, useRecommendedSlippage: isSet$1(object.use_recommended_slippage) ? globalThis.Boolean(object.use_recommended_slippage) : false }; }, toJSON(message) { const obj = {}; - if (message.sourceAddress !== void 0) obj.source_address = Address$4.toJSON(message.sourceAddress); - if (message.destinationAddress !== void 0) obj.destination_address = Address$4.toJSON(message.destinationAddress); - if (message.gasExcessAddress !== void 0) obj.gas_excess_address = Address$4.toJSON(message.gasExcessAddress); - if (message.refundAddress !== void 0) obj.refund_address = Address$4.toJSON(message.refundAddress); + if (message.sourceAddress !== void 0) obj.source_address = Address$7.toJSON(message.sourceAddress); + if (message.destinationAddress !== void 0) obj.destination_address = Address$7.toJSON(message.destinationAddress); + if (message.gasExcessAddress !== void 0) obj.gas_excess_address = Address$7.toJSON(message.gasExcessAddress); + if (message.refundAddress !== void 0) obj.refund_address = Address$7.toJSON(message.refundAddress); if (message.quote !== void 0) obj.quote = Quote.toJSON(message.quote); if (message.useRecommendedSlippage !== void 0) obj.use_recommended_slippage = message.useRecommendedSlippage; return obj; @@ -44729,10 +44750,10 @@ var BuildTransferRequest$1 = { }, fromPartial(object) { const message = createBaseBuildTransferRequest(); - message.sourceAddress = object.sourceAddress !== void 0 && object.sourceAddress !== null ? Address$4.fromPartial(object.sourceAddress) : void 0; - message.destinationAddress = object.destinationAddress !== void 0 && object.destinationAddress !== null ? Address$4.fromPartial(object.destinationAddress) : void 0; - message.gasExcessAddress = object.gasExcessAddress !== void 0 && object.gasExcessAddress !== null ? Address$4.fromPartial(object.gasExcessAddress) : void 0; - message.refundAddress = object.refundAddress !== void 0 && object.refundAddress !== null ? Address$4.fromPartial(object.refundAddress) : void 0; + message.sourceAddress = object.sourceAddress !== void 0 && object.sourceAddress !== null ? Address$7.fromPartial(object.sourceAddress) : void 0; + message.destinationAddress = object.destinationAddress !== void 0 && object.destinationAddress !== null ? Address$7.fromPartial(object.destinationAddress) : void 0; + message.gasExcessAddress = object.gasExcessAddress !== void 0 && object.gasExcessAddress !== null ? Address$7.fromPartial(object.gasExcessAddress) : void 0; + message.refundAddress = object.refundAddress !== void 0 && object.refundAddress !== null ? Address$7.fromPartial(object.refundAddress) : void 0; message.quote = object.quote !== void 0 && object.quote !== null ? Quote.fromPartial(object.quote) : void 0; message.useRecommendedSlippage = object.useRecommendedSlippage ?? false; return message; @@ -44748,16 +44769,16 @@ function createBaseBuildWithdrawalRequest() { var BuildWithdrawalRequest$1 = { fromJSON(object) { return { - sourceAddress: isSet$1(object.source_address) ? Address$4.fromJSON(object.source_address) : void 0, + sourceAddress: isSet$1(object.source_address) ? Address$7.fromJSON(object.source_address) : void 0, quoteId: isSet$1(object.quote_id) ? globalThis.String(object.quote_id) : "", - gasExcessAddress: isSet$1(object.gas_excess_address) ? Address$4.fromJSON(object.gas_excess_address) : void 0 + gasExcessAddress: isSet$1(object.gas_excess_address) ? Address$7.fromJSON(object.gas_excess_address) : void 0 }; }, toJSON(message) { const obj = {}; - if (message.sourceAddress !== void 0) obj.source_address = Address$4.toJSON(message.sourceAddress); + if (message.sourceAddress !== void 0) obj.source_address = Address$7.toJSON(message.sourceAddress); if (message.quoteId !== void 0) obj.quote_id = message.quoteId; - if (message.gasExcessAddress !== void 0) obj.gas_excess_address = Address$4.toJSON(message.gasExcessAddress); + if (message.gasExcessAddress !== void 0) obj.gas_excess_address = Address$7.toJSON(message.gasExcessAddress); return obj; }, create(base) { @@ -44765,9 +44786,9 @@ var BuildWithdrawalRequest$1 = { }, fromPartial(object) { const message = createBaseBuildWithdrawalRequest(); - message.sourceAddress = object.sourceAddress !== void 0 && object.sourceAddress !== null ? Address$4.fromPartial(object.sourceAddress) : void 0; + message.sourceAddress = object.sourceAddress !== void 0 && object.sourceAddress !== null ? Address$7.fromPartial(object.sourceAddress) : void 0; message.quoteId = object.quoteId ?? ""; - message.gasExcessAddress = object.gasExcessAddress !== void 0 && object.gasExcessAddress !== null ? Address$4.fromPartial(object.gasExcessAddress) : void 0; + message.gasExcessAddress = object.gasExcessAddress !== void 0 && object.gasExcessAddress !== null ? Address$7.fromPartial(object.gasExcessAddress) : void 0; return message; } }; @@ -45168,7 +45189,7 @@ init_errors$2(); init_Logger(); init_utils$2(); init_units(); -var log$1 = globalLogger.createChild("OmnistonSwapProvider"); +var log$2 = globalLogger.createChild("OmnistonSwapProvider"); /** * Swap provider implementation for Omniston (STON.fi) protocol * @@ -45218,7 +45239,7 @@ var OmnistonSwapProvider = class extends SwapProvider { ...this.metadata, ...config.metadata }; - log$1.info("OmnistonSwapProvider initialized", { + log$2.info("OmnistonSwapProvider initialized", { defaultSlippageBps: this.defaultSlippageBps, hasReferrer: !!this.referrerAddress }); @@ -45234,7 +45255,7 @@ var OmnistonSwapProvider = class extends SwapProvider { return this.omniston$; } async getQuote(params) { - log$1.debug("Getting Omniston quote", { + log$2.debug("Getting Omniston quote", { fromToken: params.from, toToken: params.to, amount: params.amount, @@ -45263,9 +45284,9 @@ var OmnistonSwapProvider = class extends SwapProvider { }; const quoteEvent = await new Promise((resolve, reject) => { let isSettled = false; - log$1.debug("Requesting quote", { quoteRequest }); + log$2.debug("Requesting quote", { quoteRequest }); const timeoutId = setTimeout(() => { - log$1.debug("Timeout reached"); + log$2.debug("Timeout reached"); if (!isSettled) { isSettled = true; reject(new SwapError("Quote request timed out", SwapErrorCode.NetworkError)); @@ -45274,7 +45295,7 @@ var OmnistonSwapProvider = class extends SwapProvider { }, this.quoteTimeoutMs); const unsubscribe = this.omniston.requestForQuote(quoteRequest).subscribe({ next: (event) => { - log$1.debug("Received quote event", event); + log$2.debug("Received quote event", event); if (isSettled) return; if (event.type === "noQuote") { isSettled = true; @@ -45303,14 +45324,14 @@ var OmnistonSwapProvider = class extends SwapProvider { if (quoteEvent.type !== "quoteUpdated") throw new SwapError("Quote data is missing", SwapErrorCode.InvalidQuote); const quote = quoteEvent.quote; const swapQuote = this.mapOmnistonQuoteToSwapQuote(quote, params); - log$1.debug("Received Omniston quote", { + log$2.debug("Received Omniston quote", { quoteId: quote.quoteId, bidUnits: quote.bidUnits, askUnits: quote.askUnits }); return swapQuote; } catch (error) { - log$1.error("Failed to get Omniston quote", { + log$2.error("Failed to get Omniston quote", { error, params }); @@ -45319,7 +45340,7 @@ var OmnistonSwapProvider = class extends SwapProvider { } } async buildSwapTransaction(params) { - log$1.debug("Building Omniston swap transaction", params); + log$2.debug("Building Omniston swap transaction", params); const metadata = params.quote.metadata; if (!metadata || !isOmnistonQuoteMetadata(metadata)) throw new SwapError("Invalid quote: missing Omniston quote data", SwapErrorCode.InvalidQuote); try { @@ -45348,13 +45369,13 @@ var OmnistonSwapProvider = class extends SwapProvider { })), network: params.quote.network }; - log$1.debug("Built Omniston swap transaction", { + log$2.debug("Built Omniston swap transaction", { quoteId: metadata.omnistonQuote.quoteId, transaction }); return transaction; } catch (error) { - log$1.error("Failed to build Omniston swap transaction", { + log$2.error("Failed to build Omniston swap transaction", { error, params }); @@ -45391,7 +45412,7 @@ var OmnistonSwapProvider = class extends SwapProvider { */ init_models(); /** -* Native TON identifier used by DeDust Router API +* Native GRAM identifier used by DeDust Router API */ var NATIVE_TON_MINTER = "native"; /** @@ -45434,7 +45455,7 @@ init_errors$2(); init_Logger(); init_utils$2(); init_units(); -var log = globalLogger.createChild("DeDustSwapProvider"); +var log$1 = globalLogger.createChild("DeDustSwapProvider"); /** * Default API URL for DeDust Router */ @@ -45497,7 +45518,7 @@ var DeDustSwapProvider = class extends SwapProvider { ...this.metadata, ...config.metadata }; - log.info("DeDustSwapProvider initialized", { + log$1.info("DeDustSwapProvider initialized", { apiUrl: this.apiUrl, defaultSlippageBps: this.defaultSlippageBps, hasReferral: !!this.referralAddress @@ -45510,7 +45531,7 @@ var DeDustSwapProvider = class extends SwapProvider { return [Network.mainnet()]; } async getQuote(params) { - log.debug("Getting DeDust quote", { + log$1.debug("Getting DeDust quote", { fromToken: params.from, toToken: params.to, amount: params.amount, @@ -45545,7 +45566,7 @@ var DeDustSwapProvider = class extends SwapProvider { }); if (!response.ok) { const errorText = await response.text(); - log.error("DeDust quote API error", { + log$1.error("DeDust quote API error", { status: response.status, error: errorText }); @@ -45573,7 +45594,7 @@ var DeDustSwapProvider = class extends SwapProvider { network: params.network, priceImpact: quoteResponse.price_impact ? Math.round(quoteResponse.price_impact * 100) : void 0 }; - log.debug("Received DeDust quote", { + log$1.debug("Received DeDust quote", { inAmount: quoteResponse.in_amount, outAmount: quoteResponse.out_amount, minReceived: minReceived.toString(), @@ -45581,7 +45602,7 @@ var DeDustSwapProvider = class extends SwapProvider { }); return swapQuote; } catch (error) { - log.error("Failed to get DeDust quote", { + log$1.error("Failed to get DeDust quote", { error, params }); @@ -45590,7 +45611,7 @@ var DeDustSwapProvider = class extends SwapProvider { } } async buildSwapTransaction(params) { - log.debug("Building DeDust swap transaction", params); + log$1.debug("Building DeDust swap transaction", params); const metadata = params.quote.metadata; if (!metadata || !isDeDustQuoteMetadata(metadata)) throw new SwapError("Invalid quote: missing DeDust quote data", SwapErrorCode.InvalidQuote); try { @@ -45613,7 +45634,7 @@ var DeDustSwapProvider = class extends SwapProvider { }); if (!response.ok) { const errorText = await response.text(); - log.error("DeDust swap API error", { + log$1.error("DeDust swap API error", { status: response.status, error: errorText }); @@ -45631,10 +45652,10 @@ var DeDustSwapProvider = class extends SwapProvider { })), network: params.quote.network }; - log.debug("Built DeDust swap transaction", { messageCount: transaction.messages.length }); + log$1.debug("Built DeDust swap transaction", { messageCount: transaction.messages.length }); return transaction; } catch (error) { - log.error("Failed to build DeDust swap transaction", { + log$1.error("Failed to build DeDust swap transaction", { error, params }); @@ -45745,6 +45766,385 @@ async function registerKotlinSwapProvider(args) { retainWithId(args.providerId, provider); (await getSwap()).registerProvider(provider); } +/** Static metadata returned by `TonApiGaslessProvider.getMetadata()`. */ +var DEFAULT_METADATA = { + name: "TonAPI", + url: "https://tonapi.io" +}; +//#endregion +//#region ../walletkit/dist/esm/defi/gasless/tonapi/utils.js +/** +* Copyright (c) TonTech. +* +* This source code is licensed under the MIT license found in the +* LICENSE file in the root directory of this source tree. +* +*/ +init_models(); +init_TonClientError(); +init_base64(); +init_hex(); +init_errors(); +var stripHexPrefix = (value) => { + return value.startsWith("0x") ? value.slice(2) : value; +}; +/** +* TonAPI returns BoCs as bare hex strings (no `0x` prefix); the walletkit domain +* uses base64 (`Base64String`). Re-encoding is byte-identical; `asHex` validates +* the hex first. Shared by the quote and send mappers. +*/ +var hexBocToBase64 = (hex) => { + return HexToBase64(asHex(hex.startsWith("0x") ? hex : `0x${hex}`)); +}; +var buildInternalMessageCell = (message) => { + const to = import_dist$1.Address.parse(message.address); + const value = BigInt(message.amount); + const body = message.payload ? import_dist$1.Cell.fromBase64(message.payload) : (0, import_dist$1.beginCell)().endCell(); + const init = message.stateInit ? (0, import_dist$1.loadStateInit)(import_dist$1.Cell.fromBase64(message.stateInit).beginParse()) : void 0; + return (0, import_dist$1.beginCell)().storeWritable((0, import_dist$1.storeMessageRelaxed)((0, import_dist$1.internal)({ + to, + value, + bounce: true, + body, + init + }))).endCell(); +}; +/** +* Convert an internal-message BoC (what `wallet.signMessage` returns) into an +* external message BoC that the relayer accepts for broadcast. +*/ +var internalBocToExternalMessageBoc = (internalBoc) => { + const { info, body, init } = (0, import_dist$1.loadMessageRelaxed)(import_dist$1.Cell.fromBase64(internalBoc).beginParse()); + if (info.type !== "internal") throw new GaslessError("Signed message must be an internal message", GaslessErrorCode.SendFailed); + return (0, import_dist$1.beginCell)().storeWritable((0, import_dist$1.storeMessage)((0, import_dist$1.external)({ + to: info.dest, + init: init ?? void 0, + body + }))).endCell(); +}; +/** +* Reconstruct a `Network` instance from a chainId string. Used to map +* `Object.keys(chainConfig)` back to `Network` objects. +*/ +var networkFromChainId = (chainId) => { + switch (chainId) { + case Network.mainnet().chainId: return Network.mainnet(); + case Network.testnet().chainId: return Network.testnet(); + case Network.tetra().chainId: return Network.tetra(); + default: return Network.custom(chainId); + } +}; +/** +* If this function returns true — that means we should retry request +* We should only retry false if we are sure that retrying will not help (for example, wrong input data, abort) +*/ +var isTransientError = (error) => { + if (error instanceof TonClientError) { + if (error.status >= 500 || error.status < 400) return true; + if (error.status === 408 || error.status === 429) return true; + return false; + } + if (typeof error === "object" && error !== null && "name" in error) { + if (error.name === "AbortError") return false; + } + return true; +}; +//#endregion +//#region ../walletkit/dist/esm/defi/gasless/tonapi/mappers/map-gasless-config.js +init_address$1(); +/** +* Wire → domain: map TonAPI's `/v2/gasless/config` response to `GaslessConfig`. +* Bundles both the relay address (for jetton-transfer `responseDestination`) +* and the assets the relayer accepts as fee payment. +*/ +var mapGaslessConfig = (raw) => ({ + relayAddress: asAddressFriendly(raw.relay_address), + supportedAssets: raw.gas_jettons.map((jetton) => ({ address: asAddressFriendly(jetton.master_id) })) +}); +//#endregion +//#region ../walletkit/dist/esm/defi/gasless/tonapi/mappers/map-gasless-error.js +init_errors(); +var mapTonApiGaslessError = (error, fallbackCode, fallbackMessage) => { + if (error instanceof GaslessError) return error; + return new GaslessError(error instanceof Error ? error.message : fallbackMessage, fallbackCode, error); +}; +//#endregion +//#region ../walletkit/dist/esm/defi/gasless/tonapi/mappers/map-gasless-quote.js +/** +* Copyright (c) TonTech. +* +* This source code is licensed under the MIT license found in the +* LICENSE file in the root directory of this source tree. +* +*/ +init_address$1(); +init_hex(); +/** +* Domain → wire: build the JSON body for `POST /v2/gasless/estimate/{master_id}`. +* +* Caller messages are encoded as hex BoCs of internal messages (TonAPI's wire format). +*/ +var buildGaslessQuoteRequest = (params) => ({ + wallet_address: import_dist$1.Address.parse(params.walletAddress).toRawString(), + wallet_public_key: stripHexPrefix(asHex(params.walletPublicKey)), + messages: params.messages.map((message) => ({ boc: buildInternalMessageCell(message).toBoc().toString("hex") })) +}); +/** +* Wire → domain: map the TonAPI estimate response to `GaslessQuote`. +* +* Hex BoCs in `payload` / `state_init` are converted back to base64. `network` +* is threaded in from the request — the relayer does not echo it. +*/ +var mapGaslessQuote = (raw, network) => ({ + network, + messages: raw.messages.map((message) => ({ + address: asAddressFriendly(message.address), + amount: message.amount, + payload: message.payload ? hexBocToBase64(message.payload) : void 0, + stateInit: message.state_init ? hexBocToBase64(message.state_init) : void 0 + })), + fee: raw.commission, + validUntil: raw.valid_until, + from: asAddressFriendly(raw.from) +}); +//#endregion +//#region ../walletkit/dist/esm/defi/gasless/tonapi/mappers/map-gasless-send.js +init_hex(); +init_getNormalizedExtMessageHash(); +init_errors(); +/** +* Domain → wire: build the JSON body for `POST /v2/gasless/send`. +* +* The signed internal-message BoC (returned by `wallet.signMessage`) is +* unwrapped into an external message BoC that the relayer can broadcast. +*/ +var buildGaslessSendRequest = (params) => ({ + wallet_public_key: stripHexPrefix(asHex(params.walletPublicKey)), + boc: internalBocToExternalMessageBoc(params.internalBoc).toBoc().toString("hex") +}); +/** +* Wire → domain: turn TonAPI's `GaslessTx` response into a `SendTransactionResponse`. +* +* Despite the OpenAPI description ("Normalized hash of the external message"), +* `external` is the **full hex BoC** of the external-in message the relayer +* actually broadcast — verified against live TonAPI. Crucially it is the +* *relayer's own* external message (addressed to the relayer's wallet), which +* differs from the external message we submit (addressed to the user's wallet), +* so it is the only source for the real on-chain hash. We re-encode it to base64 +* and normalize via `getNormalizedExtMessageHash` to yield the same +* `{ boc, normalizedBoc, normalizedHash }` triple as `wallet.sendTransaction`. +*/ +var mapGaslessSend = (raw) => { + if (!raw.external) throw new GaslessError("Relayer did not return the broadcasted external message", GaslessErrorCode.SendFailed, { protocolName: raw.protocol_name }); + try { + const boc = hexBocToBase64(raw.external); + const { hash: normalizedHash, boc: normalizedBoc } = getNormalizedExtMessageHash(boc); + return { + boc, + normalizedBoc, + normalizedHash + }; + } catch (cause) { + throw new GaslessError("Relayer `external` is not a parseable external-message BoC — TonAPI response format may have changed.", GaslessErrorCode.SendFailed, { + external: raw.external, + cause + }); + } +}; +//#endregion +//#region ../walletkit/dist/esm/defi/gasless/tonapi/TonApiGaslessProvider.js +/** +* Copyright (c) TonTech. +* +* This source code is licensed under the MIT license found in the +* LICENSE file in the root directory of this source tree. +* +*/ +init_index_min(); +init_ApiClientTonApi(); +init_Logger(); +init_retry(); +init_errors(); +init_GaslessProvider(); +var log = globalLogger.createChild("TonApiGaslessProvider"); +/** +* Gasless provider implementation backed by the public TonAPI REST API. +* +* Implements the flow documented at https://docs.tonapi.io/tonapi/rest-api/gasless. +* +* @example +* ```typescript +* import { Network } from '@ton/walletkit'; +* import { createTonApiGaslessProvider } from '@ton/walletkit/gasless/tonapi'; +* +* const provider = createTonApiGaslessProvider({ +* chains: { +* [Network.mainnet().chainId]: { apiKey: process.env.TON_API_KEY }, +* }, +* }); +* +* kit.gasless.registerProvider(provider); +* ``` +*/ +var TonApiGaslessProvider = class TonApiGaslessProvider extends GaslessProvider { + providerId; + chainConfig; + clients = {}; + sendRetries; + sendRetryDelayMs; + quoteRetries; + quoteRetryDelayMs; + configCacheTtlMs; + configCache; + /** + * @internal Use {@link createTonApiGaslessProvider} (AppKit) or {@link TonApiGaslessProvider.createFromContext}. + */ + constructor(chainConfig, options) { + super(); + this.chainConfig = chainConfig; + this.providerId = options.providerId ?? "tonapi"; + this.sendRetries = options.sendRetries ?? 5; + this.sendRetryDelayMs = options.sendRetryDelayMs ?? 1e3; + this.quoteRetries = options.quoteRetries ?? 5; + this.quoteRetryDelayMs = options.quoteRetryDelayMs ?? 1e3; + this.configCacheTtlMs = options.configCacheTtlMs ?? 3e5; + if (this.configCacheTtlMs > 0) this.configCache = new U({ + max: Math.max(1, Object.keys(chainConfig).length), + ttl: this.configCacheTtlMs, + fetchMethod: (_chainId, _stale, { context }) => this.fetchConfig(context) + }); + log.info("TonApiGaslessProvider initialized", { + providerId: this.providerId, + chains: Object.keys(this.chainConfig) + }); + } + /** + * Build a provider that serves every network the kit was configured with. + * + * If `config.chains` is provided, only those chains are registered (and they + * must intersect with the kit's configured networks). Otherwise every + * configured network gets a default TonAPI client. + */ + static createFromContext(ctx, config = {}) { + const configuredChains = new Set(ctx.networkManager.getConfiguredNetworks().map((n) => n.chainId)); + const chainConfig = {}; + if (config.chains) for (const [chainId, perChain] of Object.entries(config.chains)) { + if (!configuredChains.has(chainId)) { + log.warn("Skipping TonApi gasless chain not configured in the kit", { chainId }); + continue; + } + chainConfig[chainId] = perChain; + } + else for (const chainId of configuredChains) chainConfig[chainId] = {}; + if (Object.keys(chainConfig).length === 0) throw new Error("createTonApiGaslessProvider: no eligible networks (configure at least one network in the kit, or pass `chains` matching a configured network)"); + return new TonApiGaslessProvider(chainConfig, config); + } + getSupportedNetworks() { + return Object.keys(this.chainConfig).map(networkFromChainId); + } + async getMetadata() { + return DEFAULT_METADATA; + } + async getConfig(network) { + if (!this.configCache) return this.fetchConfig(network); + const value = await this.configCache.fetch(network.chainId, { context: network }); + if (!value) throw new GaslessError("Gasless config cache returned no value", GaslessErrorCode.ConfigFailed); + return value; + } + async fetchConfig(network) { + try { + return mapGaslessConfig(await this.getClient(network).getJson("/v2/gasless/config")); + } catch (error) { + log.error("Failed to fetch gasless config", { + error, + chainId: network.chainId + }); + throw mapTonApiGaslessError(error, GaslessErrorCode.ConfigFailed, "Failed to fetch gasless config"); + } + } + async getQuote(params) { + if (!params.feeAsset) throw new GaslessError("TonAPI gasless requires `feeAsset` (jetton master). Free / sponsored modes are not supported by this provider.", GaslessErrorCode.UnsupportedOperation, { network: params.network.chainId }); + const masterId = import_dist$1.Address.parse(params.feeAsset).toRawString(); + const body = buildGaslessQuoteRequest(params); + try { + const http = this.getClient(params.network); + return mapGaslessQuote(await CallForSuccess(() => http.postJson(`/v2/gasless/estimate/${masterId}`, body), this.quoteRetries + 1, this.quoteRetryDelayMs, isTransientError), params.network); + } catch (error) { + log.error("Failed to quote gasless transaction", { + error, + params + }); + throw mapTonApiGaslessError(error, GaslessErrorCode.QuoteFailed, "Failed to quote gasless transaction"); + } + } + async sendTransaction(params) { + const body = buildGaslessSendRequest(params); + const http = this.getClient(params.network); + try { + return { + ...mapGaslessSend(await CallForSuccess(() => http.postJson("/v2/gasless/send", body), this.sendRetries + 1, this.sendRetryDelayMs, isTransientError)), + internalBoc: params.internalBoc + }; + } catch (error) { + log.error("Failed to send gasless transaction", { + error, + chainId: params.network.chainId + }); + throw mapTonApiGaslessError(error, GaslessErrorCode.SendFailed, "Failed to send gasless transaction"); + } + } + getClient(network) { + const chainId = network.chainId; + const perChain = this.chainConfig[chainId]; + if (!perChain) throw new GaslessError(`TonApi gasless not configured for chain ${chainId}`, GaslessErrorCode.UnsupportedOperation, { + chainId, + configured: Object.keys(this.chainConfig) + }); + if (!this.clients[chainId]) this.clients[chainId] = new ApiClientTonApi({ + network, + endpoint: perChain.endpoint, + apiKey: perChain.apiKey + }); + return this.clients[chainId]; + } +}; +//#endregion +//#region src/api/gasless.ts +async function getGasless() { + const instance = await getKit(); + if (!instance.gasless) throw new Error("Gasless is not configured"); + return instance.gasless; +} +async function createTonApiGaslessProvider(args) { + const instance = await getKit(); + const provider = TonApiGaslessProvider.createFromContext(instance.createFactoryContext(), args?.config ?? {}); + retainWithId(provider.providerId, provider); + return { providerId: provider.providerId }; +} +async function registerGaslessProvider(args) { + (await getGasless()).registerProvider(get(args.providerId)); +} +async function setDefaultGaslessProvider(args) { + (await getGasless()).setDefaultProvider(args.providerId); +} +async function getRegisteredGaslessProviders() { + return { providerIds: (await getGasless()).getProviders().map((provider) => provider.providerId) }; +} +async function hasGaslessProvider(args) { + return { result: (await getGasless()).hasProvider(args.providerId) }; +} +async function getGaslessMetadata(args) { + return (await getGasless()).getMetadata(args.providerId); +} +async function getGaslessConfig(args) { + return (await getGasless()).getConfig(args.network, args.providerId); +} +async function getGaslessQuote(args) { + return (await getGasless()).getQuote(args.params, args.providerId); +} +async function gaslessSendTransaction(args) { + return (await getGasless()).sendTransaction(args.params, args.providerId); +} //#endregion //#region src/api/walletClient.ts async function walletClientSendBoc(args) { @@ -45800,6 +46200,12 @@ var api = { getWallet: getWalletById, getWalletAddress, getWalletNetwork, + getWalletPublicKey, + getWalletStateInit, + getSignedSignMessage, + getSignedSendTransaction, + getSignedSignData, + getSignedTonProof, removeWallet, getBalance, getRecentTransactions, @@ -45872,6 +46278,15 @@ var api = { getSwapQuote, buildSwapTransaction, registerKotlinSwapProvider, + createTonApiGaslessProvider, + registerGaslessProvider, + setDefaultGaslessProvider, + getRegisteredGaslessProviders, + hasGaslessProvider, + getGaslessMetadata, + getGaslessConfig, + getGaslessQuote, + gaslessSendTransaction, walletClientSendBoc, walletClientRunGetMethod, walletClientGetBalance, diff --git a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/core/TONWallet.kt b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/core/TONWallet.kt index 7e2325b9..5aff2e94 100644 --- a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/core/TONWallet.kt +++ b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/core/TONWallet.kt @@ -38,8 +38,6 @@ import kotlinx.serialization.json.Json /** * Represents a TON wallet with balance and state management. * - * Mirrors the canonical TON Wallet contract interface for cross-platform consistency. - * * Use [TONWallet.add] to create a new wallet from mnemonic data. * * Example: @@ -226,8 +224,38 @@ internal class TONWallet internal constructor( override suspend fun transferJettonTransaction(request: TONJettonsTransferRequest): TONTransactionRequest = engine.createTransferJettonTransaction(id, request) + // ── Adapter surface (inherited from TONWalletAdapter via ITONWallet) ── + + override fun identifier(): String = id + override suspend fun publicKey(): TONHex = TONHex(engine.getWalletPublicKey(id)) + override fun network(): TONNetwork = network + + override fun address(testnet: Boolean): TONUserFriendlyAddress = address + + override suspend fun stateInit(): TONBase64 = TONBase64(engine.getWalletStateInit(id)) + + override suspend fun signedSendTransaction( + input: TONTransactionRequest, + fakeSignature: Boolean?, + ): TONBase64 = TONBase64(engine.getSignedSendTransaction(id, input, fakeSignature)) + + override suspend fun signedSignMessage( + input: TONTransactionRequest, + fakeSignature: Boolean?, + ): TONBase64 = TONBase64(engine.getSignedSignMessage(id, input)) + + override suspend fun signedSignData( + input: TONPreparedSignData, + fakeSignature: Boolean?, + ): TONHex = TONHex(engine.getSignedSignData(id, input, fakeSignature)) + + override suspend fun signedTonProof( + input: TONProofMessage, + fakeSignature: Boolean?, + ): TONHex = TONHex(engine.getSignedTonProof(id, input, fakeSignature)) + override suspend fun signMessage( messages: List, validUntil: Double?, @@ -253,20 +281,6 @@ internal class TONWallet internal constructor( // Additional methods (not in ITONWallet interface) // ======================================================================== - /** - * Get the state init BOC for this wallet. - * - * The implementation currently returns null until state init retrieval is added to the engine. - * - * @return State init as base64-encoded BOC, or null if not available - * @throws io.ton.walletkit.WalletKitBridgeException if state init retrieval fails - */ - suspend fun stateInit(): String? { - // TODO: Implement state init retrieval when available in engine - // Reference implementation: wallet.getSateInit()?.toString() - return null - } - /** * Handle a TON Connect URL (e.g., from QR code scan or deep link). * diff --git a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/core/TONWalletKit.kt b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/core/TONWalletKit.kt index 567ebc9a..1333e311 100644 --- a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/core/TONWalletKit.kt +++ b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/core/TONWalletKit.kt @@ -43,9 +43,11 @@ import io.ton.walletkit.core.streaming.TONStreamingManager import io.ton.walletkit.core.streaming.TONStreamingProviderImpl import io.ton.walletkit.engine.WalletKitEngine import io.ton.walletkit.engine.WebViewWalletKitEngine +import io.ton.walletkit.gasless.BuiltInGaslessProvider import io.ton.walletkit.gasless.ITONGaslessManager import io.ton.walletkit.gasless.TONGaslessManager -import io.ton.walletkit.gasless.TONGaslessProvider +import io.ton.walletkit.gasless.tonapi.TONApiGaslessProvider +import io.ton.walletkit.gasless.tonapi.TONApiGaslessProviderIdentifier import io.ton.walletkit.internal.constants.BridgeMethodConstants import io.ton.walletkit.internal.util.WalletKitUtils import io.ton.walletkit.listener.TONBridgeEventsHandler @@ -74,8 +76,6 @@ import kotlinx.serialization.json.Json /** * Main entry point for TON Wallet Kit SDK. * - * Mirrors the canonical TON Wallet Kit specification for cross-platform consistency. - * * Initialize the SDK by calling [initialize] with your configuration. * Then add event handlers using [addEventsHandler] when you're ready to receive events. * @@ -485,10 +485,10 @@ internal class TONWalletKit private constructor( override suspend fun swap(): ITONSwapManager = swapManager - override suspend fun tonApiGaslessProvider(config: TONTonApiGaslessProviderConfig?): TONGaslessProvider { + override suspend fun tonApiGaslessProvider(config: TONTonApiGaslessProviderConfig?): TONApiGaslessProvider { checkNotDestroyed() val providerId = engine.createTonApiGaslessProvider(config) - return TONGaslessProvider(providerId) + return BuiltInGaslessProvider(TONApiGaslessProviderIdentifier(providerId), engine) } override suspend fun gasless(): ITONGaslessManager = gaslessManager diff --git a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/WalletKitEngine.kt b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/WalletKitEngine.kt index 1ffe4ff6..f83b3623 100644 --- a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/WalletKitEngine.kt +++ b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/WalletKitEngine.kt @@ -44,6 +44,8 @@ import io.ton.walletkit.api.generated.TONNFTsRequest import io.ton.walletkit.api.generated.TONNFTsResponse import io.ton.walletkit.api.generated.TONNetwork import io.ton.walletkit.api.generated.TONOmnistonSwapProviderConfig +import io.ton.walletkit.api.generated.TONPreparedSignData +import io.ton.walletkit.api.generated.TONProofMessage import io.ton.walletkit.api.generated.TONRawStackItem import io.ton.walletkit.api.generated.TONSendTransactionApprovalResponse import io.ton.walletkit.api.generated.TONSendTransactionRequestEvent @@ -551,6 +553,30 @@ internal interface WalletKitEngine : RequestHandler { /** Sign a transaction request as a sign-message bundle, returning the signed internal BoC (base64). */ suspend fun getSignedSignMessage(walletId: String, request: TONTransactionRequest): String + /** Get a wallet's state init (base64 BOC) for contract deployment. */ + suspend fun getWalletStateInit(walletId: String): String + + /** Produce a signed send-transaction external message BoC (base64). */ + suspend fun getSignedSendTransaction( + walletId: String, + input: TONTransactionRequest, + fakeSignature: Boolean?, + ): String + + /** Produce signed sign-data (hex). */ + suspend fun getSignedSignData( + walletId: String, + input: TONPreparedSignData, + fakeSignature: Boolean?, + ): String + + /** Produce a signed TON proof (hex). */ + suspend fun getSignedTonProof( + walletId: String, + input: TONProofMessage, + fakeSignature: Boolean?, + ): String + // ── Swap ── suspend fun createOmnistonSwapProvider(config: TONOmnistonSwapProviderConfig?): String diff --git a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/WebViewWalletKitEngine.kt b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/WebViewWalletKitEngine.kt index 0577bc50..1a175ae7 100644 --- a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/WebViewWalletKitEngine.kt +++ b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/WebViewWalletKitEngine.kt @@ -42,6 +42,8 @@ import io.ton.walletkit.api.generated.TONNFTsRequest import io.ton.walletkit.api.generated.TONNFTsResponse import io.ton.walletkit.api.generated.TONNetwork import io.ton.walletkit.api.generated.TONOmnistonSwapProviderConfig +import io.ton.walletkit.api.generated.TONPreparedSignData +import io.ton.walletkit.api.generated.TONProofMessage import io.ton.walletkit.api.generated.TONRawStackItem import io.ton.walletkit.api.generated.TONSendTransactionApprovalResponse import io.ton.walletkit.api.generated.TONSendTransactionRequestEvent @@ -113,7 +115,10 @@ import io.ton.walletkit.engine.operations.getNfts import io.ton.walletkit.engine.operations.getRegisteredGaslessProviders import io.ton.walletkit.engine.operations.getRegisteredStakingProviders import io.ton.walletkit.engine.operations.getRegisteredSwapProviders +import io.ton.walletkit.engine.operations.getSignedSendTransaction +import io.ton.walletkit.engine.operations.getSignedSignData import io.ton.walletkit.engine.operations.getSignedSignMessage +import io.ton.walletkit.engine.operations.getSignedTonProof import io.ton.walletkit.engine.operations.getStakedBalance import io.ton.walletkit.engine.operations.getStakingProviderInfo import io.ton.walletkit.engine.operations.getStakingProviderMetadata @@ -127,6 +132,7 @@ import io.ton.walletkit.engine.operations.getWallet import io.ton.walletkit.engine.operations.getWalletAddress import io.ton.walletkit.engine.operations.getWalletNetwork import io.ton.walletkit.engine.operations.getWalletPublicKey +import io.ton.walletkit.engine.operations.getWalletStateInit import io.ton.walletkit.engine.operations.getWallets import io.ton.walletkit.engine.operations.handleNewTransaction import io.ton.walletkit.engine.operations.handleTonConnectRequest @@ -567,6 +573,26 @@ internal class WebViewWalletKitEngine private constructor( override suspend fun getSignedSignMessage(walletId: String, request: TONTransactionRequest): String = rpcClient.getSignedSignMessage(walletId, request) + override suspend fun getWalletStateInit(walletId: String): String = rpcClient.getWalletStateInit(walletId) + + override suspend fun getSignedSendTransaction( + walletId: String, + input: TONTransactionRequest, + fakeSignature: Boolean?, + ): String = rpcClient.getSignedSendTransaction(walletId, input, fakeSignature) + + override suspend fun getSignedSignData( + walletId: String, + input: TONPreparedSignData, + fakeSignature: Boolean?, + ): String = rpcClient.getSignedSignData(walletId, input, fakeSignature) + + override suspend fun getSignedTonProof( + walletId: String, + input: TONProofMessage, + fakeSignature: Boolean?, + ): String = rpcClient.getSignedTonProof(walletId, input, fakeSignature) + override suspend fun createOmnistonSwapProvider(config: TONOmnistonSwapProviderConfig?): String = rpcClient.createOmnistonSwapProvider(config) diff --git a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/adapter/BridgeWalletAdapter.kt b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/adapter/BridgeWalletAdapter.kt index 64f77bdf..7bfd66bb 100644 --- a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/adapter/BridgeWalletAdapter.kt +++ b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/adapter/BridgeWalletAdapter.kt @@ -53,7 +53,7 @@ internal class BridgeWalletAdapter( override fun identifier(): String = adapterId - override fun publicKey(): TONHex = cachedPublicKey + override suspend fun publicKey(): TONHex = cachedPublicKey override fun network(): TONNetwork = cachedNetwork diff --git a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/operations/WalletOperations.kt b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/operations/WalletOperations.kt index 138165fa..7de0564c 100644 --- a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/operations/WalletOperations.kt +++ b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/operations/WalletOperations.kt @@ -23,6 +23,8 @@ package io.ton.walletkit.engine.operations import io.ton.walletkit.WalletKitBridgeException import io.ton.walletkit.api.generated.TONNetwork +import io.ton.walletkit.api.generated.TONPreparedSignData +import io.ton.walletkit.api.generated.TONProofMessage import io.ton.walletkit.api.generated.TONSignatureDomain import io.ton.walletkit.api.generated.TONTransactionRequest import io.ton.walletkit.engine.infrastructure.BridgeRpcClient @@ -33,7 +35,10 @@ import io.ton.walletkit.engine.operations.requests.CreateAdapterRequest import io.ton.walletkit.engine.operations.requests.CreateSignerFromCustomRequest import io.ton.walletkit.engine.operations.requests.CreateSignerFromMnemonicRequest import io.ton.walletkit.engine.operations.requests.CreateSignerFromSecretKeyRequest +import io.ton.walletkit.engine.operations.requests.GetSignedSendTransactionRequest +import io.ton.walletkit.engine.operations.requests.GetSignedSignDataRequest import io.ton.walletkit.engine.operations.requests.GetSignedSignMessageRequest +import io.ton.walletkit.engine.operations.requests.GetSignedTonProofRequest import io.ton.walletkit.engine.operations.requests.WalletIdRequest import io.ton.walletkit.engine.operations.responses.AdapterInfoResponse import io.ton.walletkit.engine.operations.responses.AddWalletResponse @@ -115,6 +120,48 @@ internal suspend fun BridgeRpcClient.getSignedSignMessage( ), ) +internal suspend fun BridgeRpcClient.getWalletStateInit(walletId: String): String = + callTyped(BridgeMethodConstants.METHOD_GET_WALLET_STATE_INIT, WalletIdRequest(walletId = walletId)) + +internal suspend fun BridgeRpcClient.getSignedSendTransaction( + walletId: String, + input: TONTransactionRequest, + fakeSignature: Boolean?, +): String = callTyped( + BridgeMethodConstants.METHOD_GET_SIGNED_SEND_TRANSACTION, + GetSignedSendTransactionRequest( + walletId = walletId, + input = json.encodeToJsonElement(TONTransactionRequest.serializer(), input), + fakeSignature = fakeSignature, + ), +) + +internal suspend fun BridgeRpcClient.getSignedSignData( + walletId: String, + input: TONPreparedSignData, + fakeSignature: Boolean?, +): String = callTyped( + BridgeMethodConstants.METHOD_GET_SIGNED_SIGN_DATA, + GetSignedSignDataRequest( + walletId = walletId, + input = json.encodeToJsonElement(TONPreparedSignData.serializer(), input), + fakeSignature = fakeSignature, + ), +) + +internal suspend fun BridgeRpcClient.getSignedTonProof( + walletId: String, + input: TONProofMessage, + fakeSignature: Boolean?, +): String = callTyped( + BridgeMethodConstants.METHOD_GET_SIGNED_TON_PROOF, + GetSignedTonProofRequest( + walletId = walletId, + input = json.encodeToJsonElement(TONProofMessage.serializer(), input), + fakeSignature = fakeSignature, + ), +) + internal suspend fun BridgeRpcClient.removeWallet(walletId: String) { send(BridgeMethodConstants.METHOD_REMOVE_WALLET, WalletIdRequest(walletId = walletId)) } diff --git a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/operations/requests/WalletRequests.kt b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/operations/requests/WalletRequests.kt index fb9df855..fc9460d3 100644 --- a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/operations/requests/WalletRequests.kt +++ b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/operations/requests/WalletRequests.kt @@ -49,6 +49,27 @@ internal data class GetSignedSignMessageRequest( val request: JsonElement, ) +@Serializable +internal data class GetSignedSendTransactionRequest( + val walletId: String, + val input: JsonElement, + val fakeSignature: Boolean? = null, +) + +@Serializable +internal data class GetSignedSignDataRequest( + val walletId: String, + val input: JsonElement, + val fakeSignature: Boolean? = null, +) + +@Serializable +internal data class GetSignedTonProofRequest( + val walletId: String, + val input: JsonElement, + val fakeSignature: Boolean? = null, +) + @Serializable internal data class CreateSignerFromMnemonicRequest( val mnemonic: List, diff --git a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/gasless/BuiltInGaslessProvider.kt b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/gasless/BuiltInGaslessProvider.kt new file mode 100644 index 00000000..b4962600 --- /dev/null +++ b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/gasless/BuiltInGaslessProvider.kt @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2025 TonTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package io.ton.walletkit.gasless + +import io.ton.walletkit.api.generated.TONGaslessConfig +import io.ton.walletkit.api.generated.TONGaslessProviderMetadata +import io.ton.walletkit.api.generated.TONGaslessQuote +import io.ton.walletkit.api.generated.TONGaslessQuoteParams +import io.ton.walletkit.api.generated.TONGaslessSendParams +import io.ton.walletkit.api.generated.TONGaslessSendResponse +import io.ton.walletkit.api.generated.TONNetwork +import io.ton.walletkit.engine.WalletKitEngine + +/** + * Built-in, JS-backed implementation of [ITONGaslessProvider]. Talks to the JS engine directly. + * + * Users never construct this: it's created by the SDK (via [io.ton.walletkit.ITONWalletKit.tonApiGaslessProvider]). + * + * @suppress Internal implementation. + */ +internal class BuiltInGaslessProvider( + override val identifier: TONGaslessProviderIdentifier, + private val engine: WalletKitEngine, +) : ITONGaslessProvider { + + override suspend fun metadata(): TONGaslessProviderMetadata = + engine.getGaslessMetadata(identifier.name) + + override suspend fun getConfig(network: TONNetwork?): TONGaslessConfig = + engine.getGaslessConfig(network, identifier.name) + + override suspend fun getQuote(params: TONGaslessQuoteParams): TONGaslessQuote = + engine.getGaslessQuote(params, identifier.name) + + override suspend fun sendTransaction(params: TONGaslessSendParams): TONGaslessSendResponse = + engine.gaslessSendTransaction(params, identifier.name) +} diff --git a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/gasless/TONGaslessManager.kt b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/gasless/TONGaslessManager.kt index 03deac41..bc1efbbe 100644 --- a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/gasless/TONGaslessManager.kt +++ b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/gasless/TONGaslessManager.kt @@ -34,29 +34,36 @@ internal class TONGaslessManager( private val engine: WalletKitEngine, ) : ITONGaslessManager { - override suspend fun registerProvider(provider: TONGaslessProvider) = - engine.registerGaslessProvider(provider.providerId) + override suspend fun registerProvider(provider: ITONGaslessProvider) = + engine.registerGaslessProvider(provider.identifier.name) - override suspend fun setDefaultProvider(provider: TONGaslessProvider) = - engine.setDefaultGaslessProvider(provider.providerId) + override suspend fun setDefaultProvider(identifier: TONGaslessProviderIdentifier) = + engine.setDefaultGaslessProvider(identifier.name) - override suspend fun providers(): List = - engine.getRegisteredGaslessProviders().map { TONGaslessProvider(it) } + override suspend fun providers(): List = + engine.getRegisteredGaslessProviders().map { BuiltInGaslessProvider(AnyTONGaslessProviderIdentifier(it), engine) } - override suspend fun hasProvider(provider: TONGaslessProvider): Boolean = - engine.hasGaslessProvider(provider.providerId) + override suspend fun hasProvider(identifier: TONGaslessProviderIdentifier): Boolean = + engine.hasGaslessProvider(identifier.name) - override suspend fun getMetadata(provider: TONGaslessProvider?): TONGaslessProviderMetadata = - engine.getGaslessMetadata(provider?.providerId) + override suspend fun provider(identifier: TONGaslessProviderIdentifier): ITONGaslessProvider = + BuiltInGaslessProvider(identifier, engine) - override suspend fun getConfig(network: TONNetwork?, provider: TONGaslessProvider?): TONGaslessConfig = - engine.getGaslessConfig(network, provider?.providerId) + override suspend fun getMetadata(identifier: TONGaslessProviderIdentifier?): TONGaslessProviderMetadata = + engine.getGaslessMetadata(identifier?.name) - override suspend fun getQuote(params: TONGaslessQuoteParams, provider: TONGaslessProvider?): TONGaslessQuote = - engine.getGaslessQuote(params, provider?.providerId) + override suspend fun getConfig( + network: TONNetwork?, + identifier: TONGaslessProviderIdentifier?, + ): TONGaslessConfig = engine.getGaslessConfig(network, identifier?.name) + + override suspend fun getQuote( + params: TONGaslessQuoteParams, + identifier: TONGaslessProviderIdentifier?, + ): TONGaslessQuote = engine.getGaslessQuote(params, identifier?.name) override suspend fun sendTransaction( params: TONGaslessSendParams, - provider: TONGaslessProvider?, - ): TONGaslessSendResponse = engine.gaslessSendTransaction(params, provider?.providerId) + identifier: TONGaslessProviderIdentifier?, + ): TONGaslessSendResponse = engine.gaslessSendTransaction(params, identifier?.name) } diff --git a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/internal/constants/BridgeMethodConstants.kt b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/internal/constants/BridgeMethodConstants.kt index 7078e009..23ca9c82 100644 --- a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/internal/constants/BridgeMethodConstants.kt +++ b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/internal/constants/BridgeMethodConstants.kt @@ -78,6 +78,18 @@ internal object BridgeMethodConstants { /** Method name for proactively signing a set of messages (used by gasless relay flows). */ const val METHOD_GET_SIGNED_SIGN_MESSAGE = "getSignedSignMessage" + /** Method name for getting a wallet's state init (base64 BOC). */ + const val METHOD_GET_WALLET_STATE_INIT = "getWalletStateInit" + + /** Method name for producing a signed send-transaction BoC. */ + const val METHOD_GET_SIGNED_SEND_TRANSACTION = "getSignedSendTransaction" + + /** Method name for producing signed sign-data. */ + const val METHOD_GET_SIGNED_SIGN_DATA = "getSignedSignData" + + /** Method name for producing a signed TON proof. */ + const val METHOD_GET_SIGNED_TON_PROOF = "getSignedTonProof" + /** * Method name for removing a wallet. */ diff --git a/TONWalletKit-Android/impl/src/test/java/io/ton/walletkit/CustomWalletAdapterTest.kt b/TONWalletKit-Android/impl/src/test/java/io/ton/walletkit/CustomWalletAdapterTest.kt index a5b7c20e..4f38d358 100644 --- a/TONWalletKit-Android/impl/src/test/java/io/ton/walletkit/CustomWalletAdapterTest.kt +++ b/TONWalletKit-Android/impl/src/test/java/io/ton/walletkit/CustomWalletAdapterTest.kt @@ -58,7 +58,7 @@ class CustomWalletAdapterTest { var lastTransactionRequest: TONTransactionRequest? = null override fun identifier(): String = adapterId - override fun publicKey(): TONHex = TONHex(pubKey) + override suspend fun publicKey(): TONHex = TONHex(pubKey) override fun network(): TONNetwork = net override fun address(testnet: Boolean): TONUserFriendlyAddress = TONUserFriendlyAddress(addr) @@ -153,7 +153,7 @@ class CustomWalletAdapterTest { } @Test - fun `adapter exposes identifier publicKey network address synchronously`() { + fun `adapter exposes identifier publicKey network address`() = runTest { val adapter = MockWalletAdapter() assertEquals("adapter-1", adapter.identifier()) diff --git a/TONWalletKit-Android/impl/src/test/java/io/ton/walletkit/mockbridge/infra/MockScenario.kt b/TONWalletKit-Android/impl/src/test/java/io/ton/walletkit/mockbridge/infra/MockScenario.kt index 2700049e..9b4b491a 100644 --- a/TONWalletKit-Android/impl/src/test/java/io/ton/walletkit/mockbridge/infra/MockScenario.kt +++ b/TONWalletKit-Android/impl/src/test/java/io/ton/walletkit/mockbridge/infra/MockScenario.kt @@ -94,7 +94,7 @@ interface MockScenario { val address = TONUserFriendlyAddress("EQDTest${signerId.hashCode().toString(16).padStart(40, '0')}") return object : TONWalletAdapter { override fun identifier() = adapterId - override fun publicKey() = publicKey + override suspend fun publicKey() = publicKey override fun network() = resolvedNetwork override fun address(testnet: Boolean) = address override suspend fun stateInit() = TONBase64("") From deab67672d52f0113016bf7aa9698723a75a8fdd Mon Sep 17 00:00:00 2001 From: Dmitrii Nikulin Date: Tue, 16 Jun 2026 12:31:01 +0300 Subject: [PATCH 6/9] feat: add support for gasless provider management and network retrieval --- .../io/ton/walletkit/gasless/ITONGaslessManager.kt | 3 +++ .../io/ton/walletkit/gasless/ITONGaslessProvider.kt | 3 +++ .../assets/walletkit/walletkit-android-bridge.mjs | 9 +++++++++ .../java/io/ton/walletkit/engine/WalletKitEngine.kt | 4 ++++ .../ton/walletkit/engine/WebViewWalletKitEngine.kt | 7 +++++++ .../engine/operations/GaslessOperations.kt | 13 +++++++++++++ .../engine/operations/requests/GaslessRequests.kt | 10 ++++++++++ .../ton/walletkit/gasless/BuiltInGaslessProvider.kt | 3 +++ .../io/ton/walletkit/gasless/TONGaslessManager.kt | 3 +++ .../internal/constants/BridgeMethodConstants.kt | 6 ++++++ 10 files changed, 61 insertions(+) diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/gasless/ITONGaslessManager.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/gasless/ITONGaslessManager.kt index 947077bc..bb475f63 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/gasless/ITONGaslessManager.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/gasless/ITONGaslessManager.kt @@ -47,6 +47,9 @@ interface ITONGaslessManager { */ suspend fun registerProvider(provider: ITONGaslessProvider) + /** Unregister [provider]; no-op if it isn't currently registered. */ + suspend fun removeProvider(provider: ITONGaslessProvider) + /** Set the default provider used when no identifier is specified. */ suspend fun setDefaultProvider(identifier: TONGaslessProviderIdentifier) diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/gasless/ITONGaslessProvider.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/gasless/ITONGaslessProvider.kt index 2295ec56..66744cf6 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/gasless/ITONGaslessProvider.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/gasless/ITONGaslessProvider.kt @@ -43,6 +43,9 @@ interface ITONGaslessProvider { /** Typed provider identifier. */ val identifier: TONGaslessProviderIdentifier + /** Networks this provider can operate on. */ + suspend fun supportedNetworks(): List + /** Static descriptive metadata (name, logo, url). */ suspend fun metadata(): TONGaslessProviderMetadata diff --git a/TONWalletKit-Android/impl/src/main/assets/walletkit/walletkit-android-bridge.mjs b/TONWalletKit-Android/impl/src/main/assets/walletkit/walletkit-android-bridge.mjs index d7e3a9f6..4498c921 100644 --- a/TONWalletKit-Android/impl/src/main/assets/walletkit/walletkit-android-bridge.mjs +++ b/TONWalletKit-Android/impl/src/main/assets/walletkit/walletkit-android-bridge.mjs @@ -46124,9 +46124,16 @@ async function createTonApiGaslessProvider(args) { async function registerGaslessProvider(args) { (await getGasless()).registerProvider(get(args.providerId)); } +async function removeGaslessProvider(args) { + const gasless = await getGasless(); + gasless.removeProvider(gasless.getProvider(args.providerId)); +} async function setDefaultGaslessProvider(args) { (await getGasless()).setDefaultProvider(args.providerId); } +async function getGaslessProviderSupportedNetworks(args) { + return { networks: (await getGasless()).getProvider(args.providerId).getSupportedNetworks() }; +} async function getRegisteredGaslessProviders() { return { providerIds: (await getGasless()).getProviders().map((provider) => provider.providerId) }; } @@ -46280,9 +46287,11 @@ var api = { registerKotlinSwapProvider, createTonApiGaslessProvider, registerGaslessProvider, + removeGaslessProvider, setDefaultGaslessProvider, getRegisteredGaslessProviders, hasGaslessProvider, + getGaslessProviderSupportedNetworks, getGaslessMetadata, getGaslessConfig, getGaslessQuote, diff --git a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/WalletKitEngine.kt b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/WalletKitEngine.kt index f83b3623..28fa4b9b 100644 --- a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/WalletKitEngine.kt +++ b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/WalletKitEngine.kt @@ -624,10 +624,14 @@ internal interface WalletKitEngine : RequestHandler { suspend fun registerGaslessProvider(providerId: String) + suspend fun removeGaslessProvider(providerId: String) + suspend fun setDefaultGaslessProvider(providerId: String) suspend fun getRegisteredGaslessProviders(): List + suspend fun getGaslessProviderSupportedNetworks(providerId: String): List + suspend fun hasGaslessProvider(providerId: String): Boolean suspend fun getGaslessMetadata(providerId: String?): TONGaslessProviderMetadata diff --git a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/WebViewWalletKitEngine.kt b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/WebViewWalletKitEngine.kt index 1a175ae7..9bb7eb21 100644 --- a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/WebViewWalletKitEngine.kt +++ b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/WebViewWalletKitEngine.kt @@ -106,6 +106,7 @@ import io.ton.walletkit.engine.operations.gaslessSendTransaction import io.ton.walletkit.engine.operations.getBalance import io.ton.walletkit.engine.operations.getGaslessConfig import io.ton.walletkit.engine.operations.getGaslessMetadata +import io.ton.walletkit.engine.operations.getGaslessProviderSupportedNetworks import io.ton.walletkit.engine.operations.getGaslessQuote import io.ton.walletkit.engine.operations.getJettonBalance import io.ton.walletkit.engine.operations.getJettonWalletAddress @@ -149,6 +150,7 @@ import io.ton.walletkit.engine.operations.rejectConnect import io.ton.walletkit.engine.operations.rejectSignData import io.ton.walletkit.engine.operations.rejectSignMessage import io.ton.walletkit.engine.operations.rejectTransaction +import io.ton.walletkit.engine.operations.removeGaslessProvider import io.ton.walletkit.engine.operations.removeStakingProvider import io.ton.walletkit.engine.operations.removeSwapProvider import io.ton.walletkit.engine.operations.removeWallet @@ -653,11 +655,16 @@ internal class WebViewWalletKitEngine private constructor( override suspend fun registerGaslessProvider(providerId: String) = rpcClient.registerGaslessProvider(providerId) + override suspend fun removeGaslessProvider(providerId: String) = rpcClient.removeGaslessProvider(providerId) + override suspend fun setDefaultGaslessProvider(providerId: String) = rpcClient.setDefaultGaslessProvider(providerId) override suspend fun getRegisteredGaslessProviders(): List = rpcClient.getRegisteredGaslessProviders() + override suspend fun getGaslessProviderSupportedNetworks(providerId: String): List = + rpcClient.getGaslessProviderSupportedNetworks(providerId) + override suspend fun hasGaslessProvider(providerId: String): Boolean = rpcClient.hasGaslessProvider(providerId) override suspend fun getGaslessMetadata(providerId: String?) = rpcClient.getGaslessMetadata(providerId) diff --git a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/operations/GaslessOperations.kt b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/operations/GaslessOperations.kt index 55e3ee7b..294ce2c2 100644 --- a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/operations/GaslessOperations.kt +++ b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/operations/GaslessOperations.kt @@ -35,13 +35,16 @@ import io.ton.walletkit.engine.operations.requests.CreateTonApiGaslessProviderRe import io.ton.walletkit.engine.operations.requests.GaslessSendTransactionRequest import io.ton.walletkit.engine.operations.requests.GetGaslessConfigRequest import io.ton.walletkit.engine.operations.requests.GetGaslessMetadataRequest +import io.ton.walletkit.engine.operations.requests.GetGaslessProviderSupportedNetworksRequest import io.ton.walletkit.engine.operations.requests.GetGaslessQuoteRequest import io.ton.walletkit.engine.operations.requests.HasGaslessProviderRequest import io.ton.walletkit.engine.operations.requests.RegisterGaslessProviderRequest +import io.ton.walletkit.engine.operations.requests.RemoveGaslessProviderRequest import io.ton.walletkit.engine.operations.requests.SetDefaultGaslessProviderRequest import io.ton.walletkit.engine.operations.responses.HasProviderResponse import io.ton.walletkit.engine.operations.responses.ProviderIdResponse import io.ton.walletkit.engine.operations.responses.ProviderIdsResponse +import io.ton.walletkit.engine.operations.responses.SupportedNetworksResponse import io.ton.walletkit.internal.constants.BridgeMethodConstants import kotlinx.serialization.json.Json @@ -57,6 +60,16 @@ internal suspend fun BridgeRpcClient.registerGaslessProvider(providerId: String) send(BridgeMethodConstants.METHOD_REGISTER_GASLESS_PROVIDER, RegisterGaslessProviderRequest(providerId)) } +internal suspend fun BridgeRpcClient.removeGaslessProvider(providerId: String) { + send(BridgeMethodConstants.METHOD_REMOVE_GASLESS_PROVIDER, RemoveGaslessProviderRequest(providerId)) +} + +internal suspend fun BridgeRpcClient.getGaslessProviderSupportedNetworks(providerId: String): List = + callTyped( + BridgeMethodConstants.METHOD_GET_GASLESS_PROVIDER_SUPPORTED_NETWORKS, + GetGaslessProviderSupportedNetworksRequest(providerId), + ).networks + internal suspend fun BridgeRpcClient.setDefaultGaslessProvider(providerId: String) { send(BridgeMethodConstants.METHOD_SET_DEFAULT_GASLESS_PROVIDER, SetDefaultGaslessProviderRequest(providerId)) } diff --git a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/operations/requests/GaslessRequests.kt b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/operations/requests/GaslessRequests.kt index 7658b6fe..b66b683c 100644 --- a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/operations/requests/GaslessRequests.kt +++ b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/operations/requests/GaslessRequests.kt @@ -40,6 +40,11 @@ internal data class RegisterGaslessProviderRequest( val providerId: String, ) +@Serializable +internal data class RemoveGaslessProviderRequest( + val providerId: String, +) + @Serializable internal data class SetDefaultGaslessProviderRequest( val providerId: String, @@ -50,6 +55,11 @@ internal data class HasGaslessProviderRequest( val providerId: String, ) +@Serializable +internal data class GetGaslessProviderSupportedNetworksRequest( + val providerId: String, +) + @Serializable internal data class GetGaslessMetadataRequest( val providerId: String? = null, diff --git a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/gasless/BuiltInGaslessProvider.kt b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/gasless/BuiltInGaslessProvider.kt index b4962600..1d682c74 100644 --- a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/gasless/BuiltInGaslessProvider.kt +++ b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/gasless/BuiltInGaslessProvider.kt @@ -42,6 +42,9 @@ internal class BuiltInGaslessProvider( private val engine: WalletKitEngine, ) : ITONGaslessProvider { + override suspend fun supportedNetworks(): List = + engine.getGaslessProviderSupportedNetworks(identifier.name) + override suspend fun metadata(): TONGaslessProviderMetadata = engine.getGaslessMetadata(identifier.name) diff --git a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/gasless/TONGaslessManager.kt b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/gasless/TONGaslessManager.kt index bc1efbbe..446d881c 100644 --- a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/gasless/TONGaslessManager.kt +++ b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/gasless/TONGaslessManager.kt @@ -37,6 +37,9 @@ internal class TONGaslessManager( override suspend fun registerProvider(provider: ITONGaslessProvider) = engine.registerGaslessProvider(provider.identifier.name) + override suspend fun removeProvider(provider: ITONGaslessProvider) = + engine.removeGaslessProvider(provider.identifier.name) + override suspend fun setDefaultProvider(identifier: TONGaslessProviderIdentifier) = engine.setDefaultGaslessProvider(identifier.name) diff --git a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/internal/constants/BridgeMethodConstants.kt b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/internal/constants/BridgeMethodConstants.kt index 23ca9c82..4f350400 100644 --- a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/internal/constants/BridgeMethodConstants.kt +++ b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/internal/constants/BridgeMethodConstants.kt @@ -352,12 +352,18 @@ internal object BridgeMethodConstants { /** Register a previously created gasless provider with the gasless manager. */ const val METHOD_REGISTER_GASLESS_PROVIDER = "registerGaslessProvider" + /** Unregister a previously registered gasless provider. */ + const val METHOD_REMOVE_GASLESS_PROVIDER = "removeGaslessProvider" + /** Set the default gasless provider. */ const val METHOD_SET_DEFAULT_GASLESS_PROVIDER = "setDefaultGaslessProvider" /** Get all registered gasless provider IDs. */ const val METHOD_GET_REGISTERED_GASLESS_PROVIDERS = "getRegisteredGaslessProviders" + /** Get the networks a registered gasless provider supports. */ + const val METHOD_GET_GASLESS_PROVIDER_SUPPORTED_NETWORKS = "getGaslessProviderSupportedNetworks" + /** Check if a gasless provider is registered. */ const val METHOD_HAS_GASLESS_PROVIDER = "hasGaslessProvider" From ee6423294ef4719dc565403a35b1aa9aa0969a27 Mon Sep 17 00:00:00 2001 From: Dmitrii Nikulin Date: Tue, 16 Jun 2026 14:13:26 +0300 Subject: [PATCH 7/9] chore: js parity in ITONWallet and ITONWalletAdapter --- .../walletkit/demo/core/WalletKitDemoApp.kt | 4 +- .../ui/screen/NFTDetailsScreen.kt | 2 +- .../presentation/ui/sheet/StakingSheet.kt | 2 +- .../viewmodel/JettonsListViewModel.kt | 6 +- .../viewmodel/NFTsListViewModel.kt | 6 +- .../viewmodel/SessionsViewModel.kt | 2 +- .../viewmodel/StakingViewModel.kt | 8 +- .../presentation/viewmodel/SwapViewModel.kt | 2 +- .../viewmodel/TransactionHistoryViewModel.kt | 8 +- .../viewmodel/WalletKitViewModel.kt | 10 +- .../viewmodel/WalletLifecycleManager.kt | 10 +- .../viewmodel/WalletOperationsViewModel.kt | 13 +- .../main/java/io/ton/walletkit/ITONWallet.kt | 146 ++---------------- .../java/io/ton/walletkit/ITONWalletKit.kt | 12 +- .../walletkit/gasless/ITONGaslessManager.kt | 2 +- ...NWalletAdapter.kt => ITONWalletAdapter.kt} | 11 +- .../request/TONWalletConnectionRequest.kt | 4 +- .../walletkit/staking/ITONStakingManager.kt | 4 +- .../streaming/ITONStreamingManager.kt | 2 +- .../streaming/ITONStreamingProvider.kt | 2 +- .../io/ton/walletkit/swap/ITONSwapProvider.kt | 2 +- .../java/io/ton/walletkit/core/TONWallet.kt | 41 ++--- .../io/ton/walletkit/core/TONWalletKit.kt | 15 +- .../core/streaming/TONStreamingManager.kt | 8 +- .../streaming/TONStreamingProviderImpl.kt | 2 +- .../ton/walletkit/engine/WalletKitEngine.kt | 6 +- .../engine/WebViewWalletKitEngine.kt | 6 +- .../engine/adapter/BridgeWalletAdapter.kt | 7 +- .../walletkit/engine/state/AdapterManager.kt | 8 +- .../engine/state/KotlinSwapProviderManager.kt | 2 +- .../walletkit/gasless/TONGaslessManager.kt | 2 +- .../walletkit/staking/TONStakingManager.kt | 4 +- .../ton/walletkit/swap/BuiltInSwapProvider.kt | 2 +- .../ton/walletkit/CustomWalletAdapterTest.kt | 8 +- .../io/ton/walletkit/WalletManagementTest.kt | 10 +- .../mockbridge/DelayedReadyMockTest.kt | 4 +- .../mockbridge/EngineMethodEfficiencyTests.kt | 4 +- .../mockbridge/infra/MockScenario.kt | 8 +- .../mockbridge/infra/TestWalletKitFactory.kt | 6 +- 39 files changed, 133 insertions(+), 268 deletions(-) rename TONWalletKit-Android/api/src/main/java/io/ton/walletkit/model/{TONWalletAdapter.kt => ITONWalletAdapter.kt} (91%) diff --git a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/core/WalletKitDemoApp.kt b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/core/WalletKitDemoApp.kt index 0fe06a18..dcaacc78 100644 --- a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/core/WalletKitDemoApp.kt +++ b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/core/WalletKitDemoApp.kt @@ -131,7 +131,7 @@ class WalletKitDemoApp : return } - val existingAddresses = kit.getWallets().mapNotNull { it.address?.value }.toMutableSet() + val existingAddresses = kit.getWallets().mapNotNull { it.address().value }.toMutableSet() Log.d(TAG, "Loading ${storedWallets.size} stored wallets into SDK") for ((address, walletRecord) in storedWallets) { @@ -320,7 +320,7 @@ object TONWalletKitHelper { apiKey = tonCenterApiKey, ), ) - kit.streaming().register(streamingProvider) + kit.streaming().registerProvider(streamingProvider) } catch (e: Exception) { Log.e("WalletKitDemoApp", "Streaming init ERROR network=${network.chainId} - ${e.message}", e) } diff --git a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/ui/screen/NFTDetailsScreen.kt b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/ui/screen/NFTDetailsScreen.kt index ac4d493c..2532d49b 100644 --- a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/ui/screen/NFTDetailsScreen.kt +++ b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/ui/screen/NFTDetailsScreen.kt @@ -89,7 +89,7 @@ fun NFTDetailsScreen( LaunchedEffect(walletAddress) { isLoadingWallet = true - wallet = walletKit.getWallets().firstOrNull { it.address?.value == walletAddress } + wallet = walletKit.getWallets().firstOrNull { it.address().value == walletAddress } isLoadingWallet = false } diff --git a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/ui/sheet/StakingSheet.kt b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/ui/sheet/StakingSheet.kt index f9611b4b..21fb0da8 100644 --- a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/ui/sheet/StakingSheet.kt +++ b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/ui/sheet/StakingSheet.kt @@ -84,7 +84,7 @@ fun StakingSheet( LaunchedEffect(wallet.address) { isLoadingWallet = true - tonWallet = walletKit.getWallets().firstOrNull { it.address.value == wallet.address } + tonWallet = walletKit.getWallets().firstOrNull { it.address().value == wallet.address } isLoadingWallet = false } diff --git a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/JettonsListViewModel.kt b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/JettonsListViewModel.kt index 495fdbdb..9a5d9aa4 100644 --- a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/JettonsListViewModel.kt +++ b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/JettonsListViewModel.kt @@ -63,12 +63,12 @@ class JettonsListViewModel( private var loadJob: Job? = null init { - Log.d(TAG, "Created for wallet: ${wallet.address.value}") + Log.d(TAG, "Created for wallet: ${wallet.address().value}") } override fun onCleared() { super.onCleared() - Log.d(TAG, "Cleared for wallet: ${wallet.address.value}") + Log.d(TAG, "Cleared for wallet: ${wallet.address().value}") loadJob?.cancel() } @@ -89,7 +89,7 @@ class JettonsListViewModel( return } - Log.d(TAG, "Starting loadJettons for wallet: ${wallet.address.value}") + Log.d(TAG, "Starting loadJettons for wallet: ${wallet.address().value}") loadJob?.cancel() loadJob = viewModelScope.launch { try { diff --git a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/NFTsListViewModel.kt b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/NFTsListViewModel.kt index 9995f214..cc8f3ec5 100644 --- a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/NFTsListViewModel.kt +++ b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/NFTsListViewModel.kt @@ -57,12 +57,12 @@ class NFTsListViewModel( private var loadJob: Job? = null init { - Log.d("NFTsListViewModel", "Created for wallet: ${wallet.address.value}") + Log.d("NFTsListViewModel", "Created for wallet: ${wallet.address().value}") } override fun onCleared() { super.onCleared() - Log.d("NFTsListViewModel", "Cleared for wallet: ${wallet.address.value}") + Log.d("NFTsListViewModel", "Cleared for wallet: ${wallet.address().value}") loadJob?.cancel() } @@ -80,7 +80,7 @@ class NFTsListViewModel( return } - Log.d("NFTsListViewModel", "Starting loadNFTs for wallet: ${wallet.address.value}") + Log.d("NFTsListViewModel", "Starting loadNFTs for wallet: ${wallet.address().value}") loadJob?.cancel() loadJob = viewModelScope.launch { try { diff --git a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/SessionsViewModel.kt b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/SessionsViewModel.kt index 2693b392..27033b15 100644 --- a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/SessionsViewModel.kt +++ b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/SessionsViewModel.kt @@ -67,7 +67,7 @@ class SessionsViewModel( _state.value = _state.value.copy(isLoading = true, error = null) runCatching { - val walletAddresses = getAllWallets().map { it.address.value }.toSet() + val walletAddresses = getAllWallets().map { it.address().value }.toSet() val manager = TONWalletKitHelper.sessionManager if (manager == null) { Log.d(TAG, "Custom session manager not enabled; returning empty session list") diff --git a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/StakingViewModel.kt b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/StakingViewModel.kt index 2f81203f..b74b8210 100644 --- a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/StakingViewModel.kt +++ b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/StakingViewModel.kt @@ -141,7 +141,7 @@ class StakingViewModel( TONStakingQuoteParams( direction = s.direction, amount = s.amount, - userAddress = wallet.address, + userAddress = wallet.address(), network = network, unstakeMode = if (s.direction == TONStakingQuoteDirection.unstake) s.unstakeMode else null, ), @@ -171,7 +171,7 @@ class StakingViewModel( val tx = manager.buildStakeTransaction( TONStakeParams( quote = quote, - userAddress = wallet.address, + userAddress = wallet.address(), ), ) wallet.send(tx) @@ -249,7 +249,7 @@ class StakingViewModel( return runCatching { val walletBalanceNano = wallet.balance().value val balance = manager.getStakedBalance( - userAddress = wallet.address, + userAddress = wallet.address(), network = network, ) _state.update { @@ -288,7 +288,7 @@ class StakingViewModel( val manager = kit.staking() val provider = kit.tonStakersStakingProvider(DemoApiConfig.tonStakersProviderConfig()) - manager.register(provider) + manager.registerProvider(provider) manager.setDefaultProvider(provider.identifier) runCatching { diff --git a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/SwapViewModel.kt b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/SwapViewModel.kt index f9bef9f5..7d9ae6d7 100644 --- a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/SwapViewModel.kt +++ b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/SwapViewModel.kt @@ -196,7 +196,7 @@ class SwapViewModel( val transactionRequest = manager.buildSwapTransaction( TONSwapParams( quote = quote, - userAddress = wallet.address, + userAddress = wallet.address(), ), ) wallet.send(transactionRequest) diff --git a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/TransactionHistoryViewModel.kt b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/TransactionHistoryViewModel.kt index a5e70425..162ec04d 100644 --- a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/TransactionHistoryViewModel.kt +++ b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/TransactionHistoryViewModel.kt @@ -48,12 +48,12 @@ class TransactionHistoryViewModel( val transactions: StateFlow> = _transactions.asStateFlow() init { - Log.d(TAG, "Created for wallet: ${wallet.address.value}") + Log.d(TAG, "Created for wallet: ${wallet.address().value}") } override fun onCleared() { super.onCleared() - Log.d(TAG, "Cleared for wallet: ${wallet.address.value}") + Log.d(TAG, "Cleared for wallet: ${wallet.address().value}") } sealed class TransactionState { @@ -71,7 +71,7 @@ class TransactionHistoryViewModel( fun loadTransactions(limit: Int = DEFAULT_LIMIT) { viewModelScope.launch { try { - val walletAddress = wallet.address.value + val walletAddress = wallet.address().value _state.value = TransactionState.Loading @@ -129,7 +129,7 @@ class TransactionHistoryViewModel( */ fun clearCache() { viewModelScope.launch { - val walletAddress = wallet.address.value + val walletAddress = wallet.address().value transactionCache.clear(walletAddress) _transactions.value = emptyList() _state.value = TransactionState.Initial diff --git a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/WalletKitViewModel.kt b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/WalletKitViewModel.kt index 81bc59bd..645ef7dd 100644 --- a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/WalletKitViewModel.kt +++ b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/WalletKitViewModel.kt @@ -429,7 +429,7 @@ class WalletKitViewModel @Inject constructor( } if (logSwitch) { - val walletName = lifecycleManager.walletMetadata[address]?.name ?: wallet.address?.value ?: address + val walletName = lifecycleManager.walletMetadata[address]?.name ?: wallet.address().value ?: address eventLogger.log(R.string.wallet_event_switched_wallet, walletName) } } @@ -717,7 +717,7 @@ class WalletKitViewModel @Inject constructor( val newWallet = result.getOrNull() var newAddress: String? = null - newWallet?.address?.let { address -> + newWallet?.address()?.let { address -> newAddress = address.value lifecycleManager.tonWallets[address.value] = newWallet @@ -801,7 +801,7 @@ class WalletKitViewModel @Inject constructor( if (result.isSuccess) { val (newWallet, generatedMnemonic) = result.getOrThrow() - val newAddress = newWallet.address.value + val newAddress = newWallet.address().value lifecycleManager.tonWallets[newAddress] = newWallet lifecycleManager.walletMetadata[newAddress] = pendingMetadata @@ -1172,7 +1172,7 @@ class WalletKitViewModel @Inject constructor( fun removeWallet(address: String) { viewModelScope.launch { // SDK keys wallets by walletId; our cache maps address → ITONWallet. - val walletId = lifecycleManager.tonWallets[address]?.id + val walletId = lifecycleManager.tonWallets[address]?.identifier() if (walletId == null) { _state.update { it.copy(error = uiString(R.string.wallet_error_wallet_not_found)) } return@launch @@ -1834,7 +1834,7 @@ class WalletKitViewModel @Inject constructor( viewModelScope.launch { try { val kit = getKit() - val allWalletIds = lifecycleManager.tonWallets.values.map { it.id } + val allWalletIds = lifecycleManager.tonWallets.values.map { it.identifier() } allWalletIds.forEach { walletId -> runCatching { kit.removeWallet(walletId) }.onFailure { Log.w(LOG_TAG, "Failed to remove wallet during reset", it) diff --git a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/WalletLifecycleManager.kt b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/WalletLifecycleManager.kt index 0af73bfd..a5deb7ff 100644 --- a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/WalletLifecycleManager.kt +++ b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/WalletLifecycleManager.kt @@ -73,12 +73,12 @@ class WalletLifecycleManager( val wallets = kit.getWallets() tonWallets.clear() wallets.forEach { wallet -> - wallet.address?.value?.let { tonWallets[it] = wallet } + wallet.address().value?.let { tonWallets[it] = wallet } } val metadataCorrections = mutableListOf() for (wallet in wallets) { - val address = wallet.address?.value ?: continue + val address = wallet.address().value ?: continue tonWallets[address] = wallet if (walletMetadata[address] == null) { val storedRecord = storage.loadWallet(address) @@ -120,17 +120,17 @@ class WalletLifecycleManager( } else { tonWallets.clear() freshWallets.forEach { wallet -> - wallet.address?.value?.let { tonWallets[it] = wallet } + wallet.address().value?.let { tonWallets[it] = wallet } } freshWallets } - val knownAddresses = wallets.map { it.address.value }.toSet() + val knownAddresses = wallets.map { it.address().value }.toSet() walletMetadata.keys.retainAll(knownAddresses) val result = mutableListOf() for (wallet in wallets) { - val address = wallet.address.value + val address = wallet.address().value val metadata = ensureMetadataForAddress(address) val balance = runCatching { wallet.balance() } diff --git a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/WalletOperationsViewModel.kt b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/WalletOperationsViewModel.kt index 883671a8..614d2f97 100644 --- a/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/WalletOperationsViewModel.kt +++ b/AndroidDemo/app/src/main/java/io/ton/walletkit/demo/presentation/viewmodel/WalletOperationsViewModel.kt @@ -29,6 +29,7 @@ import io.ton.walletkit.ITONWalletKit import io.ton.walletkit.api.generated.TONGaslessQuoteParams import io.ton.walletkit.api.generated.TONGaslessSendParams import io.ton.walletkit.api.generated.TONJettonsTransferRequest +import io.ton.walletkit.api.generated.TONTransactionRequest import io.ton.walletkit.api.generated.TONTransferRequest import io.ton.walletkit.demo.presentation.util.TonFormatter import io.ton.walletkit.model.TONUserFriendlyAddress @@ -153,7 +154,7 @@ class WalletOperationsViewModel( gaslessManager.setDefaultProvider(provider.identifier) } - val config = gaslessManager.getConfig(network = wallet.network) + val config = gaslessManager.getConfig(network = wallet.network()) val transfer = wallet.transferJettonTransaction( TONJettonsTransferRequest( jettonAddress = TONUserFriendlyAddress(USDT_MASTER), @@ -164,17 +165,19 @@ class WalletOperationsViewModel( ) val quote = gaslessManager.getQuote( TONGaslessQuoteParams( - network = wallet.network, - walletAddress = wallet.address, + network = wallet.network(), + walletAddress = wallet.address(), walletPublicKey = wallet.publicKey(), messages = transfer.messages, feeAsset = TONUserFriendlyAddress(USDT_MASTER), ), ) - val internalBoc = wallet.signMessage(messages = quote.messages, validUntil = quote.validUntil) + val internalBoc = wallet.signedSignMessage( + TONTransactionRequest(messages = quote.messages, validUntil = quote.validUntil, network = wallet.network()), + ) gaslessManager.sendTransaction( TONGaslessSendParams( - network = wallet.network, + network = wallet.network(), walletPublicKey = wallet.publicKey(), internalBoc = internalBoc, ), diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/ITONWallet.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/ITONWallet.kt index 6c8ab019..4bc9df41 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/ITONWallet.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/ITONWallet.kt @@ -22,167 +22,43 @@ package io.ton.walletkit import io.ton.walletkit.api.generated.* -import io.ton.walletkit.client.TONAPIClient +import io.ton.walletkit.model.ITONWalletAdapter import io.ton.walletkit.model.TONBalance -import io.ton.walletkit.model.TONBase64 import io.ton.walletkit.model.TONUserFriendlyAddress -import io.ton.walletkit.model.TONWalletAdapter -/** - * TON wallet instance for transaction management and dApp interactions. - * - * Inherits the account-level adapter surface ([TONWalletAdapter]) — `publicKey()`, `network()`, - * `address(testnet)`, `stateInit()`, and the signing primitives. - */ -interface ITONWallet : TONWalletAdapter { - /** - * Unique wallet identifier. - */ - val id: String - - /** - * Wallet address in user-friendly format. - */ - val address: TONUserFriendlyAddress - - /** API client backing this wallet — exposes per-wallet network and RPC. */ - val client: TONAPIClient - - /** Network this wallet is connected to. */ - val network: TONNetwork - - /** - * Get wallet balance. - */ +interface ITONWallet : ITONWalletAdapter { suspend fun balance(): TONBalance - /** Sign a set of messages as a sign-message bundle, returning the signed internal BoC (used by gasless relay flows). */ - suspend fun signMessage( - messages: List, - validUntil: Double? = null, - ): TONBase64 - - /** - * Create a TON transfer transaction. - * - * @param request Transfer request with recipient, amount, and optional comment - * @return Transaction request ready for sending or preview - */ suspend fun transferTONTransaction(request: TONTransferRequest): TONTransactionRequest - /** - * Create a multi-recipient TON transfer transaction. - * - * @param requests List of transfer requests - * @return Transaction request ready for sending or preview - */ suspend fun transferTONTransaction(requests: List): TONTransactionRequest - /** - * Send a transaction to the blockchain. - * - * @param transactionRequest Transaction request from transferTON/NFT/Jetton methods - * @return Broadcast response (boc, normalizedBoc, normalizedHash). - */ - suspend fun send(transactionRequest: TONTransactionRequest): TONSendTransactionResponse - - /** - * Get transaction preview with fee estimation. - * - * @param transactionRequest Transaction request to preview - * @param options Optional preview options (mode, relayGas) - * @return Preview with estimated fees and trace - */ suspend fun preview( transactionRequest: TONTransactionRequest, options: TONTransactionPreviewOptions? = null, ): TONTransactionEmulatedPreview - /** - * Create an NFT transfer transaction. - * - * @param request NFT transfer request with recipient and optional comment - * @return Transaction request ready for sending or preview - */ + suspend fun send(transactionRequest: TONTransactionRequest): TONSendTransactionResponse + suspend fun transferNFTTransaction(request: TONNFTTransferRequest): TONTransactionRequest - /** - * Create an NFT transfer transaction with raw parameters. - * - * @param request Raw NFT transfer request with full control - * @return Transaction request ready for sending or preview - */ suspend fun transferNFTTransaction(request: TONNFTRawTransferRequest): TONTransactionRequest - /** - * Get NFTs owned by this wallet. - * - * @param request Request with pagination and optional filters - * @return Response with NFTs and address book - */ suspend fun nfts(request: TONNFTsRequest): TONNFTsResponse - /** - * Get a single NFT by address. - * - * @param address NFT contract address - * @return NFT details - */ - suspend fun nft(address: TONUserFriendlyAddress): TONNFT - - /** - * Get balance of a specific jetton. - * - * @param jettonAddress Jetton master contract address - * @return Balance in jetton units - */ + suspend fun nft(address: TONUserFriendlyAddress): TONNFT? + suspend fun jettonBalance(jettonAddress: TONUserFriendlyAddress): TONBalance - /** - * Get jetton wallet address for a specific jetton. - * - * Each user has a unique jetton wallet contract for each jetton they hold. - * - * @param jettonAddress Jetton master contract address - * @return Jetton wallet contract address - */ suspend fun jettonWalletAddress(jettonAddress: TONUserFriendlyAddress): TONUserFriendlyAddress - /** - * Create a jetton transfer transaction. - * - * @param request Jetton transfer request - * @return Transaction request ready for sending or preview - */ suspend fun transferJettonTransaction(request: TONJettonsTransferRequest): TONTransactionRequest - /** - * Get jettons owned by this wallet. - * - * @param request Request with pagination - * @return Response with jettons and address book - */ - suspend fun jettons(request: TONJettonsRequest): TONJettonsResponse + suspend fun jettons(request: TONJettonsRequest? = null): TONJettonsResponse } -/** - * Get NFTs with a simple limit parameter. - * - * @param limit Maximum number of NFTs to return - * @return Response with NFTs and address book - */ -suspend fun ITONWallet.nfts(limit: Int): TONNFTsResponse { - val request = TONNFTsRequest(pagination = TONPagination(limit = limit)) - return nfts(request) -} +suspend fun ITONWallet.nfts(limit: Int): TONNFTsResponse = + nfts(TONNFTsRequest(pagination = TONPagination(limit = limit))) -/** - * Get jettons with a simple limit parameter. - * - * @param limit Maximum number of jettons to return - * @return Response with jettons and address book - */ -suspend fun ITONWallet.jettons(limit: Int): TONJettonsResponse { - val request = TONJettonsRequest(pagination = TONPagination(limit = limit)) - return jettons(request) -} +suspend fun ITONWallet.jettons(limit: Int): TONJettonsResponse = + jettons(TONJettonsRequest(pagination = TONPagination(limit = limit))) diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/ITONWalletKit.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/ITONWalletKit.kt index 488d608b..bc5bda9b 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/ITONWalletKit.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/ITONWalletKit.kt @@ -38,8 +38,8 @@ import io.ton.walletkit.gasless.ITONGaslessManager import io.ton.walletkit.gasless.tonapi.TONApiGaslessProvider import io.ton.walletkit.internal.TONWalletKitFactory import io.ton.walletkit.listener.TONBridgeEventsHandler +import io.ton.walletkit.model.ITONWalletAdapter import io.ton.walletkit.model.KeyPair -import io.ton.walletkit.model.TONWalletAdapter import io.ton.walletkit.model.WalletSigner import io.ton.walletkit.model.WalletSignerInfo import io.ton.walletkit.request.TONWalletConnectionRequest @@ -107,7 +107,7 @@ interface ITONWalletKit { workchain: Int = WalletKitConstants.DEFAULT_WORKCHAIN, walletId: Long = WalletKitConstants.DEFAULT_WALLET_ID_V5R1, domain: TONSignatureDomain? = null, - ): TONWalletAdapter + ): ITONWalletAdapter /** * Create a V4R2 wallet adapter. @@ -120,19 +120,19 @@ interface ITONWalletKit { workchain: Int = WalletKitConstants.DEFAULT_WORKCHAIN, walletId: Long = WalletKitConstants.DEFAULT_WALLET_ID_V4R2, domain: TONSignatureDomain? = null, - ): TONWalletAdapter + ): ITONWalletAdapter // ── Add wallet ── /** - * Add a wallet using a [TONWalletAdapter]. + * Add a wallet using a [ITONWalletAdapter]. */ - suspend fun addWallet(adapter: TONWalletAdapter): ITONWallet + suspend fun addWallet(adapter: ITONWalletAdapter): ITONWallet suspend fun getWallets(): List /** - * Get a wallet by its ID (from [TONWalletAdapter.identifier]). + * Get a wallet by its ID (from [ITONWalletAdapter.identifier]). */ suspend fun getWallet(walletId: String): ITONWallet? diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/gasless/ITONGaslessManager.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/gasless/ITONGaslessManager.kt index bb475f63..5425f030 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/gasless/ITONGaslessManager.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/gasless/ITONGaslessManager.kt @@ -63,7 +63,7 @@ interface ITONGaslessManager { suspend fun provider(identifier: TONGaslessProviderIdentifier): ITONGaslessProvider? /** Static metadata (display name, logo, url) for [identifier], or the default provider. */ - suspend fun getMetadata(identifier: TONGaslessProviderIdentifier? = null): TONGaslessProviderMetadata + suspend fun metadata(identifier: TONGaslessProviderIdentifier? = null): TONGaslessProviderMetadata /** * Fetch the relayer's config — the relay address and the assets it accepts as fee payment. diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/model/TONWalletAdapter.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/model/ITONWalletAdapter.kt similarity index 91% rename from TONWalletKit-Android/api/src/main/java/io/ton/walletkit/model/TONWalletAdapter.kt rename to TONWalletKit-Android/api/src/main/java/io/ton/walletkit/model/ITONWalletAdapter.kt index 4de7022e..1a1c46af 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/model/TONWalletAdapter.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/model/ITONWalletAdapter.kt @@ -25,20 +25,19 @@ import io.ton.walletkit.api.generated.TONNetwork import io.ton.walletkit.api.generated.TONPreparedSignData import io.ton.walletkit.api.generated.TONProofMessage import io.ton.walletkit.api.generated.TONTransactionRequest +import io.ton.walletkit.client.TONAPIClient import io.ton.walletkit.config.TONWalletKitConfiguration -/** - * Wallet adapter interface for wrapping existing wallet implementations. - */ -interface TONWalletAdapter { - /** Stable unique wallet identifier. */ +interface ITONWalletAdapter { fun identifier(): String suspend fun publicKey(): TONHex fun network(): TONNetwork - fun address(testnet: Boolean): TONUserFriendlyAddress + fun client(): TONAPIClient + + fun address(testnet: Boolean = false): TONUserFriendlyAddress /** State init (base64 BOC) for contract deployment. */ suspend fun stateInit(): TONBase64 diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/request/TONWalletConnectionRequest.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/request/TONWalletConnectionRequest.kt index 9ba68a2c..c29022e0 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/request/TONWalletConnectionRequest.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/request/TONWalletConnectionRequest.kt @@ -44,8 +44,8 @@ class TONWalletConnectionRequest( response: TONConnectionApprovalResponse? = null, ): TONWalletKitEvent? { val updatedEvent = event.copy( - walletId = wallet.id, - walletAddress = wallet.address, + walletId = wallet.identifier(), + walletAddress = wallet.address(), ) val embedded = handler.approveConnect(updatedEvent, response) ?: return null return when (embedded) { diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/staking/ITONStakingManager.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/staking/ITONStakingManager.kt index ac699f9c..9f365a43 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/staking/ITONStakingManager.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/staking/ITONStakingManager.kt @@ -43,10 +43,10 @@ interface ITONStakingManager { * built-in TonStakers provider returned from `ITONWalletKit.tonStakersStakingProvider`, and * any user-defined conformer. */ - suspend fun register(provider: ITONStakingProvider<*, *>) + suspend fun registerProvider(provider: ITONStakingProvider<*, *>) /** Unregister [provider]; no-op if it isn't currently registered. */ - suspend fun remove(provider: ITONStakingProvider<*, *>) + suspend fun removeProvider(provider: ITONStakingProvider<*, *>) /** Set the default provider used when no identifier is passed to query methods. */ suspend fun setDefaultProvider(identifier: TONStakingProviderIdentifier<*, *>) diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/streaming/ITONStreamingManager.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/streaming/ITONStreamingManager.kt index 7b29c49b..f86bf360 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/streaming/ITONStreamingManager.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/streaming/ITONStreamingManager.kt @@ -32,7 +32,7 @@ import kotlinx.coroutines.flow.Flow interface ITONStreamingManager { suspend fun hasProvider(network: TONNetwork): Boolean - suspend fun register(provider: ITONStreamingProvider) + suspend fun registerProvider(provider: ITONStreamingProvider) suspend fun connect() diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/streaming/ITONStreamingProvider.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/streaming/ITONStreamingProvider.kt index 3b51004c..2385c1f3 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/streaming/ITONStreamingProvider.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/streaming/ITONStreamingProvider.kt @@ -29,7 +29,7 @@ import io.ton.walletkit.api.generated.TONTransactionsUpdate import kotlinx.coroutines.flow.Flow interface ITONStreamingProvider { - val id: String + val identifier: String val type: TONProviderType get() = TONProviderType.Streaming val network: TONNetwork diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/swap/ITONSwapProvider.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/swap/ITONSwapProvider.kt index de2f8f16..7f6f8121 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/swap/ITONSwapProvider.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/swap/ITONSwapProvider.kt @@ -51,7 +51,7 @@ interface ITONSwapProvider { suspend fun supportedNetworks(): List /** Get a quote from this provider. */ - suspend fun quote(params: TONSwapQuoteParams): TONSwapQuote + suspend fun getQuote(params: TONSwapQuoteParams): TONSwapQuote /** Build a swap transaction using this provider. */ suspend fun buildSwapTransaction(params: TONSwapParams): TONTransactionRequest diff --git a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/core/TONWallet.kt b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/core/TONWallet.kt index 5aff2e94..24cfca01 100644 --- a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/core/TONWallet.kt +++ b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/core/TONWallet.kt @@ -53,21 +53,18 @@ import kotlinx.serialization.json.Json * wallet.connect("tc://...") * wallet.remove() * ``` - * - * @property id Unique wallet identifier (opaque hash from bridge) - * @property address Wallet address in user-friendly format */ internal class TONWallet internal constructor( - override val id: String, - override val address: TONUserFriendlyAddress, - override val network: TONNetwork, + private val id: String, + private val address: TONUserFriendlyAddress, + private val network: TONNetwork, private val engine: WalletKitEngine, private val account: WalletAccount, ) : ITONWallet { private val json = Json { ignoreUnknownKeys = true } - override val client: TONAPIClient = BridgedJSAPIClient( + private val apiClient: TONAPIClient = BridgedJSAPIClient( walletId = id, engine = engine, network = network, @@ -185,10 +182,7 @@ internal class TONWallet internal constructor( * @return NFT details * @throws WalletKitBridgeException if NFT retrieval fails */ - override suspend fun nft(address: TONUserFriendlyAddress): TONNFT { - return engine.getNft(address.value) - ?: throw WalletKitBridgeException("NFT not found: ${address.value}") - } + override suspend fun nft(address: TONUserFriendlyAddress): TONNFT? = engine.getNft(address.value) /** * Get balance of a specific jetton. @@ -224,7 +218,7 @@ internal class TONWallet internal constructor( override suspend fun transferJettonTransaction(request: TONJettonsTransferRequest): TONTransactionRequest = engine.createTransferJettonTransaction(id, request) - // ── Adapter surface (inherited from TONWalletAdapter via ITONWallet) ── + // ── Adapter surface (inherited from ITONWalletAdapter via ITONWallet) ── override fun identifier(): String = id @@ -232,6 +226,8 @@ internal class TONWallet internal constructor( override fun network(): TONNetwork = network + override fun client(): TONAPIClient = apiClient + override fun address(testnet: Boolean): TONUserFriendlyAddress = address override suspend fun stateInit(): TONBase64 = TONBase64(engine.getWalletStateInit(id)) @@ -256,24 +252,9 @@ internal class TONWallet internal constructor( fakeSignature: Boolean?, ): TONHex = TONHex(engine.getSignedTonProof(id, input, fakeSignature)) - override suspend fun signMessage( - messages: List, - validUntil: Double?, - ): TONBase64 { - val request = TONTransactionRequest(messages = messages, validUntil = validUntil, network = network) - return TONBase64(engine.getSignedSignMessage(id, request)) - } - - /** - * Get jettons owned by this wallet. - * - * @param request Request with pagination - * @return Response with jettons and address book - * @throws WalletKitBridgeException if jetton retrieval fails - */ - override suspend fun jettons(request: TONJettonsRequest): TONJettonsResponse { - val limit = request.pagination?.limit ?: 100 - val offset = request.pagination?.offset ?: 0 + override suspend fun jettons(request: TONJettonsRequest?): TONJettonsResponse { + val limit = request?.pagination?.limit ?: 100 + val offset = request?.pagination?.offset ?: 0 return engine.getJettons(id, limit, offset) } diff --git a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/core/TONWalletKit.kt b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/core/TONWalletKit.kt index 1333e311..6c8d4b75 100644 --- a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/core/TONWalletKit.kt +++ b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/core/TONWalletKit.kt @@ -51,8 +51,8 @@ import io.ton.walletkit.gasless.tonapi.TONApiGaslessProviderIdentifier import io.ton.walletkit.internal.constants.BridgeMethodConstants import io.ton.walletkit.internal.util.WalletKitUtils import io.ton.walletkit.listener.TONBridgeEventsHandler +import io.ton.walletkit.model.ITONWalletAdapter import io.ton.walletkit.model.KeyPair -import io.ton.walletkit.model.TONWalletAdapter import io.ton.walletkit.model.WalletSigner import io.ton.walletkit.model.WalletSignerInfo import io.ton.walletkit.request.TONWalletConnectionRequest @@ -195,7 +195,7 @@ internal class TONWalletKit private constructor( ): ITONStreamingProvider { checkNotDestroyed() val result = engine.callBridgeMethod(BridgeMethodConstants.METHOD_CREATE_TON_CENTER_STREAMING_PROVIDER, config) - return TONStreamingProviderImpl(engine = engine, network = config.network, id = result.optString("providerId")) + return TONStreamingProviderImpl(engine = engine, network = config.network, identifier = result.optString("providerId")) } override suspend fun createStreamingProvider( @@ -203,7 +203,7 @@ internal class TONWalletKit private constructor( ): ITONStreamingProvider { checkNotDestroyed() val result = engine.callBridgeMethod(BridgeMethodConstants.METHOD_CREATE_TON_API_STREAMING_PROVIDER, config) - return TONStreamingProviderImpl(engine = engine, network = config.network, id = result.optString("providerId")) + return TONStreamingProviderImpl(engine = engine, network = config.network, identifier = result.optString("providerId")) } override fun streaming(): ITONStreamingManager { @@ -262,7 +262,7 @@ internal class TONWalletKit private constructor( workchain: Int, walletId: Long, domain: TONSignatureDomain?, - ): TONWalletAdapter { + ): ITONWalletAdapter { checkNotDestroyed() return engine.createAdapter( signerId = signer.signerId, @@ -281,7 +281,7 @@ internal class TONWalletKit private constructor( workchain: Int, walletId: Long, domain: TONSignatureDomain?, - ): TONWalletAdapter { + ): ITONWalletAdapter { checkNotDestroyed() return engine.createAdapter( signerId = signer.signerId, @@ -296,7 +296,7 @@ internal class TONWalletKit private constructor( // ── Add wallet ── - override suspend fun addWallet(adapter: TONWalletAdapter): ITONWallet { + override suspend fun addWallet(adapter: ITONWalletAdapter): ITONWallet { checkNotDestroyed() val account = engine.addWallet(adapter) @@ -418,8 +418,7 @@ internal class TONWalletKit private constructor( */ override suspend fun handleNewTransaction(wallet: ITONWallet, transactionContent: TONTransactionRequest) { checkNotDestroyed() - val addr = wallet.address?.value ?: throw IllegalArgumentException("Wallet address is null") - engine.handleNewTransaction(addr, transactionContent) + engine.handleNewTransaction(wallet.address().value, transactionContent) } /** diff --git a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/core/streaming/TONStreamingManager.kt b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/core/streaming/TONStreamingManager.kt index 48ad1511..5d820225 100644 --- a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/core/streaming/TONStreamingManager.kt +++ b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/core/streaming/TONStreamingManager.kt @@ -61,18 +61,18 @@ internal class TONStreamingManager( } } - override suspend fun register(provider: ITONStreamingProvider) { + override suspend fun registerProvider(provider: ITONStreamingProvider) { if (provider is TONStreamingProviderImpl) { engine.callBridgeMethod( BridgeMethodConstants.METHOD_REGISTER_STREAMING_PROVIDER, - buildJsonObject { put("providerId", provider.id) }, + buildJsonObject { put("providerId", provider.identifier) }, ) } else { - engine.kotlinStreamingProviderManager.register(provider.id, provider) + engine.kotlinStreamingProviderManager.register(provider.identifier, provider) engine.callBridgeMethod( BridgeMethodConstants.METHOD_REGISTER_KOTLIN_STREAMING_PROVIDER, buildJsonObject { - put("providerId", provider.id) + put("providerId", provider.identifier) put("network", buildJsonObject { put("chainId", provider.network.chainId) }) }, ) diff --git a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/core/streaming/TONStreamingProviderImpl.kt b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/core/streaming/TONStreamingProviderImpl.kt index a364bda1..ed4feb96 100644 --- a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/core/streaming/TONStreamingProviderImpl.kt +++ b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/core/streaming/TONStreamingProviderImpl.kt @@ -43,7 +43,7 @@ import kotlinx.serialization.json.put internal class TONStreamingProviderImpl( private val engine: WalletKitEngine, override val network: TONNetwork, - override val id: String, + override val identifier: String, ) : ITONStreamingProvider { override suspend fun connect() { diff --git a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/WalletKitEngine.kt b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/WalletKitEngine.kt index 28fa4b9b..a415632b 100644 --- a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/WalletKitEngine.kt +++ b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/WalletKitEngine.kt @@ -78,9 +78,9 @@ import io.ton.walletkit.engine.state.KotlinStakingProviderManager import io.ton.walletkit.engine.state.KotlinStreamingProviderManager import io.ton.walletkit.engine.state.KotlinSwapProviderManager import io.ton.walletkit.listener.TONBridgeEventsHandler +import io.ton.walletkit.model.ITONWalletAdapter import io.ton.walletkit.model.KeyPair import io.ton.walletkit.model.TONHex -import io.ton.walletkit.model.TONWalletAdapter import io.ton.walletkit.model.WalletSigner import io.ton.walletkit.model.WalletSignerInfo import io.ton.walletkit.request.RequestHandler @@ -192,9 +192,9 @@ internal interface WalletKitEngine : RequestHandler { workchain: Int = 0, walletId: Long = 2147483409L, domain: TONSignatureDomain? = null, - ): TONWalletAdapter + ): ITONWalletAdapter - suspend fun addWallet(adapter: TONWalletAdapter): WalletAccount + suspend fun addWallet(adapter: ITONWalletAdapter): WalletAccount suspend fun getWallets(): List diff --git a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/WebViewWalletKitEngine.kt b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/WebViewWalletKitEngine.kt index 9bb7eb21..b067b35a 100644 --- a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/WebViewWalletKitEngine.kt +++ b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/WebViewWalletKitEngine.kt @@ -185,10 +185,10 @@ import io.ton.walletkit.internal.constants.WebViewConstants import io.ton.walletkit.internal.util.Logger import io.ton.walletkit.internal.util.WalletKitUtils import io.ton.walletkit.listener.TONBridgeEventsHandler +import io.ton.walletkit.model.ITONWalletAdapter import io.ton.walletkit.model.KeyPair import io.ton.walletkit.model.TONHex import io.ton.walletkit.model.TONUserFriendlyAddress -import io.ton.walletkit.model.TONWalletAdapter import io.ton.walletkit.model.WalletSigner import io.ton.walletkit.model.WalletSignerInfo import io.ton.walletkit.request.TONWalletConnectionRequest @@ -341,7 +341,7 @@ internal class WebViewWalletKitEngine private constructor( override suspend fun createTonMnemonic(wordCount: Int): List = rpcClient.createTonMnemonic(wordCount) - override suspend fun addWallet(adapter: TONWalletAdapter): WalletAccount { + override suspend fun addWallet(adapter: ITONWalletAdapter): WalletAccount { // BridgeWalletAdapter wraps a JS-side adapter; route through its stable adapterId so we don't // re-register in AdapterManager or create a duplicate proxy in JS. val adapterId = if (adapter is BridgeWalletAdapter) adapter.adapterId else adapterManager.registerAdapter(adapter) @@ -371,7 +371,7 @@ internal class WebViewWalletKitEngine private constructor( workchain: Int, walletId: Long, domain: TONSignatureDomain?, - ): TONWalletAdapter { + ): ITONWalletAdapter { val resolvedNetwork = network ?: TONNetwork(chainId = "-239") val response = rpcClient.createWalletAdapter(version, signerId, resolvedNetwork, workchain, walletId, domain) val adapterId = response.adapterId?.takeIf { it.isNotEmpty() } diff --git a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/adapter/BridgeWalletAdapter.kt b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/adapter/BridgeWalletAdapter.kt index 7bfd66bb..8551e235 100644 --- a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/adapter/BridgeWalletAdapter.kt +++ b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/adapter/BridgeWalletAdapter.kt @@ -25,13 +25,14 @@ import io.ton.walletkit.api.generated.TONNetwork import io.ton.walletkit.api.generated.TONPreparedSignData import io.ton.walletkit.api.generated.TONProofMessage import io.ton.walletkit.api.generated.TONTransactionRequest +import io.ton.walletkit.client.TONAPIClient import io.ton.walletkit.engine.infrastructure.BridgeRpcClient import io.ton.walletkit.internal.constants.BridgeMethodConstants import io.ton.walletkit.internal.util.Logger +import io.ton.walletkit.model.ITONWalletAdapter import io.ton.walletkit.model.TONBase64 import io.ton.walletkit.model.TONHex import io.ton.walletkit.model.TONUserFriendlyAddress -import io.ton.walletkit.model.TONWalletAdapter import io.ton.walletkit.model.WalletAdapterInfo import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.GlobalScope @@ -49,7 +50,7 @@ internal class BridgeWalletAdapter( private val cachedNetwork: TONNetwork, private val cachedAddress: TONUserFriendlyAddress, private val rpcClient: BridgeRpcClient, -) : TONWalletAdapter { +) : ITONWalletAdapter { override fun identifier(): String = adapterId @@ -57,6 +58,8 @@ internal class BridgeWalletAdapter( override fun network(): TONNetwork = cachedNetwork + override fun client(): TONAPIClient = throw UnsupportedOperationException("BridgeWalletAdapter delegates to JS engine") + override fun address(testnet: Boolean): TONUserFriendlyAddress = cachedAddress override suspend fun stateInit(): TONBase64 { diff --git a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/state/AdapterManager.kt b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/state/AdapterManager.kt index f34022ff..2389eaf3 100644 --- a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/state/AdapterManager.kt +++ b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/state/AdapterManager.kt @@ -21,7 +21,7 @@ */ package io.ton.walletkit.engine.state -import io.ton.walletkit.model.TONWalletAdapter +import io.ton.walletkit.model.ITONWalletAdapter import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import java.util.concurrent.ConcurrentHashMap @@ -40,13 +40,13 @@ import java.util.concurrent.ConcurrentHashMap * @suppress Internal component. Exposed via [WebViewWalletKitEngine] only. */ internal class AdapterManager { - private val adapters = ConcurrentHashMap() + private val adapters = ConcurrentHashMap() private val mutex = Mutex() /** * Register a wallet adapter and obtain a unique ID for the JS bridge. */ - suspend fun registerAdapter(adapter: TONWalletAdapter): String = mutex.withLock { + suspend fun registerAdapter(adapter: ITONWalletAdapter): String = mutex.withLock { val adapterId = buildString { append("native_adapter_") append(System.currentTimeMillis()) @@ -60,7 +60,7 @@ internal class AdapterManager { /** * Look up an adapter by ID. */ - fun getAdapter(adapterId: String): TONWalletAdapter? = adapters[adapterId] + fun getAdapter(adapterId: String): ITONWalletAdapter? = adapters[adapterId] /** * Remove an adapter from the registry. diff --git a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/state/KotlinSwapProviderManager.kt b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/state/KotlinSwapProviderManager.kt index 1af1647b..8016e59a 100644 --- a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/state/KotlinSwapProviderManager.kt +++ b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/engine/state/KotlinSwapProviderManager.kt @@ -40,7 +40,7 @@ internal class KotlinSwapProviderManager : override val tag: String = "KotlinSwapProviderManager" suspend fun quote(providerId: String, params: TONSwapQuoteParams): TONSwapQuote = - require(providerId).quote(params) + require(providerId).getQuote(params) suspend fun buildSwapTransaction(providerId: String, params: TONSwapParams): TONTransactionRequest = require(providerId).buildSwapTransaction(params) diff --git a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/gasless/TONGaslessManager.kt b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/gasless/TONGaslessManager.kt index 446d881c..4dd0e50b 100644 --- a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/gasless/TONGaslessManager.kt +++ b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/gasless/TONGaslessManager.kt @@ -52,7 +52,7 @@ internal class TONGaslessManager( override suspend fun provider(identifier: TONGaslessProviderIdentifier): ITONGaslessProvider = BuiltInGaslessProvider(identifier, engine) - override suspend fun getMetadata(identifier: TONGaslessProviderIdentifier?): TONGaslessProviderMetadata = + override suspend fun metadata(identifier: TONGaslessProviderIdentifier?): TONGaslessProviderMetadata = engine.getGaslessMetadata(identifier?.name) override suspend fun getConfig( diff --git a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/staking/TONStakingManager.kt b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/staking/TONStakingManager.kt index f302b867..42a0419e 100644 --- a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/staking/TONStakingManager.kt +++ b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/staking/TONStakingManager.kt @@ -43,7 +43,7 @@ internal class TONStakingManager( private val engine: WalletKitEngine, ) : ITONStakingManager { - override suspend fun register(provider: ITONStakingProvider<*, *>) { + override suspend fun registerProvider(provider: ITONStakingProvider<*, *>) { if (provider is BuiltInStakingProvider<*, *>) { // Built-in JS-backed provider: the JS side already has the instance; just register its name. engine.registerStakingProvider(provider.identifier.name) @@ -60,7 +60,7 @@ internal class TONStakingManager( } } - override suspend fun remove(provider: ITONStakingProvider<*, *>) { + override suspend fun removeProvider(provider: ITONStakingProvider<*, *>) { val name = provider.identifier.name engine.removeStakingProvider(name) // Local Kotlin registry is keyed by the same name; safe to drop unconditionally. diff --git a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/swap/BuiltInSwapProvider.kt b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/swap/BuiltInSwapProvider.kt index 1e250071..e8aa86a9 100644 --- a/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/swap/BuiltInSwapProvider.kt +++ b/TONWalletKit-Android/impl/src/main/java/io/ton/walletkit/swap/BuiltInSwapProvider.kt @@ -51,7 +51,7 @@ internal class BuiltInSwapProvider( override suspend fun supportedNetworks(): List = engine.getSwapProviderSupportedNetworks(identifier.name) - override suspend fun quote(params: TONSwapQuoteParams): TONSwapQuote { + override suspend fun getQuote(params: TONSwapQuoteParams): TONSwapQuote { val jsonOptions = params.providerOptions?.let { Json.encodeToJsonElement(SwapSerializers.quoteSerializer(identifier), it) } diff --git a/TONWalletKit-Android/impl/src/test/java/io/ton/walletkit/CustomWalletAdapterTest.kt b/TONWalletKit-Android/impl/src/test/java/io/ton/walletkit/CustomWalletAdapterTest.kt index 4f38d358..a683eb11 100644 --- a/TONWalletKit-Android/impl/src/test/java/io/ton/walletkit/CustomWalletAdapterTest.kt +++ b/TONWalletKit-Android/impl/src/test/java/io/ton/walletkit/CustomWalletAdapterTest.kt @@ -25,11 +25,12 @@ import io.ton.walletkit.api.generated.TONNetwork import io.ton.walletkit.api.generated.TONPreparedSignData import io.ton.walletkit.api.generated.TONProofMessage import io.ton.walletkit.api.generated.TONTransactionRequest +import io.ton.walletkit.client.TONAPIClient import io.ton.walletkit.config.TONWalletKitConfiguration +import io.ton.walletkit.model.ITONWalletAdapter import io.ton.walletkit.model.TONBase64 import io.ton.walletkit.model.TONHex import io.ton.walletkit.model.TONUserFriendlyAddress -import io.ton.walletkit.model.TONWalletAdapter import kotlinx.coroutines.test.runTest import org.junit.Assert.assertEquals import org.junit.Assert.assertNotNull @@ -38,7 +39,7 @@ import org.junit.Assert.assertTrue import org.junit.Test /** - * Tests for the user-implementable [TONWalletAdapter] contract — in particular the + * Tests for the user-implementable [ITONWalletAdapter] contract — in particular the * `signedSignMessage` method added for TON-1240 parity with iOS `TONWalletAdapterProtocol`. * * Mirrors iOS `TONWalletAdapterTests` / `TONWalletAdapterJSAdapterTests` at the interface layer. @@ -50,7 +51,7 @@ class CustomWalletAdapterTest { private val pubKey: String = "0xpub", private val net: TONNetwork = TONNetwork(chainId = "-239"), private val addr: String = "EQCD39VS5jcptHL8vMjEXrzGaRcCVYto7HUn4bpAOg8xqB2N", - ) : TONWalletAdapter { + ) : ITONWalletAdapter { var stateInitCalls = 0 var signedSendTransactionCalls = 0 var signedSignMessageCalls = 0 @@ -60,6 +61,7 @@ class CustomWalletAdapterTest { override fun identifier(): String = adapterId override suspend fun publicKey(): TONHex = TONHex(pubKey) override fun network(): TONNetwork = net + override fun client(): TONAPIClient = throw NotImplementedError() override fun address(testnet: Boolean): TONUserFriendlyAddress = TONUserFriendlyAddress(addr) override suspend fun stateInit(): TONBase64 { diff --git a/TONWalletKit-Android/impl/src/test/java/io/ton/walletkit/WalletManagementTest.kt b/TONWalletKit-Android/impl/src/test/java/io/ton/walletkit/WalletManagementTest.kt index e698ff0b..bf78cbfe 100644 --- a/TONWalletKit-Android/impl/src/test/java/io/ton/walletkit/WalletManagementTest.kt +++ b/TONWalletKit-Android/impl/src/test/java/io/ton/walletkit/WalletManagementTest.kt @@ -38,7 +38,7 @@ class WalletManagementTest { private fun createMockWallet(addressString: String): ITONWallet { return mockk(relaxed = true) { - every { this@mockk.address } returns TONUserFriendlyAddress(addressString) + every { this@mockk.address(any()) } returns TONUserFriendlyAddress(addressString) } } @@ -53,7 +53,7 @@ class WalletManagementTest { val wallet = mockKit.getWallet(address.value) assertNotNull(wallet) - assertEquals(address, wallet?.address) + assertEquals(address, wallet?.address()) coVerify(exactly = 1) { mockKit.getWallet(address.value) } } @@ -161,8 +161,8 @@ class WalletManagementTest { val wallets = mockKit.getWallets() assertEquals(2, wallets.size) - assertEquals(expectedWallets[0].address, wallets[0].address) - assertEquals(expectedWallets[1].address, wallets[1].address) + assertEquals(expectedWallets[0].address(), wallets[0].address()) + assertEquals(expectedWallets[1].address(), wallets[1].address()) } @Test @@ -188,7 +188,7 @@ class WalletManagementTest { // Verify wallet2 still exists val existingWallet = mockKit.getWallet(address2.value) assertNotNull(existingWallet) - assertEquals(address2, existingWallet?.address) + assertEquals(address2, existingWallet?.address()) // Verify removeWallet was called with correct address coVerify(exactly = 1) { mockKit.removeWallet(address1.value) } diff --git a/TONWalletKit-Android/impl/src/test/java/io/ton/walletkit/mockbridge/DelayedReadyMockTest.kt b/TONWalletKit-Android/impl/src/test/java/io/ton/walletkit/mockbridge/DelayedReadyMockTest.kt index f178c492..4e5abcd1 100644 --- a/TONWalletKit-Android/impl/src/test/java/io/ton/walletkit/mockbridge/DelayedReadyMockTest.kt +++ b/TONWalletKit-Android/impl/src/test/java/io/ton/walletkit/mockbridge/DelayedReadyMockTest.kt @@ -121,8 +121,8 @@ class DelayedReadyMockTest : MockBridgeTestBase() { val wallet = sdk.addWallet(adapter) assertNotNull("Wallet should be created", wallet) - assertNotNull("Wallet should have address", wallet.address) - assertTrue("Wallet address should not be empty", wallet.address!!.value.isNotEmpty()) + assertNotNull("Wallet should have address", wallet.address()) + assertTrue("Wallet address should not be empty", wallet.address().value.isNotEmpty()) } } } diff --git a/TONWalletKit-Android/impl/src/test/java/io/ton/walletkit/mockbridge/EngineMethodEfficiencyTests.kt b/TONWalletKit-Android/impl/src/test/java/io/ton/walletkit/mockbridge/EngineMethodEfficiencyTests.kt index 442d2ee5..f1c5431e 100644 --- a/TONWalletKit-Android/impl/src/test/java/io/ton/walletkit/mockbridge/EngineMethodEfficiencyTests.kt +++ b/TONWalletKit-Android/impl/src/test/java/io/ton/walletkit/mockbridge/EngineMethodEfficiencyTests.kt @@ -29,8 +29,8 @@ import io.ton.walletkit.listener.TONBridgeEventsHandler import io.ton.walletkit.mockbridge.infra.DefaultMockScenario import io.ton.walletkit.mockbridge.infra.MockBridgeTestBase import io.ton.walletkit.mockbridge.infra.MockScenario +import io.ton.walletkit.model.ITONWalletAdapter import io.ton.walletkit.model.TONHex -import io.ton.walletkit.model.TONWalletAdapter import io.ton.walletkit.model.WalletSignerInfo import kotlinx.coroutines.test.runTest import org.junit.Assert.assertEquals @@ -93,7 +93,7 @@ class EngineMethodEfficiencyTests : MockBridgeTestBase() { network: TONNetwork?, workchain: Int, walletId: Long, - ): TONWalletAdapter { + ): ITONWalletAdapter { createAdapterCount.incrementAndGet() return super.handleCreateAdapter(signerId, publicKey, version, network, workchain, walletId) } diff --git a/TONWalletKit-Android/impl/src/test/java/io/ton/walletkit/mockbridge/infra/MockScenario.kt b/TONWalletKit-Android/impl/src/test/java/io/ton/walletkit/mockbridge/infra/MockScenario.kt index 9b4b491a..a6da7653 100644 --- a/TONWalletKit-Android/impl/src/test/java/io/ton/walletkit/mockbridge/infra/MockScenario.kt +++ b/TONWalletKit-Android/impl/src/test/java/io/ton/walletkit/mockbridge/infra/MockScenario.kt @@ -28,12 +28,13 @@ import io.ton.walletkit.api.generated.TONNetwork import io.ton.walletkit.api.generated.TONPreparedSignData import io.ton.walletkit.api.generated.TONProofMessage import io.ton.walletkit.api.generated.TONTransactionRequest +import io.ton.walletkit.client.TONAPIClient import io.ton.walletkit.config.TONWalletKitConfiguration import io.ton.walletkit.engine.model.WalletAccount +import io.ton.walletkit.model.ITONWalletAdapter import io.ton.walletkit.model.TONBase64 import io.ton.walletkit.model.TONHex import io.ton.walletkit.model.TONUserFriendlyAddress -import io.ton.walletkit.model.TONWalletAdapter import io.ton.walletkit.model.WalletSignerInfo import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.buildJsonObject @@ -88,14 +89,15 @@ interface MockScenario { network: TONNetwork?, workchain: Int, walletId: Long, - ): TONWalletAdapter { + ): ITONWalletAdapter { val adapterId = "adapter-$version-${signerId.hashCode().toString(16)}" val resolvedNetwork = network ?: TONNetwork.TESTNET val address = TONUserFriendlyAddress("EQDTest${signerId.hashCode().toString(16).padStart(40, '0')}") - return object : TONWalletAdapter { + return object : ITONWalletAdapter { override fun identifier() = adapterId override suspend fun publicKey() = publicKey override fun network() = resolvedNetwork + override fun client(): TONAPIClient = throw NotImplementedError() override fun address(testnet: Boolean) = address override suspend fun stateInit() = TONBase64("") override suspend fun signedSendTransaction(input: TONTransactionRequest, fakeSignature: Boolean?) = TONBase64("") diff --git a/TONWalletKit-Android/impl/src/test/java/io/ton/walletkit/mockbridge/infra/TestWalletKitFactory.kt b/TONWalletKit-Android/impl/src/test/java/io/ton/walletkit/mockbridge/infra/TestWalletKitFactory.kt index eba24819..0562d045 100644 --- a/TONWalletKit-Android/impl/src/test/java/io/ton/walletkit/mockbridge/infra/TestWalletKitFactory.kt +++ b/TONWalletKit-Android/impl/src/test/java/io/ton/walletkit/mockbridge/infra/TestWalletKitFactory.kt @@ -33,7 +33,7 @@ import io.ton.walletkit.core.TONWalletKit import io.ton.walletkit.engine.WalletKitEngine import io.ton.walletkit.event.TONWalletKitEvent import io.ton.walletkit.listener.TONBridgeEventsHandler -import io.ton.walletkit.model.TONWalletAdapter +import io.ton.walletkit.model.ITONWalletAdapter import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.add import java.util.concurrent.CopyOnWriteArrayList @@ -147,8 +147,8 @@ internal object TestWalletKitFactory { } // Setup addWallet - coEvery { mockEngine.addWallet(any()) } answers { - val adapter = firstArg() + coEvery { mockEngine.addWallet(any()) } answers { + val adapter = firstArg() scenario.handleAddWallet(adapter.identifier()) } From f837d507967c7ff8fbcecfaa805c32f0863ca6a5 Mon Sep 17 00:00:00 2001 From: Dmitrii Nikulin Date: Tue, 16 Jun 2026 14:48:03 +0300 Subject: [PATCH 8/9] fix: correct default name for TONApiGaslessProviderIdentifier --- .../walletkit/gasless/tonapi/TONApiGaslessProviderIdentifier.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/gasless/tonapi/TONApiGaslessProviderIdentifier.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/gasless/tonapi/TONApiGaslessProviderIdentifier.kt index d78f48db..6f70e88e 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/gasless/tonapi/TONApiGaslessProviderIdentifier.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/gasless/tonapi/TONApiGaslessProviderIdentifier.kt @@ -25,7 +25,7 @@ import io.ton.walletkit.gasless.ITONGaslessProvider import io.ton.walletkit.gasless.TONGaslessProviderIdentifier /** Identifier for the built-in TonAPI gasless provider. */ -class TONApiGaslessProviderIdentifier(override val name: String = "tonApiGasless") : +class TONApiGaslessProviderIdentifier(override val name: String = "tonapi") : TONGaslessProviderIdentifier /** Typed handle for the built-in TonAPI gasless provider. */ From be76473afc04e05cb7cbb7d8881b845117c8cb64 Mon Sep 17 00:00:00 2001 From: Dmitrii Nikulin Date: Thu, 18 Jun 2026 10:58:04 +0300 Subject: [PATCH 9/9] feat: bump WALLETKIT_BRIDGE_TAG & update mjs & models --- Scripts/generate-api/generate-api-models.sh | 48 + .../api/generated/TONCryptoOnrampDeposit.kt | 78 ++ .../generated/TONCryptoOnrampDepositParams.kt | 51 ++ .../TONCryptoOnrampDestinationCurrency.kt | 69 ++ .../TONCryptoOnrampProviderMetadata.kt | 86 ++ ...TONCryptoOnrampProviderMetadataOverride.kt | 59 ++ .../api/generated/TONCryptoOnrampQuote.kt | 66 ++ .../generated/TONCryptoOnrampQuoteParams.kt | 63 ++ .../TONCryptoOnrampSourceCurrency.kt | 74 ++ .../api/generated/TONCryptoOnrampStatus.kt | 77 ++ .../generated/TONCryptoOnrampStatusParams.kt | 54 ++ .../TONCryptoOnrampSupportedCurrencies.kt | 52 ++ .../api/generated/TONDefiProviderType.kt | 7 +- .../walletkit/api/generated/TONJettonInfo.kt | 99 ++ .../api/generated/TONJettonVerification.kt | 76 ++ TONWalletKit-Android/gradle.properties | 2 +- .../walletkit/walletkit-android-bridge.mjs | 866 ++++++++++++------ 17 files changed, 1524 insertions(+), 303 deletions(-) create mode 100644 TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampDeposit.kt create mode 100644 TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampDepositParams.kt create mode 100644 TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampDestinationCurrency.kt create mode 100644 TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampProviderMetadata.kt create mode 100644 TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampProviderMetadataOverride.kt create mode 100644 TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampQuote.kt create mode 100644 TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampQuoteParams.kt create mode 100644 TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampSourceCurrency.kt create mode 100644 TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampStatus.kt create mode 100644 TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampStatusParams.kt create mode 100644 TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampSupportedCurrencies.kt create mode 100644 TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONJettonInfo.kt create mode 100644 TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONJettonVerification.kt diff --git a/Scripts/generate-api/generate-api-models.sh b/Scripts/generate-api/generate-api-models.sh index c1d2a185..6a9b7f22 100755 --- a/Scripts/generate-api/generate-api-models.sh +++ b/Scripts/generate-api/generate-api-models.sh @@ -225,6 +225,54 @@ def normalize_screaming_snake_type_names(): normalize_screaming_snake_type_names() +# Backfill generic property type references the upstream spec generator omits. A property whose +# `$ref` targets a generic model (one carrying `x-generic-params`) must itself carry +# `x-generic-type-ref` so the Kotlin template emits the type argument +# (e.g. `quote: TONCryptoOnrampQuote`); without it the property renders as the bare +# generic class and fails to compile. The owning class's type params not already claimed by a +# sibling `x-generic-type-ref` are assigned in declaration order. The "TON" prefix mirrors +# modelNamePrefix in generate-api-models-config.json. Mutates the rewritten `data` (see +# add_inheritance). No-op once upstream emits the extension directly. +def backfill_generic_type_refs(): + out_schemas = data.get("components", {}).get("schemas", {}) or {} + arity = { + name: len(sc["x-generic-params"]) + for name, sc in out_schemas.items() + if isinstance(sc, dict) and sc.get("x-generic-params") + } + if not arity: + return + for sc in out_schemas.values(): + if not isinstance(sc, dict): + continue + params = [p.get("name") for p in (sc.get("x-generic-params") or []) if isinstance(p, dict)] + if not params: + continue + props = sc.get("properties") or {} + claimed = { + pd["x-generic-type-ref"] + for pd in props.values() + if isinstance(pd, dict) and isinstance(pd.get("x-generic-type-ref"), str) + } + free = [p for p in params if p not in claimed] + for pd in props.values(): + if not isinstance(pd, dict) or "x-generic-type-ref" in pd: + continue + ref = pd.get("$ref") + target = ref.rsplit("/", 1)[-1] if isinstance(ref, str) else None + if target not in arity: + continue + args = free[:arity[target]] + if len(args) != arity[target]: + continue + del free[:len(args)] + # OpenAPI 3.0 ignores keywords sibling to `$ref`, so move the ref under `allOf` to keep + # the extension live while still resolving the referenced model. + pd["allOf"] = [{"$ref": pd.pop("$ref")}] + pd["x-generic-type-ref"] = "TON%s<%s>" % (target, ", ".join(args)) + +backfill_generic_type_refs() + with open(target, "w", encoding="utf-8") as f: json.dump(data, f, indent=2) PY diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampDeposit.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampDeposit.kt new file mode 100644 index 00000000..34773807 --- /dev/null +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampDeposit.kt @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2025 TonTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport", +) + +package io.ton.walletkit.api.generated + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +/** + * Deposit details returned by a crypto onramp provider. The user must send `amount` of `sourceCurrency` to `address` to complete the onramp; the provider then delivers the target crypto to the user's TON address. + * + * @param depositId Deposit id + * @param address Deposit address on the source chain + * @param amount Exact amount of source crypto the user must send (in base units of `sourceCurrency.decimals`). + * @param sourceCurrency + * @param providerId Identifier of the provider that issued this deposit + * @param memo Optional memo / tag required by some chains (e.g. XRP, TON comment) + * @param expiresAt Unix timestamp (ms) after which the deposit offer is no longer valid + */ +@Serializable +data class TONCryptoOnrampDeposit( + + /* Deposit id */ + @SerialName(value = "depositId") + var depositId: kotlin.String, + + /* Deposit address on the source chain */ + @SerialName(value = "address") + var address: kotlin.String, + + /* Exact amount of source crypto the user must send (in base units of `sourceCurrency.decimals`). */ + @SerialName(value = "amount") + var amount: kotlin.String, + + @SerialName(value = "sourceCurrency") + var sourceCurrency: TONCryptoOnrampSourceCurrency, + + /* Identifier of the provider that issued this deposit */ + @SerialName(value = "providerId") + var providerId: kotlin.String, + + /* Optional memo / tag required by some chains (e.g. XRP, TON comment) */ + @SerialName(value = "memo") + var memo: kotlin.String? = null, + + /* Unix timestamp (ms) after which the deposit offer is no longer valid */ + @SerialName(value = "expiresAt") + var expiresAt: kotlin.Double? = null, + +) { + + companion object +} diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampDepositParams.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampDepositParams.kt new file mode 100644 index 00000000..f5d0fbbd --- /dev/null +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampDepositParams.kt @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2025 TonTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport", +) + +package io.ton.walletkit.api.generated + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +/** + * + * + * @param quote Quote to execute the deposit against (contains recipientAddress and provider metadata) + * @param refundAddress Address to refund the crypto to in case of failure + * @param providerOptions Provider-specific options + */ +@Serializable +data class TONCryptoOnrampDepositParams( + @SerialName("quote") + var quote: TONCryptoOnrampQuote, + @SerialName("refundAddress") + var refundAddress: kotlin.String, + @SerialName("providerOptions") + var providerOptions: TProviderOptions? = null, +) { + companion object +} diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampDestinationCurrency.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampDestinationCurrency.kt new file mode 100644 index 00000000..f37447a2 --- /dev/null +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampDestinationCurrency.kt @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2025 TonTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport", +) + +package io.ton.walletkit.api.generated + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +/** + * A destination currency the user receives on TON. Chain is implicit (always TON). + * + * @param address Jetton master address (e.g. `'EQCx...'`), or `'ton'` for native Toncoin. + * @param symbol Token symbol, e.g. `'TON'`, `'USDT'`. + * @param decimals Decimals + * @param name Full token name. + * @param logo Logo URL. + */ +@Serializable +data class TONCryptoOnrampDestinationCurrency( + + /* Jetton master address (e.g. `'EQCx...'`), or `'ton'` for native Toncoin. */ + @SerialName(value = "address") + var address: kotlin.String, + + /* Token symbol, e.g. `'TON'`, `'USDT'`. */ + @SerialName(value = "symbol") + var symbol: kotlin.String, + + /* Decimals */ + @SerialName(value = "decimals") + var decimals: kotlin.Int, + + /* Full token name. */ + @SerialName(value = "name") + var name: kotlin.String? = null, + + /* Logo URL. */ + @SerialName(value = "logo") + var logo: kotlin.String? = null, + +) { + + companion object +} diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampProviderMetadata.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampProviderMetadata.kt new file mode 100644 index 00000000..b37fb36a --- /dev/null +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampProviderMetadata.kt @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2025 TonTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport", +) + +package io.ton.walletkit.api.generated + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +/** + * Static metadata for a crypto-onramp provider. + * + * @param name Human-readable provider name (e.g. 'Decent') + * @param logo URL to the provider's logo image + * @param url URL to the provider's website + * @param refundAddressMode Refund-address collection mode for this provider: - `'off'` (default): no refund address — the UI skips the address modal entirely. - `'optional'`: the UI shows the address modal with a \"Skip\" button — users may enter an address or proceed without one. - `'required'`: the UI shows the address modal and blocks submission until a non-empty address is entered. + * @param isReversedAmountSupported Whether this provider supports reversed (target-amount) quotes. When false, the UI should hide the direction toggle and only allow source-amount input. + */ +@Serializable +data class TONCryptoOnrampProviderMetadata( + + /* Human-readable provider name (e.g. 'Decent') */ + @SerialName(value = "name") + var name: kotlin.String, + + /* URL to the provider's logo image */ + @SerialName(value = "logo") + var logo: kotlin.String? = null, + + /* URL to the provider's website */ + @SerialName(value = "url") + var url: kotlin.String? = null, + + /* Refund-address collection mode for this provider: - `'off'` (default): no refund address — the UI skips the address modal entirely. - `'optional'`: the UI shows the address modal with a \"Skip\" button — users may enter an address or proceed without one. - `'required'`: the UI shows the address modal and blocks submission until a non-empty address is entered. */ + @SerialName(value = "refundAddressMode") + var refundAddressMode: TONCryptoOnrampProviderMetadata.RefundAddressMode? = null, + + /* Whether this provider supports reversed (target-amount) quotes. When false, the UI should hide the direction toggle and only allow source-amount input. */ + @SerialName(value = "isReversedAmountSupported") + var isReversedAmountSupported: kotlin.Boolean? = null, + +) { + + companion object + + /** + * Refund-address collection mode for this provider: - `'off'` (default): no refund address — the UI skips the address modal entirely. - `'optional'`: the UI shows the address modal with a \"Skip\" button — users may enter an address or proceed without one. - `'required'`: the UI shows the address modal and blocks submission until a non-empty address is entered. + * + * Values: off,optional,required + */ + @Serializable + enum class RefundAddressMode(val value: kotlin.String) { + @SerialName(value = "off") + off("off"), + + @SerialName(value = "optional") + optional("optional"), + + @SerialName(value = "required") + required("required"), + } +} diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampProviderMetadataOverride.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampProviderMetadataOverride.kt new file mode 100644 index 00000000..a8d0307f --- /dev/null +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampProviderMetadataOverride.kt @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2025 TonTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport", +) + +package io.ton.walletkit.api.generated + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +/** + * Used in provider configuration to override fields of the provider's metadata. + * + * @param name Override the provider's display name + * @param logo Override the provider's logo URL + * @param url Override the provider's website URL + */ +@Serializable +data class TONCryptoOnrampProviderMetadataOverride( + + /* Override the provider's display name */ + @SerialName(value = "name") + var name: kotlin.String? = null, + + /* Override the provider's logo URL */ + @SerialName(value = "logo") + var logo: kotlin.String? = null, + + /* Override the provider's website URL */ + @SerialName(value = "url") + var url: kotlin.String? = null, + +) { + + companion object +} diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampQuote.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampQuote.kt new file mode 100644 index 00000000..6b299a99 --- /dev/null +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampQuote.kt @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2025 TonTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport", +) + +package io.ton.walletkit.api.generated + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +/** + * + * + * @param sourceCurrency + * @param targetCurrency + * @param sourceAmount Amount of source crypto to send (in base units of `sourceCurrency.decimals`). + * @param targetAmount Amount of target crypto to receive (in base units of `targetCurrency.decimals`). + * @param rate Exchange rate (amount of target per 1 unit of source) + * @param recipientAddress TON address that will receive the target crypto + * @param providerId Identifier of the crypto onramp provider + * @param metadata Provider-specific metadata for the quote (e.g. raw response needed to execute) + */ +@Serializable +data class TONCryptoOnrampQuote( + @SerialName("sourceCurrency") + var sourceCurrency: TONCryptoOnrampSourceCurrency, + @SerialName("targetCurrency") + var targetCurrency: TONCryptoOnrampDestinationCurrency, + @SerialName("sourceAmount") + var sourceAmount: kotlin.String, + @SerialName("targetAmount") + var targetAmount: kotlin.String, + @SerialName("rate") + var rate: kotlin.String, + @SerialName("recipientAddress") + var recipientAddress: kotlin.String, + @SerialName("providerId") + var providerId: kotlin.String, + @SerialName("metadata") + var metadata: TMetadata? = null, +) { + companion object +} diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampQuoteParams.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampQuoteParams.kt new file mode 100644 index 00000000..cee6c90e --- /dev/null +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampQuoteParams.kt @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2025 TonTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport", +) + +package io.ton.walletkit.api.generated + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +/** + * + * + * @param amount Amount to onramp (either source or target crypto, depending on isSourceAmount) + * @param sourceCurrency + * @param targetCurrency + * @param recipientAddress TON address that will receive the target crypto + * @param refundAddress Refund address for the source crypto + * @param isSourceAmount If true, `amount` is the source amount to spend. If false, `amount` is the target amount to receive. Defaults to true when omitted. + * @param providerOptions Provider-specific options + */ +@Serializable +data class TONCryptoOnrampQuoteParams( + @SerialName("amount") + var amount: kotlin.String, + @SerialName("sourceCurrency") + var sourceCurrency: TONCryptoOnrampSourceCurrency, + @SerialName("targetCurrency") + var targetCurrency: TONCryptoOnrampDestinationCurrency, + @SerialName("recipientAddress") + var recipientAddress: kotlin.String, + @SerialName("refundAddress") + var refundAddress: kotlin.String? = null, + @SerialName("isSourceAmount") + var isSourceAmount: kotlin.Boolean? = null, + @SerialName("providerOptions") + var providerOptions: TProviderOptions? = null, +) { + companion object +} diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampSourceCurrency.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampSourceCurrency.kt new file mode 100644 index 00000000..ac4fc4ac --- /dev/null +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampSourceCurrency.kt @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2025 TonTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport", +) + +package io.ton.walletkit.api.generated + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +/** + * A source currency the user can spend to onramp into a TON asset. Always lives on a non-TON chain (identified by CAIP-2). + * + * @param chain CAIP-2 source chain identifier, e.g. `'eip155:42161'`. + * @param address Token contract address on the source chain, or `'native'` for the chain's native gas coin. + * @param symbol Token symbol, e.g. `'USDT0'`, `'ETH'`. + * @param decimals Decimals used to convert between display and base units. + * @param name Full token name, e.g. `'Tether USD0'`. Optional. + * @param logo Logo URL. + */ +@Serializable +data class TONCryptoOnrampSourceCurrency( + + /* CAIP-2 source chain identifier, e.g. `'eip155:42161'`. */ + @SerialName(value = "chain") + var chain: kotlin.String, + + /* Token contract address on the source chain, or `'native'` for the chain's native gas coin. */ + @SerialName(value = "address") + var address: kotlin.String, + + /* Token symbol, e.g. `'USDT0'`, `'ETH'`. */ + @SerialName(value = "symbol") + var symbol: kotlin.String, + + /* Decimals used to convert between display and base units. */ + @SerialName(value = "decimals") + var decimals: kotlin.Int, + + /* Full token name, e.g. `'Tether USD0'`. Optional. */ + @SerialName(value = "name") + var name: kotlin.String? = null, + + /* Logo URL. */ + @SerialName(value = "logo") + var logo: kotlin.String? = null, + +) { + + companion object +} diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampStatus.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampStatus.kt new file mode 100644 index 00000000..1e87c134 --- /dev/null +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampStatus.kt @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2025 TonTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport", +) + +package io.ton.walletkit.api.generated + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +/** + * Deposit details returned by a crypto onramp provider. The user must send `amount` of `sourceCurrencyAddress` to `address` on `sourceChain` to complete the onramp; the provider then delivers the target crypto to the user's TON address. + * + * Values: success,pending,failed + */ +@Serializable +enum class TONCryptoOnrampStatus(val value: kotlin.String) { + + @SerialName(value = "success") + success("success"), + + @SerialName(value = "pending") + pending("pending"), + + @SerialName(value = "failed") + failed("failed"), + ; + + /** + * Override [toString()] to avoid using the enum variable name as the value, and instead use + * the actual value defined in the API spec file. + * + * This solves a problem when the variable name and its value are different, and ensures that + * the client sends the correct enum values to the server always. + */ + override fun toString(): kotlin.String = value + + companion object { + /** + * Converts the provided [data] to a [String] on success, null otherwise. + */ + fun encode(data: kotlin.Any?): kotlin.String? = if (data is TONCryptoOnrampStatus) "$data" else null + + /** + * Returns a valid [TONCryptoOnrampStatus] for [data], null otherwise. + */ + fun decode(data: kotlin.Any?): TONCryptoOnrampStatus? = data?.let { + val normalizedData = "$it".lowercase() + values().firstOrNull { value -> + it == value || normalizedData == "$value".lowercase() + } + } + } +} diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampStatusParams.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampStatusParams.kt new file mode 100644 index 00000000..96eae9cf --- /dev/null +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampStatusParams.kt @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2025 TonTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport", +) + +package io.ton.walletkit.api.generated + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +/** + * Deposit details returned by a crypto onramp provider. The user must send `amount` of `sourceCurrencyAddress` to `address` on `sourceChain` to complete the onramp; the provider then delivers the target crypto to the user's TON address. + * + * @param depositId Deposit id + * @param providerId Identifier of the provider that issued this deposit + */ +@Serializable +data class TONCryptoOnrampStatusParams( + + /* Deposit id */ + @SerialName(value = "depositId") + var depositId: kotlin.String, + + /* Identifier of the provider that issued this deposit */ + @SerialName(value = "providerId") + var providerId: kotlin.String, + +) { + + companion object +} diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampSupportedCurrencies.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampSupportedCurrencies.kt new file mode 100644 index 00000000..c31aef0a --- /dev/null +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONCryptoOnrampSupportedCurrencies.kt @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2025 TonTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport", +) + +package io.ton.walletkit.api.generated + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +/** + * Combined currency listing returned by `CryptoOnrampProvider.getSupportedCurrencies()`. + * + * @param source + * @param destination + */ +@Serializable +data class TONCryptoOnrampSupportedCurrencies( + + @SerialName(value = "source") + var source: kotlin.collections.List, + + @SerialName(value = "destination") + var destination: kotlin.collections.List, + +) { + + companion object +} diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONDefiProviderType.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONDefiProviderType.kt index 5ffeb08c..f99593c1 100644 --- a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONDefiProviderType.kt +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONDefiProviderType.kt @@ -32,9 +32,9 @@ import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable /** - * Discriminator for DeFi-style providers (swap quotes, staking, gasless relayers). + * Discriminator for DeFi-style providers (swap quotes, staking, gasless relayers, crypto onramp). * - * Values: swap,staking,gasless + * Values: swap,staking,gasless,cryptoMinusOnramp */ @Serializable enum class TONDefiProviderType(val value: kotlin.String) { @@ -47,6 +47,9 @@ enum class TONDefiProviderType(val value: kotlin.String) { @SerialName(value = "gasless") gasless("gasless"), + + @SerialName(value = "crypto-onramp") + cryptoMinusOnramp("crypto-onramp"), ; /** diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONJettonInfo.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONJettonInfo.kt new file mode 100644 index 00000000..2db01c6c --- /dev/null +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONJettonInfo.kt @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2025 TonTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport", +) + +package io.ton.walletkit.api.generated + +import kotlinx.serialization.Contextual +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +/** + * Detailed information about a Jetton master contract. + * + * @param address The Jetton master contract address + * @param name The token name + * @param symbol The token symbol + * @param description The token description + * @param decimals The number of decimal places used by the token + * @param totalSupply Total supply in the token's smallest units + * @param image URL of the token image + * @param imageData Inline base64-encoded image data + * @param uri URI pointing to the token metadata + * @param verification + * @param metadata Additional arbitrary metadata related to the jetton + */ +@Serializable +data class TONJettonInfo( + + /* The Jetton master contract address */ + @SerialName(value = "address") + var address: kotlin.String, + + /* The token name */ + @SerialName(value = "name") + var name: kotlin.String, + + /* The token symbol */ + @SerialName(value = "symbol") + var symbol: kotlin.String, + + /* The token description */ + @SerialName(value = "description") + var description: kotlin.String, + + /* The number of decimal places used by the token */ + @SerialName(value = "decimals") + var decimals: kotlin.Int? = null, + + /* Total supply in the token's smallest units */ + @SerialName(value = "totalSupply") + var totalSupply: kotlin.String? = null, + + /* URL of the token image */ + @SerialName(value = "image") + var image: kotlin.String? = null, + + /* Inline base64-encoded image data */ + @SerialName(value = "image_data") + var imageData: kotlin.String? = null, + + /* URI pointing to the token metadata */ + @SerialName(value = "uri") + var uri: kotlin.String? = null, + + @SerialName(value = "verification") + var verification: TONJettonVerification? = null, + + /* Additional arbitrary metadata related to the jetton */ + @Contextual @SerialName(value = "metadata") + var metadata: kotlin.collections.Map? = null, + +) { + + companion object +} diff --git a/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONJettonVerification.kt b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONJettonVerification.kt new file mode 100644 index 00000000..6223f6b6 --- /dev/null +++ b/TONWalletKit-Android/api/src/main/java/io/ton/walletkit/api/generated/TONJettonVerification.kt @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2025 TonTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport", +) + +package io.ton.walletkit.api.generated + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +/** + * Verification status of a Jetton. + * + * @param verified Indicates whether the jetton has been verified + * @param source Source of the verification + * @param warnings Warnings associated with the jetton + */ +@Serializable +data class TONJettonVerification( + + /* Indicates whether the jetton has been verified */ + @SerialName(value = "verified") + var verified: kotlin.Boolean, + + /* Source of the verification */ + @SerialName(value = "source") + var source: TONJettonVerification.Source? = null, + + /* Warnings associated with the jetton */ + @SerialName(value = "warnings") + var warnings: kotlin.collections.List? = null, + +) { + + companion object + + /** + * Source of the verification + * + * Values: toncenter,community,manual + */ + @Serializable + enum class Source(val value: kotlin.String) { + @SerialName(value = "toncenter") + toncenter("toncenter"), + + @SerialName(value = "community") + community("community"), + + @SerialName(value = "manual") + manual("manual"), + } +} diff --git a/TONWalletKit-Android/gradle.properties b/TONWalletKit-Android/gradle.properties index 31f1b307..d20ba2f6 100644 --- a/TONWalletKit-Android/gradle.properties +++ b/TONWalletKit-Android/gradle.properties @@ -9,4 +9,4 @@ POM_ARTIFACT_ID=walletkit # Pinned kit tag for the committed WalletKit bridge bundle. CI verifies the bundle matches a # build of this tag; bump it by hand, then rebuild and recommit the bundle. -WALLETKIT_BRIDGE_TAG=v1.0.0 +WALLETKIT_BRIDGE_TAG=v1.1.0-beta.0 diff --git a/TONWalletKit-Android/impl/src/main/assets/walletkit/walletkit-android-bridge.mjs b/TONWalletKit-Android/impl/src/main/assets/walletkit/walletkit-android-bridge.mjs index 4498c921..171ebe70 100644 --- a/TONWalletKit-Android/impl/src/main/assets/walletkit/walletkit-android-bridge.mjs +++ b/TONWalletKit-Android/impl/src/main/assets/walletkit/walletkit-android-bridge.mjs @@ -23697,7 +23697,7 @@ var init_WalletKitError = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/errors/index.js -var init_errors$4 = __esmMin((() => { +var init_errors$5 = __esmMin((() => { init_codes(); init_WalletKitError(); })); @@ -23843,7 +23843,7 @@ function HexToBase64(data) { } var init_base64 = __esmMin((() => { init_hex(); - init_errors$4(); + init_errors$5(); })); //#endregion //#region ../walletkit/dist/esm/types/toncenter/parsers/TonTransfer.js @@ -25067,17 +25067,17 @@ function createStorageAdapter(config = {}) { if (typeof localStorage !== "undefined") try { return new LocalStorageAdapter(config); } catch (error) { - log$40.warn("Failed to create LocalStorageAdapter, falling back to memory", { error }); + log$41.warn("Failed to create LocalStorageAdapter, falling back to memory", { error }); } if (config.allowMemory) return new MemoryStorageAdapter(config); else throw new Error("No storage adapter available"); } -var log$40; +var log$41; var init_adapters = __esmMin((() => { init_Logger(); init_local(); init_memory(); - log$40 = globalLogger.createChild("StorageAdapter"); + log$41 = globalLogger.createChild("StorageAdapter"); })); //#endregion //#region ../walletkit/dist/esm/storage/adapters/extension.js @@ -25129,10 +25129,10 @@ var init_extension = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/storage/Storage.js -var log$39, Storage; +var log$40, Storage; var init_Storage = __esmMin((() => { init_Logger(); - log$39 = globalLogger.createChild("Storage"); + log$40 = globalLogger.createChild("Storage"); Storage = class { adapter; constructor(adapter) { @@ -25149,7 +25149,7 @@ var init_Storage = __esmMin((() => { if (value === null) return null; return JSON.parse(value); } catch (error) { - log$39.warn("Failed to parse stored value", { + log$40.warn("Failed to parse stored value", { key, error }); @@ -25166,7 +25166,7 @@ var init_Storage = __esmMin((() => { const serialized = JSON.stringify(value); await this.adapter.set(key, serialized); } catch (error) { - log$39.error("Failed to serialize value for storage", { + log$40.error("Failed to serialize value for storage", { key, error }); @@ -25549,11 +25549,11 @@ var init_WalletManager = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/core/TONConnectStoredSessionManager.js -var log$38, TONConnectStoredSessionManager; +var log$39, TONConnectStoredSessionManager; var init_TONConnectStoredSessionManager = __esmMin((() => { init_esm$2(); init_Logger(); - log$38 = globalLogger.createChild("TONConnectStoredSessionManager"); + log$39 = globalLogger.createChild("TONConnectStoredSessionManager"); TONConnectStoredSessionManager = class { sessions = /* @__PURE__ */ new Map(); storage; @@ -25686,16 +25686,16 @@ var init_TONConnectStoredSessionManager = __esmMin((() => { const wallet = this.walletManager.getWallet(session.walletId); if (wallet) session.walletAddress = wallet.getAddress(); else { - log$38.warn("Session Wallet not found for session", { sessionId: session.sessionId }); + log$39.warn("Session Wallet not found for session", { sessionId: session.sessionId }); continue; } } this.sessions.set(session.sessionId, session); } - log$38.debug("Loaded session metadata", { count: storedSessions.length }); + log$39.debug("Loaded session metadata", { count: storedSessions.length }); } } catch (error) { - log$38.warn("Failed to load sessions from storage", { error }); + log$39.warn("Failed to load sessions from storage", { error }); } } /** @@ -25706,7 +25706,7 @@ var init_TONConnectStoredSessionManager = __esmMin((() => { const sessionsToStore = Array.from(this.sessions.values()); await this.storage.set(this.storageKey, sessionsToStore); } catch (error) { - log$38.warn("Failed to persist sessions to storage", { error }); + log$39.warn("Failed to persist sessions to storage", { error }); } } async migrateSessions() { @@ -27301,7 +27301,7 @@ var init_timeouts = __esmMin((() => { //#endregion //#region ../walletkit/dist/esm/bridge/injection/BridgeInjector.js var init_BridgeInjector = __esmMin((() => { - init_errors$4(); + init_errors$5(); })); //#endregion //#region ../walletkit/dist/esm/bridge/utils/messageTypes.js @@ -27323,15 +27323,15 @@ var init_JSBridgeInjector = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/core/BridgeManager.js -var log$36, BridgeManager; +var log$37, BridgeManager; var init_BridgeManager = __esmMin((() => { init_esm$2(); init_dist$1(); init_Logger(); init_uuid(); - init_errors$4(); + init_errors$5(); init_JSBridgeInjector(); - log$36 = globalLogger.createChild("BridgeManager"); + log$37 = globalLogger.createChild("BridgeManager"); BridgeManager = class { config; bridgeProvider; @@ -27373,7 +27373,7 @@ var init_BridgeManager = __esmMin((() => { this.walletKitConfig = walletKitConfig; this.jsBridgeTransport = config?.jsBridgeTransport; if (this.config.bridgeUrl && !this.config.disableHttpConnection) this.bridgeProvider = new C(this.config.bridgeUrl, this.queueBridgeEvent.bind(this), (error) => { - log$36.error("Bridge listener error", { error: error.toString() }); + log$37.error("Bridge listener error", { error: error.toString() }); this.analytics?.emitBridgeClientConnectError({ error_message: `${error?.toString() || "Unknown error"}${error?.errorCode ? ` (Code: ${error?.errorCode})` : ""}`, trace_id: error?.traceId, @@ -27387,12 +27387,12 @@ var init_BridgeManager = __esmMin((() => { */ async start() { if (this.isActive === true) { - log$36.warn("Bridge already started"); + log$37.warn("Bridge already started"); return; } this.isActive = true; if (this.isConnected === true) { - log$36.warn("Bridge already connected"); + log$37.warn("Bridge already connected"); return; } try { @@ -27404,7 +27404,7 @@ var init_BridgeManager = __esmMin((() => { } } catch (error) { this.isActive = false; - log$36.error("Failed to start bridge", { error }); + log$37.error("Failed to start bridge", { error }); throw error; } const requestProcessing = () => { @@ -27417,10 +27417,10 @@ var init_BridgeManager = __esmMin((() => { * Create new session for a dApp connection */ async createSession(appSessionId) { - log$36.info("[BRIDGE] Creating session", { appSessionId }); + log$37.info("[BRIDGE] Creating session", { appSessionId }); if (!await this.sessionManager.getSession(appSessionId)) throw new WalletKitError(ERROR_CODES.SESSION_NOT_FOUND, `Session not found`, void 0, { appSessionId }); if (this.bridgeProvider && this.isConnected) { - log$36.info("[BRIDGE] Updating clients"); + log$37.info("[BRIDGE] Updating clients"); await this.updateClients(); } } @@ -27429,7 +27429,7 @@ var init_BridgeManager = __esmMin((() => { */ async removeSession(appSessionId) { if (this.bridgeProvider && this.isConnected) await this.updateClients(); - log$36.debug("Session removed", { appSessionId }); + log$37.debug("Session removed", { appSessionId }); } /** * Send response to dApp @@ -27454,12 +27454,12 @@ var init_BridgeManager = __esmMin((() => { } try { await this.bridgeProvider.send(response, sessionCrypto, sessionId, { traceId: event?.traceId }); - log$36.debug("Response sent successfully", { + log$37.debug("Response sent successfully", { sessionId, requestId: event.id }); } catch (error) { - log$36.error("Failed to send response through bridge", { + log$37.error("Failed to send response through bridge", { sessionId, requestId: event.id, error @@ -27541,7 +27541,7 @@ var init_BridgeManager = __esmMin((() => { await this.bridgeProvider?.restoreConnection(clients, { lastEventId: this.lastEventId }); this.isConnected = true; this.reconnectAttempts = 0; - log$36.info("Bridge connected successfully"); + log$37.info("Bridge connected successfully"); if (this.analytics) { const client = clients[0]; this.analytics.emitBridgeClientConnectEstablished({ @@ -27550,7 +27550,7 @@ var init_BridgeManager = __esmMin((() => { }); } } catch (error) { - log$36.error("Bridge connection failed", { error: error?.toString() }); + log$37.error("Bridge connection failed", { error: error?.toString() }); this.analytics?.emitBridgeClientConnectError({ error_message: `${error?.toString() || "Unknown error"}${error?.errorCode ? ` (Code: ${error?.errorCode})` : ""}`, trace_id: error?.traceId ?? connectTraceId, @@ -27559,9 +27559,9 @@ var init_BridgeManager = __esmMin((() => { if (!this.config.disableHttpConnection) { if (this.reconnectAttempts < (this.config.maxReconnectAttempts || 5)) { this.reconnectAttempts++; - log$36.info("Bridge reconnection attempt", { attempt: this.reconnectAttempts }); + log$37.info("Bridge reconnection attempt", { attempt: this.reconnectAttempts }); setTimeout(() => { - this.connectToSSEBridge().catch((error) => log$36.error("Bridge reconnection failed", { error })); + this.connectToSSEBridge().catch((error) => log$37.error("Bridge reconnection failed", { error })); }, this.config.reconnectInterval); } } @@ -27582,10 +27582,10 @@ var init_BridgeManager = __esmMin((() => { * Add client to existing bridge connection */ async updateClients() { - log$36.debug("Updating clients"); + log$37.debug("Updating clients"); if (this.bridgeProvider) { const clients = await this.getClients(); - log$36.info("[BRIDGE] Restoring connection", { clients: clients.length }); + log$37.info("[BRIDGE] Restoring connection", { clients: clients.length }); await this.bridgeProvider.restoreConnection(clients, { lastEventId: this.lastEventId }); } } @@ -27593,17 +27593,17 @@ var init_BridgeManager = __esmMin((() => { * Queue incoming bridge events for processing */ queueBridgeEvent(event) { - log$36.debug("Bridge event queued", { + log$37.debug("Bridge event queued", { eventId: event?.id, event }); this.eventQueue.push(event); this.processBridgeEvents().catch((error) => { - log$36.error("Error in background event processing", { error }); + log$37.error("Error in background event processing", { error }); }); } queueJsBridgeEvent(messageInfo, event) { - log$36.debug("JS Bridge event queued", { eventId: messageInfo?.messageId }); + log$37.debug("JS Bridge event queued", { eventId: messageInfo?.messageId }); if (!event) return; if (!event.traceId) event.traceId = v7(); if (event.method == "connect") this.eventQueue.push({ @@ -27632,7 +27632,7 @@ var init_BridgeManager = __esmMin((() => { walletId: messageInfo.walletId }); this.processBridgeEvents().catch((error) => { - log$36.error("Error in background event processing", { error }); + log$37.error("Error in background event processing", { error }); }); } /** @@ -27644,7 +27644,7 @@ var init_BridgeManager = __esmMin((() => { */ async processBridgeEvents() { if (this.isProcessing) { - log$36.debug("Event processing already in progress, skipping"); + log$37.debug("Event processing already in progress, skipping"); return; } this.isProcessing = true; @@ -27657,7 +27657,7 @@ var init_BridgeManager = __esmMin((() => { } } } catch (error) { - log$36.error("Error during event processing", { error }); + log$37.error("Error during event processing", { error }); this.isProcessing = false; this.restartConnection(); return; @@ -27670,7 +27670,7 @@ var init_BridgeManager = __esmMin((() => { */ async handleBridgeEvent(event) { try { - log$36.info("Bridge event received", { event }); + log$37.info("Bridge event received", { event }); const rawEvent = { id: event.id || crypto.randomUUID(), method: event.method || "unknown", @@ -27724,12 +27724,12 @@ var init_BridgeManager = __esmMin((() => { try { await this.eventStore.storeEvent(rawEvent); if (this.eventEmitter) this.eventEmitter.emit("bridgeStorageUpdated", {}, "bridge-manager"); - log$36.info("Event stored durably", { + log$37.info("Event stored durably", { eventId: rawEvent.id, method: rawEvent.method }); } catch (error) { - log$36.error("Failed to store event durably", { + log$37.error("Failed to store event durably", { eventId: rawEvent.id, error: error.message }); @@ -27738,13 +27738,13 @@ var init_BridgeManager = __esmMin((() => { method: rawEvent.method }); } - log$36.info("Bridge event processed", { rawEvent }); + log$37.info("Bridge event processed", { rawEvent }); if (event?.lastEventId && event.lastEventId !== this.lastEventId) { this.lastEventId = event.lastEventId; await this.saveLastEventId(); } } catch (error) { - log$36.error("Error handling bridge event", { error }); + log$37.error("Error handling bridge event", { error }); } } /** @@ -27755,11 +27755,11 @@ var init_BridgeManager = __esmMin((() => { const savedEventId = await this.storage.get(this.storageKey); if (savedEventId) { this.lastEventId = savedEventId; - log$36.debug("Loaded last event ID from storage", { lastEventId: this.lastEventId }); + log$37.debug("Loaded last event ID from storage", { lastEventId: this.lastEventId }); } } catch (error) { const storageError = WalletKitError.fromError(ERROR_CODES.STORAGE_READ_FAILED, "Failed to load last event ID from storage", error); - log$36.warn("Failed to load last event ID from storage", { error: storageError }); + log$37.warn("Failed to load last event ID from storage", { error: storageError }); } } /** @@ -27769,11 +27769,11 @@ var init_BridgeManager = __esmMin((() => { try { if (this.lastEventId) { await this.storage.set(this.storageKey, this.lastEventId); - log$36.debug("Saved last event ID to storage", { lastEventId: this.lastEventId }); + log$37.debug("Saved last event ID to storage", { lastEventId: this.lastEventId }); } } catch (error) { const storageError = WalletKitError.fromError(ERROR_CODES.STORAGE_WRITE_FAILED, "Failed to save last event ID to storage", error); - log$36.warn("Failed to save last event ID to storage", { error: storageError }); + log$37.warn("Failed to save last event ID to storage", { error: storageError }); } } }; @@ -27837,14 +27837,14 @@ async function fetchManifest(manifestUrl, proxyUrl) { manifest: null, manifestFetchErrorCode: CONNECT_EVENT_ERROR_CODES$1.MANIFEST_CONTENT_ERROR }; - log$35.info("Direct manifest fetch failed, trying proxy", { manifestUrl }); + log$36.info("Direct manifest fetch failed, trying proxy", { manifestUrl }); return tryFetchManifest(`${proxyUrl}${manifestUrl}`); } async function tryFetchManifest(url) { try { const response = await fetch(url); if (!response.ok) { - log$35.error("Failed to fetch manifest not ok", { + log$36.error("Failed to fetch manifest not ok", { url, status: response.status }); @@ -27858,7 +27858,7 @@ async function tryFetchManifest(url) { manifestFetchErrorCode: void 0 }; } catch (e) { - log$35.error("Failed to fetch manifest catched", { + log$36.error("Failed to fetch manifest catched", { url, error: e }); @@ -27868,23 +27868,23 @@ async function tryFetchManifest(url) { }; } } -var log$35; +var log$36; var init_manifest = __esmMin((() => { init_esm$2(); init_url(); init_Logger(); - log$35 = globalLogger.createChild("ManifestUtils"); + log$36 = globalLogger.createChild("ManifestUtils"); })); //#endregion //#region ../walletkit/dist/esm/handlers/ConnectHandler.js -var log$34, ConnectHandler; +var log$35, ConnectHandler; var init_ConnectHandler = __esmMin((() => { init_esm$2(); init_Logger(); init_BasicHandler(); init_url(); init_manifest(); - log$34 = globalLogger.createChild("ConnectHandler"); + log$35 = globalLogger.createChild("ConnectHandler"); ConnectHandler = class extends BasicHandler { config; analytics; @@ -27905,7 +27905,7 @@ var init_ConnectHandler = __esmMin((() => { manifest = result.manifest; manifestFetchErrorCode = result.manifestFetchErrorCode; } catch (error) { - log$34.warn("Failed to fetch manifest", { error }); + log$35.warn("Failed to fetch manifest", { error }); } const preview = this.createPreview(event, manifestUrl, manifest, manifestFetchErrorCode); const connectEvent = { @@ -27966,14 +27966,14 @@ var init_ConnectHandler = __esmMin((() => { if (!finalManifestFetchErrorCode && dAppUrl) try { const parsedDAppUrl = new URL(dAppUrl); if (!isValidHost(parsedDAppUrl.host)) { - log$34.warn("Invalid dApp URL in manifest - invalid host format", { + log$35.warn("Invalid dApp URL in manifest - invalid host format", { dAppUrl, host: parsedDAppUrl.host }); finalManifestFetchErrorCode = CONNECT_EVENT_ERROR_CODES$1.MANIFEST_CONTENT_ERROR; } } catch (_) { - log$34.warn("Invalid dApp URL in manifest - failed to parse", { dAppUrl }); + log$35.warn("Invalid dApp URL in manifest - failed to parse", { dAppUrl }); finalManifestFetchErrorCode = CONNECT_EVENT_ERROR_CODES$1.MANIFEST_CONTENT_ERROR; } } @@ -28637,7 +28637,7 @@ async function resolveItemsToMessages(items, wallet) { messages.push(resolveNftItem(item, wallet)); break; default: - log$33.warn("Unknown item type, skipping", { item }); + log$34.warn("Unknown item type, skipping", { item }); break; } return messages; @@ -28690,13 +28690,13 @@ function resolveNftItem(item, wallet) { mode: { flags: [SendModeFlag.IGNORE_ERRORS, SendModeFlag.PAY_GAS_SEPARATELY] } }; } -var import_dist$33, log$33; +var import_dist$33, log$34; var init_itemsResolver = __esmMin((() => { import_dist$33 = require_dist$1(); init_models(); init_messageBuilders(); init_Logger(); - log$33 = globalLogger.createChild("ItemsResolver"); + log$34 = globalLogger.createChild("ItemsResolver"); })); //#endregion //#region ../walletkit/dist/esm/utils/events.js @@ -28758,7 +28758,7 @@ function parseTonConnectTransactionRequest(event, wallet) { validation: validateTransactionRequestForWallet(request, wallet, event.isLocal) }; } catch (error) { - log$32.error("Failed to parse transaction request", { error }); + log$33.error("Failed to parse transaction request", { error }); errors.push("Failed to parse transaction request"); return { result: void 0, @@ -28769,15 +28769,15 @@ function parseTonConnectTransactionRequest(event, wallet) { }; } } -var log$32; +var log$33; var init_events = __esmMin((() => { - init_errors$4(); + init_errors$5(); init_transactionValidators(); init_internal(); init_transaction$1(); init_itemsResolver(); init_Logger(); - log$32 = globalLogger.createChild("EventsUtils"); + log$33 = globalLogger.createChild("EventsUtils"); })); //#endregion //#region ../../node_modules/.pnpm/@noble+hashes@2.2.0/node_modules/@noble/hashes/utils.js @@ -29677,7 +29677,7 @@ var import_dist$32; var init_mnemonic = __esmMin((() => { import_dist$32 = require_dist$2(); init_bip39(); - init_errors$4(); + init_errors$5(); })); //#endregion //#region ../walletkit/dist/esm/utils/sign.js @@ -31111,7 +31111,7 @@ async function createTransactionPreviewIfPossible(config, client, request, walle try { preview = await CallForSuccess(() => createTransactionPreview(client, request, wallet, options)); } catch (error) { - log$31.error("Failed to create transaction preview", { error }); + log$32.error("Failed to create transaction preview", { error }); preview = { error: { code: ERROR_CODES.UNKNOWN_EMULATION_ERROR, @@ -31122,7 +31122,7 @@ async function createTransactionPreviewIfPossible(config, client, request, walle } return preview; } -var import_dist$20, log$31, SIGN_MODE_EMULATION_VALUE; +var import_dist$20, log$32, SIGN_MODE_EMULATION_VALUE; var init_transactionPreview = __esmMin((() => { import_dist$20 = require_dist$1(); init_map_emulation_trace(); @@ -31131,7 +31131,7 @@ var init_transactionPreview = __esmMin((() => { init_retry(); init_models(); init_Logger(); - log$31 = globalLogger.createChild("TransactionPreview"); + log$32 = globalLogger.createChild("TransactionPreview"); SIGN_MODE_EMULATION_VALUE = 2000000000n; })); //#endregion @@ -31409,14 +31409,14 @@ var init_utils$2 = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/handlers/TransactionHandler.js -var log$30, TransactionHandler; +var log$31, TransactionHandler; var init_TransactionHandler = __esmMin((() => { init_esm$2(); init_Logger(); init_BasicHandler(); init_events(); init_utils$2(); - log$30 = globalLogger.createChild("TransactionHandler"); + log$31 = globalLogger.createChild("TransactionHandler"); TransactionHandler = class extends BasicHandler { config; walletManager; @@ -31438,7 +31438,7 @@ var init_TransactionHandler = __esmMin((() => { async handle(event) { const wallet = getWalletFromEvent(this.walletManager, event); if (!wallet) { - log$30.error("Wallet not found", { event }); + log$31.error("Wallet not found", { event }); return { error: { code: SEND_TRANSACTION_ERROR_CODES$1.UNKNOWN_APP_ERROR, @@ -31449,7 +31449,7 @@ var init_TransactionHandler = __esmMin((() => { } const requestValidation = this.parseTonConnectTransactionRequest(event, wallet); if (!requestValidation.result || !requestValidation?.validation?.isValid) { - log$30.error("Failed to parse transaction request", { + log$31.error("Failed to parse transaction request", { event, requestValidation }); @@ -31495,13 +31495,13 @@ var init_TransactionHandler = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/handlers/SignDataHandler.js -var log$29, SignDataHandler; +var log$30, SignDataHandler; var init_SignDataHandler = __esmMin((() => { init_internal(); init_BasicHandler(); init_Logger(); - init_errors$4(); - log$29 = globalLogger.createChild("SignDataHandler"); + init_errors$5(); + log$30 = globalLogger.createChild("SignDataHandler"); SignDataHandler = class extends BasicHandler { analytics; walletManager; @@ -31522,12 +31522,12 @@ var init_SignDataHandler = __esmMin((() => { const wallet = walletId ? this.walletManager.getWallet(walletId) : void 0; const payload = this.parseDataToSign(event); if (!payload) { - log$29.error("No data to sign found in request", { event }); + log$30.error("No data to sign found in request", { event }); throw new WalletKitError(ERROR_CODES.INVALID_REQUEST_EVENT, "No data to sign found in request", void 0, { eventId: event.id }); } const preview = this.createDataPreview(payload.data, event); if (!preview) { - log$29.error("No preview found for data", { data: payload }); + log$30.error("No preview found for data", { data: payload }); throw new WalletKitError(ERROR_CODES.RESPONSE_CREATION_FAILED, "Failed to create preview for sign data request", void 0, { eventId: event.id, data: payload @@ -31584,7 +31584,7 @@ var init_SignDataHandler = __esmMin((() => { } }; } catch (error) { - log$29.error("Error deserializing cell", { error }); + log$30.error("Error deserializing cell", { error }); return { type: "cell", value: { @@ -31598,14 +31598,14 @@ var init_SignDataHandler = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/handlers/SignMessageHandler.js -var log$28, SignMessageHandler; +var log$29, SignMessageHandler; var init_SignMessageHandler = __esmMin((() => { init_esm$2(); init_Logger(); init_BasicHandler(); init_utils$2(); init_events(); - log$28 = globalLogger.createChild("SignMessageHandler"); + log$29 = globalLogger.createChild("SignMessageHandler"); SignMessageHandler = class extends BasicHandler { config; walletManager; @@ -31627,7 +31627,7 @@ var init_SignMessageHandler = __esmMin((() => { async handle(event) { const wallet = getWalletFromEvent(this.walletManager, event); if (!wallet) { - log$28.error("Wallet not found", { event }); + log$29.error("Wallet not found", { event }); return { error: { code: SIGN_MESSAGE_ERROR_CODES.UNKNOWN_APP_ERROR, @@ -31638,7 +31638,7 @@ var init_SignMessageHandler = __esmMin((() => { } const requestValidation = this.parseTonConnectTransactionRequest(event, wallet); if (!requestValidation.result || !requestValidation?.validation?.isValid) { - log$28.error("Failed to parse sign message request", { + log$29.error("Failed to parse sign message request", { event, requestValidation }); @@ -31684,7 +31684,7 @@ var init_SignMessageHandler = __esmMin((() => { var DisconnectHandler; var init_DisconnectHandler = __esmMin((() => { init_BasicHandler(); - init_errors$4(); + init_errors$5(); DisconnectHandler = class extends BasicHandler { sessionManager; constructor(notify, sessionManager) { @@ -31723,7 +31723,7 @@ var init_DisconnectHandler = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/core/EventRouter.js -var log$27, EventRouter; +var log$28, EventRouter; var init_EventRouter = __esmMin((() => { init_ConnectHandler(); init_TransactionHandler(); @@ -31732,7 +31732,7 @@ var init_EventRouter = __esmMin((() => { init_DisconnectHandler(); init_events$1(); init_Logger(); - log$27 = globalLogger.createChild("EventRouter"); + log$28 = globalLogger.createChild("EventRouter"); EventRouter = class { config; eventEmitter; @@ -31764,7 +31764,7 @@ var init_EventRouter = __esmMin((() => { async routeEvent(event) { const validation = validateBridgeEvent(event); if (!validation.isValid) { - log$27.error("Invalid bridge event", { errors: validation.errors }); + log$28.error("Invalid bridge event", { errors: validation.errors }); return; } try { @@ -31779,7 +31779,7 @@ var init_EventRouter = __esmMin((() => { try { await this.bridgeManager.sendResponse(event, result); } catch (error) { - log$27.error("Error sending response for error event", { + log$28.error("Error sending response for error event", { error, event, result @@ -31791,7 +31791,7 @@ var init_EventRouter = __esmMin((() => { break; } } catch (error) { - log$27.error("Error routing event", { error }); + log$28.error("Error routing event", { error }); throw error; } } @@ -31920,7 +31920,7 @@ function hasConnectionResult(event) { */ async function signTransactionInternal(wallet, request) { const signedBoc = await wallet.getSignedSendTransaction(request, { fakeSignature: false }); - log$26.debug("Signing transaction", { + log$27.debug("Signing transaction", { messagesNumber: request.messages.length, fromAddress: request.fromAddress, validUntil: request.validUntil @@ -31976,7 +31976,7 @@ function parseDomain(url) { value: parsedUrl.host }; } catch (error) { - log$26.error("Failed to parse domain", { error }); + log$27.error("Failed to parse domain", { error }); return { lengthBytes: 0, value: "" @@ -32004,7 +32004,7 @@ function toTonConnectSignDataPayload(payload) { bytes: payload.data.value.content }; } -var import_dist$16, import_dist$17, log$26, RequestProcessor; +var import_dist$16, import_dist$17, log$27, RequestProcessor; var init_RequestProcessor = __esmMin((() => { import_dist$16 = require_dist$1(); init_esm$2(); @@ -32013,13 +32013,13 @@ var init_RequestProcessor = __esmMin((() => { init_tonProof(); init_retry(); init_getDefaultWalletConfig(); - init_errors$4(); + init_errors$5(); init_base64(); init_sign(); init_transaction$1(); init_utils$2(); init_events(); - log$26 = globalLogger.createChild("RequestProcessor"); + log$27 = globalLogger.createChild("RequestProcessor"); RequestProcessor = class { walletKitOptions; sessionManager; @@ -32082,7 +32082,7 @@ var init_RequestProcessor = __esmMin((() => { } return; } catch (error) { - log$26.error("Failed to approve connect request", { error }); + log$27.error("Failed to approve connect request", { error }); throw error; } } @@ -32217,7 +32217,7 @@ var init_RequestProcessor = __esmMin((() => { */ async rejectConnectRequest(event, reason, errorCode) { try { - log$26.info("Connect request rejected", { + log$27.info("Connect request rejected", { id: event.id, dAppName: event.preview.dAppInfo?.name || "", reason: reason || "User rejected connection" @@ -32234,7 +32234,7 @@ var init_RequestProcessor = __esmMin((() => { try { await this.bridgeManager.sendResponse(event, response, new SessionCrypto()); } catch (error) { - log$26.error("Failed to send connect request rejection response", { error }); + log$27.error("Failed to send connect request rejection response", { error }); } if (this.analytics) { const sessionData = event.from ? await this.sessionManager.getSession(sessionId) : void 0; @@ -32263,7 +32263,7 @@ var init_RequestProcessor = __esmMin((() => { } return; } catch (error) { - log$26.error("Failed to reject connect request", { error }); + log$27.error("Failed to reject connect request", { error }); throw error; } } @@ -32295,7 +32295,7 @@ var init_RequestProcessor = __esmMin((() => { return { signedBoc }; } } catch (error) { - log$26.error("Failed to approve transaction request", { error }); + log$27.error("Failed to approve transaction request", { error }); if (error instanceof WalletKitError) throw error; if (error?.message?.includes("Ledger device")) throw new WalletKitError(ERROR_CODES.LEDGER_DEVICE_ERROR, "Ledger device error", error); throw error; @@ -32345,7 +32345,7 @@ var init_RequestProcessor = __esmMin((() => { } return; } catch (error) { - log$26.error("Failed to reject transaction request", { error }); + log$27.error("Failed to reject transaction request", { error }); throw error; } } @@ -32376,7 +32376,7 @@ var init_RequestProcessor = __esmMin((() => { return { internalBoc }; } } catch (error) { - log$26.error("Failed to approve sign message request", { error }); + log$27.error("Failed to approve sign message request", { error }); throw error; } } @@ -32394,7 +32394,7 @@ var init_RequestProcessor = __esmMin((() => { }; await this.sendBridgeMessage(event, void 0, response); } catch (error) { - log$26.error("Failed to reject sign message request", { error }); + log$27.error("Failed to reject sign message request", { error }); throw error; } } @@ -32497,7 +32497,7 @@ var init_RequestProcessor = __esmMin((() => { }; } } catch (error) { - log$26.error("Failed to approve sign data request", { error: error?.message?.toString() ?? error?.toString() }); + log$27.error("Failed to approve sign data request", { error: error?.message?.toString() ?? error?.toString() }); if (error instanceof WalletKitError) throw error; throw error; } @@ -32532,7 +32532,7 @@ var init_RequestProcessor = __esmMin((() => { } return; } catch (error) { - log$26.error("Failed to reject sign data request", { error }); + log$27.error("Failed to reject sign data request", { error }); throw error; } } @@ -32609,14 +32609,14 @@ var init_RequestProcessor = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/core/EventStore.js -var getEventUUID, log$25, MAX_EVENT_SIZE_BYTES, StorageEventStore; +var getEventUUID, log$26, MAX_EVENT_SIZE_BYTES, StorageEventStore; var init_EventStore = __esmMin((() => { init_Logger(); init_events$1(); getEventUUID = () => { return crypto.randomUUID(); }; - log$25 = globalLogger.createChild("EventStore"); + log$26 = globalLogger.createChild("EventStore"); MAX_EVENT_SIZE_BYTES = 100 * 1024; StorageEventStore = class { storage; @@ -32649,7 +32649,7 @@ var init_EventStore = __esmMin((() => { sizeBytes }; await this.saveEvent(storedEvent); - log$25.info("Event stored", { + log$26.info("Event stored", { eventId: storedEvent.id, eventType, sizeBytes, @@ -32677,11 +32677,11 @@ var init_EventStore = __esmMin((() => { const allEvents = await this.getAllEventsFromStorage(); const event = allEvents[eventId]; if (!event) { - log$25.warn("Cannot lock non-existent event", { eventId }); + log$26.warn("Cannot lock non-existent event", { eventId }); return; } if (event.status !== "new") { - log$25.debug("Cannot lock event - not in new status", { + log$26.debug("Cannot lock event - not in new status", { eventId, status: event.status, lockedBy: event.lockedBy @@ -32696,7 +32696,7 @@ var init_EventStore = __esmMin((() => { }; allEvents[eventId] = updatedEvent; await this.storage.set(this.storageKey, allEvents); - log$25.debug("Event lock acquired", { + log$26.debug("Event lock acquired", { eventId, walletAddress: walletId }); @@ -32723,7 +32723,7 @@ var init_EventStore = __esmMin((() => { }; allEvents[eventId] = updatedEvent; await this.storage.set(this.storageKey, allEvents); - log$25.debug("Event retry count incremented", { + log$26.debug("Event retry count incremented", { eventId, retryCount: updatedEvent.retryCount, error @@ -32747,7 +32747,7 @@ var init_EventStore = __esmMin((() => { if (status === "completed") updatedEvent.completedAt = Date.now(); allEvents[eventId] = updatedEvent; await this.storage.set(this.storageKey, allEvents); - log$25.debug("Event status updated", { + log$26.debug("Event status updated", { eventId, oldStatus, newStatus: status @@ -32762,7 +32762,7 @@ var init_EventStore = __esmMin((() => { try { return (await this.getAllEventsFromStorage())[eventId] || null; } catch (error) { - log$25.warn("Failed to get event", { + log$26.warn("Failed to get event", { eventId, error }); @@ -32784,14 +32784,14 @@ var init_EventStore = __esmMin((() => { }; await this.saveEvent(recoveredEvent); recoveredCount++; - log$25.info("Recovered stale event", { + log$26.info("Recovered stale event", { eventId: event.id, lockedBy: event.lockedBy, staleMinutes: Math.round((now - event.processingStartedAt) / 6e4), retryCount: event.retryCount || 0 }); } - if (recoveredCount > 0) log$25.info("Event recovery completed", { recoveredCount }); + if (recoveredCount > 0) log$26.info("Event recovery completed", { recoveredCount }); return recoveredCount; } /** @@ -32804,7 +32804,7 @@ var init_EventStore = __esmMin((() => { const eventsToRemove = []; for (const event of events) if (event.status === "completed" && event.completedAt && event.completedAt < cutoffTime || event.status === "errored" && event.createdAt < cutoffTime) { eventsToRemove.push(event.id); - log$25.debug("Marked event for cleanup", { + log$26.debug("Marked event for cleanup", { eventId: event.id, status: event.status }); @@ -32818,7 +32818,7 @@ var init_EventStore = __esmMin((() => { } await this.storage.set(this.storageKey, allEvents); }); - log$25.info("Event cleanup completed", { cleanedUpCount }); + log$26.info("Event cleanup completed", { cleanedUpCount }); } return cleanedUpCount; } @@ -32830,7 +32830,7 @@ var init_EventStore = __esmMin((() => { const allEvents = await this.getAllEventsFromStorage(); return Object.values(allEvents); } catch (error) { - log$25.warn("Failed to get all events", { error }); + log$26.warn("Failed to get all events", { error }); return []; } } @@ -32852,7 +32852,7 @@ var init_EventStore = __esmMin((() => { try { return await this.storage.get(this.storageKey) || {}; } catch (error) { - log$25.warn("Failed to get events from storage", { error }); + log$26.warn("Failed to get events from storage", { error }); return {}; } } @@ -32885,10 +32885,10 @@ var init_EventStore = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/core/EventProcessor.js -var log$24, StorageEventProcessor; +var log$25, StorageEventProcessor; var init_EventProcessor = __esmMin((() => { init_Logger(); - log$24 = globalLogger.createChild("EventProcessor"); + log$25 = globalLogger.createChild("EventProcessor"); StorageEventProcessor = class { eventStore; config; @@ -32920,14 +32920,14 @@ var init_EventProcessor = __esmMin((() => { */ async startProcessing(walletId) { if (this.processorConfig.disableEvents) return; - if (walletId) if (this.registeredWallets.has(walletId)) log$24.debug("Processing already registered for wallet", { walletId }); + if (walletId) if (this.registeredWallets.has(walletId)) log$25.debug("Processing already registered for wallet", { walletId }); else { this.registeredWallets.add(walletId); - log$24.info("Registered wallet for event processing", { walletId }); + log$25.info("Registered wallet for event processing", { walletId }); } if (!this.isProcessing) { this.isProcessing = true; - log$24.info("Started global event processing loop"); + log$25.info("Started global event processing loop"); this.processEventsLoop(); } else this.triggerProcessing(); } @@ -32938,7 +32938,7 @@ var init_EventProcessor = __esmMin((() => { if (this.processorConfig.disableEvents) return; if (walletId) { this.registeredWallets.delete(walletId); - log$24.info("Unregistered wallet from event processing", { walletId }); + log$25.info("Unregistered wallet from event processing", { walletId }); } if (this.registeredWallets.size === 0 && this.isProcessing && !walletId) { this.isProcessing = false; @@ -32946,12 +32946,12 @@ var init_EventProcessor = __esmMin((() => { this.wakeUpResolver(); this.wakeUpResolver = void 0; } - log$24.info("Stopped global event processing loop (no more wallets)"); + log$25.info("Stopped global event processing loop (no more wallets)"); } } async clearRegisteredWallets() { this.registeredWallets.clear(); - log$24.info("Cleared registered wallets from event processing"); + log$25.info("Cleared registered wallets from event processing"); } /** * Process next available event from any source (wallet or no-wallet) @@ -32981,7 +32981,7 @@ var init_EventProcessor = __esmMin((() => { const walletId = allSessions.find((s) => s.sessionId === eventToUse.sessionId)?.walletId || "no-wallet"; return await this.processEvent(eventToUse, walletId); } catch (error) { - log$24.error("Error in processNextAvailableEvent", { error: error.message }); + log$25.error("Error in processNextAvailableEvent", { error: error.message }); return false; } } @@ -32991,9 +32991,9 @@ var init_EventProcessor = __esmMin((() => { async completeEvent(eventId) { try { await this.eventStore.updateEventStatus(eventId, "completed", "processing"); - log$24.debug("Event marked as completed", { eventId }); + log$25.debug("Event marked as completed", { eventId }); } catch (error) { - log$24.error("Failed to mark event as completed", { + log$25.error("Failed to mark event as completed", { eventId, error: error.message }); @@ -33004,14 +33004,14 @@ var init_EventProcessor = __esmMin((() => { */ startRecoveryLoop() { if (this.recoveryTimeoutId) { - log$24.debug("Recovery loop already running"); + log$25.debug("Recovery loop already running"); return; } const recoveryLoop = async () => { try { if (await this.eventStore.recoverStaleEvents(this.config.processingTimeoutMs) > 0) this.triggerProcessing(); } catch (error) { - log$24.error("Error in recovery loop", { error: error.message }); + log$25.error("Error in recovery loop", { error: error.message }); } if (this.recoveryTimeoutId !== void 0) this.recoveryTimeoutId = setTimeout(recoveryLoop, this.config.recoveryIntervalMs); }; @@ -33019,13 +33019,13 @@ var init_EventProcessor = __esmMin((() => { try { await this.eventStore.cleanupOldEvents(this.config.retentionMs); } catch (error) { - log$24.error("Error in cleanup loop", { error: error.message }); + log$25.error("Error in cleanup loop", { error: error.message }); } if (this.cleanupTimeoutId !== void 0) this.cleanupTimeoutId = setTimeout(cleanupLoop, this.config.cleanupIntervalMs); }; this.recoveryTimeoutId = setTimeout(recoveryLoop, this.config.recoveryIntervalMs); this.cleanupTimeoutId = setTimeout(cleanupLoop, this.config.cleanupIntervalMs); - log$24.info("Recovery and cleanup loops started"); + log$25.info("Recovery and cleanup loops started"); } /** * Stop the recovery process @@ -33039,7 +33039,7 @@ var init_EventProcessor = __esmMin((() => { clearTimeout(this.cleanupTimeoutId); this.cleanupTimeoutId = void 0; } - log$24.info("Recovery and cleanup loops stopped"); + log$25.info("Recovery and cleanup loops stopped"); } /** * Process a single event with retry logic @@ -33047,7 +33047,7 @@ var init_EventProcessor = __esmMin((() => { */ async processEvent(event, walletId) { if (!await this.eventStore.acquireLock(event.id, walletId)) { - log$24.debug("Failed to acquire lock on event", { + log$25.debug("Failed to acquire lock on event", { eventId: event.id, walletId }); @@ -33055,7 +33055,7 @@ var init_EventProcessor = __esmMin((() => { } const retryCount = event.retryCount || 0; if (retryCount >= this.config.maxRetries) { - log$24.error("Event exceeded max retries, marking as errored", { + log$25.error("Event exceeded max retries, marking as errored", { eventId: event.id, retryCount, maxRetries: this.config.maxRetries @@ -33063,14 +33063,14 @@ var init_EventProcessor = __esmMin((() => { try { await this.eventStore.updateEventStatus(event.id, "errored", "processing"); } catch (error) { - log$24.error("Failed to mark event as errored", { + log$25.error("Failed to mark event as errored", { eventId: event.id, error: error.message }); } return false; } - log$24.info("Processing event", { + log$25.info("Processing event", { eventId: event.id, eventType: event.eventType, walletId, @@ -33090,11 +33090,11 @@ var init_EventProcessor = __esmMin((() => { ...walletAddress ? { walletAddress } : {} }); await this.eventStore.updateEventStatus(event.id, "completed", "processing"); - log$24.info("Event processing completed", { eventId: event.id }); + log$25.info("Event processing completed", { eventId: event.id }); return true; } catch (error) { const errorMessage = error.message ?? "Unknown error"; - log$24.error("Error processing event", { + log$25.error("Error processing event", { eventId: event.id, error: errorMessage, retryCount @@ -33102,7 +33102,7 @@ var init_EventProcessor = __esmMin((() => { try { await this.eventStore.releaseLock(event.id, errorMessage); } catch (updateError) { - log$24.error("Failed to increment retry count", { + log$25.error("Failed to increment retry count", { eventId: event.id, error: updateError.message }); @@ -33117,18 +33117,18 @@ var init_EventProcessor = __esmMin((() => { while (this.isProcessing) try { if (!await this.processNextAvailableEvent()) await this.waitForWakeUpOrTimeout(500); } catch (error) { - log$24.error("Error in global processing loop", { error: error.message }); + log$25.error("Error in global processing loop", { error: error.message }); await this.waitForWakeUpOrTimeout(500); } this.wakeUpResolver = void 0; - log$24.debug("Global processing loop ended"); + log$25.debug("Global processing loop ended"); } /** * Trigger the global processing loop */ triggerProcessing() { if (this.isProcessing && this.wakeUpResolver) { - log$24.debug("Waking up global processing loop"); + log$25.debug("Waking up global processing loop"); this.wakeUpResolver(); } } @@ -33165,7 +33165,7 @@ var init_EventProcessor = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/core/wallet/extensions/ton.js -var log$23, WalletTonClass; +var log$24, WalletTonClass; var init_ton = __esmMin((() => { init_address$1(); init_validation(); @@ -33173,9 +33173,9 @@ var init_ton = __esmMin((() => { init_transactionPreview(); init_messageBuilders(); init_getNormalizedExtMessageHash(); - init_errors$4(); + init_errors$5(); init_Logger(); - log$23 = globalLogger.createChild("WalletTonClass"); + log$24 = globalLogger.createChild("WalletTonClass"); WalletTonClass = class { async createTransferTonTransaction(param) { if (!isValidAddress(param.recipientAddress)) throw new Error(`Invalid to address: ${param.recipientAddress}`); @@ -33236,7 +33236,7 @@ var init_ton = __esmMin((() => { normalizedHash }; } catch (error) { - log$23.error("Failed to send transaction", { error }); + log$24.error("Failed to send transaction", { error }); if (error instanceof WalletKitError) throw error; if (error?.message?.includes("Ledger device")) throw new WalletKitError(ERROR_CODES.LEDGER_DEVICE_ERROR, "Ledger device error", error); throw error; @@ -33352,7 +33352,7 @@ async function wrapWalletInterface(wallet) { } }); return newProxy; } -var log$22, Initializer; +var log$23, Initializer; var init_Initializer = __esmMin((() => { init_types$2(); init_storage(); @@ -33367,7 +33367,7 @@ var init_Initializer = __esmMin((() => { init_ton(); init_jetton$1(); init_nft(); - log$22 = globalLogger.createChild("Initializer"); + log$23 = globalLogger.createChild("Initializer"); Initializer = class { config; networkManager; @@ -33383,12 +33383,12 @@ var init_Initializer = __esmMin((() => { */ async initialize(options, networkManager) { try { - log$22.info("Initializing TonWalletKit..."); + log$23.info("Initializing TonWalletKit..."); this.networkManager = networkManager; const storage = this.initializeStorage(options); const { walletManager, sessionManager, bridgeManager, eventRouter, eventProcessor } = await this.initializeManagers(options, storage); const { requestProcessor } = this.initializeProcessors(sessionManager, bridgeManager, walletManager); - log$22.info("TonWalletKit initialized successfully"); + log$23.info("TonWalletKit initialized successfully"); return { walletManager, sessionManager, @@ -33399,7 +33399,7 @@ var init_Initializer = __esmMin((() => { eventProcessor }; } catch (error) { - log$22.error("Failed to initialize TonWalletKit", { error }); + log$23.error("Failed to initialize TonWalletKit", { error }); throw error; } } @@ -33435,9 +33435,9 @@ var init_Initializer = __esmMin((() => { const bridgeManager = new BridgeManager(options?.walletManifest, options?.bridge, sessionManager, storage, eventStore, eventRouter, options, this.eventEmitter, this.analyticsManager); eventRouter.setBridgeManager(bridgeManager); bridgeManager.start().then(() => { - log$22.info("Bridge manager started successfully"); + log$23.info("Bridge manager started successfully"); }).catch((e) => { - log$22.error("Could not start bridge manager", { error: e?.toString?.() }); + log$23.error("Could not start bridge manager", { error: e?.toString?.() }); }); const eventProcessor = new StorageEventProcessor(options?.eventProcessor, eventStore, DEFAULT_DURABLE_EVENTS_CONFIG, walletManager, sessionManager, eventRouter, this.eventEmitter); return { @@ -33459,7 +33459,7 @@ var init_Initializer = __esmMin((() => { */ async cleanup(components) { try { - log$22.info("Cleaning up TonWalletKit components..."); + log$23.info("Cleaning up TonWalletKit components..."); if (components.eventProcessor) { components.eventProcessor.stopRecoveryLoop(); await components.eventProcessor.clearRegisteredWallets(); @@ -33467,9 +33467,9 @@ var init_Initializer = __esmMin((() => { } if (components.bridgeManager) await components.bridgeManager.close(); if (components.eventRouter) components.eventRouter.clearCallbacks(); - log$22.info("TonWalletKit cleanup completed"); + log$23.info("TonWalletKit cleanup completed"); } catch (error) { - log$22.error("Error during cleanup", { error }); + log$23.error("Error during cleanup", { error }); } } }; @@ -33485,14 +33485,14 @@ function isTonAddress(address) { function createCacheKey(network, address) { return `${network.chainId}:${address}`; } -var import_dist$15, log$21, GRAM_ADDRESS, TON_INFO, JettonsManager; +var import_dist$15, log$22, GRAM_ADDRESS, TON_INFO, JettonsManager; var init_JettonsManager = __esmMin((() => { import_dist$15 = require_dist$1(); init_index_min(); init_Logger(); init_jettons(); init_utils$2(); - log$21 = globalLogger.createChild("JettonsManager"); + log$22 = globalLogger.createChild("JettonsManager"); GRAM_ADDRESS = "TON"; TON_INFO = { address: GRAM_ADDRESS, @@ -33519,7 +33519,7 @@ var init_JettonsManager = __esmMin((() => { ttl: 1e3 * 60 * 10 }); for (const network of this.networkManager.getConfiguredNetworks()) this.addTonToCache(network); - log$21.info("JettonsManager initialized", { cacheSize }); + log$22.info("JettonsManager initialized", { cacheSize }); } /** * Add GRAM native token to cache for a specific network @@ -33540,19 +33540,19 @@ var init_JettonsManager = __esmMin((() => { const cacheKey = this.normalizedCacheKey(targetNetwork, jettonAddress); const cachedInfo = this.cache.get(cacheKey); if (cachedInfo) { - log$21.debug("Jetton info found in cache", { + log$22.debug("Jetton info found in cache", { jettonAddress, network: targetNetwork }); return cachedInfo; } - log$21.debug("Jetton info not found in cache", { + log$22.debug("Jetton info not found in cache", { jettonAddress, network: targetNetwork }); const address = asMaybeAddressFriendly(jettonAddress); if (!address) { - log$21.error("Invalid jetton address format", { + log$22.error("Invalid jetton address format", { jettonAddress, network: targetNetwork }); @@ -33573,7 +33573,7 @@ var init_JettonsManager = __esmMin((() => { decimals = 9; } const result = { - address: jetton.jetton, + address: jetton.address, name: tokenInfo?.name ?? "", symbol: tokenInfo?.symbol ?? "", description: tokenInfo?.description ?? "", @@ -33587,7 +33587,7 @@ var init_JettonsManager = __esmMin((() => { } return null; } catch (error) { - log$21.error("Error getting jetton info", { + log$22.error("Error getting jetton info", { error, jettonAddress, network: targetNetwork @@ -33606,7 +33606,7 @@ var init_JettonsManager = __esmMin((() => { const targetNetwork = network; try { const apiClient = this.networkManager.getClient(targetNetwork); - log$21.debug("Getting address jettons", { + log$22.debug("Getting address jettons", { userAddress, network: targetNetwork, offset, @@ -33620,13 +33620,13 @@ var init_JettonsManager = __esmMin((() => { if (!response.jettons) return []; const addressJettons = []; for (const item of response.jettons) addressJettons.push(item); - log$21.debug("Retrieved address jettons", { + log$22.debug("Retrieved address jettons", { count: addressJettons.length, network: targetNetwork }); return addressJettons; } catch (error) { - log$21.error("Failed to get address jettons", { + log$22.error("Failed to get address jettons", { error, userAddress, network: targetNetwork @@ -33650,14 +33650,14 @@ var init_JettonsManager = __esmMin((() => { uri: emulationInfo.extra.uri }; this.cache.set(cacheKey, jettonInfo); - log$21.debug("Added jetton info from emulation to cache", { + log$22.debug("Added jetton info from emulation to cache", { jettonAddress, network, name: jettonInfo.name, symbol: jettonInfo.symbol }); } catch (error) { - log$21.error("Error adding jetton from emulation", { + log$22.error("Error adding jetton from emulation", { error, jettonAddress, network @@ -33674,7 +33674,7 @@ var init_JettonsManager = __esmMin((() => { if (!addressMetadata.is_indexed || !addressMetadata.token_info) continue; const jettonMasterInfo = addressMetadata.token_info.find((info) => typeof info === "object" && info !== null && "type" in info && info.type === "jetton_masters"); if (jettonMasterInfo) { - log$21.debug("Adding jetton from emulation metadata", { + log$22.debug("Adding jetton from emulation metadata", { jettonAddress, network }); @@ -33682,12 +33682,12 @@ var init_JettonsManager = __esmMin((() => { addedCount++; } } - if (addedCount > 0) log$21.info("Added jettons from emulation metadata", { + if (addedCount > 0) log$22.info("Added jettons from emulation metadata", { addedCount, network }); } catch (error) { - log$21.error("Error adding jettons from emulation metadata", { + log$22.error("Error adding jettons from emulation metadata", { error, network }); @@ -33728,11 +33728,11 @@ var init_JettonsManager = __esmMin((() => { if (network) { for (const key of this.cache.keys()) if (key.startsWith(`${network.chainId}:`)) this.cache.delete(key); this.addTonToCache(network); - log$21.info("Jetton cache cleared for network", { network }); + log$22.info("Jetton cache cleared for network", { network }); } else { this.cache.clear(); for (const net of this.networkManager.getConfiguredNetworks()) this.addTonToCache(net); - log$21.info("Jetton cache cleared for all networks"); + log$22.info("Jetton cache cleared for all networks"); } } }; @@ -33748,7 +33748,7 @@ var init_SwapProvider = __esmMin((() => { //#endregion //#region ../walletkit/dist/esm/defi/errors.js var DefiErrorCode, DefiError; -var init_errors$3 = __esmMin((() => { +var init_errors$4 = __esmMin((() => { (function(DefiErrorCode) { DefiErrorCode["ProviderNotFound"] = "PROVIDER_NOT_FOUND"; DefiErrorCode["NoDefaultProvider"] = "NO_DEFAULT_PROVIDER"; @@ -33771,8 +33771,8 @@ var init_errors$3 = __esmMin((() => { //#endregion //#region ../walletkit/dist/esm/defi/swap/errors.js var SwapErrorCode, SwapError; -var init_errors$2 = __esmMin((() => { - init_errors$3(); +var init_errors$3 = __esmMin((() => { + init_errors$4(); (function(SwapErrorCode) { SwapErrorCode["InvalidQuote"] = "INVALID_QUOTE"; SwapErrorCode["InsufficientLiquidity"] = "INSUFFICIENT_LIQUIDITY"; @@ -33794,7 +33794,7 @@ var init_errors$2 = __esmMin((() => { var DefiManager; var init_DefiManager = __esmMin((() => { init_types$2(); - init_errors$3(); + init_errors$4(); DefiManager = class { createFactoryContext; providers = []; @@ -33892,12 +33892,12 @@ var init_DefiManager = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/defi/swap/SwapManager.js -var log$20, SwapManager; +var log$21, SwapManager; var init_SwapManager = __esmMin((() => { - init_errors$2(); + init_errors$3(); init_Logger(); init_DefiManager(); - log$20 = globalLogger.createChild("SwapManager"); + log$21 = globalLogger.createChild("SwapManager"); SwapManager = class extends DefiManager { constructor(createFactoryContext) { super(createFactoryContext); @@ -33909,7 +33909,7 @@ var init_SwapManager = __esmMin((() => { * @returns Promise resolving to swap quote */ async getQuote(params, providerId) { - log$20.debug("Getting swap quote", { + log$21.debug("Getting swap quote", { fromToken: params.from, toToken: params.to, amount: params.amount, @@ -33918,14 +33918,14 @@ var init_SwapManager = __esmMin((() => { }); try { const quote = await this.getProvider(providerId || this.defaultProviderId).getQuote(params); - log$20.debug("Received swap quote", { + log$21.debug("Received swap quote", { fromAmount: quote.fromAmount, toAmount: quote.toAmount, priceImpact: quote.priceImpact }); return quote; } catch (error) { - log$20.error("Failed to get swap quote", { + log$21.error("Failed to get swap quote", { error, params }); @@ -33939,16 +33939,16 @@ var init_SwapManager = __esmMin((() => { */ async buildSwapTransaction(params) { const providerId = params.quote.providerId || this.defaultProviderId; - log$20.debug("Building swap transaction", { + log$21.debug("Building swap transaction", { providerId, userAddress: params.userAddress }); try { const transaction = await this.getProvider(providerId).buildSwapTransaction(params); - log$20.debug("Built swap transaction", params.quote); + log$21.debug("Built swap transaction", params.quote); return transaction; } catch (error) { - log$20.error("Failed to build swap transaction", { + log$21.error("Failed to build swap transaction", { error, params }); @@ -33965,7 +33965,7 @@ var init_SwapManager = __esmMin((() => { var init_swap = __esmMin((() => { init_SwapProvider(); init_SwapManager(); - init_errors$2(); + init_errors$3(); })); //#endregion //#region ../walletkit/dist/esm/defi/staking/StakingProvider.js @@ -33982,8 +33982,8 @@ var init_StakingProvider = __esmMin((() => { //#endregion //#region ../walletkit/dist/esm/defi/staking/errors.js var StakingErrorCode, StakingError; -var init_errors$1 = __esmMin((() => { - init_errors$3(); +var init_errors$2 = __esmMin((() => { + init_errors$4(); (function(StakingErrorCode) { StakingErrorCode["InvalidParams"] = "INVALID_PARAMS"; StakingErrorCode["UnsupportedOperation"] = "UNSUPPORTED_OPERATION"; @@ -33999,12 +33999,12 @@ var init_errors$1 = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/defi/staking/StakingManager.js -var log$19, StakingManager; +var log$20, StakingManager; var init_StakingManager = __esmMin((() => { - init_errors$1(); + init_errors$2(); init_Logger(); init_DefiManager(); - log$19 = globalLogger.createChild("StakingManager"); + log$20 = globalLogger.createChild("StakingManager"); StakingManager = class extends DefiManager { constructor(createFactoryContext) { super(createFactoryContext); @@ -34015,13 +34015,13 @@ var init_StakingManager = __esmMin((() => { * @param providerId - Optional provider id to use */ async getQuote(params, providerId) { - log$19.debug("Getting staking quote", params); + log$20.debug("Getting staking quote", params); try { const quote = await this.getProvider(providerId).getQuote(params); - log$19.debug("Received staking quote", quote); + log$20.debug("Received staking quote", quote); return quote; } catch (error) { - log$19.error("Failed to get staking quote", { + log$20.error("Failed to get staking quote", { error, params }); @@ -34034,11 +34034,11 @@ var init_StakingManager = __esmMin((() => { * @param providerId - Optional provider id to use */ async buildStakeTransaction(params, providerId) { - log$19.debug("Building staking transaction", params); + log$20.debug("Building staking transaction", params); try { return await this.getProvider(providerId).buildStakeTransaction(params); } catch (error) { - log$19.error("Failed to build staking transaction", { + log$20.error("Failed to build staking transaction", { error, params }); @@ -34052,7 +34052,7 @@ var init_StakingManager = __esmMin((() => { * @param providerId - Optional provider id to use */ async getStakedBalance(userAddress, network, providerId) { - log$19.debug("Getting staking balance", { + log$20.debug("Getting staking balance", { userAddress, network, provider: providerId || this.defaultProviderId @@ -34060,7 +34060,7 @@ var init_StakingManager = __esmMin((() => { try { return await this.getProvider(providerId).getStakedBalance(userAddress, network); } catch (error) { - log$19.error("Failed to get staking balance", { + log$20.error("Failed to get staking balance", { error, userAddress, network @@ -34074,14 +34074,14 @@ var init_StakingManager = __esmMin((() => { * @param providerId - Optional provider id to use */ async getStakingProviderInfo(network, providerId) { - log$19.debug("Getting staking info", { + log$20.debug("Getting staking info", { network, provider: providerId || this.defaultProviderId }); try { return await this.getProvider(providerId).getStakingProviderInfo(network); } catch (error) { - log$19.error("Failed to get staking info", { + log$20.error("Failed to get staking info", { error, network }); @@ -34094,14 +34094,14 @@ var init_StakingManager = __esmMin((() => { * @param providerId - Optional provider id to use */ getStakingProviderMetadata(network, providerId) { - log$19.debug("Getting staking metadata", { + log$20.debug("Getting staking metadata", { network, provider: providerId || this.defaultProviderId }); try { return this.getProvider(providerId).getStakingProviderMetadata(network); } catch (error) { - log$19.error("Failed to get staking metadata", { + log$20.error("Failed to get staking metadata", { error, network }); @@ -34110,7 +34110,7 @@ var init_StakingManager = __esmMin((() => { } createError(message, code, details) { const errorCode = Object.values(StakingErrorCode).includes(code) ? code : StakingErrorCode.InvalidParams; - log$19.error(message, { + log$20.error(message, { code, details }); @@ -34123,7 +34123,7 @@ var init_StakingManager = __esmMin((() => { var init_staking = __esmMin((() => { init_StakingProvider(); init_StakingManager(); - init_errors$1(); + init_errors$2(); })); //#endregion //#region ../walletkit/dist/esm/defi/gasless/GaslessProvider.js @@ -34136,8 +34136,8 @@ var init_GaslessProvider = __esmMin((() => { //#endregion //#region ../walletkit/dist/esm/defi/gasless/errors.js var GaslessErrorCode, GaslessError; -var init_errors = __esmMin((() => { - init_errors$3(); +var init_errors$1 = __esmMin((() => { + init_errors$4(); (function(GaslessErrorCode) { GaslessErrorCode["UnsupportedFeeAsset"] = "UNSUPPORTED_FEE_ASSET"; GaslessErrorCode["UnsupportedOperation"] = "UNSUPPORTED_OPERATION"; @@ -34161,12 +34161,12 @@ var init_errors = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/defi/gasless/GaslessManager.js -var log$18, GaslessManager; +var log$19, GaslessManager; var init_GaslessManager = __esmMin((() => { init_Logger(); init_DefiManager(); - init_errors(); - log$18 = globalLogger.createChild("GaslessManager"); + init_errors$1(); + log$19 = globalLogger.createChild("GaslessManager"); GaslessManager = class extends DefiManager { constructor(createFactoryContext) { super(createFactoryContext); @@ -34176,11 +34176,11 @@ var init_GaslessManager = __esmMin((() => { */ async getMetadata(providerId) { const selectedProviderId = providerId ?? this.defaultProviderId; - log$18.debug("Getting gasless provider metadata", { providerId: selectedProviderId }); + log$19.debug("Getting gasless provider metadata", { providerId: selectedProviderId }); try { return await this.getProvider(selectedProviderId).getMetadata(); } catch (error) { - log$18.error("Failed to get gasless provider metadata", { error }); + log$19.error("Failed to get gasless provider metadata", { error }); throw error; } } @@ -34192,14 +34192,14 @@ var init_GaslessManager = __esmMin((() => { async getConfig(network, providerId) { const provider = this.getProvider(providerId ?? this.defaultProviderId); const targetNetwork = network ?? provider.getSupportedNetworks()[0]; - log$18.debug("Getting gasless config", { + log$19.debug("Getting gasless config", { network: targetNetwork?.chainId, providerId: providerId ?? this.defaultProviderId }); try { return await provider.getConfig(targetNetwork); } catch (error) { - log$18.error("Failed to get gasless config", { error }); + log$19.error("Failed to get gasless config", { error }); throw error; } } @@ -34207,7 +34207,7 @@ var init_GaslessManager = __esmMin((() => { * Quote fees and obtain relayer-wrapped messages for signing. */ async getQuote(params, providerId) { - log$18.debug("Quoting gasless transaction", { + log$19.debug("Quoting gasless transaction", { network: params.network.chainId, walletAddress: params.walletAddress, feeAsset: params.feeAsset, @@ -34217,7 +34217,7 @@ var init_GaslessManager = __esmMin((() => { try { return await this.getProvider(providerId ?? this.defaultProviderId).getQuote(params); } catch (error) { - log$18.error("Failed to quote gasless transaction", { + log$19.error("Failed to quote gasless transaction", { error, params }); @@ -34228,14 +34228,14 @@ var init_GaslessManager = __esmMin((() => { * Submit a signed transaction BoC to the relayer. */ async sendTransaction(params, providerId) { - log$18.debug("Sending gasless transaction", { + log$19.debug("Sending gasless transaction", { network: params.network.chainId, providerId: providerId ?? this.defaultProviderId }); try { return await this.getProvider(providerId ?? this.defaultProviderId).sendTransaction(params); } catch (error) { - log$18.error("Failed to send gasless transaction", { error }); + log$19.error("Failed to send gasless transaction", { error }); throw error; } } @@ -34249,14 +34249,14 @@ var init_GaslessManager = __esmMin((() => { var init_gasless = __esmMin((() => { init_GaslessProvider(); init_GaslessManager(); - init_errors(); + init_errors$1(); })); //#endregion //#region ../walletkit/dist/esm/core/EventEmitter.js -var log$17, EventEmitter; +var log$18, EventEmitter; var init_EventEmitter = __esmMin((() => { init_Logger(); - log$17 = globalLogger.createChild("EventEmitter"); + log$18 = globalLogger.createChild("EventEmitter"); EventEmitter = class { listeners = {}; /** @@ -34267,7 +34267,7 @@ var init_EventEmitter = __esmMin((() => { const eventListeners = this.listeners[eventName]; if (!eventListeners) this.listeners[eventName] = new Set([listener]); else eventListeners.add(listener); - log$17.debug("Event listener added", { + log$18.debug("Event listener added", { eventName: String(eventName), totalListeners: this.listeners[eventName]?.size }); @@ -34311,10 +34311,10 @@ var init_EventEmitter = __esmMin((() => { removeAllListeners(eventName) { if (eventName) { delete this.listeners[eventName]; - log$17.debug("All listeners removed for event", { eventName: String(eventName) }); + log$18.debug("All listeners removed for event", { eventName: String(eventName) }); } else { this.listeners = {}; - log$17.debug("All event listeners cleared"); + log$18.debug("All event listeners cleared"); } } /** @@ -34333,12 +34333,12 @@ var init_EventEmitter = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/streaming/StreamingManager.js -var log$16, StreamingManager; +var log$17, StreamingManager; var init_StreamingManager = __esmMin((() => { init_Logger(); init_utils$2(); init_factory$2(); - log$16 = globalLogger.createChild("StreamingManager"); + log$17 = globalLogger.createChild("StreamingManager"); StreamingManager = class { createFactoryContext; providers = /* @__PURE__ */ new Map(); @@ -34354,7 +34354,7 @@ var init_StreamingManager = __esmMin((() => { const provider = resolveProvider(input, this.createFactoryContext()); const networkId = String(provider.network.chainId); if (this.providers.has(networkId)) { - log$16.warn(`Provider for network ${networkId} is already registered. Overriding.`); + log$17.warn(`Provider for network ${networkId} is already registered. Overriding.`); this.providerConnectionUnsubs.get(networkId)?.(); this.providers.get(networkId)?.disconnect(); } @@ -34443,6 +34443,59 @@ var init_StreamingManager = __esmMin((() => { }; })); //#endregion +//#region ../walletkit/dist/esm/providers/CustomProvidersManager.js +var CustomProvidersManager; +var init_CustomProvidersManager = __esmMin((() => { + init_types$2(); + CustomProvidersManager = class { + createFactoryContext; + providers = /* @__PURE__ */ new Map(); + eventEmitter; + constructor(createFactoryContext) { + this.createFactoryContext = createFactoryContext; + this.eventEmitter = createFactoryContext().eventEmitter; + } + /** + * Register a custom provider. Replaces any existing provider with the same id. + * Emits `provider:registered`. + * @param input - Provider instance or factory that produces one + */ + registerProvider(input) { + const provider = resolveProvider(input, this.createFactoryContext()); + this.providers.set(provider.providerId, provider); + this.eventEmitter.emit("provider:registered", { + providerId: provider.providerId, + type: provider.type + }, "custom-providers-manager"); + } + /** + * Get a registered custom provider by id. + * @param providerId - Id the provider was registered under + * @returns The provider when present, otherwise undefined + */ + getProvider(providerId) { + return this.providers.get(providerId); + } + /** + * Check if a custom provider is registered + */ + hasProvider(providerId) { + return this.providers.has(providerId); + } + /** + * Get the ids of all registered custom providers + */ + getRegisteredProviders() { + return Array.from(this.providers.keys()); + } + }; +})); +//#endregion +//#region ../walletkit/dist/esm/providers/index.js +var init_providers = __esmMin((() => { + init_CustomProvidersManager(); +})); +//#endregion //#region ../walletkit/dist/esm/analytics/swagger/generated.js var ContentType, HttpClient, Api; var init_generated = __esmMin((() => { @@ -34605,13 +34658,13 @@ function pascalToKebab(value) { var init_utils$1 = __esmMin((() => {})); //#endregion //#region ../walletkit/dist/esm/analytics/AnalyticsManager.js -var log$15, AnalyticsManager; +var log$16, AnalyticsManager; var init_AnalyticsManager = __esmMin((() => { init_Logger(); init_swagger(); init_utils$1(); init_utils$2(); - log$15 = globalLogger.createChild("AnalyticsManager"); + log$16 = globalLogger.createChild("AnalyticsManager"); AnalyticsManager = class AnalyticsManager { api; baseEvent; @@ -34675,12 +34728,12 @@ var init_AnalyticsManager = __esmMin((() => { }; if (this.appInfo?.getLocale) enhancedEvent.locale = this.appInfo.getLocale(); if (this.appInfo?.getCurrentUserId) enhancedEvent.user_id = this.appInfo.getCurrentUserId(); - log$15.debug("Analytics event emitted", { event: enhancedEvent }); + log$16.debug("Analytics event emitted", { event: enhancedEvent }); this.events.push(enhancedEvent); if (this.events.length > this.maxQueueSize) { const removed = this.events.length - this.maxQueueSize; this.events = this.events.slice(removed); - log$15.warn("Analytics queue overflow, dropped oldest events", { count: removed }); + log$16.warn("Analytics queue overflow, dropped oldest events", { count: removed }); } if (this.events.length >= this.maxBatchSize) { this.flush(); @@ -34701,10 +34754,10 @@ var init_AnalyticsManager = __esmMin((() => { const eventsToSend = this.extractEventsToSend(); try { await this.processEventsBatch(eventsToSend); - log$15.debug("Analytics events sent successfully"); + log$16.debug("Analytics events sent successfully"); } catch (error) { this.restoreEvents(eventsToSend); - log$15.error("Failed to send analytics events", { error }); + log$16.error("Failed to send analytics events", { error }); } finally { this.isProcessing = false; this.scheduleNextFlushIfNeeded(); @@ -34722,7 +34775,7 @@ var init_AnalyticsManager = __esmMin((() => { return eventsToSend; } async processEventsBatch(eventsToSend) { - log$15.debug("Sending analytics events", { count: eventsToSend.length }); + log$16.debug("Sending analytics events", { count: eventsToSend.length }); try { const response = await this.sendEvents(eventsToSend); this.handleResponse(response); @@ -34744,7 +34797,7 @@ var init_AnalyticsManager = __esmMin((() => { if (this.events.length > this.maxQueueSize) { const removed = this.events.length - this.maxQueueSize; this.events = this.events.slice(0, this.maxQueueSize); - log$15.warn("Analytics queue overflow after restore, dropped oldest events", { count: removed }); + log$16.warn("Analytics queue overflow after restore, dropped oldest events", { count: removed }); } } scheduleNextFlushIfNeeded() { @@ -34763,7 +34816,7 @@ var init_AnalyticsManager = __esmMin((() => { return status === AnalyticsManager.HTTP_STATUS.TOO_MANY_REQUESTS; } handleClientError(status, statusText) { - log$15.error("Analytics API client error", { + log$16.error("Analytics API client error", { status, statusText }); @@ -35563,7 +35616,7 @@ var init_BaseApiClient = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/clients/toncenter/ApiClientToncenter.js -var import_dist$13, log$14, MAX_ACCOUNT_STATES_BATCH$1, ApiClientToncenter; +var import_dist$13, log$15, MAX_ACCOUNT_STATES_BATCH$1, ApiClientToncenter; var init_ApiClientToncenter = __esmMin((() => { import_dist$13 = require_dist$1(); init_base64(); @@ -35582,7 +35635,7 @@ var init_ApiClientToncenter = __esmMin((() => { init_utils(); init_TonClientError(); init_utils$2(); - log$14 = globalLogger.createChild("ApiClientToncenter"); + log$15 = globalLogger.createChild("ApiClientToncenter"); MAX_ACCOUNT_STATES_BATCH$1 = 100; ApiClientToncenter = class extends BaseApiClient { constructor(config = {}) { @@ -35730,7 +35783,7 @@ var init_ApiClientToncenter = __esmMin((() => { const fulfilledResult = results.find((result) => result.status === "fulfilled"); if (fulfilledResult) return fulfilledResult.value; results.forEach((result) => { - if (result.status === "rejected") log$14.error("Error fetching trace", { error: result.reason }); + if (result.status === "rejected") log$15.error("Error fetching trace", { error: result.reason }); }); throw new Error("Failed to fetch trace"); } @@ -35741,7 +35794,7 @@ var init_ApiClientToncenter = __esmMin((() => { }, void 0, void 0, (err) => err instanceof TonClientError ? err.status !== 422 : true); if (response?.traces?.length > 0) return response; } catch (error) { - log$14.error("Error fetching pending trace", { error }); + log$15.error("Error fetching pending trace", { error }); } throw new Error("Failed to fetch pending trace"); } @@ -35870,13 +35923,13 @@ var init_toncenter$1 = __esmMin((() => { })); //#endregion //#region ../walletkit/dist/esm/core/NetworkManager.js -var log$13, KitNetworkManager; +var log$14, KitNetworkManager; var init_NetworkManager = __esmMin((() => { init_toncenter$1(); init_Logger(); - init_errors$4(); + init_errors$5(); init_models(); - log$13 = globalLogger.createChild("NetworkManager"); + log$14 = globalLogger.createChild("NetworkManager"); KitNetworkManager = class { clients = /* @__PURE__ */ new Map(); constructor(options) { @@ -35889,7 +35942,7 @@ var init_NetworkManager = __esmMin((() => { initializeClients(options) { const networks = options.networks; if (!networks) { - log$13.warn("No networks configured in TonWalletKitOptions"); + log$14.warn("No networks configured in TonWalletKitOptions"); return; } for (const [chainId, networkConfig] of Object.entries(networks)) { @@ -35897,7 +35950,7 @@ var init_NetworkManager = __esmMin((() => { if (!networkConfig) continue; const client = this.createClient(network, networkConfig.apiClient, options); this.clients.set(network.chainId, client); - log$13.info("Initialized network client", { chainId }); + log$14.info("Initialized network client", { chainId }); } } /** @@ -35953,7 +36006,7 @@ var init_NetworkManager = __esmMin((() => { */ setClient(network, client) { this.clients.set(network.chainId, client); - log$13.info("Added/updated network client", { network }); + log$14.info("Added/updated network client", { network }); } }; })); @@ -35967,7 +36020,7 @@ function parseEmbeddedRequestFromReqParam(reqParam) { try { return toEmbeddedRequest(decodeEmbeddedRequestParam(reqParam)); } catch (error) { - log$12.warn("Failed to parse embedded request req parameter", { error }); + log$13.warn("Failed to parse embedded request req parameter", { error }); return; } } @@ -35993,20 +36046,20 @@ function toEmbeddedRequest(parsed) { }; } default: - log$12.warn("Unknown embedded request method", { method: parsed.method }); + log$13.warn("Unknown embedded request method", { method: parsed.method }); return; } } -var log$12; +var log$13; var init_embeddedRequest = __esmMin((() => { init_esm$2(); init_internal(); init_Logger(); - log$12 = globalLogger.createChild("embeddedRequestParser"); + log$13 = globalLogger.createChild("embeddedRequestParser"); })); //#endregion //#region ../walletkit/dist/esm/core/TonWalletKit.js -var import_dist$12, log$11, TonWalletKit$1; +var import_dist$12, log$12, TonWalletKit$1; var init_TonWalletKit = __esmMin((() => { import_dist$12 = require_dist$1(); init_esm$2(); @@ -36020,14 +36073,15 @@ var init_TonWalletKit = __esmMin((() => { init_internal(); init_EventEmitter(); init_StreamingManager(); + init_providers(); init_analytics(); init_getDefaultWalletConfig(); - init_errors$4(); + init_errors$5(); init_retry(); init_NetworkManager(); init_utils$2(); init_embeddedRequest(); - log$11 = globalLogger.createChild("TonWalletKit"); + log$12 = globalLogger.createChild("TonWalletKit"); TonWalletKit$1 = class { walletManager; sessionManager; @@ -36039,6 +36093,7 @@ var init_TonWalletKit = __esmMin((() => { streamingManager; stakingManager; gaslessManager; + customProvidersManager; initializer; eventProcessor; bridgeManager; @@ -36066,9 +36121,10 @@ var init_TonWalletKit = __esmMin((() => { this.swapManager = new SwapManager(() => this.createFactoryContext()); this.stakingManager = new StakingManager(() => this.createFactoryContext()); this.gaslessManager = new GaslessManager(() => this.createFactoryContext()); + this.customProvidersManager = new CustomProvidersManager(() => this.createFactoryContext()); this.eventEmitter.on("restoreConnection", async ({ payload: event }) => { if (!event.domain) { - log$11.error("Domain is required for restore connection"); + log$12.error("Domain is required for restore connection"); return this.sendErrorConnectResponse(event); } const sessions = await this.sessionManager.getSessions({ @@ -36078,12 +36134,12 @@ var init_TonWalletKit = __esmMin((() => { }); const session = sessions.length > 0 ? sessions[0] : void 0; if (!session) { - log$11.error("Session not found for domain", { domain: event.domain }); + log$12.error("Session not found for domain", { domain: event.domain }); return this.sendErrorConnectResponse(event); } const wallet = session.walletId ? this.walletManager?.getWallet(session.walletId) : void 0; if (!wallet) { - log$11.error("Wallet not found for session", { walletId: session.walletId }); + log$12.error("Wallet not found for session", { walletId: session.walletId }); return this.sendErrorConnectResponse(event); } const walletAddress = wallet.getAddress(); @@ -36137,7 +36193,7 @@ var init_TonWalletKit = __esmMin((() => { await this.eventProcessor.startProcessing(); this.isInitialized = true; } catch (error) { - log$11.error("TonWalletKit initialization failed", { error: error?.toString() }); + log$12.error("TonWalletKit initialization failed", { error: error?.toString() }); throw error; } } @@ -36167,7 +36223,7 @@ var init_TonWalletKit = __esmMin((() => { const walletId = wallet.getWalletId(); await this.eventProcessor.startProcessing(walletId); } catch (error) { - log$11.error("Failed to start event processing for wallet", { + log$12.error("Failed to start event processing for wallet", { walletAddress: wallet.getAddress(), error }); @@ -36187,7 +36243,7 @@ var init_TonWalletKit = __esmMin((() => { } getWallets() { if (!this.isInitialized) { - log$11.warn("TonWalletKit not yet initialized, returning empty array"); + log$12.warn("TonWalletKit not yet initialized, returning empty array"); return []; } return this.walletManager.getWallets(); @@ -36197,7 +36253,7 @@ var init_TonWalletKit = __esmMin((() => { */ getWallet(walletId) { if (!this.isInitialized) { - log$11.warn("TonWalletKit not yet initialized, returning undefined"); + log$12.warn("TonWalletKit not yet initialized, returning undefined"); return; } return this.walletManager.getWallet(walletId); @@ -36257,7 +36313,7 @@ var init_TonWalletKit = __esmMin((() => { payload: {} }, sessionCrypto), 10, 100); } catch (error) { - log$11.error("Failed to send disconnect to bridge", { + log$12.error("Failed to send disconnect to bridge", { sessionId, error }); @@ -36267,7 +36323,7 @@ var init_TonWalletKit = __esmMin((() => { if (sessionId) try { await removeSession(sessionId); } catch (error) { - log$11.error("Failed to remove session", { + log$12.error("Failed to remove session", { sessionId, error }); @@ -36277,7 +36333,7 @@ var init_TonWalletKit = __esmMin((() => { if (sessions.length > 0) for (const session of sessions) try { await removeSession(session.sessionId); } catch (error) { - log$11.error("Failed to remove session", { + log$12.error("Failed to remove session", { sessionId: session.sessionId, error }); @@ -36351,7 +36407,7 @@ var init_TonWalletKit = __esmMin((() => { const bridgeEvent = this.parseBridgeConnectEventFromUrl(url); return await new ConnectHandler(() => {}, this.config, this.analyticsManager).handle(bridgeEvent); } catch (error) { - log$11.error("Failed to create connection event from URL", { + log$12.error("Failed to create connection event from URL", { error, url }); @@ -36368,7 +36424,7 @@ var init_TonWalletKit = __esmMin((() => { const bridgeEvent = this.parseBridgeConnectEventFromUrl(url); await this.eventRouter.routeEvent(bridgeEvent); } catch (error) { - log$11.error("Failed to handle TON Connect URL", { + log$12.error("Failed to handle TON Connect URL", { error, url }); @@ -36412,7 +36468,7 @@ var init_TonWalletKit = __esmMin((() => { const params = {}; for (const [key, value] of parsedUrl.searchParams.entries()) params[key] = value; if (!params.v || !params.id || !params.r) { - log$11.warn("Missing required TON Connect URL parameters"); + log$12.warn("Missing required TON Connect URL parameters"); return null; } return { @@ -36424,7 +36480,7 @@ var init_TonWalletKit = __esmMin((() => { ...params }; } catch (error) { - log$11.error("Failed to parse TON Connect URL", { + log$12.error("Failed to parse TON Connect URL", { error, url }); @@ -36451,7 +36507,7 @@ var init_TonWalletKit = __esmMin((() => { domain: "" }; if (params.e) if (this.config.deviceInfo?.features.some((feature) => typeof feature === "object" && feature.name === "EmbeddedRequest")) bridgeEvent.embeddedRequest = parseEmbeddedRequestFromReqParam(params.e); - else log$11.warn("Embedded request feature is not supported in features, but we received request with embedded request payload", { features: this.config.deviceInfo?.features }); + else log$12.warn("Embedded request feature is not supported in features, but we received request with embedded request payload", { features: this.config.deviceInfo?.features }); return bridgeEvent; } async approveConnectRequest(event, response) { @@ -36555,6 +36611,9 @@ var init_TonWalletKit = __esmMin((() => { case "gasless": this.gaslessManager.registerProvider(provider); break; + case "custom": + this.customProvidersManager.registerProvider(provider); + break; default: throw new Error("Unknown provider type"); } } @@ -36595,6 +36654,12 @@ var init_TonWalletKit = __esmMin((() => { return this.gaslessManager; } /** + * Custom providers API access + */ + get customProviders() { + return this.customProvidersManager; + } + /** * Get the event emitter for this kit instance * Allows external components to listen to and emit events */ @@ -36614,6 +36679,194 @@ var init_TonWalletKit = __esmMin((() => { }; })); //#endregion +//#region ../walletkit/dist/esm/defi/crypto-onramp/errors.js +var CryptoOnrampErrorCode, CryptoOnrampError; +var init_errors = __esmMin((() => { + init_errors$4(); + (function(CryptoOnrampErrorCode) { + CryptoOnrampErrorCode["ProviderError"] = "PROVIDER_ERROR"; + CryptoOnrampErrorCode["QuoteFailed"] = "QUOTE_FAILED"; + CryptoOnrampErrorCode["RefundAddressRequired"] = "REFUND_ADDRESS_REQUIRED"; + CryptoOnrampErrorCode["InvalidRefundAddress"] = "INVALID_REFUND_ADDRESS"; + CryptoOnrampErrorCode["ReversedAmountNotSupported"] = "REVERSED_AMOUNT_NOT_SUPPORTED"; + CryptoOnrampErrorCode["UnsupportedSourceChain"] = "UNSUPPORTED_SOURCE_CHAIN"; + CryptoOnrampErrorCode["UnsupportedSourceToken"] = "UNSUPPORTED_SOURCE_TOKEN"; + CryptoOnrampErrorCode["UnsupportedDestinationToken"] = "UNSUPPORTED_DESTINATION_TOKEN"; + CryptoOnrampErrorCode["RouteNotFound"] = "ROUTE_NOT_FOUND"; + CryptoOnrampErrorCode["AmountTooLarge"] = "AMOUNT_TOO_LARGE"; + CryptoOnrampErrorCode["AmountTooSmall"] = "AMOUNT_TOO_SMALL"; + CryptoOnrampErrorCode["InvalidParams"] = "INVALID_PARAMS"; + })(CryptoOnrampErrorCode || (CryptoOnrampErrorCode = {})); + CryptoOnrampError = class extends DefiError { + code; + constructor(message, code, details) { + super(message, code, details); + this.name = "CryptoOnrampError"; + this.code = code; + } + }; +})); +//#endregion +//#region ../walletkit/dist/esm/defi/crypto-onramp/CryptoOnrampManager.js +var log$11, CryptoOnrampManager; +var init_CryptoOnrampManager = __esmMin((() => { + init_errors(); + init_Logger(); + init_DefiManager(); + log$11 = globalLogger.createChild("CryptoOnrampManager"); + CryptoOnrampManager = class extends DefiManager { + /** + * Get static metadata for a crypto onramp provider + * @param providerId - Optional provider id to use + */ + getMetadata(providerId) { + const selectedProviderId = providerId || this.defaultProviderId; + log$11.debug("Getting crypto onramp metadata", { providerId: selectedProviderId }); + try { + return this.getProvider(selectedProviderId).getMetadata(); + } catch (error) { + log$11.error("Failed to get crypto onramp metadata", { error }); + throw error; + } + } + /** + * Get a quote for onramping from another crypto asset into a TON asset + * @param params - Quote parameters + * @param providerId - Optional provider name to use + * @returns Promise resolving to a crypto onramp quote + */ + async getQuote(params, providerId) { + const selectedProviderId = providerId || this.defaultProviderId; + log$11.debug("Getting crypto onramp quote", { + sourceChain: params.sourceCurrency.chain, + sourceAddress: params.sourceCurrency.address, + targetAddress: params.targetCurrency.address, + amount: params.amount, + isSourceAmount: params.isSourceAmount, + providerId: selectedProviderId + }); + try { + const quote = await this.getProvider(selectedProviderId).getQuote(params); + log$11.debug("Received crypto onramp quote", { + sourceAmount: quote.sourceAmount, + targetAmount: quote.targetAmount, + rate: quote.rate + }); + return quote; + } catch (error) { + log$11.error("Failed to get crypto onramp quote", { + error, + params + }); + throw error; + } + } + /** + * Create a deposit for a previously obtained quote + * @param params - Deposit parameters including the quote and user TON address + * @param providerId - Optional provider name to use + * @returns Promise resolving to deposit details + */ + async createDeposit(params, providerId) { + const selectedProviderId = providerId || params.quote?.providerId || this.defaultProviderId; + log$11.debug("Creating crypto onramp deposit", { + providerId: selectedProviderId, + recipientAddress: params.quote.recipientAddress + }); + try { + const deposit = await this.getProvider(selectedProviderId).createDeposit(params); + log$11.debug("Created crypto onramp deposit", { + address: deposit.address, + amount: deposit.amount, + sourceChain: deposit.sourceCurrency.chain, + sourceAddress: deposit.sourceCurrency.address + }); + return deposit; + } catch (error) { + log$11.error("Failed to create crypto onramp deposit", { + error, + params + }); + throw error; + } + } + /** + * Get the status of a deposit + * @param params - Deposit status parameters including the deposit ID + * @param providerId - Optional provider name to use + * @returns Promise resolving to the deposit status + */ + async getStatus(params, providerId) { + const selectedProviderId = providerId || this.defaultProviderId; + log$11.debug("Getting crypto onramp deposit status", { + providerId: selectedProviderId, + depositId: params.depositId + }); + try { + const status = await this.getProvider(selectedProviderId).getStatus(params); + log$11.debug("Received crypto onramp deposit status", { status }); + return status; + } catch (error) { + log$11.error("Failed to get crypto onramp deposit status", { + error, + params + }); + throw error; + } + } + /** + * Discover supported source/destination currencies for a provider. + * @param providerId Optional provider name to use + */ + async getSupportedCurrencies(providerId) { + const selectedProviderId = providerId || this.defaultProviderId; + log$11.debug("Discovering crypto onramp supported currencies", { providerId: selectedProviderId }); + try { + return await this.getProvider(selectedProviderId).getSupportedCurrencies(); + } catch (error) { + log$11.error("Failed to discover crypto onramp supported currencies", { error }); + throw error; + } + } + createError(message, code, details) { + return new CryptoOnrampError(message, code, details); + } + }; +})); +//#endregion +//#region ../walletkit/dist/esm/defi/crypto-onramp/CryptoOnrampProvider.js +var CryptoOnrampProvider; +var init_CryptoOnrampProvider = __esmMin((() => { + CryptoOnrampProvider = class { + type = "crypto-onramp"; + }; +})); +//#endregion +//#region ../walletkit/dist/esm/defi/crypto-onramp/caip2.js +var Caip2ByNetwork; +var init_caip2 = __esmMin((() => { + Caip2ByNetwork = { + EthereumMainnet: "eip155:1", + OptimismMainnet: "eip155:10", + BscMainnet: "eip155:56", + PolygonMainnet: "eip155:137", + BaseMainnet: "eip155:8453", + ArbitrumMainnet: "eip155:42161", + AvalancheMainnet: "eip155:43114", + SolanaMainnet: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp", + BitcoinMainnet: "bip122:000000000019d6689c085ae165831e93", + TronMainnet: "tron:mainnet" + }; +})); +//#endregion +//#region ../walletkit/dist/esm/defi/crypto-onramp/index.js +var init_crypto_onramp = __esmMin((() => { + init_errors(); + init_CryptoOnrampManager(); + init_CryptoOnrampProvider(); + init_caip2(); +})); +//#endregion //#region ../walletkit/dist/esm/clients/tonapi/mappers/map-account-state.js function mapAccountState(raw, address) { let status; @@ -37813,7 +38066,7 @@ var init_WalletV5R1Adapter = __esmMin((() => { init_WalletV5R1(); init_WalletV5R1_source(); init_Logger(); - init_errors$4(); + init_errors$5(); init_sign$1(); init_address$1(); init_retry(); @@ -39288,10 +39541,16 @@ var esm_exports = /* @__PURE__ */ __exportAll({ BigIntToBase64: () => BigIntToBase64, BridgeError: () => BridgeError$1, BridgeManager: () => BridgeManager, + Caip2ByNetwork: () => Caip2ByNetwork, CallForSuccess: () => CallForSuccess, ConnectHandler: () => ConnectHandler, CreateTonMnemonic: () => CreateTonMnemonic$1, CreateTonProofMessageBytes: () => CreateTonProofMessageBytes, + CryptoOnrampError: () => CryptoOnrampError, + CryptoOnrampErrorCode: () => CryptoOnrampErrorCode, + CryptoOnrampManager: () => CryptoOnrampManager, + CryptoOnrampProvider: () => CryptoOnrampProvider, + CustomProvidersManager: () => CustomProvidersManager, DEFAULT_DURABLE_EVENTS_CONFIG: () => DEFAULT_DURABLE_EVENTS_CONFIG, DEFAULT_FORWARD_AMOUNT: () => DEFAULT_FORWARD_AMOUNT, DEFAULT_JETTON_GAS_FEE: () => DEFAULT_JETTON_GAS_FEE, @@ -39417,7 +39676,7 @@ var init_esm = __esmMin((() => { init_esm$2(); init_TonWalletKit(); init_types$2(); - init_errors$4(); + init_errors$5(); init_WalletManager(); init_TONConnectStoredSessionManager(); init_BridgeManager(); @@ -39425,9 +39684,10 @@ var init_esm = __esmMin((() => { init_RequestProcessor(); init_Initializer(); init_JettonsManager(); - init_errors$3(); + init_errors$4(); init_swap(); init_staking(); + init_crypto_onramp(); init_gasless(); init_EventEmitter(); init_toncenter$1(); @@ -39477,6 +39737,7 @@ var init_esm = __esmMin((() => { init_toncenter(); init_tonapi(); init_streaming(); + init_providers(); })); //#endregion //#region src/core/moduleLoader.ts @@ -40237,7 +40498,7 @@ async function removeEventListeners() { */ async function mnemonicToKeyPair(args) { if (!MnemonicToKeyPair) throw new Error("MnemonicToKeyPair module not loaded"); - return MnemonicToKeyPair(args.mnemonic, args.mnemonicType ?? "ton"); + return MnemonicToKeyPair(args.mnemonic, args.mnemonicType); } async function sign(args) { if (!DefaultSignature) throw new Error("DefaultSignature module not loaded"); @@ -40308,7 +40569,7 @@ var ProxyWalletAdapter = class { const result = await bridgeRequest("adapterSignTransaction", { adapterId: this.adapterId, input: JSON.stringify(input), - fakeSignature: options?.fakeSignature ?? false + fakeSignature: options?.fakeSignature }); if (!result) throw new Error("adapterSignTransaction: no result from native"); return result; @@ -40320,7 +40581,7 @@ var ProxyWalletAdapter = class { const result = await bridgeRequest("adapterSignData", { adapterId: this.adapterId, input: JSON.stringify(input), - fakeSignature: options?.fakeSignature ?? false + fakeSignature: options?.fakeSignature }); if (!result) throw new Error("adapterSignData: no result from native"); return result; @@ -40329,7 +40590,7 @@ var ProxyWalletAdapter = class { const result = await bridgeRequest("adapterSignTonProof", { adapterId: this.adapterId, input: JSON.stringify(input), - fakeSignature: options?.fakeSignature ?? false + fakeSignature: options?.fakeSignature }); if (!result) throw new Error("adapterSignTonProof: no result from native"); return result; @@ -40377,13 +40638,13 @@ async function getWalletStateInit(args) { return wallet(args.walletId, "getStateInit"); } async function getSignedSendTransaction(args) { - return wallet(args.walletId, "getSignedSendTransaction", args.input, { fakeSignature: args.fakeSignature ?? false }); + return wallet(args.walletId, "getSignedSendTransaction", args.input, { fakeSignature: args.fakeSignature }); } async function getSignedSignData(args) { - return wallet(args.walletId, "getSignedSignData", args.input, { fakeSignature: args.fakeSignature ?? false }); + return wallet(args.walletId, "getSignedSignData", args.input, { fakeSignature: args.fakeSignature }); } async function getSignedTonProof(args) { - return wallet(args.walletId, "getSignedTonProof", args.input, { fakeSignature: args.fakeSignature ?? false }); + return wallet(args.walletId, "getSignedTonProof", args.input, { fakeSignature: args.fakeSignature }); } async function removeWallet(args) { return kit("removeWallet", args.walletId); @@ -40393,7 +40654,7 @@ async function getBalance(args) { } async function createSignerFromMnemonic(args) { if (!Signer) throw new Error("Signer module not loaded"); - const signer = await Signer.fromMnemonic(args.mnemonic, { type: args.mnemonicType ?? "ton" }); + const signer = await Signer.fromMnemonic(args.mnemonic, { type: args.mnemonicType }); return { signerId: retain("signer", signer), publicKey: signer.publicKey @@ -40434,7 +40695,7 @@ async function createV5R1WalletAdapter(args) { const adapter = await WalletV5R1Adapter.create(signer, { client: instance.getApiClient(network), network, - workchain: args.workchain ?? 0, + workchain: args.workchain, walletId: args.walletId, domain: args.domain }); @@ -40452,7 +40713,7 @@ async function createV4R2WalletAdapter(args) { const adapter = await WalletV4R2Adapter.create(signer, { client: instance.getApiClient(network), network, - workchain: args.workchain ?? 0, + workchain: args.workchain, walletId: args.walletId, domain: args.domain }); @@ -40602,17 +40863,19 @@ var createTransferNftTransaction = (args) => walletCall("createTransferNftTransa var createTransferNftRawTransaction = (args) => walletCall("createTransferNftRawTransaction", args); //#endregion //#region src/api/jettons.ts -/** -* Copyright (c) TonTech. -* -* This source code is licensed under the MIT license found in the -* LICENSE file in the root directory of this source tree. -* -*/ var getJettons = (args) => walletCall("getJettons", args); var createTransferJettonTransaction = (args) => walletCall("createTransferJettonTransaction", args); var getJettonBalance = (args) => walletCall("getJettonBalance", args); var getJettonWalletAddress = (args) => walletCall("getJettonWalletAddress", args); +async function getJettonInfo(args) { + return (await getKit()).jettons.getJettonInfo(args.address, args.network); +} +async function getAddressJettons(args) { + return (await getKit()).jettons.getAddressJettons(args.userAddress, args.network, args.offset, args.limit); +} +async function validateJettonAddress(args) { + return { valid: (await getKit()).jettons.validateJettonAddress(args.address) }; +} //#endregion //#region ../walletkit/dist/esm/defi/staking/tonstakers/constants.js init_models(); @@ -40793,7 +41056,7 @@ var StakingCache = class { init_models(); init_Logger(); init_StakingProvider(); -init_errors$1(); +init_errors$2(); init_ApiClientTonApi(); init_units(); var log$3 = globalLogger.createChild("TonStakersStakingProvider"); @@ -45185,7 +45448,7 @@ var isOmnistonQuoteMetadata = (metadata) => { */ init_SwapProvider(); init_models(); -init_errors$2(); +init_errors$3(); init_Logger(); init_utils$2(); init_units(); @@ -45451,7 +45714,7 @@ var isDeDustQuoteMetadata = (metadata) => { */ init_SwapProvider(); init_models(); -init_errors$2(); +init_errors$3(); init_Logger(); init_utils$2(); init_units(); @@ -45784,7 +46047,7 @@ init_models(); init_TonClientError(); init_base64(); init_hex(); -init_errors(); +init_errors$1(); var stripHexPrefix = (value) => { return value.startsWith("0x") ? value.slice(2) : value; }; @@ -45863,7 +46126,7 @@ var mapGaslessConfig = (raw) => ({ }); //#endregion //#region ../walletkit/dist/esm/defi/gasless/tonapi/mappers/map-gasless-error.js -init_errors(); +init_errors$1(); var mapTonApiGaslessError = (error, fallbackCode, fallbackMessage) => { if (error instanceof GaslessError) return error; return new GaslessError(error instanceof Error ? error.message : fallbackMessage, fallbackCode, error); @@ -45911,7 +46174,7 @@ var mapGaslessQuote = (raw, network) => ({ //#region ../walletkit/dist/esm/defi/gasless/tonapi/mappers/map-gasless-send.js init_hex(); init_getNormalizedExtMessageHash(); -init_errors(); +init_errors$1(); /** * Domain → wire: build the JSON body for `POST /v2/gasless/send`. * @@ -45964,7 +46227,7 @@ init_index_min(); init_ApiClientTonApi(); init_Logger(); init_retry(); -init_errors(); +init_errors$1(); init_GaslessProvider(); var log = globalLogger.createChild("TonApiGaslessProvider"); /** @@ -46242,6 +46505,9 @@ var api = { createTransferJettonTransaction, getJettonBalance, getJettonWalletAddress, + getJettonInfo, + getAddressJettons, + validateJettonAddress, emitBrowserPageStarted, emitBrowserPageFinished, emitBrowserError,