admin08077 commited on
Commit
8791d04
Β·
verified Β·
1 Parent(s): 2d3d4bd

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +334 -427
app.py CHANGED
@@ -12,15 +12,12 @@ import time
12
  from datetime import datetime, timedelta
13
 
14
  import streamlit as st
15
- import streamlit_authenticator as stauth
16
  import requests
17
 
18
  from sqlalchemy import create_engine, Column, Integer, String, Float, Boolean, DateTime, ForeignKey
19
  from sqlalchemy.ext.declarative import declarative_base
20
  from sqlalchemy.orm import sessionmaker, relationship
21
 
22
- from werkzeug.security import generate_password_hash, check_password_hash
23
-
24
  import openai
25
 
26
  # ========================
@@ -100,23 +97,10 @@ else:
100
 
101
  Base = declarative_base()
102
 
103
- class User(Base):
104
- __tablename__ = 'users'
105
-
106
- id = Column(Integer, primary_key=True)
107
- username = Column(String(80), unique=True, nullable=False)
108
- password = Column(String(200), nullable=False)
109
- balance = Column(Float, default=0.0)
110
- staked = Column(Float, default=0.0)
111
- blockchain_address = Column(String(42), unique=True, nullable=False) # Ethereum address
112
- tokens = relationship('Token', backref='owner', lazy=True)
113
- transactions = relationship('Transaction', backref='user', lazy=True)
114
-
115
  class Token(Base):
116
  __tablename__ = 'tokens'
117
 
118
  id = Column(String(36), primary_key=True) # UUID
119
- owner_id = Column(Integer, ForeignKey('users.id'), nullable=False)
120
  value = Column(Float, nullable=False)
121
  text = Column(String(256), nullable=False) # Text to store on blockchain
122
  recipient_address = Column(String(42), nullable=False) # Address receiving tokens
@@ -128,7 +112,6 @@ class Transaction(Base):
128
  __tablename__ = 'transactions'
129
 
130
  id = Column(Integer, primary_key=True)
131
- user_id = Column(Integer, ForeignKey('users.id'), nullable=False)
132
  token_id = Column(String(36), ForeignKey('tokens.id'), nullable=True)
133
  action = Column(String(50), nullable=False)
134
  value = Column(Float, nullable=True)
@@ -139,7 +122,6 @@ class Stake(Base):
139
  __tablename__ = 'stakes'
140
 
141
  id = Column(Integer, primary_key=True)
142
- user_id = Column(Integer, ForeignKey('users.id'), nullable=False)
143
  amount = Column(Float, nullable=False)
144
  timestamp = Column(DateTime, default=datetime.utcnow)
145
 
@@ -254,440 +236,365 @@ def process_ai(input_text):
254
  return f"❌ Error processing AI output: {str(e)}"
255
 
256
  # ========================
257
- # Streamlit Authentication Setup
258
  # ========================
259
 
260
- # Fetch users from the database
261
- users = session.query(User).all()
262
-
263
- # Build the credentials dictionary
264
- credentials = {
265
- "usernames": {
266
- user.username: {
267
- "name": user.username, # You can customize this if you have a separate name field
268
- "password": user.password # This should be the hashed password
269
- }
270
- for user in users
271
- }
272
- }
273
 
274
- # If no users are present, ensure 'usernames' is an empty dictionary
275
- if not users:
276
- credentials = {"usernames": {}}
277
 
278
- # Debugging: Display credentials structure (Remove or comment out in production)
279
- # st.write("Credentials Structure:", credentials)
280
 
281
- # Initialize Authenticator with keyword arguments
282
- authenticator = stauth.Authenticate(
283
- credentials,
284
- 'citibank_demo_business_inc_ai_crypto', # cookie_name
285
- 'abcdef', # key
286
- cookie_expiry_days=1 # cookie_expiry_days
287
- )
288
 
289
- name, authentication_status, username = authenticator.login('Login', 'main')
290
 
291
- if authentication_status:
292
- st.sidebar.success(f"Welcome *{name}*")
293
- authenticator.logout('Logout', 'sidebar')
294
-
295
- # ========================
296
- # User Dashboard with Tabs
297
- # ========================
298
-
299
- st.header("🌟 Dashboard 🌟")
300
-
301
- # Fetch user data
302
- user = session.query(User).filter_by(username=username).first()
303
-
304
- # Display Balance
305
- st.subheader("πŸ’° Your Balance")
306
- col1, col2 = st.columns(2)
307
- col1.metric("Tokens", f"{user.balance:.2f}")
308
- col2.metric("Staked Tokens", f"{user.staked:.2f}")
309
-
310
- # Create Tabs based on OpenAI configuration
311
- tabs_titles = ["Token Management", "Staking", "Trading", "Transaction History"]
312
- if openai_enabled:
313
- tabs_titles.insert(0, "AI Query")
314
- tabs_titles.append("Chat")
315
-
316
- tabs_titles.append("About Me")
317
-
318
- tabs = st.tabs(tabs_titles)
319
-
320
- # ========================
321
- # AI Query Submission (Optional)
322
- # ========================
323
- if openai_enabled:
324
- with tabs[0]:
325
- st.subheader("πŸ€– Submit AI Query")
326
- with st.form("ai_query_form"):
327
- input_text = st.text_area("Enter your query here...", height=100)
328
- submit_button = st.form_submit_button(label='Submit')
329
-
330
- if submit_button:
331
- if input_text.strip() == "":
332
- st.error("❌ Input text cannot be empty.")
333
  else:
