> ## Documentation Index
> Fetch the complete documentation index at: https://docs.etherfuse.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Solana

> Asset identifiers, wallet registration, gas handling, and swap support on Solana.

export const ChainAssets = ({chain}) => {
  const {useState, useEffect} = React;
  const [rows, setRows] = useState(null);
  const [error, setError] = useState(null);
  const EXPLORER = {
    solana: id => 'https://solscan.io/token/' + id,
    stellar: id => 'https://stellar.expert/explorer/public/asset/' + id,
    base: id => 'https://basescan.org/token/' + id,
    polygon: id => 'https://polygonscan.com/token/' + id,
    monad: id => 'https://monadvision.com/token/' + id,
    avalanche: id => 'https://snowtrace.io/token/' + id
  };
  const CHAIN_LABEL = {
    stellar: 'Stellar',
    solana: 'Solana',
    monad: 'Monad',
    base: 'Base',
    polygon: 'Polygon',
    avalanche: 'Avalanche'
  };
  const tokenLogo = s => 'https://stablebonds.s3.us-west-2.amazonaws.com/stablebond/spl-' + String(s).toLowerCase() + '.png';
  const hideOnError = e => {
    e.currentTarget.style.display = 'none';
  };
  useEffect(() => {
    let cancelled = false;
    fetch('https://api.etherfuse.com/lookup/stablebonds').then(r => {
      if (!r.ok) throw new Error('HTTP ' + r.status);
      return r.json();
    }).then(data => {
      if (cancelled) return;
      setRows(data.stablebonds || []);
    }).catch(e => {
      if (!cancelled) setError(e.message || 'failed to load');
    });
    return () => {
      cancelled = true;
    };
  }, []);
  const border = '1px solid rgba(128,128,128,0.25)';
  const cell = {
    padding: '6px 12px',
    borderBottom: border,
    textAlign: 'left',
    verticalAlign: 'middle'
  };
  const head = {
    ...cell,
    fontWeight: 600
  };
  const mono = {
    fontFamily: 'monospace',
    fontSize: '0.85em',
    wordBreak: 'break-all'
  };
  const inline = {
    display: 'inline-flex',
    alignItems: 'center',
    gap: '6px'
  };
  if (error) return <p>
        Couldn't load the live list. See <code>GET /lookup/stablebonds</code>.
      </p>;
  if (!rows) return <p>Loading live addresses…</p>;
  const items = (rows || []).filter(b => b.symbol !== 'MEX').map(b => {
    const entry = (b.blockchains || []).find(c => c.blockchain === chain);
    return entry ? {
      symbol: b.symbol,
      currency: b.bondCurrency,
      id: entry.tokenIdentifier
    } : null;
  }).filter(Boolean).sort((a, z) => String(a.symbol).localeCompare(String(z.symbol)));
  if (!items.length) return <p>No stablebonds are currently live on {CHAIN_LABEL[chain] || chain}.</p>;
  return <div>
      <table style={{
    width: '100%',
    borderCollapse: 'collapse',
    fontSize: '0.95em'
  }}>
        <thead>
          <tr>
            <th style={{
    ...head,
    width: '160px'
  }}>Asset</th>
            <th style={head}>Address</th>
          </tr>
        </thead>
        <tbody>
          {items.map(it => {
    const url = EXPLORER[chain] ? EXPLORER[chain](it.id) : null;
    return <tr key={it.symbol}>
                <td style={cell}>
                  <span style={inline}>
                    <img src={tokenLogo(it.symbol)} alt="" width={20} height={20} onError={hideOnError} />
                    <strong>{it.symbol}</strong>
                    <span style={{
      opacity: 0.6
    }}>· {it.currency}</span>
                  </span>
                </td>
                <td style={{
      ...cell,
      ...mono
    }}>
                  {url ? <a href={url} target="_blank" rel="noreferrer">
                      {it.id}
                    </a> : it.id}
                </td>
              </tr>;
  })}
        </tbody>
      </table>
      <p style={{
    fontSize: '0.8em',
    opacity: 0.65,
    marginTop: '8px'
  }}>
        Live from <code>GET https://api.etherfuse.com/lookup/stablebonds</code>. Production addresses — when quoting,
        use the <code>identifier</code> from <code>GET /ramp/assets</code> (sandbox differs).
      </p>
    </div>;
};

