Alex Dent

Collected Works

Wake Wallet

An SDK that paid users a cut of ad revenue for opting into tracking. Built the Unity client and designed the attribution layer.

Year
2024
Role
Prototyped it

Apple’s App Tracking Transparency prompt asks users whether an app can track them, and something like 80% of the time the answer is no. Most of the industry responded to that by rewriting the prompt, testing different wording and different moments to show it, which helps at the margins without changing much underneath. The premise behind Wake Wallet was that people weren’t declining because the sentence was badly phrased. They were declining because nothing was being offered in return.

So the product put an offer in front of Apple’s dialog: opt in, and you get a share of the ad revenue your attention generates. For the app that meant recovering targeted inventory it would otherwise have lost, and for the user it meant being paid for something that had been happening without them either way. The split was 40% to the app, 40% to users and 20% to the platform, calculated only on incremental revenue, so the company earned nothing unless opt-in rates actually moved.

I was the primary engineer, working on the client SDK and the data layer behind it.

Unity first, not Swift first

The plan on paper was a native Swift SDK first, with a Unity plugin following a few months later, which is the conventional order and probably the one I’d have argued for in the abstract. We went the other way. The apps that depend most heavily on ad revenue, particularly casual games and the mid-sized publishers we were most likely to sign, are overwhelmingly built in Unity, so starting there meant one integration path covered most of the market we were actually talking to. A native SDK would have been cleaner, but cleaner for the apps least likely to say yes.

The work itself was the prompt surfaces. A pre-ATT screen that makes the offer just before Apple’s dialog appears, a re-prompt flow for people who decline the first time and might reconsider once they’ve used the app a while, and an in-app banner that tells users what they’ve accumulated once the balance is worth mentioning. I bundled all of it into a reference test app, which served both as the example integration we handed to partner developers and as the build we put through App Store review.

Signal from Google Analytics, which wasn’t the same as ownership

For the first round of instrumentation I used Google Analytics, mostly because it was the quickest way to get numbers out of a live app, and the question at that stage was narrow enough to suit it: does paying people actually change whether they opt in? It did, or at least it did in the one app we had running. Acceptance came in at roughly double the baseline and eCPMs on the opted-in cohort were up somewhere around 70%, though with a single integration and a short window I’d treat both of those as directional rather than settled.

The harder problem was that we were calculating payments from those same events. Google Analytics samples and models and aggregates, which is fine when you’re trying to understand a funnel, but it isn’t built to be the ledger you invoice a partner from. Once attribution becomes a payment you need event-level data you own, with schemas you control and a record you can walk through if a publisher asks how their number was arrived at. GA was enough to see the shape of things, and I don’t think it would have held up under that kind of question.

The attribution engine that didn’t get built

What I designed to replace it was a self-hosted Snowplow pipeline acting as the system of record, with first-party collection, schema-enforced events, enrichment, and a warehouse that both the attribution engine and the audience management side would read from.

Attribution was cohort-based, comparing ARPU for users who arrived before the SDK went in against those who arrived after, treating the difference as the lift we were responsible for and paying out against that. An approach like that is only as good as the event stream underneath it, since every payout is really a claim about what would have happened otherwise, and a partner has a reasonable right to audit that claim. Owning the pipeline end to end was how we planned to be able to answer.

It didn’t get built. We had one app live and were working through the integration pipeline for the next few when the project came apart.

What I took from it

I still think the Unity call was right. It traded some engineering elegance for reach, and it’s the reason there was a live integration and a real opt-in number instead of a well-structured SDK sitting in nobody’s app. Shipping on Google Analytics was probably right for that stage too, in that it got us an answer months earlier than building the pipeline properly would have.

The part I’d handle differently sits in the gap between those two decisions. Expedient instrumentation has a shelf life, and on a product where the events are the basis for paying people, that shelf life is shorter than it feels while you’re still proving the thing works at all. We knew the replacement was needed and I had it designed, but it stayed a design while the more urgent work of finding the next integration took the time, which is an easy way for a company to end up with numbers it can’t fully stand behind.

My Work.