Smart Contract
IFlowEVMNFTBridge
A.1e4aa0b87d10b141.IFlowEVMNFTBridge
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}