<?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: Djowda</title>
    <description>The latest articles on DEV Community by Djowda (@djowda).</description>
    <link>https://dev.to/djowda</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.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F11022%2F50d46cfb-692e-4c3d-bae4-f2a6799d1fd1.png</url>
      <title>DEV Community: Djowda</title>
      <link>https://dev.to/djowda</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/djowda"/>
    <language>en</language>
    <item>
      <title>Introducing a Real-Time World Food Map — here's how it works (and how to query it with Python)</title>
      <dc:creator>Djowda</dc:creator>
      <pubDate>Mon, 15 Jun 2026 14:40:48 +0000</pubDate>
      <link>https://dev.to/djowda/introducing-a-real-time-world-food-map-heres-how-it-works-and-how-to-query-it-with-python-17ga</link>
      <guid>https://dev.to/djowda/introducing-a-real-time-world-food-map-heres-how-it-works-and-how-to-query-it-with-python-17ga</guid>
      <description>&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://djowda.com/food-freedom-map" rel="noopener noreferrer"&gt;djowda.com/food-freedom-map&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A real-time world map where anyone, anywhere on earth can &lt;strong&gt;list food, ask for it, or donate it&lt;/strong&gt; — and be seen instantly, globally — with no account, no backend, and no central server.&lt;/p&gt;

&lt;p&gt;This post covers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What we built and why&lt;/li&gt;
&lt;li&gt;The architecture behind it (Nostr + DIFP geo-grid)&lt;/li&gt;
&lt;li&gt;A Python script to query any cell on the network right now&lt;/li&gt;
&lt;li&gt;What's coming next (three-way trades + Trade on Map)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The problem we're trying to solve
&lt;/h2&gt;

&lt;p&gt;The global food system is enormously centralized. Platforms extract rent from every transaction between producers and consumers. Farmers in a village can't be discovered by someone 10km away without paying a marketplace. During a disaster, there's no open channel to broadcast "I have food here" or "we need food here" without going through a gatekeeper.&lt;/p&gt;

&lt;p&gt;We wanted to build the infrastructure layer that makes that possible. Open, permissionless, unstoppable.&lt;/p&gt;

&lt;p&gt;The result is &lt;strong&gt;DIFP&lt;/strong&gt; — the Djowda Interconnected Food Protocol. The Food Freedom Map is the first public UI on top of it.&lt;/p&gt;




&lt;h2&gt;
  
  
  What the map does right now
&lt;/h2&gt;

&lt;p&gt;Open &lt;a href="https://djowda.com/food-freedom-map" rel="noopener noreferrer"&gt;djowda.com/food-freedom-map&lt;/a&gt;, click anywhere on earth, and you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📦 &lt;strong&gt;List&lt;/strong&gt; — add a food product with a price&lt;/li&gt;
&lt;li&gt;🙋 &lt;strong&gt;Ask&lt;/strong&gt; — broadcast that you need something&lt;/li&gt;
&lt;li&gt;🤝 &lt;strong&gt;Donate&lt;/strong&gt; — offer something for free&lt;/li&gt;
&lt;li&gt;🗺️ &lt;strong&gt;Discover&lt;/strong&gt; — browse nearby stores, farms, restaurants — see their catalog, ask list, and donations in real time&lt;/li&gt;
&lt;li&gt;🔍 &lt;strong&gt;Search&lt;/strong&gt; — jump to any location by coordinates or Cell ID&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Everything happens without an account. Your identity is a secp256k1 keypair auto-generated in your browser and stored in &lt;code&gt;localStorage&lt;/code&gt;. Your pin is a signed Nostr event broadcast to &lt;code&gt;wss://relay.damus.io&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The architecture
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Layer 1 — The geo-grid (MinMax99)
&lt;/h3&gt;

&lt;p&gt;The earth is divided into a flat 500m × 500m grid: &lt;strong&gt;82,000 columns × 42,000 rows = ~3.4 billion cells&lt;/strong&gt;. Any lat/lng maps to exactly one cell ID:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;math&lt;/span&gt;

&lt;span class="n"&gt;EARTH_W&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;40_075_000&lt;/span&gt;  &lt;span class="c1"&gt;# metres
&lt;/span&gt;&lt;span class="n"&gt;EARTH_H&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20_000_000&lt;/span&gt;
&lt;span class="n"&gt;CELL_SIZE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;
&lt;span class="n"&gt;NUM_ROWS&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42_000&lt;/span&gt;
&lt;span class="n"&gt;NUM_COLS&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;82_000&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;geo_to_cell&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lat&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lng&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lng&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;180&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EARTH_W&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;360&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;EARTH_H&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pi&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lat&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pi&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;360&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EARTH_H&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pi&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="n"&gt;x_cell&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;CELL_SIZE&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;NUM_COLS&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;y_cell&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;CELL_SIZE&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;NUM_ROWS&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x_cell&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;NUM_ROWS&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;y_cell&lt;/span&gt;

&lt;span class="c1"&gt;# Example: Algiers
&lt;/span&gt;&lt;span class="n"&gt;cell&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;geo_to_cell&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;36.737&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;3.086&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cell&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# → 1711935606
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cells are grouped into &lt;strong&gt;lobbies&lt;/strong&gt; (41×41 cells ≈ 20km² each). Subscribing to a lobby ID means you get all components within that area — no bounding-box query needed, no spatial index on a server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;LOBBY_SIZE&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;41&lt;/span&gt;
&lt;span class="n"&gt;NUM_LOBBY_ROWS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1025&lt;/span&gt;  &lt;span class="c1"&gt;# ceil(42000 / 41)
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;cell_to_lobby&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cell_id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;x_cell&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cell_id&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="n"&gt;NUM_ROWS&lt;/span&gt;
    &lt;span class="n"&gt;y_cell&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cell_id&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;NUM_ROWS&lt;/span&gt;
    &lt;span class="n"&gt;lx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x_cell&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="n"&gt;LOBBY_SIZE&lt;/span&gt;
    &lt;span class="n"&gt;ly&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;y_cell&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="n"&gt;LOBBY_SIZE&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;lx&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;NUM_LOBBY_ROWS&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;ly&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Layer 2 — Nostr (NIP-01 + NIP-33)
&lt;/h3&gt;

&lt;p&gt;Every component presence is a &lt;strong&gt;kind:30420 replaceable event&lt;/strong&gt; (NIP-33). One pubkey = one component. Updating your presence replaces the old event on the relay — no accumulation of stale data.&lt;/p&gt;

&lt;p&gt;The event tags that matter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"d"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="s2"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"t"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="s2"&gt;"difp"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"t"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="s2"&gt;"s"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"cell"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"1711935606"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"lobby"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"40780"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"t"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="s2"&gt;"lobby-40780"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;#t: ["lobby-40780"]&lt;/code&gt; tag is what makes geo-discovery possible. Any client can subscribe to a lobby ID with a standard Nostr &lt;code&gt;REQ&lt;/code&gt; — no custom relay extensions, no spatial query language. It's just tag filtering.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 3 — Catalog encoding
&lt;/h3&gt;

&lt;p&gt;Product listings, ask lists, and donations are separate kind:30421 events with a compact payload:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Listing:  1:29900;6:14900;21:9900    (productId:priceCents pairs)
Ask:      3;7;44                      (productIds)
Donation: 2;15;88                     (productIds)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This keeps event sizes tiny and fits thousands of products in a single Nostr event.&lt;/p&gt;




&lt;h2&gt;
  
  
  Query the network right now — Python script
&lt;/h2&gt;

&lt;p&gt;You don't need the map UI at all. Here's a minimal Python script to query any cell and print what's there:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;websocket&lt;/span&gt;

&lt;span class="c1"&gt;# ── DIFP grid constants ─────────────────────────────────────
&lt;/span&gt;&lt;span class="n"&gt;NUM_ROWS&lt;/span&gt;       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42_000&lt;/span&gt;
&lt;span class="n"&gt;LOBBY_SIZE&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;41&lt;/span&gt;
&lt;span class="n"&gt;NUM_LOBBY_ROWS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1_025&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;cell_to_lobby&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cell_id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;x_cell&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cell_id&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="n"&gt;NUM_ROWS&lt;/span&gt;
    &lt;span class="n"&gt;y_cell&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cell_id&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;NUM_ROWS&lt;/span&gt;
    &lt;span class="n"&gt;lx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x_cell&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="n"&gt;LOBBY_SIZE&lt;/span&gt;
    &lt;span class="n"&gt;ly&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;y_cell&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="n"&gt;LOBBY_SIZE&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;lx&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;NUM_LOBBY_ROWS&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;ly&lt;/span&gt;

&lt;span class="c1"&gt;# ── Input ───────────────────────────────────────────────────
&lt;/span&gt;&lt;span class="n"&gt;cell_id&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Enter DIFP Cell ID: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="n"&gt;lobby_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;cell_to_lobby&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cell_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Cell ID  : &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;cell_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Lobby ID : &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;lobby_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Connecting to relay...&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# ── Connect &amp;amp; subscribe ─────────────────────────────────────
&lt;/span&gt;&lt;span class="n"&gt;ws&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;websocket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_connection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;wss://relay.damus.io&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;req&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;REQ&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;difp-cell-query&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;kinds&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;30420&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#t&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;   &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;lobby-&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;lobby_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;limit&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;
&lt;span class="p"&gt;}]&lt;/span&gt;

&lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;# ── Read results ────────────────────────────────────────────
&lt;/span&gt;&lt;span class="n"&gt;found&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;recv&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;EVENT&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;event&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;event_cell&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;tag&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tags&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cell&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="bp"&gt;None&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# Filter to exact cell match
&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;event_cell&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cell_id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;continue&lt;/span&gt;

        &lt;span class="n"&gt;found&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;pass&lt;/span&gt;

        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;COMPONENT #&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;found&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PubKey : &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;pubkey&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Name   : &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;n&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Unknown&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Type   : &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;cT&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;?&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Avatar : &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;aI&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;?&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Cell   : &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;event_cell&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;listings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tags&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;listing&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;catalogs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tags&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;catalog&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Listings : &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;listings&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Catalogs : &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;catalogs&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;EOSE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;

&lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Done. Components found in cell &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;cell_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;found&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Install the dependency:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;websocket-client
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Run it:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python query_cell.py
&lt;span class="c"&gt;# Enter DIFP Cell ID: 1711935606&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll see every registered component at that 500m cell — their name, type, avatar, and any catalog/listing data — pulled directly from the Nostr relay, no API key, no rate limit, no account.&lt;/p&gt;

&lt;p&gt;Try it with Cell ID &lt;code&gt;1711935606&lt;/code&gt; (Algiers) or drop your own pin on the map first, grab your Cell ID from the confirmation toast, then query it here.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why this is interesting for AI
&lt;/h2&gt;

&lt;p&gt;One of the things we're actively experimenting with: &lt;strong&gt;querying the DIFP network from an AI agent&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The geo-cell model maps cleanly to natural language queries:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;"Find me a farm within 5km of these coordinates"&lt;/em&gt; → convert to cell → find nearby lobbies → subscribe → filter by type &lt;code&gt;f&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;"What food donations are available near me right now?"&lt;/em&gt; → same pipeline, filter by donation events&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The protocol is just Nostr tag filtering. Any model that can make a WebSocket connection and parse JSON can become a food discovery agent on the open network. No API contract. No terms of service. No SDK required.&lt;/p&gt;

&lt;p&gt;We're planning to publish a reference agent implementation in the next sprint.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's coming next
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Three-way trades
&lt;/h3&gt;

&lt;p&gt;The current version supports three independent broadcast types per component: listing (sell), ask (need), and donation (give). The next update will connect these across components — enabling matched trades:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A farmer broadcasts surplus tomatoes as a listing&lt;/li&gt;
&lt;li&gt;A restaurant broadcasts tomatoes as an ask&lt;/li&gt;
&lt;li&gt;The protocol surfaces the match&lt;/li&gt;
&lt;li&gt;Both parties transact directly, peer-to-peer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No escrow platform. No commission. Just two signed events and a handshake.&lt;/p&gt;

&lt;h3&gt;
  
  
  Trade on Map
&lt;/h3&gt;

&lt;p&gt;We're also prototyping a new concept: &lt;strong&gt;Trade on Map&lt;/strong&gt;. Instead of navigating to a store profile and browsing a catalog, you see the trades themselves as map objects — color-coded by type (listing / ask / donation), filterable by product category, visible in real time as they're published to the relay.&lt;/p&gt;

&lt;p&gt;Think of it as a live order book, but geographic. You can see at a glance where surpluses and shortfalls are clustering, and what's moving.&lt;/p&gt;

&lt;p&gt;This is still early-stage. We're designing the UX now. If you have thoughts, we'd love to hear them.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try it / get involved
&lt;/h2&gt;

&lt;p&gt;The map is live: &lt;strong&gt;&lt;a href="https://djowda.com/food-freedom-map" rel="noopener noreferrer"&gt;djowda.com/food-freedom-map&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Drop your pin. Try the Python script. Share your Cell ID in the comments — we'll tell you what's in your neighborhood on the network.&lt;/p&gt;

&lt;p&gt;We're aiming for &lt;strong&gt;1,000,000 pins&lt;/strong&gt; as a signal of demand for open food infrastructure. Not a vanity metric — a message to the food system that people are ready for something better.&lt;/p&gt;

&lt;p&gt;The npm library if you want to build on the protocol:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @djowda/difp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;→ &lt;a href="https://www.npmjs.com/package/@djowda/difp" rel="noopener noreferrer"&gt;npmjs.com/package/@djowda/difp&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The protocol is open. The relay is public. Build something. 🌾&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Part of the &lt;a href="https://djowda.com/" rel="noopener noreferrer"&gt;Djowda&lt;/a&gt; open food infrastructure project.&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Protocol spec: DIFP v0.4-alpha | Built on Nostr NIP-01 + NIP-33&lt;/em&gt;&lt;/p&gt;

</description>
      <category>nostr</category>
      <category>python</category>
      <category>opensource</category>
      <category>webdev</category>
    </item>
    <item>
      <title>DIFP is Now a Library. Plug Any App Into the Open Food Network in 3 Lines of Code.</title>
      <dc:creator>Djowda</dc:creator>
      <pubDate>Fri, 12 Jun 2026 05:28:04 +0000</pubDate>
      <link>https://dev.to/djowda/difp-is-now-a-library-plug-any-app-into-the-open-food-network-in-3-lines-of-code-1o25</link>
      <guid>https://dev.to/djowda/difp-is-now-a-library-plug-any-app-into-the-open-food-network-in-3-lines-of-code-1o25</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;The protocol works. The POC proved it. Now we're making it dead simple for any developer — in any language — to join the network.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Two weeks ago we published a proof-of-concept: two Android apps syncing a 6,000-product food catalog over Nostr in real time, geo-filtered to a 500m cell, zero backend, zero commission.&lt;/p&gt;

&lt;p&gt;Today we're announcing the next step.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;@djowda/difp&lt;/code&gt; is live on npm. Alpha. Open source. Ready to use.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What just shipped
&lt;/h2&gt;

&lt;p&gt;The first DIFP SDK — a lightweight TypeScript/JavaScript library that wraps the entire protocol into a handful of intuitive calls.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @djowda/difp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three lines to join the open food network:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createDifpClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@djowda/difp&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;createDifpClient&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;registerPresence&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Marché El Baraka&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;lat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="mf"&gt;36.737&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;lng&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="mf"&gt;3.086&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. Your component is now discoverable by anyone in your geo-cell, on the open Nostr network, with no central authority, no API key, no monthly bill.&lt;/p&gt;

&lt;p&gt;📦 npm: &lt;a href="https://www.npmjs.com/package/@djowda/difp" rel="noopener noreferrer"&gt;npmjs.com/package/@djowda/difp&lt;/a&gt;&lt;br&gt;&lt;br&gt;
🔗 Source: &lt;a href="https://github.com/Djowda/difp-npm" rel="noopener noreferrer"&gt;github.com/Djowda/difp-npm&lt;/a&gt;&lt;br&gt;&lt;br&gt;
🌐 Reference web app: &lt;a href="https://github.com/Djowda/difp-reference-webApp" rel="noopener noreferrer"&gt;github.com/Djowda/difp-reference-webApp&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  What the SDK does
&lt;/h2&gt;

&lt;p&gt;The library exposes 9 core operations — the same API that will ship across every language binding:&lt;/p&gt;
&lt;h3&gt;
  
  
  Presence
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Register on the network (or let the library generate random test data)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;registerPresence&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Green Valley Store&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;lat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="mf"&gt;36.737&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;lng&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="mf"&gt;3.086&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;s&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;         &lt;span class="c1"&gt;// store&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cellId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// 1711935606&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lobbyId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// 875346&lt;/span&gt;

&lt;span class="c1"&gt;// Update your presence&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;updatePresence&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt; &lt;span class="c1"&gt;// mark as closed&lt;/span&gt;

&lt;span class="c1"&gt;// Or just test with zero config&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;registerPresence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// → generates a realistic random component and publishes it&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Catalog management
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// List a product (id=14, price=150.00 DA, available)&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;updateItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;l&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;15000&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Mark a product as something you need&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;updateItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Mark a product you're donating&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;updateItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;d&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Each call re-broadcasts the full catalog payload over Nostr as a NIP-33 addressable event — always latest state, no history needed, 6,000+ products per event.&lt;/p&gt;
&lt;h3&gt;
  
  
  Discovery
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Find components near a cell, 5 lobby levels out (default)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nearby&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getNearby&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1711935606&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nearby&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;components&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// [{ id: '79be667...', n: 'Ferme Bouzidi', cT: 'f', cI: 1711935580n, ... }]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The library computes nearby lobby IDs from the center cell, queries Nostr with &lt;code&gt;#t&lt;/code&gt; tag filters, and returns parsed Component objects. No backend involved.&lt;/p&gt;
&lt;h3&gt;
  
  
  Catalog browsing
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Browse another component's full catalog&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;catalog&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listCatalog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;79be667ef9dc...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;asks&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listAsk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;79be667ef9dc...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;donations&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listDonation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;79be667ef9dc...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;catalog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="c1"&gt;// { productId: 14n, price: 15000n, available: true }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Status
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// {&lt;/span&gt;
&lt;span class="c1"&gt;//   pubkey:       '79be667...',&lt;/span&gt;
&lt;span class="c1"&gt;//   cellId:       1711935606n,&lt;/span&gt;
&lt;span class="c1"&gt;//   lobbyId:      875346n,&lt;/span&gt;
&lt;span class="c1"&gt;//   connected:    true,&lt;/span&gt;
&lt;span class="c1"&gt;//   catalogSize:  312,&lt;/span&gt;
&lt;span class="c1"&gt;//   askCount:     7,&lt;/span&gt;
&lt;span class="c1"&gt;//   donationCount: 3&lt;/span&gt;
&lt;span class="c1"&gt;// }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Geo utilities (also exported standalone)
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;geoToCell&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cellToLobby&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@djowda/difp&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cellId&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;geoToCell&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;36.737&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;3.086&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// 1711935606n&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lobbyId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;cellToLobby&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cellId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;         &lt;span class="c1"&gt;// 875346n&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How it works under the hood
&lt;/h2&gt;

