@@ -13,26 +13,44 @@ import "FlowEVMBridgeConfig"
13
13
import " FlowEVMBridgeUtils"
14
14
15
15
/// Bridges NFTs (from the same collection) from the signer's collection in Cadence to the signer's COA in FlowEVM
16
+ /// and then performs an arbitrary number of calls afterwards to potentially do things
17
+ /// with the bridged NFTs
16
18
///
17
- /// NOTE: This transaction also onboards the NFT to the bridge if necessary which may incur additional fees
18
- /// than bridging an asset that has already been onboarded.
19
+ /// This transaction assumes that the NFT has already been onboarded to the bridge
19
20
///
20
21
/// @param nftIdentifier: The Cadence type identifier of the NFT to bridge - e.g. nft.getType().identifier
21
22
/// @param ids: The Cadence NFT.id of the NFTs to bridge to EVM
23
+ /// @params evmContractAddressHexes, calldatas, gasLimits, values: An array of calldata
24
+ /// to be included in transaction calls to Flow EVM from the signer's COA.
25
+ /// The arrays are all expected to be of the same length
22
26
///
23
- transaction (nftIdentifier : String, ids : [UInt64]) {
27
+ transaction (
28
+ nftIdentifier : String,
29
+ ids : [UInt64],
30
+ evmContractAddressHexes : [String],
31
+ calldatas : [String],
32
+ gasLimits : [UInt64],
33
+ values : [UFix64]
34
+ ) {
24
35
25
36
let nftType : Type
26
37
let collection : auth (NonFungibleToken .Withdraw ) &{NonFungibleToken .Collection }
27
- let coa : auth (EVM .Bridge ) &EVM .CadenceOwnedAccount
38
+ let coa : auth (EVM .Bridge , EVM . Call ) &EVM .CadenceOwnedAccount
28
39
let requiresOnboarding : Bool
29
40
let scopedProvider : @ScopedFTProviders .ScopedFTProvider
30
41
31
42
prepare (signer : auth (CopyValue, BorrowValue, IssueStorageCapabilityController, PublishCapability, SaveValue) &Account) {
43
+ pre {
44
+ (evmContractAddressHexes.length == calldatas.length)
45
+ && (calldatas.length == gasLimits.length)
46
+ && (gasLimits.length == values.length):
47
+ " Calldata array lengths must all be the same!"
48
+ }
49
+
32
50
/* --- Reference the signer's CadenceOwnedAccount --- */
33
51
//
34
52
// Borrow a reference to the signer's COA
35
- self .coa = signer.storage.borrow< auth (EVM.Bridge) &EVM.CadenceOwnedAccount> (from : / storage/ evm)
53
+ self .coa = signer.storage.borrow< auth (EVM.Bridge, EVM.Call ) &EVM.CadenceOwnedAccount> (from : / storage/ evm)
36
54
?? panic (" Could not borrow COA signer's account at path /storage/evm" )
37
55
38
56
/* --- Construct the NFT type --- */
@@ -98,6 +116,7 @@ transaction(nftIdentifier: String, ids: [UInt64]) {
98
116
}
99
117
100
118
execute {
119
+
101
120
if self .requiresOnboarding {
102
121
// Onboard the NFT to the bridge
103
122
FlowEVMBridge.onboardByType (
@@ -124,5 +143,22 @@ transaction(nftIdentifier: String, ids: [UInt64]) {
124
143
125
144
// Destroy the ScopedFTProvider
126
145
destroy self .scopedProvider
146
+
147
+ // Perform all the calls
148
+ for index, evmAddressHex in evmContractAddressHexes {
149
+ let evmAddress = EVM.addressFromString (evmAddressHex)
150
+
151
+ let valueBalance = EVM.Balance (attoflow : 0 )
152
+ valueBalance.setFLOW (flow : values[index])
153
+ let callResult = self .coa.call (
154
+ to : evmAddress,
155
+ data : calldatas[index].decodeHex (),
156
+ gasLimit : gasLimits[index],
157
+ value : valueBalance
158
+ )
159
+ assert (
160
+ callResult.status == EVM.Status.successful,
161
+ message : " Call failed with address \(evmAddressHex) and calldata \(calldatas[index]) with error \(callResult.errorMessage)" )
162
+ }
127
163
}
128
164
}
0 commit comments