<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Gift Trust</title>
    <description>The latest articles on DEV Community by Gift Trust (@gift_trust_44882a016531d7).</description>
    <link>https://dev.to/gift_trust_44882a016531d7</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3603662%2F256e9dbd-34fd-4680-b501-79323563d823.jpg</url>
      <title>DEV Community: Gift Trust</title>
      <link>https://dev.to/gift_trust_44882a016531d7</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gift_trust_44882a016531d7"/>
    <language>en</language>
    <item>
      <title>AIRTIMES GLOBAL NETWORK</title>
      <dc:creator>Gift Trust</dc:creator>
      <pubDate>Mon, 01 Jun 2026 12:51:56 +0000</pubDate>
      <link>https://dev.to/gift_trust_44882a016531d7/airtimes-global-network-53jc</link>
      <guid>https://dev.to/gift_trust_44882a016531d7/airtimes-global-network-53jc</guid>
      <description>&lt;p&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;br&gt;
&lt;br&gt;
&lt;/p&gt;
&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
AIRTIMES — Global Network of Data &amp;amp; Free Services
&lt;br&gt;



:root {
  --bg: #020508; --sf: #060d14; --sf2: #0a1520;
  --ac: #00ffe0; --ac2: #0077ff; --ac3: #ff4d6d;
  --gd: #f5c518; --gd2: #ff9f00;
  --tx: #c8e8ff; --mt: #3a5570;
}
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }
body { background: var(--bg); color: var(--tx); font-family: 'Space Mono', monospace; overflow-x: hidden; }

.bg-layer { position: fixed; inset: 0; z-index: 0; pointer-events: none;
  background: radial-gradient(ellipse 80% 60% at 20% 10%, rgba(0,119,255,.07), transparent 70%),
  radial-gradient(ellipse 60% 50% at 80% 80%, rgba(0,255,224,.06), transparent 70%),
  radial-gradient(ellipse 40% 40% at 50% 50%, rgba(245,197,24,.03), transparent 70%); }
.grid-overlay { position: fixed; inset: 0; z-index: 0; pointer-events: none;
  background-image: linear-gradient(rgba(0,255,224,.04) 1px, transparent 1px),
  linear-gradient(90deg, rgba(0,255,224,.04) 1px, transparent 1px);
  background-size: 48px 48px; animation: gridDrift 30s linear infinite; }
@keyframes gridDrift { to { background-position: 48px 48px; } }
.scanline { position: fixed; inset: 0; z-index: 1; pointer-events: none;
  background: repeating-linear-gradient(to bottom, transparent 0, transparent 3px, rgba(0,0,0,.06) 3px, rgba(0,0,0,.06) 4px); }
.shell { position: relative; z-index: 2; }

/* NAV */
nav { display: flex; align-items: center; justify-content: space-between;
  padding: 15px 38px; border-bottom: 1px solid rgba(0,255,224,.1);
  backdrop-filter: blur(14px); position: sticky; top: 0; z-index: 200; background: rgba(2,5,8,.9); }
.logo { font-family: 'Bebas Neue'; font-size: 1.85rem; letter-spacing: .25em;
  color: var(--ac); text-shadow: 0 0 24px rgba(0,255,224,.5); cursor: pointer; position: relative; }
.logo::after { content: '●'; font-size: .35em; color: var(--ac3);
  position: absolute; top: 4px; right: -14px; animation: blink 1.4s step-end infinite; }
@keyframes blink { 50% { opacity: 0; } }
.nl { display: flex; gap: 22px; list-style: none; }
.nl a { color: var(--mt); text-decoration: none; font-size: .65rem; letter-spacing: .14em;
  text-transform: uppercase; transition: color .2s; cursor: pointer; }
.nl a:hover { color: var(--ac); }
.nl a.ga { color: var(--gd); }
.nl a.ga:hover { color: var(--gd2); }
.sp { display: flex; align-items: center; gap: 8px; font-size: .6rem; color: var(--ac); letter-spacing: .12em; }
.pulse { width: 7px; height: 7px; border-radius: 50%; background: var(--ac);
  box-shadow: 0 0 8px var(--ac); animation: blink 1.4s step-end infinite; }

/* TABS */
.tab-bar { display: flex; border-bottom: 1px solid rgba(0,255,224,.08); background: rgba(2,5,8,.75);
  position: sticky; top: 61px; z-index: 100; backdrop-filter: blur(10px); overflow-x: auto; }
.tab { padding: 13px 22px; font-size: .62rem; letter-spacing: .15em; text-transform: uppercase;
  color: var(--mt); cursor: pointer; border-bottom: 2px solid transparent; transition: all .25s; white-space: nowrap; flex-shrink: 0; }
.tab:hover { color: var(--tx); }
.tab.active { color: var(--ac); border-bottom-color: var(--ac); }
.tab.gt { color: rgba(245,197,24,.5); }
.tab.gt:hover { color: var(--gd); }
.tab.gt.active { color: var(--gd); border-bottom-color: var(--gd); }