&lt;p&gt;Everything in the library maps to two Nostr event kinds:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Kind 30420 — Component (NIP-33 replaceable)&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Your presence on the network. Contains name, type, cell ID, lobby ID, working hours, and flags for ask/donation broadcasting. Replaced silently every time you update.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Kind 30421 — Catalog (NIP-33 replaceable)&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Your product data. One event per catalog type (&lt;code&gt;-l&lt;/code&gt;, &lt;code&gt;-a&lt;/code&gt;, &lt;code&gt;-d&lt;/code&gt;). Content is raw DIFP compact encoding:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;14:15000;1:4000;12:120000;7:8250
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ID colon price-in-cents, semicolon separated. Presence means available. Absence means not. No field names. ~7,000 products per 64 KB Nostr event.&lt;/p&gt;

&lt;p&gt;Discovery uses lobby-based &lt;code&gt;#t&lt;/code&gt; tag filtering:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"kinds"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;30420&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"#t"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"lobby-875346"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"lobby-875347"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"lobby-875472"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"limit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One query. Up to 200 components across a ~20 km radius. Entirely decentralized.&lt;/p&gt;




&lt;h2&gt;
  
  
  The PAD system — and why the next milestone matters
&lt;/h2&gt;

&lt;p&gt;The library ships with a built-in demo PAD (Preloaded Asset Distribution): a CSV of product metadata that travels with the app, not over the wire. Product names, images, units, categories — bundled at install. Only price and availability travel over Nostr.&lt;/p&gt;

&lt;p&gt;The alpha PAD has 30 demo products. The full PAD spec reserves &lt;strong&gt;indexes 1–1000 for strictly necessary raw foods&lt;/strong&gt; — universal staples that exist in every food system on earth, indexed consistently across all implementations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Indexes 1001+ are open for claim.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you are a food company, a grocery brand, or you have products in production that belong on the global food network — you can claim a permanent index in the DIFP PAD. Indexes are limited. The global network shares one namespace.&lt;/p&gt;

&lt;p&gt;We'll publish the claim process shortly. If you're interested, reach out now.&lt;/p&gt;




&lt;h2&gt;
  
  
  Multi-language SDK roadmap
&lt;/h2&gt;

&lt;p&gt;The npm library is the first. The same spec — same API names, same encoding, same Nostr wire protocol — is being implemented across:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Language&lt;/th&gt;
&lt;th&gt;Registry&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;JS/TS&lt;/td&gt;
&lt;td&gt;npm&lt;/td&gt;
&lt;td&gt;✅ Live&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Java/Android&lt;/td&gt;
&lt;td&gt;Maven Central&lt;/td&gt;
&lt;td&gt;🔨 In progress&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Python&lt;/td&gt;
&lt;td&gt;PyPI&lt;/td&gt;
&lt;td&gt;🔨 In progress&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rust&lt;/td&gt;
&lt;td&gt;crates.io&lt;/td&gt;
&lt;td&gt;📋 Planned&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Go&lt;/td&gt;
&lt;td&gt;GitHub Modules&lt;/td&gt;
&lt;td&gt;📋 Planned&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C#&lt;/td&gt;
&lt;td&gt;NuGet&lt;/td&gt;
&lt;td&gt;📋 Planned&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C/C++&lt;/td&gt;
&lt;td&gt;GitHub + Conan&lt;/td&gt;
&lt;td&gt;📋 Planned&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Every library will expose the same 9 methods with the same semantics. A component published from a Python script is discoverable by a Rust app, by the Android prototype, by the reference web app. One protocol, any language.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try the test mode — zero config required
&lt;/h2&gt;

&lt;p&gt;You don't need a real location or product data to experience the protocol. Every method accepts &lt;code&gt;'test'&lt;/code&gt; as an argument:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;createDifpClient&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Generate a random realistic component and publish it&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;registerPresence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;component&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// e.g. "Ferme Bouzidi"&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cellId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;       &lt;span class="c1"&gt;// e.g. 2034871922n&lt;/span&gt;

&lt;span class="c1"&gt;// Update with a new random component&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;updatePresence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Check nearby (uses the auto-generated cell)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nearby&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getNearby&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cellId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The library handles keypair generation, storage, and relay connection automatically. First run: new identity. Subsequent runs: same identity loaded from &lt;code&gt;~/.difp/identity.json&lt;/code&gt; (Node.js) or &lt;code&gt;localStorage&lt;/code&gt; (browser).&lt;/p&gt;




&lt;h2&gt;
  
  
  What we're building toward
&lt;/h2&gt;

&lt;p&gt;DIFP is not trying to be a lower-fee food delivery platform. It's trying to make the fee structurally impossible.&lt;/p&gt;

&lt;p&gt;The relay is open infrastructure. The events are signed by the publisher's key, not by us. There is no Djowda server sitting in the middle routing discovery. The protocol runs on Nostr's relay network — run by the community, for the community.&lt;/p&gt;

&lt;p&gt;The next milestones are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Full PAD v1&lt;/strong&gt; — 1,000 standardized raw food indexes, globally consistent&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open PAD claim&lt;/strong&gt; — brands and producers can register their products permanently in the shared namespace&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Android prototype public release&lt;/strong&gt; — the reference implementation made available to test with real devices&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-relay support&lt;/strong&gt; — publishing to multiple relays for resilience&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We're building open food infrastructure, one protocol at a time.&lt;/p&gt;




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

&lt;ul&gt;
&lt;li&gt;📦 npm package: &lt;a href="https://www.npmjs.com/package/@djowda/difp" rel="noopener noreferrer"&gt;npmjs.com/package/@djowda/difp&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;💻 Library source: &lt;a href="https://github.com/Djowda/difp-npm" rel="noopener noreferrer"&gt;github.com/Djowda/difp-npm&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🌐 Reference web app: &lt;a href="https://github.com/Djowda/difp-reference-webApp" rel="noopener noreferrer"&gt;github.com/Djowda/difp-reference-webApp&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📖 Protocol spec: &lt;a href="https://djowda.com/difp" rel="noopener noreferrer"&gt;djowda.com/difp&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📝 Previous article (the POC): &lt;a href="https://dev.to/djowda/just-killed-the-30-commission-anyone-can-now-list-and-buy-food-anywhere-on-earth-for-free-4ea5"&gt;Just Killed the 30% Commission&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Questions? Open an issue on the repo, or find us on Nostr.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>opensource</category>
      <category>showdev</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Just Killed the 30% Commission. Anyone Can Now List and Buy Food, Anywhere on Earth — for Free.</title>
      <dc:creator>Djowda</dc:creator>
      <pubDate>Sun, 07 Jun 2026 03:56:11 +0000</pubDate>
      <link>https://dev.to/djowda/just-killed-the-30-commission-anyone-can-now-list-and-buy-food-anywhere-on-earth-for-free-4ea5</link>
      <guid>https://dev.to/djowda/just-killed-the-30-commission-anyone-can-now-list-and-buy-food-anywhere-on-earth-for-free-4ea5</guid>
      <description>&lt;p&gt;&lt;em&gt;tldr; We shipped a working proof-of-concept: two Android apps syncing a 6,000-product food catalog over Nostr in real time, geo-filtered to a 500m × 500m cell. No backend. No fees. No middleman. And we're open-sourcing everything.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;It started with a napkin calculation.&lt;/p&gt;

&lt;p&gt;Every time a restaurant lists a dish on a major food delivery platform, they pay somewhere between &lt;strong&gt;25% and 35% commission&lt;/strong&gt; on every single order. Not on profit. On revenue. A store doing $10,000 in food sales hands $3,000 straight to the platform — for the privilege of being discovered.&lt;/p&gt;

&lt;p&gt;We asked: what if discovery were free? What if listing food were a right, not a subscription?&lt;/p&gt;

&lt;p&gt;That question became &lt;a href="https://djowda.com/difp" rel="noopener noreferrer"&gt;DIFP&lt;/a&gt;. And this week, it works.&lt;/p&gt;




&lt;h2&gt;
  
  
  What We Shipped
&lt;/h2&gt;

&lt;p&gt;A fully working proof-of-concept built on two pillars:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DIFP&lt;/strong&gt; (Djowda Interconnected Food Protocol) — an open protocol for syncing food catalog data compactly across distributed nodes, with geo-awareness built in from day one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nostr&lt;/strong&gt; — a decentralized communication protocol where events are signed, relays are open, and no single entity controls the network.&lt;/p&gt;

&lt;p&gt;Together: a store broadcasts its full price and availability catalog to the world. A customer anywhere subscribes to their local geo-cell. They receive only what's relevant to them. Nobody charges a commission for this. Nobody can.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Math That Made This Work
&lt;/h2&gt;

&lt;p&gt;Here's the number that changed everything.&lt;/p&gt;

