No Fianto fee during the beta. Any fee comes with at least 30 days notice. See pricing
Solana8 min read

What a Solana address is, and which one you should give or check.

A Solana address is a 32-byte account identifier written as a base58 string, and it is one of two kinds: the public key of a keypair, which someone can sign for, or a program derived address, which nobody holds a key for. Your wallet address is a public key; your USDC sits in a token account at a program derived address calculated from that wallet. To get paid you give the wallet address, never the token account, and a Fianto merchant proves that wallet by signing with it.

On this page
What is a Solana address made of?Which addresses take part in a USDC payment?Why does nobody have a private key for a program derived address?What address does a payer see at checkout?Why does a merchant give a wallet address and not a token account?How do you check a Solana address before sending money?SourcesQuestions
TL;DR
  • 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:

AddressKindWho can sign for itWhere you meet it
Customer's walletPublic keyThe customer, in their wallet appOn the checkout, shortened, after "Paying from"
Customer's USDC token accountPDA of the Associated Token Account programNobody; the Token Program moves its USDC when the owner or a delegate authorises itIn the wallet's transaction details or on an explorer
Merchant's receiving walletPublic keyThe merchantIn the merchant dashboard, proven by signature
Merchant's USDC token accountPDANobodyOn an explorer, as the receiving account of each payment
USDC mintThe token's mint accountNobody signs for it in a paymentIn the transaction, as the token being moved
Subscriptions programProgram account, De1egAFMkMWZSN5rYXRj9CAdheBamobVNubTsi9avR44Not applicable: it is codeIn the transaction the customer signs
Plan, subscription and Subscription Authority accountsPDAs of the Subscriptions programOnly that programIn 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 checkout

Why 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_token_account_missing, 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.

  1. Copy the address from its source, never from your own transaction history.
  2. 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.
  3. If you were given a token account where a wallet was expected, ask for the wallet address instead.
  4. 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.

Sources
Questions

Questions about Solana addresses.

What does a Solana address look like?

A string of letters and digits in base58 that encodes 32 bytes. Solana's docs say every account address is displayed as a base58-encoded string.

Is my Solana wallet address the same as my USDC address?

No. Your wallet address is a public key; your USDC sits in a separate token account derived from your wallet and the USDC mint. Give people the wallet address and their wallet finds the token account.

What is a program derived address on Solana?

An address derived from a program ID and some seeds that falls off the Ed25519 curve, so no private key exists for it. Only the program it was derived from can sign for it.

Which address should a merchant give to receive USDC on Solana?

The wallet address. With Fianto the merchant signs a message from that wallet, and Fianto derives the USDC token account and the subscription destinations from it.

Can I tell from the text whether an address is a wallet or a PDA?

No. Both are 32 bytes in base58. An explorer shows the account's owner, which tells you whether it is a plain wallet or an account a program controls.

Read next.

Solana8 min read

Programs, not smart contracts: how Solana runs a subscription payment

A Solana program is what other chains call a smart contract, with one structural difference: the program account holds only executable code, and every piece of state it works on lives in separate accounts that the program owns. A payment program on Solana is therefore a program plus a set of accounts, usually at program derived addresses. The Subscriptions program behind Fianto shows the pattern: a plan account for each price and its terms, one subscription account per subscriber and plan, and one authority account per wallet and token.

Solana6 min read

What is an SPL token? Solana's token standard in plain English

An SPL token is a token on Solana that is created and moved by one of Solana's two shared token programs, rather than by its own smart contract. Each SPL token is defined by a mint account, and every holder keeps the balance in a separate token account. USDC on Solana is an SPL token on the original Token program, with 6 decimals, and a one-off payment through Fianto moves it with the Token program straight from the customer's USDC account to the merchant's.

Wallets7 min read

Seed phrase vs private key vs wallet address, explained for merchants

Think of them as three generations of one secret. The seed phrase is a list of 12 to 24 words from which a wallet derives every private key it holds; each private key controls exactly one address and signs for it; the address is the public half of that key, the part you hand out to get paid. Only the address is ever meant to be shared. Fianto asks for nothing more than the address and a signature made in your wallet, never the phrase and never a key.

Give the wallet, keep the key.

Prove your receiving wallet once, and every payment finds its token account.

New posts are announced on X and Discord.