On this page
- Solana's docs: every account address is a 32-byte value shown as a base58 string, either an Ed25519 public key or a program derived address with no private key.
- A wallet address is a public key. A USDC token account, a subscription account and a plan account are program derived addresses: no private key exists for any of them.
- On a Fianto checkout the payer sees only their own wallet, shortened to its first and last four characters; the merchant's wallet is proven by a signed message, which a token account could never produce.
What is a Solana address made of?
A Solana address is 32 bytes of data that names one account, written out as text in base58, an encoding that turns bytes into letters and digits. Solana's account structure documentation puts it this way: "Every account address is a 32-byte value, displayed as a base58-encoded string."
The same page names the two kinds an address can be. A public key "corresponds to an Ed25519 keypair (has a private key)". A program derived address, or PDA, is "deterministically derived from a program ID and seeds (no private key)". A keypair is the pair of a public key, which is the address everyone sees, and a private key, which signs; your wallet app keeps the private key. Nothing in the text of an address tells you which kind it is, and that is where most confusion about Solana addresses starts.
Tokens add a third word people mix up. Solana's terminology page defines an associated token account, or ATA, as "A token account whose address is deterministically derived from a wallet address and a token mint." A mint is the account that defines a token; USDC on Solana has one mint, EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v, per Circle's list of USDC addresses. So holding USDC means three addresses at once: your wallet, the USDC mint, and the token account derived from the two.
Which addresses take part in a USDC payment?
A USDC payment on Solana touches several addresses of both kinds, and only the wallets among them have a private key. These are the ones in a Fianto subscription, the fullest case:
| Address | Kind | Who can sign for it | Where you meet it |
|---|---|---|---|
| Customer's wallet | Public key | The customer, in their wallet app | On the checkout, shortened, after "Paying from" |
| Customer's USDC token account | PDA of the Associated Token Account program | Nobody; the Token Program moves its USDC when the owner or a delegate authorises it | In the wallet's transaction details or on an explorer |
| Merchant's receiving wallet | Public key | The merchant | In the merchant dashboard, proven by signature |
| Merchant's USDC token account | PDA | Nobody | On an explorer, as the receiving account of each payment |
| USDC mint | The token's mint account | Nobody signs for it in a payment | In the transaction, as the token being moved |
| Subscriptions program | Program account, De1egAFMkMWZSN5rYXRj9CAdheBamobVNubTsi9avR44 | Not applicable: it is code | In the transaction the customer signs |
| Plan, subscription and Subscription Authority accounts | PDAs of the Subscriptions program | Only that program | In the transaction the customer signs |
A one-off payment needs fewer: the two wallets, their two USDC token accounts, the mint and the Token Program, plus Fianto's treasury token account when a fee is charged. What each part of that one-off transaction does is in what a blockchain transaction is. How the program accounts fit together is in programs, not smart contracts.
Why does nobody have a private key for a program derived address?
Nobody has a private key for a program derived address because it is chosen to fall off the Ed25519 curve, where no key pair can exist. Solana's PDA documentation says PDAs "are guaranteed to not lie on the Ed25519 curve, which means no private key exists for them." The derivation hashes the seeds with the program ID; if the result lands on the curve, it tries again with a different bump, one extra byte counted down from 255.
That retry is visible in what a payment costs to run. Solana's page prices the search at 1,500 compute units on entry plus 1,500 for each failed bump. Fianto found that the Subscriptions program re-derives the customer's USDC token account in every collection, and that a wallet needs k extra tries with a probability of one in 2 to the power k. So Fianto sizes each renewal's compute budget per customer: 40,000 units for a typical wallet, plus 2,000 per extra try per collection, instead of one flat figure that would fail about one wallet in a thousand on every renewal.
What address does a payer see at checkout?
On a Fianto checkout a payer sees one address: their own wallet's, once it is connected, shortened to its first and last four characters after "Paying from" and the wallet's name, with a Change button. The merchant's address is not shown as text. The page names the merchant instead: "Paid straight to [merchant name]. Nobody holds it in between."
That is deliberate. The payer never types or pastes an address on a Fianto checkout; the transaction is built with the merchant's token account already in it, and the wallet only signs. A payment page that asks the customer to copy a wallet address works differently, and the trade-offs are in hosted checkout vs a wallet address.
For one-off payments, under the fixed Token: USDC and Network: Solana rows, the page adds: "Send only USDC on Solana. Anything else is lost." Fianto accepts USDC on Solana and no other token or network, and an address is only meaningful on the network it belongs to. Above the button the page also says: "Your wallet address and payment are public on Solana." Every address in the table above can be looked up by anyone.
A checkout where nobody copies an address: the transaction already names the right accounts.
See the hosted checkoutWhy does a merchant give a wallet address and not a token account?
A merchant gives a wallet address because a wallet is the only kind of address that can prove who controls it, and because everything downstream is derived from it. During setup the merchant does not paste an address at all: under "The wallet you get paid to" they pick their wallet and sign a message that starts "fianto wants you to confirm this wallet receives payments for your account." A token account is a PDA with no private key, so it could never produce that signature.
From the proven wallet, Fianto works out the rest:
- The USDC token account each payment goes to, derived from the wallet and the USDC mint.
- Each subscription plan's destinations. Fianto's code writes wallets there, not token accounts, because the program checks who owns the receiving token account.
- One merchant per wallet: a wallet can be the receiving wallet of only one Fianto merchant.
The wallet must already have a USDC token account. If it does not, creating a checkout fails with merchant_, and a payer is told: "This shop cannot receive USDC yet, so the payment cannot go through. Nothing has been charged. Contact [merchant name] and try again later." Sending the wallet any amount of USDC once creates the account; the costs are in what an associated token account is, and the setup steps in Set up your business.
How do you check a Solana address before sending money?
Check a Solana address by comparing all of it with a copy you trust, not only the first and last characters, and by confirming it is a wallet if a wallet is what you were asked for. A shortened address such as the checkout's four-and-four is a convenience for recognising your own wallet, not a security check. Attackers create look-alike addresses that share those characters, a trick described in address poisoning on Solana.
- Copy the address from its source, never from your own transaction history.
- Open it on an explorer, which shows the account's owner program. A USDC token account is owned by the Token Program and records its mint and the wallet it belongs to; an account a program controls names that program.
- If you were given a token account where a wallet was expected, ask for the wallet address instead.
- Send a small test amount first when the sum matters and the transfer is manual.
If you sell with Fianto, none of these steps falls on your customers: they connect a wallet and sign. Accepting USDC this way is set out in how to accept USDC on Solana.