Home / Blog / Wallet Resolution

Wallet Resolution

The Real On-Chain Wallet Is the Fastest Copy-Trading Data Source

A social-trading app feed is a copy of events that already settled on-chain. We resolve each trader's real, verified Solana and EVM wallet so you can read their swaps straight from the chain, faster than any feed and impossible to fake.

Every social-trading app shows you a feed of what its top traders just did. That feed is useful, but it is not the source. It is a copy of something that already happened somewhere else: on-chain. A swap exists on the blockchain the moment it confirms. An app's feed is a downstream reflection of that event, reconstructed and displayed after the fact. If you are building a copy-trading system, the practical consequence is simple. Reading a trader's activity from their own on-chain wallet is faster than waiting for any app to surface it, and it cannot be faked.

This post explains why the chain is the right place to read from, why you cannot just point a listener at the wallet the app shows you, and how our wallet resolution closes that gap so you can stream trades straight from the source.

The chain is the source of truth, the feed is a copy

When a trader buys a token, the transaction is broadcast, included in a block, and confirmed. At that instant the trade is a public fact. Anyone watching that wallet's address on a Solana or EVM node can see it. An app that features the trader has to observe the same event, attribute it, enrich it, and push it into a feed. That pipeline adds latency, and it adds a layer of trust: you are now trusting the app's rendering of the event instead of the event itself.

For a copy-trading system, both of those matter. The latency is the difference between reacting to a fill and reacting to a summary of a fill. The trust question is worse. A feed can be filtered, delayed, reordered, or presented with numbers that were never checked against the chain. The transaction on-chain has none of those problems. It is signed by the trader's key, it settled, and it is immutable.

So the goal is clear: read the trader's swaps from their wallet, on the chain, as blocks confirm. The only hard part is knowing which wallet is actually theirs.

The catch: the wallet the app shows you is dead

Here is the trap. FOMO's own data exposes a custodial embedded wallet for each user, created through Privy. That address is what the app uses internally for its own account plumbing. It is not where the trader's real trading happens. In practice that custodial address shows zero on-chain transactions. If you take the address the app hands you and point a listener at it, you will watch an empty wallet forever and conclude, wrongly, that the trader is inactive.

This is the single biggest reason people give up on the on-chain approach. They try it, they subscribe to the obvious address, nothing ever fires, and they fall back to scraping a feed. The problem was never the approach. It was that they were watching the wrong wallet.

What we resolve, and how it is verified

Our core job is to resolve each trader's real on-chain wallet. Not the custodial placeholder, the actual address where their swaps land, on Solana and on EVM chains. We verify a candidate wallet against on-chain activity before we return it, so the address you get back is one that actually transacts, not one that merely exists in a user record.

You request it by handle:

GET /v2/users/{handle}

The response includes the resolved wallet address (or addresses, since a trader can be active on more than one chain). That address is the thing that makes on-chain copy trading possible. Everything downstream depends on having the correct one.

To be clear about what we do and do not do: we resolve and verify the wallet. We do not run the on-chain listener for you. The streaming described below is what you build once you have the real address. We hand you the verified wallet; you stream the chain.

Streaming trades straight from the wallet

Once you hold the real address, you subscribe to it directly on a node. On Solana, an RPC logsSubscribe on the wallet gives you a push notification the moment a transaction that touches that account confirms. You then fetch the transaction and parse the swap out of it. A minimal sketch:

import { Connection, PublicKey } from '@solana/web3.js';

// wallet resolved from GET /v2/users/{handle}
const wallet = new PublicKey(resolvedAddress);
const conn = new Connection('https://your-rpc', 'confirmed');

conn.onLogs(wallet, async (logs) => {
  if (logs.err) return;
  const tx = await conn.getParsedTransaction(logs.signature, {
    maxSupportedTransactionVersion: 0,
  });
  const swap = parseSwap(tx); // read token in/out from the instructions
  if (swap) onTraderSwap(resolvedHandle, swap);
}, 'confirmed');

If push is not available, you poll getSignaturesForAddress for the wallet and diff against the last signature you saw. On an EVM chain the shape is the same idea: subscribe to logs filtered by the trader's address, or poll recent transactions, and decode the swap from the router event. Either way you are reading the settled trade as the chain confirms it, ahead of any app that has to rebuild the same event for its feed.

The point worth repeating: none of this works without the correct wallet. The RPC subscription is standard infrastructure. The verified address is the hard part, and that is what our resolution provides.

PnL that cannot be self-reported

The same fact that makes the chain fast makes it honest. Because the trades are real on-chain events, profit and loss is computed from those events, not from anything a trader typed into a profile. There is no field to inflate. A wallet's realized and unrealized PnL is a function of the tokens it actually bought and sold and the prices it paid, all of which are on the chain. When you rank or filter traders on PnL derived this way, you are ranking them on settled history, not on a claim. That is a different quality of signal than a self-reported track record, and it is only possible because the underlying trades are read from the source.

Putting the pipeline together

Streaming a wallet's swaps tells you what a trader did. For copy trading you usually want two more things: why they did it, and a way to be told the instant it happens.

  • Pair the on-chain trade stream with /v2/thesis, which gives you the reasoning a trader has attached to their positions. A raw swap is an instruction; the thesis is the context that lets you decide whether to follow it.
  • Use /ws/alerts as the push layer for events you care about, so your system is notified rather than polling for everything.

Together that is a full copy-trading pipeline: the verified wallet to read from, the chain as the fast and unfakeable source of the trades, the thesis for the reasoning, and the alert stream for delivery. The wallet resolution is the piece that unlocks the rest, because without the real address the fastest and most trustworthy data source on the trader is invisible to you.

Where to start

If you have been reading trades out of an app feed, the change is smaller than it looks. Resolve the trader's real wallet with /v2/users/{handle}, stand up an RPC subscription to that address, and parse swaps as they confirm. Keep the feed if you like it as a cross-check, but let the chain be your primary. You will be reacting to the trade itself instead of a copy of it, and the numbers you build on top will be ones nobody had the chance to edit.

The product is free and the endpoints are documented. Start by resolving one trader you already follow, watch their real wallet fire on the next swap, and compare the timing against whatever feed you were using before.

Ship on verified trader data

Both-chain wallets, real PnL, and a realtime feed. One API.

Get an API key

FAQ

Why not just watch the wallet address the app gives me?
FOMO exposes a custodial embedded wallet created through Privy, and that address typically shows zero on-chain transactions. It is account plumbing, not where the trader actually swaps. If you subscribe to it you watch an empty wallet forever. Our /v2/users/{handle} endpoint returns the trader's real wallet, verified against on-chain activity, which is the address you actually stream.
How is reading on-chain faster than an app feed?
A swap exists on the chain the moment it confirms. An app has to observe that same event, attribute it, enrich it, and push it into a feed, which adds latency and a layer of trust. Subscribing to the trader's real wallet on a Solana or EVM node lets you react to the settled trade as the block confirms, ahead of the feed that has to rebuild it.
Do you stream the on-chain trades for me?
No. We resolve and verify the real wallet address. The on-chain streaming, for example a Solana logsSubscribe or getSignaturesForAddress poll, is what you build using that address. We provide the verified wallet, you stream the chain, and you can pair it with /v2/thesis for reasoning and /ws/alerts for delivery.