&lt;p&gt;A Nostr event holds &lt;strong&gt;64 KB of content&lt;/strong&gt;. A product catalog entry — just the fields that need to travel over the wire — can be encoded as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;500,30000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. Product ID and price in cents, comma-separated. Two optimizations made this possible:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Availability by presence&lt;/strong&gt; — if a product entry exists, it's available. If it's absent from the payload, it's not. No boolean field needed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Position-based encoding&lt;/strong&gt; — field names are dropped entirely. The app knows position 0 is the ID, position 1 is the price. Decoding happens on device.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~6,000 – 7,000 products per single Nostr event
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An entire store's catalog. One event. One relay push.&lt;/p&gt;

&lt;p&gt;The rest of the product data — names, images, categories, units — ships once, bundled with the app install (the &lt;strong&gt;PAD system&lt;/strong&gt;: Preloaded Asset Distribution). Updates are only ever price + availability. The network payload is minimal by design.&lt;/p&gt;




&lt;h2&gt;
  
  
  Geo-Discovery Without a Central Server
&lt;/h2&gt;

&lt;p&gt;The other hard problem: how does a customer in Austin find stores in Austin, while someone in Berlin finds theirs — without a central directory knowing where anyone is?&lt;/p&gt;

&lt;p&gt;DIFP uses a geo-cell system called &lt;strong&gt;MinMax99&lt;/strong&gt; that partitions the world into addressable ~500m × 500m cells. Each cell maps to a long integer — the &lt;code&gt;cellId&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The flow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A store encodes its location as a &lt;code&gt;cellId&lt;/code&gt; and publishes its Nostr event tagged &lt;code&gt;["g", "&amp;lt;cellId&amp;gt;"]&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;A customer enters their coordinates, computes the same &lt;code&gt;cellId&lt;/code&gt;, and subscribes with &lt;code&gt;{"#g": ["&amp;lt;cellId&amp;gt;"]}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The Nostr relay returns only events tagged for that cell&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No API. No account. No server knowing where you are. Just math and an open relay.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Architecture
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;STORE APP                           USER APP
──────────────────────────────────────────────────────
[CSV PAD] → Room DB                 [CSV PAD] → Room DB
     ↓                                    ↑
[Bulk randomize]                    [DIFP Decoder]
     ↓                                    ↑
[DIFP Encoder]                      [RAM Index O(1)]
     ↓                                    ↑
[NostrClient]  ──── Nostr Relay ──→ [NostrSubscriber]
  NIP-01 EVENT                        NIP-01 REQ+#g
  kind:1, #g=cellId                   filter by cellId
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The user app maintains an in-memory index of product IDs for O(1) lookup. When a Nostr event arrives, it decodes the DIFP payload, applies the delta to the RAM index, and bulk-writes to Room DB. LiveData notifies the RecyclerView. The UI updates in real time.&lt;/p&gt;

&lt;p&gt;No polling. No REST calls. No backend to go down.&lt;/p&gt;




&lt;h2&gt;
  
  
  Running It Yourself
&lt;/h2&gt;

&lt;p&gt;The POC is open source: &lt;a href="https://github.com/Djowda/difp-nostr-catalog-poc" rel="noopener noreferrer"&gt;github.com/Djowda/difp-nostr-catalog-poc&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Two apps, same CSV asset pack:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csvs"&gt;&lt;code&gt;&lt;span class="k"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;brand&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;is&lt;/span&gt;&lt;span class="err"&gt;_&lt;/span&gt;&lt;span class="k"&gt;available&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;category&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;sub&lt;/span&gt;&lt;span class="err"&gt;_&lt;/span&gt;&lt;span class="k"&gt;category&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;unit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;score&lt;/span&gt;
&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;Ail&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;DJOWDA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;Ail&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;40.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;L&lt;/span&gt;&lt;span class="err"&gt;é&lt;/span&gt;&lt;span class="k"&gt;gumes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;L&lt;/span&gt;&lt;span class="err"&gt;é&lt;/span&gt;&lt;span class="k"&gt;gumes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;1.&lt;/span&gt;&lt;span class="k"&gt;webp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;KG&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To run the demo:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install both apps on two devices (or two emulators)&lt;/li&gt;
&lt;li&gt;Enter the same coordinates on both — e.g. &lt;code&gt;40.71, -74.00&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;User app: tap &lt;strong&gt;Observe Catalog&lt;/strong&gt; → subscribes to that geo-cell on &lt;code&gt;wss://relay.damus.io&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Store app: tap &lt;strong&gt;⚡ Bulk Update 6k + Broadcast&lt;/strong&gt; → randomizes all prices, encodes DIFP, publishes to Nostr&lt;/li&gt;
&lt;li&gt;Watch the user app update in real time&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The relay is public. No auth required. No account. No fee.&lt;/p&gt;




&lt;h2&gt;
  
  
  What This Actually Means
&lt;/h2&gt;

&lt;p&gt;Let's be direct about what just became possible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Any food seller, anywhere on earth, can list their catalog for free.&lt;/strong&gt;&lt;br&gt;
No platform approval. No onboarding fee. No monthly subscription. Run the app, enter your location, broadcast.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Any buyer, anywhere on earth, can discover and purchase from local sellers.&lt;/strong&gt;&lt;br&gt;
No account with a gatekeeper platform. No delivery fee routed through a VC-backed intermediary. Just open protocol.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The 30% commission is structurally impossible in this model.&lt;/strong&gt;&lt;br&gt;
There is no central entity to collect it. The relay is open infrastructure — run by the community, for the community. DIFP events are signed by the store's Nostr key, not by us.&lt;/p&gt;

&lt;p&gt;This isn't a lower-fee platform. It's a world where the fee doesn't exist as a concept.&lt;/p&gt;


&lt;h2&gt;
  
  
  What's Still TODO
&lt;/h2&gt;

&lt;p&gt;The POC uses a placeholder Schnorr signature. Production deployment needs real NIP-01 signing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// build.gradle&lt;/span&gt;
&lt;span class="n"&gt;implementation&lt;/span&gt; &lt;span class="s"&gt;"fr.acinq.secp256k1:secp256k1-kmp-jvm:0.10.1"&lt;/span&gt;

&lt;span class="c1"&gt;// NostrClient.java&lt;/span&gt;
&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;sigBytes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Secp256k1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;signSchnorr&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;hexToBytes&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;eventIdHex&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;hexToBytes&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;PRIVATE_KEY_HEX&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
    &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Beyond that, the roadmap includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Payment layer&lt;/strong&gt; — Nostr Wallet Connect (NWC) for zap-based ordering with no payment processor taking a cut&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-cell relay mapping&lt;/strong&gt; — larger areas subscribing to multiple geo-cells&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Relay diversity&lt;/strong&gt; — publishing to multiple relays for censorship resistance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Live throughput benchmarks&lt;/strong&gt; — measuring real-world latency across relay infrastructure&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Why Food Infrastructure
&lt;/h2&gt;

&lt;p&gt;Food systems are some of the most centralized infrastructure on the planet. A handful of platforms control discovery for hundreds of thousands of local sellers. A protocol disruption that happened in music (streaming), in finance (crypto), and in social (Nostr itself) hasn't happened in food yet.&lt;/p&gt;

&lt;p&gt;We think it should.&lt;/p&gt;

&lt;p&gt;DIFP isn't a product. It's a protocol. Anyone can build on it. Anyone can run a relay. Anyone can publish a catalog.&lt;/p&gt;

&lt;p&gt;The spec is at &lt;a href="https://djowda.com/difp" rel="noopener noreferrer"&gt;djowda.com/difp&lt;/a&gt;.&lt;br&gt;
The code is at &lt;a href="https://github.com/Djowda/difp-nostr-catalog-poc" rel="noopener noreferrer"&gt;github.com/Djowda/difp-nostr-catalog-poc&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We're building open food infrastructure, one protocol at a time. Come build with us.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Questions? Comments? Open an issue on the repo or find us on Nostr.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>nostr</category>
      <category>decentralized</category>
      <category>foodtech</category>
      <category>opensource</category>
    </item>
    <item>
      <title>DIFP Nostr: Fitting 6,000+ Products into a Single 64 KB Event</title>
      <dc:creator>Djowda</dc:creator>
      <pubDate>Sat, 06 Jun 2026 03:10:09 +0000</pubDate>
      <link>https://dev.to/djowda/difp-x-nostr-fitting-6000-products-into-a-single-64-kb-event-330k</link>
      <guid>https://dev.to/djowda/difp-x-nostr-fitting-6000-products-into-a-single-64-kb-event-330k</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; — The DIFP protocol was designed to be data-compact and geo-aware from day one. We recently discovered it maps almost perfectly onto the Nostr event format. Here's how, and why it matters for decentralized food infrastructure.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Background: What Is DIFP?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://djowda.com/difp" rel="noopener noreferrer"&gt;DIFP (Djowda Interconnected Food Protocol)&lt;/a&gt; is an open protocol designed to sync food product data across distributed nodes — compactly, efficiently, and with geo-location awareness built in by default.&lt;/p&gt;

&lt;p&gt;One of its core design decisions is the &lt;strong&gt;PAD system&lt;/strong&gt; (Preloaded Asset Distribution):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Apps ship with a &lt;strong&gt;preloaded asset pack&lt;/strong&gt; — item metadata, compressed images, category structure — all bundled at install time.&lt;/li&gt;
&lt;li&gt;Only &lt;strong&gt;price&lt;/strong&gt; and &lt;strong&gt;availability&lt;/strong&gt; need to travel over the wire during sync.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This means the data footprint per product is tiny. Very tiny.&lt;/p&gt;




