<?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: SHANE JOANS V</title>
    <description>The latest articles on DEV Community by SHANE JOANS V (@shane_joans27csb_3465e66).</description>
    <link>https://dev.to/shane_joans27csb_3465e66</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%2F4232465%2Fa70d36eb-84ad-4cb0-bd84-9e9ecca5ce1c.png</url>
      <title>DEV Community: SHANE JOANS V</title>
      <link>https://dev.to/shane_joans27csb_3465e66</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/shane_joans27csb_3465e66"/>
    <language>en</language>
    <item>
      <title>Said-No: a wallet that remembers what you refused</title>
      <dc:creator>SHANE JOANS V</dc:creator>
      <pubDate>Sat, 07 Nov 2026 16:46:36 +0000</pubDate>
      <link>https://dev.to/shane_joans27csb_3465e66/said-no-a-wallet-that-remembers-what-you-refused-520f</link>
      <guid>https://dev.to/shane_joans27csb_3465e66/said-no-a-wallet-that-remembers-what-you-refused-520f</guid>
      <description>&lt;p&gt;Most wallets remember approvals. They keep a list of contracts you allowed and addresses you paid. Almost none remember the sends you &lt;em&gt;didn't&lt;/em&gt; make, and those are the ones that tell you the most about yourself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Said-No&lt;/strong&gt; is a consent firewall for Sui. When you refuse a send, it saves your reason, in your own words, to &lt;strong&gt;Walrus Memory&lt;/strong&gt;. The next time a send looks like one you refused, it quotes you back to yourself and adds friction in proportion to how similar the two are. Live chain facts come from &lt;strong&gt;Tatum's Sui gRPC gateway&lt;/strong&gt;. It is built for the Tatum x Walrus Memory "Total Recall" hackathon.&lt;/p&gt;

&lt;p&gt;Submitted to &lt;strong&gt;Track 3: Consumer Finance&lt;/strong&gt; and &lt;strong&gt;Best Walrus Memory&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Live demo: &lt;a href="https://said-no.live" rel="noopener noreferrer"&gt;Said-No&lt;/a&gt; · Code: &lt;a href="https://github.com/shane2512/Said-No" rel="noopener noreferrer"&gt;Github&lt;/a&gt; · Video: &lt;a href="https://youtu.be/j8ERXSaSCFM" rel="noopener noreferrer"&gt;Youtube&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What it looks like
&lt;/h2&gt;

&lt;p&gt;You are about to send 7 SUI to an address you have never paid. Said-No checks the chain through Tatum, recalls your past refusals from Walrus Memory, and answers:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You refused something like this before: "Too large for someone I have never paid. If this is real they can take a small test first." Without this memory the send would be &lt;strong&gt;normal&lt;/strong&gt;. With it: &lt;strong&gt;reflection&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That last line is the counterfactual, and it is the point. The memory changed the decision, and the page shows by how much.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it decides
&lt;/h2&gt;

&lt;p&gt;No model sits in the loop. Each remembered decision is compared with the send in front of you using four factors: whether the recipient is new, the amount (relative to &lt;em&gt;your&lt;/em&gt; usual amount), the hour of day, and how often you have paid that address. The default weights are 0.35, 0.30, 0.20 and 0.15. The score picks a level:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;below 0.40: &lt;strong&gt;normal&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;0.40 to 0.69: &lt;strong&gt;reminder&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;0.70 to 0.84: &lt;strong&gt;reflection&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;a memory marked "never this address", or two matching refusals at 0.85 or above: &lt;strong&gt;hold&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Approvals count too. If you have approved this kind of send more often than you refused it, the friction drops. You can forget any memory, and you can override any warning. The same inputs always give the same verdict, and a test pins that down.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It learns you, within limits.&lt;/strong&gt; Once you have three refusals, a factor that is the same across them counts for more. If you always refuse at night, the hour matters more for you. Half of each weight stays on the fixed default, so a few refusals can't swing the score far. Said-No also states the patterns it found in plain words ("You tend to refuse late-night sends"), but only when at least two refusals and 60 percent of them agree, so one bad night never becomes a rule. The "Why" panel shows every factor's contribution, so there is no black box.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reflection is a pause, not a quiz.&lt;/strong&gt; On a reflection verdict the Proceed button unlocks after five seconds. Nothing is taken away from you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Tatum and Walrus fit
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Tatum&lt;/strong&gt; supplies the live facts about the send:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;your balance, and your outgoing history, so "unusual amount" means unusual &lt;em&gt;for you&lt;/em&gt;;&lt;/li&gt;
&lt;li&gt;a dry run before anything is offered to your wallet;&lt;/li&gt;
&lt;li&gt;a check of the recipient against Tatum's malicious-address list. A listed address is held. If the screen can't run, the send is still checked and shown as "unscreened";&lt;/li&gt;
&lt;li&gt;the broadcast of the transaction your wallet signed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sui JSON-RPC is gone, so this goes through Tatum's native gRPC gateway. Two things we learned the hard way: the gateway speaks native gRPC only (grpc-web is rejected), and &lt;code&gt;ListTransactions&lt;/code&gt; is a server stream that needs a start checkpoint taken from &lt;code&gt;getServiceInfo&lt;/code&gt;, because nodes prune old history. The free plan allows three requests per second, so calls are paced and retried.&lt;/p&gt;

