Smart Contract

IFlowEVMNFTBridge

A.1e4aa0b87d10b141.IFlowEVMNFTBridge

Valid From

114,568,935

Deployed

1w ago
Feb 16, 2026, 08:14:21 PM UTC

Dependents

0 imports
1import FungibleToken from 0xf233dcee88fe0abe
2import NonFungibleToken from 0x1d7e57aa55817448
3
4import EVM from 0xe467b9dd11fa00df
5
6import FlowEVMBridgeConfig from 0x1e4aa0b87d10b141
7import CrossVMNFT from 0x1e4aa0b87d10b141
8
9access(all) contract interface IFlowEVMNFTBridge {
10    
11    /*************
12        Events
13    **************/
14
15    /// Broadcasts an NFT was bridged from Cadence to EVM
16    access(all)
17    event BridgedNFTToEVM(
18        type: String,
19        id: UInt64,
20        uuid: UInt64,
21        evmID: UInt256,
22        to: String,
23        evmContractAddress: String,
24        bridgeAddress: Address
25    )
26    /// Broadcasts an NFT was bridged from EVM to Cadence
27    access(all)
28    event BridgedNFTFromEVM(
29        type: String,
30        id: UInt64,
31        uuid: UInt64,
32        evmID: UInt256,
33        caller: String,
34        evmContractAddress: String,
35        bridgeAddress: Address
36    )
37
38    /**************
39        Getters
40    ***************/
41
42    /// Returns the EVM address associated with the provided type
43    ///
44    access(all)
45    view fun getAssociatedEVMAddress(with type: Type): EVM.EVMAddress?
46
47    /// Returns the EVM address of the bridge coordinating COA
48    ///
49    access(all)
50    view fun getBridgeCOAEVMAddress(): EVM.EVMAddress
51
52    /********************************
53        Public Bridge Entrypoints
54    *********************************/
55
56    /// Public entrypoint to bridge NFTs from Cadence to EVM.
57    ///
58    /// @param token: The NFT to be bridged
59    /// @param to: The NFT recipient in FlowEVM
60    /// @param feeProvider: A reference to a FungibleToken Provider from which the bridging fee is withdrawn in $FLOW
61    ///
62    access(all)
63    fun bridgeNFTToEVM(
64        token: @{NonFungibleToken.NFT},
65        to: EVM.EVMAddress,
66        feeProvider: auth(FungibleToken.Withdraw) &{FungibleToken.Provider}
67    ) {
68        pre {
69            emit BridgedNFTToEVM(
70                type: token.getType().identifier,
71                id: token.id,
72                uuid: token.uuid,
73                evmID: CrossVMNFT.getEVMID(from: &token as &{NonFungibleToken.NFT}) ?? UInt256(token.id),
74                to: to.toString(),
75                evmContractAddress: self.getAssociatedEVMAddress(with: token.getType())?.toString()
76                    ?? panic(
77                        "Could not find EVM Contract address associated with provided NFT identifier="
78                        .concat(token.getType().identifier)
79                    ),
80                bridgeAddress: self.account.address
81            )
82        }
83    }
84
85    /// Public entrypoint to bridge NFTs from EVM to Cadence
86    ///
87    /// @param owner: The EVM address of the NFT owner. Current ownership and successful transfer (via 
88    ///     `protectedTransferCall`) is validated before the bridge request is executed.
89    /// @param type: The Cadence Type of the NFT to be bridged. If EVM-native, this would be the Cadence Type associated
90    ///     with the EVM contract on the Flow side at onboarding.
91    /// @param id: The NFT ID to bridged
92    /// @param feeProvider: A reference to a FungibleToken Provider from which the bridging fee is withdrawn in $FLOW
93    /// @param protectedTransferCall: A function that executes the transfer of the NFT from the named owner to the
94    ///     bridge's COA. This function is expected to return a Result indicating the status of the transfer call.
95    ///
96    /// @returns The bridged NFT
97    ///
98    access(account)
99    fun bridgeNFTFromEVM(
100        owner: EVM.EVMAddress,
101        type: Type,
102        id: UInt256,
103        feeProvider: auth(FungibleToken.Withdraw) &{FungibleToken.Provider},
104        protectedTransferCall: fun (EVM.EVMAddress): EVM.Result
105    ): @{NonFungibleToken.NFT} {
106        post {
107            emit BridgedNFTFromEVM(
108                type: result.getType().identifier,
109                id: result.id,
110                uuid: result.uuid,
111                evmID: id,
112                caller: owner.toString(),
113                evmContractAddress: self.getAssociatedEVMAddress(with: result.getType())?.toString()
114                    ?? panic("Could not find EVM Contract address associated with provided NFT"),
115                bridgeAddress: self.account.address
116            )
117        }
118    }
119}