&lt;h2&gt;
  
  
  Enter Nostr
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://nostr.com" rel="noopener noreferrer"&gt;Nostr&lt;/a&gt; is a simple, open protocol for decentralized communication. One of its key specs: &lt;strong&gt;events support up to 64 KB of content&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When we started exploring Nostr as a potential transport layer, we ran the numbers — and the fit was surprisingly clean.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Math: Products Per Event
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Baseline encoding
&lt;/h3&gt;

&lt;p&gt;A product represented with three fields:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"available"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"price"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this level of verbosity, a single 64 KB Nostr event can hold approximately:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~1,500 – 2,000 products
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Already useful. But we can do better.&lt;/p&gt;

&lt;h3&gt;
  
  
  Optimized encoding
&lt;/h3&gt;

&lt;p&gt;Two key optimizations:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Drop the availability key&lt;/strong&gt; — If a product entry exists in the JSON, it's available. If it's absent, it's not. No boolean needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Drop the field names&lt;/strong&gt; — Instead of &lt;code&gt;{"id": 500, "price": 30000}&lt;/code&gt;, just store:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;500,30000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Field mapping is handled at the app level, not the protocol level. The device knows position 0 is the product ID, position 1 is the price (in smallest currency unit, e.g. cents).&lt;/p&gt;

&lt;h3&gt;
  
  
  Result
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~6,000 – 7,000 products per single Nostr event
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Possibly more, depending on the price distribution and ID ranges in a given catalog.&lt;/p&gt;




&lt;h2&gt;
  
  
  Geo-Discovery: MinMax99 Cells
&lt;/h2&gt;

&lt;p&gt;DIFP uses a geo-cell system called &lt;strong&gt;MinMax99&lt;/strong&gt; to partition the world into addressable geographic units. Each cell can correspond to a Nostr relay or event namespace.&lt;/p&gt;

&lt;p&gt;This means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A client subscribes to the Nostr relay(s) for its geographic cell.&lt;/li&gt;
&lt;li&gt;It receives events containing only the product catalog relevant to that area.&lt;/li&gt;
&lt;li&gt;Country-specific and type-specific component catalogs further narrow the data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The result is &lt;strong&gt;geo-coordinated product discovery with zero central coordination&lt;/strong&gt;.&lt;/p&gt;




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

&lt;p&gt;Putting it all together:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Mechanism&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Product catalog&lt;/td&gt;
&lt;td&gt;PAD pack (shipped with app)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Price + availability sync&lt;/td&gt;
&lt;td&gt;Nostr events (64 KB, ~6–7k products)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Geo-discovery&lt;/td&gt;
&lt;td&gt;MinMax99 cell → Nostr relay mapping&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Country/type filtering&lt;/td&gt;
&lt;td&gt;Component catalog per region&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This architecture means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No central server required&lt;/strong&gt; for product sync&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open network&lt;/strong&gt; — anyone can run a relay, anyone can publish&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Geo-aware by default&lt;/strong&gt; — clients only receive what's relevant to them&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Censorship-resistant&lt;/strong&gt; — food data lives on a distributed event graph&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Why This Matters
&lt;/h2&gt;

&lt;p&gt;Food infrastructure is one of the most centralized, fragile systems in the world. A protocol stack that enables:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;free ordering&lt;/li&gt;
&lt;li&gt;donation coordination&lt;/li&gt;
&lt;li&gt;availability broadcasting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;...across an open, serverless, geo-aware network — without gatekeepers — is worth building.&lt;/p&gt;

&lt;p&gt;We didn't design DIFP for Nostr. But the fit turned out to be near-perfect.&lt;/p&gt;




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

&lt;p&gt;We're moving into &lt;strong&gt;implementation testing&lt;/strong&gt; — mapping live DIFP events onto Nostr relays with real product catalogs and measuring real-world throughput, latency, and relay compatibility.&lt;/p&gt;

&lt;p&gt;We'll publish results here as we go.&lt;/p&gt;




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

&lt;ul&gt;
&lt;li&gt;🔗 DIFP Protocol spec: &lt;a href="https://djowda.com/difp" rel="noopener noreferrer"&gt;djowda.com/difp&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🔗 Nostr protocol: &lt;a href="https://nostr.com" rel="noopener noreferrer"&gt;nostr.com&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Follow the Djowda journey — we're building open food infrastructure, one protocol at a time.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>data</category>
      <category>performance</category>
      <category>web3</category>
    </item>
    <item>
      <title>The First Break on the Walled Garden — Rethinking e-Food Delivery as an Open Protocol</title>
      <dc:creator>Djowda</dc:creator>
      <pubDate>Sat, 30 May 2026 03:20:36 +0000</pubDate>
      <link>https://dev.to/djowda/the-first-brick-on-the-walled-garden-rethinking-e-food-delivery-as-an-open-protocol-2g77</link>
      <guid>https://dev.to/djowda/the-first-brick-on-the-walled-garden-rethinking-e-food-delivery-as-an-open-protocol-2g77</guid>
      <description>&lt;p&gt;E-food delivery is a &lt;strong&gt;trillion-dollar market&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And most of that trillion is not going to farmers, store owners, or the people who actually move food around. It's going to the infrastructure layer sitting between them — the platform tax, the per-order cut, the SaaS subscription that charges you to exist inside someone else's garden.&lt;/p&gt;

&lt;p&gt;The walled garden isn't accidental. It's the product.&lt;/p&gt;




&lt;h2&gt;
  
  
  What if food delivery was a protocol, not a platform?
&lt;/h2&gt;

&lt;p&gt;Not an app. Not a marketplace. A &lt;strong&gt;protocol&lt;/strong&gt; — like HTTP, like SMTP — that any node can speak, that no single company owns, and that costs near zero to run.&lt;/p&gt;

&lt;p&gt;That's what &lt;a href="https://djowda.com/difp/" rel="noopener noreferrer"&gt;DIFP&lt;/a&gt; is. The Djowda Interconnected Food Protocol. An open wire format for connecting food ecosystem participants — farms, stores, restaurants, wholesalers, delivery nodes, end users — directly to each other, without a platform in the middle extracting rent at every step.&lt;/p&gt;

&lt;p&gt;The spec covers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Presence &amp;amp; discovery&lt;/strong&gt; — participants announce themselves to their spatial cell, others find them by location&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Orders, asks, and donations&lt;/strong&gt; — not just commerce, but demand signals and surplus distribution in the same protocol&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spatial routing&lt;/strong&gt; — the MinMax99 grid maps the entire planet into ~500m cells; every message knows where it's going&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Decentralized registry&lt;/strong&gt; — nodes find each other through a federated lobby system, no central server required&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Version 0.4 of the spec dropped a few weeks ago. Today we're publishing the first working implementation.&lt;/p&gt;




&lt;h2&gt;
  
  
  The gRPC preview — what we built
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/Djowda/DIFP-gRPC" rel="noopener noreferrer"&gt;&lt;strong&gt;DIFP-gRPC&lt;/strong&gt;&lt;/a&gt; is a skull implementation of the full protocol stack over gRPC. Thin, end-to-end, every domain wired — nothing production-hardened yet, everything clearly marked for what it is.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's inside
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;difp.proto&lt;/code&gt;&lt;/strong&gt; — the entire DIFP v0.4 spec as a single protobuf file. Two services, 30+ message types, the full &lt;code&gt;DifpEnvelope&lt;/code&gt; wrapper with a &lt;code&gt;oneof payload&lt;/code&gt; that covers every domain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight protobuf"&gt;&lt;code&gt;&lt;span class="kd"&gt;message&lt;/span&gt; &lt;span class="nc"&gt;DifpEnvelope&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c1"&gt;// "trade.ask" | "presence.announce" | "node.ping" | …&lt;/span&gt;
  &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="na"&gt;version&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;MessageSender&lt;/span&gt; &lt;span class="na"&gt;from&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;MessageTarget&lt;/span&gt; &lt;span class="na"&gt;target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;MessageMode&lt;/span&gt;   &lt;span class="na"&gt;mode&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;oneof&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;PresenceAnnouncePayload&lt;/span&gt; &lt;span class="na"&gt;presence_announce&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;TradeAskPayload&lt;/span&gt;         &lt;span class="na"&gt;trade_ask&lt;/span&gt;         &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;QueryCellPayload&lt;/span&gt;        &lt;span class="na"&gt;query_cell&lt;/span&gt;        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;NodePingPayload&lt;/span&gt;         &lt;span class="na"&gt;node_ping&lt;/span&gt;         &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;52&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;RegistryAnnouncePayload&lt;/span&gt; &lt;span class="na"&gt;registry_announce&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// … 25+ more&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;code&gt;DifpNodeServer.java&lt;/code&gt;&lt;/strong&gt; — a Java gRPC node that implements the §18 processing pipeline:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Structural validation&lt;/li&gt;
