import streamlit as st import json import hashlib from web3 import Web3 from google import genai from google.genai import types # -------------------------------------------------- # PAGE CONFIG # -------------------------------------------------- st.set_page_config( page_title="Invoice-Flow AI", layout="wide", initial_sidebar_state="collapsed" ) # -------------------------------------------------- # PROFESSIONAL FINTECH STYLING # -------------------------------------------------- st.markdown(""" """, unsafe_allow_html=True) # -------------------------------------------------- # HERO / BRAND HEADER # -------------------------------------------------- st.markdown("""

Invoice-Flow AI

Agentic invoice verification & on-chain trust infrastructure for MSME finance

HACKATHON LIVE PROTOTYPE
""", unsafe_allow_html=True) # -------------------------------------------------- # SECRETS (HF SAFE) # -------------------------------------------------- try: GEMINI_API_KEY = st.secrets["GEMINI_API_KEY"] RPC_URL = st.secrets["RPC_URL"] PRIVATE_KEY = st.secrets["PRIVATE_KEY"] except Exception: st.error("Missing secrets. Add them in Hugging Face → Settings → Variables.") st.stop() # -------------------------------------------------- # CLIENT SETUP # -------------------------------------------------- genai_client = genai.Client(api_key=GEMINI_API_KEY) w3 = Web3(Web3.HTTPProvider(RPC_URL)) account = w3.eth.account.from_key(PRIVATE_KEY) CONTRACT_ADDRESS = "0x3af7C33f4D0303E6eb94c2D24fB0bD82B54c6914" contract = w3.eth.contract( address=Web3.to_checksum_address(CONTRACT_ADDRESS), abi=json.load(open("abi.json")) ) # -------------------------------------------------- # SESSION STATE # -------------------------------------------------- for key, default in { "invoice": None, "approved": False, "minted": False, "tx_hash": None }.items(): if key not in st.session_state: st.session_state[key] = default # -------------------------------------------------- # FALLBACK # -------------------------------------------------- def mock_invoice(): return { "seller_name": "TechFlow Solutions Pvt Ltd", "seller_gstin": "29AAACF5724R1Z5", "invoice_amount": 75000, "invoice_number": "INV-2024-001" } # -------------------------------------------------- # MAIN LAYOUT # -------------------------------------------------- col1, col2 = st.columns([1, 1]) # ---------------- LEFT ----------------- with col1: st.markdown("
", unsafe_allow_html=True) st.subheader("Invoice Ingestion") st.markdown("

Upload an invoice PDF for automated trust verification

", unsafe_allow_html=True) uploaded = st.file_uploader("Invoice PDF", type=["pdf"]) if uploaded: pdf_bytes = uploaded.getvalue() if st.button("Analyze Invoice"): with st.spinner("Extracting structured data..."): try: res = genai_client.models.generate_content( model="gemini-1.5-flash", contents=[ types.Part.from_bytes(pdf_bytes, "application/pdf"), "Extract invoice as JSON with keys seller_name, seller_gstin, invoice_amount, invoice_number. Return ONLY JSON." ] ) clean = res.text.replace("```json", "").replace("```", "").strip() st.session_state.invoice = json.loads(clean) except Exception: st.warning("AI extraction failed. Using demo-safe fallback.") st.session_state.invoice = mock_invoice() st.markdown("
", unsafe_allow_html=True) # ---------------- RIGHT ---------------- with col2: if st.session_state.invoice: st.markdown("
", unsafe_allow_html=True) st.subheader("Verification Summary") st.json(st.session_state.invoice) st.markdown("
", unsafe_allow_html=True) st.markdown("
", unsafe_allow_html=True) st.subheader("Buyer Consent") if not st.session_state.approved: st.markdown("Awaiting Buyer Confirmation", unsafe_allow_html=True) if st.button("Approve Invoice"): st.session_state.approved = True st.rerun() else: st.markdown("Buyer Approved", unsafe_allow_html=True) st.markdown("
", unsafe_allow_html=True) if st.session_state.approved: st.markdown("
", unsafe_allow_html=True) st.subheader("On-Chain Settlement") if not st.session_state.minted: if st.button("Mint Verified Receipt"): with st.spinner("Finalizing on blockchain..."): inv = st.session_state.invoice payload = f"{inv['invoice_number']}{inv['seller_gstin']}{inv['invoice_amount']}" receipt_hash = hashlib.sha256(payload.encode()).hexdigest() tx = contract.functions.mintReceipt( Web3.to_bytes(hexstr="0x" + receipt_hash), inv["seller_gstin"], int(inv["invoice_amount"]) ).build_transaction({ "from": account.address, "nonce": w3.eth.get_transaction_count(account.address), "gas": 250000, "gasPrice": w3.eth.gas_price, "chainId": 80002 }) signed = w3.eth.account.sign_transaction(tx, PRIVATE_KEY) tx_hash = w3.eth.send_raw_transaction(signed.raw_transaction) st.session_state.tx_hash = w3.to_hex(tx_hash) st.session_state.minted = True st.rerun() if st.session_state.minted: st.success("Receipt minted successfully") st.link_button( "View Transaction on PolygonScan", f"https://amoy.polygonscan.com/tx/{st.session_state.tx_hash}" ) st.markdown("
", unsafe_allow_html=True) # -------------------------------------------------- # FOOTER # -------------------------------------------------- st.markdown("---") st.caption( "Invoice-Flow AI • Trust Infrastructure for MSME Finance • " "Gemini 1.5 Flash • Polygon Amoy" )