The XRPH Wallet Hack: 4,011 Wallets Emptied in Three Hours
On the evening of 3 September 2026 an address that did not exist an hour earlier received the entire balance of 4,011 wallets. Three hours later the money was on a bridge to Ethereum. We read the whole thing off the ledger, then pulled the wallet app from Google Play and took it apart.
In one screen
- All 4,011 wallets belong to XRPH Wallet users. We checked every one on the ledger: 98.6% carry the app's own fingerprint, 95.5% were created in it, and none ever used other wallet software.
- The sweep started at 22:07 UTC and ran biggest wallet first. By 22:30 the collector held 242,536 XRP.
- 311,613 XRP went into NEAR Intents, came out on Ethereum as 178.46 ETH within a minute of each deposit, and became 445,198 DAI at one address that has not moved since.
- XRP Healthcare confirmed the count and the DAI figure. We followed every step to that address ourselves.
- We took the app apart. Payments are signed on the phone; the seed is stored unencrypted on the phone; and the staking feature sends the seed to XRP Healthcare's server. That code still ships.
- 1,225 wallets staked, nearly all between December 2023 and July 2024. 1,198 of them were drained, and so was the company's own staking wallet, whose key only the server holds. Yet seven in ten victims never staked: the exposure is the app's whole user base, not one feature.
- Asked on X, XRP Healthcare first said the wallet "is designed as a non-custodial wallet", then that it "was not aware that any part of the wallet's staking functionality was less than fully non-custodial" and is putting the question to the developers who wrote it.
- Our verdict: not until the cause is known and the seed never leaves the phone. What would change that is listed near the end.
Minute by minute
Nothing here required an exploit of the XRP Ledger. Each wallet signed an ordinary payment of its own balance. The ledger shows what the keys did, not how the attacker got them, and XRP Healthcare says that part is still under investigation. What the app itself does with those keys is further down.
Biggest wallets first
10,281 payments from 4,011 wallets: nearly all inside three hours, the last stragglers 27 hours later, 4,256 of them token transfers. Forty-five of the emptied accounts were then deleted, which sends the reserve to the collector as well.
Who was hit
The dump
The attacker did not wait to cash out. The first XRPH swap came 31 minutes after the first sweep, while wallets were still being emptied. XRPHAI went the same way: 2.43 million taken from 199 wallets and sold with five offers for 1,272 XRP in total. The market for it was that thin.
Where the money went
The collector kept 4.5 XRP. The wallet that created it, rhAtfg…VM4Y, dates from 2024, was funded by a withdrawal from the exchange VALR, and created nothing else. The two addresses the XRP passed through on its way out were not the attacker's: NEAR Intents issues a fresh XRPL address to each depositor, credits the deposit the moment it lands, and sweeps the address into its own wallet with a key of its own. That is why each was created by the attacker's payment and emptied nine seconds later.
Inside the app
The build in both stores on 3 September was 8.0.15: on Google Play since 28 July, on the App Store since 30 July, 50,000+ installs on Android, listed as a non-custodial wallet. We installed it from Google Play, decompiled its 1.3 million lines of JavaScript, and ran it on a rooted emulator with every encrypted connection opened, using a throwaway wallet funded with real XRP and XRPH.
{ amount, address, secret: seed, stakeType } to XRP Healthcare's server, and unstaking sends the seed again. 1,225 wallets used it, nearly all between December 2023 and July 2024. The screen now says: "Due to the scarcity of XRPH tokens, staking is no longer available. Existing stakers may continue until their current period ends." We had nothing staked, so this path never fired in our session. The code ships in the current build, and unstaking still uses it.The staking code, the clearest place a seed leaves the phone: two functions, each posting to one server address, with the seed in the request. It is not the only one; a second path is below.
// Staking screen (bundle_decompiled.js 836356-836377, then 836426)
r7['amount'] = r8;
r9 = r10.classicAddress; r7['address'] = r9;
r9 = r10.seed; r7['secret'] = r9; // the wallet seed
r9 = _closure2_slot3; r7['stakeType'] = r9;
r8 = r7.bind(r8)(r6); // useStake().mutateAsync(body)
// useStake (660203-660210)
r3 = r1.client;
r2['method'] = 'POST';
r2['data'] = a0; // the body above, seed included
r1 = 'wallet/stake';
r1 = r3.bind(r4)(r1, r2); // client('wallet/stake', ...)
// Unstake sheet (837292-837305) and useWithdrawStake (660304-660310)
r9 = r10.seed; r7['secret'] = r9; r4['secret'] = r7; r4['id'] = r8.unStakeId;
r1 = 'wallet/withdrawStake/' + id; r1['method'] = 'POST'; r1['data'] = r6.secret;
// API client base (472708)
r1 = 'https://xrphealthcare.sptdmw.workers.dev';// stake
const body = { amount, address: account.classicAddress, secret: account.seed, stakeType };
client('wallet/stake', { method: 'POST', data: body });
// unstake or claim
client('wallet/withdrawStake/' + unStakeId, { method: 'POST', data: { secret: account.seed } });secret. Compare the send path, where the same seed goes to a local signing routine and only the signed transaction leaves the phone. Line numbers refer to our decompiled bundle; the APK hash in the sources lets anyone reproduce them.Staking is not the only path. A second one, for approving a swap from a scanned code, builds a message with walletKeyset to the seed and sends it to the swap server over a live socket. We found it in the code, not on the wire: the in-app swap still reads "coming soon", so we cannot say it runs in normal use. What it shows is the same pattern as staking, the seed treated as something a server may receive, in a second place.
Staking was live for eight months
The "staking is no longer available" message is not a leftover. From December 2023 to July 2024 XRP Healthcare ran staking through the app, at 25% a year for a twelve-month lock and 20% for six, and because staking moves tokens, the ledger holds every stake. They all went to one wallet, r9ejnH…vK5b, created by the company's treasury the week before launch.
New stakes stopped in July 2024. The seed did not stop leaving: unstaking and rollovers kept posting it until at least 30 November 2025, and the code is in the build in the stores today. The stake request names no token, only an amount, an address, the seed and a lock type, so a new staking round, for XRPH or for XRPHAI, the second token the company launched in January 2025 and promotes inside the app for "reward boosts", would send every new staker's seed to the server again without a line changing.
Every hacked wallet, checked
Of the 4,011 payments into the collector, one was the attacker's own 15.4 XRP to fund it; the other 4,010 senders are the victims, and together they lost 267,664 XRP. We read the full history of each from a full-history node, accepted it only once its first transaction sat within a day of the day the wallet was created, and looked for the marks the XRPH Wallet leaves on the ledger.
1,199 wallets (29.9%) · 148,397 XRP (55.4%)
2,755 wallets (68.7%) · 119,256 XRP (44.6%)
56 wallets (1.4%) · 12 XRP (0.0%)
| wallet | created | the app's trustline | drained, 3 Sep 2026 |
|---|---|---|---|
| rehrNN…fyJL | 22 Apr 2025 | A11E26AE74… | 5,745.5 XRP |
| rNLyFo…3TXG | 13 Dec 2023 | 98E68C769D… | 5,070.1 XRP |
| rJRTkj…z4sq | 22 Mar 2026 | 80DE99CE20… | 3,371.2 XRP |
Download all 4,010 addresses (CSV)— each with the XRP swept from it, the number of token transfers, and whether it staked or was created in the app. Sorted by amount; the columns are the checks above.
- The staking wallet went the same way at 23:45 that night, by the same script: a check cancelled to free its reserve, then its 0.78 XRPH and 1.79 XRP into the collector. No phone ever held that key. The server that pays stakers does, and the attacker used it.
- Stakers are three in ten victims and held more than half the XRP. The other seven in ten are the same kind of wallet in every other respect: born in the app, used nowhere else, and 1,204 of them never sent a payment in their life. Nothing in build 8.0.15 sends their seed anywhere.
- "Used nowhere else" is partly the format. The app never shows a seed or a recovery phrase; its only backup is a "padlock combination", eight six-digit secret numbers, which Xaman can import but most people never carry across. Either way, every one of these wallets was signed for by the XRPH Wallet alone.
What the app explains, and what it does not
- Two paths in build 8.0.15 put a seed on the server: staking, which fired, and a swap-approval path we found only in the code. Nearly every wallet that staked was drained, and so was the server-held staking wallet. The attacker had what the server had.
- That is not the whole story. The hacked wallets are the app's user base, not its stakers: 98.6% carry the app's fingerprint, none ever used another wallet, and seven in ten never staked. The server must have held those seeds through a path this build no longer has, or the attacker reached them some other way we cannot see from here.
- The alternatives for that remainder are weak: theft from phones does not scale to 4,011 wallets in three hours, the app has no over-the-air update channel, and no new build reached either store between late July and the hack.
Asked on X on 5 September whether seed phrases are ever transmitted to or stored on its servers, XRP Healthcare answered: "XRPH is designed as a non-custodial wallet, with users retaining control of their wallet credentials and funds." The staking code sends the seed to their server. Asked a second time, more specifically, they replied later that day: "XRP Healthcare was not aware that any part of the wallet's staking functionality was less than fully non-custodial, and we would never knowingly market a product as non-custodial if that weren't the case. This is now being put directly to the developers responsible for the wallet's code." They add that they have filed a report with law enforcement and asked every exchange and swap service in the funds' path to flag and freeze. It is the first acknowledgement that the staking feature was not non-custodial.
Questions only XRP Healthcare can answer:
- Which earlier builds sent the seed to the server for sending, creating, importing or syncing a wallet, and until when?
- Where were the seeds received for staking kept, and was the staking wallet's own key kept with them?
- Was that store breached from outside, or used by someone who had access?
Do we recommend it?
- Signs payments on the phone, and we watched it do so.
- Generates keys from proper randomness; seeds are not guessable.
- Sends no wallet data to crash reporting or analytics.
- 4,010 of its users were emptied in one night, and no cause has been published.
- Its staking feature posted the seed to the company’s server, and the key that server holds was used by the attacker.
- The seed sits unencrypted on the phone.
- An account system with a shared API key and a session token that never expires, behind a wallet sold as non-custodial.
- No certificate pinning.
- The staking code still ships and unstaking still uses it; a new staking round, for XRPH or XRPHAI, would send every staker’s seed to the server again unless the code changes.
- A public post-mortem that names the cause and what was taken.
- No feature, in any build, that sends the seed off the phone.
- The seed in the phone’s secure key store, and sessions that expire.
- An independent audit of the rebuilt app, published.
Until then, anyone holding XRP or XRPH should use a wallet whose keys never leave the device, created with a new seed. That is the same advice for everyone, not only for people who were hit.
Why no alarm went off
A wallet emptying itself into a brand-new address is the most common thing on the ledger: it is what a user moving to a new wallet does. Every drain detector, ours included, therefore ignores a single sweep unless the destination is already known to be a drainer.
What the ledger showed on 3 September was different in one respect only: hundreds of unrelated wallets did it to the same address inside minutes. That shape has no innocent explanation.
The rule now runs live in our ledger feed. It needs 25 distinct wallets, funded from at least five different sources and created over a span of at least 90 days, emptying into one address under a week old within six hours. Exchanges consolidate into old, named wallets; a person moves one balance; a deposit address carries a tag. None of them trip it.
If you used XRPH Wallet
- Treat every key that was ever in the app as compromised. Move anything left to a wallet created with a new seed in different software.
- Do not import the old seed into a new app. The seed is the problem, not the app it lives in.
- If you ever staked in the app, your seed was posted to XRP Healthcare's server as part of that feature. One more reason the old seed cannot be kept.
- Ignore anyone offering recovery for a fee or a signature. The funds are on Ethereum; nobody can pull them back by having you sign something.
- Check any address before you pay it: our drain tracker and the scam list behind it are updated live.
Sources
- Collector rGGXaBdSRUfdarKDkt2csxL67F8MEGxHVB, hops raDNxjwbjGCUAix8rKCzrHYY2r9AsCjs1P and rEwVZRuLvAAo5PkkU7ZTRPJ7km4hX7o6J7, and every transaction linked above, read from a full-history XRPL node on 5 September 2026.
- Victim profile from our ledger index: the wallet that funded each of the 4,011 senders, its creation date and its trustlines. The downloadable list of all 4,010 victims carries the XRP swept from each, from the on-chain drain records.
- XRPH price from our 5-minute candles of the XRPH/XRP market.
- Wallet count and dollar figure: XRP Healthcare's statements on X, 4 September 2026. The Ethereum side we read ourselves, below; their DAI figure matches it.
- The app:
com.xrphwallet8.0.15 (build 815) installed from Google Play on 5 September 2026, base APK SHA-256 98ef9778d75a5a630816798c1458f25cb3715e266d5e91ef8c7fe5d6925e07ce, Hermes bytecode decompiled with hermes-dec. Run on a rooted Android 13 emulator with a mitmproxy certificate installed system-wide; every HTTP request and WebSocket frame logged in full and searched for the test wallet's seed, private key, entropy in hex and base64, secret-number groups and public key. - Test wallet rEtETFXqPDKzgkF7pVrbBN2vnM4fRw8JkS, funded from our own wallet and emptied by us afterwards: DEX buy AC28524C93…, payments 03F8C1E70B… (0.3 XRP) and 50B4D9EB8C… (100 XRPH), both captured leaving the phone already signed.
- Store listings read on 5 September 2026: Google Play (updated 28 July 2026, 50K+ downloads) and the App Store lookup service (8.0.15, released 30 July 2026, seller XRP Healthcare Limited).
- Staking: the full history of r9ejnHYRqpUcdcVpP9jrubpgMGBvV2vK5b (7,574 transactions) and of its treasury rQD582WZt9xx4SVKfBcpwRBYJhSpretDo7, read from a full-history node on 5 September 2026. A stake is an XRPH payment into that wallet; the treasury's own top-ups and two exchange wallets are excluded from the user counts.
- The wallet check: the full history of each of the 4,010 victims (the 4,011th payment into the collector is the attacker's own funding), read from a full-history node on 5 September 2026 and accepted only when its first transaction falls within a day of the creation date in our index, which 3,962 did at once; the rest were re-read until they did, and the 48 with no recorded creation date were read from two nodes with the longer answer kept. A partial answer from a load-balanced node looks complete and carries no error, which is why the check exists. Marks as defined in the anatomy figure.
- XRP Healthcare's posts on X, dated from their status ids: 13 Nov 2023, 22 Nov 2023, 30 Nov 2023 (with the APR replies), 3 Mar 2024, 2 Apr 2024, 13 Apr 2024 and 23 Jul 2024, which links the press release "XRP Healthcare Halts New Staking of XRPH Token to Preserve Finite Supply".
- Past the bridge: NEAR Intents' own transactions, read from an archival NEAR node and NearBlocks (the credits F4HeE2d6qt… and H1fcCZoizC…, each naming the XRPL payment it came from; the swaps and withdrawals An8z3wD7eb… and 5nBcH9S8Ri…, each naming the Ethereum address); Ethereum from Blockscout and a public node, balances read 5 September 2026 at 15:00 UTC: 0x3DC7BFf29Fc5a051aAB250516BaBD74ae7068930 holds 445,197.999216 DAI and 0.4527 ETH.
- Promotion by other accounts, for the record: 21 Dec 2022, 18 Jan 2023, 24 Jan 2024, 14 Apr 2024, 14 Jan 2025 and 30 Aug 2026.