> For the complete documentation index, see [llms.txt](https://docs.zebec.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.zebec.io/developer-docs/partner-api/topup-flow/solana.md).

# Solana example

Execute a Carbon card top-up from a Solana wallet through the Zebec Partner API.

Use this flow for a quote whose `payment.chain` is `SOLANA`. Start with the shared [top-up flow](/developer-docs/partner-api/topup-flow.md) through preflight and use the same wallet public key throughout.

## Request the quote

```http
GET /partner/v1/topup/quote?amount=100&currencyCode=USD&sourceChain=SOLANA&sourceTokenMint=<spl-token-mint>
Authorization: Bearer <accessToken>
```

Read `payment.network`, `payment.contractAddress`, `payment.tokenAmount`, and `payment.tokenDecimals` from the response. Build and submit the quote-defined SPL-token/card-program transaction with your wallet adapter. Do not convert the quoted base-unit amount with a hard-coded decimal value.

## Execute and confirm

The Partners Card SDK exposes `ZebecCardSolanaService.purchaseCard()` for wallet-backed Solana execution. Supply an adapter backed by the user's wallet and preserve the selected token and quote data when adapting the Partner API quote.

```ts
const { signature: txHash } = await solanaCardService.purchaseCard({
  amount: quote.sourceAmount,
  quote: partnerQuoteAdapter.toSdkQuote(quote),
  token: partnerQuoteAdapter.toSdkToken(quote),
  cardProgramId: program.programId,
  recipient,
  userAddress: wallet.publicKey.toBase58(),
  reloadCardId: quote.cardId,
});
```

Wait for finalization before treating `txHash` as the receipt. If you use a different Solana integration, it must submit the transaction encoded by the quote and retain the finalized transaction signature.

## Sign and submit

Sign the UTF-8 bytes of `quote.signingMessage` with the same Solana wallet. Encode the detached signature as base58.

```ts
const buyerAddress = wallet.publicKey.toBase58();
const signature = base58.encode(
  await wallet.signMessage(new TextEncoder().encode(quote.signingMessage)),
);

await partnerApi.submitTopup({
  quoteId: quote.id,
  receipt: { deposit: { txHash, buyerAddress } },
  userSignature: { signature, publicKey: buyerAddress, scheme: "solana" },
});
```

The signature wallet, preflight wallet, and transaction payer must identify the same wallet account.
