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
2amountUInt256
1000
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
17
18import HybridCustody from 0xd8a7e05a7ac670c0
19import CapabilityFilter from 0xd8a7e05a7ac670c0
20
21transaction(vaultIdentifier: String, child: Address, amount: UInt256) {
22 prepare(signer: auth(BorrowValue, CopyValue, IssueStorageCapabilityController, PublishCapability, SaveValue, UnpublishCapability) &Account) {
23 // Borrow a reference to the signer's COA
24 let coa = signer.storage.borrow<auth(EVM.Bridge) &EVM.CadenceOwnedAccount>(from: /storage/evm)
25 ?? panic("Could not borrow COA from provided gateway address")
26 let vaultType = CompositeType(vaultIdentifier)
27 ?? panic("Could not construct Vault type from identifier: ".concat(vaultIdentifier))
28 // Parse the Vault identifier into its components
29 let tokenContractAddress = FlowEVMBridgeUtils.getContractAddress(fromType: vaultType)
30 ?? panic("Could not get contract address from identifier: ".concat(vaultIdentifier))
31 let tokenContractName = FlowEVMBridgeUtils.getContractName(fromType: vaultType)
32 ?? panic("Could not get contract name from identifier: ".concat(vaultIdentifier))
33
34 /* --- Retrieve the funds --- */
35 //
36 // Borrow a reference to the FungibleToken Vault
37 let viewResolver = getAccount(tokenContractAddress).contracts.borrow<&{ViewResolver}>(name: tokenContractName)
38 ?? panic("Could not borrow ViewResolver from FungibleToken contract")
39 let vaultData = viewResolver.resolveContractView(
40 resourceType: nil,
41 viewType: Type<FungibleTokenMetadataViews.FTVaultData>()
42 ) as! FungibleTokenMetadataViews.FTVaultData? ?? panic("Could not resolve FTVaultData view")
43
44 // signer is the parent account
45 // get the manager resource and borrow childAccount
46 let m = signer.storage.borrow<auth(HybridCustody.Manage) &HybridCustody.Manager>(from: HybridCustody.ManagerStoragePath)
47 ?? panic("manager does not exist")
48 let childAcct = m.borrowAccount(addr: child) ?? panic("child account not found")
49
50 //get Ft cap from child account
51 let capType = Type<&{FungibleToken.Receiver}>()
52 let controllerID = childAcct.getControllerIDForType(type: capType, forPath: vaultData.storagePath)
53 ?? panic("no controller found for capType")
54
55 let cap = childAcct.getCapability(controllerID: controllerID, type: capType) ?? panic("no cap found")
56 let providerCap = cap as! Capability<&{FungibleToken.Receiver}>
57 assert(providerCap.check(), message: "invalid provider capability")
58
59 // Get a reference to the child's stored vault
60 let vaultRef = providerCap.borrow()!
61
62 let approxFee = FlowEVMBridgeUtils.calculateBridgeFee(bytes: 400_000)
63 /* --- Configure a ScopedFTProvider --- */
64 //
65 // Issue and store bridge-dedicated Provider Capability in storage if necessary
66 if signer.storage.type(at: FlowEVMBridgeConfig.providerCapabilityStoragePath) == nil {
67 let providerCap = signer.capabilities.storage.issue<auth(FungibleToken.Withdraw) &{FungibleToken.Provider}>(
68 /storage/flowTokenVault
69 )
70 signer.storage.save(providerCap, to: FlowEVMBridgeConfig.providerCapabilityStoragePath)
71 }
72 // Copy the stored Provider capability and create a ScopedFTProvider
73 let providerCapCopy = signer.storage.copy<Capability<auth(FungibleToken.Withdraw) &{FungibleToken.Provider}>>(
74 from: FlowEVMBridgeConfig.providerCapabilityStoragePath
75 ) ?? panic("Invalid Provider Capability found in storage.")
76 let providerFilter = ScopedFTProviders.AllowanceFilter(approxFee)
77 let scopedProvider <- ScopedFTProviders.createScopedFTProvider(
78 provider: providerCapCopy,
79 filters: [ providerFilter ],
80 expiration: getCurrentBlock().timestamp + 1.0
81 )
82
83 let vault: @{FungibleToken.Vault} <- coa.withdrawTokens(
84 type: vaultType,
85 amount: amount,
86 feeProvider: &scopedProvider as auth(FungibleToken.Withdraw) &{FungibleToken.Provider}
87 )
88
89 vaultRef.deposit(from: <- vault)
90 destroy scopedProvider
91 }
92}