<?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: U Ledger</title>
    <description>The latest articles on DEV Community by U Ledger (@zcld500).</description>
    <link>https://dev.to/zcld500</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%2F4029722%2Ffb5a6dac-250d-4fe7-aac5-3f492dadd504.png</url>
      <title>DEV Community: U Ledger</title>
      <link>https://dev.to/zcld500</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/zcld500"/>
    <language>en</language>
    <item>
      <title>Preventing Double-Counted USDT Transfers in a Multi-Wallet Ledger</title>
      <dc:creator>U Ledger</dc:creator>
      <pubDate>Mon, 20 Jul 2026 07:07:20 +0000</pubDate>
      <link>https://dev.to/zcld500/preventing-double-counted-usdt-transfers-in-a-multi-wallet-ledger-m22</link>
      <guid>https://dev.to/zcld500/preventing-double-counted-usdt-transfers-in-a-multi-wallet-ledger-m22</guid>
      <description>&lt;p&gt;A multi-wallet USDT ledger has a classification problem that is easy to miss: the same internal movement appears as an outgoing transfer in one owned wallet and an incoming transfer in another.&lt;/p&gt;

&lt;p&gt;If those wallet histories are aggregated without an ownership model, the principal may be counted as both an expense and income.&lt;/p&gt;

&lt;p&gt;This post describes a small, deterministic data model for handling that case across TRON and BSC.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Keep network identity in every key
&lt;/h2&gt;

&lt;p&gt;An address string is not a complete identity.&lt;/p&gt;

&lt;p&gt;TRON addresses and EVM addresses use different formats, while the same &lt;code&gt;0x...&lt;/code&gt; address can exist on BSC, Ethereum, Polygon, Base, or another EVM network.&lt;/p&gt;

