Aleksmorshen commited on
Commit
e39e00e
·
verified ·
1 Parent(s): 9288e8d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +62 -28
app.py CHANGED
@@ -156,8 +156,11 @@ TEMPLATE = """
156
  <meta charset="UTF-8">
157
  <meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no, user-scalable=no, viewport-fit=cover">
158
  <title>Morshen Group</title>
 
159
  <script src="https://telegram.org/js/telegram-web-app.js"></script>
160
- <script src="https://unpkg.com/@tonconnect/[email protected]/dist/tonconnect-sdk.min.js"></script>
 
 
161
  <link rel="preconnect" href="https://fonts.googleapis.com">
162
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
163
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
@@ -596,6 +599,7 @@ TEMPLATE = """
596
  }
597
 
598
  async function fetchTonBalance(address) {
 
599
  const rpcUrl = 'https://rpc.toncenter.com/api/v2/jsonRPC';
600
  try {
601
  const response = await fetch(rpcUrl, {
@@ -605,7 +609,7 @@ TEMPLATE = """
605
  },
606
  body: JSON.stringify({
607
  jsonrpc: '2.0',
608
- id: 1,
609
  method: 'getBalance',
610
  params: {
611
  address: address
@@ -616,32 +620,36 @@ TEMPLATE = """
616
  const data = await response.json();
617
  if (data.error) throw new Error(`RPC error: ${data.error.message}`);
618
  const balanceNanoTon = parseInt(data.result);
619
- const balanceTon = balanceNanoTon / 1e9;
620
- return balanceTon.toFixed(4);
621
  } catch (error) {
622
  console.error('Error fetching TON balance:', error);
623
  document.getElementById('ton-error').textContent = `Ошибка получения баланса: ${error.message}`;
624
  document.getElementById('ton-error').style.display = 'block';
625
- return 'N/A';
626
  }
627
  }
628
 
629
 
630
  function initializeWebApp() {
 
631
  if (!tg || !tg.initData) {
632
  console.error("Telegram WebApp script not loaded or initData is missing.");
633
  const greetingElement = document.getElementById('greeting');
634
  if(greetingElement) greetingElement.textContent = 'Не удалось связаться с Telegram.';
635
- document.body.style.visibility = 'visible';
636
  return;
637
  }
638
 
 
639
  tg.ready();
640
  tg.expand();
641
 
 
642
  applyTheme(tg.themeParams);
643
  tg.onEvent('themeChanged', () => applyTheme(tg.themeParams));
644
 
 
645
  fetch('/verify', {
646
  method: 'POST',
647
  headers: {
@@ -665,6 +673,7 @@ TEMPLATE = """
665
  console.error('Error sending initData for verification:', error);
666
  });
667
 
 
668
  const user = tg.initDataUnsafe?.user;
669
  const greetingElement = document.getElementById('greeting');
670
  if (user) {
@@ -674,14 +683,17 @@ TEMPLATE = """
674
  greetingElement.textContent = 'Добро пожаловать!';
675
  }
676
 
 
677
  const contactButtons = document.querySelectorAll('.contact-link');
678
  contactButtons.forEach(button => {
679
  button.addEventListener('click', (e) => {
680
  e.preventDefault();
 
681
  tg.openTelegramLink('https://t.me/morshenkhan');
682
  });
683
  });
684
 
 
685
  const modal = document.getElementById("saveModal");
686
  const saveCardBtn = document.getElementById("save-card-btn");
687
  const closeBtn = document.getElementById("modal-close-btn");
@@ -706,8 +718,10 @@ TEMPLATE = """
706
  });
707
  }
708
 
 
709
  document.body.style.visibility = 'visible';
710
 
 
711
  // --- TON Connect Integration ---
712
  const connectTonBtn = document.getElementById('connect-ton-btn');
713
  const disconnectTonBtn = document.getElementById('disconnect-ton-btn');
@@ -717,39 +731,45 @@ TEMPLATE = """
717
  const tonInfoDiv = document.getElementById('ton-info');
718
  const tonErrorDiv = document.getElementById('ton-error');
719
 
 
720
  if (connectTonBtn && disconnectTonBtn && tonWalletStatus && tonWalletAddress && tonBalance && tonInfoDiv && tonErrorDiv) {
721
- // Ensure TonConnectSDK is available globally
722
  if (!window.TonConnectSDK) {
723
- console.error("TON Connect SDK script not loaded correctly.");
724
  tonErrorDiv.textContent = 'Ошибка: TON Connect SDK не загружен.';
725
  tonErrorDiv.style.display = 'block';
726
- connectTonBtn.disabled = true;
727
- return;
728
  }
729
 
730
  try {
 
731
  tonConnectSDK = new window.TonConnectSDK.TonConnectSDK({
732
  manifestUrl: window.location.origin + '/tonconnect-manifest.json',
733
  actionsConfiguration: {
734
- twaReturnUrl: 'https://t.me/YOUR_BOT_USERNAME/YOUR_MINIAPP_SHORTNAME'
 
 
735
  }
736
  });
737
 
 
738
  tonConnectSDK.onStatusChange(async wallet => {
739
  tonErrorDiv.style.display = 'none'; // Clear previous errors
740
  if (wallet) {
 
741
  tonWalletStatus.textContent = 'Статус: Подключен ✅';
742
  tonWalletAddress.textContent = wallet.account.address;
743
  tonInfoDiv.style.display = 'block';
744
  connectTonBtn.style.display = 'none';
745
  disconnectTonBtn.style.display = 'inline-flex';
746
- tonBalance.textContent = 'Загрузка...';
747
  const balance = await fetchTonBalance(wallet.account.address);
748
  tonBalance.textContent = balance;
749
  if (tg.HapticFeedback) {
750
  tg.HapticFeedback.notificationOccurred('success');
751
  }
752
  } else {
 
753
  tonWalletStatus.textContent = 'Статус: Не подключен';
754
  tonWalletAddress.textContent = '';
755
  tonBalance.textContent = '';
@@ -760,37 +780,41 @@ TEMPLATE = """
760
  tg.HapticFeedback.notificationOccurred('warning');
761
  }
762
  }
763
- // tg.MainButton.hide(); // Hide main button if shown by SDK (optional)
 
764
  });
765
 
 
766
  connectTonBtn.addEventListener('click', () => {
767
  tonErrorDiv.style.display = 'none'; // Clear error on button click
768
- tonConnectSDK.connectWallet();
769
  });
770
 
771
  disconnectTonBtn.addEventListener('click', () => {
772
  tonErrorDiv.style.display = 'none'; // Clear error on button click
773
- tonConnectSDK.disconnect();
774
  });
775
 
 
776
  tonConnectSDK.restoreConnection();
777
 
778
  } catch (e) {
 
779
  console.error("Error initializing TON Connect SDK:", e);
780
  tonErrorDiv.textContent = `Ошибка инициализации TON Connect: ${e.message}`;
781
  tonErrorDiv.style.display = 'block';
782
- connectTonBtn.disabled = true; // Disable button on error
783
  }
784
  } else {
785
- console.error("TON Wallet section elements not found!");
786
  }
787
  // --- End TON Connect Integration ---
788
  }
789
 
790
- // Wait for the window to fully load (including external scripts like TonConnectSDK)
791
  window.addEventListener('load', initializeWebApp);
792
 
793
- // Fallback/timeout if Telegram WebApp script doesn't load or something goes wrong
794
  setTimeout(() => {
795
  if (document.body.style.visibility !== 'visible') {
796
  console.error("WebApp initialization fallback timeout triggered.");
@@ -798,7 +822,7 @@ TEMPLATE = """
798
  if(greetingElement) greetingElement.textContent = 'Ошибка загрузки интерфейса.';
799
  document.body.style.visibility = 'visible';
800
  }
801
- }, 5000); // Increased timeout slightly
802
  </script>
803
  </body>
804
  </html>
@@ -1064,10 +1088,13 @@ def verify_data():
1064
 
1065
  @app.route('/tonconnect-manifest.json')
1066
  def tonconnect_manifest():
 
 
1067
  manifest = {
1068
  "url": request.url_root.rstrip('/') + "/tonconnect-manifest.json",
1069
  "name": "Morshen Group Mini App",
1070
- "iconUrl": request.url_root.rstrip('/') + "/static/morshengroup.png",
 
1071
  "termsOfUseUrl": "https://example.com/terms",
1072
  "privacyPolicyUrl": "https://example.com/privacy"
1073
  }
@@ -1096,16 +1123,23 @@ def admin_trigger_upload():
1096
 
1097
  @app.route('/static/<path:filename>')
1098
  def static_files(filename):
1099
- if filename == 'morshengroup.png':
1100
- try:
1101
- # Serve morshengroup.jpg as png for the manifest icon
1102
- return Response(open('morshengroup.jpg', 'rb').read(), mimetype='image/png')
1103
- except FileNotFoundError:
1104
- return Response("Icon file not found", status=404)
1105
- return Response("File not found", status=404)
 
 
1106
 
1107
 
1108
  if __name__ == '__main__':
 
 
 
 
 
1109
  download_data_from_hf()
1110
  load_visitor_data()
1111
 
 
156
  <meta charset="UTF-8">
157
  <meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no, user-scalable=no, viewport-fit=cover">
158
  <title>Morshen Group</title>
159
+ <!-- Telegram WebApp script MUST be loaded first -->
160
  <script src="https://telegram.org/js/telegram-web-app.js"></script>
161
+ <!-- TON Connect SDK script with defer to avoid blocking -->
162
+ <script src="https://unpkg.com/@tonconnect/[email protected]/dist/tonconnect-sdk.min.js" defer></script>
163
+
164
  <link rel="preconnect" href="https://fonts.googleapis.com">
165
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
166
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
 
599
  }
600
 
601
  async function fetchTonBalance(address) {
602
+ // Using public RPC endpoint provided by TON Center
603
  const rpcUrl = 'https://rpc.toncenter.com/api/v2/jsonRPC';
604
  try {
605
  const response = await fetch(rpcUrl, {
 
609
  },
610
  body: JSON.stringify({
611
  jsonrpc: '2.0',
612
+ id: 1, // Request ID, can be anything
613
  method: 'getBalance',
614
  params: {
615
  address: address
 
620
  const data = await response.json();
621
  if (data.error) throw new Error(`RPC error: ${data.error.message}`);
622
  const balanceNanoTon = parseInt(data.result);
623
+ const balanceTon = balanceNanoTon / 1e9; // Convert NanoTON to TON
624
+ return balanceTon.toFixed(4); // Format to 4 decimal places
625
  } catch (error) {
626
  console.error('Error fetching TON balance:', error);
627
  document.getElementById('ton-error').textContent = `Ошибка получения баланса: ${error.message}`;
628
  document.getElementById('ton-error').style.display = 'block';
629
+ return 'N/A'; // Return N/A on error
630
  }
631
  }
632
 
633
 
634
  function initializeWebApp() {
635
+ // Check if Telegram WebApp is ready
636
  if (!tg || !tg.initData) {
637
  console.error("Telegram WebApp script not loaded or initData is missing.");
638
  const greetingElement = document.getElementById('greeting');
639
  if(greetingElement) greetingElement.textContent = 'Не удалось связаться с Telegram.';
640
+ document.body.style.visibility = 'visible'; // Show body even on error
641
  return;
642
  }
643
 
644
+ // Initialize Telegram WebApp features
645
  tg.ready();
646
  tg.expand();
647
 
648
+ // Apply theme based on Telegram app theme
649
  applyTheme(tg.themeParams);
650
  tg.onEvent('themeChanged', () => applyTheme(tg.themeParams));
651
 
652
+ // Send initData to backend for verification and logging
653
  fetch('/verify', {
654
  method: 'POST',
655
  headers: {
 
673
  console.error('Error sending initData for verification:', error);
674
  });
675
 
676
+ // Display user greeting
677
  const user = tg.initDataUnsafe?.user;
678
  const greetingElement = document.getElementById('greeting');
679
  if (user) {
 
683
  greetingElement.textContent = 'Добро пожаловать!';
684
  }
685
 
686
+ // Setup Contact Links to open Telegram chat
687
  const contactButtons = document.querySelectorAll('.contact-link');
688
  contactButtons.forEach(button => {
689
  button.addEventListener('click', (e) => {
690
  e.preventDefault();
691
+ // Replace 'morshenkhan' with the actual Telegram username
692
  tg.openTelegramLink('https://t.me/morshenkhan');
693
  });
694
  });
695
 
696
+ // Setup Save Card Modal
697
  const modal = document.getElementById("saveModal");
698
  const saveCardBtn = document.getElementById("save-card-btn");
699
  const closeBtn = document.getElementById("modal-close-btn");
 
718
  });
719
  }
720
 
721
+ // Show body after initial setup is complete
722
  document.body.style.visibility = 'visible';
723
 
724
+
725
  // --- TON Connect Integration ---
726
  const connectTonBtn = document.getElementById('connect-ton-btn');
727
  const disconnectTonBtn = document.getElementById('disconnect-ton-btn');
 
731
  const tonInfoDiv = document.getElementById('ton-info');
732
  const tonErrorDiv = document.getElementById('ton-error');
733
 
734
+ // Check if TON Connect elements exist and TON Connect SDK is loaded
735
  if (connectTonBtn && disconnectTonBtn && tonWalletStatus && tonWalletAddress && tonBalance && tonInfoDiv && tonErrorDiv) {
 
736
  if (!window.TonConnectSDK) {
737
+ console.error("TON Connect SDK script not loaded correctly or window.TonConnectSDK is not defined.");
738
  tonErrorDiv.textContent = 'Ошибка: TON Connect SDK не загружен.';
739
  tonErrorDiv.style.display = 'block';
740
+ connectTonBtn.disabled = true; // Disable connect button
741
+ return; // Stop TON Connect initialization
742
  }
743
 
744
  try {
745
+ // Initialize TON Connect SDK
746
  tonConnectSDK = new window.TonConnectSDK.TonConnectSDK({
747
  manifestUrl: window.location.origin + '/tonconnect-manifest.json',
748
  actionsConfiguration: {
749
+ // !!! IMPORTANT: Replace with your actual bot username and Mini App shortname
750
+ // Example: 'https://t.me/MyAwesomeBot/MyMiniApp'
751
+ twaReturnUrl: 'https://t.me/YOUR_BOT_USERNAME/YOUR_MINIAPP_SHORTNAME'
752
  }
753
  });
754
 
755
+ // Subscribe to wallet status changes
756
  tonConnectSDK.onStatusChange(async wallet => {
757
  tonErrorDiv.style.display = 'none'; // Clear previous errors
758
  if (wallet) {
759
+ // Wallet is connected
760
  tonWalletStatus.textContent = 'Статус: Подключен ✅';
761
  tonWalletAddress.textContent = wallet.account.address;
762
  tonInfoDiv.style.display = 'block';
763
  connectTonBtn.style.display = 'none';
764
  disconnectTonBtn.style.display = 'inline-flex';
765
+ tonBalance.textContent = 'Загрузка...'; // Show loading state for balance
766
  const balance = await fetchTonBalance(wallet.account.address);
767
  tonBalance.textContent = balance;
768
  if (tg.HapticFeedback) {
769
  tg.HapticFeedback.notificationOccurred('success');
770
  }
771
  } else {
772
+ // Wallet is disconnected
773
  tonWalletStatus.textContent = 'Статус: Не подключен';
774
  tonWalletAddress.textContent = '';
775
  tonBalance.textContent = '';
 
780
  tg.HapticFeedback.notificationOccurred('warning');
781
  }
782
  }
783
+ // Hide Telegram's MainButton if it might be interfering
784
+ // tg.MainButton.hide();
785
  });
786
 
787
+ // Add event listeners for connect/disconnect buttons
788
  connectTonBtn.addEventListener('click', () => {
789
  tonErrorDiv.style.display = 'none'; // Clear error on button click
790
+ tonConnectSDK.connectWallet(); // Trigger wallet connection flow
791
  });
792
 
793
  disconnectTonBtn.addEventListener('click', () => {
794
  tonErrorDiv.style.display = 'none'; // Clear error on button click
795
+ tonConnectSDK.disconnect(); // Trigger wallet disconnection
796
  });
797
 
798
+ // Attempt to restore previous connection on startup
799
  tonConnectSDK.restoreConnection();
800
 
801
  } catch (e) {
802
+ // Catch errors specifically during SDK instantiation
803
  console.error("Error initializing TON Connect SDK:", e);
804
  tonErrorDiv.textContent = `Ошибка инициализации TON Connect: ${e.message}`;
805
  tonErrorDiv.style.display = 'block';
806
+ connectTonBtn.disabled = true; // Disable button on initialization error
807
  }
808
  } else {
809
+ console.error("TON Wallet section HTML elements not found!");
810
  }
811
  // --- End TON Connect Integration ---
812
  }
813
 
814
+ // Wait for the window to fully load all resources (including deferred scripts)
815
  window.addEventListener('load', initializeWebApp);
816
 
817
+ // Fallback timeout in case something prevents 'load' or Telegram script
818
  setTimeout(() => {
819
  if (document.body.style.visibility !== 'visible') {
820
  console.error("WebApp initialization fallback timeout triggered.");
 
822
  if(greetingElement) greetingElement.textContent = 'Ошибка загрузки интерфейса.';
823
  document.body.style.visibility = 'visible';
824
  }
825
+ }, 5000); // Increased timeout slightly to 5 seconds
826
  </script>
827
  </body>
828
  </html>
 
1088
 
1089
  @app.route('/tonconnect-manifest.json')
1090
  def tonconnect_manifest():
1091
+ # You need to serve your icon file, e.g., place morshengroup.png in a 'static' folder
1092
+ icon_url = request.url_root.rstrip('/') + "/static/morshengroup.png"
1093
  manifest = {
1094
  "url": request.url_root.rstrip('/') + "/tonconnect-manifest.json",
1095
  "name": "Morshen Group Mini App",
1096
+ "iconUrl": icon_url,
1097
+ # !!! IMPORTANT: Replace with actual URLs for your terms of use and privacy policy
1098
  "termsOfUseUrl": "https://example.com/terms",
1099
  "privacyPolicyUrl": "https://example.com/privacy"
1100
  }
 
1123
 
1124
  @app.route('/static/<path:filename>')
1125
  def static_files(filename):
1126
+ # Assuming you place your icon file (e.g., morshengroup.png) in a 'static' folder
1127
+ # relative to your app.py file.
1128
+ # For the manifest, a PNG is usually required, but the original code used JPG.
1129
+ # Let's assume you have a morshengroup.png in a static folder.
1130
+ static_dir = os.path.join(app.root_path, 'static')
1131
+ return send_from_directory(static_dir, filename)
1132
+
1133
+ # Import send_from_directory for the static route
1134
+ from flask import send_from_directory
1135
 
1136
 
1137
  if __name__ == '__main__':
1138
+ # Ensure the static directory exists if you're using it for icons
1139
+ if not os.path.exists('static'):
1140
+ os.makedirs('static')
1141
+ # You should place your morshengroup.png file inside the new 'static' folder
1142
+
1143
  download_data_from_hf()
1144
  load_visitor_data()
1145