> ## 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.

# CCTP Aptos packages and interfaces

> Move packages and function interfaces for CCTP on Aptos

CCTP on Aptos is distributed across four Move packages:
`TokenMessengerMinterV2`, `MessageTransmitterV2`, `StablecoinHandler`, and
`CctpExtensions`. Because Move uses static dispatch, contracts cannot call each
other dynamically at runtime. Instead, these functions return receipt structs
(`BurnReceipt` and `MintReceipt`) that act as hot potatoes: they have no
abilities (they cannot be dropped, copied, or stored) and must be consumed in
the same transaction. The Move compiler enforces this at compile time, not at
runtime, so a transaction that fails to consume a receipt will not compile.

For working end-to-end examples, see
[Transfer USDC between Aptos and Arc](/cctp/quickstarts/transfer-usdc-aptos-arc).

## Package addresses

<Note>
  **Package IDs** identify deployed modules. Use them in `use` declarations and
  transaction payloads. **Object IDs** identify onchain state objects (such as
  configuration or shared resources) and are passed as function arguments when a
  transaction interacts with protocol state.
</Note>

### Testnet

#### Package IDs

| Package                  | [Domain](/cctp/concepts/supported-chains-and-domains#domain-identifiers) | Address                                                              |
| :----------------------- | :----------------------------------------------------------------------- | :------------------------------------------------------------------- |
| `MessageTransmitterV2`   | 9                                                                        | `0xa582dc019ae17b0485f7d3fcc4ca85bea7941e3b70a4b682cea22759f36e711f` |
| `TokenMessengerMinterV2` | 9                                                                        | `0xc601d3f7b89b77b552726d5d84cbf2a6d3e8a73adbbee3f09fad169a3286bb59` |
| `CctpExtensions`         | 9                                                                        | `0x84010f184db7b60e0067f360b6f809c16cf72ae6ea061cf15ffff2ce9b9b6963` |
| `StablecoinHandler`      | 9                                                                        | `0xe5d19c4eb6e1e42c5435901fc6153fd19f6615651be0e6cefe0f07226d4a6846` |

#### Object IDs

| Object                   | Object ID                                                            |
| :----------------------- | :------------------------------------------------------------------- |
| `MessageTransmitterV2`   | `0x20c2e0b179a05d08b968003d40563a8c467aa84e2fcabfa6fd5084be27988c47` |
| `TokenMessengerMinterV2` | `0x6f57203ca59e901130d8bde217b33cde19faa622dd96ecf6681a2d5307412a14` |
| `StablecoinHandler`      | `0x22d1d88ffb2e81ac025077f60079dcdfbf45fab0fd1abf7aa5e57c43db25599b` |
| `Stablecoin`             | `0x69091fbab5f7d635ee7ac5098cf0c1efbe31d68fec0f2cd565e8d168daf52832` |

### Mainnet

#### Package IDs

| Package                  | [Domain](/cctp/concepts/supported-chains-and-domains#domain-identifiers) | Address                                                              |
| :----------------------- | :----------------------------------------------------------------------- | :------------------------------------------------------------------- |
| `MessageTransmitterV2`   | 9                                                                        | `0x1b3f6d749cb835451202f9a1932e49014266f7e3d51611a9a763d156cb4bdaf6` |
| `TokenMessengerMinterV2` | 9                                                                        | `0x551e32781793c30bf1580d11e4f5171e8d068c3d45c3a5b20ae240bfdad99af8` |
| `CctpExtensions`         | 9                                                                        | `0x93c742af9a876b10c8e13584fb443597611f0efdb342530aa0ebc5ad208815ff` |
| `StablecoinHandler`      | 9                                                                        | `0x2b963f8aa28b815d2e875bd85a1a01d5f2d346f08f5b9fcf8953c77680735af2` |

#### Object IDs

| Object                   | Object ID                                                            |
| :----------------------- | :------------------------------------------------------------------- |
| `MessageTransmitterV2`   | `0x57ba011deccc5749aff12f4900fd30cac744098f7be91f1eba4e07847510ee72` |
| `TokenMessengerMinterV2` | `0x52f4732b1cb52ce28f595e29978450132772f88277182e12bc431faa677be603` |
| `StablecoinHandler`      | `0x44a1eb6f97a962623ad9d4e8db3dc8408d1b62f90baf91ae6c0d6764b9f1b984` |
| `Stablecoin`             | `0xbae207659db88bea0cbead6da0ed00aac12edcdda169e591cd41c94180b46f3b` |

## CCTP interface

* `TokenMessengerMinterV2`: initiates crosschain USDC burns and prepares mints
  upon attested message receipt.
* `MessageTransmitterV2`: provides the core messaging layer, verifying
  attestations and routing messages to the appropriate handler.
* `StablecoinHandler`: executes the actual burn and mint of USDC, consuming the
  receipt structs returned by `TokenMessengerMinterV2`.
* `CctpExtensions`: provides protocol extension hooks for advanced integrations.

### TokenMessengerMinterV2 interface

`TokenMessengerMinterV2` manages the USDC burn and mint lifecycle. Its functions
return receipt structs (`BurnReceipt` and `MintReceipt`) that must be passed to
the `StablecoinHandler` in the same transaction.

| Function           | Parameters                                                                                                                                                                                                    | Returns                        | Notes                                                                                                                                                                          |
| :----------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | :----------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `deposit_for_burn` | `caller (Signer)`, `asset (FungibleAsset)`, `destination_domain (u32)`, `mint_recipient (address)`, `destination_caller (address)`, `max_fee (u64)`, `min_finality_threshold (u32)`, `hook_data (vector<u8>)` | `(BurnReceipt, FungibleAsset)` | Pass `@0x0` as `destination_caller` to allow any caller on the destination. The returned `BurnReceipt` must be passed to `stablecoin_handler::burn()` in the same transaction. |
| `prepare_mint`     | `receipt (Receipt)`                                                                                                                                                                                           | `MintReceipt`                  | Takes the `Receipt` returned by `MessageTransmitterV2::receive_message`. The returned `MintReceipt` must be passed to `stablecoin_handler::mint()` in the same transaction.    |
| `complete_mint`    | `handler_signer (Signer)`, `mint_receipt (MintReceipt)`, `asset (FungibleAsset)`, `fee_asset (FungibleAsset)`                                                                                                 | None                           | Not called directly by integrators; called internally by the `StablecoinHandler`. Deposits minted assets and fee assets, then consumes `MintReceipt`.                          |
| `complete_burn`    | `handler_signer (Signer)`, `burn_receipt (BurnReceipt)`                                                                                                                                                       | None                           | Not called directly by integrators; called internally by the `StablecoinHandler`. Sends the crosschain message and consumes `BurnReceipt`.                                     |

### MessageTransmitterV2 interface

`MessageTransmitterV2` provides the messaging layer for CCTP on Aptos. It
verifies attestations, marks nonces as used, and returns a `Receipt` hot potato
that the caller must consume in the same transaction.

| Function                   | Parameters                                                                                                                                                         | Returns   | Notes                                                                                                                                                                                                                                                                                                                             |
| :------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `receive_message`          | `caller (Signer)`, `message (&vector<u8>)`, `attestation (&vector<u8>)`                                                                                            | `Receipt` | `message` and `attestation` are passed by reference (`&vector<u8>`). Nonce is assigned by the attestation service; it is always `0` in the emitted message. The `Receipt` must be consumed in the same transaction by `TokenMessengerMinterV2::prepare_mint()` (for USDC) or `complete_receive_message()` (for generic messages). |
| `send_message`             | `caller (Signer)`, `destination_domain (u32)`, `recipient (address)`, `destination_caller (address)`, `min_finality_threshold (u32)`, `message_body (&vector<u8>)` | None      | Called internally during the burn flow; do not call directly for USDC transfers.                                                                                                                                                                                                                                                  |
| `complete_receive_message` | `caller (Signer)`, `receipt (Receipt)`                                                                                                                             | None      | For generic messages only. USDC flows use `TokenMessengerMinterV2::prepare_mint()` instead. Destroys `Receipt` and emits a `MessageReceived` event.                                                                                                                                                                               |

### StablecoinHandler interface

`StablecoinHandler` is the entry point for executing USDC burns and mints on
Aptos. Its functions consume the receipt structs produced by
`TokenMessengerMinterV2` and call the appropriate completion functions
internally.

| Function        | Parameters                                            | Returns | Notes                                                                                                                                     |
| :-------------- | :---------------------------------------------------- | :------ | :---------------------------------------------------------------------------------------------------------------------------------------- |
| `handler::burn` | `burn_receipt (BurnReceipt)`, `asset (FungibleAsset)` | None    | Takes the `BurnReceipt` and `FungibleAsset` returned by `TokenMessengerMinterV2::deposit_for_burn()`. Calls `complete_burn()` internally. |
| `handler::mint` | `mint_receipt (MintReceipt)`                          | None    | Takes the `MintReceipt` returned by `TokenMessengerMinterV2::prepare_mint()`. Calls `complete_mint()` internally.                         |

### CctpExtensions interface

`CctpExtensions` provides protocol extension hooks for advanced integrations.
Function-level documentation is not yet available here. Refer to the
[aptos-cctp GitHub repository](https://github.com/circlefin/aptos-cctp) for the
current interface definitions.

## Move scripts

<Note>
  Precompiled scripts for `deposit_for_burn`, `deposit_for_burn_with_hook`, and
  `receive_message` are available in
  [`typescript/example/precompiled-move-scripts/`](https://github.com/circlefin/aptos-cctp/tree/master/typescript/example/precompiled-move-scripts)
  in the aptos-cctp repository. The `v2/` subdirectory contains scripts for both
  testnet and mainnet. You can also compile them from source; see the
  [Aptos documentation on compiling scripts](https://aptos.dev/en/build/smart-contracts/scripts/compiling-scripts).
</Note>

| Script                          | Description                                                                                       |
| :------------------------------ | :------------------------------------------------------------------------------------------------ |
| `deposit_for_burn.mv`           | Withdraws USDC, calls `deposit_for_burn`, then `stablecoin_handler::burn` in one transaction.     |
| `deposit_for_burn_with_hook.mv` | Same as `deposit_for_burn.mv` but includes `hook_data`.                                           |
| `receive_message.mv`            | Calls `receive_message`, then `prepare_mint`, then `stablecoin_handler::mint` in one transaction. |

## Examples

### Send USDC from Aptos (outbound)

The outbound flow uses a Move script that withdraws the fungible asset, calls
`deposit_for_burn` to create a `BurnReceipt`, then passes both to
`stablecoin_handler::burn` to complete the transfer.

```move theme={null}
script {
    use aptos_framework::fungible_asset::Metadata;
    use aptos_framework::object::{Self, Object};
    use aptos_framework::primary_fungible_store;
    use token_messenger_minter_v2::token_messenger_minter;
    use stablecoin_handler::handler;
    use std::vector;

    fun deposit_for_burn(
        caller: &signer,
        amount: u64,
        destination_domain: u32,
        mint_recipient: address,
        destination_caller: address,
        burn_token: address,
        max_fee: u64,
        min_finality_threshold: u32,
    ) {
        let token_obj: Object<Metadata> = object::address_to_object(burn_token);
        let asset = primary_fungible_store::withdraw(caller, token_obj, amount);

        let (burn_receipt, asset) = token_messenger_minter::deposit_for_burn(
            caller,
            asset,
            destination_domain,
            mint_recipient,
            destination_caller,
            max_fee,
            min_finality_threshold,
            vector::empty<u8>(),
        );

        handler::burn(burn_receipt, asset);
    }
}
```

### Send USDC from Aptos with hook data (outbound)

For transfers that include hook data (for example, to trigger a post-mint action
on the destination blockchain):

```move theme={null}
script {
    use aptos_framework::fungible_asset::Metadata;
    use aptos_framework::object::{Self, Object};
    use aptos_framework::primary_fungible_store;
    use token_messenger_minter_v2::token_messenger_minter;
    use stablecoin_handler::handler;

    fun deposit_for_burn_with_hook(
        caller: &signer,
        amount: u64,
        destination_domain: u32,
        mint_recipient: address,
        destination_caller: address,
        burn_token: address,
        max_fee: u64,
        min_finality_threshold: u32,
        hook_data: vector<u8>,
    ) {
        let token_obj: Object<Metadata> = object::address_to_object(burn_token);
        let asset = primary_fungible_store::withdraw(caller, token_obj, amount);

        let (burn_receipt, asset) = token_messenger_minter::deposit_for_burn(
            caller,
            asset,
            destination_domain,
            mint_recipient,
            destination_caller,
            max_fee,
            min_finality_threshold,
            hook_data,
        );

        handler::burn(burn_receipt, asset);
    }
}
```

### Receive USDC on Aptos (inbound)

The inbound flow verifies the attestation, creates a `Receipt`, exchanges it for
a `MintReceipt` using `prepare_mint`, then passes the `MintReceipt` to
`stablecoin_handler::mint` to deposit USDC to the recipient.

```move theme={null}
script {
    use message_transmitter_v2::message_transmitter;
    use token_messenger_minter_v2::token_messenger_minter;
    use stablecoin_handler::handler;

    fun receive_message(
        caller: &signer,
        message: vector<u8>,
        attestation: vector<u8>
    ) {
        let receipt = message_transmitter::receive_message(
            caller, &message, &attestation
        );

        let mint_receipt = token_messenger_minter::prepare_mint(receipt);

        handler::mint(mint_receipt);
    }
}
```

### Send a generic message (non-token transfer)

```move theme={null}
script {
    use message_transmitter_v2::message_transmitter;

    fun send_message(
        caller: &signer,
        destination_domain: u32,
        recipient: address,
        destination_caller: address,
        min_finality_threshold: u32,
        message_body: vector<u8>
    ) {
        message_transmitter::send_message(
            caller,
            destination_domain,
            recipient,
            destination_caller,
            min_finality_threshold,
            &message_body
        );
    }
}
```