&lt;li&gt;Semantic validation (TTL, nonce)&lt;/li&gt;
&lt;li&gt;Cryptographic check ← &lt;em&gt;TODO: Ed25519 — placeholder for now&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Payload validation&lt;/li&gt;
&lt;li&gt;Handler dispatch&lt;/li&gt;
&lt;li&gt;Propagation ← &lt;em&gt;TODO: federation — placeholder for now&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Every database interaction is an isolated, clearly named placeholder function. You replace them one at a time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;db_queryPresenceByCell&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;   &lt;span class="c1"&gt;// → your PostGIS / Firebase spatial query&lt;/span&gt;
&lt;span class="n"&gt;db_createTrade&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;           &lt;span class="c1"&gt;// → your §9.1 atomic fan-out write&lt;/span&gt;
&lt;span class="n"&gt;db_registerComponent&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;     &lt;span class="c1"&gt;// → your auth provider + persistent store&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;code&gt;MainActivity.java&lt;/code&gt;&lt;/strong&gt; — an Android test client with 6 flows you can run against a live node:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Flow&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;computeCell&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Client-side MinMax99 — validates §3.3 reference vectors&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;register&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Unary RPC — registers a component, receives a DID back&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;queryCell&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Discovers nearby participants in a spatial cell&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ping&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Bidirectional stream — &lt;code&gt;node.ping&lt;/code&gt; → &lt;code&gt;node.pong&lt;/code&gt; + RTT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tradeAsk&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Full &lt;code&gt;trade.ask&lt;/code&gt; envelope broadcast via stream&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;registryQuery&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Lobby → node lookup&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Running it
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Build and start the node&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;server\java\examples&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;\gradlew.bat&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;installDist&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;\build\install\examples\bin\Difp-Node-Server&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c"&gt;# INFO: Server started, listening on 50051&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open &lt;code&gt;examples\android\&lt;/code&gt; in Android Studio, forward the port, run a flow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;adb&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;reverse&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;tcp:50051&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;tcp:50051&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. The protocol is on the wire.&lt;/p&gt;




&lt;h2&gt;
  
  
  A note on what this actually is
&lt;/h2&gt;

&lt;p&gt;This is not a product launch. It's a proof that the architecture works — that a food coordination protocol can run on commodity hardware over a standard transport, without a platform in the loop.&lt;/p&gt;

&lt;p&gt;The "skull" framing is intentional. A skull is the minimum structure that proves the shape of the thing. Every component is present, nothing is missing, nothing is over-built. The placeholders are not laziness — they're the seams where your storage, your auth, your network plugs in.&lt;/p&gt;

&lt;h3&gt;
  
  
  What this means in practice
&lt;/h3&gt;

&lt;p&gt;In the nearest future, a single node on a &lt;strong&gt;Raspberry Pi&lt;/strong&gt; will be able to coordinate thousands of components — farms, stores, restaurants, delivery agents — for a local food network. No cloud bill. No per-transaction cut. No permission required from a platform to exist.&lt;/p&gt;

&lt;p&gt;And because DIFP is just a protocol, the client can be anything. We wrote an Android app. But the wire format doesn't care. You could write a Python script. A web dashboard. A terminal client.&lt;/p&gt;

&lt;p&gt;Yes, you could order groceries from your CLI. We're not stopping you.&lt;/p&gt;

&lt;h3&gt;
  
  
  What about donations and asks?
&lt;/h3&gt;

&lt;p&gt;This is the part that doesn't exist in any commercial delivery platform, and it matters.&lt;/p&gt;

&lt;p&gt;DIFP has three trade types — not one:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Order&lt;/strong&gt; — standard purchase&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ask&lt;/strong&gt; — a demand signal, broadcast to the network: &lt;em&gt;"I need tomatoes, who has them?"&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Donation&lt;/strong&gt; — surplus distribution: &lt;em&gt;"I have 40kg of unsold bread, who needs it?"&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All three travel on the same wire, through the same nodes, with the same routing. Food security and commerce aren't separate systems in DIFP. They're the same protocol.&lt;/p&gt;




&lt;h2&gt;
  
  
  Next on the roadmap
&lt;/h2&gt;

&lt;p&gt;The skull proves the shape. The next iterations fill it in:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Stream broadcasting&lt;/strong&gt; — push events to all subscribers in a cell (the missing piece that makes it feel live)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real storage&lt;/strong&gt; — swap the placeholder functions for your backend of choice&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ed25519 signing&lt;/strong&gt; — message integrity per §15.3 of the spec&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Federation&lt;/strong&gt; — nodes announcing themselves to peer registries on startup&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PAD catalog distribution&lt;/strong&gt; — &lt;code&gt;/.well-known/difp/pad/latest&lt;/code&gt; for the product database&lt;/li&gt;
&lt;/ol&gt;




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

&lt;ul&gt;
&lt;li&gt;📄 &lt;strong&gt;DIFP Spec v0.4&lt;/strong&gt; — &lt;a href="https://djowda.com/difp/" rel="noopener noreferrer"&gt;djowda.com/difp&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;💻 &lt;strong&gt;DIFP-gRPC repo&lt;/strong&gt; — &lt;a href="https://github.com/Djowda/DIFP-gRPC" rel="noopener noreferrer"&gt;github.com/Djowda/DIFP-gRPC&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🏗 &lt;strong&gt;Djowda on GitHub&lt;/strong&gt; — &lt;a href="https://github.com/Djowda" rel="noopener noreferrer"&gt;github.com/Djowda&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The repo is CC-BY 4.0. Fork it, implement it, build on it. If you're working on food infrastructure — especially in regions where the platform tax hits hardest — we'd love to hear what you're building.&lt;/p&gt;

&lt;p&gt;Issues, PRs, and hard questions about the architecture are all welcome.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;DIFP is an open protocol. No one owns the food network.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>grpc</category>
      <category>opensource</category>
      <category>foodtech</category>
      <category>distributedsystems</category>
    </item>
    <item>
      <title>We Open Sourced the Djowda Platform — Here Are 6 Challenges for the Community</title>
      <dc:creator>Djowda</dc:creator>
      <pubDate>Mon, 20 Apr 2026 23:07:54 +0000</pubDate>
      <link>https://dev.to/djowda/we-open-sourced-the-djowda-platform-here-are-6-challenges-for-the-community-38op</link>
      <guid>https://dev.to/djowda/we-open-sourced-the-djowda-platform-here-are-6-challenges-for-the-community-38op</guid>
      <description>&lt;p&gt;The WFP just released &lt;a href="https://hungermap.wfp.org" rel="noopener noreferrer"&gt;Hunger Map Live&lt;/a&gt; — a real-time global food insecurity dashboard. The timing felt right to contribute back.&lt;/p&gt;

&lt;p&gt;Today we're open sourcing the Djowda platform architecture: a miniature reference implementation of one food ecosystem component, built on top of the &lt;a href="https://djowda.com/difp" rel="noopener noreferrer"&gt;DIFP protocol&lt;/a&gt; concept.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://github.com/Moses-Code-Dev/FoodSecurity-DIFP-Android-Playground" rel="noopener noreferrer"&gt;github.com/Moses-Code-Dev/FoodSecurity-DIFP-Android-Playground&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  A note on what this is
&lt;/h2&gt;

&lt;p&gt;The production codebase is going through a sanitization process — a single production component sits at ~250k lines of code. This release is intentionally simplified so that developers and AI tools can ingest the core architecture without noise.&lt;/p&gt;

&lt;p&gt;The full codebase will be released gradually at &lt;strong&gt;&lt;a href="https://github.com/Djowda" rel="noopener noreferrer"&gt;github.com/Djowda&lt;/a&gt;&lt;/strong&gt; over the coming months, component by component.&lt;/p&gt;




&lt;h2&gt;
  
  
  What you can build on top of this
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;🌍 Next-gen food coordination infrastructure&lt;/strong&gt;&lt;br&gt;
The &lt;a href="https://djowda.com/difp" rel="noopener noreferrer"&gt;DIFP protocol&lt;/a&gt; is designed for internationally interoperable food coordination. The repo is a working starting point. A Tunisian cooperative and an Indian marketplace speaking the same protocol, with zero custom integration — that's what this is pointing toward.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📍 Geo-targeted food discovery on live maps&lt;/strong&gt;&lt;br&gt;
The MinMax99 spatial grid bakes location into every message. Hyper-local, cell-based food visibility — collaborative, affordable, or free for producers who need reach without a marketing budget.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🎮 Interactive map engine for games&lt;/strong&gt;&lt;br&gt;
The MinMax99 grid is essentially a ready-made spatial coordinate system. Lords of Mobile-style interactive maps, powered by native in-device Android code, are a natural derivation. The IP is there if you want to use it.&lt;/p&gt;




&lt;h2&gt;
  
  
  6 Challenges for the community
&lt;/h2&gt;

&lt;p&gt;These are genuine open problems. If you work on any of them, open an issue or share what you find.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Challenge 1 — Web version across 6 components&lt;/strong&gt;&lt;br&gt;
Build a web implementation covering at least 6 different food ecosystem component types (farmer, store, wholesaler, restaurant, delivery, user) that all speak the same DIFP protocol without breaking interoperability. Bonus: make them federate across two independent nodes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Challenge 2 — Jetpack Compose port&lt;/strong&gt;&lt;br&gt;
Rewrite the existing component in Jetpack Compose. A good test of how well the architecture holds up across UI paradigms — and a useful contribution if you get it right.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Challenge 3 — Android Gemini fused response renderer&lt;/strong&gt;&lt;br&gt;
This one is genuinely unsolved and widely needed: build an Android library for rendering mixed UI from a single AI response message — text, chart, grid of items, and action buttons all in one response surface. The current Gemini SDK on Android doesn't handle this cleanly. If you solve it, it's useful well beyond this repo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Challenge 4 — MinMax99 map overlay&lt;/strong&gt;&lt;br&gt;
Overlay the MinMax99 grid as a layer on top of existing map engines — Google Maps, OpenStreetMap, Mapbox. Build a layer switcher. Visualize cell boundaries, cell IDs, and participant density per cell. This would be a powerful tool for anyone using the protocol.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Challenge 5 — Stress test at scale&lt;/strong&gt;&lt;br&gt;
Simulate millions of concurrent users on the coordination layer. Document what breaks first. We have assumptions about Firebase fan-out performance at scale that have not been tested under real load. If you run this, share the numbers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Challenge 6 — AI coding benchmark&lt;/strong&gt;&lt;br&gt;
Can your AI coding tool produce a production-ready DIFP component from the spec alone?&lt;/p&gt;

