Documentation
Spare crypto, explained end to end.
How Change reads what you spend, works out the leftover, and turns one signature a week into money headed for stocks. Everything below is what the product actually does today.
Quickstart
Sign in and sweep in four steps
Architecture
What runs where, and why
Weekly sweep
Signed by you, checked on-chain
API reference
Every route the app calls
Getting started
Overview
Change watches the crypto you already spend, rounds each payment up to the next dollar, and collects the difference once a week. The merchant is always paid the real price — the round-up comes from you, on purpose, when you approve it.
The product is built in public and not finished. Here is exactly where it stands.
| Capability | Status | Detail |
|---|---|---|
| Wallet sign-in | Live | Ethereum, Base and Solana wallets |
| Reading spending | Live | Outgoing USDC, ETH and SOL payments |
| Purchase tagging | Live | You choose what counts as a purchase |
| Weekly swap into SPYx | Live where offered | Signed by you on Solana, verified on-chain |
| Auto-swaps and card | Planned | See the roadmap |
Getting started
Quickstart
- 1Open your account and connect a wallet — Phantom, MetaMask, Coinbase Wallet or Solflare.
- 2Sign the message your wallet shows. It proves the wallet is yours. No gas, no password.
- 3Tick the recent payments that were purchases. Round-ups are read from the blockchain, not typed in.
- 4Approve one USDC transfer for the week's total. We verify it on-chain and record it.
Getting started
How round-ups work
An $18.42 payment becomes $19.00. The $0.58 is the product. You choose whether the target is the next $1, $5 or $10 — a bigger rule fills the jar faster.
Round-ups are collected weekly rather than per purchase, because one signature a week costs one set of network fees instead of fifty.
Under the hood
Architecture
The browser holds your wallet and nothing sensitive. Every read of the blockchain, every price lookup, and every sweep check happens on the server, so API keys and verification logic never ship to the page.
| Layer | What we use |
|---|---|
| Frontend | Next.js 16 (App Router, Turbopack), React 19, Tailwind 4 |
| Wallets | wagmi 3 + viem for Ethereum and Base; Solana wallet adapter for Phantom and Solflare |
| Sign-in | Sign-In with Ethereum (EIP-4361); Ed25519 message signing on Solana |
| Sessions | HMAC-signed, http-only cookie. No passwords, no email |
| Database | Netlify DB (Neon Postgres). Falls back to browser storage when absent |
| Chain reads | Blockscout REST for Ethereum and Base; Solana JSON-RPC with parsed transactions |
| Prices | CoinGecko for crypto, Yahoo Finance for equities |
| Hosting | Netlify serverless functions behind a CDN |
Under the hood
Reading your wallet
Connecting a wallet grants a read. Change pulls your recent outgoing payments — native ETH and USDC on Ethereum and Base, SOL and USDC on Solana — prices each one in dollars at the time of the scan, and works out the leftover.
Solana needs a different approach from Ethereum. Rather than guessing from instructions, we compare your token balance before and after each transaction, which catches payments made through any program, including swaps and payment apps.
GET /api/activity?evm=0xabc…&sol=7WU9…&rule=1
{
"spends": [
{
"chain": "solana",
"asset": "USDC",
"paidUsd": 214.58,
"roundUp": 0.42,
"counterparty": "HWznbZ…DYmk"
}
],
"pendingRoundUp": 1.96
}Results are cached for 30 seconds per wallet set. Public Solana endpoints are rate limited, so a dedicated RPC key makes scans more reliable.
Under the hood
Round-up math
The rule is deliberate about round numbers: a payment that lands exactly on the target still steps up a whole increment, so spare change is never zero.
export function roundUpAmount(paid: number, rule: 1 | 5 | 10) {
const cents = Math.round(Math.max(0, paid) * 100);
const step = rule * 100;
const rem = cents % step;
const extra = rem === 0 ? step : step - rem;
return extra / 100;
}| Payment | $1 rule | $5 rule | $10 rule |
|---|---|---|---|
| $18.42 | $0.58 | $1.58 | $1.58 |
| $4.00 | $1.00 | $1.00 | $6.00 |
| $132.10 | $0.90 | $2.90 | $7.90 |
Everything is held in whole cents. Money never touches floating-point maths on the way to a total.
Under the hood
The weekly swap
One swap a week turns your round-ups into SPYx. You sign it in your own wallet, and the token arrives in that same wallet. Change never takes custody, never holds a balance, and has no allowance over your funds.
Jupiter routes the trade across Solana liquidity. You see the expected amount, the price impact and the maximum slippage before you approve anything.
POST /api/swap/quote → what $5.00 buys right now POST /api/swap/build → an unsigned transaction for your wallet POST /api/swap/send → broadcast what you signed POST /api/swap/record → read the finished swap back off the chain
The recording step is the one that matters. The server re-reads the transaction and compares your token balances before and after, so the amounts written down are the amounts that actually moved. A client that invents a number gets rejected.
Numbers
Growth model
Round-ups are small by design, which is exactly why they need time rather than attention. Hover the chart to read any year.
The rule you pick decides how fast the jar fills. Same habit, three speeds.
These paths assume a steady 8% a year, which no real market delivers. Long-run US equity returns have historically landed in that neighbourhood with severe drawdowns along the way. Nothing here is a forecast or advice.
Numbers
What your round-ups buy
Every round-up buys SPYx, a tokenized product that tracks the S&P 500, issued by Backed. It is an SPL token on Solana, and it lands in your own wallet — Change never holds it.
| Detail | Value |
|---|---|
| Token | SPYx (SP500 xStock) |
| Network | Solana |
| Paid in | USDC |
| Routed by | Jupiter, across Solana liquidity |
| Held by | Your wallet, not Change |
Because it is a token rather than a share, what you hold is the issuer's instrument tracking the index, under their terms. Tokenized stocks are not offered in every country, and the app checks before quoting a swap.
Trust
Accounts and security
Signing in means signing a sentence. The server issues a one-time code, your wallet signs a message containing it, and the signature is verified against the address — Sign-In with Ethereum on EVM chains, Ed25519 on Solana. Smart-contract wallets are verified on-chain, so Coinbase Smart Wallet and similar work too.
- No seed phrase, private key or password is ever requested or stored.
- The session is a signed, http-only cookie. A stolen copy of the page cannot read it.
- Sign-in codes expire in ten minutes, and the message names the site to stop replays elsewhere.
- Round-up amounts always come from the chain, never from the browser.
- Change is not a broker-dealer and holds no shares. Booked sweeps wait for a partner.
Trust
What we store
| Table | Contents |
|---|---|
| users | Round-up rule, chosen basket and tickers |
| wallets | Wallet addresses linked to an account |
| purchases | Tagged payments: chain, asset, amount, leftover, timestamp |
| sweeps | Amount, network, transaction hash, sending wallet, status |
No names, emails or phone numbers are collected to use the product. If the site is running without a database, that same information stays in your browser instead and never reaches a server.
Reference
API reference
Every route is server-rendered and returns JSON. Routes that touch an account need the session cookie; the activity scan is public because it only reads public chain data.
| Method | Path | Purpose |
|---|---|---|
| GET | /api/account | Your account, settings, tagged purchases and sweeps |
| PATCH | /api/account | Save the round-up rule and stock picks |
| GET | /api/auth/nonce | One-time challenge for a sign-in signature |
| POST | /api/auth/verify | Verify the signature and start a session |
| POST | /api/auth/logout | End the session |
| GET | /api/activity | Scan wallet addresses for recent payments |
| GET | /api/account/activity | Scan every wallet linked to your account |
| POST | /api/purchases | Tag a payment as a purchase |
| DELETE | /api/purchases | Untag a purchase that hasn't been swept |
| POST | /api/swap/quote | Price a swap of your round-ups into SPYx |
| POST | /api/swap/build | Build the swap for your wallet to sign |
| POST | /api/swap/send | Broadcast the transaction you signed |
| POST | /api/swap/record | Read the finished swap on-chain and record it |
Reference
Roadmap
Next up, in order: automatic swaps with a weekly cap so nothing needs approving, more tokenized assets beyond the S&P 500, and a stablecoin card that rounds up at checkout.
Where machine learning fits — planned, not live today
Merchant recognition
Classify the addresses you pay so purchases tag themselves instead of you ticking boxes.
Spend or transfer
Tell a real purchase from an exchange top-up or a move between your own wallets.
Basket suggestions
Suggest allocations from your own round-up history — advice needs a licensed partner.
Tagging purchases by hand is the honest version of a hard problem: on-chain, paying a shop and topping up an exchange look identical. Each tag you make is a labelled example, which is what any future model would learn from.
Questions about brokerage settlement, RPC providers or anything above — @getchange.