<?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: Adwait Keshari</title>
    <description>The latest articles on DEV Community by Adwait Keshari (@adwaitkeshari).</description>
    <link>https://dev.to/adwaitkeshari</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4234873%2Faadc822b-ac56-4f81-add1-9473badb26ad.png</url>
      <title>DEV Community: Adwait Keshari</title>
      <link>https://dev.to/adwaitkeshari</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/adwaitkeshari"/>
    <language>en</language>
    <item>
      <title>Ferry: one AI memory you own, carried across ChatGPT, Claude and Gemini on Walrus</title>
      <dc:creator>Adwait Keshari</dc:creator>
      <pubDate>Mon, 09 Nov 2026 11:16:20 +0000</pubDate>
      <link>https://dev.to/adwaitkeshari/ferry-one-ai-memory-you-own-carried-across-chatgpt-claude-and-gemini-on-walrus-3f67</link>
      <guid>https://dev.to/adwaitkeshari/ferry-one-ai-memory-you-own-carried-across-chatgpt-claude-and-gemini-on-walrus-3f67</guid>
      <description>&lt;p&gt;I use ChatGPT, Claude and Gemini every week. Each of them knows things about me: what I'm building, which stack I reach for, how I like answers written. None of them knows what the others know, and I don't own any of it. When I switch, I start over.&lt;/p&gt;

&lt;p&gt;Ferry is my fix. It takes the memory those apps hold about you, moves it into a store you own on Walrus Mainnet, and brings it back into whichever AI you open next. Every fact carries a receipt that shows where it came from. I built it in about 36 hours for Total Recall, the Tatum x Walrus hackathon.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Repo: &lt;a href="https://github.com/Adwaitbytes/ferry" rel="noopener noreferrer"&gt;https://github.com/Adwaitbytes/ferry&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Live app: &lt;a href="https://ferry-memory.vercel.app" rel="noopener noreferrer"&gt;https://ferry-memory.vercel.app&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Demo video: link added once it is uploaded&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Falekssqn5dd5hrlfv5e7.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Falekssqn5dd5hrlfv5e7.jpg" alt="Ferry offering 6 facts inside Gemini" width="800" height="729"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why now
&lt;/h2&gt;

&lt;p&gt;Walrus has been making this argument all week. Their Nov 5 article asked who actually owns the AI memory everyone shipped in October, and argued that memory you can't take with you is just storage rented from one vendor (&lt;a href="https://blog.walrus.xyz/memwal-long-term-memory-for-ai-agents/" rel="noopener noreferrer"&gt;Walrus&lt;/a&gt;). On Nov 8 they posted that a good assistant remembers what you said and a great one shows where it heard it (&lt;a href="https://blog.walrus.xyz/memwal-long-term-memory-for-ai-agents/" rel="noopener noreferrer"&gt;Walrus&lt;/a&gt;). On Nov 4, that agents need context that stays current, not outdated decisions (&lt;a href="https://blog.walrus.xyz/memwal-long-term-memory-for-ai-agents/" rel="noopener noreferrer"&gt;Walrus&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;We read those as a spec. Portable, with receipts, and current.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Ferry does
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Rescue.&lt;/strong&gt; Drop your ChatGPT, Claude or Gemini export into the web app. The ZIP is parsed on your device in a Web Worker and never uploaded. Ferry keeps only what you typed, asks a model to pull out durable facts, and shows each one next to the exact quote it came from. You approve, edit or discard. Approved facts go to Walrus Memory. On my own export that was 312 facts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkq66ppq2maufu9gxkiyz.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkq66ppq2maufu9gxkiyz.jpg" alt="The Ferry Library with real facts, each with its source and date" width="800" height="682"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Carry.&lt;/strong&gt; A Chrome extension watches the chat composer on chatgpt.com, claude.ai and gemini.google.com. When you tell one AI something durable, a small toast offers to save it. When you start typing in another AI, Ferry recalls what's relevant and shows a chip: "Ferry has 2 things Claude should know". You click Insert, and a clearly marked block goes at the top of your prompt. Ferry never inserts anything on its own.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4cv0cykgjjsypklf2ehe.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4cv0cykgjjsypklf2ehe.jpg" alt="Ferry chip live on Gemini, with real facts and receipts" width="800" height="729"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stays current.&lt;/strong&gt; When a new fact contradicts an old one, Ferry shows both side by side with their sources. Pick one, and Ferry writes the new fact to Walrus with a pointer to the old blob it supersedes. The old one stays in history and is never inserted again.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Blackout Drill.&lt;/strong&gt; Ferry Desk is a small chat with a model picker. Press Cut off, and the current provider goes dark. That part is simulated and labelled DEMO. The thread continues on another model, recalls the same memory from Walrus, and the counter says "0 facts lost". Your memory never lived with the provider, so there was nothing to lose.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Share and Earn.&lt;/strong&gt; You can publish a slice of your memory, say "food preferences", as a Share Card with a price. An agent that wants it calls Ferry Gate, gets HTTP 402, pays 0.01 USDC on Sui to your address, and gets only that slice.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Ferry uses Walrus
&lt;/h2&gt;

