<?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: zgrguric</title>
    <description>The latest articles on DEV Community by zgrguric (@zgrguric_88).</description>
    <link>https://dev.to/zgrguric_88</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%2Fuser%2Fprofile_image%2F3862684%2F61623a65-c8cf-4592-9a9d-811b41ab27d1.webp</url>
      <title>DEV Community: zgrguric</title>
      <link>https://dev.to/zgrguric_88</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/zgrguric_88"/>
    <language>en</language>
    <item>
      <title>Hook State Converter: Decode Xahau HookState ABI Without the Guesswork</title>
      <dc:creator>zgrguric</dc:creator>
      <pubDate>Sun, 12 Apr 2026 23:07:14 +0000</pubDate>
      <link>https://dev.to/xrplwin/hook-state-converter-decode-xahau-hookstate-abi-without-the-guesswork-7j2</link>
      <guid>https://dev.to/xrplwin/hook-state-converter-decode-xahau-hookstate-abi-without-the-guesswork-7j2</guid>
      <description>&lt;p&gt;If you've built Hooks on Xahau, you've been here: staring at a raw HookState entry like &lt;code&gt;5852504C57696E&lt;/code&gt; and trying to figure out what it actually means.&lt;/p&gt;

&lt;p&gt;Is it a &lt;code&gt;UInt32&lt;/code&gt;? A &lt;code&gt;VarString&lt;/code&gt;? A timestamp? A ledger index? Big-endian or little-endian?&lt;/p&gt;

&lt;p&gt;You either write a throwaway script, crack open a hex calculator, or just guess. None of these are great when you're in the middle of debugging a Hook at 2am.&lt;/p&gt;

&lt;p&gt;That's exactly why we built the &lt;strong&gt;&lt;a href="https://xahau.xrplwin.com/tools/hook/abi-conversion-helper" rel="noopener noreferrer"&gt;Hook State Converter&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;But before we get into the tool, let's talk about why HookState data is so hard to read in the first place — because understanding the problem makes the solution a lot more useful.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why HookState data is hard to read
&lt;/h2&gt;

&lt;p&gt;Xahau Hooks are small programs that run directly on the ledger. They can read and write persistent state using a key-value store called &lt;code&gt;HookState&lt;/code&gt;. Each entry has a 32-byte key and an arbitrary-length value, both stored as raw binary data on the ledger.&lt;/p&gt;

&lt;p&gt;That last part is the catch: &lt;em&gt;raw binary data&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Unlike a database where you define a schema upfront and the engine enforces types, &lt;code&gt;HookState&lt;/code&gt; has no built-in type system. A Hook author decides how to encode data — as a little-endian &lt;code&gt;UInt32&lt;/code&gt;, as an &lt;code&gt;XFL&lt;/code&gt; float, as a packed struct of multiple fields — and that decision lives only in the Hook's source code. The ledger just stores bytes.&lt;/p&gt;

