khairul91's picture
Update app.py from anycoder
5e3511f verified
import os
import time
import json
import hashlib
import base64
import random
import requests
from datetime import datetime
from typing import Optional, Dict, Any, List, Tuple
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
import gradio as gr
import cirq
import numpy as np
# ---------- Konfigurasi ----------
PINATA_API_KEY = os.getenv("PINATA_API_KEY", "85065bbe4e7068ff455d")
PINATA_SECRET_KEY = os.getenv("PINATA_SECRET_KEY", "7bf252357066397403574b2a707524a60b1f60bfba9cf4b6ac9e6426d59cbd75")
# ---------- BIP39 Word List ----------
BIP39 = ["abandon","ability","able","about","above","absent","absorb","abstract","absurd","abuse","access","accident","account","accuse","achieve","acid","acoustic","acquire","across","act","action","actor","actress","actual","adapt","add","addict","address","adjust","admit","adult","advance","advice","aerobic","affair","afford","afraid","africa","after","again","age","agent","agree","ahead","aim","air","airport","aisle","alarm","album","alcohol","alert","alien","all","alley","allow","almost","alone","alpha","already","also","alter","always","amateur","amazing","among","amount","amused","analyst","anchor","ancient","anger","angle","angry","animal","ankle","announce","annual","another","answer","antenna","antique","anxiety","any","apart","apology","appear","apple","approve","april","arch","arctic","area","arena","argue","arm","armed","armor","army","around","arrange","arrest","arrive","arrow","art","artefact","artist","artwork","ask","aspect","assault","asset","assist","assume","asthma","athlete","atom","attack","attend","attitude","attract","auction","audit","august","aunt","author","auto","autumn","average","avocado","avoid","awake","aware","away","awesome","awful","awkward","axis","baby","bachelor","bacon","badge","bag","balance","balcony","ball","bamboo","banana","banner","bar","barely","bargain","barrel","base","basic","basket","battle","beach","bean","beauty","because","become","beef","before","begin","behave","behind","believe","below","belt","bench","benefit","best","betray","better","between","beyond","bicycle","bid","bike","bind","biology","bird","birth","bitter","black","blade","blame","blanket","blast","bleak","bless","blind","blood","blossom","blouse","blue","blur","blush","board","boat","body","boil","bomb","bone","bonus","book","boost","border","boring","borrow","boss","bottom","bounce","box","boy","bracket","brain","brand","brass","brave","bread","breeze","brick","bridge","brief","bright","bring","brisk","broccoli","broken","bronze","broom","brother","brown","brush","bubble","buddy","budget","buffalo","build","bulb","bulk","bullet","bundle","bunker","burden","burger","burst","bus","business","busy","butter","buyer","buzz","cabbage","cabin","cable","cactus","cage","cake","call","calm","camera","camp","can","canal","cancel","candy","cannon","canoe","canvas","canyon","capable","capital","captain","car","carbon","card","cargo","carpet","carry","cart","case","cash","casino","castle","casual","cat","catalog","catch","category","cattle","caught","cause","caution","cave","ceiling","celery","cement","census","century","cereal","certain","chair","chalk","champion","change","chaos","chapter","charge","chase","chat","cheap","check","cheese","chef","cherry","chest","chicken","chief","child","chimney","choice","choose","chronic","chuckle","chunk","churn","cigar","cinnamon","circle","citizen","city","civil","claim","clap","clarify","claw","clay","clean","clerk","clever","click","client","cliff","climb","clinic","clip","clock","clog","close","cloth","cloud","clown","club","clump","cluster","clutch","coach","coast","coconut","code","coffee","coil","coin","collect","color","column","combine","come","comfort","comic","common","company","concert","conduct","confirm","congress","connect","consider","control","convince","cook","cool","copper","copy","coral","core","corn","correct","cost","cotton","couch","country","couple","course","cousin","cover","coyote","crack","cradle","craft","cram","crane","crash","crater","crawl","crazy","cream","credit","creek","crew","cricket","crime","crisp","critic","crop","cross","crouch","crowd","crucial","cruel","cruise","crumble","crunch","crush","cry","crystal","cube","culture","cup","cupboard","curious","current","curtain","curve","cushion","custom","cute","cycle","dad","damage","damp","dance","danger","daring","dash","daughter","dawn","day","deal","debate","debris","decade","december","decide","decline","decorate","decrease","deer","defense","define","defy","degree","delay","deliver","demand","demise","denial","dentist","deny","depart","depend","deposit","depth","deputy","derive","describe","desert","design","desk","despair","destroy","detail","detect","develop","device","devote","diagram","dial","diamond","diary","dice","diesel","diet","differ","digital","dignity","dilemma","dinner","dinosaur","direct","dirt","disagree","discover","disease","dish","dismiss","disorder","display","distance","divert","divide","divorce","dizzy","doctor","document","dog","doll","dolphin","domain","donate","donkey","donor","door","dose","double","dove","draft","dragon","drama","drastic","draw","dream","dress","drift","drill","drink","drip","drive","drop","drum","dry","duck","dumb","dune","during","dust","dutch","duty","dwarf","dynamic","eager","eagle","early","earn","earth","easily","east","easy","echo","ecology","economy","edge","edit","educate","effort","egg","eight","either","elbow","elder","electric","elegant","element","elephant","elevator","elite","else","embark","embody","embrace","emerge","emotion","employ","empower","empty","enable","enact","end","endless","endorse","enemy","energy","enforce","engage","engine","enhance","enjoy","enlist","enough","enrich","enroll","ensure","enter","entire","entry","envelope","episode","equal","equip","era","erase","erode","erosion","error","erupt","escape","essay","essence","estate","eternal","ethics","evidence","evil","evoke","evolve","exact","example","excess","exchange","excite","exclude","excuse","execute","exercise","exhaust","exhibit","exile","exist","exit","exotic","expand","expect","expire","explain","expose","express","extend","extra","eye","eyebrow","fabric","face","faculty","fade","faint","faith","fall","false","fame","family","famous","fan","fancy","fantasy","farm","fashion","fat","fatal","father","fatigue","fault","favorite","feature","february","federal","fee","feed","feel","female","fence","festival","fetch","fever","few","fiber","fiction","field","figure","file","film","filter","final","find","fine","finger","finish","fire","firm","first","fiscal","fish","fit","fitness","fix","flag","flame","flash","flat","flavor","flee","flight","flip","float","flock","floor","flower","fluid","flush","fly","foam","focus","fog","foil","fold","follow","food","foot","force","forest","forget","fork","fortune","forum","forward","fossil","foster","found","fox","fragile","frame","frequent","fresh","friend","fringe","frog","front","frost","frown","frozen","fruit","fuel","fun","funny","furnace","fury","future","gadget","gain","galaxy","gallery","game","gap","garage","garbage","garden","garlic","garment","gas","gasp","gate","gather","gauge","gaze","general","genius","genre","gentle","genuine","gesture","ghost","giant","gift","giggle","ginger","giraffe","girl","give","glad","glance","glare","glass","glide","glimpse","globe","gloom","glory","glove","glow","glue","goat","goddess","gold","good","goose","gorilla","gospel","gossip","govern","gown","grab","grace","grain","grant","grape","grass","gravity","great","green","grid","grief","grit","grocery","group","grow","grunt","guard","guess","guide","guilt","guitar","gun","gym","habit","hair","half","hammer","hamster","hand","happy","harbor","hard","harsh","harvest","hat","have","hawk","hazard","head","health","heart","heavy","hedgehog","height","hello","helmet","help","hen","hero","hidden","high","hill","hint","hip","hire","history","hobby","hockey","hold","hole","holiday","hollow","home","honey","hood","hope","horn","horror","horse","hospital","host","hotel","hour","hover","hub","huge","human","humble","humor","hundred","hungry","hunt","hurdle","hurry","hurt","husband","hybrid","ice","icon","idea","identify","idle","ignore","ill","illegal","illness","image","imitate","immense","immune","impact","impose","improve","impulse","inch","include","income","increase","index","indicate","indoor","industry","infant","inflict","inform","inhale","inherit","initial","inject","injury","inmate","inner","innocent","input","inquiry","insane","insect","inside","inspire","install","intact","interest","into","invest","invite","involve","iron","island","isolate","issue","item","ivory","jacket","jaguar","jar","jazz","jealous","jeans","jelly","jewel","job","join","joke","journey","joy","judge","juice","jump","jungle","junior","junk","just","kangaroo","keen","keep","ketchup","key","kick","kid","kidney","kind","kingdom","kiss","kit","kitchen","kite","kitten","kiwi","knee","knife","knock","know","lab","label","labor","ladder","lady","lake","lamp","language","laptop","large","later","latin","laugh","laundry","lava","law","lawn","lawsuit","layer","lazy","leader","leaf","learn","leave","lecture","left","leg","legal","legend","leisure","lemon","lend","length","lens","leopard","lesson","letter","level","liar","liberty","life","lift","light","like","limb","limit","link","lion","liquid","list","little","live","lizard","load","loan","lobster","local","lock","logic","lonely","long","loop","lottery","loud","lounge","love","loyal","lucky","luggage","lumber","lunar","lunch","luxury","lyrics","machine","mad","magic","magnet","maid","mail","main","major","make","mammal","man","manage","mandate","mango","mansion","manual","maple","marble","march","margin","marine","market","marriage","mask","mass","master","match","material","math","matrix","matter","maximum","maze","meadow","mean","measure","meat","mechanic","medal","media","melody","melt","member","memory","mention","menu","mercy","merge","merit","merry","mesh","message","metal","method","middle","midnight","milk","million","mimic","mind","minimum","minor","minute","miracle","mirror","misery","miss","mistake","mix","mixed","mixture","mobile","model","modify","mom","moment","monitor","monkey","monster","month","moon","moral","more","morning","mosquito","mother","motion","motor","mountain","mouse","move","movie","much","muffin","mule","multiply","muscle","museum","mushroom","music","must","mutual","myself","mystery","myth","naive","name","napkin","narrow","nasty","nation","nature","near","neck","need","negative","neglect","neither","nephew","nerve","nest","net","network","neutral","never","news","next","nice","night","noble","noise","nominee","noodle","normal","north","nose","notable","note","nothing","notice","novel","now","nuclear","number","nurse","nut","oak","obey","object","oblige","obscure","observe","obtain","obvious","occur","ocean","october","odor","off","offer","office","often","oil","okay","old","olive","olympic","omit","once","one","onion","online","only","open","opera","opinion","oppose","option","orange","orbit","orchard","order","ordinary","organ","orient","original","orphan","ostrich","other","outdoor","outer","output","outside","oval","oven","over","own","owner","oxygen","oyster","ozone","pact","paddle","page","pair","palace","palm","panda","panel","panic","panther","paper","parade","parent","park","parrot","party","pass","patch","path","patient","patrol","pattern","pause","pave","payment","peace","peanut","pear","peasant","pelican","pen","penalty","pencil","people","pepper","perfect","permit","person","pet","phone","photo","phrase","physical","piano","picnic","picture","piece","pig","pigeon","pill","pilot","pink","pioneer","pipe","pistol","pitch","pizza","place","planet","plastic","plate","play","please","pledge","pluck","plug","plunge","poem","poet","point","polar","pole","police","pond","pony","pool","popular","portion","position","possible","post","potato","pottery","poverty","powder","power","practice","praise","predict","prefer","prepare","present","pretty","prevent","price","pride","primary","print","priority","prison","private","prize","problem","process","produce","profit","program","project","promote","proof","property","prosper","protect","proud","provide","public","pudding","pull","pulp","pulse","pumpkin","punch","pupil","puppy","purchase","purity","purpose","purse","push","put","puzzle","pyramid","quality","quantum","quarter","question","quick","quit","quiz","quote","rabbit","raccoon","race","rack","radar","radio","rail","rain","raise","rally","ramp","ranch","random","range","rapid","rare","rate","rather","raven","raw","razor","ready","real","reason","rebel","rebuild","recall","receive","recipe","record","recycle","reduce","reflect","reform","refuse","region","regret","regular","reject","relax","release","relief","rely","remain","remember","remind","remove","render","renew","rent","reopen","repair","repeat","replace","report","require","rescue","resemble","resist","resource","response","result","retire","retreat","return","reunion","reveal","review","reward","rhythm","rib","ribbon","rice","rich","ride","ridge","rifle","right","rigid","ring","riot","ripple","risk","ritual","rival","river","road","roast","robot","robust","rocket","romance","roof","rookie","room","rose","rotate","rough","round","route","royal","rubber","rude","rug","rule","run","runway","rural","sad","saddle","sadness","safe","sail","salad","salmon","salon","salt","salute","same","sample","sand","satisfy","satoshi","sauce","sausage","save","say","scale","scan","scare","scatter","scene","scheme","school","science","scissors","scorpion","scout","scrap","screen","script","scrub","sea","search","season","seat","second","secret","section","security","seed","seek","segment","select","sell","seminar","senior","sense","sentence","series","service","session","settle","setup","seven","shadow","shaft","shallow","share","shed","shell","sheriff","shield","shift","shine","ship","shiver","shock","shoe","shoot","shop","short","shoulder","shove","shrimp","shrug","shuffle","shy","sibling","sick","side","siege","sight","sign","silent","silk","silly","silver","similar","simple","since","sing","siren","sister","situate","six","size","skate","sketch","ski","skill","skin","skirt","skull","slab","slam","sleep","slender","slice","slide","slight","slim","slogan","slot","slow","slush","small","smart","smile","smoke","smooth","snack","snake","snap","sniff","snow","soap","soccer","social","sock","soda","soft","solar","soldier","solid","solution","solve","someone","song","soon","sorry","sort","soul","sound","soup","source","south","space","spare","spatial","spawn","speak","special","speed","spell","spend","sphere","spice","spider","spike","spin","spirit","split","spoil","sponsor","spoon","sport","spot","spray","spread","spring","spy","square","squeeze","squirrel","stable","stadium","staff","stage","stairs","stamp","stand","start","state","stay","steak","steel","stem","step","stereo","stick","still","sting","stock","stomach","stone","stool","story","stove","strategy","street","strike","strong","struggle","student","stuff","stumble","style","subject","submit","subway","success","such","sudden","suffer","sugar","suggest","suit","summer","sun","sunny","sunset","super","supply","supreme","sure","surface","surge","surprise","surround","survey","suspect","sustain","swallow","swamp","swap","swarm","swear","sweet","swift","swim","swing","switch","sword","symbol","symptom","syrup","system","table","tackle","tag","tail","talent","talk","tank","tape","target","task","taste","tattoo","taxi","teach","team","tell","ten","tenant","tennis","tent","term","test","text","thank","that","theme","then","theory","there","they","thing","this","thought","three","thrive","throw","thumb","thunder","ticket","tide","tiger","tilt","timber","time","tiny","tip","tired","tissue","title","toast","tobacco","today","toddler","toe","together","toilet","token","tomato","tomorrow","tone","tongue","tonight","tool","tooth","top","topic","topple","torch","tornado","tortoise","toss","total","tourist","toward","tower","town","toy","track","trade","traffic","tragic","train","transfer","trap","trash","travel","tray","treat","tree","trend","trial","tribe","trick","trigger","trim","trip","trophy","trouble","truck","true","truly","trumpet","trust","truth","try","tube","tuition","tumble","tuna","tunnel","turkey","turn","turtle","twelve","twenty","twice","twin","twist","two","ugly","umbrella","unable","unaware","uncle","uncover","under","undo","unfair","unfold","unhappy","uniform","unique","unit","universe","unknown","unlock","until","unusual","unveil","update","upgrade","uphold","upon","upper","upset","urban","urge","usage","use","used","useful","useless","usual","utility","vacant","vacuum","vague","valid","valley","valve","van","vanish","vapor","various","vast","vault","vehicle","velvet","vendor","venture","venue","verb","verify","version","very","vessel","veteran","viable","vibrant","vicious","victory","video","view","village","vintage","violin","virtual","virus","visa","visit","visual","vital","vivid","vocal","voice","void","volcano","volume","vote","voyage","wage","wagon","wait","walk","wall","walnut","want","warfare","warm","warrior","wash","wasp","waste","water","wave","way","wealth","weapon","wear","weasel","weather","web","wedding","weekend","weird","welcome","west","wet","whale","what","wheat","wheel","when","where","whip","whisper","wide","width","wife","wild","will","win","window","wine","wing","wink","winner","winter","wire","wisdom","wise","wish","witness","wolf","woman","wonder","wood","wool","word","work","world","worry","worth","wrap","wreck","wrestle","wrist","write","wrong","yard","year","yellow","you","young","youth","zebra","zero","zone","zoo"]
# ---------- Session State ----------
session_db: Dict[str, Dict[str, Any]] = {}
fib_state: Dict[str, 'FibTTL'] = {}
# ---------- Fibonacci TTL ----------
class FibTTL:
def __init__(self):
self.a, self.b = 0, 1
def next(self) -> int:
self.a, self.b = self.b, self.a + self.b
return max(30, min(self.a * 30, 300))
# ---------- Core Quantum & Crypto Functions ----------
class Core:
@staticmethod
def seed() -> bytes:
"""Generate quantum random seed using Cirq simulator"""
try:
q = [cirq.GridQubit(0, i) for i in range(256)]
c = cirq.Circuit(
cirq.H.on_each(*q),
[cirq.measure(qb, key=str(i)) for i, qb in enumerate(q)]
)
r = cirq.Simulator().run(c, repetitions=1)
bits = ''.join(str(r.measurements[str(i)][0][0]) for i in range(256))
return int(bits, 2).to_bytes(32, 'big')
except Exception as e:
# Fallback to cryptographic random
return os.urandom(32)
@staticmethod
def token(seed: bytes, ttl: int = 60) -> Tuple[str, int]:
"""Generate time-based token with TTL"""
now = int(time.time())
tw = now // ttl
tb = tw.to_bytes(8, 'big')
h = hashlib.sha256(seed + tb).digest()
tok = base64.b32encode(h[:5]).decode()[:8]
return tok, (tw + 1) * ttl - now
@staticmethod
def encrypt(data: Dict[str, Any], seed: bytes) -> Tuple[str, str]:
"""Encrypt data using AES-GCM"""
key = hashlib.sha256(seed).digest()
nonce = os.urandom(12)
aesgcm = AESGCM(key)
ct = aesgcm.encrypt(nonce, json.dumps(data).encode(), None)
return base64.b64encode(nonce + ct).decode(), hashlib.sha256(ct).hexdigest()
@staticmethod
def decrypt(enc: str, seed: bytes) -> Dict[str, Any]:
"""Decrypt data using AES-GCM"""
key = hashlib.sha256(seed).digest()
raw = base64.b64decode(enc)
aesgcm = AESGCM(key)
return json.loads(aesgcm.decrypt(raw[:12], raw[12:], None))
# ---------- Recovery Phrase ----------
def generate_recovery_phrase() -> str:
"""Generate 12-word BIP39 recovery phrase"""
return ' '.join(random.sample(BIP39, 12))
# ---------- IPFS (Pinata) ----------
class IPFS:
@staticmethod
def save(data: str) -> Optional[str]:
"""Save data to IPFS via Pinata"""
try:
r = requests.post(
"https://api.pinata.cloud/pinning/pinJSONToIPFS",
headers={
"pinata_api_key": PINATA_API_KEY,
"pinata_secret_api_key": PINATA_SECRET_KEY
},
json={"pinataContent": {"data": data}},
timeout=10
)
r.raise_for_status()
return r.json().get("IpfsHash")
except Exception as e:
print(f"IPFS save error: {e}")
return None
@staticmethod
def load(cid: str) -> Optional[Dict[str, Any]]:
"""Load data from IPFS via Pinata"""
try:
r = requests.get(f"https://gateway.pinata.cloud/ipfs/{cid}", timeout=10)
if r.status_code == 200:
return r.json().get("data")
except Exception as e:
print(f"IPFS load error: {e}")
return None
# ---------- Gradio App Functions ----------
def generate_quantum_seed() -> Tuple[str, str]:
"""Generate quantum random seed and display"""
seed = Core.seed()
seed_hex = seed.hex()
seed_preview = seed_hex[:32] + "..." if len(seed_hex) > 32 else seed_hex
return seed_hex, f"βœ… Seed Generated\n\nπŸ” **Seed (Hex):** `{seed_preview}`\n\n⚑ Generated using quantum simulation (Cirq)"
def generate_recovery_phrase_fn() -> str:
"""Generate and display recovery phrase"""
phrase = generate_recovery_phrase()
return f"πŸ”‘ **Recovery Phrase:**\n\n`{phrase}`\n\n⚠️ **SIMPAN FRASA INI!** Hanya dipapar sekali."
def register_user(username: str, seed_hex: str, progress=gr.Progress()) -> str:
"""Register a new user with encrypted data"""
if not username or not seed_hex:
return "❌ Sila masukkan username dan seed."
try:
seed = bytes.fromhex(seed_hex)
data = {
"username": username,
"registered_at": datetime.now().isoformat(),
"seed_hex": seed_hex
}
progress(0.3, desc="Encrypting data...")
enc, h = Core.encrypt(data, seed)
progress(0.6, desc="Saving to IPFS...")
cid = IPFS.save(enc)
if not cid:
return "❌ Gagal menyimpan ke IPFS. Cuba lagi."
phrase = generate_recovery_phrase()
session_id = hashlib.sha256(seed_hex.encode()).hexdigest()[:16]
session_db[session_id] = {
"cid": cid,
"seed_hex": seed_hex,
"hash": h,
"phrase": phrase,
"username": username
}
progress(1.0, desc="Registration complete!")
return f"""βœ… **Pendaftaran Berjaya!**
πŸ”‘ **Session ID:** `{session_id}`
πŸ“¦ **CID:** `{cid}`
πŸ” **Hash:** `{h[:32]}...`
πŸ“ **Frasa Pemulihan:** `{phrase}`
⚠️ **TULIS & SIMPAN FRASA INI!** Hanya dipapar sekali.
Gunakan Session ID untuk log masuk."""
except Exception as e:
return f"❌ Ralat: {str(e)}"
def generate_token(session_id: str) -> str:
"""Generate time-based token for session"""
if session_id not in session_db:
return "❌ Session tidak dijumpai. Sila daftar dahulu."
try:
session = session_db[session_id]
seed = bytes.fromhex(session["seed_hex"])
if session_id not in fib_state:
fib_state[session_id] = FibTTL()
ttl = fib_state[session_id].next()
tok, rem = Core.token(seed, ttl)
return f"""πŸ” **Token:** `{tok}`
⏳ **Masa Sah:** {rem}s
πŸ“Š **Fibonacci TTL:** {ttl}s
Token akan berubah setiap {ttl} saat."""
except Exception as e:
return f"❌ Ralat: {str(e)}"
def encrypt_data(data: str, seed_hex: str) -> str:
"""Encrypt user data"""
if not data or not seed_hex:
return "❌ Sila masukkan data dan seed."
try:
seed = bytes.fromhex(seed_hex)
enc, h = Core.encrypt({"data": data}, seed)
return f"""βœ… **Data Diencrypt!**
πŸ” **Encrypted:** `{enc[:50]}...`
πŸ” **Hash:** `{h}`
Salin encrypted data untuk disimpan."""
except Exception as e:
return f"❌ Ralat: {str(e)}"
def decrypt_data(encrypted: str, seed_hex: str) -> str:
"""Decrypt user data"""
if not encrypted or not seed_hex:
return "❌ Sila masukkan encrypted data dan seed."
try:
seed = bytes.fromhex(seed_hex)
decrypted = Core.decrypt(encrypted, seed)
return f"""βœ… **Data Didecrypt!**
πŸ“„ **Data:** `{json.dumps(decrypted, indent=2)}`"""
except Exception as e:
return f"❌ Ralat decrypt: {str(e)}"
def load_from_ipfs(cid: str) -> str:
"""Load data from IPFS"""
if not cid:
return "❌ Sila masukkan CID."
try:
data = IPFS.load(cid)
if data:
return f"""βœ… **Data Berjaya Dimuatkan!**
πŸ“¦ **CID:** `{cid}`
πŸ“„ **Data:** `{json.dumps(data, indent=2)}`"""
else:
return "❌ Gagal memuatkan data dari IPFS."
except Exception as e:
return f"❌ Ralat: {str(e)}"
def verify_recovery_phrase(phrase: str, session_id: str) -> str:
"""Verify recovery phrase matches session"""
if session_id not in session_db:
return "❌ Session tidak dijumpai."
session = session_db[session_id]
if phrase.strip() == session["phrase"]:
return f"""βœ… **Frasa Pemulihan Sah!**
πŸ‘€ **Username:** `{session['username']}`
πŸ“¦ **CID:** `{session['cid']}`
πŸ” **Seed:** `{session['seed_hex'][:32]}...`
Anda boleh memulihkan akses anda."""
else:
return "❌ Frasa pemulihan tidak sepadan."
# ---------- Custom Theme ----------
custom_theme = gr.themes.Soft(
primary_hue="indigo",
secondary_hue="purple",
neutral_hue="slate",
font=gr.themes.GoogleFont("Inter"),
text_size="lg",
spacing_size="lg",
radius_size="md"
).set(
button_primary_background_fill="*primary_600",
button_primary_background_fill_hover="*primary_700",
block_title_text_weight="600",
body_text_size="md",
)
# ---------- Gradio Interface (GRADIO 6 SYNTAX) ----------
# 🚨 CRITICAL: gr.Blocks() has NO parameters in Gradio 6!
with gr.Blocks() as demo:
gr.Markdown("""
# 🌌 Hadamard Quantum Vault
Sistem keselamatan berasaskan quantum dengan enkripsi AES-GCM dan storan IPFS.
<div style="text-align: center; margin: 20px 0;">
<a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" style="text-decoration: none;">
<span style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 8px 16px; border-radius: 20px; font-weight: bold;">
Built with anycoder πŸš€
</span>
</a>
</div>
""")
with gr.Tabs():
# Tab 1: Quantum Seed Generation
with gr.TabItem("πŸ” Quantum Seed", id=1):
gr.Markdown("### Generate seed kuantum rawak menggunakan simulator Cirq")
with gr.Row():
with gr.Column(scale=1):
seed_btn = gr.Button("🎲 Generate Quantum Seed", variant="primary", size="lg")
with gr.Column(scale=2):
seed_output = gr.Textbox(label="Quantum Seed (Hex)", lines=3, interactive=False)
seed_info = gr.Markdown()
seed_btn.click(generate_quantum_seed, outputs=[seed_output, seed_info])
# Tab 2: Recovery Phrase
with gr.TabItem("πŸ”‘ Recovery Phrase", id=2):
gr.Markdown("### Jana frasa pemulihan 12-kata BIP39")
with gr.Row():
with gr.Column(scale=1):
phrase_btn = gr.Button("πŸ“ Generate Phrase", variant="primary", size="lg")
with gr.Column(scale=2):
phrase_output = gr.Markdown()
phrase_btn.click(generate_recovery_phrase_fn, outputs=phrase_output)
# Tab 3: User Registration
with gr.TabItem("πŸ‘€ Register User", id=3):
gr.Markdown("### Daftarkan pengguna baru dengan data terenkripsi")
with gr.Row():
with gr.Column():
reg_username = gr.Textbox(label="Username", placeholder="Masukkan username")
reg_seed = gr.Textbox(label="Seed (Hex)", placeholder="Paste seed dari tab Quantum Seed", lines=2)
reg_btn = gr.Button("πŸ“ Register", variant="primary", size="lg")
with gr.Column():
reg_output = gr.Markdown()
reg_btn.click(register_user, inputs=[reg_username, reg_seed], outputs=reg_output)
# Tab 4: Token Generation
with gr.TabItem("🎫 Generate Token", id=4):
gr.Markdown("### Jana token berasaskan masa dengan Fibonacci TTL")
with gr.Row():
with gr.Column():
token_session = gr.Textbox(label="Session ID", placeholder="Masukkan Session ID dari pendaftaran")
token_btn = gr.Button("πŸ” Generate Token", variant="primary", size="lg")
with gr.Column():
token_output = gr.Markdown()
token_btn.click(generate_token, inputs=token_session, outputs=token_output)
# Tab 5: Encrypt/Decrypt
with gr.TabItem("πŸ”’ Encrypt/Decrypt", id=5):
with gr.Row():
with gr.Column():
gr.Markdown("#### Encrypt Data")
enc_data = gr.Textbox(label="Data to Encrypt", lines=3, placeholder="Masukkan data untuk diencrypt")
enc_seed = gr.Textbox(label="Seed (Hex)", lines=2, placeholder="Seed untuk encryption")
enc_btn = gr.Button("πŸ” Encrypt", variant="primary")
enc_output = gr.Markdown()
enc_btn.click(encrypt_data, inputs=[enc_data, enc_seed], outputs=enc_output)
with gr.Column():
gr.Markdown("#### Decrypt Data")
dec_data = gr.Textbox(label="Encrypted Data", lines=3, placeholder="Paste encrypted data")
dec_seed = gr.Textbox(label="Seed (Hex)", lines=2, placeholder="Seed yang sama untuk decryption")
dec_btn = gr.Button("πŸ”“ Decrypt", variant="secondary")
dec_output = gr.Markdown()
dec_btn.click(decrypt_data, inputs=[dec_data, dec_seed], outputs=dec_output)
# Tab 6: IPFS Storage
with gr.TabItem("☁️ IPFS Storage", id=6):
gr.Markdown("### Muat turun data dari IPFS menggunakan CID")
with gr.Row():
with gr.Column():
ipfs_cid = gr.Textbox(label="IPFS CID", placeholder="Masukkan CID dari Pinata/IPFS")
ipfs_btn = gr.Button("πŸ“₯ Load from IPFS", variant="primary", size="lg")
with gr.Column():
ipfs_output = gr.Markdown()
ipfs_btn.click(load_from_ipfs, inputs=ipfs_cid, outputs=ipfs_output)
# Tab 7: Verify Recovery
with gr.TabItem("βœ… Verify Phrase", id=7):
gr.Markdown("### Sahkan frasa pemulihan untuk memulihkan akses")
with gr.Row():
with gr.Column():
verify_session = gr.Textbox(label="Session ID", placeholder="Masukkan Session ID")
verify_phrase = gr.Textbox(label="Recovery Phrase", lines=2, placeholder="Paste frasa pemulihan 12-kata")
verify_btn = gr.Button("βœ… Verify", variant="primary", size="lg")
with gr.Column():
verify_output = gr.Markdown()
verify_btn.click(verify_recovery_phrase, inputs=[verify_phrase, verify_session], outputs=verify_output)
# Footer
gr.Markdown("""
---
### πŸ”’ Security Notes
- **Quantum Seed**: Generated using Cirq quantum simulator (256 qubits)
- **Encryption**: AES-GCM with 256-bit keys
- **Storage**: IPFS via Pinata (decentralized)
- **Recovery**: BIP39 12-word phrase
⚠️ **Simpan seed dan recovery phrase anda dengan selamat!**
""")
# ---------- Launch (GRADIO 6 SYNTAX) ----------
# 🚨 CRITICAL: ALL app parameters go in demo.launch() for Gradio 6!
if __name__ == "__main__":
demo.launch(
theme=custom_theme,
footer_links=[
{"label": "Built with anycoder", "url": "https://huggingface.co/spaces/akhaliq/anycoder"},
{"label": "Gradio Docs", "url": "https://gradio.app/docs"},
{"label": "Cirq Documentation", "url": "https://quantumai.google/cirq"}
]
)