| 6 | "": "// \\\\u{2500}\\\\u{2500}\\\\u{2500} Config \\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\nconst CONTRACT_ID = \\\\\\\"qelo.near\\\\\\\";\\\\nconst TOKEN_CONTRACT_ID = \\\\\\\"qelo.launch.intear.near\\\\\\\";\\\\nconst QELO_DECIMALS = 24;\\\\nconst ONE_YOCTO = \\\\\\\"1\\\\\\\";\\\\nconst THIRTY_TGAS = \\\\\\\"30000000000000\\\\\\\";\\\\nconst STORAGE_DEPOSIT_AMOUNT = \\\\\\\"50000000000000000000000\\\\\\\"; // 0.05 NEAR\\\\n\\\\n// \\\\u{2500}\\\\u{2500}\\\\u{2500} GANTI DENGAN CID IPFS KAMU DI SINI \\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\nconst MY_LOGO_CID =\\\\n \\\\\\\"bafkreibn5fgqqxlz3agpgclswjxm2fgxjyy6fhmrzftlftdmq2sv25k7ly\\\\\\\";\\\\nconst MY_LOGO_URL = `https://ipfs.near.social/ipfs/${MY_LOGO_CID}`;\\\\n\\\\n// \\\\u{2500}\\\\u{2500}\\\\u{2500} Context & State \\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\nconst accountId = context.accountId;\\\\n\\\\nState.init({\\\\n receiver: \\\\\\\"\\\\\\\",\\\\n text: \\\\\\\"\\\\\\\",\\\\n amount: \\\\\\\"1\\\\\\\",\\\\n error: \\\\\\\"\\\\\\\",\\\\n});\\\\n\\\\n// \\\\u{2500}\\\\u{2500}\\\\u{2500} Fetch Data \\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\nconst globalFeed =\\\\n Near.view(CONTRACT_ID, \\\\\\\"get_global_feed\\\\\\\", { limit: 50 }) || [];\\\\nconst messageCount = Near.view(CONTRACT_ID, \\\\\\\"get_message_count\\\\\\\", {}) || 0;\\\\n\\\\nlet storageBalance = \\\\\\\"0\\\\\\\";\\\\nlet qeloBalance = \\\\\\\"0\\\\\\\";\\\\n\\\\nif (accountId) {\\\\n storageBalance =\\\\n Near.view(CONTRACT_ID, \\\\\\\"get_storage_balance\\\\\\\", { account_id: accountId }) ||\\\\n \\\\\\\"0\\\\\\\";\\\\n qeloBalance =\\\\n Near.view(TOKEN_CONTRACT_ID, \\\\\\\"ft_balance_of\\\\\\\", { account_id: accountId }) ||\\\\n \\\\\\\"0\\\\\\\";\\\\n}\\\\n\\\\nconst hasStorage = storageBalance ? Big(storageBalance).gt(0) : false;\\\\n\\\\n// \\\\u{2500}\\\\u{2500}\\\\u{2500} Helpers \\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\nconst formatQelo = (yocto) => {\\\\n if (!yocto || yocto === \\\\\\\"0\\\\\\\") return \\\\\\\"0\\\\\\\";\\\\n const str = yocto.toString().padStart(QELO_DECIMALS + 1, \\\\\\\"0\\\\\\\");\\\\n const intPart = str.slice(0, str.length - QELO_DECIMALS) || \\\\\\\"0\\\\\\\";\\\\n const decPart = str.slice(\\\\n str.length - QELO_DECIMALS,\\\\n str.length - QELO_DECIMALS + 6\\\\n );\\\\n return `${Number(intPart).toLocaleString()}.${decPart}`.replace(/\\\\\\\\.?0+$/, \\\\\\\"\\\\\\\");\\\\n};\\\\n\\\\nconst multiplyQelo = (human) => {\\\\n const parts = human.toString().split(\\\\\\\".\\\\\\\");\\\\n const intPart = parts[0] || \\\\\\\"0\\\\\\\";\\\\n const decPart = (parts[1] || \\\\\\\"\\\\\\\")\\\\n .padEnd(QELO_DECIMALS, \\\\\\\"0\\\\\\\")\\\\n .slice(0, QELO_DECIMALS);\\\\n return (intPart + decPart).replace(/^0+/, \\\\\\\"\\\\\\\") || \\\\\\\"0\\\\\\\";\\\\n};\\\\n\\\\n// \\\\u{2500}\\\\u{2500}\\\\u{2500} Styling (The Match Update) \\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\nconst MainContainer = styled.div`\\\\n /* Theme Warna Berdasarkan Logo */\\\\n --bg-primary: #000000; /* Hitam Pekat */\\\\n --neon-mint: #00EC97; /* Hijau Neon Mint dari Logo */\\\\n --neon-mint-dim: #00ba77; /* Warna Border/Redup */\\\\n --text-primary: #FFFFFF; /* Putih Kontras */\\\\n --text-muted: #888888; /* Abu-abu Redup */\\\\n --bg-card: #080808; /* Kartu Sangat Gelap */\\\\n --border-color: #1a1a1a; /* Border Tipis Gelap */\\\\n\\\\n background: var(--bg-primary);\\\\n color: var(--text-primary);\\\\n min-height: 100vh;\\\\n padding: 1.5rem;\\\\n font-family: \\\\\\'Inter\\\\\\', sans-serif;\\\\n\\\\n .glass {\\\\n background: var(--bg-card);\\\\n border: 1px solid var(--border-color);\\\\n border-radius: 0.75rem;\\\\n }\\\\n\\\\n .glass:hover {\\\\n border-color: var(--neon-mint-dim);\\\\n }\\\\n\\\\n .gradient-text-match {\\\\n /* Hanya satu warna Mint Neon, dengan efek glow */\\\\n color: var(--neon-mint);\\\\n font-weight: 700;\\\\n font-style: italic;\\\\n text-shadow: 0 0 5px var(--neon-mint-dim);\\\\n }\\\\n\\\\n .animate-blob {\\\\n animation: blob-bounce 2s ease-in-out infinite;\\\\n }\\\\n\\\\n @keyframes blob-bounce {\\\\n 0%, 100% { transform: translateY(0) scale(1); }\\\\n 50% { transform: translateY(-10px) scale(1.02); }\\\\n }\\\\n\\\\n input, textarea {\\\\n background: #020202;\\\\n border: 1px solid #1a1a1a;\\\\n color: var(--text-primary);\\\\n padding: 0.75rem;\\\\n border-radius: 0.5rem;\\\\n width: 100%;\\\\n margin-top: 0.5rem;\\\\n }\\\\n\\\\n input:focus, textarea:focus {\\\\n outline: none;\\\\n border-color: var(--neon-mint);\\\\n }\\\\n\\\\n button.primary {\\\\n background: var(--neon-mint);\\\\n color: #000000;\\\\n font-weight: bold;\\\\n padding: 0.8rem;\\\\n border-radius: 0.5rem;\\\\n border: none;\\\\n width: 100%;\\\\n cursor: pointer;\\\\n transition: all 0.2s ease-in-out;\\\\n }\\\\n button.primary:hover {\\\\n background: #FFFFFF;\\\\n box-shadow: 0 0 10px var(--neon-mint);\\\\n }\\\\n`;\\\\n\\\\nconst MessageBubble = styled.div`\\\\n display: flex;\\\\n flex-direction: column;\\\\n margin-bottom: 16px;\\\\n align-items: ${(props) => (props.isSender ? \\\\\\\"flex-end\\\\\\\" : \\\\\\\"flex-start\\\\\\\")};\\\\n\\\\n .bubble {\\\\n max-width: 80%;\\\\n padding: 12px 16px;\\\\n border-radius: 16px;\\\\n position: relative;\\\\n background: ${(props) =>\\\\n props.isSender ? \\\\\\\"rgba(0, 236, 151, 0.1)\\\\\\\" : \\\\\\\"#161616\\\\\\\"};\\\\n border: 1px solid ${(props) =>\\\\n props.isSender ? \\\\\\\"var(--neon-mint)\\\\\\\" : \\\\\\\"#333\\\\\\\"};\\\\n color: white;\\\\n box-shadow: ${(props) =>\\\\n props.isSender ? \\\\\\\"0 0 10px rgba(0, 236, 151, 0.2)\\\\\\\" : \\\\\\\"none\\\\\\\"};\\\\n }\\\\n\\\\n .sender-name {\\\\n font-size: 11px;\\\\n color: var(--text-muted);\\\\n margin-bottom: 4px;\\\\n margin-left: ${(props) => (props.isSender ? \\\\\\\"0\\\\\\\" : \\\\\\\"8px\\\\\\\")};\\\\n margin-right: ${(props) => (props.isSender ? \\\\\\\"8px\\\\\\\" : \\\\\\\"0\\\\\\\")};\\\\n }\\\\n\\\\n .footer-info {\\\\n display: flex;\\\\n justify-content: space-between;\\\\n align-items: center;\\\\n margin-top: 8px;\\\\n font-size: 10px;\\\\n gap: 10px;\\\\n }\\\\n\\\\n .qelo-tag {\\\\n color: var(--neon-mint);\\\\n font-weight: bold;\\\\n background: rgba(0, 236, 151, 0.1);\\\\n padding: 2px 6px;\\\\n border-radius: 4px;\\\\n }\\\\n `;\\\\n\\\\n// \\\\u{2500}\\\\u{2500}\\\\u{2500} Render \\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\u{2500}\\\\nreturn (\\\\n <MainContainer>\\\\n {/* Header */}\\\\n <div className=\\\\\\\"glass p-4 mb-6 flex justify-between items-center shadow-2xl\\\\\\\">\\\\n <div className=\\\\\\\"flex items-center gap-3\\\\\\\">\\\\n {/* LOGO DI HEADER DENGAN BORDER NEON */}\\\\n <img\\\\n src={MY_LOGO_URL}\\\\n style={{\\\\n width: \\\\\\\"36px\\\\\\\",\\\\n height: \\\\\\\"36px\\\\\\\",\\\\n borderRadius: \\\\\\\"50%\\\\\\\",\\\\n border: \\\\\\\"2px solid var(--neon-mint)\\\\\\\",\\\\n }}\\\\n />\\\\n <div>\\\\n <h1 className=\\\\\\\"gradient-text-match m-0 text-xl\\\\\\\">QeloChat</h1>\\\\n <div style={{ fontSize: \\\\\\\"10px\\\\\\\", color: \\\\\\\"var(--text-muted)\\\\\\\" }}>\\\\n DECENTRALIZED MESSAGING\\\\n </div>\\\\n </div>\\\\n </div>\\\\n <div className=\\\\\\\"text-right\\\\\\\">\\\\n {accountId ? (\\\\n <>\\\\n <div\\\\n style={{\\\\n color: \\\\\\\"var(--neon-mint)\\\\\\\",\\\\n fontWeight: \\\\\\\"bold\\\\\\\",\\\\n fontSize: \\\\\\\"14px\\\\\\\",\\\\n }}\\\\n >\\\\n {formatQelo(qeloBalance)} QELO\\\\n </div>\\\\n <div style={{ fontSize: \\\\\\\"12px\\\\\\\", color: \\\\\\\"var(--text-muted)\\\\\\\" }}>\\\\n {accountId}\\\\n </div>\\\\n </>\\\\n ) : (\\\\n <div style={{ fontSize: \\\\\\\"12px\\\\\\\", color: \\\\\\\"var(--text-muted)\\\\\\\" }}>\\\\n Please Login\\\\n </div>\\\\n )}\\\\n </div>\\\\n </div>\\\\n\\\\n <div style={{ display: \\\\\\\"flex\\\\\\\", gap: \\\\\\\"1.5rem\\\\\\\", flexWrap: \\\\\\\"wrap\\\\\\\" }}>\\\\n {/* Left Column: Feed */}\\\\n <div style={{ flex: 2, minWidth: \\\\\\\"300px\\\\\\\" }}>\\\\n <h3 className=\\\\\\\"gradient-text-match mb-4\\\\\\\">Live Feed ({messageCount})</h3>\\\\n\\\\n {globalFeed.length === 0 ? (\\\\n <div style={{ textAlign: \\\\\\\"center\\\\\\\", padding: \\\\\\\"60px 0\\\\\\\" }}>\\\\n <img\\\\n src={MY_LOGO_URL}\\\\n className=\\\\\\\"animate-blob\\\\\\\"\\\\n style={{\\\\n width: \\\\\\\"90px\\\\\\\",\\\\n height: \\\\\\\"90px\\\\\\\",\\\\n borderRadius: \\\\\\\"50%\\\\\\\",\\\\n marginBottom: \\\\\\\"15px\\\\\\\",\\\\n filter: \\\\\\\"drop-shadow(0 0 5px var(--neon-mint-dim))\\\\\\\",\\\\n }}\\\\n />\\\\n <p style={{ color: \\\\\\\"var(--text-muted)\\\\\\\", fontSize: \\\\\\\"14px\\\\\\\" }}>\\\\n Waiting for on-chain vibes...\\\\n </p>\\\\n </div>\\\\n ) : (\\\\n globalFeed.map((msg) => {\\\\n const isSender = msg.sender === accountId;\\\\n return (\\\\n <MessageBubble isSender={isSender} key={msg.id}>\\\\n <span className=\\\\\\\"sender-name\\\\\\\">\\\\n {isSender ? \\\\\\\"You\\\\\\\" : msg.sender.slice(0, 18) + \\\\\\\"...\\\\\\\"}\\\\n </span>\\\\n <div className=\\\\\\\"bubble\\\\\\\">\\\\n <div style={{ wordBreak: \\\\\\\"break-word\\\\\\\", fontSize: \\\\\\\"14px\\\\\\\" }}>\\\\n {msg.text}\\\\n </div>\\\\n <div className=\\\\\\\"qelo-tag\\\\\\\">\\\\n \\\\u{1f4b0} {formatQelo(msg.token_amount)} QELO\\\\n </div>\\\\n <div className=\\\\\\\"footer-info\\\\\\\">\\\\n <span style={{ fontSize: \\\\\\\"9px\\\\\\\" }}>\\\\n to: {msg.receiver.slice(0, 10)}...\\\\n </span>\\\\n <span style={{ fontSize: \\\\\\\"9px\\\\\\\" }}>\\\\n {new Date(msg.timestamp / 1000000).toLocaleTimeString(\\\\n [],\\\\n {\\\\n hour: \\\\\\\"2-digit\\\\\\\",\\\\n minute: \\\\\\\"2-digit\\\\\\\",\\\\n }\\\\n )}\\\\n </span>\\\\n </div>\\\\n </div>\\\\n </MessageBubble>\\\\n );\\\\n })\\\\n )}\\\\n </div>\\\\n\\\\n {/* Right Column: Actions */}\\\\n <div style={{ flex: 1, minWidth: \\\\\\\"300px\\\\\\\" }}>\\\\n <div className=\\\\\\\"glass p-5\\\\\\\">\\\\n <h3 className=\\\\\\\"gradient-text-match m-0 mb-4\\\\\\\">\\\\u{2709}\\\\u{fe0f} Send Message</h3>\\\\n\\\\n {!accountId ? (\\\\n <p className=\\\\\\\"text-center\\\\\\\" style={{ color: \\\\\\\"var(--text-muted)\\\\\\\" }}>\\\\n Connect wallet to broadcast on NEAR.\\\\n </p>\\\\n ) : !hasStorage ? (\\\\n <div className=\\\\\\\"text-center py-4\\\\\\\">\\\\n <p\\\\n style={{\\\\n fontSize: \\\\\\\"12px\\\\\\\",\\\\n color: \\\\\\\"var(--text-muted)\\\\\\\",\\\\n marginBottom: \\\\\\\"15px\\\\\\\",\\\\n }}\\\\n >\\\\n Register storage (0.05 NEAR) to call functions on the QeloChat\\\\n contract.\\\\n </p>\\\\n <button\\\\n className=\\\\\\\"primary\\\\\\\"\\\\n onClick={() =>\\\\n Near.call(\\\\n CONTRACT_ID,\\\\n \\\\\\\"storage_deposit\\\\\\\",\\\\n {},\\\\n THIRTY_TGAS,\\\\n STORAGE_DEPOSIT_AMOUNT\\\\n )\\\\n }\\\\n >\\\\n Register Storage (0.05 NEAR)\\\\n </button>\\\\n </div>\\\\n ) : (\\\\n <div className=\\\\\\\"space-y-4\\\\\\\">\\\\n <div className=\\\\\\\"mb-3\\\\\\\">\\\\n <label style={{ fontSize: \\\\\\\"11px\\\\\\\", color: \\\\\\\"var(--text-muted)\\\\\\\" }}>\\\\n Receiver\\\\n </label>\\\\n <input\\\\n value={state.receiver}\\\\n onChange={(e) => State.update({ receiver: e.target.value })}\\\\n placeholder=\\\\\\\"username.near\\\\\\\"\\\\n />\\\\n </div>\\\\n <div className=\\\\\\\"mb-3\\\\\\\">\\\\n <label style={{ fontSize: \\\\\\\"11px\\\\\\\", color: \\\\\\\"var(--text-muted)\\\\\\\" }}>\\\\n Message (Max 1000 Chars)\\\\n </label>\\\\n <textarea\\\\n value={state.text}\\\\n onChange={(e) => State.update({ text: e.target.value })}\\\\n placeholder=\\\\\\\"Type something nice...\\\\\\\"\\\\n rows={3}\\\\n maxLength={1000}\\\\n />\\\\n </div>\\\\n <div className=\\\\\\\"mb-4\\\\\\\">\\\\n <label style={{ fontSize: \\\\\\\"11px\\\\\\\", color: \\\\\\\"var(--text-muted)\\\\\\\" }}>\\\\n Amount ($QELO)\\\\n </label>\\\\n <input\\\\n type=\\\\\\\"number\\\\\\\"\\\\n value={state.amount}\\\\n onChange={(e) => State.update({ amount: e.target.value })}\\\\n step=\\\\\\\"0.1\\\\\\\"\\\\n />\\\\n </div>\\\\n {state.error && (\\\\n <p style={{ color: \\\\\\\"#ef4444\\\\\\\", fontSize: \\\\\\\"12px\\\\\\\" }}>\\\\n {state.error}\\\\n </p>\\\\n )}\\\\n <button\\\\n className=\\\\\\\"primary\\\\\\\"\\\\n onClick={() => {\\\\n State.update({ error: \\\\\\\"\\\\\\\" });\\\\n if (!state.receiver || !state.text) {\\\\n State.update({\\\\n error: \\\\\\\"Receiver and message are required\\\\\\\",\\\\n });\\\\n return;\\\\n }\\\\n const yocto = multiplyQelo(state.amount);\\\\n Near.call(\\\\n TOKEN_CONTRACT_ID,\\\\n \\\\\\\"ft_transfer_call\\\\\\\",\\\\n {\\\\n receiver_id: CONTRACT_ID,\\\\n amount: yocto,\\\\n msg: JSON.stringify({\\\\n receiver: state.receiver,\\\\n text: state.text,\\\\n }),\\\\n },\\\\n \\\\\\\"80000000000000\\\\\\\",\\\\n ONE_YOCTO\\\\n );\\\\n }}\\\\n >\\\\n Broadcast on-chain\\\\n </button>\\\\n </div>\\\\n )}\\\\n </div>\\\\n </div>\\\\n </div>\\\\n </MainContainer>\\\\n);\\\\n" |