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

# Transfer USDC from Solana to HyperCore

This guide shows how to transfer USDC from Solana to HyperCore using the
`TokenMessengerV2` contract. Solana's CCTP implementation does not have the
`depositForBurnWithAuth`, and there is no `CctpExtension` contract for Solana.
As such, transfers from Solana to HyperCore follow the standard CCTP flow, with
the addition of hook data to call the `CctpForwarder` contract on HyperEVM.

This guide does not provide full example code for the transfer to HyperCore from
Solana.

<Note>
  Fast Transfers from Solana to HyperEVM incur a protocol fee and a dynamic
  forwarding fee for the HyperEVM chain relay transaction. Fast Transfer is the
  default for transfers from Solana to HyperCore.
</Note>

## Steps

Use the following steps to transfer USDC from Solana to HyperCore.

### Step 1. Get CCTP fees from the API

Query the CCTP API for the fees for transferring USDC from Solana to HyperCore.
This value is passed to the `maxFee` parameter in the `depositForBurnWithHook`
transaction. The following is an example request to the CCTP using source domain
5 (Solana) and destination domain 19 (HyperEVM):

```shell theme={null}
curl --request GET \
  --url 'https://iris-api-sandbox.circle.com/v2/burn/USDC/fees/5/19?forward=true&hyperCoreDeposit=true' \
  --header 'Content-Type: application/json'
```

**Response:**

```json theme={null}
[
  {
    "finalityThreshold": 1000, // fast transfer
    "minimumFee": 1, // in basis points
    "forwardFee": {
      "low": 211203,
      "med": 216109, // 0.216109 USDC
      "high": 221014
    }
  },
  {
    "finalityThreshold": 2000, // standard transfer
    "minimumFee": 0,
    "forwardFee": {
      "low": 211203,
      "med": 216109, // 0.216109 USDC
      "high": 221014
    }
  }
]
```

### Step 2. Calculate the USDC amounts minus fees

There is a protocol fee to deposit USDC from Solana to HyperEVM and a dynamic
forwarding fee for the HyperEVM chain relay transaction. The CCTP fast transfer
fee is 1 basis point (0.01%) of the transfer amount. The forwarding fee is 0.20
USDC (`0_200_000` subunits) plus a dynamic destination chain gas fee. For a 10
USDC transfer from Solana to HyperCore, the protocol fee is 0.001 USDC (10 USDC
× 0.0001) and an example forwarding fee is 0.216109 USDC, for a total fee of
0.217109 USDC.

Because the protocol fee scales with the transfer amount and the forwarding fee
is dynamic, you must recalculate `maxFee` for each transfer. For a programmatic
approach, see [`calculateMaxFee`](/cctp/concepts/fees#maximum-fee-parameter) on
the fees page.

### Step 3. Sign and broadcast a `depositForBurnWithHook` transaction on the `TokenMessengerV2` contract

Create a `depositForBurnWithHook` transaction for the `TokenMessengerV2`
contract with the following parameters:

* `amount`: The amount of USDC to transfer
* `destinationDomain`: 19 (HyperEVM)
* `mintRecipient`: The address of the `CctpForwarder` contract on HyperEVM
* `destinationCaller`: The address of the `CctpForwarder` contract on HyperEVM
* `maxFee`: The protocol fee + forwarding fee calculated in Step 2
* `minFinalityThreshold`: `1000` (Fast Transfer)
* `hookData`: The hook data to call the `CctpForwarder` contract on HyperEVM

<Warning>
  Always set both `mintRecipient` and `destinationCaller` to the `CctpForwarder`
  [contract address](/cctp/references/hypercore-contract-addresses) on HyperEVM
  when you transfer USDC to HyperCore.

  * If `destinationCaller` is wrong, the forwarder cannot complete the transfer.
  * If `mintRecipient` is wrong, the minted USDC is not sent to the forwarder.

  In either case, funds become permanently stuck and **cannot be recovered**.
</Warning>

The `hookData` is the data to execute the forwarder to HyperCore. The following
is an example of the hook data:

```ts TypeScript theme={null}
/**
 * Generate CCTP forwarder hook data for HyperCore
 *
 * Hook Data Format:
 * Field                        Bytes      Type       Index
 * magicBytes                   24         bytes24    0     ASCII prefix "cctp-forward", followed by padding
 * version                      4          uint32     24
 * dataLength                   4          uint32     28
 * hyperCoreMintRecipient       20         address    32    EVM address - optional, included if requesting a deposit to HyperCore
 * hyperCoreDestinationDex      4          uint32     52    The destinationDexId on HyperCore (0 for perp and uint32.max for spot)
 */
function encodeForwardHookData(
  hyperCoreMintRecipient?: `0x${string}`,
  hyperCoreDestinationDex: number = 0,
): `0x${string}` {
  // Validate hex prefix if recipient provided
  if (hyperCoreMintRecipient && !hyperCoreMintRecipient.startsWith("0x")) {
    throw new Error("Address must start with 0x");
  }

  // Magic bytes: "cctp-forward" (12 chars) padded to 24 bytes with zeros
  const magic = "cctp-forward";
  const magicHex = Buffer.from(magic, "utf-8").toString("hex").padEnd(48, "0");

  // Version: uint32 = 0 (4 bytes, big-endian)
  const version = "00000000";

  if (!hyperCoreMintRecipient) {
    // No recipient: dataLength = 0, return header only (32 bytes)
    const dataLength = "00000000";
    return `0x${magicHex}${version}${dataLength}`;
  }

  // With recipient: dataLength = 24 (20 bytes address + 4 bytes dex)
  const dataLength = "00000018"; // 24 in hex

  // Address: 20 bytes (remove 0x prefix)
  const address = hyperCoreMintRecipient.slice(2).toLowerCase();

  // Destination DEX: uint32 big-endian
  // 0 = perps, 4294967295 (0xFFFFFFFF) = spot
  const dex = (hyperCoreDestinationDex >>> 0).toString(16).padStart(8, "0");

  return `0x${magicHex}${version}${dataLength}${address}${dex}`;
}
```

For full example code calling the `depositForBurnWithHook` function, see the
[Solana CCTP V2 example on GitHub](https://github.com/circlefin/solana-cctp-contracts/blob/9f8cf26d059cf8927ae0a0b351f3a7a88c7bdade/examples/v2/solana.ts#L94).

Once the deposit transaction is confirmed, the USDC is minted on HyperEVM and
automatically forwarded to your address on HyperCore.

By default (when `hyperCoreDestinationDex` is `0`), deposits credit the perps
balance on HyperCore. To deposit to the spot balance, set
`hyperCoreDestinationDex` to `4294967295` (uint32 max value).
