Receive USDC on Stellar or Solana
Create a Stellar or Solana address for a customer that receives USDC, with no memo, and know when a Stellar address is ready.
This recipe creates a Stellar or Solana address that receives USDC for a customer, with no memo, and shows how to tell when a Stellar address is ready. It is for a freelancer platform whose contractors receive USDC on Stellar from clients abroad.
Status. Available for USDC. USDT on Stellar or Solana is Not supported.
Money example
- You create a Stellar wallet for Kofi with the address
GBJPEJTFUYGBFUUJDBOZKDXIQE3ASFTPNMIT2F4NNQH5HEA76I42CH5P. - Kofi's client sends 120 USDC on Stellar to that address. The client needs no memo, because the address belongs only to Kofi.
- Gravv sends
inflow.onchain.completed, records acrypto_fundingrow of 120, and the wallet showsUSDC 120.0000000(Stellar uses 7 decimals).
Before you start
You need the same things as for an EVM address. The customer exists, a scoped key has account:create, and you have registered your webhook URL. See Give a customer a stablecoin address on an EVM network.
Find out what is required
- Stellar and Solana take USDC only.
- A Stellar address can hold USDC only once it has a USDC trustline (the address's permission to hold USDC). Gravv adds it when it creates the wallet, normally within a few seconds. The API does not show it.
- A Solana address opens its USDC balance with the first USDC it receives.
Steps
1. Create the wallet
curl --request POST \
--url https://api.gravv.xyz/v1/wallets \
--header 'Api-Key: <API_KEY>' \
--header 'Idempotency-Key: 55a8d506-5b17-4cb1-8d2a-1bc014e18368' \
--header 'Content-Type: application/json' \
--data '
{
"customer_id": "401d68fb-fe97-4c56-84a6-5651cdbde747",
"network": "stellar",
"name": "Kofi USDC"
}
'
const response = await fetch("https://api.gravv.xyz/v1/wallets", {
method: "POST",
headers: {
"Api-Key": process.env.GRAVV_API_KEY,
"Idempotency-Key": "55a8d506-5b17-4cb1-8d2a-1bc014e18368",
"Content-Type": "application/json",
},
body: JSON.stringify({
"customer_id": "401d68fb-fe97-4c56-84a6-5651cdbde747",
"network": "stellar",
"name": "Kofi USDC"
}),
});
console.log(response.status, await response.json());
import os
import requests
response = requests.post(
"https://api.gravv.xyz/v1/wallets",
headers={
"Api-Key": os.environ["GRAVV_API_KEY"],
"Idempotency-Key": "55a8d506-5b17-4cb1-8d2a-1bc014e18368",
"Content-Type": "application/json",
},
json={
"customer_id": "401d68fb-fe97-4c56-84a6-5651cdbde747",
"network": "stellar",
"name": "Kofi USDC",
},
)
print(response.status_code, response.json())
{
"data": {
"id": "30803889-fa61-4774-8d11-8e3781728a07",
"address": "GBJPEJTFUYGBFUUJDBOZKDXIQE3ASFTPNMIT2F4NNQH5HEA76I42CH5P",
"network": "stellar",
"name": "Kofi USDC",
"date_created": "2026-10-13T10:02:41Z",
"customer_id": "401d68fb-fe97-4c56-84a6-5651cdbde747",
"wallet_type": "customer"
},
"error": null
}
For Solana, send "network": "solana". Its address is base58, such as Borqy3dEjw9az7Uj9nW69A9ZDansFGHWEggUx7tkv44f.
2. Optional: make sure a Stellar address is ready
GET /v1/wallets/{wallet_id} lists USDC at "0.0000000" right after creation, so it does not prove the trustline exists. Ask the sender to send a small amount first, or look up the address on a Stellar explorer and check for a USDC balance line. A Stellar sender's wallet refuses to send to an address with no USDC trustline.
3. Receive and read the balance
Follow steps 2 to 4 for an EVM address. To read the balance, get the wallet by its id.
curl --request GET \
--url https://api.gravv.xyz/v1/wallets/30803889-fa61-4774-8d11-8e3781728a07 \
--header 'Api-Key: <API_KEY>'
const response = await fetch("https://api.gravv.xyz/v1/wallets/30803889-fa61-4774-8d11-8e3781728a07", {
method: "GET",
headers: {
"Api-Key": process.env.GRAVV_API_KEY,
},
});
console.log(response.status, await response.json());
import os
import requests
response = requests.get(
"https://api.gravv.xyz/v1/wallets/30803889-fa61-4774-8d11-8e3781728a07",
headers={
"Api-Key": os.environ["GRAVV_API_KEY"],
},
)
print(response.status_code, response.json())
{
"data": {
"id": "30803889-fa61-4774-8d11-8e3781728a07",
"network": "stellar",
"assets": [
{ "symbol": "USDC", "balance": "120.0000000", "decimals": 7, "updated_at": "2026-10-13T10:20:05Z" },
{ "symbol": "XLM", "balance": "1.5000000", "decimals": 7, "updated_at": "2026-10-13T10:20:05Z" }
]
},
"error": null
}
A new Solana wallet lists only SOL until the first USDC arrives.
What can go wrong
| Response | Why | Fix |
|---|---|---|
| The sender's wallet says the address has no trustline | Gravv is still setting up the Stellar wallet | Wait and send again. If the error stays, contact support with the wallet id |
| USDT sent on Solana shows in the balance, but there is no row | USDT is not a deposit coin on Solana | Contact support with the hash. Ask senders to send USDC |
| The sender added a memo | The address needs no memo, and Gravv ignores it | No action needed |
GET /v1/wallets?wallet_address=… returns nothing |
The filter is exact and case-sensitive | Use the address exactly as Gravv returned it |
| The create call returns an error | The errors are the same as for any wallet | See the EVM recipe |
Webhooks you will receive
Gravv sends inflow.onchain.completed and inflow.onchain.failed, as for an EVM address.
Testing in sandbox
Sandbox Stellar and Solana wallets are real test-network wallets. Send USDC to the address from a public USDC faucet for that test network, then watch for the webhook and the balance. See Fund wallets during testing. Never send main-network coins to a sandbox address, because you lose them.