&lt;p&gt;Test it. Take the &lt;a href="https://djowda.com/difp" rel="noopener noreferrer"&gt;DIFP v0.2 specification&lt;/a&gt;, give it to Claude, Gemini, Copilot, or whatever tool you use, and ask it to build a conformant node component. Document what it gets right, what it misses, and where the spec needs to be clearer. This is useful both as a benchmark and as protocol feedback.&lt;/p&gt;




&lt;h2&gt;
  
  
  Repo details
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;License&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;   &lt;span class="s"&gt;AGPL-3.0&lt;/span&gt;
&lt;span class="na"&gt;Protocol&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;  &lt;span class="s"&gt;DIFP v0.2 (message envelope + spatial grid)&lt;/span&gt;
&lt;span class="na"&gt;Platform&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;  &lt;span class="s"&gt;Android (Java)&lt;/span&gt;
&lt;span class="na"&gt;Status&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;    &lt;span class="s"&gt;Miniature reference — full releases at github.com/Djowda&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Before publishing any derivative app:&lt;/strong&gt; rename the package identifier to avoid Play Store conflicts. The Djowda name and logo are trademarks — see the README for full notices.&lt;/p&gt;
&lt;/blockquote&gt;




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

&lt;ul&gt;
&lt;li&gt;📦 Playground repo: &lt;a href="https://github.com/Moses-Code-Dev/FoodSecurity-DIFP-Android-Playground" rel="noopener noreferrer"&gt;github.com/Moses-Code-Dev/FoodSecurity-DIFP-Android-Playground&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📄 DIFP Protocol Spec: &lt;a href="https://djowda.com/difp" rel="noopener noreferrer"&gt;djowda.com/difp&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🏗 Full platform (coming): &lt;a href="https://github.com/Djowda" rel="noopener noreferrer"&gt;github.com/Djowda&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🌍 WFP Hunger Map: &lt;a href="https://hungermap.wfp.org" rel="noopener noreferrer"&gt;hungermap.wfp.org&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;We built this in the open because the food coordination problem is bigger than any one team. The repo is yours — fork it, break it, build on it, and tell us what you find.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>android</category>
      <category>foodsecurity</category>
      <category>challenge</category>
    </item>
    <item>
      <title>We Open-Sourced a Protocol to Fix How the Food Supply Chain Talks to Itself</title>
      <dc:creator>Djowda</dc:creator>
      <pubDate>Wed, 11 Mar 2026 02:21:29 +0000</pubDate>
      <link>https://dev.to/djowda/we-open-sourced-a-protocol-to-fix-how-the-food-supply-chain-talks-to-itself-5h0b</link>
      <guid>https://dev.to/djowda/we-open-sourced-a-protocol-to-fix-how-the-food-supply-chain-talks-to-itself-5h0b</guid>
      <description>&lt;p&gt;Almost one billion people face food insecurity every year — not because the world doesn't produce enough food, but because the &lt;strong&gt;coordination infrastructure between producers and consumers is broken&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Farmers don't know who needs what. Stores don't know what's available 2km away. Surplus rots while scarcity persists — sometimes in the same city block.&lt;/p&gt;

&lt;p&gt;We spent years building a prototype to solve this. Today we're publishing the protocol that powers it.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://djowda.com/difp" rel="noopener noreferrer"&gt;djowda.com/difp&lt;/a&gt;&lt;/strong&gt; — DIFP v0.1, Provisional Specification · CC-BY 4.0 · Free to implement&lt;/p&gt;




&lt;h2&gt;
  
  
  What DIFP actually is
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;DIFP&lt;/strong&gt; (Djowda Interconnected Food Protocol) is a lightweight, open, spatial food coordination protocol. It defines:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Participant identity&lt;/strong&gt; — how food ecosystem actors identify themselves globally without a central registry&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spatial addressing&lt;/strong&gt; — how Earth's surface is divided into ~500m × 500m cells, each acting as a coordination zone&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Presence &amp;amp; discovery&lt;/strong&gt; — how participants announce and find each other within and across cells&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The trade message format&lt;/strong&gt; — a universal structure for orders, asks, and donations between any two participants&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Protocol federation&lt;/strong&gt; — how independent DIFP nodes interoperate without a central broker&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is &lt;strong&gt;transport-agnostic&lt;/strong&gt;. The reference implementation uses Firebase Realtime Database. Conformant implementations may use REST, WebSockets, MQTT, or anything equivalent.&lt;/p&gt;




&lt;h2&gt;
  
  
  The problem it solves for developers
&lt;/h2&gt;

&lt;p&gt;Right now if you're building a grocery delivery app, a farm management tool, a restaurant POS, or a truck routing system — you're building in isolation.&lt;/p&gt;

&lt;p&gt;There's no shared layer. No common identity. No standard way to say &lt;em&gt;"I'm a farmer at this location with these items available."&lt;/em&gt; Every integration is custom. Every partnership is a new API contract.&lt;/p&gt;

&lt;p&gt;DIFP proposes a fix: &lt;strong&gt;one protocol, one grid, one trade message format&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Any two systems that implement DIFP can discover each other, exchange availability data, and complete trades — with zero custom integration work.&lt;/p&gt;




&lt;h2&gt;
  
  
  The spatial grid — the core innovation
&lt;/h2&gt;

&lt;p&gt;The foundational piece of DIFP is a deterministic global grid called &lt;strong&gt;MinMax99&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The entire surface of Earth is divided into &lt;strong&gt;~3.44 billion cells&lt;/strong&gt;, each 500×500 meters. Every participant gets a &lt;strong&gt;cell ID&lt;/strong&gt; derived from their GPS coordinates using a single pure-math function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="nf"&gt;geoToCellNumber&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;latitude&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;longitude&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// Longitude → x in meters (linear)&lt;/span&gt;
    &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;longitude&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;180.0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;EARTH_WIDTH_METERS&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;360.0&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Latitude → y in meters (Mercator, origin at top)&lt;/span&gt;
    &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;EARTH_HEIGHT_METERS&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
             &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nc"&gt;Math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;log&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;tan&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;PI&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;4.0&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nc"&gt;Math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toRadians&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;latitude&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
               &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;EARTH_HEIGHT_METERS&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;2.0&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nc"&gt;Math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;PI&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

    &lt;span class="c1"&gt;// Meters → cell indices&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;xCell&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;Math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;floor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="no"&gt;CELL_SIZE_METERS&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// CELL_SIZE_METERS = 500&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;yCell&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;Math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;floor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="no"&gt;CELL_SIZE_METERS&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Clamp + encode&lt;/span&gt;
    &lt;span class="n"&gt;xCell&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;max&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;min&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;xCell&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;NUM_COLUMNS&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;  &lt;span class="c1"&gt;// NUM_COLUMNS = 82,000&lt;/span&gt;
    &lt;span class="n"&gt;yCell&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;max&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;min&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;yCell&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;NUM_ROWS&lt;/span&gt;    &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;  &lt;span class="c1"&gt;// NUM_ROWS    = 42,000&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;long&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;xCell&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="no"&gt;NUM_ROWS&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;yCell&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Grid constants&lt;/strong&gt; (all conformant implementations MUST use these exactly):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;EARTH_WIDTH_METERS  = 40,075,000
EARTH_HEIGHT_METERS = 20,000,000
CELL_SIZE_METERS    = 500
NUM_COLUMNS         = 82,000
NUM_ROWS            = 42,000
TOTAL_CELLS         ≈ 3.44 billion
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Reference test vectors&lt;/strong&gt; to validate your port:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Location&lt;/th&gt;
&lt;th&gt;lat, lng&lt;/th&gt;
&lt;th&gt;Cell ID&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Algiers, Algeria&lt;/td&gt;
&lt;td&gt;36.7372, 3.0868&lt;/td&gt;
&lt;td&gt;3440210&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Paris, France&lt;/td&gt;
&lt;td&gt;48.8566, 2.3522&lt;/td&gt;
&lt;td&gt;3467891&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tokyo, Japan&lt;/td&gt;
&lt;td&gt;35.6762, 139.6503&lt;/td&gt;
&lt;td&gt;6543210&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;New York, USA&lt;/td&gt;
&lt;td&gt;40.7128, -74.0060&lt;/td&gt;
&lt;td&gt;1823445&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Why a grid instead of geo-queries?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Discovery is O(1).&lt;/strong&gt; To find all stores near a farmer, query the farmer's cell + immediate neighbors. No radius search. No expensive geo API call.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cells are lobbies.&lt;/strong&gt; All components in the same cell share context — they can discover each other without knowing each other in advance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Works offline.&lt;/strong&gt; Cell IDs are computed client-side from GPS. No server round-trip needed to know your own address.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cheap at scale.&lt;/strong&gt; A Firebase &lt;code&gt;equalTo(cellId)&lt;/code&gt; query is fast and inexpensive. No PostGIS, no Elasticsearch geo-shape queries.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Neighbor resolution
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_nearby_cells&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;center_cell_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;xC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;yC&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;cell_number_to_xy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;center_cell_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;dx&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;radius&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;dy&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;radius&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;clamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;xC&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;dx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;NUM_COLUMNS&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;clamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;yC&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;dy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;NUM_ROWS&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;NUM_ROWS&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Radius&lt;/th&gt;
&lt;th&gt;Grid&lt;/th&gt;
&lt;th&gt;Cells&lt;/th&gt;
&lt;th&gt;Coverage&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;1×1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;~0.25 km²&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;3×3&lt;/td&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;~2.25 km²&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;5×5&lt;/td&gt;
&lt;td&gt;25&lt;/td&gt;
&lt;td&gt;~6.25 km²&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;11×11&lt;/td&gt;
&lt;td&gt;121&lt;/td&gt;
&lt;td&gt;~30 km²&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Participant identity — DIDs without a blockchain
&lt;/h2&gt;