334
- with st.spinner("πŸ” Processing your AI query..."):
335
- ai_output = process_ai(input_text)
336
- if ai_output.startswith("❌"):
337
- st.error(ai_output)
338
- else:
339
- st.success("βœ… AI Query Processed!")
340
- st.write(f"**AI Output:** {ai_output}")
341
- # Grade AI Output
342
- token_amount = calculate_token_grade(ai_output)
343
- if token_amount > 0:
344
- # Mint Token via API
345
- token_address = user.blockchain_address
346
- token_contract = CONTRACT_ADDRESS # Using hardcoded contract address
347
- balance = "100" # Adjust as needed
348
- mint_success, mint_response = mint_tokens_via_api(token_address, token_contract, balance)
349
- if mint_success:
350
- st.success("βœ… Token minted successfully via API!")
351
- st.write(f"**API Response:** {json.dumps(mint_response, indent=2)}")
352
- # Update local database
353
- token = Token(
354
- id=str(uuid.uuid4()),
355
- owner_id=user.id,
356
- value=token_amount,
357
- text=input_text, # Store the input text
358
- recipient_address=token_address,
359
- verified=False,
360
- verification_hash=hashlib.sha256(ai_output.encode()).hexdigest()
361
- )
362
- session.add(token)
363
- session.commit()
364
- # Update user's balance
365
- user.balance += token_amount
366
- session.commit()
367
- # Record transaction
368
- transaction = Transaction(
369
- user_id=user.id,
370
- token_id=token.id,
371
- action='minted',
372
- value=token_amount,
373
- hash=token.verification_hash
374
- )
375
- session.add(transaction)
376
- session.commit()
377
- st.write(f"**Token ID:** {token.id}")
378
- st.write(f"**Tokens Earned:** {token_amount:.2f}")
379
- st.write(f"**Stored Text:** {token.text}")
380
- else:
381
- st.error(f"❌ Token minting failed: {mint_response}")
382
  else:
