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

  1. You create a Stellar wallet for Kofi with the address GBJPEJTFUYGBFUUJDBOZKDXIQE3ASFTPNMIT2F4NNQH5HEA76I42CH5P.
  2. Kofi's client sends 120 USDC on Stellar to that address. The client needs no memo, because the address belongs only to Kofi.
  3. Gravv sends inflow.onchain.completed, records a crypto_funding row of 120, and the wallet shows USDC 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.

Reference

Was this page helpful?