#◇*◇▒*●#╱○╳&*?■◇~◆^╲@░◆~@▓◆▓╳▪~▒╳◇▫$&~!@◆^▓^%▪%#&#▓*~░~█^&▪~░$#░
Transaction ID
Execution Fee
0.00126 FLOWExecution Error
panic: no child account with that address
90 }
91 } else {
92 let manager = acct.storage.borrow<auth(HybridCustody.Manage) &HybridCustody.Manager>(from: HybridCustody.ManagerStoragePath)
93 ?? panic("Missing or mis-typed HybridCustody Manager")
94
95 let child = manager.borrowAccount(addr: ftReceiverAddress) ?? panic("no child account with that address")
96 let ftProviderCap = child.getCapability(controllerID: ftProviderControllerID, type: Type<auth(FungibleToken.Withdraw) &{FungibleToken.Provider}>()) ?? panic("no ft provider found")
97 self.tokenProvider = ftProviderCap as! Capability<auth(FungibleToken.Withdraw) &{FungibleToken.Provider}>?
98 }
99
100 assert(self.tokenProvider!.check(), message: "Missing or mis-typed token provider")Raw Error
[Error Code: 1101] error caused by: 1 error occurred: * transaction execute failed: [Error Code: 1101] cadence runtime error: Execution failed: error: panic: no child account with that address --> d9ae72b5652d1ad327ceff14469170cec043c065d3390cf15d5ef56d710a7a3f:95:78 | 95 | let child = manager.borrowAccount(addr: ftReceiverAddress) ?? panic("no child account with that address") | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Was this error unhelpful? Consider suggesting an improvement here: https://github.com/onflow/cadence/issues.
Transaction Summary
Contract CallCalled FungibleToken, NonFungibleToken, MetadataViews +6 more
Script Arguments
Cadence Script
1import FungibleToken from 0xf233dcee88fe0abe
2import NonFungibleToken from 0x1d7e57aa55817448
3import MetadataViews from 0x1d7e57aa55817448
4import NFTCatalog from 0x49a7cda3a1eecc29
5import Flowty from 0x5c57f79c6694797f
6import HybridCustody from 0xd8a7e05a7ac670c0
7import FungibleTokenMetadataViews from 0xf233dcee88fe0abe
8import CapabilityCache from 0xacc5081c003e24cf
9import AddressUtils from 0xa340dc0a4ec828ab
10
11transaction(
12 listItemID: UInt64,
13 amount: UFix64,
14 interestRate: UFix64,
15 term: UFix64,
16 autoRepaymentEnabled: Bool,
17 loanExpiresAfter: UFix64,
18 ftProviderControllerID: UInt64,
19 nftProviderControllerID: UInt64,
20 collectionIdentifier: String,
21 nftProviderAddress: Address,
22 ftReceiverAddress: Address,
23 paymentTokenIdentifier: String
24) {
25 let tokenReceiver: Capability<&{FungibleToken.Receiver}>
26 let nftProvider: Capability<auth(NonFungibleToken.Withdraw) &{NonFungibleToken.Provider, NonFungibleToken.CollectionPublic}>
27 let storefront: auth(Flowty.List) &Flowty.FlowtyStorefront
28 let nftReceiver: Capability<&{NonFungibleToken.CollectionPublic}>
29 let paymentVault: @{FungibleToken.Vault}
30 let tokenProvider: Capability<auth(FungibleToken.Withdraw) &{FungibleToken.Provider}>?
31 let paymentTokenType: Type
32 let nftType: Type
33
34 prepare(acct: auth(Storage, Capabilities) &Account) {
35 self.paymentTokenType = CompositeType(paymentTokenIdentifier) ?? panic("invalid payment token type identifier")
36
37 if(acct.storage.borrow<&Flowty.FlowtyStorefront>(from: Flowty.FlowtyStorefrontStoragePath) == nil) {
38 // Create a new empty .Storefront
39 let storefront <- Flowty.createStorefront()
40
41 // save it to the account
42 acct.storage.save(<-storefront, to: Flowty.FlowtyStorefrontStoragePath)
43 acct.capabilities.publish(
44 acct.capabilities.storage.issue<&{Flowty.FlowtyStorefrontPublic}>(Flowty.FlowtyStorefrontStoragePath),
45 at: Flowty.FlowtyStorefrontPublicPath
46 )
47 }
48
49 let namespace = "flowty"
50 let cacheStoragePath = CapabilityCache.getPathForCache(namespace)
51 if acct.storage.borrow<&CapabilityCache.Cache>(from: cacheStoragePath) == nil {
52 let c <- CapabilityCache.createCache(namespace: namespace)
53 acct.storage.save(<-c, to: cacheStoragePath)
54 }
55 let cache = acct.storage.borrow<auth(CapabilityCache.Add, CapabilityCache.Get) &CapabilityCache.Cache>(from: cacheStoragePath)
56 ?? panic("capability cache not found")
57
58 let catalogEntry = NFTCatalog.getCatalogEntry(collectionIdentifier: collectionIdentifier) ?? panic("Provided collection is not in the NFT Catalog.")
59 self.nftType = catalogEntry.nftType
60
61 // We need a provider capability, but one is not provided by default so we create one if needed.
62 let publicCollectionPath = catalogEntry.collectionData.publicPath
63 let storageCollectionPath = catalogEntry.collectionData.storagePath
64
65 let ftAddress = AddressUtils.parseAddress(self.paymentTokenType)!
66 let contractName = self.paymentTokenType.identifier.split(separator: ".")[2]
67 let ftContract = getAccount(ftAddress).contracts.borrow<&{FungibleToken}>(name: contractName)
68 ?? panic("could not borrow fungible token contract")
69
70 let ftVaultData = ftContract.resolveContractView(resourceType: self.paymentTokenType, viewType: Type<FungibleTokenMetadataViews.FTVaultData>())! as! FungibleTokenMetadataViews.FTVaultData
71
72 // Do we need to setup this vault for the signing account?
73 if ftReceiverAddress == acct.address && acct.storage.type(at: ftVaultData.storagePath) == nil {
74 acct.storage.save(<- ftVaultData.createEmptyVault(), to: ftVaultData.storagePath)
75 acct.capabilities.unpublish(ftVaultData.receiverPath)
76 acct.capabilities.unpublish(ftVaultData.metadataPath)
77
78 acct.capabilities.publish(acct.capabilities.storage.issue<&{FungibleToken.Receiver}>(ftVaultData.storagePath), at: ftVaultData.receiverPath)
79 acct.capabilities.publish(acct.capabilities.storage.issue<&{FungibleToken.Vault}>(ftVaultData.storagePath), at: ftVaultData.metadataPath)
80 }
81
82 if autoRepaymentEnabled {
83 if ftReceiverAddress == acct.address {
84 let borrowType = Type<auth(FungibleToken.Withdraw) &{FungibleToken.Provider, FungibleToken.Balance, FungibleToken.Receiver}>()
85 if let provider = cache.getCapabilityByType(resourceType: self.paymentTokenType, capabilityType: CapabilityType(borrowType)!) {
86 self.tokenProvider = provider as! Capability<auth(FungibleToken.Withdraw) &{FungibleToken.Provider, FungibleToken.Balance, FungibleToken.Receiver}>
87 } else {
88 self.tokenProvider = acct.capabilities.storage.issueWithType(ftVaultData.storagePath, type: borrowType) as! Capability<auth(FungibleToken.Withdraw) &{FungibleToken.Provider, FungibleToken.Balance, FungibleToken.Receiver}>
89 cache.addCapability(resourceType: self.paymentTokenType, cap: self.tokenProvider!)
90 }
91 } else {
92 let manager = acct.storage.borrow<auth(HybridCustody.Manage) &HybridCustody.Manager>(from: HybridCustody.ManagerStoragePath)
93 ?? panic("Missing or mis-typed HybridCustody Manager")
94
95 let child = manager.borrowAccount(addr: ftReceiverAddress) ?? panic("no child account with that address")
96 let ftProviderCap = child.getCapability(controllerID: ftProviderControllerID, type: Type<auth(FungibleToken.Withdraw) &{FungibleToken.Provider}>()) ?? panic("no ft provider found")
97 self.tokenProvider = ftProviderCap as! Capability<auth(FungibleToken.Withdraw) &{FungibleToken.Provider}>?
98 }
99
100 assert(self.tokenProvider!.check(), message: "Missing or mis-typed token provider")
101 } else {
102 self.tokenProvider = nil
103 }
104
105 if ftReceiverAddress == acct.address {
106 if acct.storage.borrow<&{FungibleToken.Vault}>(from: ftVaultData.storagePath) == nil {
107 acct.storage.save(<- ftVaultData.createEmptyVault(), to: ftVaultData.storagePath)
108 acct.capabilities.publish(
109 acct.capabilities.storage.issue<&{FungibleToken.Receiver}>(ftVaultData.storagePath),
110 at: ftVaultData.receiverPath
111 )
112
113 acct.capabilities.publish(
114 acct.capabilities.storage.issue<&{FungibleToken.Balance}>(ftVaultData.storagePath),
115 at: ftVaultData.metadataPath
116 )
117 }
118
119 self.tokenReceiver = acct.capabilities.get<&{FungibleToken.Receiver}>(ftVaultData.receiverPath)!
120 } else {
121 let manager = acct.storage.borrow<auth(HybridCustody.Manage) &HybridCustody.Manager>(from: HybridCustody.ManagerStoragePath)
122 ?? panic("Missing or mis-typed HybridCustody Manager")
123
124 let child = manager.borrowAccount(addr: ftReceiverAddress) ?? panic("no child account with that address")
125 self.tokenReceiver = getAccount(ftReceiverAddress).capabilities.get<&{FungibleToken.Receiver}>(ftVaultData.receiverPath)!
126 }
127
128 assert(self.tokenReceiver.check(), message: "Missing or mis-typed token receiver")
129
130 if nftProviderAddress == acct.address {
131 if !acct.capabilities.get<&{NonFungibleToken.CollectionPublic}>(publicCollectionPath).check() {
132 acct.capabilities.unpublish(publicCollectionPath)
133
134 acct.capabilities.publish(
135 acct.capabilities.storage.issue<&{NonFungibleToken.CollectionPublic}>(storageCollectionPath),
136 at: publicCollectionPath
137 )
138 }
139
140 let borrowType = Type<auth(NonFungibleToken.Withdraw) &{NonFungibleToken.Provider, NonFungibleToken.CollectionPublic}>()
141 if let provider = cache.getCapabilityByType(resourceType: self.nftType, capabilityType: CapabilityType(borrowType)!) {
142 self.nftProvider = provider as! Capability<auth(NonFungibleToken.Withdraw) &{NonFungibleToken.Provider, NonFungibleToken.CollectionPublic}>
143 } else {
144 self.nftProvider = acct.capabilities.storage.issueWithType(catalogEntry.collectionData.storagePath, type: borrowType) as! Capability<auth(NonFungibleToken.Withdraw) &{NonFungibleToken.Provider, NonFungibleToken.CollectionPublic}>
145 cache.addCapability(resourceType: self.nftType, cap: self.nftProvider!)
146 }
147
148 self.nftReceiver = acct.capabilities.get<&{NonFungibleToken.CollectionPublic}>(publicCollectionPath)!
149 } else {
150 let manager = acct.storage.borrow<auth(HybridCustody.Manage) &HybridCustody.Manager>(from: HybridCustody.ManagerStoragePath)
151 ?? panic("Missing or mis-typed HybridCustody Manager")
152
153 let child = manager.borrowAccount(addr: nftProviderAddress) ?? panic("no child account with that address")
154
155 let providerCap = child.getCapability(controllerID: nftProviderControllerID, type: Type<auth(NonFungibleToken.Withdraw) &{NonFungibleToken.Provider, NonFungibleToken.CollectionPublic}>()) ?? panic("no nft provider found")
156 self.nftProvider = providerCap as! Capability<auth(NonFungibleToken.Withdraw) &{NonFungibleToken.Provider, NonFungibleToken.CollectionPublic}>
157
158 let receiverCap = child.getPublicCapability(path: publicCollectionPath, type: Type<&{NonFungibleToken.CollectionPublic}>()) ?? panic("no nft collection public found")
159 self.nftReceiver = receiverCap as! Capability<&{NonFungibleToken.CollectionPublic}>
160 }
161
162 assert(self.nftProvider.check(), message: "Missing or mis-typed NFT Provider")
163 assert(self.nftReceiver.check(), message: "Missing or mis-typed NFT Receiver")
164
165 self.storefront = acct.storage.borrow<auth(Flowty.List) &Flowty.FlowtyStorefront>(from: Flowty.FlowtyStorefrontStoragePath)
166 ?? panic("Missing or mis-typed Flowty FlowtyStorefront")
167
168 let tokenVault = acct.storage.borrow<auth(FungibleToken.Withdraw) &{FungibleToken.Vault}>(from: ftVaultData.storagePath)
169 ?? panic("Cannot borrow token vault from acct storage")
170
171 self.paymentVault <- tokenVault.withdraw(amount: Flowty.ListingFee)
172 }
173
174 execute {
175 let paymentCut = Flowty.PaymentCut(
176 receiver: self.tokenReceiver,
177 amount: amount
178 )
179 self.storefront.createListing(
180 payment: <-self.paymentVault,
181 nftProviderCapability: self.nftProvider,
182 nftPublicCollectionCapability: self.nftReceiver,
183 fusdProviderCapability: self.tokenProvider,
184 nftType: self.nftType,
185 nftID: listItemID,
186 amount: amount,
187 interestRate: interestRate,
188 term: term,
189 paymentVaultType: self.paymentTokenType,
190 paymentCuts: [paymentCut],
191 expiresAfter: loanExpiresAfter
192 )
193 }
194}