&lt;p&gt;When you look at an account's HookState on an explorer, you see something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Key:   637373746F6D65725F6163636F756E74000000000000000000000000000000000000
Value: 05A528BCFA2189C8E2E7813775ED71B2C4BE349F`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What does the key mean? What type is the value? Is it an &lt;code&gt;AccountID&lt;/code&gt;? A &lt;code&gt;hash&lt;/code&gt;? A packed amount and timestamp? There is no metadata attached to the entry. The ledger doesn't know and doesn't care — it just stores and retrieves bytes on demand.&lt;/p&gt;

&lt;p&gt;This creates a real problem for anyone who isn't the original Hook author:&lt;/p&gt;

&lt;p&gt;Auditors trying to verify what state a Hook is reading and writing Developers debugging why a Hook behaved unexpectedly Integration builders trying to read HookState from an external app Explorer users who just want to understand what they're looking at. Even if you are the original author, coming back to a Hook months later and trying to remember your own encoding scheme is painful. And if the Hook is open source but the ABI schema isn't documented anywhere, you're left reading C source code and mentally simulating byte offsets.&lt;/p&gt;




&lt;h2&gt;
  
  
  The encoding rabbit hole
&lt;/h2&gt;

&lt;p&gt;To illustrate how quickly this gets complicated, consider a simple HookState key that encodes a string like customer_account padded to 32 bytes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;637573746F6D65725F6163636F756E740000000000000000000000000000000000000000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To decode this manually you would:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Split the hex into byte pairs: 63 75 73 74 6F 6D 65 72 5F 61 63 63 ...&lt;/li&gt;
&lt;li&gt;Convert each byte from hex to ASCII: c u s t o m e r _ a c c o u n t \0 \0 ...&lt;/li&gt;
&lt;li&gt;Recognize it as a null-padded ASCII string&lt;/li&gt;
&lt;li&gt;Figure out where the meaningful content ends and the padding begins&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's a relatively simple case. Now imagine the value is a packed struct: &lt;code&gt;05A528BCFA2189C8E2E7813775ED71B2C4BE349F&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Is that 20 bytes? Yes. So it could be a &lt;code&gt;Hash160&lt;/code&gt; or an &lt;code&gt;AccountID&lt;/code&gt;. Both are 20 bytes. How do you know which one? You go read the Hook source code. If you're lucky it's commented. Usually it isn't.&lt;/p&gt;

&lt;p&gt;Now multiply this across a Hook that stores 10 or 15 different state keys, each with a different encoding scheme, and you start to understand why debugging HookState is one of the more tedious parts of Xahau development.&lt;/p&gt;




&lt;h2&gt;
  
  
  What the Hook State Converter does
&lt;/h2&gt;

&lt;p&gt;The Hook ABI Conversion Helper is our answer to this problem. It gives you an interactive UI to paste hex, decode it visually, and export a reusable ABI schema — all without writing a single line of code.&lt;/p&gt;

&lt;p&gt;The tool accepts three inputs:&lt;br&gt;
HookState key + value pairs — the most common case HookParameter pairs — named parameters passed into Hook invocations Invoke blobs — raw binary payloads attached to Invoke transactions.&lt;/p&gt;
&lt;h2&gt;
  
  
  Paste hex. Get answers.
&lt;/h2&gt;

&lt;p&gt;Paste your hex into the input fields and the UI immediately does three things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Splits the hex into individual byte buttons&lt;/li&gt;
&lt;li&gt;Marks the key as Solved or Unsolved depending on whether it matches a known schema&lt;/li&gt;
&lt;li&gt;Runs an automatic scan and populates suggestions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each byte is a clickable button. You select bytes by clicking — selecting byte 5 means you've selected bytes 1 through 5 as a single segment. The UI updates in real time to show you every ABI type that fits that exact byte length.&lt;/p&gt;


&lt;h2&gt;
  
  
  Smart suggestions first
&lt;/h2&gt;

&lt;p&gt;You don't need to know the type upfront. The Suggest button scans your hex across all supported ABI types simultaneously and surfaces the most plausible matches as clickable buttons — each showing the type name and the decoded value inline.&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.amazonaws.com%2Fuploads%2Farticles%2Fprjpd7f6mn5iaxc3w6pi.webp" 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.amazonaws.com%2Fuploads%2Farticles%2Fprjpd7f6mn5iaxc3w6pi.webp" alt="ABI Conversion Helper Suggestions" width="700" height="139"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For example, paste &lt;code&gt;5852504C57696E&lt;/code&gt; and you'll instantly see:&lt;br&gt;
&lt;strong&gt;VarString&lt;/strong&gt; XRPLWin&lt;br&gt;
&lt;strong&gt;UInt64&lt;/strong&gt; 32075751449710680&lt;br&gt;
&lt;strong&gt;Blob&lt;/strong&gt; 5852504C57696E&lt;/p&gt;

&lt;p&gt;One click to confirm. The tool locks that interpretation and moves on to the remaining bytes. The scan is smart about filtering noise — it suppresses leading null bytes from Null suggestions since those are almost always padding, surfaces VarString matches only when the bytes decode to printable UTF-8, and collapses partial string matches so you see the longest valid string, not every sub-sequence.&lt;/p&gt;


&lt;h2&gt;
  
  
  Manual byte picking for complex states
&lt;/h2&gt;

&lt;p&gt;If autoscan doesn't nail it, or you're working with a tightly packed multi-field state, the byte picker gives you full control.&lt;/p&gt;

&lt;p&gt;Click any byte button to select from byte 1 up to that point. The result panel shows every ABI type that fits that exact byte length — &lt;code&gt;UInt16&lt;/code&gt;, &lt;code&gt;UInt16&lt;/code&gt; (BE),  &lt;code&gt;Int16&lt;/code&gt; , &lt;code&gt;Timestamp&lt;/code&gt;, &lt;code&gt;LedgerIndex&lt;/code&gt; — each with the decoded value shown.&lt;/p&gt;

&lt;p&gt;Select the type that matches your Hook's logic. The tool locks that segment, advances to the remaining bytes, and a new engine appears for the next segment. You repeat the process until every byte is accounted for.&lt;/p&gt;

&lt;p&gt;This chained engine approach means you can decode a 32-byte key that encodes, say, a 4-byte &lt;code&gt;UInt32&lt;/code&gt; flag, a 20-byte &lt;code&gt;AccountID&lt;/code&gt;, and 8 bytes of NULL padding — step by step, segment by segment, without losing track of where you are in the buffer.&lt;/p&gt;


&lt;h2&gt;
  
  
  20+ ABI types supported
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Types&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Integers&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;UInt8/16/32/64&lt;/code&gt;, &lt;code&gt;Int8/16/32/64&lt;/code&gt; (LE &amp;amp; BE)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Floats&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;XFL&lt;/code&gt; (LE &amp;amp; BE)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Amounts&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Amount&lt;/code&gt;, &lt;code&gt;NativeAmount&lt;/code&gt;, &lt;code&gt;IOUAmount&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Strings&lt;/td&gt;
&lt;td&gt;&lt;code&gt;VarString&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hashes&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Hash128/160/256/512&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Identity&lt;/td&gt;
&lt;td&gt;&lt;code&gt;AccountID&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ledger&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Timestamp&lt;/code&gt;, &lt;code&gt;LedgerIndex&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Raw&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Blob&lt;/code&gt;, &lt;code&gt;Null&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h2&gt;
  
  
  Both little-endian and big-endian variants are available for integer and float types, since Hooks developers sometimes store values in BE when interfacing with external systems.
&lt;/h2&gt;
&lt;h2&gt;
  
  
  Per-segment options
&lt;/h2&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.amazonaws.com%2Fuploads%2Farticles%2Frcgzxvju1f41zsnk3m99.webp" 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.amazonaws.com%2Fuploads%2Farticles%2Frcgzxvju1f41zsnk3m99.webp" alt="Segment options" width="700" height="365"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you select a type, a small options panel appears for that segment. You can:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rename the label&lt;/strong&gt; — give it a meaningful name like customer_account instead of VarString&lt;br&gt;
&lt;strong&gt;Add a description&lt;/strong&gt; — document what this field represents.&lt;br&gt;
&lt;strong&gt;Set a filtering rule&lt;/strong&gt; — define a literal pattern or regex that this segment must match for the decoding to be valid. Useful for sentinel bytes or magic values that identify the schema version.&lt;br&gt;
&lt;strong&gt;Exclude from view&lt;/strong&gt; — mark padding or fixed bytes as hidden so they don't clutter the final table.&lt;br&gt;
&lt;strong&gt;Set a renderer&lt;/strong&gt; — control how the decoded value is displayed, for example there are various Timestamp renderers.&lt;/p&gt;

&lt;p&gt;Hit &lt;strong&gt;Apply&lt;/strong&gt; and the finalized table updates immediately.&lt;/p&gt;


&lt;h2&gt;
  
  
  Export the ABI schema
&lt;/h2&gt;

&lt;p&gt;Once every byte is accounted for, the tool renders a full breakdown table with raw and rendered values side by side, and below it — the Segment ABI as JSON.&lt;/p&gt;

&lt;p&gt;A 32-byte key encoding the string customer_account produces:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
  {
    "type": "VarString",
    "byteLength": 32,
    "label": "Customer Account"
  }
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This JSON is the reusable schema and it's part of the Hook manifest format that XRPLWin uses internally. When a Hook manifest is registered with the explorer, it includes ABI definitions like this one — and XRPLWin uses them to automatically decode and display HookState entries in a human-readable way for anyone viewing that Hook on the explorer. You won't need to copy or paste anything manually — a dedicated projection builder UI is available that will use this conversion helper under the hood to generate manifest segments interactively.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;XRPLWin is a explorer for XRPL and Xahau. We build tools for the Xahau ecosystem at &lt;a href="https://xahau.xrplwin.com" rel="noopener noreferrer"&gt;xahau.xrplwin.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>xahau</category>
      <category>blockchain</category>
      <category>webdev</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