&lt;p&gt;Use a network-qualified key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;addressKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;network&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;network&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt;`&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;The same rule should apply to transaction identifiers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;transferKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;network&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;txHash&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;logIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;network&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;txHash&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;logIndex&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&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;Including a log index is useful on EVM networks when one transaction emits multiple token-transfer events.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Maintain an explicit ownership registry
&lt;/h2&gt;

&lt;p&gt;Do not infer ownership from recent activity or transfer direction.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;owned&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;Map&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tron:T_SAMPLE_OPERATIONS&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&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="s2"&gt;TRON operations&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tron:T_SAMPLE_PAYMENTS&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&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="s2"&gt;TRON payments&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bsc:0xsampleoperations&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&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="s2"&gt;BSC operations&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bsc:0xsampletreasury&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&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="s2"&gt;BSC treasury&lt;/span&gt;&lt;span class="dl"&gt;"&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;In production, normalize addresses according to the network before adding them to the registry.&lt;/p&gt;

&lt;p&gt;The ownership list should be user-controlled because public blockchain data cannot reliably explain the business relationship behind an address.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Classify principal movement before calculating totals
&lt;/h2&gt;

&lt;p&gt;A minimal transfer record might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;network&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;txHash&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;logIndex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;tokenContract&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;fee&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;confirmations&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then classification becomes deterministic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;classifyTransfer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;owned&lt;/span&gt;&lt;span class="p"&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;fromOwned&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;owned&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;addressKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;network&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&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;toOwned&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;owned&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;addressKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;network&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fromOwned&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;toOwned&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;internal&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fromOwned&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;outgoing&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;toOwned&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;incoming&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;external&lt;/span&gt;&lt;span class="dl"&gt;"&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;Only &lt;code&gt;incoming&lt;/code&gt; and &lt;code&gt;outgoing&lt;/code&gt; principal movements should contribute to ordinary receipt and payment totals.&lt;/p&gt;

&lt;p&gt;An &lt;code&gt;internal&lt;/code&gt; movement should remain visible in the ledger for traceability, but its principal should not be added to revenue or expense.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Treat network fees separately
&lt;/h2&gt;

&lt;p&gt;The principal transfer and the network fee are different accounting events.&lt;/p&gt;

&lt;p&gt;For an internal transfer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;principal movement: internal, excluded from ordinary income/expense&lt;/li&gt;
&lt;li&gt;network fee: possible operating cost, retained separately&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Combining both into one signed amount makes later reconciliation harder.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Separate blockchain facts from business meaning
&lt;/h2&gt;

&lt;p&gt;The blockchain can confirm:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;timestamp&lt;/li&gt;
&lt;li&gt;network&lt;/li&gt;
&lt;li&gt;token contract&lt;/li&gt;
&lt;li&gt;sender and recipient&lt;/li&gt;
&lt;li&gt;amount&lt;/li&gt;
&lt;li&gt;transaction hash&lt;/li&gt;
&lt;li&gt;confirmation state&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It cannot confirm whether the transfer represents a customer payment, supplier payment, refund, treasury movement, or test.&lt;/p&gt;

&lt;p&gt;Keep business metadata in a separate layer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;expectedAmount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;counterpartyId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;invoiceId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;note&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;reconciled&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;still_due&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;overpaid&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;review&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This prevents a label correction from rewriting the underlying public transaction record.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Start with a bounded range
&lt;/h2&gt;

&lt;p&gt;A safer onboarding sequence is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;add one owned public address&lt;/li&gt;
&lt;li&gt;read a recent bounded period&lt;/li&gt;
&lt;li&gt;validate the network and token contract&lt;/li&gt;
&lt;li&gt;label known counterparties&lt;/li&gt;
&lt;li&gt;add the remaining owned wallets&lt;/li&gt;
&lt;li&gt;reclassify owned-to-owned transfers&lt;/li&gt;
&lt;li&gt;compare expected and actual payments&lt;/li&gt;
&lt;li&gt;import older history only when needed&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This makes failures easier to isolate. A zero result might otherwise mean the wrong network, the wrong token contract, an incomplete provider response, or simply no activity.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Do not request wallet authority for reconciliation
&lt;/h2&gt;

&lt;p&gt;This workflow uses public transaction data. It does not require a wallet connection, seed phrase, private key, or signing permission.&lt;/p&gt;

&lt;p&gt;I built an interactive sample of the multi-wallet deduplication flow using example wallets and transfers. It can be reviewed without registration or a real address:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://u.geeklabx.com/en/guides/multi-wallet/?utm_source=devto&amp;amp;utm_medium=organic_content&amp;amp;utm_campaign=intent_outreach_202607&amp;amp;utm_content=multi_wallet_data_model" rel="noopener noreferrer"&gt;Open the no-sign-up multi-wallet example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Disclosure: I built U Ledger. The link is a product guide and sample workflow, not a trading, custody, exchange, or investment service.&lt;/p&gt;

</description>
      <category>web3</category>
      <category>blockchain</category>
      <category>javascript</category>
      <category>fintech</category>
    </item>
    <item>
      <title>How to Reconcile USDT Across Multiple Wallets Without Double-Counting Internal Transfers</title>
      <dc:creator>U Ledger</dc:creator>
      <pubDate>Wed, 15 Jul 2026 06:32:09 +0000</pubDate>
      <link>https://dev.to/zcld500/how-to-reconcile-usdt-across-multiple-wallets-without-double-counting-internal-transfers-2oge</link>
      <guid>https://dev.to/zcld500/how-to-reconcile-usdt-across-multiple-wallets-without-double-counting-internal-transfers-2oge</guid>
      <description>&lt;p&gt;Managing USDT across several wallets looks simple until the first internal transfer appears.&lt;/p&gt;

&lt;p&gt;If one business controls wallet A and wallet B, moving 5,000 USDT from A to B is not revenue and it is not an expense. It is a change in custody. Yet a basic transaction export often shows one outgoing movement and one incoming movement, which can inflate both sides of an operating report.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why summing wallet activity fails
&lt;/h2&gt;

&lt;p&gt;A reliable multi-wallet ledger needs more context than amount and timestamp. For every transaction, preserve at least:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;network and transaction hash;&lt;/li&gt;
&lt;li&gt;sending and receiving addresses;&lt;/li&gt;
&lt;li&gt;which addresses belong to the same business;&lt;/li&gt;
&lt;li&gt;token amount and network fee;&lt;/li&gt;
&lt;li&gt;transaction direction from the business perspective;&lt;/li&gt;
&lt;li&gt;a link between both sides of an internal transfer.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;TRON and BNB Smart Chain should also remain separate. They have different fee mechanics and transaction identifiers, even when the transferred asset is USDT.&lt;/p&gt;

&lt;h2&gt;
  
  
  A practical reconciliation workflow
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Build an ownership map
&lt;/h3&gt;

&lt;p&gt;Give every controlled address an operational name such as &lt;code&gt;Treasury TRON&lt;/code&gt;, &lt;code&gt;Sales BSC&lt;/code&gt;, or &lt;code&gt;Vendor Wallet&lt;/code&gt;. Do not rely on shortened address fragments during review.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Import public transaction histories
&lt;/h3&gt;

&lt;p&gt;Import each wallet separately and retain its source network. Normalize timestamps and token units, but keep the original transaction hash so every record can be traced back to the chain.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Classify by ownership
&lt;/h3&gt;

&lt;p&gt;For each transfer, ask whether the sender and receiver are controlled by the same business.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;External sender to controlled receiver:&lt;/strong&gt; candidate inflow.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Controlled sender to external receiver:&lt;/strong&gt; candidate outflow.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Controlled sender to controlled receiver:&lt;/strong&gt; internal transfer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Neither side controlled:&lt;/strong&gt; outside the ledger scope.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This classification is more reliable than rules based only on direction or amount.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Separate fees from principal
&lt;/h3&gt;

&lt;p&gt;An internal transfer may still create a real cost. The USDT principal remains internal, while TRX or BNB paid as network fees is an expense. Combining them into one number hides useful accounting detail.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Match both sides
&lt;/h3&gt;

&lt;p&gt;Use the transaction hash when possible. If data came from sources that represent the two sides differently, match on network, token, amount, addresses, and a narrow time window. Store an explicit relationship between the paired records instead of deleting one side.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Review exceptions
&lt;/h3&gt;

&lt;p&gt;Flag unmatched internal-looking transfers, duplicate imports, unsupported tokens, missing fees, and sudden balance differences. Exceptions deserve human review; normal transfers should not require repeated manual work.&lt;/p&gt;

&lt;h2&gt;
  
  
  A privacy boundary that is easy to explain
&lt;/h2&gt;

&lt;p&gt;Reconciliation only needs public blockchain data. A bookkeeping tool should not require a wallet connection, seed phrase, private key, or signing permission.&lt;/p&gt;

&lt;p&gt;That boundary reduces risk and makes the workflow easier to audit: the tool reads public history and organizes it, but it cannot move funds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Explore a sample workflow
&lt;/h2&gt;

&lt;p&gt;I built U Ledger to demonstrate this approach for operational USDT records across TRON and BSC. The English demo uses sample data, so you can explore the workflow without creating an account or entering a real wallet address.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://u.geeklabx.com/en/guides/multi-wallet/?utm_source=devto&amp;amp;utm_medium=organic_content&amp;amp;utm_campaign=overseas_launch_202607&amp;amp;utm_content=multi_wallet_article" rel="noopener noreferrer"&gt;Explore the multi-wallet reconciliation guide&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The most important principle is simple: ownership relationships determine whether a transfer changes the business's economic position. Once that rule is explicit, multi-wallet reporting becomes much easier to trust.&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>cryptocurrency</category>
      <category>web3</category>
      <category>privacy</category>
    </item>
  </channel>
</rss>