&lt;p&gt;Two chain-only nudges need no past refusal: three or more sends in an hour, and a new recipient with an amount five times your usual. Both can only raise a send to a reminder, so ordinary sends stay silent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Walrus Memory&lt;/strong&gt; holds the decisions. Each is stored as a plain sentence plus a JSON line, and the matching happens in code. Memory's own semantic search adds one more thing: you can type what a send is for ("a stranger says the offer ends today"), and if that means roughly what a past refusal meant, Said-No quotes that refusal. It is a nudge, never a block. Writes take about 25 seconds, which the UI shows honestly instead of hiding. The blobs are encrypted, so a block explorer shows no readable text.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your wallet, your memory
&lt;/h2&gt;

&lt;p&gt;You can run a check with no wallet at all and see Tatum's facts straight away. A wallet is needed only when you save a refusal or send. Then you connect your own Sui wallet and the server holds &lt;strong&gt;no spending key&lt;/strong&gt;: it checks the send, builds an unsigned transfer, your wallet signs it, and Tatum broadcasts it. You sign one message to unlock your memories, which live in a separate namespace per wallet. If Tatum or Memory is unreachable, Said-No does not quietly say "normal". It treats the send as at least a reflection. A safety tool that goes silent when it breaks is worse than none.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it learned from being built
&lt;/h2&gt;

&lt;p&gt;Memory is only useful if it is correct. Three bugs taught us that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Frozen ratios.&lt;/strong&gt; We first stored "this amount was 3x your usual" at save time. As your usual changed, old memories went wrong: a 0.5 SUI send scored 0.70 and a 0.01 SUI send scored 1.00. We now store real amounts and rebase them at check time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No history.&lt;/strong&gt; A brand-new wallet has no median, so the amount ratio came out as 10,000,000. Now it is neutral.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shared memory.&lt;/strong&gt; When we made memories per wallet, an explicit namespace in the save call overrode each wallet's own, so every visitor shared one pool. A live two-wallet test against real Walrus caught it within minutes, and we bound the namespace inside the client so no caller can override it.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Honest limits
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The 12 memories we wrote to Walrus mainnet for the hackathon were drafted with an AI assistant as example decisions. They prove the writes, not months of real use. The README lists every blob ID.&lt;/li&gt;
&lt;li&gt;Tatum reads and sends work on testnet and mainnet. Testnet sends were run repeatedly, and &lt;strong&gt;one of the real mainnet send&lt;/strong&gt; (0.0000001 SUI, &lt;a href="https://suiscan.xyz/mainnet/tx/2xVuyxj3L4YGVxKVbaVrfkwGJNrDww61GFtd7ondLDGy" rel="noopener noreferrer"&gt;digest&lt;/a&gt;) was made from the live app and checked on-chain. The recipient got exactly that amount; the sender also paid the roughly 0.001 SUI network fee. One small transaction, not a load test.&lt;/li&gt;
&lt;li&gt;The meaning-match cutoff came from a small sample of memories and will need re-tuning with more. The scam-list check has been confirmed live only for a clean address.&lt;/li&gt;
&lt;li&gt;Memories sit in the project's Walrus account, so the operator can read them. This is a demo, not a vault.&lt;/li&gt;
&lt;li&gt;Said-No adds friction. It cannot stop a determined user, and it is not financial advice.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Open &lt;a href="https://said-no.live/app" rel="noopener noreferrer"&gt;https://said-no.live/app&lt;/a&gt; and run a check, no wallet needed. To see it remember you, connect a Sui wallet (testnet is free from the faucet), deny a send with a reason, then check the same send again and watch it quote you back.&lt;/p&gt;

</description>
      <category>web3</category>
      <category>security</category>
      <category>blockchain</category>
      <category>hackathon</category>
    </item>
  </channel>
</rss>