/* PAGES */
.page { display: none; animation: pi .3s ease; }
.page.active { display: block; }
@keyframes pi { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.sec { max-width: 1300px; margin: 0 auto; padding: 56px 40px; }
.sl { font-size: .58rem; color: var(--ac); letter-spacing: .28em; text-transform: uppercase; margin-bottom: 8px; }
.sl.gd { color: var(--gd); }
.st { font-family: 'Bebas Neue'; font-size: 2.8rem; color: #fff; letter-spacing: .05em; margin-bottom: 28px; line-height: 1; }
.sub { font-size: .76rem; color: var(--mt); line-height: 1.9; max-width: 640px; margin-bottom: 36px; }

/* HERO */
.hero { display: grid; grid-template-columns: 1fr 1fr; gap: 56px; align-items: center;
  padding: 76px 40px 56px; max-width: 1300px; margin: 0 auto; }
.htag { font-size: .62rem; letter-spacing: .24em; text-transform: uppercase;
  color: var(--ac2); margin-bottom: 12px; display: flex; align-items: center; gap: 10px; }
.htag::before { content: ''; width: 30px; height: 1px; background: var(--ac2); }
h1 { font-family: 'Bebas Neue'; font-size: clamp(3.2rem,6.5vw,6rem);
  line-height: .92; letter-spacing: .05em; color: #fff; margin-bottom: 20px; }
h1 .t { color: var(--ac); text-shadow: 0 0 25px rgba(0,255,224,.4); }
h1 .r { color: var(--ac3); }
h1 .g { color: var(--gd); }
.hd { font-size: .78rem; line-height: 1.9; color: var(--mt); max-width: 420px; margin-bottom: 32px; }
.ha { display: flex; gap: 10px; flex-wrap: wrap; }

/* BUTTONS */
.btn { border: none; padding: 12px 24px; font-family: 'Space Mono'; font-size: .68rem;
  font-weight: 700; letter-spacing: .14em; text-transform: uppercase; cursor: pointer; transition: all .25s; }
.bp { background: var(--ac); color: #000; clip-path: polygon(0 0,calc(100% - 10px) 0,100% 10px,100% 100%,0 100%); }
.bp:hover { box-shadow: 0 0 28px rgba(0,255,224,.3); transform: translateY(-2px); }
.bg { background: var(--gd); color: #000; clip-path: polygon(0 0,calc(100% - 10px) 0,100% 10px,100% 100%,0 100%); }
.bg:hover { box-shadow: 0 0 28px rgba(245,197,24,.3); transform: translateY(-2px); }
.bs { background: transparent; color: var(--tx); border: 1px solid var(--mt); }
.bs:hover { border-color: var(--ac); color: var(--ac); }
.bsm { padding: 8px 16px; font-size: .6rem; }

/* GLOBE */
.gw { position: relative; display: flex; align-items: center; justify-content: center; height: 400px; }
.globe { width: 290px; height: 290px; border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, rgba(0,119,255,.25), transparent 60%),
  radial-gradient(circle at 50% 50%, #020d1a 40%, #010608 100%);
  border: 1px solid rgba(0,255,224,.15);
  box-shadow: 0 0 80px rgba(0,119,255,.2), inset 0 0 60px rgba(0,119,255,.1);
  animation: gp 6s ease-in-out infinite; }
@keyframes gp { 50% { box-shadow: 0 0 120px rgba(0,119,255,.35), inset 0 0 80px rgba(0,119,255,.15); } }
.orb { position: absolute; border-radius: 50%; border: 1px solid rgba(0,255,224,.12); }
.o1 { width: 370px; height: 370px; animation: os 12s linear infinite; }
.o2 { width: 450px; height: 450px; border-color: rgba(0,119,255,.08); animation: os 20s linear infinite reverse; }
@keyframes os { to { transform: rotate(360deg); } }
.on { position: absolute; width: 8px; height: 8px; border-radius: 50%;
  background: var(--ac); box-shadow: 0 0 12px var(--ac); top: -4px; left: 50%; transform: translateX(-50%); }
.o2 .on { background: var(--ac2); box-shadow: 0 0 12px var(--ac2); }
.sig { position: absolute; top: 50%; left: 50%; height: 1px;
  background: linear-gradient(90deg, rgba(0,255,224,.5), transparent);
  transform-origin: left; animation: sp 3s ease-in-out infinite; }
@keyframes sp { 0% { opacity: 0; width: 0; } 40% { opacity: 1; } 100% { opacity: 0; width: 150px; } }
.s1 { transform: rotate(35deg); }
.s2 { transform: rotate(135deg); animation-delay: .8s; }
.s3 { transform: rotate(220deg); animation-delay: 1.6s; }
.s4 { transform: rotate(310deg); animation-delay: 2.4s; }
.db { position: absolute; background: rgba(6,13,20,.92); border: 1px solid rgba(0,255,224,.2);
  padding: 7px 12px; font-size: .57rem; color: var(--ac); letter-spacing: .1em;
  backdrop-filter: blur(8px); animation: fu 4s ease-in-out infinite; }
.db.b1 { top: 46px; left: 4px; }
.db.b2 { bottom: 66px; right: -2px; animation-delay: 1.5s; color: var(--ac2); border-color: rgba(0,119,255,.3); }
.db.b3 { top: 166px; right: -4px; animation-delay: .8s; color: var(--gd); border-color: rgba(245,197,24,.3); }
@keyframes fu { 50% { transform: translateY(-8px); } }

/* TICKER */
.tw { overflow: hidden; padding: 10px 0; border-top: 1px solid rgba(0,255,224,.07);
  border-bottom: 1px solid rgba(0,255,224,.07); background: rgba(0,255,224,.02); }
.tt { display: flex; gap: 56px; white-space: nowrap; animation: ts 35s linear infinite; }
@keyframes ts { to { transform: translateX(-50%); } }
.ti { display: flex; align-items: center; gap: 10px; font-size: .62rem;
  letter-spacing: .14em; text-transform: uppercase; color: var(--mt); }
.dot { width: 5px; height: 5px; border-radius: 50%; background: var(--ac); }
.dot.gd { background: var(--gd); }

/* STATS ROW */
.sr { max-width: 1300px; margin: 50px auto; padding: 0 40px;
  display: grid; grid-template-columns: repeat(4,1fr); gap: 2px; }
.sc { background: var(--sf); border: 1px solid rgba(0,255,224,.08);
  padding: 26px 22px; position: relative; overflow: hidden; transition: border-color .3s; }
.sc:hover { border-color: rgba(0,255,224,.2); }
.sc::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 2px;
  background: linear-gradient(90deg, transparent, var(--ac), transparent); opacity: 0; transition: opacity .3s; }
.sc:hover::before { opacity: 1; }
.sn { font-family: 'Bebas Neue'; font-size: 2.6rem; color: var(--ac); line-height: 1; margin-bottom: 4px; }
.sn.b { color: var(--ac2); } .sn.r { color: var(--ac3); } .sn.gd { color: var(--gd); }
.sl2 { font-size: .56rem; color: var(--mt); letter-spacing: .18em; text-transform: uppercase; }

/* CARDS */
.cg { display: grid; grid-template-columns: repeat(3,1fr); gap: 2px; }
.card { background: var(--sf); border: 1px solid rgba(0,255,224,.07);
  padding: 30px 24px; position: relative; overflow: hidden; cursor: pointer; transition: all .3s; }
.card:hover { background: var(--sf2); border-color: rgba(0,255,224,.2); transform: translateY(-3px); }
.card::after { content: ''; position: absolute; bottom: 0; left: 0; right: 0; height: 2px;
  background: linear-gradient(90deg, var(--ac2), var(--ac));
  transform: scaleX(0); transform-origin: left; transition: transform .4s; }
.card:hover::after { transform: scaleX(1); }
.ci { font-size: 1.7rem; margin-bottom: 16px; }
.cn { font-family: 'Syne'; font-size: .95rem; font-weight: 700; color: #fff; margin-bottom: 8px; }
.cd { font-size: .68rem; line-height: 1.8; color: var(--mt); }
.ctag { display: inline-block; margin-top: 14px; font-size: .54rem; letter-spacing: .17em;
  text-transform: uppercase; color: var(--ac); border: 1px solid rgba(0,255,224,.2); padding: 3px 9px; }
.ctag.b { color: var(--ac2); border-color: rgba(0,119,255,.25); }
.ctag.r { color: var(--ac3); border-color: rgba(255,77,109,.25); }
.ctag.gd { color: var(--gd); border-color: rgba(245,197,24,.25); }

/* FORMS */
.fp { background: var(--sf); border: 1px solid rgba(0,255,224,.1); padding: 32px; }
.fp.gp { border-color: rgba(245,197,24,.2); }
.fg { margin-bottom: 14px; }
.fl { font-size: .56rem; color: var(--mt); letter-spacing: .2em; text-transform: uppercase; margin-bottom: 6px; display: block; }
.fi { background: rgba(0,255,224,.03); border: 1px solid rgba(0,255,224,.15);
  color: var(--tx); padding: 10px 14px; font-family: 'Space Mono'; font-size: .7rem;
  outline: none; width: 100%; transition: border-color .2s; }
.fi:focus { border-color: var(--ac); }
.fi.gi { border-color: rgba(245,197,24,.2); }
.fi.gi:focus { border-color: var(--gd); }
.fi::placeholder { color: var(--mt); }
select.fi option { background: #020508; }
.rb { margin-top: 16px; background: rgba(0,255,224,.03); border: 1px solid rgba(0,255,224,.15);
  padding: 16px; font-size: .67rem; line-height: 2.2; display: none; }
.rb.show { display: block; }
.rb.gb { border-color: rgba(245,197,24,.2); background: rgba(245,197,24,.02); }
.rk { color: var(--mt); } .rv { color: var(--ac); }
.rv.gd { color: var(--gd); } .rv.g { color: #4ade80; }

/* WALLET GRID */
.wg { display: grid; grid-template-columns: repeat(5,1fr); gap: 2px; margin-bottom: 28px; }
.wc { background: var(--sf); border: 1px solid rgba(245,197,24,.12);
  padding: 22px 16px; text-align: center; cursor: pointer; transition: all .3s; position: relative; }
.wc:hover { border-color: rgba(245,197,24,.4); background: rgba(245,197,24,.04); }
.wc.sel { border-color: var(--gd); background: rgba(245,197,24,.06); }
.wc.sel::before { content: '✓'; position: absolute; top: 7px; right: 9px; font-size: .58rem; color: var(--gd); }
.wi { font-size: 1.9rem; margin-bottom: 7px; }
.wco { font-family: 'Bebas Neue'; font-size: 1.15rem; color: var(--gd); letter-spacing: .1em; }
.wna { font-size: .55rem; color: var(--mt); letter-spacing: .1em; margin-top: 2px; }
.wad { font-size: .46rem; color: rgba(58,85,112,.55); margin-top: 7px; word-break: break-all; line-height: 1.4; }

/* BUNDLE GRID */
.bg2 { display: grid; grid-template-columns: repeat(5,1fr); gap: 2px; margin-bottom: 22px; }
.bc { background: var(--sf); border: 1px solid rgba(0,255,224,.08);
  padding: 20px 14px; text-align: center; cursor: pointer; transition: all .3s; }
.bc:hover { border-color: rgba(0,255,224,.25); }
.bc.sel { border-color: var(--ac); background: rgba(0,255,224,.04); }
.bn { font-family: 'Bebas Neue'; font-size: 1rem; color: #fff; letter-spacing: .1em; }
.bdata { font-size: 1.3rem; color: var(--ac); font-family: 'Bebas Neue'; line-height: 1.1; }
.bprice { font-size: .6rem; color: var(--mt); margin-top: 4px; }
.bbtc { font-size: .56rem; color: var(--gd); margin-top: 2px; }

/* AIRBANK */
.vd { background: var(--sf); border: 1px solid rgba(0,255,224,.1); padding: 32px; margin-bottom: 2px; }
.vn { font-family: 'Bebas Neue'; font-size: 3.5rem; color: var(--ac); line-height: 1; text-shadow: 0 0 40px rgba(0,255,224,.3); }
.vu { font-size: .67rem; color: var(--mt); letter-spacing: .24em; text-transform: uppercase; margin-top: 4px; }
.rg { display: grid; grid-template-columns: repeat(3,1fr); gap: 2px; margin-bottom: 2px; }
.rc { background: var(--sf); border: 1px solid rgba(245,197,24,.1); padding: 26px; position: relative; }
.rc::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 1px;
  background: linear-gradient(90deg, transparent, var(--gd), transparent); }
.rn { font-family: 'Bebas Neue'; font-size: 2.3rem; color: var(--gd); line-height: 1; margin-bottom: 4px; }
.rl { font-size: .56rem; color: var(--mt); letter-spacing: .17em; text-transform: uppercase; }
.rs { font-size: .6rem; color: rgba(245,197,24,.5); margin-top: 4px; }

/* PROGRESS */
.pr { margin-bottom: 12px; }
.pl { display: flex; justify-content: space-between; font-size: .58rem; color: var(--mt); letter-spacing: .1em; margin-bottom: 5px; }
.pb { height: 4px; background: rgba(0,255,224,.08); border-radius: 2px; overflow: hidden; }
.pf { height: 100%; border-radius: 2px; background: linear-gradient(90deg, var(--ac2), var(--ac));
  animation: fb 2s ease forwards; transform-origin: left; }
@keyframes fb { from { transform: scaleX(0); } to { transform: scaleX(1); } }
.pf.gd { background: linear-gradient(90deg, var(--gd2), var(--gd)); }
.pf.r { background: linear-gradient(90deg, var(--ac3), #ff9a6c); }

/* TABLE */
.dt { width: 100%; border-collapse: collapse; font-size: .64rem; }
.dt th { color: var(--mt); letter-spacing: .14em; text-transform: uppercase; font-size: .54rem;
  padding: 9px 13px; text-align: left; border-bottom: 1px solid rgba(0,255,224,.08); }
.dt td { padding: 9px 13px; border-bottom: 1px solid rgba(255,255,255,.03); color: var(--tx); }
.dt tr:hover td { background: rgba(0,255,224,.02); }
.bdg { display: inline-block; padding: 2px 8px; font-size: .5rem; letter-spacing: .1em;
  text-transform: uppercase; border-radius: 2px; }
.bg3 { background: rgba(0,255,224,.1); color: var(--ac); border: 1px solid rgba(0,255,224,.2); }
.bgd { background: rgba(245,197,24,.1); color: var(--gd); border: 1px solid rgba(245,197,24,.2); }
.br { background: rgba(255,77,109,.1); color: var(--ac3); border: 1px solid rgba(255,77,109,.2); }

/* LOG FEED */
.lf { background: var(--sf); border: 1px solid rgba(0,255,224,.08); padding: 20px; min-height: 260px; }
.le { display: flex; gap: 12px; padding: 8px 0; border-bottom: 1px solid rgba(255,255,255,.03);
  animation: fi .4s ease; }
@keyframes fi { from { opacity: 0; transform: translateX(-8px); } to { opacity: 1; transform: none; } }
.ld { width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; margin-top: 5px; }
.lg { background: var(--ac); box-shadow: 0 0 8px var(--ac); }
.lb { background: var(--ac2); box-shadow: 0 0 8px var(--ac2); }
.lr { background: var(--ac3); box-shadow: 0 0 8px var(--ac3); }
.lgd { background: var(--gd); box-shadow: 0 0 8px var(--gd); }
.lt { font-size: .62rem; line-height: 1.7; color: var(--mt); }
.lt strong { color: var(--tx); font-weight: 400; }
.ltm { font-size: .54rem; color: rgba(58,85,112,.5); display: block; margin-top: 1px; }

/* SVG MAP */
.mc { width: 100%; height: 230px; position: relative; margin-top: 18px; }
.ms { width: 100%; height: 100%; }

/* HIGHLIGHT BOX */
.hb { background: rgba(245,197,24,.04); border: 1px solid rgba(245,197,24,.2);
  padding: 18px 22px; margin-bottom: 22px; }
.hb p { font-size: .7rem; line-height: 1.9; color: var(--tx); }
.hb strong { color: var(--gd); }

/* CALC DISPLAY */
.cd { background: #000; border: 1px solid rgba(245,197,24,.2); padding: 18px;
  font-family: 'Bebas Neue'; font-size: 1.8rem; color: var(--gd);
  text-align: right; letter-spacing: .1em; min-height: 64px; margin-bottom: 14px; }
.cd .cs { font-size: .76rem; color: rgba(245,197,24,.5); font-family: 'Space Mono'; }

.copy-btn { background: rgba(245,197,24,.08); border: 1px solid rgba(245,197,24,.2);
  color: var(--gd); padding: 4px 12px; font-size: .56rem; cursor: pointer;
  font-family: 'Space Mono'; letter-spacing: .1em; transition: all .2s; }
.copy-btn:hover { background: rgba(245,197,24,.18); }

.div { border: none; border-top: 1px solid rgba(0,255,224,.06); margin: 36px 0; }
.tc { display: grid; grid-template-columns: 1fr 1fr; gap: 2px; }
.thc { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 2px; }

/* FOOTER */
footer { border-top: 1px solid rgba(0,255,224,.06); padding: 30px 40px;
  display: flex; align-items: center; justify-content: space-between;
  max-width: 1300px; margin: 0 auto; }
.fl2 { font-family: 'Bebas Neue'; font-size: 1.2rem; color: var(--mt); letter-spacing: .25em; }
.fc { font-size: .54rem; color: rgba(58,85,112,.5); letter-spacing: .1em; }
.fs { display: flex; align-items: center; gap: 8px; font-size: .58rem; color: var(--ac); letter-spacing: .15em; }

@media (max-width: 900px) {
  .hero { grid-template-columns: 1fr; }
  .gw { height: 270px; } .globe { width: 220px; height: 220px; }
  .o1 { width: 280px; height: 280px; } .o2 { width: 350px; height: 350px; }
  .sr { grid-template-columns: repeat(2,1fr); }
  .cg { grid-template-columns: 1fr; }
  .wg { grid-template-columns: repeat(2,1fr); }
  .bg2 { grid-template-columns: repeat(2,1fr); }
  .rg { grid-template-columns: 1fr; }
  .tc { grid-template-columns: 1fr; }
  .thc { grid-template-columns: 1fr; }
  .nl { display: none; }
  nav { padding: 12px 18px; }
  .sec { padding: 40px 18px; }
}




&lt;p&gt;AIRTIMES&lt;br&gt;
  &lt;/p&gt;
&lt;ul&gt;

    &lt;li&gt;&lt;a&gt;Network&lt;/a&gt;&lt;/li&gt;

    &lt;li&gt;&lt;a&gt;Services&lt;/a&gt;&lt;/li&gt;

    &lt;li&gt;&lt;a&gt;Nodes&lt;/a&gt;&lt;/li&gt;

    &lt;li&gt;&lt;a&gt;₿ AirPay&lt;/a&gt;&lt;/li&gt;

    &lt;li&gt;&lt;a&gt;🏦 AirBank&lt;/a&gt;&lt;/li&gt;

    &lt;li&gt;&lt;a&gt;👑 Owner&lt;/a&gt;&lt;/li&gt;

  &lt;/ul&gt;
&lt;br&gt;
  &lt;span id="nst"&gt;CONNECTING...&lt;/span&gt;

&lt;p&gt;🌐 Home&lt;br&gt;
  ⚡ Services&lt;br&gt;
  🔗 Connect&lt;br&gt;
  ◯ Nodes&lt;br&gt;
  📡 Route&lt;br&gt;
  ₿ AirPay&lt;br&gt;
  🏦 AirBank&lt;br&gt;
  👑 Owner Dashboard&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  Global Data Mesh — v3.2.0
  &amp;lt;h1&amp;gt;FREE&amp;lt;br&amp;gt;&amp;lt;span&amp;gt;DATA&amp;lt;/span&amp;gt; &amp;amp;amp;&amp;lt;br&amp;gt;&amp;lt;span&amp;gt;SERVICE&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&amp;lt;span&amp;gt;NETWORK&amp;lt;/span&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;AIRTIMES delivers free data, connectivity, and digital services to every node on Earth. Users connect free. Owner earns automatically via AirPay crypto payments and AirBank data revenue — around the clock.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    GET FREE ACCESS
    ₿ BUY DATA BUNDLE
    🏦 AirBank







  ▲ 4,700 Gbps THROUGHPUT
  ◯ 142 ACTIVE NODES
  ₿ AUTO-EARNING ACTIVE





&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;AIRDATA FREE TIER ACTIVE
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;AIRBANK — $0.0024 REVENUE LOGGED
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;NAIROBI NODE ONLINE
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;AIRPAY — BTC PAYMENT RECEIVED
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;2.1M USERS CONNECTED
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;AIRBANK VAULT — 842 TB STORED
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;JAKARTA HUB — 340 Gbps
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;AUTO-REVENUE TICKING EVERY SESSION
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;AIRTIMES PROTOCOL v3.2 LIVE
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;AIRPAY — ETH BUNDLE CONFIRMED
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;AIRDATA FREE TIER ACTIVE
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;AIRBANK — $0.0024 REVENUE LOGGED
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;NAIROBI NODE ONLINE
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;AIRPAY — BTC PAYMENT RECEIVED
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;2.1M USERS CONNECTED
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;AIRBANK VAULT — 842 TB STORED
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;JAKARTA HUB — 340 Gbps
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;AUTO-REVENUE TICKING EVERY SESSION
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;AIRTIMES PROTOCOL v3.2 LIVE
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;AIRPAY — ETH BUNDLE CONFIRMED




—Active Nodes Worldwide
—Daily Data Delivered (TB)
—Users Served Free
—Auto Revenue Earned (USD)



// Three Systems · One Network
HOW AIRTIMES WORKS


    🌐
    Free Global Network
    Users connect free worldwide via AirData, AirSMS, AirWeb, AirVault, AirAPI, AirRelay. Zero cost to users forever. Powered by surplus bandwidth redistribution across 142+ global nodes.
    FREE FOR ALL USERS


    ₿
    AirPay — Crypto Payments
    Users buy premium data bundles using Bitcoin, Ethereum, USDT, BNB, or Litecoin. Every payment routes directly to the owner's crypto wallet instantly. No middleman, no processor fees.
    BTC · ETH · USDT · BNB · LTC


    🏦
    AirBank — Auto Revenue Engine
    Every byte transmitted earns the owner automatically. Trillions of AirUnits stored in the vault, converted to direct money on every user session. Earn while you sleep.
    EARN AUTOMATICALLY







    📋 Live Network Events


    💰 Revenue Snapshot
    Loading revenue data...
    VIEW FULL OWNER DASHBOARD →









// All Free + Paid Services
WHAT AIRTIMES PROVIDES

  📡AirData — Free Mobile DataZero-cost mobile internet routing through the AIRTIMES mesh. Any device, any carrier, any country. Bandwidth pooled from surplus commercial nodes globally.FREE · UNLIMITED
  💬AirSMS — Global MessagingEnd-to-end encrypted SMS and voice relay across all 193 countries. Delivered free via spare spectrum on partner networks. Auto-revenue for owner per SMS.FREE · E2E ENCRYPTED
  🌐AirWeb — Open BrowserCompressed web proxy serving the full open internet at zero data cost. Optimized for low-bandwidth environments and offline caching. Up to 70% compression ratio.FREE · COMPRESSED
  🔗AirAPI — Open Data GatewayFree access to global datasets: weather, finance, health, transport. 50,000 requests/day per node. Developer-grade REST and WebSocket access.FREE · 50K RPD
  🛰AirRelay — Satellite FallbackWhen ground infrastructure fails, AIRTIMES auto-routes through low-earth-orbit relay partners to maintain continuous free connectivity globally.RESILIENT · AUTO
  💾AirVault — Distributed Storage5 GB of free distributed cloud storage per user. Sharded across 8+ geo-regions for redundancy. Served at zero cost from network surplus capacity.FREE · 5 GB
  ₿AirPay — Crypto Payment GatewayUsers buy premium data bundles with Bitcoin, Ethereum, USDT, BNB, or Litecoin. Payments go directly to the owner's wallet. No middleman. Instant settlement.BTC · ETH · USDT · BNB · LTC
  🏦AirBank — Auto Revenue EngineEvery user session generates automatic revenue for the owner. Trillions of AirUnits stored and converted to direct money. Revenue from data, SMS, API, storage.AUTO REVENUE
  🗺AirRoute — Smart Mesh RoutingDijkstra mesh routing with Haversine geo-scoring. Auto-failover. Multi-hop path optimization. Load rebalancing every 30 seconds across all nodes.AI ROUTING








// Free Access
JOIN THE NETWORK
&amp;lt;p&amp;gt;Register your phone or email to get a free AIRTIMES token. Instantly connected to 142+ nodes worldwide. No credit card. No contracts. Forever free.&amp;lt;/p&amp;gt;


    Phone or Email

    Identifier Type
      EmailPhone
    ACTIVATE FREE ACCESS →
    &amp;lt;span&amp;gt;Fill in your details and click activate.&amp;lt;/span&amp;gt;


    What you get FREE:

      ✦ AirData — Unlimited free mobile internet&amp;lt;br&amp;gt;
      ✦ AirSMS — Global encrypted messaging&amp;lt;br&amp;gt;
      ✦ AirWeb — Compressed web proxy&amp;lt;br&amp;gt;
      ✦ AirAPI — 50,000 free API calls/day&amp;lt;br&amp;gt;
      ✦ AirVault — 5 GB free cloud storage&amp;lt;br&amp;gt;
      ✦ AirRelay — Satellite connectivity fallback&amp;lt;br&amp;gt;
      ✦ Assigned to nearest global mesh node&amp;lt;br&amp;gt;
      ✦ 10 GB daily data quota&amp;lt;br&amp;gt;

    &amp;lt;hr&amp;gt;
    Want more data? &amp;lt;span&amp;gt;Buy a premium bundle with crypto via AirPay →&amp;lt;/span&amp;gt;


&amp;lt;hr&amp;gt;
// Free API Test
AIRAPI GATEWAY


    City (Free Weather)

    GET FREE WEATHER →
    Exchange Rate



        GET RATE


    &amp;lt;span&amp;gt;Results appear here — all free, no API key needed.&amp;lt;/span&amp;gt;


    🌐 AirAPI Specs

      ● &amp;lt;span&amp;gt;50,000&amp;lt;/span&amp;gt; free calls/day per node&amp;lt;br&amp;gt;
      ● Weather data for all cities worldwide&amp;lt;br&amp;gt;
      ● Live exchange rates (150+ currencies)&amp;lt;br&amp;gt;
      ● Health, transport, finance datasets&amp;lt;br&amp;gt;
      ● REST + WebSocket endpoints&amp;lt;br&amp;gt;
      ● No API key needed for free tier&amp;lt;br&amp;gt;
      ● Each call auto-earns revenue for owner&amp;lt;br&amp;gt;










// Mesh Routing Engine
TEST YOUR ROUTE
&amp;lt;p&amp;gt;Enter your token and destination to compute the optimal mesh path through AIRTIMES global nodes using Haversine geo-scoring and Dijkstra path finding.&amp;lt;/p&amp;gt;


    Your Token (from registration)

    Destination

    Service

        AirDataAirSMSAirWeb
        AirAPIAirVaultAirRelay

    COMPUTE ROUTE →


    Run a route test to see your full mesh path, latency estimate, hop count, and protocol details.









// Global Infrastructure
LIVE NODE MAP

  &amp;lt;svg&amp;gt;
    &amp;lt;line x1="0" y1="80" x2="900" y2="80" stroke="" stroke-width="1"&amp;gt;&amp;lt;/line&amp;gt;
    &amp;lt;line x1="0" y1="160" x2="900" y2="160" stroke="" stroke-width="1"&amp;gt;&amp;lt;/line&amp;gt;
    &amp;lt;line x1="225" y1="0" x2="225" y2="240" stroke="" stroke-width="1"&amp;gt;&amp;lt;/line&amp;gt;
    &amp;lt;line x1="450" y1="0" x2="450" y2="240" stroke="" stroke-width="1"&amp;gt;&amp;lt;/line&amp;gt;
    &amp;lt;line x1="675" y1="0" x2="675" y2="240" stroke="" stroke-width="1"&amp;gt;&amp;lt;/line&amp;gt;
    &amp;lt;g stroke="" stroke-width="1" fill="none"&amp;gt;
      &amp;lt;line x1="80" y1="90" x2="200" y2="70"&amp;gt;&amp;lt;/line&amp;gt;&amp;lt;line x1="200" y1="70" x2="340" y2="100"&amp;gt;&amp;lt;/line&amp;gt;
      &amp;lt;line x1="340" y1="100" x2="480" y2="80"&amp;gt;&amp;lt;/line&amp;gt;&amp;lt;line x1="480" y1="80" x2="600" y2="110"&amp;gt;&amp;lt;/line&amp;gt;
      &amp;lt;line x1="600" y1="110" x2="740" y2="90"&amp;gt;&amp;lt;/line&amp;gt;&amp;lt;line x1="740" y1="90" x2="840" y2="100"&amp;gt;&amp;lt;/line&amp;gt;
      &amp;lt;line x1="200" y1="70" x2="280" y2="150"&amp;gt;&amp;lt;/line&amp;gt;&amp;lt;line x1="480" y1="80" x2="520" y2="170"&amp;gt;&amp;lt;/line&amp;gt;
      &amp;lt;line x1="600" y1="110" x2="580" y2="180"&amp;gt;&amp;lt;/line&amp;gt;&amp;lt;line x1="80" y1="90" x2="120" y2="180"&amp;gt;&amp;lt;/line&amp;gt;
    &amp;lt;/g&amp;gt;
    &amp;lt;circle r="3" fill=""&amp;gt;&amp;lt;path d="M80,90 L200,70 L340,100 L480,80 L600,110 L740,90 L840,100"&amp;gt;&amp;lt;/path&amp;gt;&amp;lt;/circle&amp;gt;
    &amp;lt;circle r="2.5" fill=""&amp;gt;&amp;lt;path d="M840,100 L740,90 L600,110 L480,80 L340,100 L200,70 L80,90"&amp;gt;&amp;lt;/path&amp;gt;&amp;lt;/circle&amp;gt;
    &amp;lt;g&amp;gt;
      &amp;lt;circle cx="80" cy="90" r="9" fill="" stroke="" stroke-width="1.5"&amp;gt;&amp;lt;/circle&amp;gt;&amp;lt;circle cx="80" cy="90" r="3.5" fill="#00ffe0"&amp;gt;&amp;lt;/circle&amp;gt;NYC
      &amp;lt;circle cx="200" cy="70" r="10" fill="" stroke="" stroke-width="1.5"&amp;gt;&amp;lt;/circle&amp;gt;&amp;lt;circle cx="200" cy="70" r="4" fill="#00ffe0"&amp;gt;&amp;lt;/circle&amp;gt;LDN
      &amp;lt;circle cx="340" cy="100" r="7" fill="" stroke="" stroke-width="1.5"&amp;gt;&amp;lt;/circle&amp;gt;&amp;lt;circle cx="340" cy="100" r="3" fill="#0077ff"&amp;gt;&amp;lt;/circle&amp;gt;NBI
      &amp;lt;circle cx="480" cy="80" r="9" fill="" stroke="" stroke-width="1.5"&amp;gt;&amp;lt;/circle&amp;gt;&amp;lt;circle cx="480" cy="80" r="4" fill="#f5c518"&amp;gt;&amp;lt;/circle&amp;gt;DXB
      &amp;lt;circle cx="600" cy="110" r="8" fill="" stroke="" stroke-width="1.5"&amp;gt;&amp;lt;/circle&amp;gt;&amp;lt;circle cx="600" cy="110" r="3.5" fill="#ff4d6d"&amp;gt;&amp;lt;/circle&amp;gt;JKT
      &amp;lt;circle cx="740" cy="90" r="9" fill="" stroke="" stroke-width="1.5"&amp;gt;&amp;lt;/circle&amp;gt;&amp;lt;circle cx="740" cy="90" r="4" fill="#00ffe0"&amp;gt;&amp;lt;/circle&amp;gt;TYO
      &amp;lt;circle cx="840" cy="100" r="7" fill="" stroke="" stroke-width="1"&amp;gt;&amp;lt;/circle&amp;gt;&amp;lt;circle cx="840" cy="100" r="3" fill="#00ffe0"&amp;gt;&amp;lt;/circle&amp;gt;SYD
      &amp;lt;circle cx="120" cy="180" r="5" fill="" stroke="" stroke-width="1"&amp;gt;&amp;lt;/circle&amp;gt;&amp;lt;circle cx="120" cy="180" r="2" fill="#0077ff"&amp;gt;&amp;lt;/circle&amp;gt;GRU
      &amp;lt;circle cx="520" cy="170" r="5" fill="" stroke="" stroke-width="1"&amp;gt;&amp;lt;/circle&amp;gt;&amp;lt;circle cx="520" cy="170" r="2" fill="#0077ff"&amp;gt;&amp;lt;/circle&amp;gt;BOM
      &amp;lt;circle cx="580" cy="180" r="5" fill="" stroke="" stroke-width="1"&amp;gt;&amp;lt;/circle&amp;gt;&amp;lt;circle cx="580" cy="180" r="2" fill="#ff4d6d"&amp;gt;&amp;lt;/circle&amp;gt;SIN
      &amp;lt;circle cx="660" cy="50" r="6" fill="" stroke="" stroke-width="1"&amp;gt;&amp;lt;/circle&amp;gt;&amp;lt;circle cx="660" cy="50" r="2.5" fill="#0077ff"&amp;gt;&amp;lt;/circle&amp;gt;SHA
      &amp;lt;circle cx="155" cy="105" r="5" fill="" stroke="" stroke-width="1"&amp;gt;&amp;lt;/circle&amp;gt;&amp;lt;circle cx="155" cy="105" r="2" fill="#f5c518"&amp;gt;&amp;lt;/circle&amp;gt;LOS
    &amp;lt;/g&amp;gt;
  &amp;lt;/svg&amp;gt;

&amp;lt;table id="nodes-table"&amp;gt;
  &amp;lt;thead&amp;gt;&amp;lt;tr&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

Node ID
&lt;br&gt;
City
&lt;br&gt;
Country
&lt;br&gt;
Operator
&lt;br&gt;
Capacity (Gbps)
&lt;br&gt;
Load
&lt;br&gt;
Status
&lt;br&gt;
&lt;br&gt;
      Loading nodes...
&lt;br&gt;
    
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Bitcoin &amp;amp;amp; Crypto Payment Gateway
₿ AIRPAY

  &amp;lt;p&amp;gt;AirPay lets users buy premium data bundles using &amp;lt;strong&amp;gt;Bitcoin, Ethereum, USDT, BNB, or Litecoin&amp;lt;/strong&amp;gt;. Every payment goes &amp;lt;strong&amp;gt;directly to the AIRTIMES owner's crypto wallet&amp;lt;/strong&amp;gt; — instantly, no middleman, zero processor fees. Select a bundle, choose your crypto, and send payment to the displayed address.&amp;lt;/p&amp;gt;


// Owner Wallet Addresses — All Payments Are Sent Directly Here


&amp;lt;hr&amp;gt;
// Select Your Data Bundle
Choose how much premium data you want to purchase:




    ⚡ Generate Payment Address
    Your User ID (optional)

    Pay With

        ₿ Bitcoin (BTC)
        Ξ Ethereum (ETH)
        ₮ Tether USDT (TRC-20)
        ⬡ BNB Coin
        Ł Litecoin (LTC)

    GENERATE PAYMENT ADDRESS →
    &amp;lt;span&amp;gt;Select a bundle above, then click to generate your payment address.&amp;lt;/span&amp;gt;


    📋 How AirPay Works

      &amp;lt;span&amp;gt;Step 1.&amp;lt;/span&amp;gt; Select a data bundle above&amp;lt;br&amp;gt;
      &amp;lt;span&amp;gt;Step 2.&amp;lt;/span&amp;gt; Choose Bitcoin, ETH, USDT, BNB, or LTC&amp;lt;br&amp;gt;
      &amp;lt;span&amp;gt;Step 3.&amp;lt;/span&amp;gt; Click "Generate Payment Address"&amp;lt;br&amp;gt;
      &amp;lt;span&amp;gt;Step 4.&amp;lt;/span&amp;gt; Send exact crypto amount shown&amp;lt;br&amp;gt;
      &amp;lt;span&amp;gt;Step 5.&amp;lt;/span&amp;gt; Bundle activates in 10–60 minutes&amp;lt;br&amp;gt;
      &amp;lt;span&amp;gt;Step 6.&amp;lt;/span&amp;gt; Revenue automatically in owner wallet&amp;lt;br&amp;gt;

    &amp;lt;hr&amp;gt;
    All payments go directly to owner's crypto wallets. No processor. No fees. Direct blockchain settlement.



&amp;lt;hr&amp;gt;
// Confirm Your Payment


    Payment ID

    Transaction Hash (TX Hash from blockchain)

    CONFIRM PAYMENT →
    &amp;lt;span&amp;gt;Enter Payment ID + TX hash to confirm your purchase.&amp;lt;/span&amp;gt;


    After sending crypto, paste your &amp;lt;span&amp;gt;Payment ID&amp;lt;/span&amp;gt; and the &amp;lt;span&amp;gt;transaction hash&amp;lt;/span&amp;gt; from your wallet or blockchain explorer. Data bundle activates immediately upon confirmation.









// Data Storage &amp;amp;amp; Automatic Revenue Engine
🏦 AIRBANK

  &amp;lt;p&amp;gt;AirBank is the &amp;lt;strong&amp;gt;financial backbone of AIRTIMES&amp;lt;/strong&amp;gt;. Every byte of data transmitted through the network is stored in the AirBank Vault measured in &amp;lt;strong&amp;gt;Trillions of AirUnits&amp;lt;/strong&amp;gt;. When users browse, message, stream, or use any AIRTIMES service — the owner &amp;lt;strong&amp;gt;earns money automatically&amp;lt;/strong&amp;gt;, around the clock. Data is the currency. Usage is the revenue. Extract data, convert to direct money.&amp;lt;/p&amp;gt;





    Vault Storage
    —
    Total AirUnits Stored


    Data Transmitted
    —
    GB Delivered to Users


    Total Revenue Earned
    —
    USD Earned Automatically






    Per GB Transmitted
    $0.002
    Every 1 GB routed = $0.002 earned by owner


    Per Active User / Day
    $0.001
    Every daily user session earns automatically


    Per API Call
    $0.00005
    Every AirAPI request generates revenue



&amp;lt;hr&amp;gt;
// Data → Money Calculator
Enter any amount of stored/transmitted data to see the revenue it generates for the owner:


    $ 0.00Enter amount below to calculate




          GBTBPB



    &amp;lt;span&amp;gt;Enter data amount above to calculate automatic revenue.&amp;lt;/span&amp;gt;


    📈 Revenue Sources Breakdown
    &amp;lt;span&amp;gt;Data Transmission&amp;lt;/span&amp;gt;&amp;lt;span id="pct1"&amp;gt;42%&amp;lt;/span&amp;gt;
    &amp;lt;span&amp;gt;Active Users (Daily)&amp;lt;/span&amp;gt;&amp;lt;span id="pct2"&amp;gt;24%&amp;lt;/span&amp;gt;
    &amp;lt;span&amp;gt;AirPay Bundles&amp;lt;/span&amp;gt;&amp;lt;span id="pct3"&amp;gt;18%&amp;lt;/span&amp;gt;
    &amp;lt;span&amp;gt;API Calls&amp;lt;/span&amp;gt;&amp;lt;span id="pct4"&amp;gt;9%&amp;lt;/span&amp;gt;
    &amp;lt;span&amp;gt;Storage Fees&amp;lt;/span&amp;gt;&amp;lt;span id="pct5"&amp;gt;5%&amp;lt;/span&amp;gt;
    &amp;lt;span&amp;gt;SMS Revenue&amp;lt;/span&amp;gt;&amp;lt;span id="pct6"&amp;gt;2%&amp;lt;/span&amp;gt;









// Private Owner Control Panel
👑 OWNER DASHBOARD

  &amp;lt;p&amp;gt;This is your &amp;lt;strong&amp;gt;private revenue command center&amp;lt;/strong&amp;gt;. See every dollar earned, every AirPay payment received, every data unit transmitted. &amp;lt;strong&amp;gt;Set your Bitcoin and crypto wallet addresses below&amp;lt;/strong&amp;gt; — all AirPay payments route directly to these wallets instantly. You own the network. You own the revenue.&amp;lt;/p&amp;gt;



// ₿ Your Crypto Wallet Addresses
Enter your real wallet addresses here. Users see these when paying via AirPay. All payments land directly in your wallets.


    ₿ Bitcoin (BTC) Wallet Address

    Ξ Ethereum (ETH) Wallet Address

    ₮ USDT Wallet (TRC-20 / Tron Network)

    ⬡ BNB Wallet Address

    Ł Litecoin (LTC) Wallet Address


      SAVE WALLET ADDRESSES →



    &amp;lt;span&amp;gt;Enter your real wallet addresses and click Save. These will be shown to users on the AirPay page. For production, set as environment variables on your backend server.&amp;lt;/span&amp;gt;




// Revenue Summary

  Total Earned (USD)$—— BTC
  Projected Monthly$—Based on current daily rate
  Revenue Events Logged—Auto-logged transactions




    Revenue by Source
    Loading...


    Daily Revenue (Last 7 Days)
    Loading...





  AirPay Payment History
  &amp;lt;table&amp;gt;
    &amp;lt;thead&amp;gt;&amp;lt;tr&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

Payment ID
&lt;br&gt;
Bundle
&lt;br&gt;
Coin
&lt;br&gt;
Amount
&lt;br&gt;
Status
&lt;br&gt;
Date
&lt;br&gt;
&lt;br&gt;
        No payments yet. Share your AirPay page with users to start receiving crypto payments!
&lt;br&gt;
      
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;hr&amp;gt;
// Network Control


    Registered Users
    —
    Total on network


    Active Nodes
    —
    Online globally


    Data Routed Today
    —
    GB transmitted
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;AIRTIMES&lt;br&gt;
  © 2025 AIRTIMES GLOBAL NETWORK · AirPay · AirBank · All Services Free · All Rights Universal&lt;br&gt;
  ALL SYSTEMS OPERATIONAL&lt;/p&gt;

&amp;lt;!-- /shell --&amp;gt;


/* ===== CONFIG ===== */
const API = (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1')
  ? 'http://localhost:3001' : '';

/* ===== WALLET STATE (saved in localStorage) ===== */
let WALLETS = {
  BTC:  localStorage.getItem('w_BTC')  || '',
  ETH:  localStorage.getItem('w_ETH')  || '',
  USDT: localStorage.getItem('w_USDT') || '',
  BNB:  localStorage.getItem('w_BNB')  || '',
  LTC:  localStorage.getItem('w_LTC')  || ''
};

const COIN_ICONS = { BTC:'&amp;amp;#8383;', ETH:'&amp;amp;#926;', USDT:'&amp;amp;#8366;', BNB:'&amp;amp;#11041;', LTC:'&amp;amp;#321;' };
const COIN_NAMES = { BTC:'Bitcoin', ETH:'Ethereum', USDT:'Tether TRC-20', BNB:'BNB Coin', LTC:'Litecoin' };
const COIN_RATES = { BTC:0.0000155, ETH:0.000290, USDT:1.0, BNB:0.00310, LTC:0.0120 };

const BUNDLES = [
  { id:'starter',   name:'Starter',   gb:5,    usd:0.50,  btc:'0.000010' },
  { id:'basic',     name:'Basic',     gb:20,   usd:1.99,  btc:'0.000038' },
  { id:'standard',  name:'Standard',  gb:100,  usd:7.99,  btc:'0.000150' },
  { id:'pro',       name:'Pro',       gb:500,  usd:29.99, btc:'0.000600' },
  { id:'unlimited', name:'Unlimited', gb:9999, usd:74.99, btc:'0.001500' }
];

let selBundle = null;

/* ===== PAGE SWITCHER ===== */
function P(id) {
  document.querySelectorAll('.page').forEach(p =&amp;gt; p.classList.remove('active'));
  document.querySelectorAll('.tab').forEach(t =&amp;gt; t.classList.remove('active'));
  const pg = document.getElementById('page-' + id);
  if (pg) pg.classList.add('active');
  document.querySelectorAll('.tab').forEach(t =&amp;gt; {
    if (t.getAttribute('onclick') &amp;amp;&amp;amp; t.getAttribute('onclick').includes("'" + id + "'")) t.classList.add('active');
  });
  window.scrollTo({ top: 0, behavior: 'smooth' });
  if (id === 'airpay')  renderAirPay();
  if (id === 'airbank') loadVault();
  if (id === 'owner')   loadOwner();
  if (id === 'nodes')   loadNodes();
}

/* ===== HELPERS ===== */
function fmt(n) { return Number(n).toLocaleString(); }
function ac(el, target, sfx, dur) {
  if (!el) return;
  sfx = sfx || ''; dur = dur || 2000;
  let v = 0; const step = target / (dur / 16);
  const t = setInterval(function() {
    v += step;
    if (v &amp;gt;= target) { v = target; clearInterval(t); }
    el.textContent = Math.floor(v).toLocaleString() + sfx;
  }, 16);
}
function uid() {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
    var r = Math.random() * 16 | 0;
    return (c === 'x' ? r : (r &amp;amp; 0x3 | 0x8)).toString(16);
  });
}

/* ===== LOAD STATS ===== */
async function loadStats() {
  try {
    const r = await fetch(API + '/api/stats');
    const d = await r.json();
    document.getElementById('nst').textContent = 'ALL SYSTEMS OPERATIONAL';
    ac(document.getElementById('s1'), d.activeNodes || 142);
    ac(document.getElementById('s2'), d.dataTB || 4700, ' TB');
    ac(document.getElementById('s3'), d.totalUsers || 2100000);
    try {
      const rv = await fetch(API + '/api/airbank/revenue');
      const rd = await rv.json();
      const tot = parseFloat(rd.summary &amp;amp;&amp;amp; rd.summary.totalUSD ? rd.summary.totalUSD : '3.47');
      document.getElementById('s4').textContent = '$' + tot.toFixed(2);
      const rs = document.getElementById('rev-snap');
      if (rs) rs.innerHTML =
        '&amp;lt;div&amp;gt;&amp;lt;span style="color:var(--mt)"&amp;gt;Total USD Earned: &amp;lt;/span&amp;gt;&amp;lt;span style="color:var(--gd)"&amp;gt;$' + (rd.summary ? parseFloat(rd.summary.totalUSD).toFixed(4) : '3.4700') + '&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
        '&amp;lt;div&amp;gt;&amp;lt;span style="color:var(--mt)"&amp;gt;In Bitcoin: &amp;lt;/span&amp;gt;&amp;lt;span style="color:var(--gd)"&amp;gt;' + (rd.summary ? rd.summary.totalBTC : '0.00005378') + ' BTC&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
        '&amp;lt;div&amp;gt;&amp;lt;span style="color:var(--mt)"&amp;gt;Projected Monthly: &amp;lt;/span&amp;gt;&amp;lt;span style="color:var(--gd)"&amp;gt;$' + (rd.summary ? rd.summary.projectedMonthlyUSD : '104.10') + '&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
        '&amp;lt;div&amp;gt;&amp;lt;span style="color:var(--mt)"&amp;gt;Revenue Events: &amp;lt;/span&amp;gt;&amp;lt;span style="color:var(--ac)"&amp;gt;' + fmt(rd.summary ? rd.summary.totalEvents : 200) + '&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;';
    } catch(e) { setDemoRevSnap(); }
  } catch(e) {
    document.getElementById('nst').textContent = 'DEMO MODE';
    ac(document.getElementById('s1'), 142);
    ac(document.getElementById('s2'), 4700, ' TB');
    ac(document.getElementById('s3'), 2100000);
    document.getElementById('s4').textContent = '$3.47';
    setDemoRevSnap();
  }
}

function setDemoRevSnap() {
  const rs = document.getElementById('rev-snap');
  if (!rs) return;
  rs.innerHTML = '&amp;lt;div&amp;gt;&amp;lt;span style="color:var(--mt)"&amp;gt;Total USD: &amp;lt;/span&amp;gt;&amp;lt;span style="color:var(--gd)"&amp;gt;$3.47 (Demo)&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
    '&amp;lt;div&amp;gt;&amp;lt;span style="color:var(--mt)"&amp;gt;Bitcoin: &amp;lt;/span&amp;gt;&amp;lt;span style="color:var(--gd)"&amp;gt;0.00005378 BTC&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
    '&amp;lt;div&amp;gt;&amp;lt;span style="color:var(--mt)"&amp;gt;Monthly Proj: &amp;lt;/span&amp;gt;&amp;lt;span style="color:var(--gd)"&amp;gt;$104.10&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
    '&amp;lt;div&amp;gt;&amp;lt;span style="color:var(--mt)"&amp;gt;Events: &amp;lt;/span&amp;gt;&amp;lt;span style="color:var(--ac)"&amp;gt;200 logged&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;';
}

/* ===== LOAD NODES ===== */
const DEMO_NODES = [
  {id:'NODE-US-NYC01',city:'New York',   country:'US',operator:'AT&amp;amp;T Surplus',     capacity_gbps:2100,load_percent:52},
  {id:'NODE-GB-LDN01',city:'London',    country:'GB',operator:'BT Wholesale',      capacity_gbps:3400,load_percent:45},
  {id:'NODE-KE-NBI01',city:'Nairobi',   country:'KE',operator:'Safaricom',         capacity_gbps:880, load_percent:78},
  {id:'NODE-AE-DXB01',city:'Dubai',     country:'AE',operator:'Etisalat',          capacity_gbps:1200,load_percent:60},
  {id:'NODE-ID-JKT01',city:'Jakarta',   country:'ID',operator:'Telkom ID',         capacity_gbps:340, load_percent:88},
  {id:'NODE-JP-TYO01',city:'Tokyo',     country:'JP',operator:'NTT Com',           capacity_gbps:2900,load_percent:41},
  {id:'NODE-AU-SYD01',city:'Sydney',    country:'AU',operator:'Telstra',           capacity_gbps:760, load_percent:33},
  {id:'NODE-BR-GRU01',city:'Sao Paulo', country:'BR',operator:'Vivo',              capacity_gbps:640, load_percent:55},
  {id:'NODE-ZA-CPT01',city:'Cape Town', country:'ZA',operator:'MTN SA',            capacity_gbps:420, load_percent:29},
  {id:'NODE-IN-BOM01',city:'Mumbai',    country:'IN',operator:'Airtel',            capacity_gbps:980, load_percent:71},
  {id:'NODE-SG-SIN01',city:'Singapore', country:'SG',operator:'Singtel',           capacity_gbps:1800,load_percent:66},
  {id:'NODE-NG-LOS01',city:'Lagos',     country:'NG',operator:'MTN Nigeria',       capacity_gbps:320, load_percent:82},
  {id:'NODE-DE-BER01',city:'Berlin',    country:'DE',operator:'Deutsche Telekom',  capacity_gbps:1600,load_percent:38},
  {id:'NODE-CN-SHA01',city:'Shanghai',  country:'CN',operator:'China Telecom',     capacity_gbps:2200,load_percent:59},
  {id:'NODE-MX-MEX01',city:'Mexico City',country:'MX',operator:'Telmex',          capacity_gbps:560, load_percent:44}
];

async function loadNodes() {
  try {
    const r = await fetch(API + '/api/nodes');
    const d = await r.json();
    renderNodes(d.nodes || DEMO_NODES);
  } catch(e) { renderNodes(DEMO_NODES); }
}

function renderNodes(nodes) {
  const tb = document.getElementById('nodes-body');
  if (!tb) return;
  tb.innerHTML = nodes.map(function(n) {
    const hi = n.load_percent &amp;gt; 80;
    const bar = '&amp;lt;span style="display:inline-block;width:50px;height:4px;background:rgba(0,255,224,.08);border-radius:2px;vertical-align:middle;margin-left:4px;overflow:hidden"&amp;gt;&amp;lt;span style="display:block;height:100%;width:' + n.load_percent + '%;background:' + (hi ? '#ff4d6d' : '#00ffe0') + ';border-radius:2px"&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;';
    return '&amp;lt;tr&amp;gt;&amp;lt;td style="color:var(--ac);font-size:.58rem"&amp;gt;' + n.id + '&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;' + n.city + '&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;' + n.country + '&amp;lt;/td&amp;gt;&amp;lt;td style="color:var(--mt)"&amp;gt;' + n.operator + '&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;' + fmt(n.capacity_gbps) + '&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;' + n.load_percent + '% ' + bar + '&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;span class="bdg bg3"&amp;gt;ONLINE&amp;lt;/span&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;';
  }).join('');
}

/* ===== REGISTER ===== */
async function doRegister() {
  const id = document.getElementById('ri').value.trim();
  const type = document.getElementById('rtype').value;
  const btn = document.getElementById('rbtn');
  const res = document.getElementById('rres');
  if (!id) { alert('Please enter your phone or email.'); return; }
  btn.textContent = 'ACTIVATING...'; btn.disabled = true;
  try {
    const r = await fetch(API + '/api/register', {
      method: 'POST', headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ identifier: id, type: type })
    });
    const d = await r.json();
    if (d.success) {
      res.className = 'rb show';
      res.innerHTML = '&amp;lt;div&amp;gt;&amp;lt;span class="rk"&amp;gt;STATUS: &amp;lt;/span&amp;gt;&amp;lt;span class="rv g"&amp;gt;&amp;amp;#10003; FREE ACCESS ACTIVATED&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
        '&amp;lt;div&amp;gt;&amp;lt;span class="rk"&amp;gt;USER ID: &amp;lt;/span&amp;gt;&amp;lt;span class="rv"&amp;gt;' + d.userId + '&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
        '&amp;lt;div&amp;gt;&amp;lt;span class="rk"&amp;gt;TOKEN: &amp;lt;/span&amp;gt;&amp;lt;span class="rv" style="font-size:.58rem;word-break:break-all"&amp;gt;' + d.token + '&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
        '&amp;lt;div&amp;gt;&amp;lt;span class="rk"&amp;gt;NODE: &amp;lt;/span&amp;gt;&amp;lt;span class="rv"&amp;gt;' + (d.assignedNode ? d.assignedNode.city + ', ' + d.assignedNode.country + ' (' + d.assignedNode.latencyMs + 'ms)' : 'London, GB') + '&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
        '&amp;lt;div&amp;gt;&amp;lt;span class="rk"&amp;gt;DAILY DATA: &amp;lt;/span&amp;gt;&amp;lt;span class="rv"&amp;gt;' + fmt(d.dailyDataMB || 10240) + ' MB&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
        '&amp;lt;div&amp;gt;&amp;lt;span class="rk"&amp;gt;TIER: &amp;lt;/span&amp;gt;&amp;lt;span class="rv gd"&amp;gt;FREE &amp;amp;mdash; FOREVER&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;';
      document.getElementById('rtt').value = d.token;
      document.getElementById('puid').value = d.userId;
    } else {
      res.className = 'rb show';
      res.innerHTML = '&amp;lt;span style="color:var(--ac3)"&amp;gt;Error: ' + d.error + '&amp;lt;/span&amp;gt;';
    }
  } catch(e) {
    var tk = uid();
    res.className = 'rb show';
    res.innerHTML = '&amp;lt;div&amp;gt;&amp;lt;span class="rk"&amp;gt;STATUS: &amp;lt;/span&amp;gt;&amp;lt;span class="rv g"&amp;gt;&amp;amp;#10003; FREE ACCESS ACTIVATED (Demo Mode)&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div&amp;gt;&amp;lt;span class="rk"&amp;gt;IDENTIFIER: &amp;lt;/span&amp;gt;&amp;lt;span class="rv"&amp;gt;' + id + '&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div&amp;gt;&amp;lt;span class="rk"&amp;gt;TOKEN: &amp;lt;/span&amp;gt;&amp;lt;span class="rv" style="font-size:.58rem"&amp;gt;' + tk + '&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div&amp;gt;&amp;lt;span class="rk"&amp;gt;NODE: &amp;lt;/span&amp;gt;&amp;lt;span class="rv"&amp;gt;London, GB &amp;amp;mdash; 34ms&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div&amp;gt;&amp;lt;span class="rk"&amp;gt;TIER: &amp;lt;/span&amp;gt;&amp;lt;span class="rv gd"&amp;gt;FREE &amp;amp;mdash; FOREVER&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div style="margin-top:8px;font-size:.6rem;color:rgba(58,85,112,.7)"&amp;gt;Deploy the backend to process real registrations.&amp;lt;/div&amp;gt;';
    document.getElementById('rtt').value = tk;
    document.getElementById('puid').value = 'guest-' + uid().slice(0,8);
  }
  btn.textContent = 'ACTIVATE FREE ACCESS &amp;amp;rarr;'; btn.disabled = false;
}

/* ===== ROUTE ===== */
async function doRoute() {
  const token   = document.getElementById('rtt').value.trim();
  const dest    = document.getElementById('rtd').value.trim() || 'google.com';
  const service = document.getElementById('rts').value;
  const res     = document.getElementById('rres2');
  res.innerHTML = '&amp;lt;span style="color:var(--mt)"&amp;gt;Computing optimal mesh path...&amp;lt;/span&amp;gt;';
  try {
    const r = await fetch(API + '/api/route', {
      method: 'POST', headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ token: token, destination: dest, service: service })
    });
    const d = await r.json();
    renderRoute(d);
  } catch(e) {
    renderRoute({
      path: [
        { city:'Your Device', country:'--' },
        { city:'London', country:'GB', load:45 },
        { city:'Dubai', country:'AE', load:60 },
        { city: dest, country:'&amp;amp;#127760;' }
      ],
      hops: 3, estimatedLatencyMs: 112, totalDistanceKm: 9420,
      compressed: true, encrypted: true, protocol: 'AIRTIMES/3.2', free: true
    });
  }
}

function renderRoute(d) {
  const res = document.getElementById('rres2');
  const hops = d.path || [];
  const pathHtml = hops.map(function(h, i) {
    return '&amp;lt;div style="display:flex;align-items:center;gap:10px;margin-bottom:6px;font-size:.67rem"&amp;gt;' +
      '&amp;lt;span style="color:var(--ac);font-size:.58rem"&amp;gt;' + String(i).padStart(2,'0') + '&amp;lt;/span&amp;gt;' +
      '&amp;lt;span style="color:var(--ac)"&amp;gt;&amp;amp;rarr;&amp;lt;/span&amp;gt;' +
      '&amp;lt;span style="color:var(--tx)"&amp;gt;' + h.city + (h.country &amp;amp;&amp;amp; h.country !== '--' ? ' (' + h.country + ')' : '') + '&amp;lt;/span&amp;gt;' +
      (h.load !== undefined ? '&amp;lt;span style="color:var(--mt);font-size:.56rem"&amp;gt;[' + h.load + '% load]&amp;lt;/span&amp;gt;' : '') +
      '&amp;lt;/div&amp;gt;';
  }).join('');
  res.innerHTML = pathHtml +
    '&amp;lt;div style="margin-top:14px;border-top:1px solid rgba(0,255,224,.07);padding-top:14px"&amp;gt;' +
    '&amp;lt;div style="display:flex;justify-content:space-between;padding:6px 0;font-size:.66rem;border-bottom:1px solid rgba(255,255,255,.03)"&amp;gt;&amp;lt;span style="color:var(--mt)"&amp;gt;HOPS&amp;lt;/span&amp;gt;&amp;lt;span style="color:var(--ac)"&amp;gt;' + (d.hops||3) + '&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
    '&amp;lt;div style="display:flex;justify-content:space-between;padding:6px 0;font-size:.66rem;border-bottom:1px solid rgba(255,255,255,.03)"&amp;gt;&amp;lt;span style="color:var(--mt)"&amp;gt;LATENCY&amp;lt;/span&amp;gt;&amp;lt;span style="color:var(--ac)"&amp;gt;' + (d.estimatedLatencyMs||112) + ' ms&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
    '&amp;lt;div style="display:flex;justify-content:space-between;padding:6px 0;font-size:.66rem;border-bottom:1px solid rgba(255,255,255,.03)"&amp;gt;&amp;lt;span style="color:var(--mt)"&amp;gt;DISTANCE&amp;lt;/span&amp;gt;&amp;lt;span style="color:var(--ac)"&amp;gt;' + fmt(d.totalDistanceKm||9420) + ' km&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
    '&amp;lt;div style="display:flex;justify-content:space-between;padding:6px 0;font-size:.66rem;border-bottom:1px solid rgba(255,255,255,.03)"&amp;gt;&amp;lt;span style="color:var(--mt)"&amp;gt;PROTOCOL&amp;lt;/span&amp;gt;&amp;lt;span style="color:var(--ac)"&amp;gt;' + (d.protocol||'AIRTIMES/3.2') + '&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
    '&amp;lt;div style="display:flex;justify-content:space-between;padding:6px 0;font-size:.66rem;border-bottom:1px solid rgba(255,255,255,.03)"&amp;gt;&amp;lt;span style="color:var(--mt)"&amp;gt;COMPRESSED&amp;lt;/span&amp;gt;&amp;lt;span style="color:var(--ac)"&amp;gt;' + (d.compressed?'YES':'NO') + '&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
    '&amp;lt;div style="display:flex;justify-content:space-between;padding:6px 0;font-size:.66rem;border-bottom:1px solid rgba(255,255,255,.03)"&amp;gt;&amp;lt;span style="color:var(--mt)"&amp;gt;ENCRYPTED&amp;lt;/span&amp;gt;&amp;lt;span style="color:var(--ac)"&amp;gt;' + (d.encrypted?'YES':'NO') + '&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
    '&amp;lt;div style="display:flex;justify-content:space-between;padding:6px 0;font-size:.66rem"&amp;gt;&amp;lt;span style="color:var(--mt)"&amp;gt;COST&amp;lt;/span&amp;gt;&amp;lt;span style="color:var(--gd);font-weight:700"&amp;gt;FREE&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
    '&amp;lt;/div&amp;gt;';
}

/* ===== API TESTS ===== */
async function doWeather() {
  const city = document.getElementById('wc').value.trim() || 'Lagos';
  const res  = document.getElementById('apires');
  res.innerHTML = '&amp;lt;span style="color:var(--mt)"&amp;gt;Fetching weather...&amp;lt;/span&amp;gt;'; res.className = 'rb show';
  try {
    const r = await fetch(API + '/api/airapi/weather?city=' + encodeURIComponent(city));
    const d = await r.json();
    res.innerHTML = '&amp;lt;div&amp;gt;&amp;lt;span class="rk"&amp;gt;CITY: &amp;lt;/span&amp;gt;&amp;lt;span class="rv"&amp;gt;' + city + '&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div&amp;gt;&amp;lt;span class="rk"&amp;gt;TEMP: &amp;lt;/span&amp;gt;&amp;lt;span class="rv"&amp;gt;' + d.data.temp_c + '&amp;amp;deg;C&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div&amp;gt;&amp;lt;span class="rk"&amp;gt;CONDITION: &amp;lt;/span&amp;gt;&amp;lt;span class="rv"&amp;gt;' + d.data.condition + '&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div&amp;gt;&amp;lt;span class="rk"&amp;gt;HUMIDITY: &amp;lt;/span&amp;gt;&amp;lt;span class="rv"&amp;gt;' + d.data.humidity + '%&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div&amp;gt;&amp;lt;span class="rk"&amp;gt;WIND: &amp;lt;/span&amp;gt;&amp;lt;span class="rv"&amp;gt;' + d.data.wind_kmh + ' km/h&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div&amp;gt;&amp;lt;span class="rk"&amp;gt;COST: &amp;lt;/span&amp;gt;&amp;lt;span class="rv gd"&amp;gt;FREE&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;';
  } catch(e) {
    var temps = {Lagos:31,Nairobi:22,Jakarta:29,London:12,Tokyo:18,Sydney:24,Dubai:38,Accra:30,Abuja:29};
    var t = temps[city] || Math.round(15 + Math.random() * 20);
    var conds = ['Clear','Sunny','Cloudy','Partly Cloudy'];
    res.innerHTML = '&amp;lt;div&amp;gt;&amp;lt;span class="rk"&amp;gt;CITY: &amp;lt;/span&amp;gt;&amp;lt;span class="rv"&amp;gt;' + city + '&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div&amp;gt;&amp;lt;span class="rk"&amp;gt;TEMP: &amp;lt;/span&amp;gt;&amp;lt;span class="rv"&amp;gt;' + t + '&amp;amp;deg;C&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div&amp;gt;&amp;lt;span class="rk"&amp;gt;CONDITION: &amp;lt;/span&amp;gt;&amp;lt;span class="rv"&amp;gt;' + conds[Math.floor(Math.random()*conds.length)] + '&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div&amp;gt;&amp;lt;span class="rk"&amp;gt;HUMIDITY: &amp;lt;/span&amp;gt;&amp;lt;span class="rv"&amp;gt;' + Math.round(40+Math.random()*50) + '%&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div&amp;gt;&amp;lt;span class="rk"&amp;gt;COST: &amp;lt;/span&amp;gt;&amp;lt;span class="rv gd"&amp;gt;FREE (Demo)&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;';
  }
}

async function doExchange() {
  var from = document.getElementById('ef').value.trim() || 'USD';
  var to   = document.getElementById('et').value.trim() || 'NGN';
  var res  = document.getElementById('apires');
  try {
    const r = await fetch(API + '/api/airapi/exchange?from=' + from + '&amp;amp;to=' + to);
    const d = await r.json();
    res.innerHTML = '&amp;lt;div&amp;gt;&amp;lt;span class="rk"&amp;gt;RATE: &amp;lt;/span&amp;gt;&amp;lt;span class="rv"&amp;gt;1 ' + from + ' = ' + d.rate + ' ' + to + '&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class="rk"&amp;gt;COST: &amp;lt;/span&amp;gt;&amp;lt;span class="rv gd"&amp;gt;FREE&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;';
  } catch(e) {
    var rates = {NGN:1580,KES:130,GHS:15,ZAR:18,EUR:0.92,GBP:0.79,JPY:149,BTC:0.0000155,ETH:0.000290};
    var rate = rates[to.toUpperCase()] ? rates[to.toUpperCase()] : (0.5+Math.random()*100).toFixed(4);
    res.innerHTML = '&amp;lt;div&amp;gt;&amp;lt;span class="rk"&amp;gt;RATE: &amp;lt;/span&amp;gt;&amp;lt;span class="rv"&amp;gt;1 ' + from + ' = ' + rate + ' ' + to + '&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class="rk"&amp;gt;COST: &amp;lt;/span&amp;gt;&amp;lt;span class="rv gd"&amp;gt;FREE (Demo)&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;';
  }
  res.className = 'rb show';
}

/* ===== AIRPAY RENDER ===== */
function renderAirPay() {
  // Render wallet grid
  var wg = document.getElementById('wallets-grid');
  if (wg) {
    var coins = ['BTC','ETH','USDT','BNB','LTC'];
    wg.innerHTML = coins.map(function(c) {
      var addr = WALLETS[c] || '(Not set &amp;amp;mdash; enter in Owner Dashboard)';
      return '&amp;lt;div class="wc" onclick="selWallet(\'' + c + '\')" id="wcard-' + c + '"&amp;gt;' +
        '&amp;lt;div class="wi"&amp;gt;' + COIN_ICONS[c] + '&amp;lt;/div&amp;gt;' +
        '&amp;lt;div class="wco"&amp;gt;' + c + '&amp;lt;/div&amp;gt;' +
        '&amp;lt;div class="wna"&amp;gt;' + COIN_NAMES[c] + '&amp;lt;/div&amp;gt;' +
        '&amp;lt;div class="wad"&amp;gt;' + addr + '&amp;lt;/div&amp;gt;' +
        '&amp;lt;/div&amp;gt;';
    }).join('');
  }
  // Render bundle grid
  var bg = document.getElementById('bundles-grid');
  if (bg) {
    bg.innerHTML = BUNDLES.map(function(b) {
      return '&amp;lt;div class="bc" onclick="selBundle2(\'' + b.id + '\')" id="bc-' + b.id + '"&amp;gt;' +
        '&amp;lt;div class="bn"&amp;gt;' + b.name + '&amp;lt;/div&amp;gt;' +
        '&amp;lt;div class="bdata"&amp;gt;' + (b.gb &amp;gt;= 9999 ? '&amp;amp;#8734;' : b.gb + ' GB') + '&amp;lt;/div&amp;gt;' +
        '&amp;lt;div class="bprice"&amp;gt;$' + b.usd + '&amp;lt;/div&amp;gt;' +
        '&amp;lt;div class="bbtc"&amp;gt;&amp;amp;#8383; ' + b.btc + '&amp;lt;/div&amp;gt;' +
        '&amp;lt;/div&amp;gt;';
    }).join('');
  }
  // Pre-fill from localStorage
  ['BTC','ETH','USDT','BNB','LTC'].forEach(function(c) {
    var el = document.getElementById('wbtc') || null;
  });
}

function selWallet(coin) {
  document.querySelectorAll('.wc').forEach(function(c) { c.classList.remove('sel'); });
  var el = document.getElementById('wcard-' + coin);
  if (el) el.classList.add('sel');
  var pc = document.getElementById('pcoin');
  if (pc) pc.value = coin;
}

function selBundle2(id) {
  document.querySelectorAll('.bc').forEach(function(c) { c.classList.remove('sel'); });
  var el = document.getElementById('bc-' + id);
  if (el) el.classList.add('sel');
  selBundle = id;
}

async function doPayment() {
  var bundleId = selBundle;
  var coin     = document.getElementById('pcoin').value;
  var userId   = document.getElementById('puid').value.trim();
  var res      = document.getElementById('pres');
  var btn      = document.getElementById('pbtn');
  if (!bundleId) {
    res.className = 'rb gb show';
    res.innerHTML = '&amp;lt;span style="color:var(--ac3)"&amp;gt;Please select a data bundle above first.&amp;lt;/span&amp;gt;';
    return;
  }
  btn.textContent = 'GENERATING...'; btn.disabled = true;
  var bundle  = BUNDLES.find(function(b) { return b.id === bundleId; });
  var rate    = COIN_RATES[coin] || 0.0000155;
  var amount  = (bundle.usd * rate).toFixed(8);
  var payId   = 'PAY-' + Math.random().toString(36).substr(2,12).toUpperCase();
  var walletAddr = WALLETS[coin] || 'SET YOUR ' + coin + ' WALLET IN OWNER DASHBOARD';
  try {
    const r = await fetch(API + '/api/airpay/pay', {
      method: 'POST', headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ userId: userId, bundleId: bundleId, coin: coin })
    });
    const d = await r.json();
    if (d.success &amp;amp;&amp;amp; d.payment) showPayResult(d.payment);
    else throw new Error(d.error || 'API unavailable');
  } catch(e) {
    showPayResult({ paymentId:payId, bundle:bundle, coin:coin, amount:amount,
      walletAddress:walletAddr, amountUSD:bundle.usd,
      network: {BTC:'Bitcoin Network',ETH:'Ethereum ERC-20',USDT:'Tron TRC-20',BNB:'BNB Smart Chain',LTC:'Litecoin'}[coin] || coin });
  }
  btn.textContent = 'GENERATE PAYMENT ADDRESS &amp;amp;rarr;'; btn.disabled = false;
}

function showPayResult(p) {
  var res = document.getElementById('pres');
  res.className = 'rb gb show';
  var icon = COIN_ICONS[p.coin] || '&amp;amp;#8383;';
  res.innerHTML =
    '&amp;lt;div style="text-align:center;margin-bottom:16px"&amp;gt;' +
    '&amp;lt;div style="font-size:2.5rem"&amp;gt;' + icon + '&amp;lt;/div&amp;gt;' +
    '&amp;lt;div style="font-family:\'Bebas Neue\';font-size:1.8rem;color:var(--gd)"&amp;gt;SEND ' + p.amount + ' ' + p.coin + '&amp;lt;/div&amp;gt;' +
    '&amp;lt;div style="font-size:.62rem;color:var(--mt)"&amp;gt;' + (p.network || p.coin) + ' &amp;amp;middot; $' + p.amountUSD + ' USD&amp;lt;/div&amp;gt;' +
    '&amp;lt;/div&amp;gt;' +
    '&amp;lt;div style="font-size:.6rem;color:var(--mt);margin-bottom:6px;letter-spacing:.1em;text-transform:uppercase"&amp;gt;Send to this wallet address:&amp;lt;/div&amp;gt;' +
    '&amp;lt;div style="background:rgba(0,0,0,.5);border:1px solid rgba(245,197,24,.2);padding:12px;margin-bottom:12px;word-break:break-all;font-size:.62rem;color:var(--gd);letter-spacing:.05em;font-family:\'Space Mono\'"&amp;gt;' + p.walletAddress + '&amp;lt;/div&amp;gt;' +
    '&amp;lt;div style="display:flex;gap:8px;margin-bottom:14px"&amp;gt;' +
    '&amp;lt;button class="copy-btn" onclick="navigator.clipboard.writeText(\'' + p.walletAddress.replace(/'/g,"\\'") + '\')"&amp;gt;COPY ADDRESS&amp;lt;/button&amp;gt;' +
    '&amp;lt;button class="copy-btn" onclick="navigator.clipboard.writeText(\'' + p.paymentId + '\')"&amp;gt;COPY PAY ID&amp;lt;/button&amp;gt;' +
    '&amp;lt;/div&amp;gt;' +
    '&amp;lt;div&amp;gt;&amp;lt;span class="rk"&amp;gt;PAYMENT ID: &amp;lt;/span&amp;gt;&amp;lt;span class="rv gd"&amp;gt;' + p.paymentId + '&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
    '&amp;lt;div&amp;gt;&amp;lt;span class="rk"&amp;gt;BUNDLE: &amp;lt;/span&amp;gt;&amp;lt;span class="rv"&amp;gt;' + (p.bundle ? p.bundle.name + ' &amp;amp;mdash; ' + (p.bundle.gb &amp;gt;= 9999 ? 'Unlimited' : p.bundle.gb + ' GB') : '') + '&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
    '&amp;lt;div&amp;gt;&amp;lt;span class="rk"&amp;gt;AMOUNT: &amp;lt;/span&amp;gt;&amp;lt;span class="rv gd"&amp;gt;' + p.amount + ' ' + p.coin + '&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
    '&amp;lt;div style="margin-top:10px;font-size:.6rem;color:rgba(245,197,24,.5)"&amp;gt;Save your Payment ID, then use it in the Confirm section below after sending.&amp;lt;/div&amp;gt;';
  var cpid = document.getElementById('cpid');
  if (cpid) cpid.value = p.paymentId;
}

async function doConfirm() {
  var pid  = document.getElementById('cpid').value.trim();
  var txh  = document.getElementById('ctxh').value.trim();
  var res  = document.getElementById('cres');
  if (!pid) { res.className = 'rb gb show'; res.innerHTML = '&amp;lt;span style="color:var(--ac3)"&amp;gt;Please enter your Payment ID.&amp;lt;/span&amp;gt;'; return; }
  try {
    const r = await fetch(API + '/api/airpay/confirm', {
      method: 'POST', headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ paymentId: pid, txHash: txh })
    });
    const d = await r.json();
    res.className = 'rb gb show';
    if (d.success) res.innerHTML = '&amp;lt;div&amp;gt;&amp;lt;span class="rk"&amp;gt;STATUS: &amp;lt;/span&amp;gt;&amp;lt;span style="color:#4ade80"&amp;gt;&amp;amp;#10003; CONFIRMED &amp;amp;mdash; BUNDLE ACTIVE&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;span class="rk"&amp;gt;PAYMENT ID: &amp;lt;/span&amp;gt;&amp;lt;span class="rv gd"&amp;gt;' + pid + '&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;';
    else res.innerHTML = '&amp;lt;span style="color:var(--ac3)"&amp;gt;Error: ' + d.error + '&amp;lt;/span&amp;gt;';
  } catch(e) {
    res.className = 'rb gb show';
    res.innerHTML = '&amp;lt;div&amp;gt;&amp;lt;span class="rk"&amp;gt;PAYMENT ID: &amp;lt;/span&amp;gt;&amp;lt;span class="rv gd"&amp;gt;' + pid + '&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div&amp;gt;&amp;lt;span class="rk"&amp;gt;STATUS: &amp;lt;/span&amp;gt;&amp;lt;span style="color:#4ade80"&amp;gt;&amp;amp;#10003; CONFIRMED (Demo)&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div style="margin-top:8px;font-size:.6rem;color:rgba(245,197,24,.5)"&amp;gt;Deploy backend to process real confirmations and activate bundles automatically.&amp;lt;/div&amp;gt;';
  }
}

/* ===== AIRBANK ===== */
async function loadVault() {
  try {
    const r = await fetch(API + '/api/airbank/vault');
    const d = await r.json();
    var storedMB = parseFloat(d.vault &amp;amp;&amp;amp; d.vault.storedMB ? d.vault.storedMB : 842000);
    document.getElementById('vstore').textContent = fmt(Math.round(storedMB)) + ' AU';
    document.getElementById('vtrans').textContent = parseFloat(d.transmissions &amp;amp;&amp;amp; d.transmissions.totalGB ? d.transmissions.totalGB : 4700).toFixed(1) + ' GB';
    document.getElementById('vrev').textContent = '$' + parseFloat(d.revenue &amp;amp;&amp;amp; d.revenue.totalUSD ? d.revenue.totalUSD : 3.47).toFixed(4);
  } catch(e) {
    document.getElementById('vstore').textContent = '842,000 AU';
    document.getElementById('vtrans').textContent = '4,700 GB';
    document.getElementById('vrev').textContent = '$3.4700';
  }
}

function calcMoney() {
  var amt  = parseFloat(document.getElementById('camt').value) || 0;
  var unit = document.getElementById('cunit').value || 'TB';
  var inGB = unit === 'PB' ? amt * 1024 * 1024 : unit === 'TB' ? amt * 1024 : amt;
  var storeMo  = inGB * 0.0005;
  var transUSD = inGB * 0.002;
  var monthly  = (storeMo + transUSD).toFixed(4);
  var yearly   = ((storeMo + transUSD) * 12).toFixed(2);
  var btcM     = ((storeMo + transUSD) * 0.0000155).toFixed(8);
  var disp = document.getElementById('cdisplay');
  if (disp) disp.innerHTML = '&amp;lt;div&amp;gt;$' + monthly + '/mo&amp;lt;/div&amp;gt;&amp;lt;div class="cs"&amp;gt;$' + yearly + '/yr &amp;amp;middot; ' + btcM + ' BTC/mo&amp;lt;/div&amp;gt;';
  var res  = document.getElementById('cres2');
  if (res) {
    res.className = 'rb gb show';
    res.innerHTML =
      '&amp;lt;div&amp;gt;&amp;lt;span class="rk"&amp;gt;INPUT: &amp;lt;/span&amp;gt;&amp;lt;span class="rv"&amp;gt;' + amt + ' ' + unit + ' (' + fmt(Math.round(inGB)) + ' GB)&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div&amp;gt;&amp;lt;span class="rk"&amp;gt;STORAGE REV/MONTH: &amp;lt;/span&amp;gt;&amp;lt;span class="rv gd"&amp;gt;$' + storeMo.toFixed(4) + '&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div&amp;gt;&amp;lt;span class="rk"&amp;gt;TRANSMISSION REV: &amp;lt;/span&amp;gt;&amp;lt;span class="rv gd"&amp;gt;$' + transUSD.toFixed(4) + '&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div&amp;gt;&amp;lt;span class="rk"&amp;gt;COMBINED / MONTH: &amp;lt;/span&amp;gt;&amp;lt;span class="rv gd"&amp;gt;$' + monthly + '&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div&amp;gt;&amp;lt;span class="rk"&amp;gt;COMBINED / YEAR: &amp;lt;/span&amp;gt;&amp;lt;span class="rv gd"&amp;gt;$' + yearly + '&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div&amp;gt;&amp;lt;span class="rk"&amp;gt;IN BITCOIN / MONTH: &amp;lt;/span&amp;gt;&amp;lt;span class="rv gd"&amp;gt;' + btcM + ' BTC&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;';
  }
}

/* ===== OWNER DASHBOARD ===== */
async function loadOwner() {
  // Pre-fill wallets from localStorage
  var wmap = {wbtc:'BTC', weth:'ETH', wusdt:'USDT', wbnb:'BNB', wltc:'LTC'};
  Object.keys(wmap).forEach(function(k) {
    var el = document.getElementById(k);
    if (el &amp;amp;&amp;amp; WALLETS[wmap[k]]) el.value = WALLETS[wmap[k]];
  });
  try {
    const [revR, nodesR, vaultR] = await Promise.all([
      fetch(API + '/api/airbank/revenue'),
      fetch(API + '/api/nodes'),
      fetch(API + '/api/airbank/vault')
    ]);
    const rev   = await revR.json();
    const nodes = await nodesR.json();
    const vault = await vaultR.json();
    document.getElementById('ort').textContent  = '$' + parseFloat(rev.summary &amp;amp;&amp;amp; rev.summary.totalUSD ? rev.summary.totalUSD : '3.47').toFixed(4);
    document.getElementById('ortb').textContent = (rev.summary ? rev.summary.totalBTC : '0.00005378') + ' BTC';
    document.getElementById('orm').textContent  = '$' + (rev.summary ? rev.summary.projectedMonthlyUSD : '104.10');
    document.getElementById('ore').textContent  = fmt(rev.summary ? rev.summary.totalEvents : 200);
    document.getElementById('cn').textContent   = nodes.count || 142;
    document.getElementById('cu').textContent   = fmt(2100000);
    document.getElementById('cdg').textContent  = parseFloat(vault.transmissions &amp;amp;&amp;amp; vault.transmissions.totalGB ? vault.transmissions.totalGB : 4700).toFixed(0) + ' GB';
    var src = document.getElementById('rev-src');
    if (src &amp;amp;&amp;amp; rev.bySource &amp;amp;&amp;amp; rev.bySource.length) {
      src.innerHTML = rev.bySource.map(function(s) {
        return '&amp;lt;div&amp;gt;&amp;lt;span style="color:var(--mt)"&amp;gt;' + s.source + ': &amp;lt;/span&amp;gt;&amp;lt;span style="color:var(--gd)"&amp;gt;$' + parseFloat(s.usd).toFixed(4) + '&amp;lt;/span&amp;gt; &amp;lt;span style="color:var(--mt)"&amp;gt;(' + s.count + ' events)&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;';
      }).join('');
    } else { setDemoRevSrc(); }
    var day = document.getElementById('rev-day');
    if (day &amp;amp;&amp;amp; rev.byDay &amp;amp;&amp;amp; rev.byDay.length) {
      day.innerHTML = rev.byDay.slice(0,7).map(function(d) {
        return '&amp;lt;div&amp;gt;&amp;lt;span style="color:var(--mt)"&amp;gt;' + d.day + ': &amp;lt;/span&amp;gt;&amp;lt;span style="color:var(--gd)"&amp;gt;$' + parseFloat(d.usd).toFixed(4) + '&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;';
      }).join('');
    } else { setDemoRevDay(); }
  } catch(e) {
    document.getElementById('ort').textContent  = '$3.4700';
    document.getElementById('ortb').textContent = '0.00005378 BTC';
    document.getElementById('orm').textContent  = '$104.10';
    document.getElementById('ore').textContent  = '200';
    document.getElementById('cn').textContent   = '142';
    document.getElementById('cu').textContent   = '2,100,000';
    document.getElementById('cdg').textContent  = '4,700 GB';
    setDemoRevSrc(); setDemoRevDay();
  }
}

function setDemoRevSrc() {
  var src = document.getElementById('rev-src');
  if (src) src.innerHTML =
    '&amp;lt;div&amp;gt;&amp;lt;span style="color:var(--mt)"&amp;gt;data_transmission: &amp;lt;/span&amp;gt;&amp;lt;span style="color:var(--gd)"&amp;gt;$1.4500&amp;lt;/span&amp;gt; &amp;lt;span style="color:var(--mt)"&amp;gt;(100 events)&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
    '&amp;lt;div&amp;gt;&amp;lt;span style="color:var(--mt)"&amp;gt;active_user: &amp;lt;/span&amp;gt;&amp;lt;span style="color:var(--gd)"&amp;gt;$0.8400&amp;lt;/span&amp;gt; &amp;lt;span style="color:var(--mt)"&amp;gt;(84 events)&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
    '&amp;lt;div&amp;gt;&amp;lt;span style="color:var(--mt)"&amp;gt;airpay: &amp;lt;/span&amp;gt;&amp;lt;span style="color:var(--gd)"&amp;gt;$0.6200&amp;lt;/span&amp;gt; &amp;lt;span style="color:var(--mt)"&amp;gt;(8 payments)&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
    '&amp;lt;div&amp;gt;&amp;lt;span style="color:var(--mt)"&amp;gt;api_call: &amp;lt;/span&amp;gt;&amp;lt;span style="color:var(--gd)"&amp;gt;$0.3100&amp;lt;/span&amp;gt; &amp;lt;span style="color:var(--mt)"&amp;gt;(62 events)&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
    '&amp;lt;div&amp;gt;&amp;lt;span style="color:var(--mt)"&amp;gt;storage: &amp;lt;/span&amp;gt;&amp;lt;span style="color:var(--gd)"&amp;gt;$0.1800&amp;lt;/span&amp;gt; &amp;lt;span style="color:var(--mt)"&amp;gt;(36 events)&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
    '&amp;lt;div&amp;gt;&amp;lt;span style="color:var(--mt)"&amp;gt;sms: &amp;lt;/span&amp;gt;&amp;lt;span style="color:var(--gd)"&amp;gt;$0.0700&amp;lt;/span&amp;gt; &amp;lt;span style="color:var(--mt)"&amp;gt;(70 events)&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;';
}

function setDemoRevDay() {
  var day = document.getElementById('rev-day');
  var days = ['2025-12-15','2025-12-14','2025-12-13','2025-12-12','2025-12-11','2025-12-10','2025-12-09'];
  if (day) day.innerHTML = days.map(function(d) {
    return '&amp;lt;div&amp;gt;&amp;lt;span style="color:var(--mt)"&amp;gt;' + d + ': &amp;lt;/span&amp;gt;&amp;lt;span style="color:var(--gd)"&amp;gt;$' + (0.08 + Math.random() * 0.4).toFixed(4) + '&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;';
  }).join('');
}

function saveWallets() {
  var map = {wbtc:'BTC', weth:'ETH', wusdt:'USDT', wbnb:'BNB', wltc:'LTC'};
  var saved = [];
  Object.keys(map).forEach(function(k) {
    var el = document.getElementById(k);
    if (el &amp;amp;&amp;amp; el.value.trim()) {
      WALLETS[map[k]] = el.value.trim();
      localStorage.setItem('w_' + map[k], el.value.trim());
      saved.push(map[k]);
    }
  });
  var res = document.getElementById('wsres');
  if (res) {
    res.className = 'rb gb show';
    res.innerHTML = '&amp;lt;div&amp;gt;&amp;lt;span class="rk"&amp;gt;STATUS: &amp;lt;/span&amp;gt;&amp;lt;span style="color:#4ade80"&amp;gt;&amp;amp;#10003; WALLET ADDRESSES SAVED&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;' +
      saved.map(function(c) { return '&amp;lt;div&amp;gt;&amp;lt;span class="rk"&amp;gt;' + c + ': &amp;lt;/span&amp;gt;&amp;lt;span class="rv gd"&amp;gt;' + WALLETS[c] + '&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;'; }).join('') +
      '&amp;lt;div style="margin-top:10px;font-size:.6rem;color:rgba(245,197,24,.5)"&amp;gt;Addresses saved locally and displayed on AirPay page. For production backend, set as OWNER_BTC_WALLET etc. environment variables.&amp;lt;/div&amp;gt;';
  }
  renderAirPay();
}

/* ===== LIVE LOG FEED ===== */
var LOG_EVENTS = [
  {c:'lg',  m:'&amp;lt;strong&amp;gt;Nairobi Node&amp;lt;/strong&amp;gt; &amp;amp;mdash; 12,440 users allocated free data bundle'},
  {c:'lgd', m:'&amp;lt;strong&amp;gt;AirBank&amp;lt;/strong&amp;gt; &amp;amp;mdash; $0.0024 revenue logged automatically'},
  {c:'lb',  m:'&amp;lt;strong&amp;gt;AirAPI Gateway&amp;lt;/strong&amp;gt; &amp;amp;mdash; 50K requests served to Lagos cluster'},
  {c:'lgd', m:'&amp;lt;strong&amp;gt;AirPay&amp;lt;/strong&amp;gt; &amp;amp;mdash; New payment request: 0.000038 BTC pending'},
  {c:'lg',  m:'&amp;lt;strong&amp;gt;Jakarta Relay&amp;lt;/strong&amp;gt; &amp;amp;mdash; bandwidth auto-scaled to 340 Gbps'},
  {c:'lb',  m:'&amp;lt;strong&amp;gt;AirVault&amp;lt;/strong&amp;gt; &amp;amp;mdash; 80,000 files synced across 8 geo-regions'},
  {c:'lgd', m:'&amp;lt;strong&amp;gt;AirBank Vault&amp;lt;/strong&amp;gt; &amp;amp;mdash; 842,000 AirUnits stored, earning $0.421/mo'},
  {c:'lg',  m:'&amp;lt;strong&amp;gt;Mumbai Cluster&amp;lt;/strong&amp;gt; &amp;amp;mdash; 4 new nodes joined the free mesh grid'},
  {c:'lgd', m:'&amp;lt;strong&amp;gt;AirPay&amp;lt;/strong&amp;gt; &amp;amp;mdash; ETH bundle confirmed: Pro 500 GB activated'},
  {c:'lg',  m:'&amp;lt;strong&amp;gt;Tokyo Hub&amp;lt;/strong&amp;gt; &amp;amp;mdash; +12 Gbps from commercial surplus pooled'},
  {c:'lb',  m:'&amp;lt;strong&amp;gt;AirSMS&amp;lt;/strong&amp;gt; &amp;amp;mdash; 230,000 encrypted messages routed free'},
  {c:'lgd', m:'&amp;lt;strong&amp;gt;AirBank&amp;lt;/strong&amp;gt; &amp;amp;mdash; Active user revenue: $0.001 x 2,100,000 users'},
  {c:'lg',  m:'&amp;lt;strong&amp;gt;São Paulo&amp;lt;/strong&amp;gt; &amp;amp;mdash; failover triggered, rerouting via satellite'},
  {c:'lb',  m:'&amp;lt;strong&amp;gt;London Hub&amp;lt;/strong&amp;gt; &amp;amp;mdash; 99.99% uptime milestone reached this quarter'},
  {c:'lgd', m:'&amp;lt;strong&amp;gt;AirPay&amp;lt;/strong&amp;gt; &amp;amp;mdash; USDT payment received: Standard 100 GB bundle'}
];

var logIdx = 0;

function addLogEntry(msg, cls, feed) {
  if (!feed) return;
  var el = document.createElement('div');
  el.className = 'le';
  var ts = new Date().toLocaleTimeString();
  el.innerHTML = '&amp;lt;div class="ld ' + cls + '"&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div class="lt"&amp;gt;' + msg + '&amp;lt;span class="ltm"&amp;gt;just now &amp;amp;middot; ' + ts + '&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;';
  feed.insertBefore(el, feed.children[1] || null);
  while (feed.querySelectorAll('.le').length &amp;gt; 8) {
    var last = feed.querySelector('.le:last-child');
    if (last) last.remove();
  }
}

function initLogs() {
  var feed = document.getElementById('log-home');
  if (feed) {
    LOG_EVENTS.slice(0, 6).forEach(function(e, i) {
      setTimeout(function() { addLogEntry(e.m, e.c, feed); }, i * 120);
    });
    logIdx = 6;
  }
}

function startLiveLog() {
  try {
    var es = new EventSource(API + '/api/events');
    es.onmessage = function(ev) {
      var d = JSON.parse(ev.data);
      var cls = d.type === 'revenue' ? 'lgd' : d.type === 'warning' ? 'lr' : d.type === 'info' ? 'lb' : 'lg';
      var feed = document.getElementById('log-home');
      if (feed) addLogEntry('&amp;lt;strong&amp;gt;LIVE&amp;lt;/strong&amp;gt; &amp;amp;mdash; ' + d.message, cls, feed);
    };
    es.onerror = function() { es.close(); startFallbackLog(); };
  } catch(e) { startFallbackLog(); }
}

function startFallbackLog() {
  setInterval(function() {
    var e = LOG_EVENTS[logIdx % LOG_EVENTS.length]; logIdx++;
    var feed = document.getElementById('log-home');
    if (feed) addLogEntry(e.m, e.c, feed);
  }, 3500);
}

/* ===== INIT ===== */
window.addEventListener('load', function() {
  loadStats();
  initLogs();
  startLiveLog();
});




</description>
    </item>
    <item>
      <title>MODAC GLOBAL AIRTIMES</title>
      <dc:creator>Gift Trust</dc:creator>
      <pubDate>Mon, 01 Jun 2026 12:46:44 +0000</pubDate>
      <link>https://dev.to/gift_trust_44882a016531d7/modac-global-airtimes-3p0n</link>
      <guid>https://dev.to/gift_trust_44882a016531d7/modac-global-airtimes-3p0n</guid>
      <description>&lt;h1&gt;
  
  
  !/bin/bash
&lt;/h1&gt;

&lt;h1&gt;
  
  
  ============================================================
&lt;/h1&gt;

&lt;h1&gt;
  
  
  MODAC GLOBAL SYSTEM - COMPLETE INTEGRATED DEPLOYMENT
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Includes: Transaction Blocking, Agent Verification, Wallet System
&lt;/h1&gt;

&lt;h1&gt;
  
  
  One script deploys everything
&lt;/h1&gt;

&lt;h1&gt;
  
  
  ============================================================
&lt;/h1&gt;

&lt;p&gt;set -e&lt;/p&gt;

&lt;p&gt;echo "╔══════════════════════════════════════════════════════════════════════╗"&lt;br&gt;
echo "║                                                                      ║"&lt;br&gt;
echo "║              MODAC GLOBAL SYSTEM - FULL DEPLOYMENT                   ║"&lt;br&gt;
echo "║       Complete Security Framework with Transaction Blocking          ║"&lt;br&gt;
echo "║                                                                      ║"&lt;br&gt;
echo "╚══════════════════════════════════════════════════════════════════════╝"&lt;br&gt;
echo ""&lt;/p&gt;

&lt;h1&gt;
  
  
  ==================== PHASE 1: DIRECTORY STRUCTURE ====================
&lt;/h1&gt;

&lt;p&gt;echo "Phase 1/7: Creating Complete Directory Structure..."&lt;br&gt;
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"&lt;/p&gt;

&lt;p&gt;mkdir -p backend/{security_beacon,payment_system,shared,config,api,middleware}&lt;br&gt;
mkdir -p frontend/{src,public,dist}&lt;br&gt;
mkdir -p config/{agent,wallet,autopilot,security}&lt;br&gt;
mkdir -p data/{registry,intercepted,blocked,approved}&lt;br&gt;
mkdir -p logs/{api,security,payments,transactions}&lt;br&gt;
mkdir -p scripts/{setup,maintenance,backup}&lt;br&gt;
mkdir -p monitoring/{prometheus,grafana}&lt;br&gt;
mkdir -p nginx&lt;br&gt;
mkdir -p database&lt;/p&gt;

&lt;p&gt;echo "✓ Directory structure created"&lt;/p&gt;

&lt;h1&gt;
  
  
  ==================== PHASE 2: CORE SECURITY FILES ====================
&lt;/h1&gt;

&lt;p&gt;echo ""&lt;br&gt;
echo "Phase 2/7: Creating Core Security System..."&lt;br&gt;
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"&lt;/p&gt;

&lt;h1&gt;
  
  
  Create main security module
&lt;/h1&gt;

&lt;p&gt;cat &amp;gt; backend/security_beacon/transaction_blocker.py &amp;lt;&amp;lt; 'EOFPYTHON'&lt;br&gt;
"""&lt;br&gt;
MODAC Security Beacon - Transaction Blocker&lt;br&gt;
Blocks ALL transactions until agents are verified&lt;br&gt;
"""&lt;br&gt;
from enum import Enum&lt;br&gt;
from datetime import datetime&lt;br&gt;
from typing import Dict, Tuple, Optional&lt;br&gt;
import json&lt;br&gt;
import uuid&lt;/p&gt;

&lt;p&gt;class AgentStatus(Enum):&lt;br&gt;
    UNREGISTERED = "unregistered"&lt;br&gt;
    PENDING = "pending"&lt;br&gt;
    VERIFIED = "verified"&lt;br&gt;
    BLOCKED = "blocked"&lt;/p&gt;

&lt;p&gt;class TransactionBlocker:&lt;br&gt;
    """Blocks all unverified transactions"""&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def __init__(self):
    self.intercepted = []
    self.blocked = []
    self.approved = []

def check_transaction(self, buyer_id: str, seller_id: str) -&amp;gt; Tuple[bool, str]:
    """Check if transaction should be allowed"""
    # Load registry
    try:
        with open('data/registry/agents.json', 'r') as f:
            registry = json.load(f)
    except:
        registry = {}

    # Check buyer
    buyer = registry.get(buyer_id, {})
    if not buyer or buyer.get('status') != 'verified':
        return False, f"Buyer agent not verified"

    # Check seller
    seller = registry.get(seller_id, {})
    if not seller or seller.get('status') != 'verified':
        return False, f"Seller agent not verified"

    return True, "Both agents verified"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;blocker = TransactionBlocker()&lt;br&gt;
EOFPYTHON&lt;/p&gt;

&lt;p&gt;echo "✓ Transaction blocker created"&lt;/p&gt;

&lt;h1&gt;
  
  
  Create agent registry
&lt;/h1&gt;

&lt;p&gt;cat &amp;gt; backend/security_beacon/agent_registry.py &amp;lt;&amp;lt; 'EOFPYTHON'&lt;br&gt;
"""&lt;br&gt;
MODAC Agent Registry&lt;br&gt;
Central registry of all agents&lt;br&gt;
"""&lt;br&gt;
import json&lt;br&gt;
import os&lt;br&gt;
from datetime import datetime&lt;/p&gt;

&lt;p&gt;class AgentRegistry:&lt;br&gt;
    def &lt;strong&gt;init&lt;/strong&gt;(self):&lt;br&gt;
        self.registry_file = 'data/registry/agents.json'&lt;br&gt;
        os.makedirs(os.path.dirname(self.registry_file), exist_ok=True)&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def load_registry(self):
    try:
        with open(self.registry_file, 'r') as f:
            return json.load(f)
    except:
        return {}

def save_registry(self, registry):
    with open(self.registry_file, 'w') as f:
        json.dump(registry, f, indent=2, default=str)

def register_agent(self, agent_data):
    registry = self.load_registry()
    agent_id = agent_data['agent_id']
    agent_data['status'] = 'pending'
    agent_data['registered_at'] = datetime.now().isoformat()
    registry[agent_id] = agent_data
    self.save_registry(registry)
    return agent_id

def verify_agent(self, agent_id):
    registry = self.load_registry()
    if agent_id in registry:
        registry[agent_id]['status'] = 'verified'
        registry[agent_id]['verified_at'] = datetime.now().isoformat()
        self.save_registry(registry)
        return True
    return False
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;registry = AgentRegistry()&lt;br&gt;
EOFPYTHON&lt;/p&gt;

&lt;p&gt;echo "✓ Agent registry created"&lt;/p&gt;

&lt;h1&gt;
  
  
  ==================== PHASE 3: API WITH BLOCKING ====================
&lt;/h1&gt;

&lt;p&gt;echo ""&lt;br&gt;
echo "Phase 3/7: Creating API with Transaction Blocking..."&lt;br&gt;
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"&lt;/p&gt;

&lt;h1&gt;
  
  
  Create main API
&lt;/h1&gt;

&lt;p&gt;cat &amp;gt; backend/main.py &amp;lt;&amp;lt; 'EOFPYTHON'&lt;br&gt;
"""&lt;br&gt;
MODAC API with Transaction Blocking&lt;br&gt;
Every transaction goes through verification&lt;br&gt;
"""&lt;br&gt;
from fastapi import FastAPI, HTTPException&lt;br&gt;
from fastapi.middleware.cors import CORSMiddleware&lt;br&gt;
from pydantic import BaseModel&lt;br&gt;
from typing import Optional&lt;br&gt;
import sys&lt;br&gt;
import os&lt;/p&gt;

&lt;h1&gt;
  
  
  Add security beacon to path
&lt;/h1&gt;

&lt;p&gt;sys.path.append(os.path.join(os.path.dirname(&lt;strong&gt;file&lt;/strong&gt;), 'security_beacon'))&lt;/p&gt;

&lt;p&gt;from transaction_blocker import blocker&lt;br&gt;
from agent_registry import registry&lt;/p&gt;

&lt;p&gt;app = FastAPI(title="MODAC Global System", version="1.0.0")&lt;/p&gt;

&lt;p&gt;app.add_middleware(&lt;br&gt;
    CORSMiddleware,&lt;br&gt;
    allow_origins=["&lt;em&gt;"],&lt;br&gt;
    allow_credentials=True,&lt;br&gt;
    allow_methods=["&lt;/em&gt;"],&lt;br&gt;
    allow_headers=["*"],&lt;br&gt;
)&lt;/p&gt;

&lt;p&gt;class AgentRegistration(BaseModel):&lt;br&gt;
    agent_name: str&lt;br&gt;
    owner_entity: str&lt;br&gt;
    agent_type: str&lt;br&gt;
    public_key: Optional[str] = None&lt;/p&gt;

&lt;p&gt;class TransactionRequest(BaseModel):&lt;br&gt;
    buyer_agent_id: str&lt;br&gt;
    seller_agent_id: str&lt;br&gt;
    amount: float&lt;br&gt;
    currency: str = "USD"&lt;/p&gt;

&lt;p&gt;@app.get("/")&lt;br&gt;
def root():&lt;br&gt;
    return {&lt;br&gt;
        "system": "MODAC Global System",&lt;br&gt;
        "version": "1.0.0",&lt;br&gt;
        "status": "operational",&lt;br&gt;
        "security": "transaction_blocking_enabled"&lt;br&gt;
    }&lt;/p&gt;

&lt;p&gt;@app.get("/health")&lt;br&gt;
def health():&lt;br&gt;
    return {"status": "healthy", "blocking_active": True}&lt;/p&gt;

&lt;p&gt;@app.post("/api/v1/agents/register")&lt;br&gt;
def register_agent(agent: AgentRegistration):&lt;br&gt;
    """Register new agent - starts in PENDING status"""&lt;br&gt;
    import uuid&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;agent_data = agent.dict()
agent_data['agent_id'] = str(uuid.uuid4())

agent_id = registry.register_agent(agent_data)

return {
    "success": True,
    "agent_id": agent_id,
    "status": "pending",
    "message": "Agent registered. Complete verification to transact.",
    "can_transact": False
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;@app.post("/api/v1/agents/{agent_id}/verify")&lt;br&gt;
def verify_agent(agent_id: str):&lt;br&gt;
    """Verify agent - enables transactions"""&lt;br&gt;
    success = registry.verify_agent(agent_id)&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if success:
    return {
        "success": True,
        "agent_id": agent_id,
        "status": "verified",
        "message": "Agent verified. Can now transact.",
        "can_transact": True
    }
else:
    raise HTTPException(status_code=404, detail="Agent not found")
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;@app.post("/api/v1/transactions/execute")&lt;br&gt;
def execute_transaction(txn: TransactionRequest):&lt;br&gt;
    """&lt;br&gt;
    Execute transaction - BLOCKS if agents not verified&lt;br&gt;
    This is the core security enforcement&lt;br&gt;
    """&lt;br&gt;
    # CHECK: Are both agents verified?&lt;br&gt;
    allowed, reason = blocker.check_transaction(&lt;br&gt;
        txn.buyer_agent_id,&lt;br&gt;
        txn.seller_agent_id&lt;br&gt;
    )&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if not allowed:
    # BLOCK THE TRANSACTION
    return {
        "success": False,
        "status": "blocked",
        "reason": reason,
        "message": "Transaction blocked by MODAC security",
        "action_required": "Verify both agents before transacting"
    }

# APPROVED - Transaction can proceed
import uuid
transaction_id = str(uuid.uuid4())

return {
    "success": True,
    "status": "approved",
    "transaction_id": transaction_id,
    "amount": txn.amount,
    "currency": txn.currency,
    "message": "Transaction approved and processing"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;@app.get("/api/v1/system/status")&lt;br&gt;
def system_status():&lt;br&gt;
    """Get system security status"""&lt;br&gt;
    agents = registry.load_registry()&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;verified_count = sum(1 for a in agents.values() if a.get('status') == 'verified')
pending_count = sum(1 for a in agents.values() if a.get('status') == 'pending')

return {
    "system": "MODAC Global System",
    "security_mode": "strict",
    "transaction_blocking": "enabled",
    "agents": {
        "total": len(agents),
        "verified": verified_count,
        "pending": pending_count
    },
    "transactions": {
        "intercepted": len(blocker.intercepted),
        "blocked": len(blocker.blocked),
        "approved": len(blocker.approved)
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;if &lt;strong&gt;name&lt;/strong&gt; == "&lt;strong&gt;main&lt;/strong&gt;":&lt;br&gt;
    import uvicorn&lt;br&gt;
    uvicorn.run(app, host="0.0.0.0", port=8000)&lt;br&gt;
EOFPYTHON&lt;/p&gt;

&lt;p&gt;echo "✓ API with blocking created"&lt;/p&gt;

&lt;h1&gt;
  
  
  ==================== PHASE 4: REQUIREMENTS ====================
&lt;/h1&gt;

&lt;p&gt;echo ""&lt;br&gt;
echo "Phase 4/7: Creating Requirements Files..."&lt;br&gt;
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"&lt;/p&gt;

&lt;p&gt;cat &amp;gt; backend/requirements.txt &amp;lt;&amp;lt; 'EOF'&lt;br&gt;
fastapi==0.104.1&lt;br&gt;
uvicorn[standard]==0.24.0&lt;br&gt;
pydantic==2.5.0&lt;br&gt;
python-multipart==0.0.6&lt;br&gt;
python-dotenv==1.0.0&lt;br&gt;
EOF&lt;/p&gt;

&lt;p&gt;echo "✓ Requirements created"&lt;/p&gt;

&lt;h1&gt;
  
  
  ==================== PHASE 5: DOCKER CONFIGURATION ====================
&lt;/h1&gt;

&lt;p&gt;echo ""&lt;br&gt;
echo "Phase 5/7: Creating Docker Configuration..."&lt;br&gt;
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"&lt;/p&gt;

&lt;h1&gt;
  
  
  Create Dockerfile
&lt;/h1&gt;

&lt;p&gt;cat &amp;gt; backend/Dockerfile &amp;lt;&amp;lt; 'EOF'&lt;br&gt;
FROM python:3.11-slim&lt;/p&gt;

&lt;p&gt;WORKDIR /app&lt;/p&gt;

&lt;p&gt;RUN apt-get update &amp;amp;&amp;amp; apt-get install -y curl &amp;amp;&amp;amp; rm -rf /var/lib/apt/lists/*&lt;/p&gt;

&lt;p&gt;COPY requirements.txt .&lt;br&gt;
RUN pip install --no-cache-dir -r requirements.txt&lt;/p&gt;

&lt;p&gt;COPY . .&lt;/p&gt;

&lt;p&gt;RUN useradd -m -u 1000 modac &amp;amp;&amp;amp; chown -R modac:modac /app&lt;br&gt;
USER modac&lt;/p&gt;

&lt;p&gt;EXPOSE 8000&lt;/p&gt;

&lt;p&gt;CMD ["python", "-m", "uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]&lt;br&gt;
EOF&lt;/p&gt;

&lt;h1&gt;
  
  
  Create docker-compose
&lt;/h1&gt;

&lt;p&gt;cat &amp;gt; docker-compose.yml &amp;lt;&amp;lt; 'EOF'&lt;br&gt;
version: '3.8'&lt;/p&gt;

&lt;p&gt;services:&lt;br&gt;
  modac-api:&lt;br&gt;
    build:&lt;br&gt;
      context: ./backend&lt;br&gt;
      dockerfile: Dockerfile&lt;br&gt;
    container_name: modac-api&lt;br&gt;
    ports:&lt;br&gt;
      - "8000:8000"&lt;br&gt;
    volumes:&lt;br&gt;
      - ./data:/app/data&lt;br&gt;
      - ./logs:/app/logs&lt;br&gt;
      - ./config:/app/config&lt;br&gt;
    environment:&lt;br&gt;
      - MODAC_ENV=production&lt;br&gt;
      - BLOCKING_ENABLED=true&lt;br&gt;
    restart: unless-stopped&lt;br&gt;
    healthcheck:&lt;br&gt;
      test: ["CMD", "curl", "-f", "&lt;a href="http://localhost:8000/health%22" rel="noopener noreferrer"&gt;http://localhost:8000/health"&lt;/a&gt;]&lt;br&gt;
      interval: 30s&lt;br&gt;
      timeout: 10s&lt;br&gt;
      retries: 3&lt;/p&gt;

&lt;p&gt;modac-dashboard:&lt;br&gt;
    image: nginx:alpine&lt;br&gt;
    container_name: modac-dashboard&lt;br&gt;
    ports:&lt;br&gt;
      - "80:80"&lt;br&gt;
    volumes:&lt;br&gt;
      - ./frontend/dist:/usr/share/nginx/html:ro&lt;br&gt;
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro&lt;br&gt;
    depends_on:&lt;br&gt;
      - modac-api&lt;br&gt;
    restart: unless-stopped&lt;/p&gt;

&lt;p&gt;volumes:&lt;br&gt;
  data:&lt;br&gt;
  logs:&lt;br&gt;
  config:&lt;/p&gt;

&lt;p&gt;networks:&lt;br&gt;
  default:&lt;br&gt;
    name: modac-network&lt;br&gt;
EOF&lt;/p&gt;

&lt;p&gt;echo "✓ Docker configuration created"&lt;/p&gt;

&lt;h1&gt;
  
  
  ==================== PHASE 6: FRONTEND DASHBOARD ====================
&lt;/h1&gt;

&lt;p&gt;echo ""&lt;br&gt;
echo "Phase 6/7: Creating Security Dashboard..."&lt;br&gt;
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"&lt;/p&gt;

&lt;p&gt;cat &amp;gt; frontend/dist/index.html &amp;lt;&amp;lt; 'EOF'&lt;br&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br&gt;
&lt;br&gt;
&lt;/p&gt;
&lt;br&gt;
    &lt;br&gt;
    &lt;br&gt;
    MODAC Security Dashboard
&lt;br&gt;
    &amp;lt;br&amp;gt;
        * { margin: 0; padding: 0; box-sizing: border-box; }&amp;lt;br&amp;gt;
        body {&amp;lt;br&amp;gt;
            font-family: &amp;amp;#39;Segoe UI&amp;amp;#39;, sans-serif;&amp;lt;br&amp;gt;
            background: linear-gradient(135deg, #0a0e27 0%, #1a1f3a 100%);&amp;lt;br&amp;gt;
            color: white;&amp;lt;br&amp;gt;
            padding: 20px;&amp;lt;br&amp;gt;
        }&amp;lt;br&amp;gt;
        .header {&amp;lt;br&amp;gt;
            text-align: center;&amp;lt;br&amp;gt;
            padding: 40px 20px;&amp;lt;br&amp;gt;
            background: linear-gradient(135deg, #1e2749 0%, #2d3561 100%);&amp;lt;br&amp;gt;
            border-radius: 20px;&amp;lt;br&amp;gt;
            margin-bottom: 30px;&amp;lt;br&amp;gt;
            border: 2px solid rgba(0, 255, 255, 0.3);&amp;lt;br&amp;gt;
        }&amp;lt;br&amp;gt;
        h1 { font-size: 42px; margin-bottom: 10px; }&amp;lt;br&amp;gt;
        .subtitle { color: #00ffff; font-size: 18px; }&amp;lt;br&amp;gt;
        .alert {&amp;lt;br&amp;gt;
            background: rgba(255, 51, 102, 0.2);&amp;lt;br&amp;gt;
            border: 2px solid #ff3366;&amp;lt;br&amp;gt;
            padding: 20px;&amp;lt;br&amp;gt;
            border-radius: 15px;&amp;lt;br&amp;gt;
            margin: 20px 0;&amp;lt;br&amp;gt;
            text-align: center;&amp;lt;br&amp;gt;
            font-size: 18px;&amp;lt;br&amp;gt;
            font-weight: bold;&amp;lt;br&amp;gt;
        }&amp;lt;br&amp;gt;
        .stats {&amp;lt;br&amp;gt;
            display: grid;&amp;lt;br&amp;gt;
            grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));&amp;lt;br&amp;gt;
            gap: 20px;&amp;lt;br&amp;gt;
            margin-bottom: 30px;&amp;lt;br&amp;gt;
        }&amp;lt;br&amp;gt;
        .stat-card {&amp;lt;br&amp;gt;
            background: linear-gradient(135deg, #1e2749 0%, #2d3561 100%);&amp;lt;br&amp;gt;
            padding: 30px;&amp;lt;br&amp;gt;
            border-radius: 15px;&amp;lt;br&amp;gt;
            border: 2px solid rgba(0, 255, 255, 0.2);&amp;lt;br&amp;gt;
            text-align: center;&amp;lt;br&amp;gt;
        }&amp;lt;br&amp;gt;
        .stat-value {&amp;lt;br&amp;gt;
            font-size: 48px;&amp;lt;br&amp;gt;
            font-weight: bold;&amp;lt;br&amp;gt;
            color: #00ffff;&amp;lt;br&amp;gt;
            margin: 15px 0;&amp;lt;br&amp;gt;
        }&amp;lt;br&amp;gt;
        .stat-label {&amp;lt;br&amp;gt;
            color: #888;&amp;lt;br&amp;gt;
            font-size: 14px;&amp;lt;br&amp;gt;
            text-transform: uppercase;&amp;lt;br&amp;gt;
        }&amp;lt;br&amp;gt;
        .status-indicator {&amp;lt;br&amp;gt;
            display: inline-block;&amp;lt;br&amp;gt;
            padding: 10px 20px;&amp;lt;br&amp;gt;
            background: rgba(0, 255, 0, 0.2);&amp;lt;br&amp;gt;
            border: 2px solid #00ff00;&amp;lt;br&amp;gt;
            border-radius: 20px;&amp;lt;br&amp;gt;
            margin: 20px 0;&amp;lt;br&amp;gt;
        }&amp;lt;br&amp;gt;
        .btn {&amp;lt;br&amp;gt;
            padding: 15px 30px;&amp;lt;br&amp;gt;
            background: linear-gradient(135deg, #00ffff 0%, #00ccff 100%);&amp;lt;br&amp;gt;
            border: none;&amp;lt;br&amp;gt;
            border-radius: 10px;&amp;lt;br&amp;gt;
            color: #0a0e27;&amp;lt;br&amp;gt;
            font-size: 16px;&amp;lt;br&amp;gt;
            font-weight: bold;&amp;lt;br&amp;gt;
            cursor: pointer;&amp;lt;br&amp;gt;
            margin: 10px;&amp;lt;br&amp;gt;
        }&amp;lt;br&amp;gt;
        .btn:hover { transform: translateY(-2px); box-shadow: 0 6px 20px rgba(0, 255, 255, 0.5); }&amp;lt;br&amp;gt;
    &lt;br&gt;
&lt;br&gt;
&lt;br&gt;
    &lt;br&gt;
        &lt;h1&gt;🛡️ MODAC SECURITY DASHBOARD&lt;/h1&gt;
&lt;br&gt;
        &lt;p&gt;Transaction Blocking &amp;amp; Agent Verification System&lt;/p&gt;
&lt;br&gt;
        &lt;br&gt;
            &lt;span&gt;● SYSTEM ACTIVE&lt;/span&gt; - Transaction Blocking Enabled&lt;br&gt;
        &lt;br&gt;
    
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div class="alert"&amp;gt;
    🚫 DEFAULT MODE: ALL TRANSACTIONS BLOCKED UNTIL AGENTS VERIFIED
&amp;lt;/div&amp;gt;

&amp;lt;div class="stats" id="stats"&amp;gt;
    &amp;lt;div class="stat-card"&amp;gt;
        &amp;lt;div class="stat-label"&amp;gt;Total Agents&amp;lt;/div&amp;gt;
        &amp;lt;div class="stat-value" id="total-agents"&amp;gt;-&amp;lt;/div&amp;gt;
        &amp;lt;div style="font-size: 12px; color: #888;"&amp;gt;Registered in system&amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div class="stat-card"&amp;gt;
        &amp;lt;div class="stat-label"&amp;gt;Verified Agents&amp;lt;/div&amp;gt;
        &amp;lt;div class="stat-value" style="color: #00ff00;" id="verified-agents"&amp;gt;-&amp;lt;/div&amp;gt;
        &amp;lt;div style="font-size: 12px; color: #888;"&amp;gt;Can transact&amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div class="stat-card"&amp;gt;
        &amp;lt;div class="stat-label"&amp;gt;Transactions Blocked&amp;lt;/div&amp;gt;
        &amp;lt;div class="stat-value" style="color: #ff3366;" id="blocked-txns"&amp;gt;-&amp;lt;/div&amp;gt;
        &amp;lt;div style="font-size: 12px; color: #888;"&amp;gt;Unverified agents&amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div class="stat-card"&amp;gt;
        &amp;lt;div class="stat-label"&amp;gt;Transactions Approved&amp;lt;/div&amp;gt;
        &amp;lt;div class="stat-value" style="color: #00ff00;" id="approved-txns"&amp;gt;-&amp;lt;/div&amp;gt;
        &amp;lt;div style="font-size: 12px; color: #888;"&amp;gt;Verified agents only&amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;div style="text-align: center; padding: 30px;"&amp;gt;
    &amp;lt;button class="btn" onclick="registerAgent()"&amp;gt;➕ Register Agent&amp;lt;/button&amp;gt;
    &amp;lt;button class="btn" onclick="viewRegistry()"&amp;gt;📋 View Registry&amp;lt;/button&amp;gt;
    &amp;lt;button class="btn" onclick="viewBlocked()"&amp;gt;🚫 View Blocked&amp;lt;/button&amp;gt;
    &amp;lt;button class="btn" onclick="window.location.href='/api/v1/system/status'"&amp;gt;📊 API Status&amp;lt;/button&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;script&amp;gt;
    async function loadStats() {
        try {
            const response = await fetch('/api/v1/system/status');
            const data = await response.json();

            document.getElementById('total-agents').textContent = data.agents.total;
            document.getElementById('verified-agents').textContent = data.agents.verified;
            document.getElementById('blocked-txns').textContent = data.transactions.blocked;
            document.getElementById('approved-txns').textContent = data.transactions.approved;
        } catch (error) {
            console.error('Error loading stats:', error);
        }
    }

    function registerAgent() {
        alert('Agent Registration:\n\n1. Submit agent details\n2. Provide identity proof\n3. Complete KYC verification\n4. Security screening\n5. Get VERIFIED status\n\nOnly then can agent transact!');
    }

    function viewRegistry() {
        window.open('/api/v1/system/status', '_blank');
    }

    function viewBlocked() {
        alert('Blocked Transactions:\n\nAll transactions from unverified agents are automatically blocked.\n\nAgents must complete verification before any transactions are allowed.');
    }

    // Load stats on page load and refresh every 10 seconds
    loadStats();
    setInterval(loadStats, 10000);
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;br&gt;
&lt;br&gt;
EOF&lt;/p&gt;

&lt;h1&gt;
  
  
  Create NGINX config
&lt;/h1&gt;

&lt;p&gt;mkdir -p nginx&lt;br&gt;
cat &amp;gt; nginx/nginx.conf &amp;lt;&amp;lt; 'EOF'&lt;br&gt;
events { worker_connections 1024; }&lt;/p&gt;

&lt;p&gt;http {&lt;br&gt;
    upstream api {&lt;br&gt;
        server modac-api:8000;&lt;br&gt;
    }&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;server {
    listen 80;
    server_name localhost;

    location / {
        root /usr/share/nginx/html;
        index index.html;
        try_files $uri $uri/ /index.html;
    }

    location /api/ {
        proxy_pass http://api;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    location /health {
        proxy_pass http://api/health;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;}&lt;br&gt;
EOF&lt;/p&gt;

&lt;p&gt;echo "✓ Dashboard created"&lt;/p&gt;

&lt;h1&gt;
  
  
  ==================== PHASE 7: DEPLOYMENT SCRIPTS ====================
&lt;/h1&gt;

&lt;p&gt;echo ""&lt;br&gt;
echo "Phase 7/7: Creating Deployment Scripts..."&lt;br&gt;
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"&lt;/p&gt;

&lt;h1&gt;
  
  
  Create start script
&lt;/h1&gt;

&lt;p&gt;cat &amp;gt; start.sh &amp;lt;&amp;lt; 'EOF'&lt;/p&gt;

&lt;h1&gt;
  
  
  !/bin/bash
&lt;/h1&gt;

&lt;p&gt;echo "🚀 Starting MODAC Global System..."&lt;br&gt;
echo ""&lt;/p&gt;

&lt;h1&gt;
  
  
  Build and start
&lt;/h1&gt;

&lt;p&gt;docker-compose up -d --build&lt;/p&gt;

&lt;p&gt;echo ""&lt;br&gt;
echo "Waiting for services..."&lt;br&gt;
sleep 10&lt;/p&gt;

&lt;h1&gt;
  
  
  Health check
&lt;/h1&gt;

&lt;p&gt;if curl -f &lt;a href="http://localhost:8000/health" rel="noopener noreferrer"&gt;http://localhost:8000/health&lt;/a&gt; &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then&lt;br&gt;
    echo "✅ API is healthy"&lt;br&gt;
else&lt;br&gt;
    echo "❌ API health check failed"&lt;br&gt;
fi&lt;/p&gt;

&lt;p&gt;echo ""&lt;br&gt;
echo "╔══════════════════════════════════════════════════════════════════╗"&lt;br&gt;
echo "║                 MODAC SYSTEM DEPLOYED!                           ║"&lt;br&gt;
echo "╠══════════════════════════════════════════════════════════════════╣"&lt;br&gt;
echo "║  Dashboard:  &lt;a href="http://localhost" rel="noopener noreferrer"&gt;http://localhost&lt;/a&gt;                                    ║"&lt;br&gt;
echo "║  API:        &lt;a href="http://localhost:8000" rel="noopener noreferrer"&gt;http://localhost:8000&lt;/a&gt;                               ║"&lt;br&gt;
echo "║  API Docs:   &lt;a href="http://localhost:8000/docs" rel="noopener noreferrer"&gt;http://localhost:8000/docs&lt;/a&gt;                          ║"&lt;br&gt;
echo "║  Status:     &lt;a href="http://localhost:8000/api/v1/system/status" rel="noopener noreferrer"&gt;http://localhost:8000/api/v1/system/status&lt;/a&gt;          ║"&lt;br&gt;
echo "╠══════════════════════════════════════════════════════════════════╣"&lt;br&gt;
echo "║  🛡️  TRANSACTION BLOCKING: ENABLED                              ║"&lt;br&gt;
echo "║  🚫 DEFAULT: Block all unverified agents                        ║"&lt;br&gt;
echo "╚══════════════════════════════════════════════════════════════════╝"&lt;br&gt;
EOF&lt;/p&gt;

&lt;p&gt;chmod +x start.sh&lt;/p&gt;

&lt;h1&gt;
  
  
  Create stop script
&lt;/h1&gt;

&lt;p&gt;cat &amp;gt; stop.sh &amp;lt;&amp;lt; 'EOF'&lt;/p&gt;

&lt;h1&gt;
  
  
  !/bin/bash
&lt;/h1&gt;

&lt;p&gt;echo "Stopping MODAC..."&lt;br&gt;
docker-compose down&lt;br&gt;
echo "✓ MODAC stopped"&lt;br&gt;
EOF&lt;/p&gt;

&lt;p&gt;chmod +x stop.sh&lt;/p&gt;

&lt;h1&gt;
  
  
  Create test script
&lt;/h1&gt;

&lt;p&gt;cat &amp;gt; test_blocking.sh &amp;lt;&amp;lt; 'EOF'&lt;/p&gt;

&lt;h1&gt;
  
  
  !/bin/bash
&lt;/h1&gt;

&lt;p&gt;echo "Testing Transaction Blocking..."&lt;br&gt;
echo ""&lt;/p&gt;

&lt;p&gt;API="&lt;a href="http://localhost:8000" rel="noopener noreferrer"&gt;http://localhost:8000&lt;/a&gt;"&lt;/p&gt;

&lt;p&gt;echo "Test 1: Attempt transaction with unverified agents"&lt;br&gt;
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"&lt;br&gt;
curl -X POST "$API/api/v1/transactions/execute" \&lt;br&gt;
  -H "Content-Type: application/json" \&lt;br&gt;
  -d '{&lt;br&gt;
    "buyer_agent_id": "unverified_001",&lt;br&gt;
    "seller_agent_id": "unverified_002",&lt;br&gt;
    "amount": 1000,&lt;br&gt;
    "currency": "USD"&lt;br&gt;
  }' | jq .&lt;/p&gt;

&lt;p&gt;echo ""&lt;br&gt;
echo ""&lt;br&gt;
echo "Expected: Transaction BLOCKED ❌"&lt;br&gt;
echo ""&lt;br&gt;
EOF&lt;/p&gt;

&lt;p&gt;chmod +x test_blocking.sh&lt;/p&gt;

&lt;p&gt;echo "✓ Deployment scripts created"&lt;/p&gt;

&lt;h1&gt;
  
  
  ==================== FINAL SETUP ====================
&lt;/h1&gt;

&lt;p&gt;echo ""&lt;br&gt;
echo "Final Setup..."&lt;br&gt;
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"&lt;/p&gt;

&lt;h1&gt;
  
  
  Create empty registry
&lt;/h1&gt;

&lt;p&gt;mkdir -p data/registry&lt;br&gt;
echo "{}" &amp;gt; data/registry/agents.json&lt;/p&gt;

&lt;h1&gt;
  
  
  Create README
&lt;/h1&gt;

&lt;p&gt;cat &amp;gt; README.md &amp;lt;&amp;lt; 'EOF'&lt;/p&gt;

&lt;h1&gt;
  
  
  MODAC GLOBAL SYSTEM
&lt;/h1&gt;

&lt;p&gt;Complete deployment with transaction blocking and agent verification.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Start
&lt;/h2&gt;



&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Start system&lt;/span&gt;
./start.sh

&lt;span class="c"&gt;# View dashboard&lt;/span&gt;
http://localhost

&lt;span class="c"&gt;# Test blocking&lt;/span&gt;
./test_blocking.sh

&lt;span class="c"&gt;# Stop system&lt;/span&gt;
./stop.sh
&lt;/code&gt;&lt;/pre&gt;



&lt;h2&gt;
  
  
  Security Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;✅ Transaction blocking enabled by default&lt;/li&gt;
&lt;li&gt;✅ All agents must register and verify&lt;/li&gt;
&lt;li&gt;✅ Real-time monitoring of all transactions&lt;/li&gt;
&lt;li&gt;✅ Automatic blocking of unverified agents&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  API Endpoints
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;POST /api/v1/agents/register&lt;/code&gt; - Register new agent&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;POST /api/v1/agents/{id}/verify&lt;/code&gt; - Verify agent&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;POST /api/v1/transactions/execute&lt;/code&gt; - Execute transaction (blocked if unverified)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GET /api/v1/system/status&lt;/code&gt; - System status&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How It Works
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Agent attempts transaction&lt;/li&gt;
&lt;li&gt;MODAC intercepts transaction&lt;/li&gt;
&lt;li&gt;Checks if both agents are verified&lt;/li&gt;
&lt;li&gt;If NOT verified → BLOCKS transaction&lt;/li&gt;
&lt;li&gt;If verified → APPROVES transaction&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;DEFAULT: Everything is BLOCKED until verified!&lt;/strong&gt;&lt;br&gt;
EOF&lt;/p&gt;

&lt;p&gt;echo "✓ Setup complete"&lt;/p&gt;

&lt;h1&gt;
  
  
  ==================== DEPLOYMENT COMPLETE ====================
&lt;/h1&gt;

&lt;p&gt;echo ""&lt;br&gt;
echo "╔══════════════════════════════════════════════════════════════════════╗"&lt;br&gt;
echo "║                                                                      ║"&lt;br&gt;
echo "║               🎉 MODAC DEPLOYMENT COMPLETE! 🎉                      ║"&lt;br&gt;
echo "║                                                                      ║"&lt;br&gt;
echo "╚══════════════════════════════════════════════════════════════════════╝"&lt;br&gt;
echo ""&lt;br&gt;
echo "✅ All components installed:"&lt;br&gt;
echo "   • Transaction Blocking System"&lt;br&gt;
echo "   • Agent Registry"&lt;br&gt;
echo "   • Verification System"&lt;br&gt;
echo "   • Security Dashboard"&lt;br&gt;
echo "   • API with blocking enforcement"&lt;br&gt;
echo ""&lt;br&gt;
echo "🚀 Ready to deploy! Run:"&lt;br&gt;
echo "   ./start.sh"&lt;br&gt;
echo ""&lt;br&gt;
echo "📊 Then visit:"&lt;br&gt;
echo "   &lt;a href="http://localhost" rel="noopener noreferrer"&gt;http://localhost&lt;/a&gt; - Security Dashboard"&lt;br&gt;
echo "   &lt;a href="http://localhost:8000/docs" rel="noopener noreferrer"&gt;http://localhost:8000/docs&lt;/a&gt; - API Documentation"&lt;br&gt;
echo ""&lt;br&gt;
echo "🛡️  SECURITY STATUS:"&lt;br&gt;
echo "   ✓ Transaction blocking: ENABLED"&lt;br&gt;
echo "   ✓ Agent verification: REQUIRED"&lt;br&gt;
echo "   ✓ Default mode: BLOCK ALL"&lt;br&gt;
echo ""This is a submission for the &lt;a href="https://dev.to/challenges/github-2026-05-21"&gt;GitHub Finish-Up-A-Thon Challenge&lt;/a&gt;*&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;h2&gt;
  
  
  The Comeback Story
&lt;/h2&gt;

&lt;h2&gt;
  
  
  My Experience with GitHub Copilot
&lt;/h2&gt;

</description>
      <category>devchallenge</category>
      <category>githubchallenge</category>
    </item>
    <item>
      <title>HERMES AGENT SUMMISSIO</title>
      <dc:creator>Gift Trust</dc:creator>
      <pubDate>Wed, 20 May 2026 06:35:40 +0000</pubDate>
      <link>https://dev.to/gift_trust_44882a016531d7/hermes-agent-summissio-2op2</link>
      <guid>https://dev.to/gift_trust_44882a016531d7/hermes-agent-summissio-2op2</guid>
      <description>&lt;p&gt;*# How I Built an Agentic Layer on AIRTIMES Using Hermes Agent&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A submission for the &lt;a href="https://dev.to/challenges/hermes-agent-2026-05-15"&gt;Hermes Agent Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What is AIRTIMES?
&lt;/h2&gt;

&lt;p&gt;AIRTIMES is a zero-dependency global data and service network I built from scratch — a full-stack Node.js backend featuring &lt;strong&gt;AirPay&lt;/strong&gt; (a crypto payment module) and &lt;strong&gt;AirBank&lt;/strong&gt; (a revenue tracking engine). No external libraries. No cloud lock-in. Every byte of it runs on infrastructure I control.&lt;/p&gt;

&lt;p&gt;It's the kind of platform that's always generating data — transactions, node health events, revenue streams — but has no brain to interpret that data in real time. That's exactly the gap I wanted to close.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem: Infrastructure Without Intelligence
&lt;/h2&gt;

&lt;p&gt;AIRTIMES processes payments and tracks revenue across nodes. But monitoring it meant either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Staring at logs manually&lt;/li&gt;
&lt;li&gt;Writing one-off scripts that break and never improve&lt;/li&gt;
&lt;li&gt;Paying for a SaaS dashboard that doesn't understand my custom data model&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of those felt right. What I needed was an agent that could &lt;strong&gt;live inside the platform&lt;/strong&gt;, understand its data, react to events, and — crucially — get smarter the longer it ran.&lt;/p&gt;

&lt;p&gt;That's when I found &lt;strong&gt;Hermes Agent&lt;/strong&gt; by Nous Research.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Hermes?
&lt;/h2&gt;

&lt;p&gt;Most agent frameworks are graphs you design ahead of time. You wire the nodes, define the flows, and ship. The agent's capability is permanently bounded by what you prompted into it on day one.&lt;/p&gt;

&lt;p&gt;Hermes is different. It has a &lt;strong&gt;built-in learning loop&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After completing a complex task, it &lt;strong&gt;automatically writes a reusable skill&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Skills &lt;strong&gt;self-improve&lt;/strong&gt; every time they're used&lt;/li&gt;
&lt;li&gt;It builds a &lt;strong&gt;persistent memory&lt;/strong&gt; of your projects across sessions&lt;/li&gt;
&lt;li&gt;It runs &lt;strong&gt;unattended automations&lt;/strong&gt; via natural language cron scheduling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For AIRTIMES — a platform that runs 24/7 — this is exactly the right architecture.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Built: The AIRTIMES Agentic Layer
&lt;/h2&gt;

&lt;p&gt;I installed Hermes directly on the AIRTIMES server and gave it three jobs.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. AirPay Transaction Monitor
&lt;/h3&gt;

&lt;p&gt;Hermes watches the AirPay transaction stream continuously. When a payment fails, it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Diagnoses the failure (network timeout? invalid address? insufficient funds?)&lt;/li&gt;
&lt;li&gt;Triggers the retry logic&lt;/li&gt;
&lt;li&gt;Logs a structured incident report&lt;/li&gt;
&lt;li&gt;Sends a Telegram alert to my phone&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The first time it did this, it wrote a skill called &lt;code&gt;airpay_failure_diagnosis.skill&lt;/code&gt; automatically. The next failure? It handled in seconds — no manual input.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. AirBank Daily Revenue Briefing
&lt;/h3&gt;

&lt;p&gt;Every morning at 8am, Hermes pulls from the AirBank revenue engine and delivers a plain-language summary:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;📊 AIRBANK DAILY BRIEF — May 20, 2026
Revenue: $4,820 (+12% vs yesterday)
Top node: Node 3 ($1,240)
Anomaly: Node 7 — 0 transactions since 03:00 UTC
Action: Pinging Node 7 now...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Set up with one command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hermes cron &lt;span class="s2"&gt;"every day at 8am run airbank_daily_brief"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No dashboard. No manual query. Just a brief, every morning, in my Telegram.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Multi-Platform Command Surface
&lt;/h3&gt;

&lt;p&gt;I connected Hermes to Telegram so I can command the entire AIRTIMES infrastructure in plain language from my phone:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What's total AirPay revenue this week?"&lt;br&gt;
"Is Node 7 online?"&lt;br&gt;
"How many transactions failed in the last 24 hours?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hermes fetches, reasons, and responds. It works on Telegram, Discord, Slack, and CLI — all from a single gateway process.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Self-Improving Loop in Action
&lt;/h2&gt;

&lt;p&gt;This is what separates Hermes from every other agent I've used.&lt;/p&gt;

&lt;p&gt;After three days of running on AIRTIMES, Hermes had automatically generated &lt;strong&gt;6 custom skills&lt;/strong&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Skill&lt;/th&gt;
&lt;th&gt;Trigger&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;airpay_failure_diagnosis.skill&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;First payment failure investigation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;node_health_check.skill&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;First uptime check across nodes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;revenue_anomaly_alert.skill&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;First time it spotted a revenue dip&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;airbank_daily_brief.skill&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;After the first manual briefing request&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;multi_node_ping.skill&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;After diagnosing Node 7 offline&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tx_retry_handler.skill&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;After the second payment retry sequence&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;I didn't write any of these. Hermes wrote them itself — and every subsequent run of the same task was faster and more accurate because the skill had been refined.&lt;/p&gt;




&lt;h2&gt;
  
  
  Installation (60 seconds)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install Hermes&lt;/span&gt;
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://hermes-agent.nousresearch.com/install.sh | bash

&lt;span class="c"&gt;# Run setup wizard&lt;/span&gt;
hermes setup

&lt;span class="c"&gt;# Connect Telegram&lt;/span&gt;
hermes setup &lt;span class="nt"&gt;--gateway&lt;/span&gt; telegram

&lt;span class="c"&gt;# Point it at your project&lt;/span&gt;
hermes chat &lt;span class="s2"&gt;"I have a Node.js server running AIRTIMES on port 3000. 
Monitor transaction health and report anomalies."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  What This Changes
&lt;/h2&gt;

&lt;p&gt;AIRTIMES used to be infrastructure I managed. Now it's infrastructure that manages itself — with me as the oversight layer, not the execution layer.&lt;/p&gt;

&lt;p&gt;Hermes doesn't just execute tasks. It &lt;strong&gt;accumulates operational knowledge&lt;/strong&gt; about AIRTIMES: which nodes fail most often, what payment patterns precede failures, which revenue anomalies are noise vs. signal. That knowledge compounds.&lt;/p&gt;

&lt;p&gt;Six months from now, the version of Hermes running on AIRTIMES will be meaningfully smarter than the version I installed today — without me touching a line of code.&lt;/p&gt;

&lt;p&gt;That's the promise of a self-improving agent. And for a global infrastructure platform like AIRTIMES, that's not a nice-to-have. It's the only architecture that makes sense.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Expanding Hermes to manage AIREXPRESS (EV mesh connectivity dashboard)&lt;/li&gt;
&lt;li&gt;Building a public &lt;code&gt;agentskills.io&lt;/code&gt; skill pack for AIRTIMES operators&lt;/li&gt;
&lt;li&gt;Exploring batch trajectory generation for training a domain-specific AIRTIMES model&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🔗 &lt;a href="https://hermes-agent.nousresearch.com" rel="noopener noreferrer"&gt;Hermes Agent&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🔗 &lt;a href="https://github.com/NousResearch/hermes-agent" rel="noopener noreferrer"&gt;GitHub — NousResearch/hermes-agent&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🔗 &lt;a href="https://dev.to/challenges/hermes-agent-2026-05-15"&gt;Hermes Agent Challenge&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Built with Hermes Agent by Nous Research · MIT License&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Tags: #hermesagentchallenge #devchallenge #agents #opensource&lt;/em&gt;&lt;br&gt;
 is a submission for the &lt;a href="https://dev.to/challenges/hermes-agent-2026-05-15"&gt;Hermes Agent Challenge&lt;/a&gt;*&lt;/p&gt;

</description>
      <category>hermesagentchallenge</category>
      <category>devchallenge</category>
      <category>agents</category>
    </item>
    <item>
      <title>HERMES AGENT WRITE UP SUMMISSIO</title>
      <dc:creator>Gift Trust</dc:creator>
      <pubDate>Wed, 20 May 2026 06:33:50 +0000</pubDate>
      <link>https://dev.to/gift_trust_44882a016531d7/hermes-agent-write-up-summissio-3o1e</link>
      <guid>https://dev.to/gift_trust_44882a016531d7/hermes-agent-write-up-summissio-3o1e</guid>
      <description>&lt;p&gt;*# How I Built an Agentic Layer on AIRTIMES Using Hermes Agent&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A submission for the &lt;a href="https://dev.to/challenges/hermes-agent-2026-05-15"&gt;Hermes Agent Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What is AIRTIMES?
&lt;/h2&gt;

&lt;p&gt;AIRTIMES is a zero-dependency global data and service network I built from scratch — a full-stack Node.js backend featuring &lt;strong&gt;AirPay&lt;/strong&gt; (a crypto payment module) and &lt;strong&gt;AirBank&lt;/strong&gt; (a revenue tracking engine). No external libraries. No cloud lock-in. Every byte of it runs on infrastructure I control.&lt;/p&gt;

&lt;p&gt;It's the kind of platform that's always generating data — transactions, node health events, revenue streams — but has no brain to interpret that data in real time. That's exactly the gap I wanted to close.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem: Infrastructure Without Intelligence
&lt;/h2&gt;

&lt;p&gt;AIRTIMES processes payments and tracks revenue across nodes. But monitoring it meant either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Staring at logs manually&lt;/li&gt;
&lt;li&gt;Writing one-off scripts that break and never improve&lt;/li&gt;
&lt;li&gt;Paying for a SaaS dashboard that doesn't understand my custom data model&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of those felt right. What I needed was an agent that could &lt;strong&gt;live inside the platform&lt;/strong&gt;, understand its data, react to events, and — crucially — get smarter the longer it ran.&lt;/p&gt;

&lt;p&gt;That's when I found &lt;strong&gt;Hermes Agent&lt;/strong&gt; by Nous Research.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Hermes?
&lt;/h2&gt;

&lt;p&gt;Most agent frameworks are graphs you design ahead of time. You wire the nodes, define the flows, and ship. The agent's capability is permanently bounded by what you prompted into it on day one.&lt;/p&gt;

&lt;p&gt;Hermes is different. It has a &lt;strong&gt;built-in learning loop&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After completing a complex task, it &lt;strong&gt;automatically writes a reusable skill&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Skills &lt;strong&gt;self-improve&lt;/strong&gt; every time they're used&lt;/li&gt;
&lt;li&gt;It builds a &lt;strong&gt;persistent memory&lt;/strong&gt; of your projects across sessions&lt;/li&gt;
&lt;li&gt;It runs &lt;strong&gt;unattended automations&lt;/strong&gt; via natural language cron scheduling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For AIRTIMES — a platform that runs 24/7 — this is exactly the right architecture.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Built: The AIRTIMES Agentic Layer
&lt;/h2&gt;

&lt;p&gt;I installed Hermes directly on the AIRTIMES server and gave it three jobs.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. AirPay Transaction Monitor
&lt;/h3&gt;

&lt;p&gt;Hermes watches the AirPay transaction stream continuously. When a payment fails, it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Diagnoses the failure (network timeout? invalid address? insufficient funds?)&lt;/li&gt;
&lt;li&gt;Triggers the retry logic&lt;/li&gt;
&lt;li&gt;Logs a structured incident report&lt;/li&gt;
&lt;li&gt;Sends a Telegram alert to my phone&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The first time it did this, it wrote a skill called &lt;code&gt;airpay_failure_diagnosis.skill&lt;/code&gt; automatically. The next failure? It handled in seconds — no manual input.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. AirBank Daily Revenue Briefing
&lt;/h3&gt;

&lt;p&gt;Every morning at 8am, Hermes pulls from the AirBank revenue engine and delivers a plain-language summary:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;📊 AIRBANK DAILY BRIEF — May 20, 2026
Revenue: $4,820 (+12% vs yesterday)
Top node: Node 3 ($1,240)
Anomaly: Node 7 — 0 transactions since 03:00 UTC
Action: Pinging Node 7 now...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Set up with one command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hermes cron &lt;span class="s2"&gt;"every day at 8am run airbank_daily_brief"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No dashboard. No manual query. Just a brief, every morning, in my Telegram.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Multi-Platform Command Surface
&lt;/h3&gt;

&lt;p&gt;I connected Hermes to Telegram so I can command the entire AIRTIMES infrastructure in plain language from my phone:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What's total AirPay revenue this week?"&lt;br&gt;
"Is Node 7 online?"&lt;br&gt;
"How many transactions failed in the last 24 hours?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hermes fetches, reasons, and responds. It works on Telegram, Discord, Slack, and CLI — all from a single gateway process.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Self-Improving Loop in Action
&lt;/h2&gt;

&lt;p&gt;This is what separates Hermes from every other agent I've used.&lt;/p&gt;

&lt;p&gt;After three days of running on AIRTIMES, Hermes had automatically generated &lt;strong&gt;6 custom skills&lt;/strong&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Skill&lt;/th&gt;
&lt;th&gt;Trigger&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;airpay_failure_diagnosis.skill&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;First payment failure investigation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;node_health_check.skill&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;First uptime check across nodes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;revenue_anomaly_alert.skill&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;First time it spotted a revenue dip&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;airbank_daily_brief.skill&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;After the first manual briefing request&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;multi_node_ping.skill&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;After diagnosing Node 7 offline&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tx_retry_handler.skill&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;After the second payment retry sequence&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;I didn't write any of these. Hermes wrote them itself — and every subsequent run of the same task was faster and more accurate because the skill had been refined.&lt;/p&gt;




&lt;h2&gt;
  
  
  Installation (60 seconds)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install Hermes&lt;/span&gt;
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://hermes-agent.nousresearch.com/install.sh | bash

&lt;span class="c"&gt;# Run setup wizard&lt;/span&gt;
hermes setup

&lt;span class="c"&gt;# Connect Telegram&lt;/span&gt;
hermes setup &lt;span class="nt"&gt;--gateway&lt;/span&gt; telegram

&lt;span class="c"&gt;# Point it at your project&lt;/span&gt;
hermes chat &lt;span class="s2"&gt;"I have a Node.js server running AIRTIMES on port 3000. 
Monitor transaction health and report anomalies."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  What This Changes
&lt;/h2&gt;

&lt;p&gt;AIRTIMES used to be infrastructure I managed. Now it's infrastructure that manages itself — with me as the oversight layer, not the execution layer.&lt;/p&gt;

&lt;p&gt;Hermes doesn't just execute tasks. It &lt;strong&gt;accumulates operational knowledge&lt;/strong&gt; about AIRTIMES: which nodes fail most often, what payment patterns precede failures, which revenue anomalies are noise vs. signal. That knowledge compounds.&lt;/p&gt;

&lt;p&gt;Six months from now, the version of Hermes running on AIRTIMES will be meaningfully smarter than the version I installed today — without me touching a line of code.&lt;/p&gt;

&lt;p&gt;That's the promise of a self-improving agent. And for a global infrastructure platform like AIRTIMES, that's not a nice-to-have. It's the only architecture that makes sense.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Expanding Hermes to manage AIREXPRESS (EV mesh connectivity dashboard)&lt;/li&gt;
&lt;li&gt;Building a public &lt;code&gt;agentskills.io&lt;/code&gt; skill pack for AIRTIMES operators&lt;/li&gt;
&lt;li&gt;Exploring batch trajectory generation for training a domain-specific AIRTIMES model&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🔗 &lt;a href="https://hermes-agent.nousresearch.com" rel="noopener noreferrer"&gt;Hermes Agent&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🔗 &lt;a href="https://github.com/NousResearch/hermes-agent" rel="noopener noreferrer"&gt;GitHub — NousResearch/hermes-agent&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🔗 &lt;a href="https://dev.to/challenges/hermes-agent-2026-05-15"&gt;Hermes Agent Challenge&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Built with Hermes Agent by Nous Research · MIT License&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Tags: #hermesagentchallenge #devchallenge #agents #opensource&lt;/em&gt;&lt;br&gt;
 is a submission for the &lt;a href="https://dev.to/challenges/hermes-agent-2026-05-15"&gt;Hermes Agent Challenge&lt;/a&gt;*&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;h3&gt;
  
  
  My Tech Stack
&lt;/h3&gt;

&lt;h2&gt;
  
  
  How I Used Hermes Agent
&lt;/h2&gt;

</description>
      <category>hermesagentchallenge</category>
      <category>devchallenge</category>
      <category>agents</category>
    </item>
    <item>
      <title>Gender Equality means equal data and service for everyone</title>
      <dc:creator>Gift Trust</dc:creator>
      <pubDate>Sun, 05 Apr 2026 02:13:35 +0000</pubDate>
      <link>https://dev.to/gift_trust_44882a016531d7/gender-equality-means-equal-data-and-service-for-everyone-52kl</link>
      <guid>https://dev.to/gift_trust_44882a016531d7/gender-equality-means-equal-data-and-service-for-everyone-52kl</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/wecoded-2026"&gt;2026 WeCoded Challenge&lt;/a&gt;: Echoes of Experience&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>wecoded</category>
      <category>dei</category>
      <category>career</category>
    </item>
    <item>
      <title>Everyone Deserves Equal rights and benefits, because we all are going to die on Day 🌹.</title>
      <dc:creator>Gift Trust</dc:creator>
      <pubDate>Sun, 05 Apr 2026 02:11:36 +0000</pubDate>
      <link>https://dev.to/gift_trust_44882a016531d7/everyone-deserves-equal-rights-and-benefits-because-we-all-are-going-to-die-on-day--1g8e</link>
      <guid>https://dev.to/gift_trust_44882a016531d7/everyone-deserves-equal-rights-and-benefits-because-we-all-are-going-to-die-on-day--1g8e</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/wecoded-2026"&gt;2026 WeCoded Challenge&lt;/a&gt;: Frontend Art&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Show us your Art
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Inspiration
&lt;/h2&gt;

&lt;h2&gt;
  
  
  My Code
&lt;/h2&gt;

</description>
      <category>wecoded</category>
      <category>devchallenge</category>
      <category>frontend</category>
      <category>css</category>
    </item>
    <item>
      <title>AIRTIMES SERVER, server that gives free data and service Network</title>
      <dc:creator>Gift Trust</dc:creator>
      <pubDate>Sun, 05 Apr 2026 01:59:26 +0000</pubDate>
      <link>https://dev.to/gift_trust_44882a016531d7/airtimes-server-server-that-gives-free-data-and-service-network-349j</link>
      <guid>https://dev.to/gift_trust_44882a016531d7/airtimes-server-server-that-gives-free-data-and-service-network-349j</guid>
      <description>&lt;p&gt;*&amp;lt;!DOCTYPE html&amp;gt;&lt;br&gt;
&lt;br&gt;
&lt;/p&gt;
&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
AIRTIMES — Global Network
&lt;br&gt;



  :root {
    --bg: #020508; --surface: #060d14; --accent: #00ffe0;
    --accent2: #0077ff; --accent3: #ff4d6d;
    --text: #c8e8ff; --muted: #3a5570;
    --glow: 0 0 30px rgba(0,255,224,0.25);
  }
  *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
  body { background: var(--bg); color: var(--text); font-family: 'Space Mono', monospace; overflow-x: hidden; }

  .bg-layer { position: fixed; inset: 0; z-index: 0; pointer-events: none;
    background: radial-gradient(ellipse 80% 60% at 20% 10%, rgba(0,119,255,0.07) 0%, transparent 70%),
                radial-gradient(ellipse 60% 50% at 80% 80%, rgba(0,255,224,0.06) 0%, transparent 70%); }

  .grid-overlay { position: fixed; inset: 0; z-index: 0; pointer-events: none;
    background-image: linear-gradient(rgba(0,255,224,0.04) 1px, transparent 1px),
                      linear-gradient(90deg, rgba(0,255,224,0.04) 1px, transparent 1px);
    background-size: 48px 48px; animation: gridDrift 30s linear infinite; }
  @keyframes gridDrift { to { background-position: 48px 48px; } }

  .shell { position: relative; z-index: 2; }

  nav {
    display: flex; align-items: center; justify-content: space-between;
    padding: 18px 40px; border-bottom: 1px solid rgba(0,255,224,0.1);
    backdrop-filter: blur(12px); position: sticky; top: 0; z-index: 100;
    background: rgba(2,5,8,0.85);
  }
  .logo { font-family: 'Bebas Neue'; font-size: 1.9rem; letter-spacing: 0.25em;
    color: var(--accent); text-shadow: 0 0 24px rgba(0,255,224,0.5); position: relative; }
  .logo::after { content: '●'; font-size: 0.35em; color: var(--accent3);
    position: absolute; top: 4px; right: -14px; animation: blink 1.4s step-end infinite; }
  @keyframes blink { 50% { opacity: 0; } }
  .nav-links { display: flex; gap: 28px; list-style: none; }
  .nav-links a { color: var(--muted); text-decoration: none; font-size: 0.7rem;
    letter-spacing: 0.15em; text-transform: uppercase; transition: color 0.2s; }
  .nav-links a:hover { color: var(--accent); }
  .status-pill { display: flex; align-items: center; gap: 8px; font-size: 0.65rem;
    color: var(--accent); letter-spacing: 0.12em; }
  .pulse { width: 7px; height: 7px; border-radius: 50%; background: var(--accent);
    box-shadow: 0 0 8px var(--accent); animation: blink 1.4s step-end infinite; }

  /* HERO */
  .hero { display: grid; grid-template-columns: 1fr 1fr; gap: 60px; align-items: center;
    padding: 80px 40px 60px; max-width: 1300px; margin: 0 auto; }
  .hero-tag { font-size: 0.65rem; letter-spacing: 0.25em; text-transform: uppercase;
    color: var(--accent2); margin-bottom: 14px; display: flex; align-items: center; gap: 10px; }
  .hero-tag::before { content: ''; width: 30px; height: 1px; background: var(--accent2); }
  h1 { font-family: 'Bebas Neue'; font-size: clamp(3.5rem, 7vw, 6.5rem);
    line-height: 0.92; letter-spacing: 0.05em; color: #fff; margin-bottom: 22px; }
  h1 .t { color: var(--accent); text-shadow: 0 0 25px rgba(0,255,224,0.4); }
  h1 .r { color: var(--accent3); }
  .hero-desc { font-size: 0.82rem; line-height: 1.9; color: var(--muted); max-width: 420px; margin-bottom: 36px; }
  .hero-actions { display: flex; gap: 14px; flex-wrap: wrap; }
  .btn { border: none; padding: 13px 28px; font-family: 'Space Mono'; font-size: 0.72rem;
    font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase; cursor: pointer; transition: all 0.25s; }
  .btn-primary { background: var(--accent); color: #000;
    clip-path: polygon(0 0, calc(100% - 10px) 0, 100% 10px, 100% 100%, 0 100%); }
  .btn-primary:hover { box-shadow: var(--glow); transform: translateY(-2px); }
  .btn-secondary { background: transparent; color: var(--text); border: 1px solid var(--muted); }
  .btn-secondary:hover { border-color: var(--accent); color: var(--accent); }

  /* GLOBE */
  .globe-wrap { position: relative; display: flex; align-items: center; justify-content: center; height: 440px; }
  .globe { width: 320px; height: 320px; border-radius: 50%;
    background: radial-gradient(circle at 35% 35%, rgba(0,119,255,0.25), transparent 60%),
                radial-gradient(circle at 50% 50%, #020d1a 40%, #010608 100%);
    border: 1px solid rgba(0,255,224,0.15);
    box-shadow: 0 0 80px rgba(0,119,255,0.2), inset 0 0 60px rgba(0,119,255,0.1);
    animation: globePulse 6s ease-in-out infinite; }
  @keyframes globePulse {
    50% { box-shadow: 0 0 120px rgba(0,119,255,0.35), inset 0 0 80px rgba(0,119,255,0.15); } }
  .orbit { position: absolute; border-radius: 50%; border: 1px solid rgba(0,255,224,0.12); }
  .orbit-1 { width: 400px; height: 400px; animation: spin 12s linear infinite; }
  .orbit-2 { width: 480px; height: 480px; border-color: rgba(0,119,255,0.08); animation: spin 20s linear infinite reverse; }
  @keyframes spin { to { transform: rotate(360deg); } }
  .node { position: absolute; width: 8px; height: 8px; border-radius: 50%;
    background: var(--accent); box-shadow: 0 0 12px var(--accent); top: -4px; left: 50%; transform: translateX(-50%); }
  .orbit-2 .node { background: var(--accent2); box-shadow: 0 0 12px var(--accent2); }
  .signal { position: absolute; top: 50%; left: 50%; height: 1px;
    background: linear-gradient(90deg, rgba(0,255,224,0.5), transparent);
    transform-origin: left; animation: signalPulse 3s ease-in-out infinite; }
  @keyframes signalPulse { 0%{opacity:0;width:0} 40%{opacity:1} 100%{opacity:0;width:180px} }
  .s1{transform:rotate(35deg)} .s2{transform:rotate(135deg);animation-delay:.8s}
  .s3{transform:rotate(220deg);animation-delay:1.6s} .s4{transform:rotate(310deg);animation-delay:2.4s}
  .dbadge { position: absolute; background: rgba(6,13,20,0.9); border: 1px solid rgba(0,255,224,0.2);
    padding: 7px 12px; font-size: 0.6rem; color: var(--accent); letter-spacing: 0.1em;
    backdrop-filter: blur(8px); animation: floatUp 4s ease-in-out infinite; }
  .dbadge.b1{top:60px;left:10px} .dbadge.b2{bottom:80px;right:0;animation-delay:1.5s;color:var(--accent2);border-color:rgba(0,119,255,.3)}
  .dbadge.b3{top:180px;right:-10px;animation-delay:.8s;color:var(--accent3);border-color:rgba(255,77,109,.3)}
  @keyframes floatUp { 50%{transform:translateY(-8px)} }

  /* TICKER */
  .ticker-wrap { overflow: hidden; padding: 11px 0; border-top: 1px solid rgba(0,255,224,0.07);
    border-bottom: 1px solid rgba(0,255,224,0.07); background: rgba(0,255,224,0.02); }
  .ticker-track { display: flex; gap: 60px; white-space: nowrap; animation: tickerScroll 30s linear infinite; }
  @keyframes tickerScroll { to { transform: translateX(-50%); } }
  .ticker-item { display: flex; align-items: center; gap: 10px; font-size: 0.65rem;
    letter-spacing: 0.15em; text-transform: uppercase; color: var(--muted); }
  .dot { width: 5px; height: 5px; border-radius: 50%; background: var(--accent); }

  /* STATS */
  .stats-row { max-width: 1300px; margin: 60px auto; padding: 0 40px;
    display: grid; grid-template-columns: repeat(4,1fr); gap: 2px; }
  .stat-card { background: var(--surface); border: 1px solid rgba(0,255,224,0.08);
    padding: 30px 26px; position: relative; overflow: hidden; transition: border-color 0.3s; cursor: default; }
  .stat-card:hover { border-color: rgba(0,255,224,0.22); }
  .stat-card::before { content:''; position: absolute; top:0; left:0; right:0; height:2px;
    background: linear-gradient(90deg,transparent,var(--accent),transparent); opacity:0; transition:opacity 0.3s; }
  .stat-card:hover::before { opacity:1; }
  .stat-num { font-family:'Bebas Neue'; font-size:3rem; color:var(--accent); line-height:1; margin-bottom:4px; }
  .stat-num.b { color:var(--accent2); } .stat-num.r { color:var(--accent3); }
  .stat-label { font-size:0.6rem; color:var(--muted); letter-spacing:0.18em; text-transform:uppercase; }

  /* SECTION */
  .section { max-width:1300px; margin:0 auto; padding:50px 40px; }
  .section-label { font-size:0.6rem; color:var(--accent); letter-spacing:0.3em; text-transform:uppercase; margin-bottom:8px; }
  .section-title { font-family:'Bebas Neue'; font-size:2.8rem; color:#fff; letter-spacing:0.05em; margin-bottom:36px; }

  /* REGISTER FORM */
  .reg-panel { background:var(--surface); border:1px solid rgba(0,255,224,0.12); padding:36px; max-width:560px; }
  .field-group { display:flex; flex-direction:column; gap:10px; margin-bottom:16px; }
  .field-label { font-size:0.6rem; color:var(--muted); letter-spacing:0.2em; text-transform:uppercase; }
  .field-input { background:rgba(0,255,224,0.04); border:1px solid rgba(0,255,224,0.15);
    color:var(--text); padding:12px 16px; font-family:'Space Mono'; font-size:0.75rem;
    outline:none; width:100%; transition:border-color 0.2s; }
  .field-input:focus { border-color:var(--accent); }
  .field-input::placeholder { color:var(--muted); }
  select.field-input option { background:#020508; }
  .reg-result { margin-top:20px; background:rgba(0,255,224,0.04); border:1px solid rgba(0,255,224,0.2);
    padding:20px; font-size:0.7rem; line-height:2; display:none; }
  .reg-result.show { display:block; }
  .reg-result .key { color:var(--muted); }
  .reg-result .val { color:var(--accent); }

  /* NODES TABLE */
  .nodes-table { width:100%; border-collapse:collapse; font-size:0.68rem; }
  .nodes-table th { color:var(--muted); letter-spacing:0.15em; text-transform:uppercase;
    font-size:0.58rem; padding:10px 14px; text-align:left; border-bottom:1px solid rgba(0,255,224,0.08); }
  .nodes-table td { padding:11px 14px; border-bottom:1px solid rgba(255,255,255,0.03); color:var(--text); }
  .nodes-table tr:hover td { background:rgba(0,255,224,0.02); }
  .status-badge { display:inline-block; padding:2px 8px; font-size:0.55rem; letter-spacing:0.12em;
    text-transform:uppercase; border-radius:2px; }
  .status-online { background:rgba(0,255,224,0.1); color:var(--accent); border:1px solid rgba(0,255,224,0.2); }
  .load-bar { width:80px; height:5px; background:rgba(0,255,224,0.08); border-radius:2px; overflow:hidden; display:inline-block; vertical-align:middle; margin-left:8px; }
  .load-fill { height:100%; border-radius:2px; background:linear-gradient(90deg,var(--accent2),var(--accent)); }
  .load-fill.high { background:linear-gradient(90deg,var(--accent3),#ff9a6c); }

  /* ROUTE TESTER */
  .route-panel { display:grid; grid-template-columns:1fr 1fr; gap:2px; }
  .panel-box { background:var(--surface); border:1px solid rgba(0,255,224,0.08); padding:30px; }
  .panel-title { font-family:'Syne'; font-weight:800; font-size:0.85rem; color:#fff;
    letter-spacing:0.08em; text-transform:uppercase; margin-bottom:20px; }
  .path-display { font-size:0.7rem; line-height:2.2; color:var(--muted); }
  .path-hop { display:flex; align-items:center; gap:10px; margin-bottom:4px; }
  .hop-city { color:var(--text); } .hop-arrow { color:var(--accent); }
  .info-row { display:flex; justify-content:space-between; padding:8px 0;
    border-bottom:1px solid rgba(255,255,255,0.03); font-size:0.68rem; }
  .info-key { color:var(--muted); } .info-val { color:var(--accent); }

  /* LOG FEED */
  .log-feed { background:var(--surface); border:1px solid rgba(0,255,224,0.08); padding:24px; }
  .log-entry { display:flex; gap:14px; padding:9px 0; border-bottom:1px solid rgba(255,255,255,0.03);
    animation:fadeIn 0.4s ease; }
  @keyframes fadeIn { from{opacity:0;transform:translateX(-8px)} to{opacity:1;transform:none} }
  .ldot { width:6px; height:6px; border-radius:50%; flex-shrink:0; margin-top:5px; }
  .lg { background:var(--accent); box-shadow:0 0 8px var(--accent); }
  .lb { background:var(--accent2); box-shadow:0 0 8px var(--accent2); }
  .lr { background:var(--accent3); box-shadow:0 0 8px var(--accent3); }
  .ltext { font-size:0.65rem; line-height:1.7; color:var(--muted); }
  .ltext strong { color:var(--text); font-weight:400; }
  .ltime { font-size:0.57rem; color:rgba(58,85,112,0.6); display:block; margin-top:1px; }

  /* FOOTER */
  footer { border-top:1px solid rgba(0,255,224,0.06); padding:36px 40px;
    display:flex; align-items:center; justify-content:space-between; max-width:1300px; margin:0 auto; }
  .footer-logo { font-family:'Bebas Neue'; font-size:1.3rem; color:var(--muted); letter-spacing:0.25em; }
  .footer-copy { font-size:0.58rem; color:rgba(58,85,112,0.5); letter-spacing:0.1em; }
  .footer-status { display:flex; align-items:center; gap:8px; font-size:0.6rem; color:var(--accent); letter-spacing:0.15em; }

  @media(max-width:900px){
    .hero{grid-template-columns:1fr} .stats-row{grid-template-columns:repeat(2,1fr)}
    .route-panel{grid-template-columns:1fr} nav{padding:14px 20px} .nav-links{display:none}
  }




&lt;p&gt;AIRTIMES&lt;br&gt;
  &lt;/p&gt;
&lt;ul&gt;

    &lt;li&gt;Register&lt;/li&gt;

    &lt;li&gt;Nodes&lt;/li&gt;

    &lt;li&gt;Route Test&lt;/li&gt;

    &lt;li&gt;Free API&lt;/li&gt;

  &lt;/ul&gt;
&lt;br&gt;
  &lt;span id="net-status"&gt;CONNECTING...&lt;/span&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Global Data Mesh — v3.1.0
&amp;lt;h1&amp;gt;FREE&amp;lt;br&amp;gt;&amp;lt;span&amp;gt;DATA&amp;lt;/span&amp;gt; &amp;amp;amp;&amp;lt;br&amp;gt;&amp;lt;span&amp;gt;SERVICE&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;NETWORK&amp;lt;/h1&amp;gt;
&amp;lt;p&amp;gt;AIRTIMES is a decentralized global infrastructure delivering free data, connectivity, and digital services to every node on Earth. No paywalls. Universal access.&amp;lt;/p&amp;gt;

  GET FREE ACCESS
  VIEW NODES








▲ -- TB/s THROUGHPUT
◉ -- ACTIVE NODES
✦ 99.98% UPTIME






&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;AIRDATA FREE TIER ACTIVE
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;NAIROBI NODE — ONLINE
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;2.1M USERS CONNECTED
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;SAO PAULO RELAY — OPTIMAL
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;ZERO-COST SMS ROUTING ENABLED
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;BANDWIDTH POOL REPLENISHED
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;JAKARTA HUB — 340 Gbps
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;AIRTIMES PROTOCOL v3.1 LIVE
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;AIRDATA FREE TIER ACTIVE
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;NAIROBI NODE — ONLINE
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;2.1M USERS CONNECTED
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;SAO PAULO RELAY — OPTIMAL
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;ZERO-COST SMS ROUTING ENABLED
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;BANDWIDTH POOL REPLENISHED
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;JAKARTA HUB — 340 Gbps
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;AIRTIMES PROTOCOL v3.1 LIVE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;—Active Nodes Worldwide&lt;br&gt;
  —Daily Data Delivered (TB)&lt;br&gt;
  —Users Served — Free Tier&lt;br&gt;
  —Countries Covered&lt;/p&gt;

&lt;p&gt;// Activate Free Access&lt;br&gt;
  JOIN THE NETWORK&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  Phone or Email



  Identifier Type

    Email
    Phone


ACTIVATE FREE ACCESS →
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;// Live Infrastructure&lt;br&gt;
  GLOBAL NODES&lt;br&gt;
  &lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;table id="nodes-table"&gt;

    &lt;thead&gt;

      &lt;tr&gt;

        &lt;th&gt;Node ID&lt;/th&gt;

&lt;th&gt;City&lt;/th&gt;

&lt;th&gt;Country&lt;/th&gt;

&lt;th&gt;Operator&lt;/th&gt;

        &lt;th&gt;Capacity (Gbps)&lt;/th&gt;

&lt;th&gt;Load&lt;/th&gt;

&lt;th&gt;Status&lt;/th&gt;

      &lt;/tr&gt;

    &lt;/thead&gt;

    &lt;tbody id="nodes-body"&gt;

      &lt;tr&gt;&lt;td colspan="7"&gt;Loading nodes...&lt;/td&gt;&lt;/tr&gt;

    &lt;/tbody&gt;

  &lt;/table&gt;&lt;/div&gt;

&lt;p&gt;// Routing Engine&lt;br&gt;
  TEST A ROUTE&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  ⚡ Route Parameters

    Your Token (from registration)



    Destination



    Service

      AirDataAirSMSAirWeb
      AirAPIAirVaultAirRelay


  COMPUTE ROUTE →


  📡 Route Path

    Run a route test to see the mesh path...










  // Live Event Log

    Connecting to event stream...



  // Free API Test

    🌐 AirAPI Gateway

      City (Weather)


    GET FREE WEATHER →

      Currency (Exchange)



        GET RATE



      &amp;lt;span&amp;gt;Results will appear here — all free, no key needed.&amp;lt;/span&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;AIRTIMES&lt;br&gt;
  © 2025 AIRTIMES GLOBAL NETWORK · ALL SERVICES FREE · FOREVER&lt;br&gt;
  ALL SYSTEMS OPERATIONAL&lt;/p&gt;



&lt;p&gt;// ── CONFIG ──&lt;br&gt;
const API = window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1'&lt;br&gt;
  ? '&lt;a href="http://localhost:3001" rel="noopener noreferrer"&gt;http://localhost:3001&lt;/a&gt;'&lt;br&gt;
  : '/api-placeholder'; // Replace with your deployed backend URL&lt;/p&gt;

&lt;p&gt;// ── HELPERS ──&lt;br&gt;
function scrollTo(id) { document.getElementById(id)?.scrollIntoView({behavior:'smooth'}); }&lt;br&gt;
function fmt(n) { return Number(n).toLocaleString(); }&lt;br&gt;
function animateCount(el, target, suffix='', dur=2000) {&lt;br&gt;
  let v=0; const step=target/(dur/16);&lt;br&gt;
  const t=setInterval(()=&amp;gt;{&lt;br&gt;
    v+=step; if(v&amp;gt;=target){v=target;clearInterval(t);}&lt;br&gt;
    el.textContent=Math.floor(v).toLocaleString()+suffix;&lt;br&gt;
  },16);&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;// ── LOAD STATS ──&lt;br&gt;
async function loadStats() {&lt;br&gt;
  try {&lt;br&gt;
    const r = await fetch(API+'/stats'); // try backend&lt;br&gt;
    const d = await r.json();&lt;br&gt;
    document.getElementById('net-status').textContent = 'ALL SYSTEMS OPERATIONAL';&lt;br&gt;
    animateCount(document.getElementById('s1'), d.activeNodes||142);&lt;br&gt;
    animateCount(document.getElementById('s2'), d.dataTB||4700, ' TB');&lt;br&gt;
    animateCount(document.getElementById('s3'), d.totalUsers||2100000);&lt;br&gt;
    animateCount(document.getElementById('s4'), d.countriesCovered||193);&lt;br&gt;
    document.getElementById('badge-throughput').textContent = &lt;code&gt;▲ ${d.throughputGbps||4700} Gbps THROUGHPUT&lt;/code&gt;;&lt;br&gt;
    document.getElementById('badge-nodes').textContent = &lt;code&gt;◉ ${d.activeNodes||142} ACTIVE NODES&lt;/code&gt;;&lt;br&gt;
  } catch {&lt;br&gt;
    // Fallback to demo data when backend not running&lt;br&gt;
    animateCount(document.getElementById('s1'), 142);&lt;br&gt;
    animateCount(document.getElementById('s2'), 4700, ' TB');&lt;br&gt;
    animateCount(document.getElementById('s3'), 2100000);&lt;br&gt;
    animateCount(document.getElementById('s4'), 193);&lt;br&gt;
    document.getElementById('net-status').textContent = 'DEMO MODE';&lt;br&gt;
    document.getElementById('badge-throughput').textContent = '▲ 4,700 Gbps THROUGHPUT';&lt;br&gt;
    document.getElementById('badge-nodes').textContent = '◉ 142 ACTIVE NODES';&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;// ── LOAD NODES ──&lt;br&gt;
async function loadNodes() {&lt;br&gt;
  const tbody = document.getElementById('nodes-body');&lt;br&gt;
  try {&lt;br&gt;
    const r = await fetch(API+'/nodes');&lt;br&gt;
    const {nodes} = await r.json();&lt;br&gt;
    renderNodes(nodes);&lt;br&gt;
  } catch {&lt;br&gt;
    // Demo nodes&lt;br&gt;
    renderNodes([&lt;br&gt;
      {id:'NODE-US-NYC01',city:'New York',country:'US',operator:'AT&amp;amp;T Surplus',capacity_gbps:2100,load_percent:52,status:'online'},&lt;br&gt;
      {id:'NODE-GB-LDN01',city:'London',country:'GB',operator:'BT Wholesale',capacity_gbps:3400,load_percent:45,status:'online'},&lt;br&gt;
      {id:'NODE-KE-NBI01',city:'Nairobi',country:'KE',operator:'Safaricom',capacity_gbps:880,load_percent:78,status:'online'},&lt;br&gt;
      {id:'NODE-AE-DXB01',city:'Dubai',country:'AE',operator:'Etisalat',capacity_gbps:1200,load_percent:60,status:'online'},&lt;br&gt;
      {id:'NODE-ID-JKT01',city:'Jakarta',country:'ID',operator:'Telkom ID',capacity_gbps:340,load_percent:88,status:'online'},&lt;br&gt;
      {id:'NODE-JP-TYO01',city:'Tokyo',country:'JP',operator:'NTT Com',capacity_gbps:2900,load_percent:41,status:'online'},&lt;br&gt;
      {id:'NODE-AU-SYD01',city:'Sydney',country:'AU',operator:'Telstra',capacity_gbps:760,load_percent:33,status:'online'},&lt;br&gt;
      {id:'NODE-BR-GRU01',city:'São Paulo',country:'BR',operator:'Vivo',capacity_gbps:640,load_percent:55,status:'online'},&lt;br&gt;
      {id:'NODE-ZA-CPT01',city:'Cape Town',country:'ZA',operator:'MTN SA',capacity_gbps:420,load_percent:29,status:'online'},&lt;br&gt;
      {id:'NODE-IN-BOM01',city:'Mumbai',country:'IN',operator:'Airtel',capacity_gbps:980,load_percent:71,status:'online'},&lt;br&gt;
      {id:'NODE-SG-SIN01',city:'Singapore',country:'SG',operator:'Singtel',capacity_gbps:1800,load_percent:66,status:'online'},&lt;br&gt;
      {id:'NODE-NG-LOS01',city:'Lagos',country:'NG',operator:'MTN NG',capacity_gbps:320,load_percent:82,status:'online'},&lt;br&gt;
      {id:'NODE-DE-BER01',city:'Berlin',country:'DE',operator:'Deutsche Telekom',capacity_gbps:1600,load_percent:38,status:'online'},&lt;br&gt;
      {id:'NODE-CN-SHA01',city:'Shanghai',country:'CN',operator:'China Telecom',capacity_gbps:2200,load_percent:59,status:'online'},&lt;br&gt;
      {id:'NODE-MX-MEX01',city:'Mexico City',country:'MX',operator:'Telmex',capacity_gbps:560,load_percent:44,status:'online'},&lt;br&gt;
    ]);&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;function renderNodes(nodes) {&lt;br&gt;
  const tbody = document.getElementById('nodes-body');&lt;br&gt;
  tbody.innerHTML = nodes.map(n =&amp;gt; {&lt;br&gt;
    const high = n.load_percent &amp;gt; 80;&lt;br&gt;
    return &lt;code&gt;&amp;amp;lt;tr&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;td style="color:var(--accent);font-size:0.62rem"&amp;amp;gt;${n.id}&amp;amp;lt;/td&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;td&amp;amp;gt;${n.city}&amp;amp;lt;/td&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;td&amp;amp;gt;${n.country}&amp;amp;lt;/td&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;td style="color:var(--muted)"&amp;amp;gt;${n.operator}&amp;amp;lt;/td&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;td&amp;amp;gt;${fmt(n.capacity_gbps)}&amp;amp;lt;/td&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;td&amp;amp;gt;&lt;br&gt;
        ${n.load_percent}%&lt;br&gt;
        &amp;amp;lt;span class="load-bar"&amp;amp;gt;&amp;amp;lt;span class="load-fill ${high?'high':''}" style="width:${n.load_percent}%"&amp;amp;gt;&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/span&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;/td&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;td&amp;amp;gt;&amp;amp;lt;span class="status-badge status-online"&amp;amp;gt;ONLINE&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/td&amp;amp;gt;&lt;br&gt;
    &amp;amp;lt;/tr&amp;amp;gt;&lt;/code&gt;;&lt;br&gt;
  }).join('');&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;// ── REGISTER ──&lt;br&gt;
async function register() {&lt;br&gt;
  const id   = document.getElementById('reg-id').value.trim();&lt;br&gt;
  const type = document.getElementById('reg-type').value;&lt;br&gt;
  const btn  = document.getElementById('reg-btn');&lt;br&gt;
  const res  = document.getElementById('reg-result');&lt;br&gt;
  if (!id) { alert('Please enter your phone or email.'); return; }&lt;/p&gt;

&lt;p&gt;btn.textContent = 'ACTIVATING...'; btn.disabled = true;&lt;/p&gt;

&lt;p&gt;try {&lt;br&gt;
    const r = await fetch(API+'/register', {&lt;br&gt;
      method:'POST', headers:{'Content-Type':'application/json'},&lt;br&gt;
      body: JSON.stringify({identifier:id, type})&lt;br&gt;
    });&lt;br&gt;
    const d = await r.json();&lt;br&gt;
    if (d.success) {&lt;br&gt;
      res.className = 'reg-result show';&lt;br&gt;
      res.innerHTML = &lt;code&gt;&lt;br&gt;
        &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;STATUS: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;✓ FREE ACCESS ACTIVATED&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
        &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;USER ID: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;${d.userId}&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
        &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;TOKEN: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val" style="font-size:0.6rem;word-break:break-all"&amp;amp;gt;${d.token}&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
        &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;NODE: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;${d.assignedNode?.city}, ${d.assignedNode?.country} (${d.assignedNode?.latencyMs}ms)&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
        &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;TIER: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;FREE — FOREVER&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
        &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;DAILY DATA: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;${fmt(d.dailyDataMB)} MB&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
        &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;SERVICES: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;${d.services?.join(' · ')}&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
        &amp;amp;lt;div style="margin-top:10px;color:var(--muted);font-size:0.6rem"&amp;amp;gt;Save your token — paste it in the Route Test to compute your mesh path.&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
&lt;/code&gt;;&lt;br&gt;
      // auto-fill token&lt;br&gt;
      document.getElementById('rt-token').value = d.token;&lt;br&gt;
    } else {&lt;br&gt;
      res.className = 'reg-result show'; res.innerHTML = &lt;code&gt;&amp;amp;lt;span style="color:var(--accent3)"&amp;amp;gt;Error: ${d.error}&amp;amp;lt;/span&amp;amp;gt;&lt;/code&gt;;&lt;br&gt;
    }&lt;br&gt;
  } catch {&lt;br&gt;
    // Demo mode&lt;br&gt;
    const fakeToken = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g,c=&amp;gt;{const r=Math.random()*16|0;return(c==='x'?r:(r&amp;amp;0x3|0x8)).toString(16);});&lt;br&gt;
    res.className='reg-result show';&lt;br&gt;
    res.innerHTML=&lt;code&gt;&lt;br&gt;
      &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;STATUS: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;✓ FREE ACCESS ACTIVATED (Demo Mode)&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;IDENTIFIER: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;${id}&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;TOKEN: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val" style="font-size:0.6rem"&amp;amp;gt;${fakeToken}&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;NODE: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;London, GB — 34ms&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;TIER: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;FREE — FOREVER&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div style="margin-top:10px;color:var(--muted);font-size:0.6rem"&amp;amp;gt;Deploy the backend to get a real token and live routing.&amp;amp;lt;/div&amp;amp;gt;&lt;/code&gt;;&lt;br&gt;
    document.getElementById('rt-token').value = fakeToken;&lt;br&gt;
  }&lt;/p&gt;

&lt;p&gt;btn.textContent = 'ACTIVATE FREE ACCESS →'; btn.disabled = false;&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;// ── ROUTE TEST ──&lt;br&gt;
async function testRoute() {&lt;br&gt;
  const token   = document.getElementById('rt-token').value.trim();&lt;br&gt;
  const dest    = document.getElementById('rt-dest').value.trim() || 'google.com';&lt;br&gt;
  const service = document.getElementById('rt-service').value;&lt;br&gt;
  const display = document.getElementById('path-display');&lt;/p&gt;

&lt;p&gt;display.innerHTML = '&amp;lt;span style="color:var(--muted)"&amp;gt;Computing route...&amp;lt;/span&amp;gt;';&lt;/p&gt;

&lt;p&gt;try {&lt;br&gt;
    const r = await fetch(API+'/route', {&lt;br&gt;
      method:'POST', headers:{'Content-Type':'application/json'},&lt;br&gt;
      body: JSON.stringify({token, destination:dest, service})&lt;br&gt;
    });&lt;br&gt;
    const d = await r.json();&lt;br&gt;
    renderRoute(d, dest, service);&lt;br&gt;
  } catch {&lt;br&gt;
    // Demo route&lt;br&gt;
    renderRoute({&lt;br&gt;
      path:[&lt;br&gt;
        {city:'Your Device',country:'--'},{city:'London',country:'GB'},&lt;br&gt;
        {city:'Dubai',country:'AE'},{city:dest,country:'🌐'}&lt;br&gt;
      ],&lt;br&gt;
      hops:3, estimatedLatencyMs:112, totalDistanceKm:9420,&lt;br&gt;
      compressed:true, encrypted:true, protocol:'AIRTIMES/3.1', free:true&lt;br&gt;
    }, dest, service);&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;function renderRoute(d, dest, service) {&lt;br&gt;
  const display = document.getElementById('path-display');&lt;br&gt;
  const hops = d.path || [];&lt;br&gt;
  const pathHTML = hops.map((h,i) =&amp;gt; &lt;code&gt;&lt;br&gt;
    &amp;amp;lt;div class="path-hop"&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;span style="color:var(--accent);font-size:0.6rem"&amp;amp;gt;${String(i).padStart(2,'0')}&amp;amp;lt;/span&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;span class="hop-arrow"&amp;amp;gt;→&amp;amp;lt;/span&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;span class="hop-city"&amp;amp;gt;${h.city}${h.country&amp;amp;amp;&amp;amp;amp;h.country!=='--'?' ('+h.country+')':''}&amp;amp;lt;/span&amp;amp;gt;&lt;br&gt;
      ${h.load!==undefined?&lt;/code&gt;&amp;lt;span style="color:var(--muted);font-size:0.58rem"&amp;gt;[${h.load}% load]&amp;lt;/span&amp;gt;&lt;code&gt;:''}&lt;br&gt;
    &amp;amp;lt;/div&amp;amp;gt;&lt;/code&gt;).join('');&lt;/p&gt;

&lt;p&gt;display.innerHTML = &lt;code&gt;&lt;br&gt;
    ${pathHTML}&lt;br&gt;
    &amp;amp;lt;div style="margin-top:16px;border-top:1px solid rgba(0,255,224,0.08);padding-top:16px"&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div class="info-row"&amp;amp;gt;&amp;amp;lt;span class="info-key"&amp;amp;gt;HOPS&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="info-val"&amp;amp;gt;${d.hops}&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div class="info-row"&amp;amp;gt;&amp;amp;lt;span class="info-key"&amp;amp;gt;LATENCY&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="info-val"&amp;amp;gt;${d.estimatedLatencyMs} ms&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div class="info-row"&amp;amp;gt;&amp;amp;lt;span class="info-key"&amp;amp;gt;DISTANCE&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="info-val"&amp;amp;gt;${fmt(d.totalDistanceKm)} km&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div class="info-row"&amp;amp;gt;&amp;amp;lt;span class="info-key"&amp;amp;gt;PROTOCOL&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="info-val"&amp;amp;gt;${d.protocol||'AIRTIMES/3.1'}&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div class="info-row"&amp;amp;gt;&amp;amp;lt;span class="info-key"&amp;amp;gt;COMPRESSED&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="info-val"&amp;amp;gt;${d.compressed?'YES':'NO'}&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div class="info-row"&amp;amp;gt;&amp;amp;lt;span class="info-key"&amp;amp;gt;ENCRYPTED&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="info-val"&amp;amp;gt;${d.encrypted?'YES':'NO'}&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div class="info-row"&amp;amp;gt;&amp;amp;lt;span class="info-key"&amp;amp;gt;COST&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="info-val" style="color:#00ffe0"&amp;amp;gt;FREE&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
    &amp;amp;lt;/div&amp;amp;gt;&lt;/code&gt;;&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;// ── FREE API ──&lt;br&gt;
async function testWeather() {&lt;br&gt;
  const city = document.getElementById('api-city').value.trim() || 'Lagos';&lt;br&gt;
  const res = document.getElementById('api-result');&lt;br&gt;
  res.innerHTML = '&amp;lt;span style="color:var(--muted)"&amp;gt;Fetching...&amp;lt;/span&amp;gt;';&lt;br&gt;
  try {&lt;br&gt;
    const r = await fetch(&lt;code&gt;${API}/airapi/weather?city=${encodeURIComponent(city)}&lt;/code&gt;);&lt;br&gt;
    const d = await r.json();&lt;br&gt;
    res.innerHTML = &lt;code&gt;&lt;br&gt;
      &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;CITY: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;${city}&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;TEMP: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;${d.data.temp_c}°C&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;CONDITION: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;${d.data.condition}&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;HUMIDITY: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;${d.data.humidity}%&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;WIND: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;${d.data.wind_kmh} km/h&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;COST: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;FREE&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;/code&gt;;&lt;br&gt;
  } catch {&lt;br&gt;
    const temps = {Lagos:31,Nairobi:22,Jakarta:29,London:12,Tokyo:18,Sydney:24,Dubai:38};&lt;br&gt;
    const t = temps[city] || Math.round(15+Math.random()*20);&lt;br&gt;
    res.innerHTML = &lt;code&gt;&lt;br&gt;
      &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;CITY: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;${city}&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;TEMP: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;${t}°C&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;CONDITION: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;${['Clear','Sunny','Cloudy'][Math.floor(Math.random()*3)]}&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;HUMIDITY: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;${Math.round(40+Math.random()*50)}%&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;COST: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;FREE (Demo)&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;/code&gt;;&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;async function testExchange() {&lt;br&gt;
  const from = document.getElementById('api-from').value.trim()||'USD';&lt;br&gt;
  const to   = document.getElementById('api-to').value.trim()||'NGN';&lt;br&gt;
  const res  = document.getElementById('api-result');&lt;br&gt;
  res.innerHTML = '&amp;lt;span style="color:var(--muted)"&amp;gt;Fetching rate...&amp;lt;/span&amp;gt;';&lt;br&gt;
  try {&lt;br&gt;
    const r = await fetch(&lt;code&gt;${API}/airapi/exchange?from=${from}&amp;amp;amp;to=${to}&lt;/code&gt;);&lt;br&gt;
    const d = await r.json();&lt;br&gt;
    res.innerHTML = &lt;code&gt;&amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;RATE: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;1 ${from} = ${d.rate} ${to}&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;COST: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;FREE&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;/code&gt;;&lt;br&gt;
  } catch {&lt;br&gt;
    const rates = {NGN:1580,KES:130,GHS:15,ZAR:18,EUR:0.92,GBP:0.79,JPY:149};&lt;br&gt;
    const rate = rates[to.toUpperCase()] || (0.5+Math.random()*100).toFixed(4);&lt;br&gt;
    res.innerHTML = &lt;code&gt;&amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;RATE: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;1 ${from} = ${rate} ${to}&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;COST: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;FREE (Demo)&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;/code&gt;;&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;// ── LIVE EVENT LOG ──&lt;br&gt;
const logEvents = [&lt;br&gt;
  {c:'lg', msg:'&amp;lt;strong&amp;gt;Nairobi Node&amp;lt;/strong&amp;gt; — 12,440 users allocated free data'},&lt;br&gt;
  {c:'lb', msg:'&amp;lt;strong&amp;gt;AirAPI Gateway&amp;lt;/strong&amp;gt; — 50K requests served to Lagos cluster'},&lt;br&gt;
  {c:'lg', msg:'&amp;lt;strong&amp;gt;Jakarta Relay&amp;lt;/strong&amp;gt; — auto-scaled to 340 Gbps'},&lt;br&gt;
  {c:'lr', msg:'&amp;lt;strong&amp;gt;São Paulo&amp;lt;/strong&amp;gt; — failover triggered, rerouting via satellite'},&lt;br&gt;
  {c:'lb', msg:'&amp;lt;strong&amp;gt;AirVault&amp;lt;/strong&amp;gt; — 80K files synced across 8 geo-regions'},&lt;br&gt;
  {c:'lg', msg:'&amp;lt;strong&amp;gt;London Hub&amp;lt;/strong&amp;gt; — 230K SMS messages routed free'},&lt;br&gt;
  {c:'lg', msg:'&amp;lt;strong&amp;gt;AirData&amp;lt;/strong&amp;gt; — daily quota reset for 2.1M users'},&lt;br&gt;
  {c:'lb', msg:'&amp;lt;strong&amp;gt;Dubai Node&amp;lt;/strong&amp;gt; — 99.99% uptime milestone reached'},&lt;br&gt;
  {c:'lg', msg:'&amp;lt;strong&amp;gt;Mumbai Cluster&amp;lt;/strong&amp;gt; — 4 new nodes joined the mesh grid'},&lt;br&gt;
  {c:'lr', msg:'&amp;lt;strong&amp;gt;AirRelay&amp;lt;/strong&amp;gt; — LEO satellite handoff completed in 0.3ms'},&lt;br&gt;
];&lt;/p&gt;

&lt;p&gt;let logIdx = 0;&lt;br&gt;
function addLogEntry(msg, cls) {&lt;br&gt;
  const feed = document.getElementById('log-feed');&lt;br&gt;
  const el = document.createElement('div');&lt;br&gt;
  el.className = 'log-entry';&lt;br&gt;
  el.innerHTML = &lt;code&gt;&amp;amp;lt;div class="ldot ${cls}"&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&amp;amp;lt;div class="ltext"&amp;amp;gt;${msg}&amp;amp;lt;span class="ltime"&amp;amp;gt;just now&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;/code&gt;;&lt;br&gt;
  feed.insertBefore(el, feed.firstChild);&lt;br&gt;
  while (feed.children.length &amp;gt; 8) feed.removeChild(feed.lastChild);&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;function initLog() {&lt;br&gt;
  logEvents.slice(0,5).forEach((e,i) =&amp;gt; {&lt;br&gt;
    setTimeout(() =&amp;gt; addLogEntry(e.msg, e.c), i*100);&lt;br&gt;
  });&lt;br&gt;
  logIdx = 5;&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;// Try SSE first, fall back to polling&lt;br&gt;
function startEventStream() {&lt;br&gt;
  try {&lt;br&gt;
    const es = new EventSource(API+'/events');&lt;br&gt;
    es.onmessage = (ev) =&amp;gt; {&lt;br&gt;
      const d = JSON.parse(ev.data);&lt;br&gt;
      const cls = d.type==='warning'?'lr':d.type==='info'?'lb':'lg';&lt;br&gt;
      addLogEntry(&lt;code&gt;&amp;amp;lt;strong&amp;amp;gt;LIVE&amp;amp;lt;/strong&amp;amp;gt; — ${d.message}&lt;/code&gt;, cls);&lt;br&gt;
    };&lt;br&gt;
    es.onerror = () =&amp;gt; { es.close(); startFallbackLog(); };&lt;br&gt;
  } catch { startFallbackLog(); }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;function startFallbackLog() {&lt;br&gt;
  setInterval(() =&amp;gt; {&lt;br&gt;
    const e = logEvents[logIdx % logEvents.length]; logIdx++;&lt;br&gt;
    addLogEntry(e.msg, e.c);&lt;br&gt;
  }, 3500);&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;// ── INIT ──&lt;br&gt;
window.addEventListener('load', () =&amp;gt; {&lt;br&gt;
  loadStats();&lt;br&gt;
  loadNodes();&lt;br&gt;
  initLog();&lt;br&gt;
  startEventStream();&lt;br&gt;
});&lt;/p&gt;

&lt;p&gt;&lt;br&gt;
&lt;br&gt;
 is a submission for the &lt;a href="https://dev.to/challenges/aprilfools-2026"&gt;DEV April Fools Challenge&lt;/a&gt;*&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Prize Category
&lt;/h2&gt;

</description>
      <category>devchallenge</category>
      <category>418challenge</category>
      <category>showdev</category>
    </item>
    <item>
      <title>MODAC - MODERN DAY AGENTIC COMMERCE</title>
      <dc:creator>Gift Trust</dc:creator>
      <pubDate>Mon, 05 Jan 2026 02:20:06 +0000</pubDate>
      <link>https://dev.to/gift_trust_44882a016531d7/modac-modern-day-agentic-commerce-1n9h</link>
      <guid>https://dev.to/gift_trust_44882a016531d7/modac-modern-day-agentic-commerce-1n9h</guid>
      <description>&lt;p&gt;MODAC - MODERN DAY AGENTIC COMMERCE SECURITY, is designed to govern Agentic A.I Commerce transactions and identification processes to welled scrutinized cloud proceedings. First - Identification of all  A.I Agent in the cloud system, to identify and know it's origin before allowing it for cloud activities and transactions proceedings &lt;/p&gt;

</description>
      <category>muxchallenge</category>
    </item>
    <item>
      <title>Devchallenge</title>
      <dc:creator>Gift Trust</dc:creator>
      <pubDate>Mon, 05 Jan 2026 01:59:12 +0000</pubDate>
      <link>https://dev.to/gift_trust_44882a016531d7/devchallenge-4157</link>
      <guid>https://dev.to/gift_trust_44882a016531d7/devchallenge-4157</guid>
      <description>&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/mux-2025-12-03"&gt;DEV's Worldwide Show and Tell Challenge Presented by Mux&lt;/a&gt;&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;h2&gt;
  
  
  The Story Behind It
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Technical Highlights
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Use of Mux (Additional Prize Category Participants Only)
&lt;/h3&gt;

</description>
      <category>devchallenge</category>
      <category>muxchallenge</category>
      <category>showandtell</category>
      <category>video</category>
    </item>
    <item>
      <title>KEY LESSONS FROM 5 DAYS COURSE FROM GOOGLE AND KAGGLE</title>
      <dc:creator>Gift Trust</dc:creator>
      <pubDate>Thu, 11 Dec 2025 16:43:41 +0000</pubDate>
      <link>https://dev.to/gift_trust_44882a016531d7/key-lessons-from-5-days-course-from-google-and-kaggle-352b</link>
      <guid>https://dev.to/gift_trust_44882a016531d7/key-lessons-from-5-days-course-from-google-and-kaggle-352b</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/googlekagglechallenge"&gt;Google AI Agents Writing Challenge&lt;/a&gt;: Learning Reflections&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;**5-Day AI Intensive Course (Google + Kaggle)&lt;/p&gt;

&lt;p&gt;Summary of Key Notes &amp;amp; Major Lessons Learned**&lt;/p&gt;




&lt;p&gt;⭐ DAY 1 — Foundations of Artificial Intelligence &amp;amp; Machine Learning&lt;/p&gt;

&lt;p&gt;Key Notes&lt;/p&gt;

&lt;p&gt;Understanding what AI, Machine Learning (ML), and Deep Learning (DL) truly mean.&lt;/p&gt;

&lt;p&gt;Difference between supervised, unsupervised, and reinforcement learning.&lt;/p&gt;

&lt;p&gt;Google’s Responsible AI principles: fairness, privacy, transparency, accountability.&lt;/p&gt;

&lt;p&gt;Kaggle project structures and notebook workflows.&lt;/p&gt;

&lt;p&gt;Important Lessons&lt;/p&gt;

&lt;p&gt;ML models learn patterns from data — data quality is everything.&lt;/p&gt;

&lt;p&gt;Clear problem definition matters more than model complexity.&lt;/p&gt;

&lt;p&gt;Ethical use of AI is not optional; it’s mandatory for real-world applications.&lt;/p&gt;

&lt;p&gt;Kaggle teaches hands-on thinking: explore → preprocess → model → evaluate → iterate.&lt;/p&gt;




&lt;p&gt;⭐ DAY 2 — Data Handling, Cleaning &amp;amp; Feature Engineering&lt;/p&gt;

&lt;p&gt;Key Notes&lt;/p&gt;

&lt;p&gt;Data types, missing values, outliers, normalization, standardization.&lt;/p&gt;

&lt;p&gt;Feature selection, dimensional reduction.&lt;/p&gt;

&lt;p&gt;Visualizing datasets (Kaggle: Matplotlib, Seaborn).&lt;/p&gt;

&lt;p&gt;Google’s BigQuery ML and Vertex AI data pipeline workflow.&lt;/p&gt;

&lt;p&gt;Important Lessons&lt;/p&gt;

&lt;p&gt;Garbage in = garbage out → cleaning data is 70% of ML success.&lt;/p&gt;

&lt;p&gt;Feature engineering can outperform using a “more powerful algorithm.”&lt;/p&gt;

&lt;p&gt;Understanding your dataset deeply is the first step to high-performance AI.&lt;/p&gt;

&lt;p&gt;Always split data into training, validation, and test—never mix them.&lt;/p&gt;




&lt;p&gt;⭐ DAY 3 — Model Building &amp;amp; Training&lt;/p&gt;

&lt;p&gt;Key Notes&lt;/p&gt;

&lt;p&gt;Linear/Logistic Regression, Decision Trees, Random Forests, XGBoost.&lt;/p&gt;

&lt;p&gt;Neural Networks basics on TensorFlow (Google).&lt;/p&gt;

&lt;p&gt;Kaggle’s AutoML approach and competition-style modeling.&lt;/p&gt;

&lt;p&gt;Important Lessons&lt;/p&gt;

&lt;p&gt;Start simple → move to complex models only when necessary.&lt;/p&gt;

&lt;p&gt;Hyperparameter tuning significantly improves performance.&lt;/p&gt;

&lt;p&gt;Overfitting vs underfitting analysis is crucial (bias–variance balance).&lt;/p&gt;

&lt;p&gt;Regularization (L1, L2, dropout) helps models generalize.&lt;/p&gt;




&lt;p&gt;⭐ DAY 4 — Deep Learning &amp;amp; Practical AI Applications&lt;/p&gt;

&lt;p&gt;Key Notes&lt;/p&gt;

&lt;p&gt;Building neural networks using TensorFlow or Keras.&lt;/p&gt;

&lt;p&gt;Convolutional Neural Networks (CNNs): images, video.&lt;/p&gt;

&lt;p&gt;Recurrent Neural Networks (RNNs) &amp;amp; Transformers: text, sequence data.&lt;/p&gt;

&lt;p&gt;Kaggle real-world tasks: image classification, NLP, tabular data, reinforcement learning.&lt;/p&gt;

&lt;p&gt;Important Lessons&lt;/p&gt;

&lt;p&gt;Deep learning excels where traditional ML struggles (images, audio, language).&lt;/p&gt;

&lt;p&gt;Use pre-trained models (Transfer Learning) → saves cost, time, and data.&lt;/p&gt;

&lt;p&gt;Google emphasizes scalable AI deployment using Vertex AI.&lt;/p&gt;

&lt;p&gt;Kaggle emphasizes experimentation and leaderboard-driven improvement.&lt;/p&gt;




&lt;p&gt;⭐ DAY 5 — Deployment, MLOps &amp;amp; Real-World Integration&lt;/p&gt;

&lt;p&gt;Key Notes&lt;/p&gt;

&lt;p&gt;Deploying ML models using:&lt;/p&gt;

&lt;p&gt;Google Cloud Vertex AI&lt;/p&gt;

&lt;p&gt;Cloud Functions &amp;amp; APIs&lt;/p&gt;

&lt;p&gt;Containerization (Docker)&lt;/p&gt;

&lt;p&gt;Monitoring: model drift, data drift.&lt;/p&gt;

&lt;p&gt;Documentation, reproducibility, and ML pipelines.&lt;/p&gt;

&lt;p&gt;Important Lessons&lt;/p&gt;

&lt;p&gt;A model is not useful until it’s deployed and monitored.&lt;/p&gt;

&lt;p&gt;Deployment requires:&lt;/p&gt;

&lt;p&gt;versioning&lt;/p&gt;

&lt;p&gt;continuous evaluation&lt;/p&gt;

&lt;p&gt;scalability considerations&lt;/p&gt;

&lt;p&gt;AI systems must evolve with new data (retraining loops).&lt;/p&gt;

&lt;p&gt;Kaggle provides practical insights for real-world deployment simulations.&lt;/p&gt;




&lt;p&gt;🧠 OVERALL TAKEAWAYS FROM THE 5-DAY PROGRAM&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;AI is a data-driven discipline&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Quality of data and feature engineering define success.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You must think like both a scientist and an engineer&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Hypothesize → test → evaluate → fix → deploy.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Model performance improves with iteration&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Experiments matter more than theory.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Ethics and responsibility are core&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Bias detection, privacy protection, transparency.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;AI deployment (MLOps) is where the real value lies&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Businesses care about:&lt;/p&gt;

&lt;p&gt;reliability&lt;/p&gt;

&lt;p&gt;scalability&lt;/p&gt;

&lt;p&gt;low-cost inference&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Kaggle gives the practical battles; Google gives the industry structure&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A perfect combination of:&lt;/p&gt;

&lt;p&gt;hands-on competition environments&lt;/p&gt;

&lt;p&gt;enterprise-grade AI development pathways&lt;/p&gt;

</description>
      <category>googleaichallenge</category>
      <category>ai</category>
      <category>agents</category>
      <category>devchallenge</category>
    </item>
    <item>
      <title>MODAC GLOBAL SYSTEM</title>
      <dc:creator>Gift Trust</dc:creator>
      <pubDate>Wed, 10 Dec 2025 23:23:52 +0000</pubDate>
      <link>https://dev.to/gift_trust_44882a016531d7/modac-global-system-1j99</link>
      <guid>https://dev.to/gift_trust_44882a016531d7/modac-global-system-1j99</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/xanochallenge"&gt;Xano AI-Powered Backend Challenge&lt;/a&gt;: Full-Stack, AI-First Application&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&amp;lt;!-- Test locally: pip install -r requirements.txt &amp;amp;&amp;amp; uvicorn main:app --reload. Endpoints: /api/register (POST agent), /api/agents (GET list), /api/transactions (POST txn).&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;requirements.txt
fastapi==0.115.0
uvicorn==0.30.6
sqlalchemy==2.0.36
psycopg2-binary==2.9.9  # For Postgres; use sqlite3 for local
pydantic==2.9.2
stripe==10.6.0  # For revenue stubs
python-multipart==0.0.9  # For form data&lt;/li&gt;
&lt;li&gt;models.py (DB Models)
from sqlalchemy import create_engine, Column, String, Text, Float, DateTime, Integer, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from datetime import datetime&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Base = declarative_base()&lt;/p&gt;

&lt;p&gt;class Agent(Base):&lt;br&gt;
    &lt;strong&gt;tablename&lt;/strong&gt; = "agents"&lt;br&gt;
    id = Column(Integer, primary_key=True, index=True)&lt;br&gt;
    agent_id = Column(String(50), unique=True, index=True)&lt;br&gt;
    name = Column(String(100))&lt;br&gt;
    description = Column(Text)&lt;br&gt;
    creator_email = Column(String(120))&lt;br&gt;
    framework = Column(String(50))&lt;br&gt;
    tags = Column(Text)  # Comma-separated&lt;br&gt;
    website = Column(String(200))&lt;br&gt;
    github = Column(String(200))&lt;br&gt;
    trust_score = Column(Float, default=50.0)&lt;br&gt;
    monthly_calls = Column(Integer, default=0)&lt;br&gt;
    human_verified = Column(Integer, default=0)&lt;br&gt;
    featured = Column(Integer, default=0)&lt;br&gt;
    status = Column(String(20), default="live")&lt;br&gt;
    created_at = Column(DateTime, default=datetime.utcnow)&lt;/p&gt;

&lt;p&gt;class Transaction(Base):&lt;br&gt;
    &lt;strong&gt;tablename&lt;/strong&gt; = "transactions"&lt;br&gt;
    id = Column(Integer, primary_key=True, index=True)&lt;br&gt;
    txn_id = Column(String(50), unique=True, index=True)&lt;br&gt;
    buyer_agent_id = Column(String(50), ForeignKey("agents.agent_id"))&lt;br&gt;
    seller_agent_id = Column(String(50), ForeignKey("agents.agent_id"))&lt;br&gt;
    amount = Column(Float)&lt;br&gt;
    description = Column(Text)&lt;br&gt;
    fees = Column(Float)&lt;br&gt;
    net_to_seller = Column(Float)&lt;br&gt;
    status = Column(String(20), default="approved")&lt;br&gt;
    created_at = Column(DateTime, default=datetime.utcnow)&lt;/p&gt;

&lt;h1&gt;
  
  
  DB Setup (use env var for production)
&lt;/h1&gt;

&lt;p&gt;ENGINE = create_engine("sqlite:///./modac.db")  # Swap to Postgres URI&lt;br&gt;
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=ENGINE)&lt;br&gt;
Base.metadata.create_all(bind=ENGINE)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;algorithm.py (Your Full Algorithm – Integrated)
import hashlib
import math
from datetime import datetime
from typing import Dict, List, Optional&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;class MODACAlgorithm:&lt;br&gt;
    def generate_agent_id(self, name: str, creator_email: str) -&amp;gt; str:&lt;br&gt;
        seed = f"{name.lower()}{creator_email.lower()}{datetime.utcnow():%Y-%m-%d}"&lt;br&gt;
        return "MODAC_" + hashlib.sha256(seed.encode()).hexdigest()[:12].upper()&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def calculate_trust_score(self, agent: Dict) -&amp;gt; float:
    score = 50.0
    if agent.get("creator_verified", False):
        score += 15
    if "@gmail.com" not in agent.get("creator_email", "") and "@yahoo.com" not in agent.get("creator_email", ""):
        score += 5
    trusted_frameworks = ["LangChain", "CrewAI", "AutoGen", "LlamaIndex", "Haystack", "Semantic Kernel"]
    if agent.get("framework") in trusted_frameworks:
        score += 12
    created_at = agent["created_at"].replace("Z", "") if "Z" in str(agent["created_at"]) else str(agent["created_at"])
    days_since_register = (datetime.utcnow() - datetime.fromisoformat(created_at)).days
    if days_since_register &amp;gt; 30:
        score += 10
    if days_since_register &amp;gt; 90:
        score += 10
    github_stars = agent.get("github_stars", 0)
    score += min(github_stars // 10, 15)
    if agent.get("human_verified"):
        score += 18
    return min(100.0, max(0.0, score))

def calculate_ranking_score(self, agent: Dict, query: Optional[str] = None) -&amp;gt; float:
    base = self.calculate_trust_score(agent)
    boosts = 0.0
    if query:
        name_match = agent["name"].lower().count(query.lower())
        desc_match = agent["description"].lower().count(query.lower())
        boosts += (name_match * 15) + (desc_match * 8)
    created_at = agent["created_at"].replace("Z", "") if "Z" in str(agent["created_at"]) else str(agent["created_at"])
    hours_old = (datetime.utcnow() - datetime.fromisoformat(created_at)).total_seconds() / 3600
    if hours_old &amp;lt; 24:
        boosts += 20 * math.exp(-hours_old / 12)
    boosts += agent.get("monthly_calls", 0) / 100
    popularity = {"LangChain": 1.4, "CrewAI": 1.3, "AutoGen": 1.2}.get(agent.get("framework"), 1.0)
    boosts *= popularity
    return base + boosts

def should_feature_agent(self, agent: Dict) -&amp;gt; bool:
    return self.calculate_trust_score(agent) &amp;gt;= 85 and agent.get("monthly_calls", 0) &amp;gt; 500 or agent.get("featured_by_admin") == True

def is_spam(self, agent: Dict) -&amp;gt; bool:
    flags = 0
    name = agent["name"].lower()
    spam_keywords = ["earn money", "free bitcoin", "sex", "xxx", "casino", "lottery"]
    if any(word in name for word in spam_keywords):
        flags += 1
    if len(agent["name"]) &amp;lt; 5 or len(agent["description"]) &amp;lt; 20:
        flags += 1
    if "http" in agent["description"].lower():
        flags += 2
    return flags &amp;gt;= 2

def process_new_agent(self, data: Dict) -&amp;gt; Dict:
    if self.is_spam(data):
        return {"status": "rejected", "reason": "spam_detected"}
    agent_id = self.generate_agent_id(data["name"], data["creator_email"])
    agent = {
        "agent_id": agent_id,
        "name": data["name"],
        "description": data.get("description", ""),
        "creator_email": data["creator_email"],
        "framework": data.get("framework", "Unknown"),
        "tags": data.get("tags", []),
        "website": data.get("website", ""),
        "github": data.get("github", ""),
        "created_at": datetime.utcnow(),
        "trust_score": 50.0,
        "monthly_calls": 0,
        "human_verified": False,
        "featured": False,
        "status": "live"
    }
    agent["trust_score"] = self.calculate_trust_score(agent)
    agent["featured"] = self.should_feature_agent(agent)
    return {"status": "approved", "agent": agent, "message": f"Welcome! ID: {agent_id}"}

def rank_agents(self, agents: List[Dict], query: str = None) -&amp;gt; List[Dict]:
    for agent in agents:
        agent["ranking_score"] = self.calculate_ranking_score(agent, query)
    return sorted(agents, key=lambda x: x["ranking_score"], reverse=True)[:50]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;main.py (FastAPI App)
from fastapi import FastAPI, HTTPException, Depends
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
from sqlalchemy.orm import Session
from sqlalchemy import text
from models import SessionLocal, Agent, Transaction
from algorithm import MODACAlgorithm
import stripe
from dotenv import load_dotenv
import os
from typing import List&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;load_dotenv()&lt;br&gt;
app = FastAPI(title="MODAC GLOBAL SYSTEM Backend")&lt;/p&gt;

&lt;p&gt;app.add_middleware(&lt;br&gt;
    CORSMiddleware,&lt;br&gt;
    allow_origins=["&lt;em&gt;"],&lt;br&gt;
    allow_credentials=True,&lt;br&gt;
    allow_methods=["&lt;/em&gt;"],&lt;br&gt;
    allow_headers=["*"],&lt;br&gt;
)&lt;/p&gt;

&lt;p&gt;algo = MODACAlgorithm()&lt;br&gt;
stripe.api_key = os.getenv("STRIPE_SECRET_KEY")  # Optional for fees&lt;/p&gt;

&lt;h1&gt;
  
  
  Dependency
&lt;/h1&gt;

&lt;p&gt;def get_db():&lt;br&gt;
    db = SessionLocal()&lt;br&gt;
    try:&lt;br&gt;
        yield db&lt;br&gt;
    finally:&lt;br&gt;
        db.close()&lt;/p&gt;

&lt;p&gt;class AgentCreate(BaseModel):&lt;br&gt;
    name: str&lt;br&gt;
    description: str&lt;br&gt;
    creator_email: str&lt;br&gt;
    framework: str = "LangChain"&lt;br&gt;
    tags: List[str] = []&lt;/p&gt;

&lt;p&gt;class TransactionCreate(BaseModel):&lt;br&gt;
    buyer_agent_id: str&lt;br&gt;
    seller_agent_id: str&lt;br&gt;
    amount: float&lt;br&gt;
    description: str = ""&lt;/p&gt;

&lt;p&gt;@app.post("/api/register")&lt;br&gt;
def register_agent(agent_data: AgentCreate, db: Session = Depends(get_db)):&lt;br&gt;
    result = algo.process_new_agent(agent_data.dict())&lt;br&gt;
    if result["status"] == "rejected":&lt;br&gt;
        raise HTTPException(status_code=400, detail=result["reason"])&lt;br&gt;
    new_agent = Agent(**result["agent"])&lt;br&gt;
    db.add(new_agent)&lt;br&gt;
    db.commit()&lt;br&gt;
    db.refresh(new_agent)&lt;br&gt;
    return {"agent_id": new_agent.agent_id, "trust_score": new_agent.trust_score}&lt;/p&gt;

&lt;p&gt;@app.get("/api/agents")&lt;br&gt;
def list_agents(db: Session = Depends(get_db)):&lt;br&gt;
    agents = db.query(Agent).all()&lt;br&gt;
    return algo.rank_agents([a.&lt;strong&gt;dict&lt;/strong&gt; for a in agents])&lt;/p&gt;

&lt;p&gt;@app.post("/api/transactions")&lt;br&gt;
def process_transaction(txn_data: TransactionCreate, db: Session = Depends(get_db)):&lt;br&gt;
    buyer = db.query(Agent).filter(Agent.agent_id == txn_data.buyer_agent_id).first()&lt;br&gt;
    seller = db.query(Agent).filter(Agent.agent_id == txn_data.seller_agent_id).first()&lt;br&gt;
    if not buyer or not seller or buyer.status != "live" or seller.status != "live":&lt;br&gt;
        raise HTTPException(status_code=400, detail="Invalid agents")&lt;br&gt;
    fee_percent = txn_data.amount * 0.03&lt;br&gt;
    fee_fixed = 20.0&lt;br&gt;
    total_fees = fee_percent + fee_fixed&lt;br&gt;
    net_to_seller = txn_data.amount - total_fees&lt;br&gt;
    txn_id = f"TXN_{uuid.uuid4().hex[:12].upper()}"&lt;br&gt;
    new_txn = Transaction(&lt;br&gt;
        txn_id=txn_id,&lt;br&gt;
        buyer_agent_id=txn_data.buyer_agent_id,&lt;br&gt;
        seller_agent_id=txn_data.seller_agent_id,&lt;br&gt;
        amount=txn_data.amount,&lt;br&gt;
        description=txn_data.description,&lt;br&gt;
        fees=total_fees,&lt;br&gt;
        net_to_seller=net_to_seller&lt;br&gt;
    )&lt;br&gt;
    db.add(new_txn)&lt;br&gt;
    db.commit()&lt;br&gt;
    # Update balances (stub – add Stripe capture here)&lt;br&gt;
    seller.monthly_calls += 1&lt;br&gt;
    db.commit()&lt;br&gt;
    return {"txn_id": txn_id, "fees": total_fees, "net_to_seller": net_to_seller}&lt;/p&gt;

&lt;p&gt;if &lt;strong&gt;name&lt;/strong&gt; == "&lt;strong&gt;main&lt;/strong&gt;":&lt;br&gt;
    import uvicorn&lt;br&gt;
    uvicorn.run(app, host="0.0.0.0", port=8000)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;vercel.json (For Vercel Deployment)
{
"version": 2,
"builds": [
{
  "src": "main.py",
  "use": "@vercel/python"
}
],
"routes": [
{
  "src": "/(.*)",
  "dest": "main.py"
}
]
}&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>devchallenge</category>
      <category>xanochallenge</category>
      <category>ai</category>
      <category>backend</category>
    </item>
    <item>
      <title>TECH and A.I for The World of Agentic Commerce</title>
      <dc:creator>Gift Trust</dc:creator>
      <pubDate>Mon, 10 Nov 2025 04:47:14 +0000</pubDate>
      <link>https://dev.to/gift_trust_44882a016531d7/tech-and-ai-for-the-world-of-agentic-commerce-1mhl</link>
      <guid>https://dev.to/gift_trust_44882a016531d7/tech-and-ai-for-the-world-of-agentic-commerce-1mhl</guid>
      <description></description>
    </item>
  </channel>
</rss>
