TransactionSEALED
▒?▓╳╱▫~%^◆$░╲~□@◇@░●*■○▓^█*▒#$░■╲●◇?#╳▫░~□░□$**○◆!▒●~●*#$╲●~○●╳&
Transaction ID
Execution Error
Error Code: 1009
error caused by: 1 error occurred:
Raw Error
[Error Code: 1009] error caused by: 1 error occurred: * transaction verification failed: [Error Code: 1006] invalid proposal key: public key 6 on account f380b22ef386ac7e does not have a valid signature: [Error Code: 1009] invalid envelope key: public key 6 on account f380b22ef386ac7e does not have a valid signature: signature is not valid
Transaction Summary
TransactionScript Arguments
0vaultIdentifierString
A.f1ab99c82dee3526.USDCFlow.Vault
1childAddress
2amountUFix64
0.00100000
Cadence Script
1import MetadataViews from 0x1d7e57aa55817448
2import ViewResolver from 0x1d7e57aa55817448
3import NonFungibleToken from 0x1d7e57aa55817448
4
5import FungibleToken from 0xf233dcee88fe0abe
6import FlowToken from 0x1654653399040a61
7import FungibleTokenMetadataViews from 0xf233dcee88fe0abe
8
9import ScopedFTProviders from 0x1e4aa0b87d10b141
10
11import EVM from 0xe467b9dd11fa00df
12
13import FlowEVMBridgeUtils from 0x1e4aa0b87d10b141
14import FlowEVMBridge from 0x1e4aa0b87d10b141
15import FlowEVMBridgeConfig from 0x1e4aa0b87d10b141
16
17import HybridCustody from 0xd8a7e05a7ac670c0
18import CapabilityFilter from 0xd8a7e05a7ac670c0
19
20
21transaction(vaultIdentifier: String, child: Address, amount: UFix64, recipient:String) {
22 // The Vault resource that holds the tokens that are being transferred
23 let paymentVault: @{FungibleToken.Vault}
24 // let coa: auth(EVM.Bridge) &EVM.CadenceOwnedAccount
25 let scopedProvider: @ScopedFTProviders.ScopedFTProvider
26
27 prepare(signer: auth(Storage, CopyValue, BorrowValue, IssueStorageCapabilityController, PublishCapability, SaveValue) &Account) {
28 /* --- Reference the signer's CadenceOwnedAccount --- */
29 //
30 // Borrow a reference to the signer's COA
31 // self.coa = signer.storage.borrow<auth(EVM.Bridge) &EVM.CadenceOwnedAccount>(from: /storage/evm)
32 // ?? panic("Could not borrow COA from provided gateway address")
33
34 /* --- Retrieve the funds --- */
35 //
36 // Borrow a reference to the FungibleToken Vault
37 let vaultType = CompositeType(vaultIdentifier)
38 ?? panic("Could not construct Vault type from identifier: ".concat(vaultIdentifier))
39 // Parse the Vault identifier into its components
40 let tokenContractAddress = FlowEVMBridgeUtils.getContractAddress(fromType: vaultType)
41 ?? panic("Could not get contract address from identifier: ".concat(vaultIdentifier))
42 let tokenContractName = FlowEVMBridgeUtils.getContractName(fromType: vaultType)
43 ?? panic("Could not get contract name from identifier: ".concat(vaultIdentifier))
44
45 let viewResolver = getAccount(tokenContractAddress).contracts.borrow<&{ViewResolver}>(name: tokenContractName)
46 ?? panic("Could not borrow ViewResolver from FungibleToken contract")
47 let vaultData = viewResolver.resolveContractView(
48 resourceType: nil,
49 viewType: Type<FungibleTokenMetadataViews.FTVaultData>()
50 ) as! FungibleTokenMetadataViews.FTVaultData? ?? panic("Could not resolve FTVaultData view")
51 let vault = signer.storage.borrow<auth(FungibleToken.Withdraw) &{FungibleToken.Vault}>(
52 from: vaultData.storagePath
53 ) ?? panic("Could not access signer's FungibleToken Vault")
54
55 // signer is the parent account
56 // get the manager resource and borrow childAccount
57 let m = signer.storage.borrow<auth(HybridCustody.Manage) &HybridCustody.Manager>(from: HybridCustody.ManagerStoragePath)
58 ?? panic("manager does not exist")
59 let childAcct = m.borrowAccount(addr: child) ?? panic("child account not found")
60
61 //get Ft cap from child account
62 let capType = Type<auth(FungibleToken.Withdraw) &{FungibleToken.Provider}>()
63 let controllerID = childAcct.getControllerIDForType(type: capType, forPath: vaultData.storagePath)
64 ?? panic("no controller found for capType")
65
66 let cap = childAcct.getCapability(controllerID: controllerID, type: capType) ?? panic("no cap found")
67 let providerCap = cap as! Capability<auth(FungibleToken.Withdraw) &{FungibleToken.Provider}>
68 assert(providerCap.check(), message: "invalid provider capability")
69
70 // Get a reference to the child's stored vault
71 let vaultRef = providerCap.borrow()!
72
73 // Withdraw tokens from the signer's stored vault
74 vault.deposit(from: <- vaultRef.withdraw(amount: amount))
75 // Withdraw the requested balance & calculate the approximate bridge fee based on storage usage
76 let currentStorageUsage = signer.storage.used
77 self.paymentVault <- vault.withdraw(amount: amount)
78 let withdrawnStorageUsage = signer.storage.used
79 // Approximate the bridge fee based on the difference in storage usage with some buffer
80 let approxFee = FlowEVMBridgeUtils.calculateBridgeFee(
81 bytes: 400_000
82 )
83
84 /* --- Configure a ScopedFTProvider --- */
85 //
86 // Issue and store bridge-dedicated Provider Capability in storage if necessary
87 if signer.storage.type(at: FlowEVMBridgeConfig.providerCapabilityStoragePath) == nil {
88 let providerCap = signer.capabilities.storage.issue<auth(FungibleToken.Withdraw) &{FungibleToken.Provider}>(
89 /storage/flowTokenVault
90 )
91 signer.storage.save(providerCap, to: FlowEVMBridgeConfig.providerCapabilityStoragePath)
92 }
93 // Copy the stored Provider capability and create a ScopedFTProvider
94 let providerCapCopy = signer.storage.copy<Capability<auth(FungibleToken.Withdraw) &{FungibleToken.Provider}>>(from: FlowEVMBridgeConfig.providerCapabilityStoragePath)
95 ?? panic("Invalid Provider Capability found in storage.")
96 let providerFilter = ScopedFTProviders.AllowanceFilter(approxFee)
97 self.scopedProvider <- ScopedFTProviders.createScopedFTProvider(
98 provider: providerCapCopy,
99 filters: [ providerFilter ],
100 expiration: getCurrentBlock().timestamp + 1.0
101 )
102 }
103
104 execute {
105 let recipientEVMAddress = EVM.addressFromString(recipient)
106 FlowEVMBridge.bridgeTokensToEVM(
107 vault: <-self.paymentVault,
108 to: recipientEVMAddress,
109 feeProvider: &self.scopedProvider as auth(FungibleToken.Withdraw) &{FungibleToken.Provider}
110 )
111 // Destroy the ScopedFTProvider
112 destroy self.scopedProvider
113 }
114}