383
- st.error("❌ Token amount determined as zero. Please try again.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
384
 
385
- # ========================
386
- # Token Management
387
- # ========================
388
- token_tab_index = 0
389
- if openai_enabled:
390
- token_tab_index = 1
391
- with tabs[token_tab_index]:
392
- st.subheader("πŸͺ™ Your Tokens")
393
- tokens = session.query(Token).filter_by(owner_id=user.id).all()
394
- if tokens:
395
- token_data = []
396
- for token in tokens:
397
- token_info = {
398
- "Token ID": token.id,
399
- "Value": f"{token.value:.2f}",
400
- "Recipient Address": token.recipient_address,
401
- "Text": token.text,
402
- "Verified": "Yes" if token.verified else "No",
403
- "Verification Hash": token.verification_hash or "N/A",
404
- "Created At": token.created_at.strftime('%Y-%m-%d %H:%M:%S')
405
- }
406
- token_data.append(token_info)
407
- st.table(token_data)
408
  else:
409
- st.write("πŸ“­ You have no tokens yet.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
410
 
411
- # ========================
412
- # Staking
413
- # ========================
414
- staking_tab_index = token_tab_index + 1
415
- with tabs[staking_tab_index]:
416
- st.subheader("πŸ“ˆ Stake Tokens")
417
- with st.form("stake_form"):
418
- stake_amount = st.number_input("Amount to Stake", min_value=0.0, step=1.0)
419
- stake_button = st.form_submit_button(label='Stake Tokens')
420
-
421
- if stake_button:
422
- if stake_amount <= 0:
423
- st.error("❌ Stake amount must be greater than zero.")
424
- elif user.balance < stake_amount:
425
- st.error("❌ Insufficient balance.")
426
  else:
427
- user.balance -= stake_amount
428
- user.staked += stake_amount
429
- stake = Stake(
430
- user_id=user.id,
431
- amount=stake_amount
432
- )
433
- session.add(stake)
434
  session.commit()
 
 
435
  # Record transaction
436
  transaction = Transaction(
437
- user_id=user.id,
438
- action='stake',
439
- value=stake_amount
440
  )
441
  session.add(transaction)
442
  session.commit()
443
- st.success("βœ… Staked successfully.")
444
- st.write(f"**New Balance:** {user.balance:.2f}")
445
- st.write(f"**Total Staked:** {user.staked:.2f}")
446
-
447
- # ========================
448
- # Trading
449
- # ========================
450
- trading_tab_index = staking_tab_index + 1
451
- with tabs[trading_tab_index]:
452
- st.subheader("πŸ”„ Trade Tokens")
453
- with st.form("trade_form"):
454
- seller_username = st.text_input("Seller Username")
455
- token_id = st.text_input("Token ID")
456
- trade_button = st.form_submit_button(label='Trade Token')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
457
 
458
- if trade_button:
459
- if seller_username.strip() == "" or token_id.strip() == "":
460
- st.error("❌ Seller username and Token ID are required.")
461
  else:
462
- seller = session.query(User).filter_by(username=seller_username).first()
463
- if not seller:
464
- st.error("❌ Seller not found.")
465
- else:
466
- token = session.query(Token).filter_by(id=token_id, owner_id=seller.id).first()
467
- if not token:
468
- st.error("❌ Token not found or unauthorized.")
469
- else:
470
- # Transfer ownership
471
- token.owner_id = user.id
472
- session.commit()
473
- # Update balances
474
- seller.balance -= token.value
475
- user.balance += token.value
476
- session.commit()
477
- # Record transaction
478
- transaction = Transaction(
479
- user_id=user.id,
480
- token_id=token.id,
481
- action='trade',
482
- value=token.value
483
- )
484
- session.add(transaction)
485
- session.commit()
486
- st.success("βœ… Trade successful.")
487
- st.write(f"**New Balance:** {user.balance:.2f}")
488
- st.write(f"**Token Value:** {token.value:.2f}")
489
-
490
- # ========================
491
- # Transaction History
492
- # ========================
493
- transaction_history_tab_index = trading_tab_index + 1
494
- with tabs[transaction_history_tab_index]:
495
- st.subheader("πŸ“œ Transaction History")
496
- transactions = session.query(Transaction).filter_by(user_id=user.id).order_by(Transaction.timestamp.desc()).all()
497
- if transactions:
498
- transaction_data = []
499
- for tx in transactions:
500
- tx_info = {
501
- "Action": tx.action,
502
- "Value": f"{tx.value:.2f}" if tx.value else "N/A",
503
- "Hash": tx.hash or "N/A",
504
- "Timestamp": tx.timestamp.strftime('%Y-%m-%d %H:%M:%S')
505
- }
506
- transaction_data.append(tx_info)
507
- st.table(transaction_data)
508
- else:
509
- st.write("πŸ“­ No transactions found.")
510
-
511
- # ========================
512
- # Chat Interface (Optional)
513
- # ========================
514
- if openai_enabled:
515
- chat_tab_index = transaction_history_tab_index + 1
516
- with tabs[chat_tab_index]:
517
- st.subheader("πŸ’¬ Chat with CITIBANK DEMO BUSINESS INC AI")
518
- if 'chat_history' not in st.session_state:
519
- st.session_state['chat_history'] = []
520
-
521
- def get_ai_response(user_input):
522
- """
523
- Generate AI response using OpenAI.
524
- """
525
- try:
526
- response = openai.Completion.create(
527
- engine="text-davinci-003", # Use 'gpt-4' if available
528
- prompt=user_input,
529
- max_tokens=150,
530
- temperature=0.7,
531
- n=1,
532
- stop=None
533
- )
534
- ai_output = response.choices[0].text.strip()
535
- return ai_output
536
- except Exception as e:
537
- return f"❌ Error processing AI output: {str(e)}"
538
-
539
- user_input = st.text_input("You:", key="chat_input")
540
-
541
- if st.button("Send"):
542
- if user_input.strip() == "":
543
- st.warning("❌ Please enter a message.")
544
- else:
545
- st.session_state.chat_history.append(("You", user_input))
546
- ai_response = get_ai_response(user_input)
547
- st.session_state.chat_history.append(("CITIBANK DEMO BUSINESS INC AI", ai_response))
548
-
549
- for sender, message in st.session_state.chat_history:
550
- if sender == "You":
551
- st.markdown(f"**You:** {message}")
552
- else:
553
- st.markdown(f"**CITIBANK DEMO BUSINESS INC AI:** {message}")
554
-
555
- # ========================
556
- # About Me Tab
557
- # ========================
558
- about_me_tab_index = transaction_history_tab_index + (2 if openai_enabled else 1)
559
- with tabs[about_me_tab_index]:
560
- st.subheader("ℹ️ About CITIBANK DEMO BUSINESS INC AI Crypto Ecosystem")
561
- st.markdown("""
562
- ### 🌟 Overview
563
- The **CITIBANK DEMO BUSINESS INC AI Crypto Ecosystem** is a cutting-edge platform that seamlessly integrates **Artificial Intelligence** with **Blockchain Technology** to create a **self-sustaining** and **monetizable** ecosystem. This system empowers users to interact with AI services, earn and manage cryptocurrency tokens, and participate in a transparent and decentralized economy.
564
-
565
- ### πŸš€ Features
566
- - **User Authentication:** Secure registration and login system with hashed passwords.
567
- - **AI Query Submission:** Submit queries to the AI and receive insightful responses. *(Requires OpenAI API Key)*
568
- - **AI Grading Mechanism:** AI evaluates its own outputs based on a predefined rubric to determine token rewards. *(Requires OpenAI API Key)*
569
- - **Token Minting:** Earn tokens based on the AI-generated content's quality.
570
- - **Token Management:** View and manage your tokens, including verification status.
571
- - **Staking:** Stake your tokens to earn rewards and support the ecosystem.
572
- - **Trading:** Trade tokens with other users within the ecosystem.
573
- - **Transaction History:** Transparent logs of all your activities.
574
- - **Chat Interface:** Interact with the AI through a dedicated chat box. *(Requires OpenAI API Key)*
575
- - **About Section:** Detailed information about the ecosystem and its functionalities.
576
-
577
- ### πŸ› οΈ Technology Stack
578
- - **Backend:** Streamlit, SQLAlchemy
579
- - **Frontend:** Streamlit Interface with Tabs
580
- - **Blockchain:** Solidity, Ethereum (or any EVM-compatible blockchain)
581
- - **Database:** SQLite (for demonstration) or PostgreSQL (for production)
582
- - **AI Services:** OpenAI GPT-4 API *(Optional)*
583
-
584
- ### πŸ”’ Security
585
- - **Password Hashing:** User passwords are securely hashed using industry-standard algorithms.
586
- - **Input Validation:** Comprehensive validation to prevent vulnerabilities like SQL injection and XSS attacks.
587
- - **Secure Data Handling:** Sensitive information such as API keys are managed securely within the application interface.
588
-
589
- ### 🌐 Deployment
590
- The application is optimized for deployment on **Hugging Face Spaces**, ensuring accessibility and scalability. Users can configure all necessary settings directly through the Streamlit interface, eliminating the need for external environment variables.
591
-
592
- ### πŸ“ˆ Scalability
593
- - **Modular Design:** Each component is isolated, allowing for independent scaling and maintenance.
594
- - **Efficient Database Management:** Utilizing SQLAlchemy for optimized interactions.
595
- - **Asynchronous Processing:** Background threads handle long-running tasks without blocking the main application.
596
- - **Optimized API Interactions:** Efficient handling of API requests to manage high volumes of token minting.
597
-
598
- ---
599
- *Embark on this transformative journey with **CITIBANK DEMO BUSINESS INC** to redefine the synergy between AI and blockchain, creating an unparalleled decentralized economy.*
600
- """)
601
-
602
- # ========================
603
- # Mint Token Functionality
604
- # ========================
605
-
606
- st.sidebar.header("πŸͺ™ Mint Token")
607
- with st.sidebar.form("mint_token_form"):
608
- mint_address = st.text_input("Recipient Address (0x...)", value="")
609
- mint_text = st.text_input("Mint Text", value="")
610
- mint_button = st.form_submit_button(label='Mint Token')
611
-
612
- if mint_button:
613
- if not mint_address or not mint_text:
614
- st.sidebar.error("❌ Both Address and Text are required.")
615
- elif not (mint_address.startswith("0x") and len(mint_address) == 42):
616
- st.sidebar.error("❌ Invalid Blockchain Address format.")
617
- else:
618
- with st.sidebar.spinner("πŸ” Minting tokens and storing text..."):
619
- # Mint tokens via external API
620
- token_contract = CONTRACT_ADDRESS # Using hardcoded contract address
621
- balance = "100" # Adjust as needed or make it dynamic
622
- mint_success, mint_response = mint_tokens_via_api(mint_address, token_contract, balance)
623
-
624
- if mint_success:
625
- st.sidebar.success("βœ… Token minted successfully via API!")
626
- st.sidebar.write(f"**API Response:** {json.dumps(mint_response, indent=2)}")
627
-
628
- # Update local database
629
- token = Token(
630
- id=str(uuid.uuid4()),
631
- owner_id=user.id,
632
- value=100.0, # Assuming balance is 100 tokens
633
- text=mint_text, # Store the input text
634
- recipient_address=mint_address,
635
- verified=False,
636
- verification_hash=hashlib.sha256(mint_text.encode()).hexdigest()
637
- )
638
- session.add(token)
639
- session.commit()
640
-
641
- # Update user's balance
642
- user.balance += token.value
643
- session.commit()
644
-
645
- # Record transaction
646
- transaction = Transaction(
647
- user_id=user.id,
648
- token_id=token.id,
649
- action='minted',
650
- value=token.value,
651
- hash=token.verification_hash
652
- )
653
- session.add(transaction)
654
- session.commit()
655
-
656
- st.sidebar.write(f"**Token ID:** {token.id}")
657
- st.sidebar.write(f"**Tokens Earned:** {token.value:.2f}")
658
- st.sidebar.write(f"**Stored Text:** {token.text}")
659
- else:
660
- st.sidebar.error(f"❌ Token minting failed: {mint_response}")
661
-
662
- elif authentication_status == False:
663
- st.error('❌ Username/password is incorrect')
664
 
665
- elif authentication_status == None:
666
- st.warning('⚠️ Please enter your username and password')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
667
 
668
  # ========================
669
- # User Registration
670
  # ========================
671
 
672
- st.sidebar.subheader("πŸ“’ Register New User")
673
- with st.sidebar.form("register_form"):
674
- new_username = st.text_input("New Username")
675
- new_password = st.text_input("New Password", type="password")
676
- blockchain_address = st.text_input("Blockchain Address (0x...)")
677
- register_button = st.form_submit_button(label='Register')
678
-
679
- if register_button:
680
- if not new_username or not new_password or not blockchain_address:
681
- st.sidebar.error("❌ All fields are required.")
682
- elif not (blockchain_address.startswith("0x") and len(blockchain_address) == 42):
683
  st.sidebar.error("❌ Invalid Blockchain Address format.")
684
- elif session.query(User).filter_by(username=new_username).first():
685
- st.sidebar.error("❌ Username already exists.")
686
- elif session.query(User).filter_by(blockchain_address=blockchain_address).first():
687
- st.sidebar.error("❌ Blockchain address already in use.")
688
  else:
689
- hashed_password = generate_password_hash(new_password)
690
- new_user = User(username=new_username, password=hashed_password, blockchain_address=blockchain_address)
691
- session.add(new_user)
692
- session.commit()
693
- st.sidebar.success("βœ… User registered successfully!")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  from datetime import datetime, timedelta
13
 
14
  import streamlit as st
 
15
  import requests
16
 
17
  from sqlalchemy import create_engine, Column, Integer, String, Float, Boolean, DateTime, ForeignKey
18
  from sqlalchemy.ext.declarative import declarative_base
19
  from sqlalchemy.orm import sessionmaker, relationship
20
 
 
 
21
  import openai
22
 
23
  # ========================
 
97
 
98
  Base = declarative_base()
99
 
 
 
 
 
 
 
 
 
 
 
 
 
100
  class Token(Base):
101
  __tablename__ = 'tokens'
102
 
103
  id = Column(String(36), primary_key=True) # UUID
 
104
  value = Column(Float, nullable=False)
105
  text = Column(String(256), nullable=False) # Text to store on blockchain
106
  recipient_address = Column(String(42), nullable=False) # Address receiving tokens
 
112
  __tablename__ = 'transactions'
113
 
114
  id = Column(Integer, primary_key=True)
 
115
  token_id = Column(String(36), ForeignKey('tokens.id'), nullable=True)
116
  action = Column(String(50), nullable=False)
117
  value = Column(Float, nullable=True)
 
122
  __tablename__ = 'stakes'
123
 
124
  id = Column(Integer, primary_key=True)
 
125
  amount = Column(Float, nullable=False)
126
  timestamp = Column(DateTime, default=datetime.utcnow)
127
 
 
236
  return f"❌ Error processing AI output: {str(e)}"
237
 
238
  # ========================
239
+ # Initialize Application State
240
  # ========================
241
 
242
+ # For the purpose of this version without user authentication,
243
+ # we'll manage a single global balance and staked tokens.
244
+ # In a multi-user scenario, this should be adjusted accordingly.
 
 
 
 
 
 
 
 
 
 
245
 
246
+ if 'balance' not in st.session_state:
247
+ st.session_state.balance = 0.0
 
248
 
249
+ if 'staked' not in st.session_state:
250
+ st.session_state.staked = 0.0
251
 
252
+ # ========================
253
+ # User Dashboard with Tabs
254
+ # ========================
 
 
 
 
255
 
256
+ st.header("🌟 Dashboard 🌟")
257
 
258
+ # Display Balance
259
+ st.subheader("πŸ’° Balance")
260
+ col1, col2 = st.columns(2)
261
+ col1.metric("Tokens", f"{st.session_state.balance:.2f}")
262
+ col2.metric("Staked Tokens", f"{st.session_state.staked:.2f}")
263
+
264
+ # Create Tabs based on OpenAI configuration
265
+ tabs_titles = ["Token Management", "Staking", "Trading", "Transaction History"]
266
+ if openai_enabled:
267
+ tabs_titles.insert(0, "AI Query")
268
+ tabs_titles.append("Chat")
269
+
270
+ tabs_titles.append("About")
271
+
272
+ tabs = st.tabs(tabs_titles)
273
+
274
+ # ========================
275
+ # AI Query Submission (Optional)
276
+ # ========================
277
+ if openai_enabled:
278
+ with tabs[0]:
279
+ st.subheader("πŸ€– Submit AI Query")
280
+ with st.form("ai_query_form"):
281
+ input_text = st.text_area("Enter your query here...", height=100)
282
+ submit_button = st.form_submit_button(label='Submit')
283
+
284
+ if submit_button:
285
+ if input_text.strip() == "":
286
+ st.error("❌ Input text cannot be empty.")
287
+ else:
288
+ with st.spinner("πŸ” Processing your AI query..."):
289
+ ai_output = process_ai(input_text)
290
+ if ai_output.startswith("❌"):
291
+ st.error(ai_output)
 
 
 
 
 
 
 
 
292
  else:
293
+ st.success("βœ… AI Query Processed!")
294
+ st.write(f"**AI Output:** {ai_output}")
295
+ # Grade AI Output
296
+ token_amount = calculate_token_grade(ai_output)
297
+ if token_amount > 0:
298
+ # Mint Token via API
299
+ token_address = "0xYourDefaultAddressHere" # Replace with a default or configurable address
300
+ token_contract = CONTRACT_ADDRESS # Using hardcoded contract address
301
+ balance = "100" # Adjust as needed
302
+ mint_success, mint_response = mint_tokens_via_api(token_address, token_contract, balance)
303
+ if mint_success:
304
+ st.success("βœ… Token minted successfully via API!")
305
+ st.write(f"**API Response:** {json.dumps(mint_response, indent=2)}")
306
+ # Update local database
307
+ token = Token(
308
+ id=str(uuid.uuid4()),
309
+ value=token_amount,
310
+ text=input_text, # Store the input text
311
+ recipient_address=token_address,
312
+ verified=False,
313
+ verification_hash=hashlib.sha256(ai_output.encode()).hexdigest()
314
+ )
315
+ session.add(token)
316
+ session.commit()
317
+ # Update session state balance
318
+ st.session_state.balance += token_amount
319
+ # Record transaction
320
+ transaction = Transaction(
321
+ token_id=token.id,
322
+ action='minted',
323
+ value=token_amount,
324
+ hash=token.verification_hash
325
+ )
326
+ session.add(transaction)
327
+ session.commit()
328
+ st.write(f"**Token ID:** {token.id}")
329
+ st.write(f"**Tokens Earned:** {token_amount:.2f}")
330
+ st.write(f"**Stored Text:** {token.text}")
 
 
 
 
 
 
 
 
 
 
331
  else:
332
+ st.error(f"❌ Token minting failed: {mint_response}")
333
+ else:
334
+ st.error("❌ Token amount determined as zero. Please try again.")
335
+
336
+ # ========================
337
+ # Token Management
338
+ # ========================
339
+ token_tab_index = 0
340
+ if openai_enabled:
341
+ token_tab_index = 1
342
+ with tabs[token_tab_index]:
343
+ st.subheader("πŸͺ™ Tokens")
344
+ tokens = session.query(Token).all()
345
+ if tokens:
346
+ token_data = []
347
+ for token in tokens:
348
+ token_info = {
349
+ "Token ID": token.id,
350
+ "Value": f"{token.value:.2f}",
351
+ "Recipient Address": token.recipient_address,
352
+ "Text": token.text,
353
+ "Verified": "Yes" if token.verified else "No",
354
+ "Verification Hash": token.verification_hash or "N/A",
355
+ "Created At": token.created_at.strftime('%Y-%m-%d %H:%M:%S')
356
+ }
357
+ token_data.append(token_info)
358
+ st.table(token_data)
359
+ else:
360
+ st.write("πŸ“­ No tokens found.")
361
+
362
+ # ========================
363
+ # Staking
364
+ # ========================
365
+ staking_tab_index = token_tab_index + 1
366
+ with tabs[staking_tab_index]:
367
+ st.subheader("πŸ“ˆ Stake Tokens")
368
+ with st.form("stake_form"):
369
+ stake_amount = st.number_input("Amount to Stake", min_value=0.0, step=1.0)
370
+ stake_button = st.form_submit_button(label='Stake Tokens')
371
 
372
+ if stake_button:
373
+ if stake_amount <= 0:
374
+ st.error("❌ Stake amount must be greater than zero.")
375
+ elif st.session_state.balance < stake_amount:
376
+ st.error("❌ Insufficient balance.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
377
  else:
378
+ st.session_state.balance -= stake_amount
379
+ st.session_state.staked += stake_amount
380
+ stake = Stake(
381
+ amount=stake_amount
382
+ )
383
+ session.add(stake)
384
+ session.commit()
385
+ # Record transaction
386
+ transaction = Transaction(
387
+ action='stake',
388
+ value=stake_amount
389
+ )
390
+ session.add(transaction)
391
+ session.commit()
392
+ st.success("βœ… Staked successfully.")
393
+ st.write(f"**New Balance:** {st.session_state.balance:.2f}")
394
+ st.write(f"**Total Staked:** {st.session_state.staked:.2f}")
395
+
396
+ # ========================
397
+ # Trading
398
+ # ========================
399
+ trading_tab_index = staking_tab_index + 1
400
+ with tabs[trading_tab_index]:
401
+ st.subheader("πŸ”„ Trade Tokens")
402
+ with st.form("trade_form"):
403
+ seller_address = st.text_input("Seller Blockchain Address (0x...)")
404
+ token_id = st.text_input("Token ID")
405
+ trade_button = st.form_submit_button(label='Trade Token')
406
 
407
+ if trade_button:
408
+ if seller_address.strip() == "" or token_id.strip() == "":
409
+ st.error("❌ Seller address and Token ID are required.")
410
+ elif not (seller_address.startswith("0x") and len(seller_address) == 42):
411
+ st.error("❌ Invalid Blockchain Address format.")
412
+ else:
413
+ token = session.query(Token).filter_by(id=token_id, recipient_address=seller_address).first()
414
+ if not token:
415
+ st.error("❌ Token not found or unauthorized.")
 
 
 
 
 
 
416
  else:
417
+ # Transfer ownership by updating recipient address
418
+ token.recipient_address = "0xYourDefaultAddressHere" # Replace with your address or handle accordingly
 
 
 
 
 
419
  session.commit()
420
+ # Update session state balance
421
+ st.session_state.balance += token.value
422
  # Record transaction
423
  transaction = Transaction(
424
+ token_id=token.id,
425
+ action='trade',
426
+ value=token.value
427
  )
428
  session.add(transaction)
429
  session.commit()
430
+ st.success("βœ… Trade successful.")
431
+ st.write(f"**New Balance:** {st.session_state.balance:.2f}")
432
+ st.write(f"**Token Value:** {token.value:.2f}")
433
+
434
+ # ========================
435
+ # Transaction History
436
+ # ========================
437
+ transaction_history_tab_index = trading_tab_index + 1
438
+ with tabs[transaction_history_tab_index]:
439
+ st.subheader("πŸ“œ Transaction History")
440
+ transactions = session.query(Transaction).order_by(Transaction.timestamp.desc()).all()
441
+ if transactions:
442
+ transaction_data = []
443
+ for tx in transactions:
444
+ tx_info = {
445
+ "Action": tx.action,
446
+ "Value": f"{tx.value:.2f}" if tx.value else "N/A",
447
+ "Hash": tx.hash or "N/A",
448
+ "Timestamp": tx.timestamp.strftime('%Y-%m-%d %H:%M:%S')
449
+ }
450
+ transaction_data.append(tx_info)
451
+ st.table(transaction_data)
452
+ else:
453
+ st.write("πŸ“­ No transactions found.")
454
+
455
+ # ========================
456
+ # Chat Interface (Optional)
457
+ # ========================
458
+ if openai_enabled:
459
+ chat_tab_index = transaction_history_tab_index + 1
460
+ with tabs[chat_tab_index]:
461
+ st.subheader("πŸ’¬ Chat with CITIBANK DEMO BUSINESS INC AI")
462
+ if 'chat_history' not in st.session_state:
463
+ st.session_state['chat_history'] = []
464
+
465
+ def get_ai_response(user_input):
466
+ """
467
+ Generate AI response using OpenAI.
468
+ """
469
+ try:
470
+ response = openai.Completion.create(
471
+ engine="text-davinci-003", # Use 'gpt-4' if available
472
+ prompt=user_input,
473
+ max_tokens=150,
474
+ temperature=0.7,
475
+ n=1,
476
+ stop=None
477
+ )
478
+ ai_output = response.choices[0].text.strip()
479
+ return ai_output
480
+ except Exception as e:
481
+ return f"❌ Error processing AI output: {str(e)}"
482
+
483
+ user_input = st.text_input("You:", key="chat_input")
484
 
485
+ if st.button("Send"):
486
+ if user_input.strip() == "":
487
+ st.warning("❌ Please enter a message.")
488
  else:
489
+ st.session_state.chat_history.append(("You", user_input))
490
+ ai_response = get_ai_response(user_input)
491
+ st.session_state.chat_history.append(("CITIBANK DEMO BUSINESS INC AI", ai_response))
492
+
493
+ for sender, message in st.session_state.chat_history:
494
+ if sender == "You":
495
+ st.markdown(f"**You:** {message}")
496
+ else:
497
+ st.markdown(f"**CITIBANK DEMO BUSINESS INC AI:** {message}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
498
 
499
+ # ========================
500
+ # About Me Tab
501
+ # ========================
502
+ about_me_tab_index = transaction_history_tab_index + (2 if openai_enabled else 1)
503
+ with tabs[about_me_tab_index]:
504
+ st.subheader("ℹ️ About CITIBANK DEMO BUSINESS INC AI Crypto Ecosystem")
505
+ st.markdown("""
506
+ ### 🌟 Overview
507
+ The **CITIBANK DEMO BUSINESS INC AI Crypto Ecosystem** is a cutting-edge platform that seamlessly integrates **Artificial Intelligence** with **Blockchain Technology** to create a **self-sustaining** and **monetizable** ecosystem. This system empowers users to interact with AI services, earn and manage cryptocurrency tokens, and participate in a transparent and decentralized economy.
508
+
509
+ ### πŸš€ Features
510
+ - **AI Query Submission:** Submit queries to the AI and receive insightful responses. *(Requires OpenAI API Key)*
511
+ - **AI Grading Mechanism:** AI evaluates its own outputs based on a predefined rubric to determine token rewards. *(Requires OpenAI API Key)*
512
+ - **Token Minting:** Earn tokens based on the AI-generated content's quality.
513
+ - **Token Management:** View and manage your tokens, including verification status.
514
+ - **Staking:** Stake your tokens to earn rewards and support the ecosystem.
515
+ - **Trading:** Trade tokens within the ecosystem.
516
+ - **Transaction History:** Transparent logs of all your activities.
517
+ - **Chat Interface:** Interact with the AI through a dedicated chat box. *(Requires OpenAI API Key)*
518
+ - **About Section:** Detailed information about the ecosystem and its functionalities.
519
+
520
+ ### πŸ› οΈ Technology Stack
521
+ - **Backend:** Streamlit, SQLAlchemy
522
+ - **Frontend:** Streamlit Interface with Tabs
523
+ - **Blockchain:** Solidity, Ethereum (or any EVM-compatible blockchain)
524
+ - **Database:** SQLite (for demonstration) or PostgreSQL (for production)
525
+ - **AI Services:** OpenAI GPT-4 API *(Optional)*
526
+
527
+ ### πŸ”’ Security
528
+ - **Input Validation:** Comprehensive validation to prevent vulnerabilities like SQL injection and XSS attacks.
529
+ - **Secure Data Handling:** Sensitive information such as API keys are managed securely within the application interface.
530
+
531
+ ### 🌐 Deployment
532
+ The application is optimized for deployment on **Hugging Face Spaces**, ensuring accessibility and scalability. Users can configure all necessary settings directly through the Streamlit interface, eliminating the need for external environment variables.
533
+
534
+ ### πŸ“ˆ Scalability
535
+ - **Modular Design:** Each component is isolated, allowing for independent scaling and maintenance.
536
+ - **Efficient Database Management:** Utilizing SQLAlchemy for optimized interactions.
537
+ - **Asynchronous Processing:** Background threads handle long-running tasks without blocking the main application.
538
+ - **Optimized API Interactions:** Efficient handling of API requests to manage high volumes of token minting.
539
+
540
+ ---
541
+ *Embark on this transformative journey with **CITIBANK DEMO BUSINESS INC** to redefine the synergy between AI and blockchain, creating an unparalleled decentralized economy.*
542
+ """)
543
 
544
  # ========================
545
+ # Mint Token Functionality
546
  # ========================
547
 
548
+ st.sidebar.header("πŸͺ™ Mint Token")
549
+ with st.sidebar.form("mint_token_form"):
550
+ mint_address = st.text_input("Recipient Address (0x...)", value="")
551
+ mint_text = st.text_input("Mint Text", value="")
552
+ mint_button = st.form_submit_button(label='Mint Token')
553
+
554
+ if mint_button:
555
+ if not mint_address or not mint_text:
556
+ st.sidebar.error("❌ Both Address and Text are required.")
557
+ elif not (mint_address.startswith("0x") and len(mint_address) == 42):
 
558
  st.sidebar.error("❌ Invalid Blockchain Address format.")
 
 
 
 
559
  else:
560
+ with st.sidebar.spinner("πŸ” Minting tokens and storing text..."):
561
+ # Mint tokens via external API
562
+ token_contract = CONTRACT_ADDRESS # Using hardcoded contract address
563
+ balance = "100" # Adjust as needed or make it dynamic
564
+ mint_success, mint_response = mint_tokens_via_api(mint_address, token_contract, balance)
565
+
566
+ if mint_success:
567
+ st.sidebar.success("βœ… Token minted successfully via API!")
568
+ st.sidebar.write(f"**API Response:** {json.dumps(mint_response, indent=2)}")
569
+
570
+ # Update local database
571
+ token = Token(
572
+ id=str(uuid.uuid4()),
573
+ value=100.0, # Assuming balance is 100 tokens
574
+ text=mint_text, # Store the input text
575
+ recipient_address=mint_address,
576
+ verified=False,
577
+ verification_hash=hashlib.sha256(mint_text.encode()).hexdigest()
578
+ )
579
+ session.add(token)
580
+ session.commit()
581
+
582
+ # Update session state balance
583
+ st.session_state.balance += token.value
584
+ session.commit()
585
+
586
+ # Record transaction
587
+ transaction = Transaction(
588
+ token_id=token.id,
589
+ action='minted',
590
+ value=token.value,
591
+ hash=token.verification_hash
592
+ )
593
+ session.add(transaction)
594
+ session.commit()
595
+
596
+ st.sidebar.write(f"**Token ID:** {token.id}")
597
+ st.sidebar.write(f"**Tokens Earned:** {token.value:.2f}")
598
+ st.sidebar.write(f"**Stored Text:** {token.text}")
599
+ else:
600
+ st.sidebar.error(f"❌ Token minting failed: {mint_response}")