Skip to main content

cctp_rs/contracts/
token_messenger.rs

1// SPDX-FileCopyrightText: 2025 Semiotic AI, Inc.
2//
3// SPDX-License-Identifier: Apache-2.0
4//! `TokenMessenger` contract bindings and wrapper
5//!
6//! This module contains the Alloy-generated contract bindings for the CCTP
7//! `TokenMessenger` contract, which manages USDC burn and mint operations for
8//! cross-chain transfers.
9
10use std::marker::PhantomData;
11
12use alloy_contract::CallBuilder;
13use alloy_network::Ethereum;
14use alloy_primitives::{Address, U256};
15use alloy_provider::Provider;
16use alloy_rpc_types::TransactionRequest;
17use alloy_sol_types::sol;
18use tracing::{debug, info};
19use TokenMessenger::{depositForBurnCall, TokenMessengerInstance};
20
21use crate::spans;
22
23/// The CCTP v1 Token Messenger contract wrapper
24pub struct TokenMessengerContract<P: Provider<Ethereum>> {
25    instance: TokenMessengerInstance<P>,
26}
27
28impl<P: Provider<Ethereum>> TokenMessengerContract<P> {
29    /// Create a new `TokenMessengerContract`.
30    pub fn new(address: Address, provider: P) -> Self {
31        debug!(
32            contract_address = %address,
33            event = "token_messenger_contract_initialized"
34        );
35        Self {
36            instance: TokenMessengerInstance::new(address, provider),
37        }
38    }
39
40    /// Create the call builder for the `depositForBurn` function.
41    ///
42    /// Most users will want to use the `deposit_for_burn_transaction` function instead.
43    pub fn deposit_for_burn_call_builder(
44        &self,
45        from_address: Address,
46        recipient: Address,
47        destination_domain: u32,
48        token_address: Address,
49        amount: U256,
50    ) -> CallBuilder<&P, PhantomData<depositForBurnCall>> {
51        self.instance
52            .depositForBurn(
53                amount,
54                destination_domain,
55                recipient.into_word(),
56                token_address,
57            )
58            .from(from_address)
59    }
60
61    /// Create the transaction request for the `depositForBurn` function.
62    ///
63    /// Most users will want to use this function instead of the `deposit_for_burn_call_builder` function.
64    pub fn deposit_for_burn_transaction(
65        &self,
66        from_address: Address,
67        recipient: Address,
68        destination_domain: u32,
69        token_address: Address,
70        amount: U256,
71    ) -> TransactionRequest {
72        let span = spans::deposit_for_burn(
73            &from_address,
74            &recipient,
75            destination_domain,
76            &token_address,
77            &amount,
78        );
79        let _guard = span.enter();
80
81        info!(
82            from_address = %from_address,
83            recipient = %recipient,
84            destination_domain = destination_domain,
85            token_address = %token_address,
86            amount = %amount,
87            contract_address = %self.instance.address(),
88            event = "deposit_for_burn_transaction_created"
89        );
90
91        self.deposit_for_burn_call_builder(
92            from_address,
93            recipient,
94            destination_domain,
95            token_address,
96            amount,
97        )
98        .into_transaction_request()
99    }
100}
101
102sol!(
103    #[allow(clippy::too_many_arguments)]
104    #[allow(missing_docs)]
105    #[sol(rpc)]
106    TokenMessenger,
107    "abis/v1_token_messenger.json"
108);