<img src="https://mintcdn.com/etherfuse/XRSchVFGUgreQatD/img/chains/solana.svg?fit=max&auto=format&n=XRSchVFGUgreQatD&q=85&s=6018dc319aab06dfc6ee3da2de48c522" alt="Solana" width="64" noZoom style={{ float: "right", margin: "0 0 1rem 1.5rem" }} data-path="img/chains/solana.svg" />

We support onramps, offramps and swaps on Solana. Solana needs the least per-transaction setup of the supported networks: there are no trustlines, and network fees are negligible. The end-to-end flows are in the [Onramps](/v2/guides/testing-onramps), [Offramps](/v2/guides/testing-offramps) and [Swaps](/v2/guides/testing-swaps) guides.

## Supported operations

| Operation | Supported |
| - | - |
| Onramp (fiat → token) | ✓ |
| Offramp (token → fiat) | ✓ |
| Swap (token → token) | ✓ |

## Asset identifiers

Solana assets use the **Base58 mint address**, for example `AvvetPGuuB5FD5m86fpw3LtDKyQoUFT1mG9WarNQLW4q`.

<Tip>
  Read the mint, the token's `asset`, from [`GET /supported_assets?chain=solana`](/v2/api-reference/assets/list-supported-assets) (or the public [`GET /lookup/stablebonds`](/v2/api-reference/lookup/list-stablebonds)). Do not hardcode it; mints differ between sandbox and production.
</Tip>

## Stablebond addresses

Live mint accounts for every stablebond on Solana, each linked to Solscan:

<ChainAssets chain="solana" />

## Register a Solana wallet

Register the wallet as a payment account with `accountDetails` of kind `address` and `chain` `solana`. Set `$ORGANIZATION_ID` to the organization that owns the wallet: your own organization or a customer organization. See [Organizations in the route](/v2/overview#organizations-in-the-route).

```bash theme={null}
curl -X POST https://api.sand.etherfuse.com/organization/$ORGANIZATION_ID/payment_account \
  -H "Authorization: <api_key>" \
  -H "Content-Type: application/json" \
  -d '{
    "kind": "wallet",
    "label": "Solana wallet",
    "accountDetails": {
      "kind": "address",
      "address": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU",
      "chain": "solana"
    }
  }'
```

Use the returned `id` as the `source` or `destination` of a [quote](/v2/api-reference/quotes/create-quote).

## Wallet and gas

Solana has no trustline or account-reserve step. Network fees are a tiny fraction of a cent. On an offramp or swap, the customer's wallet pays the fee for the funding transaction. The prepared transaction only transfers the tokens; our receiving wallet's token account already exists.

## Offramps and swaps: fund the order

For an offramp or swap from a Solana wallet, `fundingInstructions.destination.address` is the address to pay. The source asset is an SPL token. Fund the order in one of two ways:

1. **Sign the prepared transaction.** `preparedTransaction.transaction` is an unsigned v0 transaction, base64-encoded in Solana's wire format. The customer's wallet is the fee payer and the only signer. Sign it and submit it.
2. **Send the tokens yourself.** Send the order's `source.amount` of `source.asset` to `address`.

Decode it as a versioned transaction, for example with `VersionedTransaction.deserialize` in `@solana/web3.js`. `Transaction.from` reads only legacy transactions.

The prepared transaction uses a recent blockhash, so it goes stale. After `preparedTransaction.refreshAfter`, about 60 seconds after we build it, call [`POST /organization/{organizationId}/order/{id}/funding_instructions/refresh`](/v2/api-reference/orders/refresh-funding-instructions). It returns the order as it is. The new funding instructions arrive a moment later in an `orderUpdated` webhook, and on [`GET .../order/{id}`](/v2/api-reference/orders/get-order).

Every refresh builds a new transaction. Until the old one's blockhash expires, both can land, so have the customer sign and submit only the newest one.

## Swaps

A swap on Solana is an order between two Solana wallet accounts. Track it like any other order: read [`GET /organization/{organizationId}/order/{id}`](/v2/api-reference/orders/get-order), or subscribe to [`orderUpdated`](/v2/api-reference/webhook-events/orderupdated). The status moves `created` → `funded` → `completed`. See [Swaps](/v2/guides/testing-swaps).

## Related

<CardGroup cols={3}>
  <Card title="Onramps" icon="arrow-up-right-dots" href="/v2/guides/testing-onramps" />

  <Card title="Offramps" icon="arrow-down" href="/v2/guides/testing-offramps" />

  <Card title="Swaps" icon="right-left" href="/v2/guides/testing-swaps" />
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.