&lt;p&gt;Walrus Memory is the store. Every fact is a memory in your own MemWalAccount on Sui Mainnet, written through the hosted relayer with a delegate key that lives in the extension.&lt;/p&gt;

&lt;p&gt;Walrus Memory stores plain text with no tags, so we append one header line to every memory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I am allergic to cashews.
⟦ferry:v1 t=constraint s=chatgpt c=&amp;lt;hash&amp;gt; at=&amp;lt;date&amp;gt; cf=0.92 q=&amp;lt;hash&amp;gt; sup=- st=active⟧
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The sentence comes first so embeddings stay clean. The header carries the fact type, which AIs it was heard in, a hashed conversation id, the date, confidence, a hash of the supporting quote, the blob it supersedes and its status. That one line is what makes receipts, conflicts and forget possible on a store that doesn't have them built in. A fact containing the header brackets is refused before it's written, so nobody can forge one (&lt;a href="https://github.com/Adwaitbytes/ferry/blob/main/packages/core/src/header.ts" rel="noopener noreferrer"&gt;header.ts&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;A few things we learned the hard way, all from reading the relayer source:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The rate limit is points, not calls. A single &lt;code&gt;remember&lt;/code&gt; costs 5 points; &lt;code&gt;rememberBulk&lt;/code&gt; with up to 20 items costs 10. A key gets 30 points a minute and an account 500 an hour. So every write in Ferry is a bulk write through a paced queue (&lt;a href="https://github.com/Adwaitbytes/ferry/blob/main/packages/memwal/src/governor.ts" rel="noopener noreferrer"&gt;governor.ts&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;The relayer doesn't send CORS headers yet (&lt;a href="https://github.com/MystenLabs/walrus-memory/issues/1119" rel="noopener noreferrer"&gt;#1119&lt;/a&gt;). We didn't want a Ferry server in the memory path, so the extension service worker became the memory engine for everything, including the web app, which talks to it through &lt;code&gt;externally_connectable&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;There is no delete. Forget in Ferry means a tombstone memory plus local exclusion, and the receipt drawer shows the storage epoch when the encrypted blob actually expires. We say exactly that in the UI.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Seal&lt;/strong&gt; is used in Vault mode. Instead of the relayer embedding and encrypting your text, the browser makes the embedding and Seal-encrypts the fact before it leaves the device (&lt;a href="https://github.com/Adwaitbytes/ferry/blob/main/packages/memwal/src/vault.ts" rel="noopener noreferrer"&gt;vault.ts&lt;/a&gt;). The relayer still sees vectors, the owner address and when you search, and we say so.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Walrus blobs&lt;/strong&gt; back the receipts. The Verify button on any fact refetches its blob from the Walrus aggregator and checks the bytes against the blob id. Since the blob is ciphertext, the UI words it carefully: the ciphertext on Walrus matches the blob id.&lt;/p&gt;

&lt;h2&gt;
  
  
  How we used Tatum
&lt;/h2&gt;

&lt;p&gt;Sui's public JSON-RPC was deprecated during the hackathon, so every chain read in Ferry goes through Tatum's Sui gRPC gateway at &lt;code&gt;sui-mainnet-grpc.gateway.tatum.io&lt;/code&gt;. One catch: Tatum speaks native gRPC, not gRPC-Web, so the default browser client fails against it. We run a native transport on the server and put a thin proxy in front of it, which also keeps the API key out of the extension bundle (&lt;a href="https://github.com/Adwaitbytes/ferry/blob/main/packages/chain/src/tatum.ts" rel="noopener noreferrer"&gt;tatum.ts&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Tatum does four real jobs in Ferry:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Account and delegate reads.&lt;/strong&gt; Pairing confirms your new delegate key is on your MemWalAccount by reading the object through Tatum. The Devices page lists every key with its label and date.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Blob epochs.&lt;/strong&gt; Each receipt shows the Walrus Blob object's certified epoch, end epoch and owner, read live (&lt;a href="https://github.com/Adwaitbytes/ferry/blob/main/packages/chain/src/readers.ts" rel="noopener noreferrer"&gt;readers.ts&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Payment verification.&lt;/strong&gt; When an agent pays Gate, we fetch the transaction through Tatum and check status, coin type, amount, recipient and finality before serving anything (&lt;a href="https://github.com/Adwaitbytes/ferry/blob/main/packages/chain/src/payment.ts" rel="noopener noreferrer"&gt;payment.ts&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Price data.&lt;/strong&gt; Earnings show in USDC and in dollars using Tatum's exchange rate endpoint, cached for 60 seconds (&lt;a href="https://github.com/Adwaitbytes/ferry/blob/main/packages/chain/src/price.ts" rel="noopener noreferrer"&gt;price.ts&lt;/a&gt;).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The free plan allows 3 requests per second, so the proxy has a token bucket, a short cache and a credit meter you can see on the Proofs page. We used 20 of 100,000 free-plan credits by 9 Nov 2026 credits over the hackathon.&lt;/p&gt;

&lt;h2&gt;
  
  
  Agent payments with MPP on Sui
&lt;/h2&gt;

&lt;p&gt;Gate speaks MPP, the Machine Payments Protocol, using &lt;code&gt;@suimpp/mpp&lt;/code&gt; on Sui Mainnet with Circle USDC. The flow is plain HTTP:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The agent asks for a card and gets &lt;code&gt;402&lt;/code&gt; with a &lt;code&gt;WWW-Authenticate: Payment&lt;/code&gt; challenge naming the price and recipient.&lt;/li&gt;
&lt;li&gt;It sends 0.01 USDC to the card owner's address and retries with the digest.&lt;/li&gt;
&lt;li&gt;Gate re-verifies the transaction through Tatum, inserts the digest into a Neon table with a unique constraint so it can never be replayed, and returns the facts with a payment receipt.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Ferry never holds the money. And because Walrus delegate keys can read a whole account, Gate never gets a key to your private memory. It reads from a separate Public profile account that only contains what you published (&lt;a href="https://github.com/Adwaitbytes/ferry/blob/main/packages/pay/src/gateway.ts" rel="noopener noreferrer"&gt;gateway.ts&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Our test agent, TripScout, pays from a terminal in about 13 lines. The first real payment ran on Sui Testnet, because we had no real money for Mainnet USDC: TripScout paid 0.01 USDC straight to the card owner, the Gate checked it through Tatum, and five facts came back (&lt;a href="https://suiscan.xyz/testnet/tx/BfqBDhWvz3gcy9Dys1mUPxjm4Tvisu6uLSnT2KQ1j4Gv" rel="noopener noreferrer"&gt;transaction&lt;/a&gt;). The same code runs on Mainnet; only one setting changes.&lt;/p&gt;

&lt;p&gt;The payment on Suiscan: &lt;a href="https://suiscan.xyz/testnet/tx/BfqBDhWvz3gcy9Dys1mUPxjm4Tvisu6uLSnT2KQ1j4Gv" rel="noopener noreferrer"&gt;https://suiscan.xyz/testnet/tx/BfqBDhWvz3gcy9Dys1mUPxjm4Tvisu6uLSnT2KQ1j4Gv&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How Ferry learned over time
&lt;/h2&gt;

&lt;p&gt;The point of a memory is that the product behaves differently tomorrow because of what happened today. Here is what that looked like on 9 Nov 2026, using the founder's own real data. Every number below is read from the paired extension's index and from Walrus.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;312 facts rescued&lt;/strong&gt; from the founder's own Claude history and written to Walrus Mainnet, 0 failed writes. We asked Claude what it knew, then four more times to search older chats. Each answer went through Rescue, where Ferry pulled out facts and we reviewed every card. Three were thrown out: two near duplicates and one that read a client's factory as the founder's own.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What they cover:&lt;/strong&gt; 128 projects, 67 preferences, 39 decisions, 15 people, 14 dislikes, 13 identity facts, 13 skills, 9 goals, 9 routines, 4 constraints and 1 lesson.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The import taught the product.&lt;/strong&gt; The first try turned 91 lines into 19 facts and then failed outright on a long chunk. We changed how pasted answers are split, gave each chunk a fair output budget, and made a failed batch split itself and retry instead of failing the import. After that, 80 to 100 lines of real history became 40 to 75 clean facts per pass.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory showed up somewhere else.&lt;/strong&gt; Typing a planning question into Gemini, a model that never saw any of this, Ferry offered "6 things Gemini should know", including "Product priority is Select 360 first, Wave second, SpeakCoach third", with the receipt one click away.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It survived a provider cut.&lt;/strong&gt; In the Blackout Drill we cut Claude off mid-thread. The same thread continued on Gemini, which answered from the same Walrus memory: "focus on Select 360 first this week." Facts lost: 0.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Total memories on Mainnet: 312. Account: &lt;a href="https://suiscan.xyz/mainnet/object/0x2707ca76b9a7ed62b1405089b745738e64f6d83e61763668d9c26c7572c691d2" rel="noopener noreferrer"&gt;https://suiscan.xyz/mainnet/object/0x2707ca76b9a7ed62b1405089b745738e64f6d83e61763668d9c26c7572c691d2&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security, briefly
&lt;/h2&gt;

&lt;p&gt;Ferry stores things people say about themselves, and it writes them somewhere they can't be deleted. So we treated poisoning as the main threat. Ferry only saves the user's own messages, only with approval, and every candidate passes an injection scanner (imperatives aimed at AIs, exfiltration URLs, encoded payloads, hidden Unicode) and a sensitive data detector before anything is written. Card numbers, government ids and secrets are always blocked. The red-team suite has 81 cases; all 81 pass in CI. Details in &lt;a href="https://github.com/Adwaitbytes/ferry/blob/main/docs/THREAT_MODEL.md" rel="noopener noreferrer"&gt;THREAT_MODEL.md&lt;/a&gt; and &lt;a href="https://github.com/Adwaitbytes/ferry/blob/main/docs/REDTEAM.md" rel="noopener noreferrer"&gt;REDTEAM.md&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's honest to say
&lt;/h2&gt;

&lt;p&gt;Standard mode is not end to end encrypted, because the hosted relayer sees text while it processes it. Vault mode fixes that at the cost of one wallet approval per session. Forget is hide, not delete. The extension is required for memory operations until the relayer ships CORS. And export formats change without notice, so our parsers are defensive and we will keep testing them against fresh exports.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Web app: &lt;a href="https://ferry-memory.vercel.app" rel="noopener noreferrer"&gt;https://ferry-memory.vercel.app&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Extension: &lt;a href="https://github.com/Adwaitbytes/ferry/releases/tag/v0.1.0-beta.1" rel="noopener noreferrer"&gt;https://github.com/Adwaitbytes/ferry/releases/tag/v0.1.0-beta.1&lt;/a&gt; (load unpacked in Chrome)&lt;/li&gt;
&lt;li&gt;Repo, with a 10 minute quickstart: &lt;a href="https://github.com/Adwaitbytes/ferry" rel="noopener noreferrer"&gt;https://github.com/Adwaitbytes/ferry&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Switch AIs. Keep yourself.&lt;/p&gt;

&lt;p&gt;Built by Adwait Keshari for Total Recall by &lt;a href="https://tatum.io" rel="noopener noreferrer"&gt;Tatum&lt;/a&gt; x &lt;a href="https://walrus.xyz" rel="noopener noreferrer"&gt;Walrus&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>walrus</category>
      <category>sui</category>
      <category>tatum</category>
      <category>hackathon</category>
    </item>
  </channel>
</rss>