&lt;p&gt;DIFP uses a &lt;strong&gt;Decentralized Identifier (DID)&lt;/strong&gt; scheme that requires no central authority and works offline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;difp://{cellId}/{typeCode}/{componentId}

# Examples
difp://3440210/f/ali-farm-01       # Farmer in cell 3,440,210 (Algiers)
difp://3440210/s/safeway-dz-042    # Store in same cell
difp://1820044/fa/cevital-plant-1  # Factory in cell 1,820,044
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ten canonical component types:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Code&lt;/th&gt;
&lt;th&gt;Actor&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Seed Provider&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;f&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Farmer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;fa&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Factory&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;w&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Wholesaler&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;s&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Store&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;r&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Restaurant&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;u&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;User / Consumer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;t&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Transport&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;d&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Delivery&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;a&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Admin&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  The trade message — one format for everything
&lt;/h2&gt;

&lt;p&gt;All exchanges in the food ecosystem — commercial orders, donation offers, resource requests — are modeled as &lt;strong&gt;Trades&lt;/strong&gt; between exactly two participants.&lt;/p&gt;

&lt;p&gt;Three trade types:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Code&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;o&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Order&lt;/td&gt;
&lt;td&gt;Purchase request with items, quantities, prices&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;a&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Ask&lt;/td&gt;
&lt;td&gt;Demand signal — "I need this, who has it?"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;d&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Donation&lt;/td&gt;
&lt;td&gt;Surplus signal — "I have this, who needs it?"&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The Ask and Donation types are first-class citizens of the protocol, not afterthoughts. They're how DIFP addresses food insecurity directly — signaling surplus and scarcity without requiring a commercial transaction.&lt;/p&gt;

&lt;h3&gt;
  
  
  Trade message schema
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"difp://3440210/f/ali-farm-01"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sT"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"f"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sC"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"3440210"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"difp://3440210/s/safeway-dz-042"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rT"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rC"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"3440210"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ty"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"o"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"st"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"p"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"items"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"difp:item:dz:vegetables:tomato_kg:v1"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"q"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"p"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"u"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"kg"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"total"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="mi"&gt;4000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"listSize"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"createdAt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1710000000000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"info"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"phone"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"+213..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"comment"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Status lifecycle
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PENDING (p)
    │
    ├── receiver accepts ──► ACCEPTED (a)
    │                              │
    │                              └──► PROCESSING (pr) ──► COMPLETED (c) ✓
    │
    ├── receiver denies ──► DENIED (dn) ✗
    │
    └── sender cancels  ──► CANCELLED (x) ✗
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The four-node atomic write pattern (fan-out)
&lt;/h3&gt;

&lt;p&gt;Every trade touches four Firebase nodes in a &lt;strong&gt;single atomic &lt;code&gt;updateChildren()&lt;/code&gt; call&lt;/strong&gt;. No partial writes. No race conditions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TD/{tradeId}                                    ← canonical full record
T/{senderType}/{senderId}/o/{tradeId}           ← sender outbox summary
T/{receiverType}/{receiverId}/i/{tradeId}       ← receiver inbox summary
TA/{tradeId}                                    ← analytics (no PII)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;updates&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
&lt;span class="n"&gt;updates&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TD/"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;tradeId&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tradeData&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;updates&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"T/"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;senderType&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"/"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;senderId&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"/o/"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;tradeId&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;senderSummary&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;updates&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"T/"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;receiverType&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"/"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;receiverId&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"/i/"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;tradeId&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;receiverSummary&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;updates&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TA/"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;tradeId&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"/createdAt"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;updates&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TA/"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;tradeId&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"/senderCell"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;senderCell&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;updates&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TA/"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;tradeId&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"/receiverCell"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;receiverCell&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;updateChildren&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;updates&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// atomic&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;TA&lt;/code&gt; (analytics) node tracks timing and cell pairs for map-route animation — and &lt;strong&gt;must never contain PII&lt;/strong&gt; (no phone numbers, no addresses, no item details).&lt;/p&gt;




&lt;h2&gt;
  
  
  The catalog system — PAD + live sync
&lt;/h2&gt;

&lt;p&gt;DIFP separates item metadata (static) from availability and pricing (live).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PAD (Pre-loaded Application Data):&lt;/strong&gt; ~6,000 items per country per component type, distributed as a compressed package with the app. Contains item names (multilingual), categories, units, thumbnail references. Never changes at runtime.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Live sync:&lt;/strong&gt; Only &lt;code&gt;price&lt;/code&gt; and &lt;code&gt;available&lt;/code&gt; travel over the wire during normal usage.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This means a farmer's app works in a village with 2G. The catalog is already on-device. Only the delta syncs.&lt;/p&gt;

&lt;p&gt;Item identity is globally namespaced:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;difp:item:{countryCode}:{category}:{itemSlug}:{version}

# Examples
difp:item:dz:vegetables:tomato_kg:v1
difp:item:in:grains:basmati_rice_kg:v2
difp:item:fr:dairy:camembert_250g:v1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Protocol federation
&lt;/h2&gt;

&lt;p&gt;DIFP is designed for independent operators — NGOs, national food agencies, regional cooperatives — to run their own nodes and interoperate.&lt;/p&gt;

&lt;p&gt;Every conformant node exposes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET https://{host}/.well-known/difp/info
# Returns: protocol version, nodeId, cell coverage, federated peers

GET https://{host}/.well-known/difp/cell/{cellId}
# Returns: all PresenceRecords in that cell

POST https://{host}/.well-known/difp/trade/incoming
# Accepts: signed TradeMessage from another DIFP node
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A Tunisian cooperative and an Indian marketplace running separate DIFP nodes can discover each other's participants and complete cross-node trades with zero custom integration — because they speak the same protocol.&lt;/p&gt;




&lt;h2&gt;
  
  
  How to implement (minimum viable node)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Step 1 — Port the grid algorithm.&lt;/strong&gt; Validate against the reference test vectors above. This is the only piece that MUST be bit-for-bit identical across all implementations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2 — Stand up a presence store.&lt;/strong&gt; Any backend (Firebase, PostgreSQL + PostGIS, DynamoDB). Index by &lt;code&gt;cell_id&lt;/code&gt; + &lt;code&gt;component_type&lt;/code&gt;. Expose the &lt;code&gt;/.well-known/difp/&lt;/code&gt; endpoints.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3 — Implement the trade engine.&lt;/strong&gt; Four-node write pattern. Role-based status transitions. Atomic writes.&lt;/p&gt;

&lt;p&gt;That's a working DIFP node. Steps 4 (catalog) and 5 (federation) can be added incrementally.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A working node with 10 participants is more valuable than a perfect spec with zero.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  What this means for AI + food
&lt;/h2&gt;

&lt;p&gt;One thing we didn't anticipate when designing this: &lt;strong&gt;DIFP makes food data natively queryable by AI systems&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Because every participant has a DID, a cell ID, a typed presence record, and a live catalog — any AI assistant with access to a DIFP node can answer questions like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;"Which farmers within 3km have tomatoes available right now?"&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"What's the current wholesale price of potatoes in this region?"&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"Which stores near me are broadcasting a donation?"&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No scraping. No stale listings. Live, structured, geographic data — in a format any system can query.&lt;/p&gt;




&lt;h2&gt;
  
  
  Current status &amp;amp; what's next (v0.2 targets)
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ID&lt;/th&gt;
&lt;th&gt;Topic&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;Ed25519 message signing for trustless cross-node verification&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;B&lt;/td&gt;
&lt;td&gt;Supply &amp;amp; Demand Radar — Ask/Donation signals aggregate into cell-level heat maps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;td&gt;Map route animation from TA cell pairs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;D&lt;/td&gt;
&lt;td&gt;MQTT profile for IoT farm sensors&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;E&lt;/td&gt;
&lt;td&gt;USSD/SMS fallback for participants with no smartphone&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;I&lt;/td&gt;
&lt;td&gt;Conformance test suite&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Read the spec. Build on it. Break it.
&lt;/h2&gt;

&lt;p&gt;Full specification: &lt;strong&gt;&lt;a href="https://djowda.com/difp" rel="noopener noreferrer"&gt;djowda.com/difp&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Download: &lt;a href="https://djowda.com/assets/docs/DIFP-v0_1-Provisional.docx" rel="noopener noreferrer"&gt;DIFP-v0.1-Provisional.docx&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Contact: &lt;a href="mailto:sales@djowda.com"&gt;sales@djowda.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;License: &lt;strong&gt;CC-BY 4.0&lt;/strong&gt; — free to implement, fork, extend, and commercialize. Credit required.&lt;/p&gt;




&lt;p&gt;The food system doesn't need another closed platform. It needs a shared language.&lt;/p&gt;

&lt;p&gt;We just published ours. 🌍&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>protocol</category>
      <category>foodtech</category>
      <category>architecture</category>
    </item>
  </channel>
</rss>
